summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlmaz Mingaleev <mingaleev@google.com>2021-02-24 14:43:01 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-02-24 14:43:01 +0000
commit59dc7492b21ea28c2087f6360aead79d027efc8b (patch)
tree3471f21861ec91b670c5fb3dcb045fe784adb29c
parent283cf8374d149246c3bc40c66a05bcabc664d6c0 (diff)
parente5664618490d407b03b2ac54f24c3ffea5690775 (diff)
downloadbouncycastle-59dc7492b21ea28c2087f6360aead79d027efc8b.tar.gz
Merge "Update BC to 1.68." am: e566461849
Original change: https://android-review.googlesource.com/c/platform/external/bouncycastle/+/1596471 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I6ccd4fdd384e09a8765cae76dc89df5ad93820f7
-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/RSA.java9
-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/keystore/bc/BcKeyStoreSpi.java22
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java246
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DESede.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java17
-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.java411
-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/provider/BouncyCastleProvider.java47
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java4
-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.java57
-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.java102
-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/ASN1EncodableVector.java142
-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.java126
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Integer.java176
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Null.java3
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Object.java49
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1ObjectIdentifier.java41
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1OctetString.java73
-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.java24
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1Sequence.java246
-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.java107
-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.java46
-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/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/DERNull.java12
-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/DEROctetString.java23
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROutputStream.java20
-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.java104
-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.java116
-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.java98
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERUTF8String.java5
-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.java75
-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.java19
-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.java20
-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.java2
-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.java8
-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/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.java2
-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.java29
-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.java2
-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.java78
-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/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.java13
-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.java8
-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/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/StagedAgreement.java13
-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/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/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/RSA.java9
-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/keystore/bc/BcKeyStoreSpi.java22
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java246
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/AES.java6
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/DESede.java7
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java17
-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.java45
-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/exception/ExtCertPathValidatorException.java5
-rw-r--r--repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/BouncyCastleProvider.java47
-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/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.java57
-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.java27
-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/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/PemReader.java5
-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/X509V2AttributeCertificate.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ApplicationSpecific.java10
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1BitString.java102
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Boolean.java104
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1EncodableVector.java142
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Enumerated.java73
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1External.java14
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1GeneralizedTime.java182
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Generator.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1InputStream.java126
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Integer.java176
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Null.java3
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Object.java49
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ObjectIdentifier.java41
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OctetString.java73
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OutputStream.java263
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Primitive.java24
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Sequence.java246
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Set.java452
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1StreamParser.java31
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObject.java107
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UTCTime.java30
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERApplicationSpecific.java12
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERFactory.java14
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERGenerator.java36
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetString.java110
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringGenerator.java23
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROutputStream.java44
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequence.java46
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSet.java57
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObject.java123
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ConstructedOctetStream.java46
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERApplicationSpecific.java8
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBMPString.java71
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBitString.java46
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBoolean.java24
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternal.java16
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERFactory.java14
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralString.java9
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralizedTime.java16
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGraphicString.java8
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERIA5String.java12
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNull.java12
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNumericString.java6
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetString.java23
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROutputStream.java20
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERPrintableString.java6
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequence.java104
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequenceParser.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSet.java116
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSetParser.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERT61String.java6
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERTaggedObject.java98
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUTF8String.java5
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUniversalString.java24
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVideotexString.java8
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVisibleString.java8
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLApplicationSpecific.java8
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLBitString.java32
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLExternal.java13
-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.java24
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequence.java93
-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.java91
-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.java91
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DefiniteLengthInputStream.java40
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyConstructionEnumeration.java13
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyEncodedSequence.java115
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LimitedInputStream.java5
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/StreamUtil.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java24
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/Attribute.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/Attributes.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/CMSAlgorithmProtection.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/CMSAttributes.java6
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/ContentInfo.java6
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/GCMParameters.java6
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/IssuerAndSerialNumber.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/SignedData.java6
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/SignerIdentifier.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/SignerInfo.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/Time.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/eac/EACObjectIdentifiers.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/kisa/KISAObjectIdentifiers.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java13
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java8
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ntt/NTTObjectIdentifiers.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/BasicOCSPResponse.java10
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CertID.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CrlID.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPObjectIdentifiers.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPRequest.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPResponse.java11
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPResponseStatus.java22
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/Request.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponseBytes.java8
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponseData.java11
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/RevokedInfo.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/Signature.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/SingleResponse.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/TBSRequest.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/Attribute.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/AuthenticatedSafe.java11
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CRLBag.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertBag.java7
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequest.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/ContentInfo.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/DHParameter.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedData.java6
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/IssuerAndSerialNumber.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/MacData.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBEParameter.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBES2Parameters.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBKDF2Params.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PKCS12PBEParams.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java75
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/Pfx.java8
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java19
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAPrivateKey.java9
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAPrivateKeyStructure.java9
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAPublicKey.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSASSAPSSparams.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/SafeBag.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/SignedData.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKey.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/SECNamedCurves.java391
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/util/ASN1Dump.java11
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/AttributeTypeAndValue.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/RDN.java27
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500Name.java107
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java3
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStyle.java20
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/IETFUtils.java186
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttCertValidityPeriod.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Attribute.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificate.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java21
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/BasicConstraints.java8
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLDistPoint.java20
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLReason.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CertificateList.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DSAParameter.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DigestInfo.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DistributionPoint.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ExtendedKeyUsage.java10
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extension.java41
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extensions.java22
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ExtensionsGenerator.java88
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralName.java29
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralNames.java20
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralSubtree.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Holder.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuerSerial.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyPurposeId.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyUsage.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/NameConstraints.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ObjectDigestInfo.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/OtherName.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java289
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyConstraints.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyInformation.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/RSAPublicKeyStructure.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertList.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificate.java78
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificateStructure.java7
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V1TBSCertificateGenerator.java13
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V2Form.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java13
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Extensions.java13
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Name.java8
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509NameEntryConverter.java34
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java29
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHDomainParameters.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHValidationParms.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DomainParameters.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ECNamedCurveTable.java16
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ValidationParams.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962NamedCurves.java563
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962Parameters.java8
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9Curve.java18
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParameters.java32
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECPoint.java6
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9FieldID.java6
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesRegistrar.java49
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/KeyGenerationParameters.java2
-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/digests/SHA256Digest.java26
-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.java278
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/OAEPEncoding.java1
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/PKCS1Encoding.java27
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESEngine.java149
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESFastEngine.java149
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESWrapEngine.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/BlowfishEngine.java3
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeWrapEngine.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSABlindedEngine.java28
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/DSAParametersGenerator.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java8
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/PKCS5S1ParametersGenerator.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java6
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/AEADBlockCipher.java137
-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/CCMBlockCipher.java14
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CFBBlockCipher.java5
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/OFBBlockCipher.java11
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMUtil.java86
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java9
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DESParameters.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHParameters.java3
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/DHPublicKeyParameters.java104
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECDomainParameters.java71
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECKeyParameters.java13
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECNamedDomainParameters.java7
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECPrivateKeyParameters.java9
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ECPublicKeyParameters.java12
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/ParametersWithRandom.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAKeyParameters.java24
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSASigner.java8
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/ECDSASigner.java7
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/RSADigestSigner.java26
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/tls/CertificateType.java2
-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.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PrivateKeyFactory.java69
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PublicKeyFactory.java140
-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/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/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/PKIXCertStoreSelector.java15
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXExtendedParameters.java55
-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/provider/asymmetric/RSA.java9
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParameterGeneratorSpi.java9
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java10
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java36
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java6
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java24
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java9
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java10
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java24
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java3
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java52
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java26
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java6
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java62
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java56
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java27
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyFactorySpi.java56
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java39
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/rsa/RSAUtil.java11
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java146
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java42
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/PKCS12BagAttributeCarrierImpl.java7
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java124
-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.java27
-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.java650
-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.java781
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java135
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java23
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java22
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java246
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/AES.java6
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/DESede.java7
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java17
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPKCS12.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/RC2.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java94
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java411
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java17
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java21
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java18
-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/PBE.java14
-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/spec/CompositeAlgorithmSpec.java72
-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/util/AnnotatedPrivateKey.java118
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/BCJcaJceHelper.java7
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java45
-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.java27
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java45
-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.java45
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/PKCS10CertificationRequest.java1
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/exception/ExtCertPathValidatorException.java5
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/BouncyCastleProvider.java47
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java550
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPrivateKey.java9
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPublicKey.java37
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCRLUtil.java54
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java37
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java57
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXNameConstraintValidator.java1872
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXNameConstraintValidatorException.java14
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PrincipalUtils.java128
-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.java378
-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/X509CRLObject.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CertificateObject.java27
-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/ECAlgorithms.java167
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECCurve.java242
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECFieldElement.java99
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECLookupTable.java1
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECPoint.java253
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/GLVMultiplier.java8
-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/ScaleYNegateXPointMap.java20
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WNafL2RMultiplier.java25
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WNafPreCompInfo.java51
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WNafUtil.java224
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192K1Curve.java57
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java47
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java11
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java52
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192R1Curve.java62
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java47
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192R1FieldElement.java9
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java51
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224K1Curve.java60
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224K1Field.java47
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224K1FieldElement.java11
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224K1Point.java52
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224R1Curve.java62
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java50
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224R1FieldElement.java10
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP224R1Point.java51
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Curve.java53
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java49
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java11
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java52
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Curve.java62
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java49
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java9
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java51
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Curve.java62
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java51
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java9
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java51
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Curve.java62
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java44
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java9
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java51
-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/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.java32
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java80
-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/FiniteFields.java2
-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.java133
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Mod.java578
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat.java308
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat192.java28
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat224.java21
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat256.java28
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Arrays.java880
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/BigIntegers.java149
-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/Integers.java20
-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/Objects.java18
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Pack.java99
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Properties.java128
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64Encoder.java145
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Hex.java60
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/HexEncoder.java142
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/TeeInputStream.java5
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemReader.java5
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/AttributeCertificateHolder.java5
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/AttributeCertificateIssuer.java2
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509Util.java4
-rw-r--r--repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V2AttributeCertificate.java2
1387 files changed, 49712 insertions, 29798 deletions
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/RSA.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
index 8cda5d03..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
@@ -96,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);
@@ -279,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/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/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..9e9b4f1d 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,29 @@ public class PKCS12KeyStoreSpi
throw new IOException("error constructing MAC: " + e.toString());
}
}
+ 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");
+ }
+ }
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 +967,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,9 +1302,57 @@ public class PKCS12KeyStoreSpi
private void doStore(OutputStream stream, char[] password, boolean useDEREncoding)
throws IOException
{
- if (password == null)
+ if (keys.size() == 0)
{
- throw new NullPointerException("No password supplied for PKCS#12 KeyStore.");
+ if (password == null)
+ {
+ Enumeration cs = certs.keys();
+
+ ASN1EncodableVector certSeq = new ASN1EncodableVector();
+
+ while (cs.hasMoreElements())
+ {
+ try
+ {
+ String certId = (String)cs.nextElement();
+ Certificate cert = (Certificate)certs.get(certId);
+
+ SafeBag sBag = createSafeBag(certId, cert);
+
+ certSeq.add(sBag);
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new IOException("Error encoding certificate: " + e.toString());
+ }
+ }
+
+ if (useDEREncoding)
+ {
+ ContentInfo bagInfo = new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DERSequence(certSeq).getEncoded()));
+
+ Pfx pfx = new Pfx(new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DERSequence(bagInfo).getEncoded())), null);
+
+ pfx.encodeTo(stream, ASN1Encoding.DER);
+ }
+ else
+ {
+ ContentInfo bagInfo = new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(new BERSequence(certSeq).getEncoded()));
+
+ Pfx pfx = new Pfx(new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(new BERSequence(bagInfo).getEncoded())), null);
+
+ pfx.encodeTo(stream, ASN1Encoding.BER);
+ }
+
+ return;
+ }
+ }
+ else
+ {
+ if (password == null)
+ {
+ throw new NullPointerException("no password supplied for PKCS#12 KeyStore");
+ }
}
//
@@ -1496,66 +1538,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 +1629,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 +1662,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 +1864,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 004e6640..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);
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 6a52aef2..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
@@ -410,13 +410,8 @@ public final class DESede
// 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");
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 d461b9c8..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;
@@ -51,6 +52,7 @@ public class PBEPBKDF2
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
}
@@ -94,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());
@@ -538,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
{
@@ -576,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 d3d04db4..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,9 +330,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"))
@@ -309,7 +348,7 @@ public class BaseBlockCipher
{
ivLength = baseEngine.getBlockSize();
cipher = new BufferedGenericBlockCipher(
- new CBCBlockCipher(baseEngine));
+ new CBCBlockCipher(baseEngine));
}
else if (modeName.startsWith("OFB"))
{
@@ -319,12 +358,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"))
@@ -335,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)
@@ -368,11 +412,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;
@@ -381,7 +425,7 @@ public class BaseBlockCipher
if (baseEngine instanceof DSTU7624Engine)
{
cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
- new KCTRBlockCipher(baseEngine)));
+ new KCTRBlockCipher(baseEngine)));
}
else
{
@@ -394,26 +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
- 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
@@ -432,7 +476,7 @@ public class BaseBlockCipher
}
// BEGIN Android-removed: Unsupported modes
/*
- else if (modeName.startsWith("OCB"))
+ else if (modeName.equals("OCB"))
{
if (engineProvider != null)
{
@@ -447,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
@@ -479,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"))
{
@@ -541,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;
@@ -565,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.");
}
@@ -589,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;
}
@@ -794,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)
{
@@ -814,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());
@@ -833,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"))
@@ -879,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))
{
@@ -907,7 +946,7 @@ public class BaseBlockCipher
if ((ivLength != 0) && !(param instanceof ParametersWithIV) && !(param instanceof AEADParameters))
{
- SecureRandom ivRandom = random;
+ SecureRandom ivRandom = random;
if (ivRandom == null)
{
@@ -916,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
@@ -972,7 +1011,6 @@ public class BaseBlockCipher
}
-
if (random != null && padded)
{
param = new ParametersWithRandom(param, random);
@@ -996,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);
}
@@ -1069,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)
{
@@ -1104,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
@@ -1129,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);
@@ -1171,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)
@@ -1195,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)
{
@@ -1222,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);
@@ -1230,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)
{
@@ -1359,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
{
@@ -1387,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)
{
@@ -1411,9 +1477,9 @@ public class BaseBlockCipher
}
}
- private AEADBlockCipher cipher;
+ private AEADCipher cipher;
- AEADGenericBlockCipher(AEADBlockCipher cipher)
+ AEADGenericBlockCipher(AEADCipher cipher)
{
this.cipher = cipher;
}
@@ -1426,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()
@@ -1436,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)
@@ -1454,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
{
@@ -1478,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/provider/BouncyCastleProvider.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java
index fd6ed40b..bb12aecf 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java
@@ -14,6 +14,8 @@ 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;
@@ -31,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:
@@ -59,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";
@@ -67,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
*/
@@ -105,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"
};
@@ -124,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",
};
@@ -154,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()
{
@@ -187,6 +193,7 @@ public final class BouncyCastleProvider extends Provider
loadAlgorithms(SECURE_RANDOM_PACKAGE, SECURE_RANDOMS);
loadPQCKeys(); // so we can handle certificates containing them.
+
//
// X509Store
//
@@ -199,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
//
@@ -223,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");
@@ -263,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
@@ -313,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();)
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/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 5e1905e5..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,9 +44,16 @@ 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 {
@@ -125,7 +135,8 @@ public class PKIXCertPathValidatorSpi
//
// (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,6 +309,19 @@ 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--)
@@ -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 7324c5f4..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;
@@ -102,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.
*
@@ -114,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)
{
@@ -136,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]);
@@ -166,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;
}
@@ -200,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()
@@ -215,10 +228,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))
@@ -227,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)
@@ -264,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);
}
@@ -289,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/ASN1EncodableVector.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/ASN1EncodableVector.java
index 3e49d657..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,47 +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
*/
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
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
- 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;
}
/**
@@ -52,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];
}
/**
@@ -62,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 4f919b02..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
@@ -113,7 +113,7 @@ public class ASN1InputStream
protected int readLength()
throws IOException
{
- return readLength(this, limit);
+ return readLength(this, limit, false);
}
protected void readFully(
@@ -143,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)
{
@@ -164,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);
@@ -180,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");
}
@@ -194,26 +202,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();
- }
-
@android.compat.annotation.UnsupportedAppUsage
public ASN1Primitive readObject()
throws IOException
@@ -328,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();
@@ -370,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);
}
}
@@ -383,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))
{
- 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/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 52e5ca43..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
@@ -14,7 +14,11 @@ import com.android.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.
@@ -77,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;
}
/**
@@ -89,10 +93,10 @@ public class ASN1Integer
* @param value the BigInteger representing the value desired.
*/
@android.compat.annotation.UnsupportedAppUsage
- public ASN1Integer(
- BigInteger value)
+ public ASN1Integer(BigInteger value)
{
- bytes = value.toByteArray();
+ this.bytes = value.toByteArray();
+ this.start = 0;
}
/**
@@ -117,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()
@@ -185,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))
{
@@ -214,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()
@@ -222,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 e6dcdf9d..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
@@ -75,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 4f3f5bbc..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;
@@ -16,20 +17,26 @@ public abstract class ASN1Object
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.
*/
- 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();
}
@@ -40,30 +47,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()
@@ -89,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.
@@ -97,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 25980b40..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
@@ -177,7 +177,7 @@ public class ASN1ObjectIdentifier
{
if (identifier == null)
{
- throw new IllegalArgumentException("'identifier' cannot be null");
+ throw new NullPointerException("'identifier' cannot be null");
}
if (!isValidIdentifier(identifier))
{
@@ -331,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()
@@ -371,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 d6e81e28..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
@@ -107,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.
*
@@ -146,7 +196,7 @@ public abstract class ASN1OctetString
{
try
{
- return ASN1OctetString.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
+ return getInstance(fromByteArray((byte[])obj));
}
catch (IOException e)
{
@@ -176,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;
}
@@ -244,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 b272f944..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,6 +2,7 @@
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.
@@ -12,7 +13,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);
}
/**
@@ -54,7 +64,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;
}
@@ -94,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 99196c2c..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;
@@ -62,7 +62,8 @@ 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.
@@ -116,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
@@ -124,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());
}
/**
@@ -173,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();
@@ -260,12 +287,12 @@ public abstract class ASN1Sequence
public ASN1Primitive getLoadedObject()
{
- return outer;
+ return ASN1Sequence.this;
}
-
+
public ASN1Primitive toASN1Primitive()
{
- return outer;
+ return ASN1Sequence.this;
}
};
}
@@ -276,10 +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.
*/
- public ASN1Encodable getObjectAt(
- int index)
+ public ASN1Encodable getObjectAt(int index)
{
- return (ASN1Encodable)seq.elementAt(index);
+ return elements[index];
}
/**
@@ -289,80 +315,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);
}
/**
@@ -371,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()
@@ -383,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 41b3e468..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
@@ -13,10 +13,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,
@@ -24,7 +23,7 @@ public abstract class ASN1TaggedObject
{
if (explicit)
{
- return (ASN1TaggedObject)obj.getObject();
+ return getInstance(obj.getObject());
}
throw new IllegalArgumentException("implicitly tagged tagged object");
@@ -35,7 +34,7 @@ public abstract class ASN1TaggedObject
{
if (obj == null || obj instanceof ASN1TaggedObject)
{
- return (ASN1TaggedObject)obj;
+ return (ASN1TaggedObject)obj;
}
else if (obj instanceof byte[])
{
@@ -67,82 +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);
}
-
+
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();
}
/**
@@ -169,11 +125,6 @@ public abstract class ASN1TaggedObject
return explicit;
}
- public boolean isEmpty()
- {
- return empty;
- }
-
/**
* Return whatever was following the tag.
* <p>
@@ -183,12 +134,7 @@ public abstract class ASN1TaggedObject
*/
public ASN1Primitive getObject()
{
- if (obj != null)
- {
- return obj.toASN1Primitive();
- }
-
- return null;
+ return obj.toASN1Primitive();
}
/**
@@ -234,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 d482549f..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
@@ -65,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);
}
/**
@@ -126,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/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/DERNull.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DERNull.java
index fba340db..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
@@ -17,11 +17,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()
{
}
@@ -35,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/DEROctetString.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/asn1/DEROctetString.java
index 859b5147..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
@@ -44,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 be3fa36f..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(maxTargetSdk = 30, trackingBug = 170729553)
- 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/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 f169aa15..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
@@ -14,6 +13,11 @@ import java.util.Enumeration;
public class DERSequence
extends ASN1Sequence
{
+ public static DERSequence convert(ASN1Sequence seq)
+ {
+ return (DERSequence)seq.toDERObject();
+ }
+
private int bodyLength = -1;
/**
@@ -26,57 +30,57 @@ 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.
*/
@android.compat.annotation.UnsupportedAppUsage
- 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();
@@ -91,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 a2f57a92..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(maxTargetSdk = 30, trackingBug = 170729553)
- 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();
@@ -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 db19ce1e..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
@@ -12,8 +12,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.
@@ -34,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 bbf74927..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
@@ -131,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 dc4c4622..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
@@ -264,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)}
@@ -295,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");
@@ -312,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 8fa82566..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;
@@ -90,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(
@@ -178,6 +177,11 @@ public class PrivateKeyInfo
}
}
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
public ASN1Set getAttributes()
{
return attributes;
@@ -188,6 +192,11 @@ public class PrivateKeyInfo
return privateKeyAlgorithm;
}
+ public ASN1OctetString getPrivateKey()
+ {
+ return new DEROctetString(privateKey.getOctets());
+ }
+
public ASN1Encodable parsePrivateKey()
throws IOException
{
@@ -230,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 a7671ff4..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
@@ -47,6 +47,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();
@@ -58,7 +59,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))
@@ -79,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)
*/
@@ -99,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
@@ -207,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");
@@ -216,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");
@@ -241,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);
@@ -252,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);
@@ -347,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 efcc01ca..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
@@ -98,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 cd52cc07..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
@@ -49,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(
@@ -137,7 +137,7 @@ public class BasicConstraints
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
if (cA != null)
{
@@ -156,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/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 efda1628..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
@@ -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 414640e8..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
@@ -188,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);
}
}
@@ -429,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 2f1539d7..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
@@ -147,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 4bea27eb..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.
@@ -93,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");
}
@@ -160,7 +165,7 @@ public class TBSCertificate
public int getVersionNumber()
{
- return version.getValue().intValue() + 1;
+ return version.intValueExact() + 1;
}
public ASN1Integer getVersion()
@@ -220,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/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 5d43230e..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
@@ -175,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);
@@ -185,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 5fbf5f14..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
@@ -379,7 +379,7 @@ public class X509Name
public static X509Name getInstance(
Object obj)
{
- if (obj == null || obj instanceof X509Name)
+ if (obj instanceof X509Name)
{
return (X509Name)obj;
}
@@ -935,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);
@@ -952,8 +952,8 @@ public class X509Name
else
{
vec.add(new DERSet(sVec));
+
sVec = new ASN1EncodableVector();
-
sVec.add(new DERSequence(v));
}
@@ -1195,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)
{
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/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/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/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/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/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/RSA.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
index 11d19fe5..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
@@ -103,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);
@@ -286,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/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/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..bd77e0e4 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,29 @@ public class PKCS12KeyStoreSpi
throw new IOException("error constructing MAC: " + e.toString());
}
}
+ else if (password != null)
+ {
+ if (!Properties.isOverrideSet("com.android.org.bouncycastle.pkcs12.ignore_useless_passwd"))
+ {
+ throw new IOException("password supplied for keystore that does not require one");
+ }
+ }
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 +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++)
{
@@ -1312,9 +1306,57 @@ public class PKCS12KeyStoreSpi
private void doStore(OutputStream stream, char[] password, boolean useDEREncoding)
throws IOException
{
- if (password == null)
+ if (keys.size() == 0)
{
- throw new NullPointerException("No password supplied for PKCS#12 KeyStore.");
+ if (password == null)
+ {
+ Enumeration cs = certs.keys();
+
+ ASN1EncodableVector certSeq = new ASN1EncodableVector();
+
+ while (cs.hasMoreElements())
+ {
+ try
+ {
+ String certId = (String)cs.nextElement();
+ Certificate cert = (Certificate)certs.get(certId);
+
+ SafeBag sBag = createSafeBag(certId, cert);
+
+ certSeq.add(sBag);
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new IOException("Error encoding certificate: " + e.toString());
+ }
+ }
+
+ if (useDEREncoding)
+ {
+ ContentInfo bagInfo = new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DERSequence(certSeq).getEncoded()));
+
+ Pfx pfx = new Pfx(new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DERSequence(bagInfo).getEncoded())), null);
+
+ pfx.encodeTo(stream, ASN1Encoding.DER);
+ }
+ else
+ {
+ ContentInfo bagInfo = new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(new BERSequence(certSeq).getEncoded()));
+
+ Pfx pfx = new Pfx(new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(new BERSequence(bagInfo).getEncoded())), null);
+
+ pfx.encodeTo(stream, ASN1Encoding.BER);
+ }
+
+ return;
+ }
+ }
+ else
+ {
+ if (password == null)
+ {
+ throw new NullPointerException("no password supplied for PKCS#12 KeyStore");
+ }
}
//
@@ -1500,66 +1542,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 +1633,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 +1666,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 +1871,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 e8ab2754..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);
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 f1d1366a..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
@@ -440,13 +440,8 @@ public final class DESede
// 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");
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 34e9de51..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;
@@ -55,6 +56,7 @@ public class PBEPBKDF2
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
}
@@ -98,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());
@@ -608,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
*/
@@ -649,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 5e91663b..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;
@@ -82,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
{
@@ -105,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/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/provider/BouncyCastleProvider.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/jce/provider/BouncyCastleProvider.java
index 1c543ba3..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
@@ -15,6 +15,8 @@ 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;
@@ -32,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:
@@ -61,7 +64,7 @@ import com.android.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConver
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";
@@ -69,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
*/
@@ -107,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"
};
@@ -126,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",
};
@@ -157,7 +163,7 @@ public final class BouncyCastleProvider extends Provider
@android.compat.annotation.UnsupportedAppUsage
public BouncyCastleProvider()
{
- super(PROVIDER_NAME, 1.61, info);
+ super(PROVIDER_NAME, 1.68, info);
AccessController.doPrivileged(new PrivilegedAction()
{
@@ -190,6 +196,7 @@ public final class BouncyCastleProvider extends Provider
loadAlgorithms(SECURE_RANDOM_PACKAGE, SECURE_RANDOMS);
loadPQCKeys(); // so we can handle certificates containing them.
+
//
// X509Store
//
@@ -202,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
//
@@ -226,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");
@@ -266,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
@@ -316,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();)
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/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 6fcc6099..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,9 +46,16 @@ 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 {
@@ -127,7 +137,8 @@ public class PKIXCertPathValidatorSpi
//
// (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,6 +311,19 @@ 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--)
@@ -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 911d9025..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;
@@ -168,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)
{
@@ -197,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/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/PemReader.java b/repackaged/bcprov/src/main/java/com/android/org/bouncycastle/util/io/pem/PemReader.java
index 2ce8c069..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
@@ -44,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/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/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_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
index 9378fd49..38a6d582 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1BitString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1BitString.java
index e3ae7c46..001dd61d 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1BitString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1BitString.java
@@ -1,7 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1;
-import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
@@ -102,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.
*
@@ -114,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)
{
@@ -136,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]);
@@ -166,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;
}
@@ -200,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()
@@ -215,10 +228,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))
@@ -227,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)
@@ -264,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);
}
@@ -289,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Boolean.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Boolean.java
index d6f4dd75..80d935ac 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Boolean.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Boolean.java
@@ -3,12 +3,10 @@ package com.android.internal.org.bouncycastle.asn1;
import java.io.IOException;
-import com.android.internal.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.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1EncodableVector.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1EncodableVector.java
index 56817e2f..aabcc624 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1EncodableVector.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1EncodableVector.java
@@ -1,45 +1,89 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.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
*/
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;
}
/**
@@ -50,7 +94,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];
}
/**
@@ -60,6 +109,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Enumerated.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Enumerated.java
index b17af845..d95d62e7 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Enumerated.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Enumerated.java
@@ -5,7 +5,6 @@ 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 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.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1External.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1External.java
index cdf6bf1f..4f6aa4c1 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1External.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1External.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1GeneralizedTime.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1GeneralizedTime.java
index a0b6d447..5e755543 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1GeneralizedTime.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1GeneralizedTime.java
@@ -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_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
index 43af5218..29c5bc4a 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1InputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1InputStream.java
index 3b3e9bcf..482fcff9 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1InputStream.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1InputStream.java
@@ -111,7 +111,7 @@ public class ASN1InputStream
protected int readLength()
throws IOException
{
- return readLength(this, limit);
+ return readLength(this, limit, false);
}
protected void readFully(
@@ -141,7 +141,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)
{
@@ -162,12 +162,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);
@@ -178,12 +186,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");
}
@@ -192,26 +200,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
{
@@ -325,7 +330,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();
@@ -367,9 +372,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);
}
}
@@ -380,47 +385,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/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Integer.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Integer.java
index 692ae8f0..d09e3436 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Integer.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Integer.java
@@ -14,7 +14,11 @@ import com.android.internal.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.
@@ -77,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;
}
/**
@@ -88,10 +92,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;
}
/**
@@ -116,62 +120,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.internal.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()
@@ -184,27 +203,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))
{
@@ -213,7 +222,7 @@ public class ASN1Integer
ASN1Integer other = (ASN1Integer)o;
- return Arrays.areEqual(bytes, other.bytes);
+ return Arrays.areEqual(this.bytes, other.bytes);
}
public String toString()
@@ -221,4 +230,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.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
index e8840f7b..d47488ee 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Null.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Null.java
@@ -75,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Object.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Object.java
index 5d58b5e1..adcd257a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Object.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Object.java
@@ -3,6 +3,7 @@ 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;
@@ -13,20 +14,26 @@ import com.android.internal.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();
}
@@ -37,30 +44,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()
@@ -86,6 +74,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.
@@ -94,6 +84,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ObjectIdentifier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
index f92ccebf..0a0eac7a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
@@ -177,7 +177,7 @@ public class ASN1ObjectIdentifier
{
if (identifier == null)
{
- throw new IllegalArgumentException("'identifier' cannot be null");
+ throw new NullPointerException("'identifier' cannot be null");
}
if (!isValidIdentifier(identifier))
{
@@ -331,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()
@@ -371,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OctetString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OctetString.java
index 99f3b23a..f7b9617a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OctetString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OctetString.java
@@ -107,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.
*
@@ -146,7 +196,7 @@ public abstract class ASN1OctetString
{
try
{
- return ASN1OctetString.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
+ return getInstance(fromByteArray((byte[])obj));
}
catch (IOException e)
{
@@ -176,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;
}
@@ -244,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OutputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OutputStream.java
index 74719241..7447d3b3 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OutputStream.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1OutputStream.java
@@ -3,6 +3,7 @@ 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.
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Primitive.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Primitive.java
index 46c11456..f8dafff4 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Primitive.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Primitive.java
@@ -2,6 +2,7 @@
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.
@@ -12,7 +13,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);
}
/**
@@ -54,7 +64,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;
}
@@ -94,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Sequence.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Sequence.java
index 95883aba..afbb74f7 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Sequence.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Sequence.java
@@ -4,7 +4,7 @@ package com.android.internal.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.internal.org.bouncycastle.util.Arrays;
@@ -62,7 +62,8 @@ public abstract class ASN1Sequence
extends ASN1Primitive
implements com.android.internal.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.
@@ -116,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
@@ -124,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());
}
/**
@@ -173,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();
@@ -260,12 +287,12 @@ public abstract class ASN1Sequence
public ASN1Primitive getLoadedObject()
{
- return outer;
+ return ASN1Sequence.this;
}
-
+
public ASN1Primitive toASN1Primitive()
{
- return outer;
+ return ASN1Sequence.this;
}
};
}
@@ -276,10 +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.
*/
- public ASN1Encodable getObjectAt(
- int index)
+ public ASN1Encodable getObjectAt(int index)
{
- return (ASN1Encodable)seq.elementAt(index);
+ return elements[index];
}
/**
@@ -289,80 +315,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);
}
/**
@@ -371,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()
@@ -383,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Set.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Set.java
index 0ef3ba6c..110d200b 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Set.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1Set.java
@@ -4,7 +4,7 @@ package com.android.internal.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.internal.org.bouncycastle.util.Arrays;
@@ -100,8 +100,8 @@ public abstract class ASN1Set
extends ASN1Primitive
implements com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1StreamParser.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1StreamParser.java
index c34e1551..888a2f66 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1StreamParser.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1StreamParser.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObject.java
index 54fd1d67..c0f96273 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObject.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1TaggedObject.java
@@ -13,10 +13,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,
@@ -24,7 +23,7 @@ public abstract class ASN1TaggedObject
{
if (explicit)
{
- return (ASN1TaggedObject)obj.getObject();
+ return getInstance(obj.getObject());
}
throw new IllegalArgumentException("implicitly tagged tagged object");
@@ -35,7 +34,7 @@ public abstract class ASN1TaggedObject
{
if (obj == null || obj instanceof ASN1TaggedObject)
{
- return (ASN1TaggedObject)obj;
+ return (ASN1TaggedObject)obj;
}
else if (obj instanceof byte[])
{
@@ -67,82 +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);
}
-
+
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();
}
/**
@@ -169,11 +125,6 @@ public abstract class ASN1TaggedObject
return explicit;
}
- public boolean isEmpty()
- {
- return empty;
- }
-
/**
* Return whatever was following the tag.
* <p>
@@ -183,12 +134,7 @@ public abstract class ASN1TaggedObject
*/
public ASN1Primitive getObject()
{
- if (obj != null)
- {
- return obj.toASN1Primitive();
- }
-
- return null;
+ return obj.toASN1Primitive();
}
/**
@@ -234,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UTCTime.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UTCTime.java
index e47fcbf4..7bd92981 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UTCTime.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ASN1UTCTime.java
@@ -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_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
index 72636951..cb5023a7 100644
--- 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
@@ -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_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
index 11789286..5cc2da0c 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERGenerator.java
index 5ae19783..fa9f0df7 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERGenerator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERGenerator.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetString.java
index 1966b99f..8710d814 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetString.java
@@ -4,7 +4,7 @@ package com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringGenerator.java
index 8d3d6a1f..877563d1 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringGenerator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BEROctetStringGenerator.java
@@ -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_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
index 6e731f07..eee12a12 100644
--- 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
@@ -1,53 +1,23 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequence.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequence.java
index d4788e9b..e3770e48 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequence.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSequence.java
@@ -2,7 +2,6 @@
package com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSet.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSet.java
index 547c7bae..fbc6fd13 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSet.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERSet.java
@@ -2,7 +2,6 @@
package com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObject.java
index 42cd2e18..3c301b7e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObject.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/BERTaggedObject.java
@@ -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_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
index 9042c9c4..bde1f86f 100644
--- 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
@@ -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_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
index 03ab923c..f3e45898 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBMPString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBMPString.java
index c93b85a1..9ffb1bec 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBMPString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBMPString.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBitString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBitString.java
index 85275648..40d010ac 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBitString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBitString.java
@@ -65,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);
}
/**
@@ -125,17 +114,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBoolean.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBoolean.java
deleted file mode 100644
index 0b6f8b7f..00000000
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERBoolean.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/* GENERATED SOURCE. DO NOT MODIFY. */
-package com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternal.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternal.java
index 0357b1c8..da29a777 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternal.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERExternal.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERFactory.java
index df38995d..e4dc5f62 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERFactory.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERFactory.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralString.java
index 690a9457..660923d5 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralString.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralizedTime.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralizedTime.java
index a3c4be83..448f169f 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralizedTime.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGeneralizedTime.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGraphicString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGraphicString.java
index 1a5a2a73..779c899b 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGraphicString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERGraphicString.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERIA5String.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERIA5String.java
index df90706f..7cdb97b5 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERIA5String.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERIA5String.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNull.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNull.java
index d0803458..e86c7838 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNull.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNull.java
@@ -16,11 +16,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()
{
}
@@ -34,10 +30,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNumericString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNumericString.java
index 5907975e..a573f31f 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNumericString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERNumericString.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetString.java
index b8f5dfab..7b2dc381 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROctetString.java
@@ -43,18 +43,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROutputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROutputStream.java
index 2606c2a5..6e08148d 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROutputStream.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DEROutputStream.java
@@ -8,30 +8,22 @@ 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)
+ 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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERPrintableString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERPrintableString.java
index 505d509b..e885eb7d 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERPrintableString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERPrintableString.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequence.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequence.java
index bbfc9c5e..d1593ef8 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequence.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSequence.java
@@ -2,7 +2,6 @@
package com.android.internal.org.bouncycastle.asn1;
import java.io.IOException;
-import java.util.Enumeration;
/**
* Definite length SEQUENCE, encoding tells explicit number of bytes
@@ -14,6 +13,11 @@ import java.util.Enumeration;
public class DERSequence
extends ASN1Sequence
{
+ public static DERSequence convert(ASN1Sequence seq)
+ {
+ return (DERSequence)seq.toDERObject();
+ }
+
private int bodyLength = -1;
/**
@@ -25,56 +29,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();
@@ -89,21 +93,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_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
index b4020763..a0235928 100644
--- 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
@@ -4,7 +4,7 @@ package com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSet.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSet.java
index ca4f60ca..d6914adb 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSet.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERSet.java
@@ -2,7 +2,6 @@
package com.android.internal.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,63 +33,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();
@@ -100,21 +97,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_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
index 38c30dd3..f640c3c5 100644
--- 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
@@ -4,7 +4,7 @@ package com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERT61String.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERT61String.java
index 06f2deee..2dad092f 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERT61String.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERT61String.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERTaggedObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERTaggedObject.java
index 57f907f4..201a7eda 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERTaggedObject.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERTaggedObject.java
@@ -12,8 +12,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.
@@ -34,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUTF8String.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUTF8String.java
index b32752c0..d5f753a3 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUTF8String.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUTF8String.java
@@ -131,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUniversalString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUniversalString.java
index 016a53a2..b4c2a16e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUniversalString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERUniversalString.java
@@ -1,7 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVideotexString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVideotexString.java
index f57bd36a..155d5466 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVideotexString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVideotexString.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVisibleString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVisibleString.java
index a2db52da..e402c13e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVisibleString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DERVisibleString.java
@@ -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_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
index 96989595..174ef829 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLBitString.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLBitString.java
index a2514220..cb72e952 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLBitString.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLBitString.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLExternal.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLExternal.java
index 6439b9ec..5d8c6191 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLExternal.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLExternal.java
@@ -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_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
index b8df994b..99a0abd4 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLOutputStream.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLOutputStream.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequence.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequence.java
index 27373bb8..b4a770f8 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequence.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSequence.java
@@ -2,7 +2,6 @@
package com.android.internal.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_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
index e4ea3aa2..543b4f92 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSet.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLSet.java
@@ -2,7 +2,6 @@
package com.android.internal.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_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
index 68cb4c75..c6904a4b 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLTaggedObject.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DLTaggedObject.java
@@ -12,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DefiniteLengthInputStream.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DefiniteLengthInputStream.java
index d1c3e2e8..f951b426 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DefiniteLengthInputStream.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/DefiniteLengthInputStream.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyConstructionEnumeration.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyConstructionEnumeration.java
index dbabb17b..31ba8971 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyConstructionEnumeration.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyConstructionEnumeration.java
@@ -3,6 +3,7 @@ package com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyEncodedSequence.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyEncodedSequence.java
index be9aaa6a..cd914ee7 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyEncodedSequence.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/LazyEncodedSequence.java
@@ -3,6 +3,7 @@ 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.
@@ -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_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
index 6b525b24..a4b51950 100644
--- 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
@@ -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_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
index 4411a478..4795bbd9 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
index 0c8980e0..4310f102 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
@@ -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_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
index 55e26e62..979108c8 100644
--- 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
@@ -11,7 +11,7 @@ import com.android.internal.org.bouncycastle.asn1.ASN1Set;
import com.android.internal.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_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
index 8e769394..56edaf51 100644
--- 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
@@ -9,7 +9,7 @@ import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
import com.android.internal.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_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
index 6b85d5b1..9c6427b0 100644
--- 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
@@ -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_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
index 641ce37e..2bc8e778 100644
--- 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
@@ -6,8 +6,8 @@ import com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/ContentInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/ContentInfo.java
index 85bbb28a..51bbd3ea 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/ContentInfo.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/ContentInfo.java
@@ -12,8 +12,8 @@ import com.android.internal.org.bouncycastle.asn1.BERSequence;
import com.android.internal.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_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
index ee12a4b8..e08c5a28 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/GCMParameters.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/cms/GCMParameters.java
@@ -12,7 +12,7 @@ import com.android.internal.org.bouncycastle.asn1.DERSequence;
import com.android.internal.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_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
index db92e3f0..6c15b2bc 100644
--- 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
@@ -15,7 +15,7 @@ import com.android.internal.org.bouncycastle.asn1.x509.X509CertificateStructure;
import com.android.internal.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_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
index 18f37ebb..dda5b4d4 100644
--- 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
@@ -17,7 +17,7 @@ import com.android.internal.org.bouncycastle.asn1.BERTaggedObject;
import com.android.internal.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_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
index 53b66ec4..fdc2d9b8 100644
--- 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
@@ -10,7 +10,7 @@ import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
import com.android.internal.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_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
index 1b658a2c..32fc718c 100644
--- 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
@@ -17,7 +17,7 @@ import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
import com.android.internal.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_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
index 1a5f1530..ed1b3717 100644
--- 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
@@ -19,7 +19,7 @@ import com.android.internal.org.bouncycastle.asn1.DERGeneralizedTime;
import com.android.internal.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_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
index 33a4195a..798f8a1a 100644
--- 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
@@ -6,7 +6,7 @@ import com.android.internal.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_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
index 370a2256..3cca440c 100644
--- 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
@@ -7,10 +7,10 @@ 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="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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
index 18c020cd..2f69ddea 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
index 350ff273..db60cf09 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
@@ -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_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
index 244048a1..5ba6bbbd 100644
--- 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
@@ -4,7 +4,7 @@ package com.android.internal.org.bouncycastle.asn1.ntt;
import com.android.internal.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_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
index b32a578b..7bc4eebf 100644
--- 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
@@ -12,6 +12,14 @@ 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
@@ -101,7 +109,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/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
index 06b1b035..a209ed46 100644
--- 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
@@ -97,7 +97,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/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CrlID.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CrlID.java
index d9ac95b2..403a4aca 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CrlID.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/CrlID.java
@@ -92,7 +92,7 @@ public class CrlID
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(3);
if (crlUrl != null)
{
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
index 1698ec1d..8203dcf9 100644
--- 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
@@ -4,7 +4,7 @@ package com.android.internal.org.bouncycastle.asn1.ocsp;
import com.android.internal.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.
* @hide This class is not part of the Android public SDK API
*/
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPRequest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/OCSPRequest.java
index 38c4ab1e..48b98bb7 100644
--- 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
@@ -80,7 +80,7 @@ public class OCSPRequest
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(tbsRequest);
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
index a1d51733..f54ca405 100644
--- 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
@@ -10,8 +10,17 @@ 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
{
@@ -80,7 +89,7 @@ public class OCSPResponse
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(responseStatus);
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
index aa301e58..8c6308c7 100644
--- 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
@@ -7,7 +7,22 @@ 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
@@ -23,6 +38,8 @@ public class OCSPResponseStatus
private ASN1Enumerated value;
/**
+ * RFC 2560, RFC 6960
+ * <p>
* The OCSPResponseStatus enumeration.
* <pre>
* OCSPResponseStatus ::= ENUMERATED {
@@ -63,6 +80,11 @@ public class OCSPResponseStatus
return null;
}
+ public int getIntValue()
+ {
+ return value.intValueExact();
+ }
+
public BigInteger getValue()
{
return value.getValue();
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
index df836651..039c28d0 100644
--- 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
@@ -81,7 +81,7 @@ public class Request
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(reqCert);
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponseBytes.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponseBytes.java
index 1f5eccf2..2480e2f3 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponseBytes.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/ResponseBytes.java
@@ -11,6 +11,12 @@ 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
@@ -79,7 +85,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/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
index 9aae08b6..24af4927 100644
--- 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
@@ -14,6 +14,15 @@ 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
@@ -165,7 +174,7 @@ public class ResponseData
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(5);
if (versionPresent || !version.equals(V1))
{
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/RevokedInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/RevokedInfo.java
index c75b9d84..7c6b7b92 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/RevokedInfo.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/ocsp/RevokedInfo.java
@@ -83,7 +83,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/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
index d1fc0ada..3d5a4821 100644
--- 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
@@ -100,7 +100,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/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
index 74e37302..297c716d 100644
--- 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
@@ -145,7 +145,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/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
index 4787da3d..74d7c3e4 100644
--- 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
@@ -148,7 +148,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/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
index c3b80d2c..2114df52 100644
--- 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
@@ -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_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
index 0df396cb..cdf87d02 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CRLBag.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CRLBag.java
index 68d6f483..a12a870d 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CRLBag.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CRLBag.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertBag.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertBag.java
index 70ba1052..60f7506c 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertBag.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertBag.java
@@ -7,6 +7,7 @@ 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;
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequest.java
index 8f1db499..b3ee00e3 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequest.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequest.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
index 20f206c5..bce5f0e6 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/ContentInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/ContentInfo.java
index 0ee82e09..ed6988d5 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/ContentInfo.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/ContentInfo.java
@@ -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_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
index 196c5a9a..4cafc7db 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedData.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedData.java
index d9eb0258..600b9d2e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedData.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedData.java
@@ -57,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
index ec73cbe6..47c61003 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/EncryptedPrivateKeyInfo.java
@@ -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_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
index 00e98809..d88f45a3 100644
--- 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
@@ -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_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
index 68505430..63c01547 100644
--- 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
@@ -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_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
index 9cfd35d9..1ac91122 100644
--- 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
@@ -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_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
index 5be343a8..0f4a9d4b 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBKDF2Params.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
index ce632e79..82a22eca 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
@@ -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_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
index 21ccc37a..d7c4d0b0 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
index af8a6302..040a1c26 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
@@ -263,6 +263,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)}
@@ -294,7 +337,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");
@@ -311,40 +354,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/Pfx.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/Pfx.java
index c88c34d6..a7825003 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/Pfx.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/Pfx.java
@@ -1,8 +1,6 @@
/* 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;
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
index 5a226bbc..9d8e99d7 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/PrivateKeyInfo.java
@@ -2,7 +2,6 @@
package com.android.internal.org.bouncycastle.asn1.pkcs;
import java.io.IOException;
-import java.math.BigInteger;
import java.util.Enumeration;
import com.android.internal.org.bouncycastle.asn1.ASN1BitString;
@@ -90,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(
@@ -178,6 +177,11 @@ public class PrivateKeyInfo
}
}
+ public ASN1Integer getVersion()
+ {
+ return version;
+ }
+
public ASN1Set getAttributes()
{
return attributes;
@@ -188,6 +192,11 @@ public class PrivateKeyInfo
return privateKeyAlgorithm;
}
+ public ASN1OctetString getPrivateKey()
+ {
+ return new DEROctetString(privateKey.getOctets());
+ }
+
public ASN1Encodable parsePrivateKey()
throws IOException
{
@@ -230,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
index 25d31709..6cd16150 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java
@@ -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_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
index f1732069..95b4d04f 100644
--- 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
@@ -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_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
index 6ff89d87..2cf4a2a1 100644
--- 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
@@ -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_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
index b5abf915..a1a8e529 100644
--- 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
@@ -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_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
index bbea15da..3a5157c2 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/SafeBag.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/SafeBag.java
index 3b34333f..93fec390 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/SafeBag.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/pkcs/SafeBag.java
@@ -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_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
index 9ff835d3..9aa084f1 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKey.java
index 640393a2..e8b76a7b 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKey.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKey.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java
index d2bd3c54..4cb9eab1 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/ECPrivateKeyStructure.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/SECNamedCurves.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/SECNamedCurves.java
index ea78ab4d..31cbd7ff 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/SECNamedCurves.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/sec/SECNamedCurves.java
@@ -11,8 +11,10 @@ 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;
@@ -21,6 +23,13 @@ import com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/util/ASN1Dump.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/util/ASN1Dump.java
index e904391a..786d4842 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/util/ASN1Dump.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/util/ASN1Dump.java
@@ -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_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
index 5c68a357..413343a7 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/RDN.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/RDN.java
index efcca209..fc078820 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/RDN.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/RDN.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500Name.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500Name.java
index 63a4a226..ed3f3789 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500Name.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/X500Name.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
index 7e36d8df..3580944a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStyle.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStyle.java
index 1cc99148..e320f828 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStyle.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/BCStyle.java
@@ -47,6 +47,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();
@@ -58,7 +59,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))
@@ -79,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)
*/
@@ -99,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
@@ -207,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");
@@ -216,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");
@@ -241,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);
@@ -252,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);
@@ -347,6 +355,4 @@ public class BCStyle
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
index fb78084f..130a589e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/IETFUtils.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x500/style/IETFUtils.java
@@ -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_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
index c5da2d93..99fd6e31 100644
--- 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
@@ -96,7 +96,7 @@ public class AlgorithmIdentifier
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
v.add(algorithm);
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
index be633540..d23cf793 100644
--- 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
@@ -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_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
index 4ac78b5f..25f5bd3d 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificate.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificate.java
index 4ff69d41..11488623 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificate.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificate.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java
index 8d54f215..db94e6f1 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AttributeCertificateInfo.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
index 808803ac..23ae0c71 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/AuthorityKeyIdentifier.java
@@ -38,9 +38,9 @@ import com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/BasicConstraints.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/BasicConstraints.java
index c23f92ea..54cb6b78 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/BasicConstraints.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/BasicConstraints.java
@@ -49,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(
@@ -137,7 +137,7 @@ public class BasicConstraints
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector(2);
if (cA != null)
{
@@ -156,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_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
index 561b1ca7..ab7fd7bb 100644
--- 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
@@ -1,7 +1,6 @@
/* 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;
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLReason.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLReason.java
index f446b9e3..10552814 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLReason.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CRLReason.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CertificateList.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CertificateList.java
index 2b18089b..218a6237 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CertificateList.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/CertificateList.java
@@ -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_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
index 6ef3ea72..954ab397 100644
--- 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
@@ -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_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
index b829a596..58d4e270 100644
--- 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
@@ -79,7 +79,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DistributionPoint.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DistributionPoint.java
index 542ea062..4d3b786c 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DistributionPoint.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/DistributionPoint.java
@@ -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_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
index de1190b8..31e60566 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extension.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extension.java
index fdb23a6d..548f9302 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extension.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extension.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extensions.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extensions.java
index a2908943..0d5cec18 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extensions.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Extensions.java
@@ -15,6 +15,14 @@ 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ExtensionsGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
index 0cab859d..7f9db5fa 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralName.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralName.java
index 0a2f9411..779009a0 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralName.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralName.java
@@ -188,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);
}
}
@@ -429,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_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
index c32fc0eb..6b6a7ce1 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralSubtree.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralSubtree.java
index ac4e0704..64773c66 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralSubtree.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/GeneralSubtree.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Holder.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Holder.java
index 72b0db91..9a4eed12 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Holder.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/Holder.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuerSerial.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuerSerial.java
index 8eea0010..0c5aba5f 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuerSerial.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuerSerial.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
index 8661418a..43d1c23b 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyPurposeId.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyPurposeId.java
index 1d681604..0aac42b6 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyPurposeId.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyPurposeId.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyUsage.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyUsage.java
index 6205b18d..94433bf6 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyUsage.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/KeyUsage.java
@@ -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_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
index 981226f5..fea0b02e 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ObjectDigestInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
index abe1fbbb..e174f4c5 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/ObjectDigestInfo.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/OtherName.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/OtherName.java
index a2c7e039..098b21f5 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/OtherName.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/OtherName.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
index a5162a1a..70c7a58e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
@@ -13,7 +13,10 @@ 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;
@@ -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_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
index 3a81af58..f7224438 100644
--- 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
@@ -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_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
index aee5ef84..6ef7537f 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
index 8126c4c2..8b3fda34 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
@@ -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_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
index bd676a1c..d7df4554 100644
--- 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
@@ -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_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
index b9403790..ca1d7b0a 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
index f36e5c03..d26ac7b5 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
@@ -146,7 +146,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertList.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertList.java
index d0df1bb5..49e763fc 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertList.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertList.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificate.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificate.java
index e8968fd0..74e28279 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificate.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificate.java
@@ -3,13 +3,18 @@ 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.
@@ -93,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");
}
@@ -160,7 +165,7 @@ public class TBSCertificate
public int getVersionNumber()
{
- return version.getValue().intValue() + 1;
+ return version.intValueExact() + 1;
}
public ASN1Integer getVersion()
@@ -220,6 +225,69 @@ public class TBSCertificate
public ASN1Primitive toASN1Primitive()
{
- return seq;
+ 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
index f98de72c..5ae69dff 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificateStructure.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/TBSCertificateStructure.java
@@ -7,7 +7,6 @@ import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
import com.android.internal.org.bouncycastle.asn1.DERBitString;
-import com.android.internal.org.bouncycastle.asn1.DERTaggedObject;
import com.android.internal.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import com.android.internal.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_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
index 1771988a..85f7bed0 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V2Form.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V2Form.java
index 6724b507..110b9302 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V2Form.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V2Form.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java
index f9ec8b9c..2123bdcb 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator.java
@@ -166,7 +166,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);
@@ -176,12 +176,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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Extensions.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Extensions.java
index f099dd8f..2f3fbefd 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Extensions.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Extensions.java
@@ -16,7 +16,7 @@ import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
import com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Name.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Name.java
index b82fee6b..90652395 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Name.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509Name.java
@@ -378,7 +378,7 @@ public class X509Name
public static X509Name getInstance(
Object obj)
{
- if (obj == null || obj instanceof X509Name)
+ if (obj instanceof X509Name)
{
return (X509Name)obj;
}
@@ -930,7 +930,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);
@@ -947,8 +947,8 @@ public class X509Name
else
{
vec.add(new DERSet(sVec));
+
sVec = new ASN1EncodableVector();
-
sVec.add(new DERSequence(v));
}
@@ -1190,7 +1190,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/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509NameEntryConverter.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509NameEntryConverter.java
index e531f9f1..9329e674 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509NameEntryConverter.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509NameEntryConverter.java
@@ -3,11 +3,10 @@ package com.android.internal.org.bouncycastle.asn1.x509;
import java.io.IOException;
-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.DERPrintableString;
-import com.android.internal.org.bouncycastle.util.Strings;
+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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
index ad52e8ac..89e8a562 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
@@ -8,7 +8,6 @@ import com.android.internal.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_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
index 6cd6c53d..6206a0d9 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHValidationParms.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHValidationParms.java
index 72b8a57d..a2d4c8a5 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHValidationParms.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/DHValidationParms.java
@@ -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_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
index e87341bd..672a4460 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ECNamedCurveTable.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
index b957e28b..08ada94e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
@@ -9,12 +9,12 @@ import com.android.internal.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.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;
-import com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ValidationParams.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ValidationParams.java
index 4206c7d7..0e2329c8 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ValidationParams.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/ValidationParams.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962NamedCurves.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962NamedCurves.java
index 04e2b10d..7b82cc0c 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962NamedCurves.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962NamedCurves.java
@@ -7,6 +7,7 @@ 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;
@@ -17,25 +18,40 @@ import com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962Parameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962Parameters.java
index d77c6ab5..07808324 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962Parameters.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X962Parameters.java
@@ -1,8 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.asn1.x9;
-import java.io.IOException;
-
import com.android.internal.org.bouncycastle.asn1.ASN1Choice;
import com.android.internal.org.bouncycastle.asn1.ASN1Null;
import com.android.internal.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_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
index f2adedd9..bef641a2 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParameters.java
index 2a5f2ecd..58ca88b9 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParameters.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/asn1/x9/X9ECParameters.java
@@ -38,7 +38,7 @@ 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_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
index d975a312..42cf2834 100644
--- 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
@@ -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_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
index aa0d3f77..d28c460d 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesRegistrar.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesRegistrar.java
index 005a4226..7a337ce8 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesRegistrar.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/CryptoServicesRegistrar.java
@@ -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_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
index a5636552..7da35273 100644
--- 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
@@ -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_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/digests/SHA256Digest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA256Digest.java
index a1e395e2..2626336b 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA256Digest.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/digests/SHA256Digest.java
@@ -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_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
index e6692a0e..d2f0a3a8 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/ec/CustomNamedCurves.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/ec/CustomNamedCurves.java
@@ -23,6 +23,7 @@ import com.android.internal.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.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;
@@ -53,6 +54,7 @@ import com.android.internal.org.bouncycastle.math.ec.custom.sec.SecP521R1Curve;
// 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;
@@ -61,6 +63,13 @@ import com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/OAEPEncoding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/OAEPEncoding.java
index 5278e8d0..23fcdd6e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/OAEPEncoding.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/OAEPEncoding.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/PKCS1Encoding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
index 394e457e..aafbf6ed 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
@@ -1,8 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.org.bouncycastle.crypto.encodings;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.security.SecureRandom;
import com.android.internal.org.bouncycastle.crypto.AsymmetricBlockCipher;
@@ -12,6 +10,7 @@ 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESEngine.java
index be2fbff7..1ad46f64 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESEngine.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESEngine.java
@@ -12,7 +12,7 @@ import com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESFastEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESFastEngine.java
index 38fe1c48..71345c14 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESFastEngine.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESFastEngine.java
@@ -11,7 +11,7 @@ import com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESWrapEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESWrapEngine.java
index 6a54a93d..2b45af8c 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESWrapEngine.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/AESWrapEngine.java
@@ -5,7 +5,7 @@ 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="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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/BlowfishEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/BlowfishEngine.java
index 73ee165b..adbb0d34 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/BlowfishEngine.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/BlowfishEngine.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeWrapEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
index 91aa3667..d3ee6cad 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java
index f29cc070..ed18b615 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RFC3394WrapEngine.java
@@ -15,8 +15,8 @@ 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="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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSABlindedEngine.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSABlindedEngine.java
index 367f0d9e..14f6c2fd 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSABlindedEngine.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/engines/RSABlindedEngine.java
@@ -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_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
index 3ea79d1b..f10fa48b 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
index f5e34499..1b649ebc 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
@@ -6,7 +6,6 @@ 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.CryptoServicesRegistrar;
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;
@@ -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_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
index f9d4ec91..d9d39900 100644
--- 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
@@ -12,7 +12,7 @@ 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=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_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
index cd9d5e83..1e666239 100644
--- 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
@@ -13,7 +13,7 @@ import com.android.internal.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_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
index 2223874a..d26027fe 100644
--- 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
@@ -18,7 +18,7 @@ import com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
index ae4eb33d..86a62fe5 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
@@ -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_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
index 2673bff7..aa233b16 100644
--- 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
@@ -2,147 +2,18 @@
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;
/**
- * 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.internal.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.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/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/CCMBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CCMBlockCipher.java
index e0d2c5a1..f93c727b 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CCMBlockCipher.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CCMBlockCipher.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CFBBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CFBBlockCipher.java
index 916cbd23..d8f51e35 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CFBBlockCipher.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/CFBBlockCipher.java
@@ -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_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
index f5d9743f..73ff41dc 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMUtil.java
index a712b701..0797bca2 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMUtil.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/modes/gcm/GCMUtil.java
@@ -2,6 +2,7 @@
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;
/**
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java
index 456a5f1b..14c634a7 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java
@@ -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_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
index b36fcfea..d5c14d21 100644
--- 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
@@ -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_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
index 159a0dfc..009e91ad 100644
--- 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
@@ -4,6 +4,7 @@ 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
@@ -98,7 +99,7 @@ public class DHParameters
}
}
- if (m > p.bitLength())
+ 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");
}
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
index e9d5a96d..8f64d6b5 100644
--- 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
@@ -3,6 +3,9 @@ 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
*/
@@ -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_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
index c782c981..e461cad7 100644
--- 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
@@ -3,11 +3,13 @@ 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
@@ -15,13 +17,19 @@ import com.android.internal.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_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
index d62e8cf3..f45b269a 100644
--- 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
@@ -7,19 +7,24 @@ package com.android.internal.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_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
index 85055ae9..8929ee04 100644
--- 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
@@ -4,6 +4,7 @@ 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;
@@ -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_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
index ae4ff8b7..a5b07d24 100644
--- 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
@@ -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_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
index 7b3321b6..f858cade 100644
--- 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
@@ -9,19 +9,19 @@ import com.android.internal.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_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
index 1f8e8695..994aff49 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAKeyParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAKeyParameters.java
index e90097bc..c23d9f50 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAKeyParameters.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/params/RSAKeyParameters.java
@@ -3,12 +3,22 @@ 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;
@@ -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.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");
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSASigner.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSASigner.java
index 1594f2c3..0be6a4a6 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSASigner.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/DSASigner.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/ECDSASigner.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/ECDSASigner.java
index 710cca06..0216020a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/ECDSASigner.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/signers/ECDSASigner.java
@@ -19,6 +19,7 @@ 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
@@ -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_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
index 4ce4da89..cee94d63 100644
--- 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
@@ -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_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
index acc44924..4f4873a3 100644
--- 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
@@ -3,6 +3,8 @@ 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
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
index 18efee2d..b096efb9 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PrivateKeyFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PrivateKeyFactory.java
index eb943bc7..323d2c59 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PrivateKeyFactory.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PrivateKeyFactory.java
@@ -52,6 +52,7 @@ import com.android.internal.org.bouncycastle.crypto.params.RSAPrivateCrtKeyParam
// 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.
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PublicKeyFactory.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PublicKeyFactory.java
index 3cd04c63..9e1f295f 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PublicKeyFactory.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/crypto/util/PublicKeyFactory.java
@@ -66,6 +66,8 @@ import com.android.internal.org.bouncycastle.crypto.params.RSAKeyParameters;
// 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
@@ -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_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/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/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/PKIXCertStoreSelector.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/PKIXCertStoreSelector.java
index ba68cc60..d0a75cdd 100644
--- 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
@@ -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_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
index 68385368..ab85a390 100644
--- 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
@@ -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_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/provider/asymmetric/RSA.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
index f86a7a95..40c585ec 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/RSA.java
@@ -103,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);
@@ -286,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_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
index 441237bb..603c969d 100644
--- 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
@@ -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_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
index 00dc9329..943380ca 100644
--- 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
@@ -28,6 +28,7 @@ import com.android.internal.org.bouncycastle.crypto.params.DHPrivateKeyParameter
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;
@@ -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_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
index 3288df1e..0326ea11 100644
--- 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
@@ -25,6 +25,7 @@ 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
@@ -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_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
index cad5df5c..f7d7b5bc 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
index 50679fdb..cc30d173 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
@@ -2,6 +2,7 @@
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;
@@ -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_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
index 201f4f15..87c56f95 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
index 1c98a716..e9fe33f4 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
@@ -13,6 +13,7 @@ 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;
@@ -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.internal.org.bouncycastle.jce.spec.ECParameterSpec ecSpec = EC5Util.convertSpec(ecParameterSpec, false);
+ com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java
index 1574a21d..051e0b62 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java
@@ -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.internal.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.internal.org.bouncycastle.math.ec.ECPoint calculateQ(com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec spec)
- {
- return spec.getG().multiply(d).normalize();
- }
-
private DERBitString getPublicKeyDetails(BCECPublicKey pub)
{
try
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
index f9fb6f05..13e42f84 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
@@ -10,7 +10,6 @@ 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.ASN1OctetString;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
import com.android.internal.org.bouncycastle.asn1.DERBitString;
@@ -30,6 +29,7 @@ import com.android.internal.org.bouncycastle.jcajce.provider.config.ProviderConf
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
@@ -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.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
index fa0f1d5f..d07bebfd 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
@@ -11,6 +11,7 @@ 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;
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
index 5f9cfac7..87ea4794 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
@@ -25,6 +25,8 @@ import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.Bas
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;
@@ -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.internal.org.bouncycastle.jce.spec.ECPublicKeySpec(EC5Util.convertPoint(k.getParams(), k.getW(), false), EC5Util.convertSpec(k.getParams(), false));
+ 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(), false), implicitSpec);
+ 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)
@@ -121,7 +123,7 @@ public class KeyFactorySpi
if (k.getParams() != null)
{
- return new com.android.internal.org.bouncycastle.jce.spec.ECPrivateKeySpec(k.getS(), EC5Util.convertSpec(k.getParams(), false));
+ return new com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
index 10ae9837..0892390f 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java
@@ -22,6 +22,7 @@ import com.android.internal.org.bouncycastle.crypto.params.ECKeyGenerationParame
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;
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
index 6513b056..87ad7658 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
@@ -1,6 +1,7 @@
/* 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;
@@ -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_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
index cb0b02a2..e81dfec5 100644
--- 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
@@ -2,17 +2,18 @@
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.DERNull;
-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 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;
/**
@@ -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_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
index c7078260..7492e8df 100644
--- 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
@@ -11,7 +11,6 @@ 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.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.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.internal.org.bouncycastle.asn1.pkcs.RSAPrivateKey key)
+ 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()
@@ -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.internal.org.bouncycastle.asn1.pkcs.RSAPrivateKey(getModulus(), ZERO, getPrivateExponent(), ZERO, ZERO, ZERO, ZERO, ZERO));
+ 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)
@@ -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_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
index 149202e5..2c071517 100644
--- 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
@@ -22,20 +22,30 @@ import com.android.internal.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.internal.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_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
index 890876f9..53ccca49 100644
--- 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
@@ -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_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
index 6b9cbeeb..3b0d53e1 100644
--- 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
@@ -8,6 +8,9 @@ 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;
@@ -22,27 +25,33 @@ import com.android.internal.org.bouncycastle.jcajce.provider.asymmetric.util.Pri
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_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
index 2b4b83d6..98a1710a 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
index 1031b7a4..7eaea818 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
@@ -14,12 +14,16 @@ 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;
@@ -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.internal.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.internal.org.bouncycastle.jce.spec.ECParameterSpec convertSpec(
- ECParameterSpec ecSpec,
- boolean withCompression)
+ 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,
- convertPoint(curve, ecSpec.getGenerator(), withCompression),
- ecSpec.getOrder(),
- BigInteger.valueOf(ecSpec.getCofactor()),
- ecSpec.getCurve().getSeed());
+ 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,
- convertPoint(curve, ecSpec.getGenerator(), withCompression),
- ecSpec.getOrder(),
- BigInteger.valueOf(ecSpec.getCofactor()),
- ecSpec.getCurve().getSeed());
+ 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,
- boolean withCompression)
+ public static com.android.internal.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.internal.org.bouncycastle.math.ec.ECPoint convertPoint(
- ECCurve curve,
- ECPoint point,
- boolean withCompression)
+ public static com.android.internal.org.bouncycastle.math.ec.ECPoint convertPoint(ECCurve curve, ECPoint point)
{
return curve.createPoint(point.getAffineX(), point.getAffineY());
}
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
index 12ce9670..5d0ebfe4 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
@@ -1,10 +1,14 @@
/* 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;
@@ -28,6 +32,7 @@ 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;
@@ -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.internal.org.bouncycastle.math.ec.ECPoint q = calculateQ(d, spec);
+ 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);
@@ -396,11 +401,6 @@ public class ECUtil
return buf.toString();
}
- private static com.android.internal.org.bouncycastle.math.ec.ECPoint calculateQ(BigInteger d, com.android.internal.org.bouncycastle.jce.spec.ECParameterSpec spec)
- {
- return spec.getG().multiply(d).normalize();
- }
-
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();
@@ -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_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
index e57c6f80..5b5d0121 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
index 1729a2d4..25c42303 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
@@ -9,43 +9,64 @@ import com.android.internal.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_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
index d9417f6e..aac92316 100644
--- 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
@@ -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_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
index d72a1201..1eb9d66d 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java
@@ -1,682 +1,150 @@
/* 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.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.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.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.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.jcajce.util.JcaJceHelper;
-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)
- */
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.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;
- }
- }
+ 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_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
index 857a8395..39f0ff1d 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java
@@ -70,476 +70,140 @@ import com.android.internal.org.bouncycastle.util.Strings;
import com.android.internal.org.bouncycastle.util.encoders.Hex;
class X509CertificateObject
- extends X509Certificate
+ extends X509CertificateImpl
implements PKCS12BagAttributeCarrier
{
- private JcaJceHelper bcHelper;
- private com.android.internal.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.internal.org.bouncycastle.asn1.x509.Certificate c)
+ X509CertificateObject(JcaJceHelper bcHelper, com.android.internal.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.internal.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.internal.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.internal.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.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
index 5401cc6c..bcf9fb54 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
@@ -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.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 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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java
index bedc241d..8f8787f7 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java
index a2d23a47..da100c13 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/digest/BCMessageDigest.java
@@ -4,6 +4,8 @@ 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java
index 62e8a432..44be654a 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/bc/BcKeyStoreSpi.java
@@ -52,6 +52,8 @@ 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;
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java
index 44c46e0e..0788dac7 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java
@@ -3,7 +3,6 @@ package com.android.internal.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.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.BEROutputStream;
+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.DEROutputStream;
import com.android.internal.org.bouncycastle.asn1.DERSequence;
import com.android.internal.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,29 @@ public class PKCS12KeyStoreSpi
throw new IOException("error constructing MAC: " + e.toString());
}
}
+ else if (password != null)
+ {
+ if (!Properties.isOverrideSet("com.android.internal.org.bouncycastle.pkcs12.ignore_useless_passwd"))
+ {
+ throw new IOException("password supplied for keystore that does not require one");
+ }
+ }
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 +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++)
{
@@ -1312,9 +1306,57 @@ public class PKCS12KeyStoreSpi
private void doStore(OutputStream stream, char[] password, boolean useDEREncoding)
throws IOException
{
- if (password == null)
+ if (keys.size() == 0)
{
- throw new NullPointerException("No password supplied for PKCS#12 KeyStore.");
+ if (password == null)
+ {
+ Enumeration cs = certs.keys();
+
+ ASN1EncodableVector certSeq = new ASN1EncodableVector();
+
+ while (cs.hasMoreElements())
+ {
+ try
+ {
+ String certId = (String)cs.nextElement();
+ Certificate cert = (Certificate)certs.get(certId);
+
+ SafeBag sBag = createSafeBag(certId, cert);
+
+ certSeq.add(sBag);
+ }
+ catch (CertificateEncodingException e)
+ {
+ throw new IOException("Error encoding certificate: " + e.toString());
+ }
+ }
+
+ if (useDEREncoding)
+ {
+ ContentInfo bagInfo = new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DERSequence(certSeq).getEncoded()));
+
+ Pfx pfx = new Pfx(new ContentInfo(PKCSObjectIdentifiers.data, new DEROctetString(new DERSequence(bagInfo).getEncoded())), null);
+
+ pfx.encodeTo(stream, ASN1Encoding.DER);
+ }
+ else
+ {
+ ContentInfo bagInfo = new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(new BERSequence(certSeq).getEncoded()));
+
+ Pfx pfx = new Pfx(new ContentInfo(PKCSObjectIdentifiers.data, new BEROctetString(new BERSequence(bagInfo).getEncoded())), null);
+
+ pfx.encodeTo(stream, ASN1Encoding.BER);
+ }
+
+ return;
+ }
+ }
+ else
+ {
+ if (password == null)
+ {
+ throw new NullPointerException("no password supplied for PKCS#12 KeyStore");
+ }
}
//
@@ -1500,66 +1542,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 +1633,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 +1666,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 +1871,11 @@ public class PKCS12KeyStoreSpi
{
return orig.elements();
}
+
+ public int size()
+ {
+ return orig.size();
+ }
}
private static class DefaultSecretKeyProvider
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/AES.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/AES.java
index 6850b293..55510fd2 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/AES.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/AES.java
@@ -27,6 +27,7 @@ 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;
@@ -56,6 +57,7 @@ import com.android.internal.org.bouncycastle.jcajce.provider.symmetric.util.Base
// 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;
@@ -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);
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
index 2cbe3fd7..ea07f691 100644
--- 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
@@ -440,13 +440,8 @@ public final class DESede
// 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");
diff --git a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java
index e069d082..ab218e1f 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java
@@ -18,6 +18,7 @@ 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;
@@ -55,6 +56,7 @@ public class PBEPBKDF2
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
}
@@ -98,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());
@@ -608,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
*/
@@ -649,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_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
index 1a7d0ba0..66ad0d50 100644
--- 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
@@ -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_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
index 5f86d90a..0160099a 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java
index dbeab4bf..de352165 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BCPBEKey.java
@@ -1,31 +1,40 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.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.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
+ 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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java
index 51cca627..7eaf8ac8 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java
@@ -2,7 +2,6 @@
package com.android.internal.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.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;
@@ -40,6 +41,7 @@ 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;
@@ -83,6 +85,7 @@ 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;
/**
@@ -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.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
index 2d109ed7..c142c388 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
@@ -1,7 +1,6 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.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_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
index 852d2892..a1f9a8d8 100644
--- 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
@@ -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_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
index ebd3bc52..e70fe76f 100644
--- 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
@@ -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_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/PBE.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
index d631b658..52557652 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java
@@ -21,6 +21,7 @@ import com.android.internal.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.internal.org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator;
import com.android.internal.org.bouncycastle.crypto.generators.PKCS12ParametersGenerator;
import com.android.internal.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_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/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/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/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
index 897f8343..15130f26 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/BCJcaJceHelper.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jcajce/util/BCJcaJceHelper.java
@@ -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_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
index 550b082f..9a5edec8 100644
--- 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
@@ -3,16 +3,24 @@ 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;
@@ -82,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
{
@@ -105,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_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
index 6c8f0e49..8e459bc1 100644
--- 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
@@ -3,17 +3,25 @@ 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;
@@ -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_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
index dfd06591..090f009a 100644
--- 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
@@ -3,17 +3,25 @@ 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;
@@ -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_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
index bba92629..c6a6e516 100644
--- 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
@@ -3,17 +3,25 @@ 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;
@@ -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_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
index 3918d4b9..b19d5069 100644
--- 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
@@ -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_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
index 65410dcf..7541386f 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/BouncyCastleProvider.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/BouncyCastleProvider.java
index 59e0c564..2f3f1ea2 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/BouncyCastleProvider.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/BouncyCastleProvider.java
@@ -15,6 +15,8 @@ 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;
@@ -32,6 +34,7 @@ import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricKeyI
// 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:
@@ -61,7 +64,7 @@ import com.android.internal.org.bouncycastle.jcajce.provider.util.AsymmetricKeyI
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";
@@ -69,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
*/
@@ -107,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"
};
@@ -126,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",
};
@@ -156,7 +162,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()
{
@@ -189,6 +195,7 @@ public final class BouncyCastleProvider extends Provider
loadAlgorithms(SECURE_RANDOM_PACKAGE, SECURE_RANDOMS);
loadPQCKeys(); // so we can handle certificates containing them.
+
//
// X509Store
//
@@ -201,7 +208,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 +232,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.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");
@@ -265,15 +291,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 +341,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();)
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
index f4f165cd..4d19fe5a 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
index 606b7a06..e6aa3075 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
@@ -4,15 +4,18 @@ 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;
@@ -49,6 +52,7 @@ 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;
@@ -67,11 +71,15 @@ 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;
@@ -80,8 +88,6 @@ import com.android.internal.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.internal.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.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(); )
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPrivateKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPrivateKey.java
index 092b13e4..fd3fd5c1 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPrivateKey.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPrivateKey.java
@@ -29,6 +29,7 @@ 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;
@@ -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.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPublicKey.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPublicKey.java
index aa96510f..46cd2358 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPublicKey.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/JCEECPublicKey.java
@@ -15,7 +15,6 @@ 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.ASN1Sequence;
import com.android.internal.org.bouncycastle.asn1.DERBitString;
import com.android.internal.org.bouncycastle.asn1.DERNull;
import com.android.internal.org.bouncycastle.asn1.DEROctetString;
@@ -42,8 +41,6 @@ import com.android.internal.org.bouncycastle.jce.interfaces.ECPointEncoder;
// 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.math.ec.custom.sec.SecP256K1Point;
-import com.android.internal.org.bouncycastle.math.ec.custom.sec.SecP256R1Point;
import com.android.internal.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.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCRLUtil.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCRLUtil.java
index 40074b59..c5fec2b5 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCRLUtil.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/PKIXCRLUtil.java
@@ -17,18 +17,18 @@ import com.android.internal.org.bouncycastle.jcajce.PKIXCRLStoreSelector;
import com.android.internal.org.bouncycastle.util.Store;
import com.android.internal.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.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
- *
- * @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.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 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_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
index 88b7f85f..5a9df5f8 100644
--- 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
@@ -20,11 +20,9 @@ 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.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.asymmetric.x509.CertificateFactory;
-import com.android.internal.org.bouncycastle.jce.exception.ExtCertPathBuilderException;
import com.android.internal.org.bouncycastle.x509.ExtendedPKIXBuilderParameters;
import com.android.internal.org.bouncycastle.x509.ExtendedPKIXParameters;
@@ -37,6 +35,18 @@ import com.android.internal.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_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
index 1e4e5dc8..fe1bd4f3 100644
--- 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
@@ -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.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;
@@ -43,9 +46,16 @@ 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 {
@@ -127,7 +137,8 @@ public class PKIXCertPathValidatorSpi
//
// (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,6 +311,19 @@ 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--)
@@ -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_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
index 24a38d7e..74679123 100644
--- 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
@@ -1,1459 +1,62 @@
/* GENERATED SOURCE. DO NOT MODIFY. */
package com.android.internal.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.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.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.util.Arrays;
-import com.android.internal.org.bouncycastle.util.Integers;
-import com.android.internal.org.bouncycastle.util.Strings;
+import com.android.internal.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.internal.org.bouncycastle.asn1.x509.PKIXNameConstraintValidator validator = new com.android.internal.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_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
index f29377e4..ebcb3633 100644
--- 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
@@ -7,8 +7,22 @@ package com.android.internal.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_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
index a2a00525..9cd9a2b2 100644
--- 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
@@ -3,34 +3,20 @@ package com.android.internal.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.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 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_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
index 37fcf3da..64da5710 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/RFC3280CertPathUtilities.java
@@ -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.internal.org.bouncycastle.asn1.ASN1Encodable;
import com.android.internal.org.bouncycastle.asn1.ASN1EncodableVector;
-import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
import com.android.internal.org.bouncycastle.asn1.ASN1Primitive;
@@ -55,17 +54,19 @@ 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.PKIXCRLStoreSelector;
+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 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_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/X509CRLObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CRLObject.java
index 96d34355..e20ba04f 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CertificateObject.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CertificateObject.java
index 4d34408d..10c90b70 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CertificateObject.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/jce/provider/X509CertificateObject.java
@@ -1,7 +1,6 @@
/* 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.InetAddress;
@@ -38,7 +37,6 @@ 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;
@@ -167,26 +165,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)
{
@@ -196,19 +182,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_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/ECAlgorithms.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECAlgorithms.java
index 6f819a2a..c5bb0dd6 100644
--- 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
@@ -4,9 +4,11 @@ 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECCurve.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECCurve.java
index 176a9859..d936d107 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECCurve.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECCurve.java
@@ -2,6 +2,7 @@
package com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECFieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECFieldElement.java
index fb4cff0f..7e612ec0 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECFieldElement.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECFieldElement.java
@@ -4,10 +4,9 @@ package com.android.internal.org.bouncycastle.math.ec;
import java.math.BigInteger;
import java.util.Random;
-import com.android.internal.org.bouncycastle.math.raw.Mod;
-import com.android.internal.org.bouncycastle.math.raw.Nat;
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
@@ -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_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
index 37e36722..6323b0b8 100644
--- 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
@@ -8,4 +8,5 @@ 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/ECPoint.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/ECPoint.java
index 60db91ce..90eefc78 100644
--- 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
@@ -2,8 +2,11 @@
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
@@ -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_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
index 1a1101e3..19ffeca7 100644
--- 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
@@ -3,6 +3,7 @@ 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;
/**
@@ -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_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/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/WNafL2RMultiplier.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/WNafL2RMultiplier.java
index 04b785de..b6b44711 100644
--- 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
@@ -3,6 +3,8 @@ 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.
@@ -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_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
index 4a0dfecc..0505a466 100644
--- 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
@@ -8,6 +8,10 @@ package com.android.internal.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_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
index 25698176..e74c8fb5 100644
--- 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
@@ -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_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
index d8f410d7..21c4ad56 100644
--- 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
@@ -2,7 +2,9 @@
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;
@@ -16,10 +18,10 @@ import com.android.internal.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_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
index 022bdcbe..6d8ba91e 100644
--- 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
@@ -2,9 +2,12 @@
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
@@ -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_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
index b8d85305..39d8ef08 100644
--- 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
@@ -4,16 +4,17 @@ 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.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 = 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_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
index f06458f2..632f5710 100644
--- 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
@@ -12,56 +12,14 @@ import com.android.internal.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_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
index ec1c9cb7..c052ddec 100644
--- 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
@@ -2,7 +2,10 @@
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;
@@ -15,10 +18,10 @@ import com.android.internal.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_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
index b63e68e8..580aa328 100644
--- 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
@@ -2,9 +2,12 @@
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
@@ -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_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
index de86f91b..ac55d3b1 100644
--- 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
@@ -4,16 +4,17 @@ 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.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 = 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_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
index 915b3b44..9f96a0eb 100644
--- 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
@@ -12,55 +12,14 @@ import com.android.internal.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_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
index 6347218a..b1fc91dc 100644
--- 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
@@ -2,7 +2,9 @@
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;
@@ -16,10 +18,10 @@ import com.android.internal.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_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
index b013511c..437e3bda 100644
--- 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
@@ -2,9 +2,12 @@
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
@@ -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_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
index 4dad039f..96fea43b 100644
--- 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
@@ -4,16 +4,17 @@ 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.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 = 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_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
index a8ef860c..2e1017cb 100644
--- 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
@@ -12,56 +12,14 @@ import com.android.internal.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_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
index 16ca8bda..52ebc74c 100644
--- 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
@@ -2,7 +2,10 @@
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;
@@ -15,10 +18,10 @@ import com.android.internal.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_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
index 7737e9d5..cf24a779 100644
--- 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
@@ -2,9 +2,12 @@
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
@@ -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_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
index e6a45674..afe1a986 100644
--- 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
@@ -8,13 +8,15 @@ 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 = 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_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
index ece37770..9b8ccf6c 100644
--- 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
@@ -12,55 +12,14 @@ import com.android.internal.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_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
index 31d5b4c4..a39fc8a4 100644
--- 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
@@ -2,7 +2,9 @@
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;
@@ -16,10 +18,10 @@ import com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
index f8cdadaa..fd47d216 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java
@@ -2,9 +2,12 @@
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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
index eb6c123e..08218941 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java
@@ -4,16 +4,17 @@ 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.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 = 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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
index b3d17dae..283554e3 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java
@@ -12,56 +12,14 @@ import com.android.internal.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_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
index 54477c1d..9050b6cb 100644
--- 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
@@ -2,7 +2,10 @@
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;
@@ -15,10 +18,10 @@ import com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
index bbec4bce..b9cea7a8 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java
@@ -2,9 +2,12 @@
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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
index e373c766..3cfbea6c 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1FieldElement.java
@@ -4,16 +4,17 @@ 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.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 = 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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
index a7abfbd6..475624a0 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
@@ -12,55 +12,14 @@ import com.android.internal.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_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
index bf631679..a652b010 100644
--- 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
@@ -2,7 +2,10 @@
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;
@@ -15,10 +18,10 @@ import com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
index 524a78d5..c95f7599 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java
@@ -2,9 +2,12 @@
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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
index e58dea80..a2791d47 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1FieldElement.java
@@ -4,16 +4,17 @@ 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.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 = 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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
index 63b381ed..27b6aa51 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java
@@ -12,55 +12,14 @@ import com.android.internal.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_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
index 5a170b74..2a004079 100644
--- 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
@@ -2,7 +2,10 @@
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;
@@ -15,10 +18,10 @@ import com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
index d29f8201..d4780f3d 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java
@@ -2,9 +2,12 @@
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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
index f06233ab..4e524721 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1FieldElement.java
@@ -4,16 +4,17 @@ 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.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 = 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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java
index 2eef8e2b..3bb4f698 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java
@@ -11,55 +11,14 @@ import com.android.internal.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_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/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
index cdec5440..6471e248 100644
--- 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
@@ -3,7 +3,6 @@ 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.ECPointMap;
import com.android.internal.org.bouncycastle.math.ec.ScaleXPointMap;
@@ -13,28 +12,24 @@ import com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java
index ab49e0a5..94dd7faa 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java
@@ -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_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/FiniteFields.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/FiniteFields.java
index f3180764..45cc70f7 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/FiniteFields.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/field/FiniteFields.java
@@ -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_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
index 31e75530..1cd7c3b9 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Mod.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Mod.java
index dd821ff8..c6d6bece 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Mod.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Mod.java
@@ -3,15 +3,51 @@ package com.android.internal.org.bouncycastle.math.raw;
import java.util.Random;
-import com.android.internal.org.bouncycastle.util.Pack;
+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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat.java
index ed2d05e4..515ac476 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat.java
@@ -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_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
index 5ec313e9..2931d21d 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat224.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat224.java
index f93768bb..8f8423df 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat224.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat224.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat256.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat256.java
index 20ae3ad9..0771409b 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat256.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/math/raw/Nat256.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Arrays.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Arrays.java
index f83b0caf..3ce0b11b 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Arrays.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Arrays.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/BigIntegers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/BigIntegers.java
index 08ba17f4..62a5367c 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/BigIntegers.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/BigIntegers.java
@@ -4,6 +4,9 @@ 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
@@ -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_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/Integers.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Integers.java
index d5e348dc..09db1219 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Integers.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Integers.java
@@ -7,6 +7,26 @@ package com.android.internal.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_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/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
index dc149c1c..ef00137e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Pack.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Pack.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Properties.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Properties.java
index 34b528cd..4817548e 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Properties.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/Properties.java
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64Encoder.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64Encoder.java
index e7350080..cda38c11 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64Encoder.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/Base64Encoder.java
@@ -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_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
index b73f57d8..ad53cbf6 100644
--- 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
@@ -13,8 +13,8 @@ import com.android.internal.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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/HexEncoder.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/HexEncoder.java
index 5395fdaa..93ec0684 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/HexEncoder.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/encoders/HexEncoder.java
@@ -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_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
index 1e73bd0f..7f9f9871 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemReader.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemReader.java
index 76f88973..a192b36c 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemReader.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/util/io/pem/PemReader.java
@@ -44,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_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
index 62002457..8c340679 100644
--- 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
@@ -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_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
index 0100d06a..385bfa4f 100644
--- 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
@@ -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_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
index 93da538b..2074c0ca 100644
--- 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
@@ -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_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V2AttributeCertificate.java b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V2AttributeCertificate.java
index a9cbdf39..6ae4aeec 100644
--- a/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V2AttributeCertificate.java
+++ b/repackaged_platform/bcprov/src/main/java/com/android/internal/org/bouncycastle/x509/X509V2AttributeCertificate.java
@@ -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()