summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergio Giro <sgiro@google.com>2016-02-04 23:52:52 +0000
committerSergio Giro <sgiro@google.com>2016-02-10 22:41:50 +0000
commit79d3bf2425a53baab7feb744dad710b6c15533c9 (patch)
tree2cba8cee6020669038b6603397dbc80dd73aa9ce
parent013d8784e65adfe3af81f7ff010eddc17c0c332e (diff)
downloadbouncycastle-79d3bf2425a53baab7feb744dad710b6c15533c9.tar.gz
bouncycastle: upgrade to version 1.54
Merge remote-tracking branch 'aosp/upstream-master' (cherry picked from commit 4a2d5c40ffefaaa02c656a091f33fecdf8592607) Change-Id: Icd734732677bc8ed04d8cd78bbb686efa152ed58
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cert/X509AttributeCertificateHolder.java4
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java2
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java4
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/CMSAttributeTableGenerator.java14
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java61
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/CMSUtils.java106
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java7
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java10
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/PKCS7ProcessableObject.java65
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/PasswordRecipient.java2
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java12
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/SignerInformation.java93
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/openssl/CertificateTrustBlock.java132
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java16
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java45
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecific.java226
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1BitString.java291
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1Boolean.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1Choice.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1EncodableVector.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralizedTime.java1
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java10
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java108
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1Primitive.java11
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1Sequence.java13
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java14
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1String.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecific.java108
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecificParser.java20
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BERGenerator.java20
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BERSequence.java13
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BERSequenceParser.java22
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BERSet.java17
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BERSetParser.java22
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObjectParser.java34
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERApplicationSpecific.java233
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERBMPString.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java221
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DEREncodableVector.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERExternal.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERExternalParser.java28
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralString.java41
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERGraphicString.java124
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERIA5String.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERNumericString.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DEROctetString.java10
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DEROctetStringParser.java21
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERPrintableString.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERSequence.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERSet.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERUTF8String.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERVideotexString.java124
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERVisibleString.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DLBitString.java145
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DLSequence.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/InMemoryRepresentable.java1
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/OIDTokenizer.java17
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/AttributeTable.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/CMSAlgorithmProtection.java136
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/CMSAttributes.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/SignedData.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/cms/SignerInfo.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java29
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTNamedCurves.java48
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java13
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBES2Algorithms.java77
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java85
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java80
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/sec/SECNamedCurves.java90
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/sec/SECObjectIdentifiers.java21
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java18
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x500/AttributeTypeAndValue.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x500/DirectoryString.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x500/RDN.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x500/X500Name.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x500/X500NameBuilder.java58
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x500/X500NameStyle.java12
-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.java52
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x500/style/RFC4519Style.java86
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java76
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLDistPoint.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/DistributionPoint.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/DistributionPointName.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/Extension.java62
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtensionsGenerator.java17
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralNames.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyPurposeId.java10
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraintValidator.java18
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraintValidatorException.java10
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java1920
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyInformation.java31
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierId.java31
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java117
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertList.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java28
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/DHDomainParameters.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/DHPublicKey.java54
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/DHValidationParms.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/DomainParameters.java223
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java79
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java99
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/X962NamedCurves.java68
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/X962Parameters.java28
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParameters.java70
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParametersHolder.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECPoint.java42
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java17
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/digests/GeneralDigest.java37
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java504
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java32
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java167
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java156
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeWrapEngine.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/RSABlindedEngine.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java10
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAParametersGenerator.java120
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java132
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java36
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java177
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMUtil.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/DESedeParameters.java49
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/KDFParameters.java31
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/RC2Parameters.java14
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java59
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java22
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/PBKDFKey.java11
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/PKCS12Key.java82
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/PKCS12KeyWithParameters.java69
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStore.java12
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStoreSelector.java56
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStore.java12
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStoreSelector.java68
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedBuilderParameters.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedParameters.java12
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DH.java16
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java140
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/RSA.java107
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParametersSpi.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPrivateKey.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java100
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParametersSpi.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java167
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java37
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java48
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java45
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java468
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateCrtKey.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java1
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java25
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/KeyPairGeneratorSpi.java11
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java323
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java137
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java92
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java12
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLEntryObject.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CRLObject.java63
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java79
-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/SHA1.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java89
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java309
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/ARC4.java14
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java28
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DES.java26
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DESede.java22
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/GcmSpecUtil.java78
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/RC2.java34
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SymmetricAlgorithmProvider.java13
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Twofish.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java333
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java60
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseStreamCipher.java54
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java117
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/util/DigestFactory.java43
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/spec/PBKDF2KeySpec.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/spec/UserKeyingMaterialSpec.java21
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/util/AlgorithmParametersUtils.java68
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/util/JcaJceUtils.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/util/MessageDigestUtils.java63
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java20
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java14
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java17
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java31
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPublicKey.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPublicKey.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/JDKDSAPublicKey.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java19
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java20
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLEntryObject.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java54
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java42
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/spec/ECNamedCurveSpec.java38
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/Primes.java674
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/ECAlgorithms.java17
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/ECConstants.java1
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java413
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java29
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/ECPoint.java340
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/LongArray.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/Tnaf.java124
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/WTauNafMultiplier.java66
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/WTauNafPreCompInfo.java12
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1FieldElement.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Point.java10
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Point.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1FieldElement.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224K1Point.java10
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Point.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1FieldElement.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Point.java10
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Point.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Point.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeBEndomorphism.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/endo/GLVTypeBParameters.java49
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/raw/Nat.java40
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/raw/Nat192.java88
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/raw/Nat256.java89
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/Arrays.java88
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/IPAddress.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/Integers.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/Memoable.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/Pack.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/Properties.java36
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/Selector.java11
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/Store.java13
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/StoreException.java15
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/StringList.java20
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/Strings.java68
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/io/Streams.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/io/pem/PemWriter.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/x509/AttributeCertificateHolder.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/x509/X509Attribute.java1
-rw-r--r--bcprov/src/main/java/org/bouncycastle/x509/X509V1CertificateGenerator.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/x509/X509V2AttributeCertificate.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/x509/extension/AuthorityKeyIdentifierStructure.java21
-rw-r--r--bouncycastle.version2
265 files changed, 11358 insertions, 2972 deletions
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/X509AttributeCertificateHolder.java b/bcpkix/src/main/java/org/bouncycastle/cert/X509AttributeCertificateHolder.java
index c465c834..e6b0d7ec 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/X509AttributeCertificateHolder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/X509AttributeCertificateHolder.java
@@ -279,7 +279,7 @@ public class X509AttributeCertificateHolder
*/
public byte[] getSignature()
{
- return attrCert.getSignatureValue().getBytes();
+ return attrCert.getSignatureValue().getOctets();
}
/**
@@ -340,7 +340,7 @@ public class X509AttributeCertificateHolder
throw new CertException("unable to process signature: " + e.getMessage(), e);
}
- return verifier.verify(attrCert.getSignatureValue().getBytes());
+ return verifier.verify(this.getSignature());
}
public boolean equals(
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java b/bcpkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java
index 29c48fa6..4b773e2e 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/X509CRLHolder.java
@@ -291,7 +291,7 @@ public class X509CRLHolder
throw new CertException("unable to process signature: " + e.getMessage(), e);
}
- return verifier.verify(x509CRL.getSignature().getBytes());
+ return verifier.verify(x509CRL.getSignature().getOctets());
}
public boolean equals(
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java b/bcpkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java
index dc61c78f..b5ad578d 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/X509CertificateHolder.java
@@ -240,7 +240,7 @@ public class X509CertificateHolder
*/
public byte[] getSignature()
{
- return x509Certificate.getSignature().getBytes();
+ return x509Certificate.getSignature().getOctets();
}
/**
@@ -289,7 +289,7 @@ public class X509CertificateHolder
throw new CertException("unable to process signature: " + e.getMessage(), e);
}
- return verifier.verify(x509Certificate.getSignature().getBytes());
+ return verifier.verify(this.getSignature());
}
public boolean equals(
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/CMSAttributeTableGenerator.java b/bcpkix/src/main/java/org/bouncycastle/cms/CMSAttributeTableGenerator.java
index 528c738b..a38752c1 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/CMSAttributeTableGenerator.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/CMSAttributeTableGenerator.java
@@ -1,18 +1,20 @@
package org.bouncycastle.cms;
-import org.bouncycastle.asn1.cms.AttributeTable;
-
import java.util.Map;
+import org.bouncycastle.asn1.cms.AttributeTable;
+
/**
* Note: The SIGNATURE parameter is only available when generating unsigned attributes.
*/
public interface CMSAttributeTableGenerator
{
- static final String CONTENT_TYPE = "contentType";
- static final String DIGEST = "digest";
- static final String SIGNATURE = "encryptedDigest";
- static final String DIGEST_ALGORITHM_IDENTIFIER = "digestAlgID";
+ String CONTENT_TYPE = "contentType";
+ String DIGEST = "digest";
+ String SIGNATURE = "encryptedDigest";
+ String DIGEST_ALGORITHM_IDENTIFIER = "digestAlgID";
+ String MAC_ALGORITHM_IDENTIFIER = "macAlgID";
+ String SIGNATURE_ALGORITHM_IDENTIFIER = "signatureAlgID";
AttributeTable getAttributes(Map parameters)
throws CMSAttributeTableGenerationException;
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java b/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java
index 5ef95ee3..7f6d4a2c 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/CMSSignedData.java
@@ -5,10 +5,15 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
@@ -20,9 +25,8 @@ import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.cms.ContentInfo;
import org.bouncycastle.asn1.cms.SignedData;
import org.bouncycastle.asn1.cms.SignerInfo;
-import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.operator.OperatorCreationException;
-import org.bouncycastle.operator.SignatureAlgorithmIdentifierFinder;
import org.bouncycastle.util.Encodable;
import org.bouncycastle.util.Store;
@@ -184,11 +188,18 @@ public class CMSSignedData
// this can happen if the signed message is sent simply to send a
// certificate chain.
//
- if (signedData.getEncapContentInfo().getContent() != null)
+ ASN1Encodable content = signedData.getEncapContentInfo().getContent();
+ if (content != null)
{
- this.signedContent = new CMSProcessableByteArray(signedData.getEncapContentInfo().getContentType(),
- ((ASN1OctetString)(signedData.getEncapContentInfo()
- .getContent())).getOctets());
+ if (content instanceof ASN1OctetString)
+ {
+ this.signedContent = new CMSProcessableByteArray(signedData.getEncapContentInfo().getContentType(),
+ ((ASN1OctetString)content).getOctets());
+ }
+ else
+ {
+ this.signedContent = new PKCS7ProcessableObject(signedData.getEncapContentInfo().getContentType(), content);
+ }
}
else
{
@@ -231,7 +242,6 @@ public class CMSSignedData
{
ASN1Set s = signedData.getSignerInfos();
List signerInfos = new ArrayList();
- SignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder();
for (int i = 0; i != s.size(); i++)
{
@@ -258,6 +268,26 @@ public class CMSSignedData
}
/**
+ * Return if this is object represents a detached signature.
+ *
+ * @return true if this message represents a detached signature, false otherwise.
+ */
+ public boolean isDetachedSignature()
+ {
+ return signedData.getEncapContentInfo().getContent() == null && signedData.getSignerInfos().size() > 0;
+ }
+
+ /**
+ * Return if this is object represents a certificate management message.
+ *
+ * @return true if the message has no signers or content, false otherwise.
+ */
+ public boolean isCertificateManagementMessage()
+ {
+ return signedData.getEncapContentInfo().getContent() == null && signedData.getSignerInfos().size() == 0;
+ }
+
+ /**
* Return any X.509 certificate objects in this SignedData structure as a Store of X509CertificateHolder objects.
*
* @return a Store of X509CertificateHolder objects.
@@ -303,6 +333,23 @@ public class CMSSignedData
// END android-removed
/**
+ * Return the digest algorithm identifiers for the SignedData object
+ *
+ * @return the set of digest algorithm identifiers
+ */
+ public Set<AlgorithmIdentifier> getDigestAlgorithmIDs()
+ {
+ Set<AlgorithmIdentifier> digests = new HashSet<AlgorithmIdentifier>(signedData.getDigestAlgorithms().size());
+
+ for (Enumeration en = signedData.getDigestAlgorithms().getObjects(); en.hasMoreElements();)
+ {
+ digests.add(AlgorithmIdentifier.getInstance(en.nextElement()));
+ }
+
+ return Collections.unmodifiableSet(digests);
+ }
+
+ /**
* Return the a string representation of the OID associated with the
* encapsulated content info structure carried in the signed data.
*
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/CMSUtils.java b/bcpkix/src/main/java/org/bouncycastle/cms/CMSUtils.java
index e5f7e9b3..7dd16e03 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/CMSUtils.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/CMSUtils.java
@@ -5,8 +5,10 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
@@ -16,6 +18,7 @@ import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.BEROctetStringGenerator;
import org.bouncycastle.asn1.BERSet;
+import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
@@ -24,7 +27,10 @@ import org.bouncycastle.asn1.cms.ContentInfo;
// import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat;
// import org.bouncycastle.asn1.ocsp.OCSPResponse;
// import org.bouncycastle.asn1.ocsp.OCSPResponseStatus;
+// import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+// import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
// END android-removed
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.cert.X509AttributeCertificateHolder;
import org.bouncycastle.cert.X509CRLHolder;
import org.bouncycastle.cert.X509CertificateHolder;
@@ -37,6 +43,49 @@ import org.bouncycastle.util.io.TeeOutputStream;
class CMSUtils
{
+ private static final Set<String> des = new HashSet<String>();
+
+ static
+ {
+ des.add("DES");
+ des.add("DESEDE");
+ // BEGIN android-removed
+ // des.add(OIWObjectIdentifiers.desCBC.getId());
+ // des.add(PKCSObjectIdentifiers.des_EDE3_CBC.getId());
+ // des.add(PKCSObjectIdentifiers.des_EDE3_CBC.getId());
+ // des.add(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId());
+ // END android-removed
+ }
+
+ static boolean isDES(String algorithmID)
+ {
+ String name = Strings.toUpperCase(algorithmID);
+
+ return des.contains(name);
+ }
+
+ static boolean isEquivalent(AlgorithmIdentifier algId1, AlgorithmIdentifier algId2)
+ {
+ if (algId1 == null || algId2 == null)
+ {
+ return false;
+ }
+
+ if (!algId1.getAlgorithm().equals(algId2.getAlgorithm()))
+ {
+ return false;
+ }
+
+ ASN1Encodable params1 = algId1.getParameters();
+ ASN1Encodable params2 = algId2.getParameters();
+ if (params1 != null)
+ {
+ return params1.equals(params2) || (params1.equals(DERNull.INSTANCE) && params2 == null);
+ }
+
+ return params2 == null || params2.equals(DERNull.INSTANCE);
+ }
+
static ContentInfo readContentInfo(
byte[] input)
throws CMSException
@@ -229,63 +278,6 @@ class CMSUtils
}
}
- static byte[] getPasswordBytes(int scheme, char[] password)
- {
- if (scheme == PasswordRecipient.PKCS5_SCHEME2)
- {
- return PKCS5PasswordToBytes(password);
- }
-
- return PKCS5PasswordToUTF8Bytes(password);
- }
-
- /**
- * converts a password to a byte array according to the scheme in
- * PKCS5 (ascii, no padding)
- *
- * @param password a character array representing the password.
- * @return a byte array representing the password.
- */
- private static byte[] PKCS5PasswordToBytes(
- char[] password)
- {
- if (password != null)
- {
- byte[] bytes = new byte[password.length];
-
- for (int i = 0; i != bytes.length; i++)
- {
- bytes[i] = (byte)password[i];
- }
-
- return bytes;
- }
- else
- {
- return new byte[0];
- }
- }
-
- /**
- * converts a password to a byte array according to the scheme in
- * PKCS5 (UTF-8, no padding)
- *
- * @param password a character array representing the password.
- * @return a byte array representing the password.
- */
- private static byte[] PKCS5PasswordToUTF8Bytes(
- char[] password)
- {
- if (password != null)
- {
- return Strings.toUTF8ByteArray(password);
- }
- else
- {
- return new byte[0];
- }
- }
-
public static byte[] streamToByteArray(
InputStream in)
throws IOException
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java b/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java
index d454fa6c..2230c780 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureAlgorithmNameGenerator.java
@@ -173,6 +173,13 @@ public class DefaultCMSSignatureAlgorithmNameGenerator
public String getSignatureName(AlgorithmIdentifier digestAlg, AlgorithmIdentifier encryptionAlg)
{
+ String digestName = getDigestAlgName(encryptionAlg.getAlgorithm());
+
+ if (!digestName.equals(encryptionAlg.getAlgorithm().getId()))
+ {
+ return digestName + "with" + getEncryptionAlgName(encryptionAlg.getAlgorithm());
+ }
+
return getDigestAlgName(digestAlg.getAlgorithm()) + "with" + getEncryptionAlgName(encryptionAlg.getAlgorithm());
}
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java b/bcpkix/src/main/java/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java
index 837edd85..ddfd2ebd 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java
@@ -10,8 +10,10 @@ import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.cms.Attribute;
import org.bouncycastle.asn1.cms.AttributeTable;
+import org.bouncycastle.asn1.cms.CMSAlgorithmProtection;
import org.bouncycastle.asn1.cms.CMSAttributes;
import org.bouncycastle.asn1.cms.Time;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
/**
* Default signed attributes generator.
@@ -93,6 +95,14 @@ public class DefaultSignedAttributeTableGenerator
std.put(attr.getAttrType(), attr);
}
+ if (!std.contains(CMSAttributes.cmsAlgorithmProtect))
+ {
+ Attribute attr = new Attribute(CMSAttributes.cmsAlgorithmProtect, new DERSet(new CMSAlgorithmProtection(
+ (AlgorithmIdentifier)parameters.get(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER),
+ CMSAlgorithmProtection.SIGNATURE, (AlgorithmIdentifier)parameters.get(CMSAttributeTableGenerator.SIGNATURE_ALGORITHM_IDENTIFIER))));
+ std.put(attr.getAttrType(), attr);
+ }
+
return std;
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/PKCS7ProcessableObject.java b/bcpkix/src/main/java/org/bouncycastle/cms/PKCS7ProcessableObject.java
new file mode 100644
index 00000000..077b2dc6
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/PKCS7ProcessableObject.java
@@ -0,0 +1,65 @@
+package org.bouncycastle.cms;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Iterator;
+
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1Encoding;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ASN1Sequence;
+
+public class PKCS7ProcessableObject
+ implements CMSTypedData
+{
+ private final ASN1ObjectIdentifier type;
+ private final ASN1Encodable structure;
+
+ public PKCS7ProcessableObject(
+ ASN1ObjectIdentifier type,
+ ASN1Encodable structure)
+ {
+ this.type = type;
+ this.structure = structure;
+ }
+
+ public ASN1ObjectIdentifier getContentType()
+ {
+ return type;
+ }
+
+ public void write(OutputStream cOut)
+ throws IOException, CMSException
+ {
+ if (structure instanceof ASN1Sequence)
+ {
+ ASN1Sequence s = ASN1Sequence.getInstance(structure);
+
+ for (Iterator it = s.iterator(); it.hasNext();)
+ {
+ ASN1Encodable enc = (ASN1Encodable)it.next();
+
+ cOut.write(enc.toASN1Primitive().getEncoded(ASN1Encoding.DER));
+ }
+ }
+ else
+ {
+ byte[] encoded = structure.toASN1Primitive().getEncoded(ASN1Encoding.DER);
+ int index = 1;
+
+ while ((encoded[index] & 0xff) > 127)
+ {
+ index++;
+ }
+
+ index++;
+
+ cOut.write(encoded, index, encoded.length - index);
+ }
+ }
+
+ public Object getContent()
+ {
+ return structure;
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/PasswordRecipient.java b/bcpkix/src/main/java/org/bouncycastle/cms/PasswordRecipient.java
index c81c3028..7322fdcc 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/PasswordRecipient.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/PasswordRecipient.java
@@ -8,7 +8,7 @@ public interface PasswordRecipient
public static final int PKCS5_SCHEME2 = 0;
public static final int PKCS5_SCHEME2_UTF8 = 1;
- byte[] calculateDerivedKey(byte[] encodedPassword, AlgorithmIdentifier derivationAlgorithm, int keySize)
+ byte[] calculateDerivedKey(int schemeID, AlgorithmIdentifier derivationAlgorithm, int keySize)
throws CMSException;
RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncryptionAlgorithm, AlgorithmIdentifier contentEncryptionAlgorithm, byte[] derivedKey, byte[] encryptedEncryptedContentKey)
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java b/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java
index f264729c..e1b0ce1f 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGenerator.java
@@ -183,13 +183,15 @@ public class SignerInfoGenerator
*/
ASN1Set signedAttr = null;
+ AlgorithmIdentifier digestEncryptionAlgorithm = sigEncAlgFinder.findEncryptionAlgorithm(signer.getAlgorithmIdentifier());
+
AlgorithmIdentifier digestAlg = null;
if (sAttrGen != null)
{
digestAlg = digester.getAlgorithmIdentifier();
calculatedDigest = digester.getDigest();
- Map parameters = getBaseParameters(contentType, digester.getAlgorithmIdentifier(), calculatedDigest);
+ Map parameters = getBaseParameters(contentType, digester.getAlgorithmIdentifier(), digestEncryptionAlgorithm, calculatedDigest);
AttributeTable signed = sAttrGen.getAttributes(Collections.unmodifiableMap(parameters));
signedAttr = getAttributeSet(signed);
@@ -220,7 +222,7 @@ public class SignerInfoGenerator
ASN1Set unsignedAttr = null;
if (unsAttrGen != null)
{
- Map parameters = getBaseParameters(contentType, digestAlg, calculatedDigest);
+ Map parameters = getBaseParameters(contentType, digestAlg, digestEncryptionAlgorithm, calculatedDigest);
parameters.put(CMSAttributeTableGenerator.SIGNATURE, Arrays.clone(sigBytes));
AttributeTable unsigned = unsAttrGen.getAttributes(Collections.unmodifiableMap(parameters));
@@ -228,8 +230,6 @@ public class SignerInfoGenerator
unsignedAttr = getAttributeSet(unsigned);
}
- AlgorithmIdentifier digestEncryptionAlgorithm = sigEncAlgFinder.findEncryptionAlgorithm(signer.getAlgorithmIdentifier());
-
return new SignerInfo(signerIdentifier, digestAlg,
signedAttr, digestEncryptionAlgorithm, new DEROctetString(sigBytes), unsignedAttr);
}
@@ -255,7 +255,7 @@ public class SignerInfoGenerator
return null;
}
- private Map getBaseParameters(ASN1ObjectIdentifier contentType, AlgorithmIdentifier digAlgId, byte[] hash)
+ private Map getBaseParameters(ASN1ObjectIdentifier contentType, AlgorithmIdentifier digAlgId, AlgorithmIdentifier sigAlgId, byte[] hash)
{
Map param = new HashMap();
@@ -265,7 +265,9 @@ public class SignerInfoGenerator
}
param.put(CMSAttributeTableGenerator.DIGEST_ALGORITHM_IDENTIFIER, digAlgId);
+ param.put(CMSAttributeTableGenerator.SIGNATURE_ALGORITHM_IDENTIFIER, sigAlgId);
param.put(CMSAttributeTableGenerator.DIGEST, Arrays.clone(hash));
+
return param;
}
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/SignerInformation.java b/bcpkix/src/main/java/org/bouncycastle/cms/SignerInformation.java
index 081d1218..ac6dd0f9 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/SignerInformation.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/SignerInformation.java
@@ -18,6 +18,7 @@ import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.cms.Attribute;
import org.bouncycastle.asn1.cms.AttributeTable;
+import org.bouncycastle.asn1.cms.CMSAlgorithmProtection;
import org.bouncycastle.asn1.cms.CMSAttributes;
import org.bouncycastle.asn1.cms.IssuerAndSerialNumber;
import org.bouncycastle.asn1.cms.SignerIdentifier;
@@ -38,21 +39,22 @@ import org.bouncycastle.util.io.TeeOutputStream;
*/
public class SignerInformation
{
- private SignerId sid;
- private SignerInfo info;
- private AlgorithmIdentifier digestAlgorithm;
- private AlgorithmIdentifier encryptionAlgorithm;
- private final ASN1Set signedAttributeSet;
- private final ASN1Set unsignedAttributeSet;
- private CMSProcessable content;
- private byte[] signature;
- private ASN1ObjectIdentifier contentType;
- private byte[] resultDigest;
+ private final SignerId sid;
+ private final CMSProcessable content;
+ private final byte[] signature;
+ private final ASN1ObjectIdentifier contentType;
+ private final boolean isCounterSignature;
// Derived
- private AttributeTable signedAttributeValues;
- private AttributeTable unsignedAttributeValues;
- private boolean isCounterSignature;
+ private AttributeTable signedAttributeValues;
+ private AttributeTable unsignedAttributeValues;
+ private byte[] resultDigest;
+
+ protected final SignerInfo info;
+ protected final AlgorithmIdentifier digestAlgorithm;
+ protected final AlgorithmIdentifier encryptionAlgorithm;
+ protected final ASN1Set signedAttributeSet;
+ protected final ASN1Set unsignedAttributeSet;
SignerInformation(
SignerInfo info,
@@ -89,6 +91,28 @@ public class SignerInformation
this.resultDigest = resultDigest;
}
+ /**
+ * Protected constructor. In some cases clients have their own idea about how to encode
+ * the signed attributes and calculate the signature. This constructor is to allow developers
+ * to deal with that by extending off the class and overridng methods like getSignedAttributes().
+ *
+ * @param baseInfo the SignerInformation to base this one on.
+ */
+ protected SignerInformation(SignerInformation baseInfo)
+ {
+ this.info = baseInfo.info;
+ this.contentType = baseInfo.contentType;
+ this.isCounterSignature = baseInfo.isCounterSignature();
+ this.sid = baseInfo.getSID();
+ this.digestAlgorithm = info.getDigestAlgorithm();
+ this.signedAttributeSet = info.getAuthenticatedAttributes();
+ this.unsignedAttributeSet = info.getUnauthenticatedAttributes();
+ this.encryptionAlgorithm = info.getDigestEncryptionAlgorithm();
+ this.signature = info.getEncryptedDigest().getOctets();
+ this.content = baseInfo.content;
+ this.resultDigest = baseInfo.resultDigest;
+ }
+
public boolean isCounterSignature()
{
return isCounterSignature;
@@ -428,6 +452,46 @@ public class SignerInformation
}
}
+ AttributeTable signedAttrTable = this.getSignedAttributes();
+
+ // RFC 6211 Validate Algorithm Identifier protection attribute if present
+ {
+ AttributeTable unsignedAttrTable = this.getUnsignedAttributes();
+ if (unsignedAttrTable != null && unsignedAttrTable.getAll(CMSAttributes.cmsAlgorithmProtect).size() > 0)
+ {
+ throw new CMSException("A cmsAlgorithmProtect attribute MUST be a signed attribute");
+ }
+ if (signedAttrTable != null)
+ {
+ ASN1EncodableVector protectionAttributes = signedAttrTable.getAll(CMSAttributes.cmsAlgorithmProtect);
+ if (protectionAttributes.size() > 1)
+ {
+ throw new CMSException("Only one instance of a cmsAlgorithmProtect attribute can be present");
+ }
+
+ if (protectionAttributes.size() > 0)
+ {
+ Attribute attr = Attribute.getInstance(protectionAttributes.get(0));
+ if (attr.getAttrValues().size() != 1)
+ {
+ throw new CMSException("A cmsAlgorithmProtect attribute MUST contain exactly one value");
+ }
+
+ CMSAlgorithmProtection algorithmProtection = CMSAlgorithmProtection.getInstance(attr.getAttributeValues()[0]);
+
+ if (!CMSUtils.isEquivalent(algorithmProtection.getDigestAlgorithm(), info.getDigestAlgorithm()))
+ {
+ throw new CMSException("CMS Algorithm Identifier Protection check failed for digestAlgorithm");
+ }
+
+ if (!CMSUtils.isEquivalent(algorithmProtection.getSignatureAlgorithm(), info.getDigestEncryptionAlgorithm()))
+ {
+ throw new CMSException("CMS Algorithm Identifier Protection check failed for signatureAlgorithm");
+ }
+ }
+ }
+ }
+
// RFC 3852 11.2 Check the message-digest attribute is correct
{
ASN1Primitive validMessageDigest = getSingleValuedSignedAttribute(
@@ -457,7 +521,6 @@ public class SignerInformation
// RFC 3852 11.4 Validate countersignature attribute(s)
{
- AttributeTable signedAttrTable = this.getSignedAttributes();
if (signedAttrTable != null
&& signedAttrTable.getAll(CMSAttributes.counterSignature).size() > 0)
{
@@ -470,7 +533,7 @@ public class SignerInformation
ASN1EncodableVector csAttrs = unsignedAttrTable.getAll(CMSAttributes.counterSignature);
for (int i = 0; i < csAttrs.size(); ++i)
{
- Attribute csAttr = (Attribute)csAttrs.get(i);
+ Attribute csAttr = Attribute.getInstance(csAttrs.get(i));
if (csAttr.getAttrValues().size() < 1)
{
throw new CMSException("A countersignature attribute MUST contain at least one AttributeValue");
diff --git a/bcpkix/src/main/java/org/bouncycastle/openssl/CertificateTrustBlock.java b/bcpkix/src/main/java/org/bouncycastle/openssl/CertificateTrustBlock.java
new file mode 100644
index 00000000..9a76084b
--- /dev/null
+++ b/bcpkix/src/main/java/org/bouncycastle/openssl/CertificateTrustBlock.java
@@ -0,0 +1,132 @@
+package org.bouncycastle.openssl;
+
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.DERTaggedObject;
+import org.bouncycastle.asn1.DERUTF8String;
+
+public class CertificateTrustBlock
+{
+ private ASN1Sequence uses;
+ private ASN1Sequence prohibitions;
+ private String alias;
+
+ public CertificateTrustBlock(Set<ASN1ObjectIdentifier> uses)
+ {
+ this(null, uses, null);
+ }
+
+ public CertificateTrustBlock(String alias, Set<ASN1ObjectIdentifier> uses)
+ {
+ this(alias, uses, null);
+ }
+
+ public CertificateTrustBlock(String alias, Set<ASN1ObjectIdentifier> uses, Set<ASN1ObjectIdentifier> prohibitions)
+ {
+ this.alias = alias;
+ this.uses = toSequence(uses);
+ this.prohibitions = toSequence(prohibitions);
+ }
+
+ CertificateTrustBlock(byte[] encoded)
+ {
+ ASN1Sequence seq = ASN1Sequence.getInstance(encoded);
+
+ for (Enumeration en = seq.getObjects(); en.hasMoreElements();)
+ {
+ ASN1Encodable obj = (ASN1Encodable)en.nextElement();
+
+ if (obj instanceof ASN1Sequence)
+ {
+ this.uses = ASN1Sequence.getInstance(obj);
+ }
+ else if (obj instanceof ASN1TaggedObject)
+ {
+ this.prohibitions = ASN1Sequence.getInstance((ASN1TaggedObject)obj, false);
+ }
+ else if (obj instanceof DERUTF8String)
+ {
+ this.alias = DERUTF8String.getInstance(obj).getString();
+ }
+ }
+ }
+
+ public String getAlias()
+ {
+ return alias;
+ }
+
+ public Set<ASN1ObjectIdentifier> getUses()
+ {
+ return toSet(uses);
+ }
+
+ public Set<ASN1ObjectIdentifier> getProhibitions()
+ {
+ return toSet(prohibitions);
+ }
+
+ private Set<ASN1ObjectIdentifier> toSet(ASN1Sequence seq)
+ {
+ if (seq != null)
+ {
+ Set<ASN1ObjectIdentifier> oids = new HashSet<ASN1ObjectIdentifier>(seq.size());
+
+ for (Enumeration en = seq.getObjects(); en.hasMoreElements(); )
+ {
+ oids.add(ASN1ObjectIdentifier.getInstance(en.nextElement()));
+ }
+
+ return oids;
+ }
+
+ return Collections.EMPTY_SET;
+ }
+
+ private ASN1Sequence toSequence(Set<ASN1ObjectIdentifier> oids)
+ {
+ if (oids == null || oids.isEmpty())
+ {
+ return null;
+ }
+
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ for (Iterator it = oids.iterator(); it.hasNext();)
+ {
+ v.add((ASN1Encodable)it.next());
+ }
+
+ return new DERSequence(v);
+ }
+
+ ASN1Sequence toASN1Sequence()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ if (uses != null)
+ {
+ v.add(uses);
+ }
+ if (prohibitions != null)
+ {
+ v.add(new DERTaggedObject(false, 0, prohibitions));
+ }
+ if (alias != null)
+ {
+ v.add(new DERUTF8String(alias));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
index 293370f8..dc2c431b 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
@@ -72,6 +72,20 @@ public class DefaultDigestAlgorithmIdentifierFinder
digestNameToOids.put("SHA-512", NISTObjectIdentifiers.id_sha512);
// BEGIN android-removed
+ // digestNameToOids.put("SHA1", OIWObjectIdentifiers.idSHA1);
+ // digestNameToOids.put("SHA224", NISTObjectIdentifiers.id_sha224);
+ // digestNameToOids.put("SHA256", NISTObjectIdentifiers.id_sha256);
+ // digestNameToOids.put("SHA384", NISTObjectIdentifiers.id_sha384);
+ // digestNameToOids.put("SHA512", NISTObjectIdentifiers.id_sha512);
+
+ // digestNameToOids.put("SHA3-224", NISTObjectIdentifiers.id_sha3_224);
+ // digestNameToOids.put("SHA3-256", NISTObjectIdentifiers.id_sha3_256);
+ // digestNameToOids.put("SHA3-384", NISTObjectIdentifiers.id_sha3_384);
+ // digestNameToOids.put("SHA3-512", NISTObjectIdentifiers.id_sha3_512);
+ //
+ // digestNameToOids.put("SHAKE-128", NISTObjectIdentifiers.id_shake128);
+ // digestNameToOids.put("SHAKE-256", NISTObjectIdentifiers.id_shake256);
+ //
// digestNameToOids.put("GOST3411", CryptoProObjectIdentifiers.gostR3411);
//
// digestNameToOids.put("MD2", PKCSObjectIdentifiers.md2);
@@ -106,4 +120,4 @@ public class DefaultDigestAlgorithmIdentifierFinder
{
return new AlgorithmIdentifier((ASN1ObjectIdentifier)digestNameToOids.get(digAlgName), DERNull.INSTANCE);
}
-} \ 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 a0847fb1..19d46ec9 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java
@@ -40,9 +40,11 @@ import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.cert.X509CertificateHolder;
+import org.bouncycastle.jcajce.util.AlgorithmParametersUtils;
import org.bouncycastle.jcajce.util.JcaJceHelper;
-import org.bouncycastle.jcajce.util.JcaJceUtils;
+import org.bouncycastle.jcajce.util.MessageDigestUtils;
import org.bouncycastle.operator.OperatorCreationException;
+import org.bouncycastle.util.Integers;
class OperatorHelper
{
@@ -50,6 +52,7 @@ class OperatorHelper
private static final Map asymmetricWrapperAlgNames = new HashMap();
private static final Map symmetricWrapperAlgNames = new HashMap();
private static final Map symmetricKeyAlgNames = new HashMap();
+ private static final Map symmetricWrapperKeySizes = new HashMap();
static
{
@@ -114,6 +117,16 @@ class OperatorHelper
symmetricWrapperAlgNames.put(KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap, "SEEDWrap");
symmetricWrapperAlgNames.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESede");
+ symmetricWrapperKeySizes.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap, Integers.valueOf(192));
+ symmetricWrapperKeySizes.put(NISTObjectIdentifiers.id_aes128_wrap, Integers.valueOf(128));
+ symmetricWrapperKeySizes.put(NISTObjectIdentifiers.id_aes192_wrap, Integers.valueOf(192));
+ symmetricWrapperKeySizes.put(NISTObjectIdentifiers.id_aes256_wrap, Integers.valueOf(256));
+ symmetricWrapperKeySizes.put(NTTObjectIdentifiers.id_camellia128_wrap, Integers.valueOf(128));
+ symmetricWrapperKeySizes.put(NTTObjectIdentifiers.id_camellia192_wrap, Integers.valueOf(192));
+ symmetricWrapperKeySizes.put(NTTObjectIdentifiers.id_camellia256_wrap, Integers.valueOf(256));
+ symmetricWrapperKeySizes.put(KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap, Integers.valueOf(128));
+ symmetricWrapperKeySizes.put(PKCSObjectIdentifiers.des_EDE3_CBC, Integers.valueOf(192));
+
symmetricKeyAlgNames.put(NISTObjectIdentifiers.aes, "AES");
symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes128_CBC, "AES");
symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes192_CBC, "AES");
@@ -129,6 +142,16 @@ class OperatorHelper
this.helper = helper;
}
+ String getWrappingAlgorithmName(ASN1ObjectIdentifier algOid)
+ {
+ return (String)symmetricWrapperAlgNames.get(algOid);
+ }
+
+ int getKeySizeInBits(ASN1ObjectIdentifier algOid)
+ {
+ return ((Integer)symmetricWrapperKeySizes.get(algOid)).intValue();
+ }
+
Cipher createAsymmetricWrapper(ASN1ObjectIdentifier algorithm, Map extraAlgNames)
throws OperatorCreationException
{
@@ -248,7 +271,7 @@ class OperatorHelper
try
{
- dig = helper.createDigest(JcaJceUtils.getDigestAlgName(digAlgId.getAlgorithm()));
+ dig = helper.createDigest(MessageDigestUtils.getDigestName(digAlgId.getAlgorithm()));
}
catch (NoSuchAlgorithmException e)
{
@@ -318,7 +341,7 @@ class OperatorHelper
{
AlgorithmParameters params = helper.createAlgorithmParameters(algName);
- JcaJceUtils.loadParameters(params, algorithm.getParameters());
+ AlgorithmParametersUtils.loadParameters(params, algorithm.getParameters());
PSSParameterSpec spec = (PSSParameterSpec)params.getParameterSpec(PSSParameterSpec.class);
sig.setParameter(spec);
@@ -342,7 +365,7 @@ class OperatorHelper
if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
{
RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params);
- return JcaJceUtils.getDigestAlgName(rsaParams.getHashAlgorithm().getAlgorithm()) + "WITHRSAANDMGF1";
+ return getDigestName(rsaParams.getHashAlgorithm().getAlgorithm()) + "WITHRSAANDMGF1";
}
}
@@ -354,6 +377,20 @@ class OperatorHelper
return sigAlgId.getAlgorithm().getId();
}
+ // we need to remove the - to create a correct signature name
+ private static String getDigestName(ASN1ObjectIdentifier oid)
+ {
+ String name = MessageDigestUtils.getDigestName(oid);
+
+ int dIndex = name.indexOf('-');
+ if (dIndex > 0)
+ {
+ return name.substring(0, dIndex) + name.substring(dIndex + 1);
+ }
+
+ return MessageDigestUtils.getDigestName(oid);
+ }
+
public X509Certificate convertCertificate(X509CertificateHolder certHolder)
throws CertificateException
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecific.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecific.java
new file mode 100644
index 00000000..fca4e01a
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecific.java
@@ -0,0 +1,226 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import org.bouncycastle.util.Arrays;
+
+/**
+ * Base class for an application specific object
+ */
+public abstract class ASN1ApplicationSpecific
+ extends ASN1Primitive
+{
+ protected final boolean isConstructed;
+ protected final int tag;
+ protected final byte[] octets;
+
+ ASN1ApplicationSpecific(
+ boolean isConstructed,
+ int tag,
+ byte[] octets)
+ {
+ this.isConstructed = isConstructed;
+ this.tag = tag;
+ this.octets = octets;
+ }
+
+ /**
+ * Return an ASN1ApplicationSpecific from the passed in object, which may be a byte array, or null.
+ *
+ * @param obj the object to be converted.
+ * @return obj's representation as an ASN1ApplicationSpecific object.
+ */
+ public static ASN1ApplicationSpecific getInstance(Object obj)
+ {
+ if (obj == null || obj instanceof ASN1ApplicationSpecific)
+ {
+ return (ASN1ApplicationSpecific)obj;
+ }
+ else if (obj instanceof byte[])
+ {
+ try
+ {
+ return ASN1ApplicationSpecific.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("Failed to construct object from byte[]: " + e.getMessage());
+ }
+ }
+
+ throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
+ }
+
+ protected static int getLengthOfHeader(byte[] data)
+ {
+ int length = data[1] & 0xff; // TODO: assumes 1 byte tag
+
+ if (length == 0x80)
+ {
+ return 2; // indefinite-length encoding
+ }
+
+ if (length > 127)
+ {
+ int size = length & 0x7f;
+
+ // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
+ if (size > 4)
+ {
+ throw new IllegalStateException("DER length more than 4 bytes: " + size);
+ }
+
+ return size + 2;
+ }
+
+ return 2;
+ }
+
+ /**
+ * Return true if the object is marked as constructed, false otherwise.
+ *
+ * @return true if constructed, otherwise false.
+ */
+ public boolean isConstructed()
+ {
+ return isConstructed;
+ }
+
+ /**
+ * Return the contents of this object as a byte[]
+ *
+ * @return the encoded contents of the object.
+ */
+ public byte[] getContents()
+ {
+ return octets;
+ }
+
+ /**
+ * Return the tag number associated with this object,
+ *
+ * @return the application tag number.
+ */
+ public int getApplicationTag()
+ {
+ return tag;
+ }
+
+ /**
+ * Return the enclosed object assuming explicit tagging.
+ *
+ * @return the resulting object
+ * @throws IOException if reconstruction fails.
+ */
+ public ASN1Primitive getObject()
+ throws IOException
+ {
+ return new ASN1InputStream(getContents()).readObject();
+ }
+
+ /**
+ * Return the enclosed object assuming implicit tagging.
+ *
+ * @param derTagNo the type tag that should be applied to the object's contents.
+ * @return the resulting object
+ * @throws IOException if reconstruction fails.
+ */
+ public ASN1Primitive getObject(int derTagNo)
+ throws IOException
+ {
+ if (derTagNo >= 0x1f)
+ {
+ throw new IOException("unsupported tag number");
+ }
+
+ byte[] orig = this.getEncoded();
+ byte[] tmp = replaceTagNumber(derTagNo, orig);
+
+ if ((orig[0] & BERTags.CONSTRUCTED) != 0)
+ {
+ tmp[0] |= BERTags.CONSTRUCTED;
+ }
+
+ return new ASN1InputStream(tmp).readObject();
+ }
+
+ int encodedLength()
+ throws IOException
+ {
+ return StreamUtil.calculateTagLength(tag) + StreamUtil.calculateBodyLength(octets.length) + octets.length;
+ }
+
+ /* (non-Javadoc)
+ * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
+ */
+ void encode(ASN1OutputStream out) throws IOException
+ {
+ int classBits = BERTags.APPLICATION;
+ if (isConstructed)
+ {
+ classBits |= BERTags.CONSTRUCTED;
+ }
+
+ out.writeEncoded(classBits, tag, octets);
+ }
+
+ boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (!(o instanceof ASN1ApplicationSpecific))
+ {
+ return false;
+ }
+
+ ASN1ApplicationSpecific other = (ASN1ApplicationSpecific)o;
+
+ return isConstructed == other.isConstructed
+ && tag == other.tag
+ && Arrays.areEqual(octets, other.octets);
+ }
+
+ public int hashCode()
+ {
+ return (isConstructed ? 1 : 0) ^ tag ^ Arrays.hashCode(octets);
+ }
+
+ private byte[] replaceTagNumber(int newTag, byte[] input)
+ throws IOException
+ {
+ int tagNo = input[0] & 0x1f;
+ int index = 1;
+ //
+ // with tagged object tag number is bottom 5 bits, or stored at the start of the content
+ //
+ if (tagNo == 0x1f)
+ {
+ tagNo = 0;
+
+ int b = input[index++] & 0xff;
+
+ // X.690-0207 8.1.2.4.2
+ // "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
+ if ((b & 0x7f) == 0) // Note: -1 will pass
+ {
+ throw new ASN1ParsingException("corrupted stream - invalid high tag number found");
+ }
+
+ while ((b >= 0) && ((b & 0x80) != 0))
+ {
+ tagNo |= (b & 0x7f);
+ tagNo <<= 7;
+ b = input[index++] & 0xff;
+ }
+
+// tagNo |= (b & 0x7f);
+ }
+
+ byte[] tmp = new byte[input.length - index + 1];
+
+ System.arraycopy(input, index, tmp, 1, tmp.length - 1);
+
+ tmp[0] = (byte)newTag;
+
+ return tmp;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1BitString.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1BitString.java
new file mode 100644
index 00000000..513d4e5b
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1BitString.java
@@ -0,0 +1,291 @@
+package org.bouncycastle.asn1;
+
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.io.Streams;
+
+/**
+ * Base class for BIT STRING objects
+ */
+public abstract class ASN1BitString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+ protected final byte[] data;
+ protected final int padBits;
+
+ /**
+ * @param bitString an int containing the BIT STRING
+ * @return the correct number of pad bits for a bit string defined in
+ * a 32 bit constant
+ */
+ static protected int getPadBits(
+ int bitString)
+ {
+ int val = 0;
+ for (int i = 3; i >= 0; i--)
+ {
+ //
+ // this may look a little odd, but if it isn't done like this pre jdk1.2
+ // JVM's break!
+ //
+ if (i != 0)
+ {
+ if ((bitString >> (i * 8)) != 0)
+ {
+ val = (bitString >> (i * 8)) & 0xFF;
+ break;
+ }
+ }
+ else
+ {
+ if (bitString != 0)
+ {
+ val = bitString & 0xFF;
+ break;
+ }
+ }
+ }
+
+ if (val == 0)
+ {
+ return 0;
+ }
+
+ int bits = 1;
+
+ while (((val <<= 1) & 0xFF) != 0)
+ {
+ bits++;
+ }
+
+ return 8 - bits;
+ }
+
+ /**
+ * @param bitString an int containing the BIT STRING
+ * @return the correct number of bytes for a bit string defined in
+ * a 32 bit constant
+ */
+ static protected byte[] getBytes(int bitString)
+ {
+ if (bitString == 0)
+ {
+ return new byte[0];
+ }
+
+ int bytes = 4;
+ for (int i = 3; i >= 1; i--)
+ {
+ if ((bitString & (0xFF << (i * 8))) != 0)
+ {
+ break;
+ }
+ bytes--;
+ }
+
+ byte[] result = new byte[bytes];
+ for (int i = 0; i < bytes; i++)
+ {
+ result[i] = (byte) ((bitString >> (i * 8)) & 0xFF);
+ }
+
+ return result;
+ }
+
+ /**
+ * Base constructor.
+ *
+ * @param data the octets making up the bit string.
+ * @param padBits the number of extra bits at the end of the string.
+ */
+ public ASN1BitString(
+ byte[] data,
+ int padBits)
+ {
+ if (data == null)
+ {
+ throw new NullPointerException("data cannot be null");
+ }
+ if (data.length == 0 && padBits != 0)
+ {
+ throw new IllegalArgumentException("zero length data with non-zero pad bits");
+ }
+ if (padBits > 7 || padBits < 0)
+ {
+ throw new IllegalArgumentException("pad bits cannot be greater than 7 or less than 0");
+ }
+
+ this.data = Arrays.clone(data);
+ this.padBits = padBits;
+ }
+
+ /**
+ * Return a String representation of this BIT STRING
+ *
+ * @return a String representation.
+ */
+ public String getString()
+ {
+ StringBuffer buf = new StringBuffer("#");
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+ ASN1OutputStream aOut = new ASN1OutputStream(bOut);
+
+ try
+ {
+ aOut.writeObject(this);
+ }
+ 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]);
+ buf.append(table[string[i] & 0xf]);
+ }
+
+ return buf.toString();
+ }
+
+ /**
+ * @return the value of the bit string as an int (truncating if necessary)
+ */
+ public int intValue()
+ {
+ int value = 0;
+ byte[] string = data;
+
+ if (padBits > 0 && data.length <= 4)
+ {
+ string = derForm(data, padBits);
+ }
+
+ for (int i = 0; i != string.length && i != 4; i++)
+ {
+ value |= (string[i] & 0xff) << (8 * i);
+ }
+
+ return value;
+ }
+
+ /**
+ * Return the octets contained in this BIT STRING, checking that this BIT STRING really
+ * does represent an octet aligned string. Only use this method when the standard you are
+ * following dictates that the BIT STRING will be octet aligned.
+ *
+ * @return a copy of the octet aligned data.
+ */
+ public byte[] getOctets()
+ {
+ if (padBits != 0)
+ {
+ throw new IllegalStateException("attempt to get non-octet aligned data from BIT STRING");
+ }
+
+ return Arrays.clone(data);
+ }
+
+ public byte[] getBytes()
+ {
+ return derForm(data, padBits);
+ }
+
+ public int getPadBits()
+ {
+ return padBits;
+ }
+
+ public String toString()
+ {
+ return getString();
+ }
+
+ public int hashCode()
+ {
+ return padBits ^ Arrays.hashCode(this.getBytes());
+ }
+
+ protected boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (!(o instanceof ASN1BitString))
+ {
+ return false;
+ }
+
+ 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)
+ {
+ rv[data.length - 1] &= 0xff << padBits;
+ }
+
+ return rv;
+ }
+
+ static ASN1BitString fromInputStream(int length, InputStream stream)
+ throws IOException
+ {
+ if (length < 1)
+ {
+ throw new IllegalArgumentException("truncated BIT STRING detected");
+ }
+
+ int padBits = stream.read();
+ byte[] data = new byte[length - 1];
+
+ if (data.length != 0)
+ {
+ if (Streams.readFully(stream, data) != data.length)
+ {
+ throw new EOFException("EOF encountered in middle of BIT STRING");
+ }
+
+ if (padBits > 0 && padBits < 8)
+ {
+ if (data[data.length - 1] != (byte)(data[data.length - 1] & (0xff << padBits)))
+ {
+ return new DLBitString(data, padBits);
+ }
+ }
+ }
+
+ return new DERBitString(data, padBits);
+ }
+
+ public ASN1Primitive getLoadedObject()
+ {
+ return this.toASN1Primitive();
+ }
+
+ ASN1Primitive toDERObject()
+ {
+ return new DERBitString(data, padBits);
+ }
+
+ ASN1Primitive toDLObject()
+ {
+ return new DLBitString(data, padBits);
+ }
+
+ abstract void encode(ASN1OutputStream out)
+ 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 30d7d452..d883a732 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Boolean.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Boolean.java
@@ -8,7 +8,6 @@ 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:
- * </p>
* <ul>
* <li> ASN1Boolean.TRUE literal</li>
* <li> ASN1Boolean.FALSE literal</li>
@@ -23,9 +22,7 @@ public class ASN1Boolean
private static final byte[] TRUE_VALUE = new byte[] { (byte)0xff };
private static final byte[] FALSE_VALUE = new byte[] { 0 };
- // BEGIN android-changed
- final private byte[] value;
- // END android-changed
+ private final byte[] value;
public static final ASN1Boolean FALSE = new ASN1Boolean(false);
public static final ASN1Boolean TRUE = new ASN1Boolean(true);
@@ -63,6 +60,7 @@ public class ASN1Boolean
/**
* return an ASN1Boolean from the passed in boolean.
+ * @param value true or false depending on the ASN1Boolean wanted.
* @return an ASN1Boolean instance.
*/
public static ASN1Boolean getInstance(
@@ -73,6 +71,7 @@ public class ASN1Boolean
/**
* return an ASN1Boolean from the passed in value.
+ * @param value non-zero (true) or zero (false) depending on the ASN1Boolean wanted.
* @return an ASN1Boolean instance.
*/
public static ASN1Boolean getInstance(
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Choice.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Choice.java
index 8a6714f2..3ca88905 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Choice.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Choice.java
@@ -7,7 +7,7 @@ package org.bouncycastle.asn1;
* <p>
* If you use this interface your class should also implement the getInstance()
* pattern which takes a tag object and the tagging mode used.
- * <p>
+ * </p>
* <hr>
* <p><b>X.690</b></p>
* <p><b>8: Basic encoding rules</b></p>
@@ -16,7 +16,7 @@ package org.bouncycastle.asn1;
* The encoding of a choice value shall be the same as the encoding of a value of the chosen type.
* <blockquote>
* NOTE 1 &mdash; The encoding may be primitive or constructed depending on the chosen type.
- * <p>
+ * <br />
* NOTE 2 &mdash; The tag used in the identifier octets is the tag of the chosen type,
* as specified in the ASN.1 definition of the choice type.
* </blockquote>
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1EncodableVector.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1EncodableVector.java
index 530da524..2828541e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1EncodableVector.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1EncodableVector.java
@@ -8,7 +8,7 @@ import java.util.Vector;
*/
public class ASN1EncodableVector
{
- Vector v = new Vector();
+ private final Vector v = new Vector();
/**
* Base constructor.
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java
index d6fd2e29..195b924f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java
@@ -11,7 +11,7 @@ import org.bouncycastle.util.Arrays;
public class ASN1Enumerated
extends ASN1Primitive
{
- byte[] bytes;
+ private final byte[] bytes;
/**
* return an enumerated from the passed in object
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralizedTime.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralizedTime.java
index bbe5ae17..089526e1 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralizedTime.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1GeneralizedTime.java
@@ -162,6 +162,7 @@ public class ASN1GeneralizedTime
* To read in the time and get a date which is compatible with our local
* time zone.
* </p>
+ * @return a String representation of the time.
*/
public String getTime()
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java
index 1971af92..0c63a1a6 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java
@@ -236,11 +236,11 @@ public class ASN1InputStream
//
int length = readLength();
- if (length < 0) // indefinite length method
+ if (length < 0) // indefinite-length method
{
if (!isConstructed)
{
- throw new IOException("indefinite length primitive encoding encountered");
+ throw new IOException("indefinite-length primitive encoding encountered");
}
IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(this, limit);
@@ -430,7 +430,7 @@ public class ASN1InputStream
switch (tagNo)
{
case BIT_STRING:
- return DERBitString.fromInputStream(defIn.getRemaining(), defIn);
+ return ASN1BitString.fromInputStream(defIn.getRemaining(), defIn);
case BMP_STRING:
return new DERBMPString(getBMPCharBuffer(defIn));
case BOOLEAN:
@@ -465,6 +465,10 @@ public class ASN1InputStream
return new DERUTF8String(defIn.toByteArray());
case VISIBLE_STRING:
return new DERVisibleString(defIn.toByteArray());
+ case GRAPHIC_STRING:
+ return new DERGraphicString(defIn.toByteArray());
+ case VIDEOTEX_STRING:
+ return new DERVideotexString(defIn.toByteArray());
default:
throw new IOException("unknown tag " + tagNo + " encountered");
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java
index 10326cf6..c3c3f9cf 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java
@@ -11,7 +11,7 @@ import org.bouncycastle.util.Arrays;
public class ASN1Integer
extends ASN1Primitive
{
- byte[] bytes;
+ private final byte[] bytes;
/**
* return an integer from the passed in object
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
index 9d54058d..ac65d96f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
@@ -3,6 +3,8 @@ package org.bouncycastle.asn1;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.Map;
import org.bouncycastle.util.Arrays;
@@ -12,7 +14,7 @@ import org.bouncycastle.util.Arrays;
public class ASN1ObjectIdentifier
extends ASN1Primitive
{
- String identifier;
+ private final String identifier;
private byte[] body;
@@ -304,7 +306,7 @@ public class ASN1ObjectIdentifier
}
}
- protected synchronized byte[] getBody()
+ private synchronized byte[] getBody()
{
if (body == null)
{
@@ -350,6 +352,11 @@ public class ASN1ObjectIdentifier
boolean asn1Equals(
ASN1Primitive o)
{
+ if (o == this)
+ {
+ return true;
+ }
+
if (!(o instanceof ASN1ObjectIdentifier))
{
return false;
@@ -414,69 +421,74 @@ public class ASN1ObjectIdentifier
return isValidBranchID(identifier, 2);
}
- private static ASN1ObjectIdentifier[][] cache = new ASN1ObjectIdentifier[256][];
-
- static ASN1ObjectIdentifier fromOctetString(byte[] enc)
+ /**
+ * Intern will return a reference to a pooled version of this object, unless it
+ * is not present in which case intern will add it.
+ * <p>
+ * The pool is also used by the ASN.1 parsers to limit the number of duplicated OID
+ * objects in circulation.
+ * </p>
+ * @return a reference to the identifier in the pool.
+ */
+ public ASN1ObjectIdentifier intern()
{
- if (enc.length < 3)
+ synchronized (pool)
{
- return new ASN1ObjectIdentifier(enc);
- }
-
- int idx1 = enc[enc.length - 2] & 0xff;
- // in this case top bit is always zero
- int idx2 = enc[enc.length - 1] & 0x7f;
-
- ASN1ObjectIdentifier possibleMatch;
+ OidHandle hdl = new OidHandle(getBody());
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)pool.get(hdl);
- synchronized (cache)
- {
- ASN1ObjectIdentifier[] first = cache[idx1];
- if (first == null)
+ if (oid != null)
{
- first = cache[idx1] = new ASN1ObjectIdentifier[128];
+ return oid;
}
-
- possibleMatch = first[idx2];
- if (possibleMatch == null)
+ else
{
- return first[idx2] = new ASN1ObjectIdentifier(enc);
+ pool.put(hdl, this);
+ return this;
}
+ }
+ }
- if (Arrays.areEqual(enc, possibleMatch.getBody()))
- {
- return possibleMatch;
- }
+ private static final Map pool = new HashMap();
- idx1 = (idx1 + 1) & 0xff;
- first = cache[idx1];
- if (first == null)
- {
- first = cache[idx1] = new ASN1ObjectIdentifier[128];
- }
+ private static class OidHandle
+ {
+ private int key;
+ private final byte[] enc;
- possibleMatch = first[idx2];
- if (possibleMatch == null)
- {
- return first[idx2] = new ASN1ObjectIdentifier(enc);
- }
+ OidHandle(byte[] enc)
+ {
+ this.key = Arrays.hashCode(enc);
+ this.enc = enc;
+ }
- if (Arrays.areEqual(enc, possibleMatch.getBody()))
- {
- return possibleMatch;
- }
+ public int hashCode()
+ {
+ return key;
+ }
- idx2 = (idx2 + 1) & 0x7f;
- possibleMatch = first[idx2];
- if (possibleMatch == null)
+ public boolean equals(Object o)
+ {
+ if (o instanceof OidHandle)
{
- return first[idx2] = new ASN1ObjectIdentifier(enc);
+ return Arrays.areEqual(enc, ((OidHandle)o).enc);
}
+
+ return false;
}
+ }
- if (Arrays.areEqual(enc, possibleMatch.getBody()))
+ static ASN1ObjectIdentifier fromOctetString(byte[] enc)
+ {
+ OidHandle hdl = new OidHandle(enc);
+
+ synchronized (pool)
{
- return possibleMatch;
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)pool.get(hdl);
+ if (oid != null)
+ {
+ return oid;
+ }
}
return new ASN1ObjectIdentifier(enc);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java
index 200b66a3..a3fa4a41 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java
@@ -63,14 +63,14 @@ import org.bouncycastle.util.encoders.Hex;
* each encoding in the contents octets may itself
* be primitive or constructed.
* However, such encodings will usually be primitive.
- * </p><p>
+ * <br />
* NOTE 2 &mdash; In particular, the tags in the contents octets are always universal class, number 4.
* </blockquote>
* </p>
* <p><b>9: Canonical encoding rules</b></p>
* <p><b>9.1 Length forms</b></p>
* <p>
- * If the encoding is constructed, it shall employ the indefinite length form.
+ * If the encoding is constructed, it shall employ the indefinite-length form.
* If the encoding is primitive, it shall include the fewest length octets necessary.
* [Contrast with 8.1.3.2 b).]
* </p>
@@ -83,7 +83,7 @@ import org.bouncycastle.util.encoders.Hex;
* the constructed encoding shall be encoded with a primitive encoding.
* The encoding of each fragment, except possibly
* the last, shall have 1000 contents octets. (Contrast with 8.21.6.)
- * </p>
+ * </p><p>
* <b>10: Distinguished encoding rules</b>
* </p><p>
* <b>10.1 Length forms</b>
@@ -166,6 +166,8 @@ public abstract class ASN1OctetString
}
/**
+ * Base constructor.
+ *
* @param string the octets making up the octet string.
*/
public ASN1OctetString(
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Primitive.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Primitive.java
index 3c887e55..db72d6ad 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Primitive.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Primitive.java
@@ -18,7 +18,7 @@ public abstract class ASN1Primitive
*
* @param data the byte stream to parse.
* @return the base ASN.1 object represented by the byte stream.
- * @exception IOException if there is a problem parsing the data.
+ * @exception IOException if there is a problem parsing the data, or parsing the stream did not exhaust the available data.
*/
public static ASN1Primitive fromByteArray(byte[] data)
throws IOException
@@ -27,7 +27,14 @@ public abstract class ASN1Primitive
try
{
- return aIn.readObject();
+ ASN1Primitive o = aIn.readObject();
+
+ if (aIn.available() != 0)
+ {
+ throw new IOException("Extra data detected in stream");
+ }
+
+ return o;
}
catch (ClassCastException e)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Sequence.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Sequence.java
index aa543f28..0ca4d8f5 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Sequence.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Sequence.java
@@ -2,8 +2,11 @@ package org.bouncycastle.asn1;
import java.io.IOException;
import java.util.Enumeration;
+import java.util.Iterator;
import java.util.Vector;
+import org.bouncycastle.util.Arrays;
+
/**
* ASN.1 <code>SEQUENCE</code> and <code>SEQUENCE OF</code> constructs.
* <p>
@@ -41,7 +44,7 @@ import java.util.Vector;
* </p>
* <p><b>9: Canonical encoding rules</b></p>
* <p><b>9.1 Length forms</b></p>
- * If the encoding is constructed, it shall employ the indefinite length form.
+ * If the encoding is constructed, it shall employ the indefinite-length form.
* If the encoding is primitive, it shall include the fewest length octets necessary.
* [Contrast with 8.1.3.2 b).]
*
@@ -53,6 +56,7 @@ import java.util.Vector;
*/
public abstract class ASN1Sequence
extends ASN1Primitive
+ implements org.bouncycastle.util.Iterable<ASN1Encodable>
{
protected Vector seq = new Vector();
@@ -188,7 +192,7 @@ public abstract class ASN1Sequence
}
}
- /**
+ /*
* Create a sequence containing a vector of objects.
*/
protected ASN1Sequence(
@@ -379,4 +383,9 @@ public abstract class ASN1Sequence
{
return seq.toString();
}
+
+ public Iterator<ASN1Encodable> iterator()
+ {
+ return new Arrays.Iterator<ASN1Encodable>(toArray());
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java
index b4d263a3..1f6234f5 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Set.java
@@ -1,10 +1,12 @@
package org.bouncycastle.asn1;
-import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Enumeration;
+import java.util.Iterator;
import java.util.Vector;
+import org.bouncycastle.util.Arrays;
+
/**
* ASN.1 <code>SET</code> and <code>SET OF</code> constructs.
* <p>
@@ -48,7 +50,7 @@ import java.util.Vector;
*
* <h3>9: Canonical encoding rules</h3>
* <h4>9.1 Length forms</h4>
- * If the encoding is constructed, it shall employ the indefinite length form.
+ * If the encoding is constructed, it shall employ the indefinite-length form.
* If the encoding is primitive, it shall include the fewest length octets necessary.
* [Contrast with 8.1.3.2 b).]
* <h4>9.3 Set components</h4>
@@ -94,6 +96,7 @@ import java.util.Vector;
*/
public abstract class ASN1Set
extends ASN1Primitive
+ implements org.bouncycastle.util.Iterable<ASN1Encodable>
{
private Vector set = new Vector();
private boolean isSorted = false;
@@ -252,7 +255,7 @@ public abstract class ASN1Set
}
}
- /**
+ /*
* create a sequence containing a vector of objects.
*/
protected ASN1Set(
@@ -552,4 +555,9 @@ public abstract class ASN1Set
{
return set.toString();
}
+
+ public Iterator<ASN1Encodable> iterator()
+ {
+ return new Arrays.Iterator<ASN1Encodable>(toArray());
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java
index 418c1016..a4bb370e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1StreamParser.java
@@ -61,7 +61,7 @@ public class ASN1StreamParser
{
if (!constructed)
{
- throw new IOException("indefinite length primitive encoding encountered");
+ throw new IOException("indefinite-length primitive encoding encountered");
}
return readIndef(tag);
@@ -92,8 +92,7 @@ public class ASN1StreamParser
}
}
- // TODO ASN1Exception
- throw new RuntimeException("implicit tagging not implemented");
+ throw new ASN1Exception("implicit tagging not implemented");
}
ASN1Primitive readTaggedObject(boolean constructed, int tag) throws IOException
@@ -145,11 +144,11 @@ public class ASN1StreamParser
//
int length = ASN1InputStream.readLength(_in, _limit);
- if (length < 0) // indefinite length method
+ if (length < 0) // indefinite-length method
{
if (!isConstructed)
{
- throw new IOException("indefinite length primitive encoding encountered");
+ throw new IOException("indefinite-length primitive encoding encountered");
}
IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(_in, _limit);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1String.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1String.java
index fde4e239..37544406 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1String.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1String.java
@@ -1,6 +1,13 @@
package org.bouncycastle.asn1;
+/**
+ * General interface implemented by ASN.1 STRING objects.
+ */
public interface ASN1String
{
+ /**
+ * Return a Java String representation of this STRING type's content.
+ * @return a Java String representation of this STRING.
+ */
public String getString();
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java
index fb1e2442..778bea74 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java
@@ -192,6 +192,7 @@ public abstract class ASN1TaggedObject
public ASN1Encodable getObjectParser(
int tag,
boolean isExplicit)
+ throws IOException
{
switch (tag)
{
@@ -208,7 +209,7 @@ public abstract class ASN1TaggedObject
return getObject();
}
- throw new RuntimeException("implicit tagging not implemented for tag: " + tag);
+ throw new ASN1Exception("implicit tagging not implemented for tag: " + tag);
}
public ASN1Primitive getLoadedObject()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecific.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecific.java
index 8bc8a4eb..f8d6aa22 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecific.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecific.java
@@ -1,10 +1,114 @@
package org.bouncycastle.asn1;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * An indefinite-length encoding version of an application specific object.
+ */
public class BERApplicationSpecific
- extends DERApplicationSpecific
+ extends ASN1ApplicationSpecific
{
+ BERApplicationSpecific(
+ boolean isConstructed,
+ int tag,
+ byte[] octets)
+ {
+ super(isConstructed, tag, octets);
+ }
+
+ /**
+ * Create an application specific object with a tagging of explicit/constructed.
+ *
+ * @param tag the tag number for this object.
+ * @param object the object to be contained.
+ */
+ public BERApplicationSpecific(
+ int tag,
+ ASN1Encodable object)
+ throws IOException
+ {
+ this(true, tag, object);
+ }
+
+ /**
+ * Create an application specific object with the tagging style given by the value of constructed.
+ *
+ * @param constructed true if the object is constructed.
+ * @param tag the tag number for this object.
+ * @param object the object to be contained.
+ */
+ public BERApplicationSpecific(
+ boolean constructed,
+ int tag,
+ ASN1Encodable object)
+ throws IOException
+ {
+ super(constructed || object.toASN1Primitive().isConstructed(), tag, getEncoding(constructed, object));
+ }
+
+ private static byte[] getEncoding(boolean explicit, ASN1Encodable object)
+ throws IOException
+ {
+ byte[] data = object.toASN1Primitive().getEncoded(ASN1Encoding.BER);
+
+ if (explicit)
+ {
+ return data;
+ }
+ else
+ {
+ int lenBytes = getLengthOfHeader(data);
+ byte[] tmp = new byte[data.length - lenBytes];
+ System.arraycopy(data, lenBytes, tmp, 0, tmp.length);
+ return tmp;
+ }
+ }
+
+ /**
+ * Create an application specific object which is marked as constructed
+ *
+ * @param tagNo the tag number for this object.
+ * @param vec the objects making up the application specific object.
+ */
public BERApplicationSpecific(int tagNo, ASN1EncodableVector vec)
{
- super(tagNo, vec);
+ super(true, tagNo, getEncodedVector(vec));
+ }
+
+ private static byte[] getEncodedVector(ASN1EncodableVector vec)
+ {
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ for (int i = 0; i != vec.size(); i++)
+ {
+ try
+ {
+ bOut.write(((ASN1Object)vec.get(i)).getEncoded(ASN1Encoding.BER));
+ }
+ catch (IOException e)
+ {
+ throw new ASN1ParsingException("malformed object: " + e, e);
+ }
+ }
+ return bOut.toByteArray();
+ }
+
+ /* (non-Javadoc)
+ * @see org.bouncycastle.asn1.ASN1Primitive#encode(org.bouncycastle.asn1.DEROutputStream)
+ */
+ void encode(ASN1OutputStream out) throws IOException
+ {
+ int classBits = BERTags.APPLICATION;
+ if (isConstructed)
+ {
+ classBits |= BERTags.CONSTRUCTED;
+ }
+
+ out.writeTag(classBits, tag);
+ out.write(0x80);
+ out.write(octets);
+ out.write(0x00);
+ out.write(0x00);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecificParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecificParser.java
index 63bd9f3d..e4904e05 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecificParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERApplicationSpecificParser.java
@@ -2,6 +2,9 @@ package org.bouncycastle.asn1;
import java.io.IOException;
+/**
+ * A parser for indefinite-length application specific objects.
+ */
public class BERApplicationSpecificParser
implements ASN1ApplicationSpecificParser
{
@@ -14,18 +17,34 @@ public class BERApplicationSpecificParser
this.parser = parser;
}
+ /**
+ * Return the object contained in this application specific object,
+ * @return the contained object.
+ * @throws IOException if the underlying stream cannot be read, or does not contain an ASN.1 encoding.
+ */
public ASN1Encodable readObject()
throws IOException
{
return parser.readObject();
}
+ /**
+ * Return an in-memory, encodable, representation of the application specific object.
+ *
+ * @return a BERApplicationSpecific.
+ * @throws IOException if there is an issue loading the data.
+ */
public ASN1Primitive getLoadedObject()
throws IOException
{
return new BERApplicationSpecific(tag, parser.readVector());
}
+ /**
+ * Return a BERApplicationSpecific representing this parser and its contents.
+ *
+ * @return a BERApplicationSpecific
+ */
public ASN1Primitive toASN1Primitive()
{
try
@@ -37,5 +56,4 @@ public class BERApplicationSpecificParser
throw new ASN1ParsingException(e.getMessage(), e);
}
}
-
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERGenerator.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERGenerator.java
index ef7f9a38..c855110f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERGenerator.java
@@ -1,23 +1,25 @@
package org.bouncycastle.asn1;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
+/**
+ * Base class for generators for indefinite-length structures.
+ */
public class BERGenerator
extends ASN1Generator
{
private boolean _tagged = false;
private boolean _isExplicit;
private int _tagNo;
-
+
protected BERGenerator(
OutputStream out)
{
super(out);
}
- public BERGenerator(
+ protected BERGenerator(
OutputStream out,
int tagNo,
boolean isExplicit)
@@ -72,18 +74,6 @@ public class BERGenerator
writeHdr(tag);
}
}
-
- protected void writeBERBody(
- InputStream contentStream)
- throws IOException
- {
- int ch;
-
- while ((ch = contentStream.read()) >= 0)
- {
- _out.write(ch);
- }
- }
protected void writeBEREnd()
throws IOException
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERSequence.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERSequence.java
index aa44950f..d4bfa061 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERSequence.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERSequence.java
@@ -3,18 +3,21 @@ package org.bouncycastle.asn1;
import java.io.IOException;
import java.util.Enumeration;
+/**
+ * Carrier class for an indefinite-length SEQUENCE.
+ */
public class BERSequence
extends ASN1Sequence
{
/**
- * create an empty sequence
+ * Create an empty sequence
*/
public BERSequence()
{
}
/**
- * create a sequence containing one object
+ * Create a sequence containing one object
*/
public BERSequence(
ASN1Encodable obj)
@@ -23,7 +26,7 @@ public class BERSequence
}
/**
- * create a sequence containing a vector of objects.
+ * Create a sequence containing a vector of objects.
*/
public BERSequence(
ASN1EncodableVector v)
@@ -32,7 +35,7 @@ public class BERSequence
}
/**
- * create a sequence containing an array of objects.
+ * Create a sequence containing an array of objects.
*/
public BERSequence(
ASN1Encodable[] array)
@@ -52,8 +55,6 @@ public class BERSequence
return 2 + length + 2;
}
- /*
- */
void encode(
ASN1OutputStream out)
throws IOException
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERSequenceParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERSequenceParser.java
index d5d43959..543a182e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERSequenceParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERSequenceParser.java
@@ -2,6 +2,9 @@ package org.bouncycastle.asn1;
import java.io.IOException;
+/**
+ * Parser for indefinite-length SEQUENCEs.
+ */
public class BERSequenceParser
implements ASN1SequenceParser
{
@@ -12,18 +15,35 @@ public class BERSequenceParser
this._parser = parser;
}
+ /**
+ * Read the next object in the SEQUENCE.
+ *
+ * @return the next object in the SEQUENCE, null if there are no more.
+ * @throws IOException if there is an issue reading the underlying stream.
+ */
public ASN1Encodable readObject()
throws IOException
{
return _parser.readObject();
}
+ /**
+ * Return an in-memory, encodable, representation of the SEQUENCE.
+ *
+ * @return a BERSequence.
+ * @throws IOException if there is an issue loading the data.
+ */
public ASN1Primitive getLoadedObject()
throws IOException
{
return new BERSequence(_parser.readVector());
}
-
+
+ /**
+ * Return an BERSequence representing this parser and its contents.
+ *
+ * @return an BERSequence
+ */
public ASN1Primitive toASN1Primitive()
{
try
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERSet.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERSet.java
index 064d7786..63a276bb 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERSet.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERSet.java
@@ -3,17 +3,22 @@ package org.bouncycastle.asn1;
import java.io.IOException;
import java.util.Enumeration;
+/**
+ * Carrier class for an indefinite-length SET.
+ */
public class BERSet
extends ASN1Set
{
/**
- * create an empty sequence
+ * Create an empty SET.
*/
public BERSet()
{
}
/**
+ * Create a SET containing one object.
+ *
* @param obj - a single object that makes up the set.
*/
public BERSet(
@@ -23,7 +28,8 @@ public class BERSet
}
/**
- * @param v - a vector of objects making up the set.
+ * Create a SET containing multiple objects.
+ * @param v a vector of objects making up the set.
*/
public BERSet(
ASN1EncodableVector v)
@@ -32,7 +38,8 @@ public class BERSet
}
/**
- * create a set from an array of objects.
+ * Create a SET from an array of objects.
+ * @param a an array of ASN.1 objects.
*/
public BERSet(
ASN1Encodable[] a)
@@ -52,8 +59,6 @@ public class BERSet
return 2 + length + 2;
}
- /*
- */
void encode(
ASN1OutputStream out)
throws IOException
@@ -70,4 +75,4 @@ public class BERSet
out.write(0x00);
out.write(0x00);
}
-}
+} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERSetParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERSetParser.java
index 5a30f3cf..c6e18095 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERSetParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERSetParser.java
@@ -2,6 +2,9 @@ package org.bouncycastle.asn1;
import java.io.IOException;
+/**
+ * Parser for indefinite-length SETs.
+ */
public class BERSetParser
implements ASN1SetParser
{
@@ -12,18 +15,35 @@ public class BERSetParser
this._parser = parser;
}
+ /**
+ * Read the next object in the SET.
+ *
+ * @return the next object in the SET, null if there are no more.
+ * @throws IOException if there is an issue reading the underlying stream.
+ */
public ASN1Encodable readObject()
throws IOException
{
return _parser.readObject();
}
+ /**
+ * Return an in-memory, encodable, representation of the SET.
+ *
+ * @return a BERSet.
+ * @throws IOException if there is an issue loading the data.
+ */
public ASN1Primitive getLoadedObject()
throws IOException
{
return new BERSet(_parser.readVector());
}
+ /**
+ * Return an BERSet representing this parser and its contents.
+ *
+ * @return an BERSet
+ */
public ASN1Primitive toASN1Primitive()
{
try
@@ -35,4 +55,4 @@ public class BERSetParser
throw new ASN1ParsingException(e.getMessage(), e);
}
}
-}
+} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObjectParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObjectParser.java
index 7cd334a4..02f3f265 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObjectParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObjectParser.java
@@ -2,6 +2,9 @@ package org.bouncycastle.asn1;
import java.io.IOException;
+/**
+ * Parser for indefinite-length tagged objects.
+ */
public class BERTaggedObjectParser
implements ASN1TaggedObjectParser
{
@@ -19,16 +22,34 @@ public class BERTaggedObjectParser
_parser = parser;
}
+ /**
+ * Return true if this tagged object is marked as constructed.
+ *
+ * @return true if constructed, false otherwise.
+ */
public boolean isConstructed()
{
return _constructed;
}
+ /**
+ * Return the tag number associated with this object.
+ *
+ * @return the tag number.
+ */
public int getTagNo()
{
return _tagNumber;
}
+ /**
+ * Return an object parser for the contents of this tagged object.
+ *
+ * @param tag the actual tag number of the object (needed if implicit).
+ * @param isExplicit true if the contained object was explicitly tagged, false if implicit.
+ * @return an ASN.1 encodable object parser.
+ * @throws IOException if there is an issue building the object parser from the stream.
+ */
public ASN1Encodable getObjectParser(
int tag,
boolean isExplicit)
@@ -46,12 +67,23 @@ public class BERTaggedObjectParser
return _parser.readImplicit(_constructed, tag);
}
+ /**
+ * Return an in-memory, encodable, representation of the tagged object.
+ *
+ * @return an ASN1TaggedObject.
+ * @throws IOException if there is an issue loading the data.
+ */
public ASN1Primitive getLoadedObject()
throws IOException
{
return _parser.readTaggedObject(_constructed, _tagNumber);
}
+ /**
+ * Return an ASN1TaggedObject representing this parser and its contents.
+ *
+ * @return an ASN1TaggedObject
+ */
public ASN1Primitive toASN1Primitive()
{
try
@@ -63,4 +95,4 @@ public class BERTaggedObjectParser
throw new ASN1ParsingException(e.getMessage());
}
}
-}
+} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERApplicationSpecific.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERApplicationSpecific.java
index 85d9843b..a5999c09 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERApplicationSpecific.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERApplicationSpecific.java
@@ -3,28 +3,27 @@ package org.bouncycastle.asn1;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import org.bouncycastle.util.Arrays;
-
/**
- * Base class for an application specific object
+ * A DER encoding version of an application specific object.
*/
public class DERApplicationSpecific
- extends ASN1Primitive
+ extends ASN1ApplicationSpecific
{
- private final boolean isConstructed;
- private final int tag;
- private final byte[] octets;
-
DERApplicationSpecific(
boolean isConstructed,
int tag,
byte[] octets)
{
- this.isConstructed = isConstructed;
- this.tag = tag;
- this.octets = octets;
+ super(isConstructed, tag, octets);
}
+ /**
+ * Create an application specific object from the passed in data. This will assume
+ * the data does not represent a constructed object.
+ *
+ * @param tag the tag number for this object.
+ * @param octets the encoding of the object's body.
+ */
public DERApplicationSpecific(
int tag,
byte[] octets)
@@ -32,44 +31,67 @@ public class DERApplicationSpecific
this(false, tag, octets);
}
+ /**
+ * Create an application specific object with a tagging of explicit/constructed.
+ *
+ * @param tag the tag number for this object.
+ * @param object the object to be contained.
+ */
public DERApplicationSpecific(
- int tag,
+ int tag,
ASN1Encodable object)
throws IOException
{
this(true, tag, object);
}
+ /**
+ * Create an application specific object with the tagging style given by the value of constructed.
+ *
+ * @param constructed true if the object is constructed.
+ * @param tag the tag number for this object.
+ * @param object the object to be contained.
+ */
public DERApplicationSpecific(
- boolean explicit,
+ boolean constructed,
int tag,
ASN1Encodable object)
throws IOException
{
- ASN1Primitive primitive = object.toASN1Primitive();
-
- byte[] data = primitive.getEncoded(ASN1Encoding.DER);
+ super(constructed || object.toASN1Primitive().isConstructed(), tag, getEncoding(constructed, object));
+ }
- this.isConstructed = explicit || (primitive instanceof ASN1Set || primitive instanceof ASN1Sequence);
- this.tag = tag;
+ private static byte[] getEncoding(boolean explicit, ASN1Encodable object)
+ throws IOException
+ {
+ byte[] data = object.toASN1Primitive().getEncoded(ASN1Encoding.DER);
if (explicit)
{
- this.octets = data;
+ return data;
}
else
{
int lenBytes = getLengthOfHeader(data);
byte[] tmp = new byte[data.length - lenBytes];
System.arraycopy(data, lenBytes, tmp, 0, tmp.length);
- this.octets = tmp;
+ return tmp;
}
}
+ /**
+ * Create an application specific object which is marked as constructed
+ *
+ * @param tagNo the tag number for this object.
+ * @param vec the objects making up the application specific object.
+ */
public DERApplicationSpecific(int tagNo, ASN1EncodableVector vec)
{
- this.tag = tagNo;
- this.isConstructed = true;
+ super(true, tagNo, getEncodedVector(vec));
+ }
+
+ private static byte[] getEncodedVector(ASN1EncodableVector vec)
+ {
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
for (int i = 0; i != vec.size(); i++)
@@ -83,112 +105,7 @@ public class DERApplicationSpecific
throw new ASN1ParsingException("malformed object: " + e, e);
}
}
- this.octets = bOut.toByteArray();
- }
-
- public static DERApplicationSpecific getInstance(Object obj)
- {
- if (obj == null || obj instanceof DERApplicationSpecific)
- {
- return (DERApplicationSpecific)obj;
- }
- else if (obj instanceof byte[])
- {
- try
- {
- return DERApplicationSpecific.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
- }
- catch (IOException e)
- {
- throw new IllegalArgumentException("failed to construct object from byte[]: " + e.getMessage());
- }
- }
-
- throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
- }
-
- private int getLengthOfHeader(byte[] data)
- {
- int length = data[1] & 0xff; // TODO: assumes 1 byte tag
-
- if (length == 0x80)
- {
- return 2; // indefinite-length encoding
- }
-
- if (length > 127)
- {
- int size = length & 0x7f;
-
- // Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
- if (size > 4)
- {
- throw new IllegalStateException("DER length more than 4 bytes: " + size);
- }
-
- return size + 2;
- }
-
- return 2;
- }
-
- public boolean isConstructed()
- {
- return isConstructed;
- }
-
- public byte[] getContents()
- {
- return octets;
- }
-
- public int getApplicationTag()
- {
- return tag;
- }
-
- /**
- * Return the enclosed object assuming explicit tagging.
- *
- * @return the resulting object
- * @throws IOException if reconstruction fails.
- */
- public ASN1Primitive getObject()
- throws IOException
- {
- return new ASN1InputStream(getContents()).readObject();
- }
-
- /**
- * Return the enclosed object assuming implicit tagging.
- *
- * @param derTagNo the type tag that should be applied to the object's contents.
- * @return the resulting object
- * @throws IOException if reconstruction fails.
- */
- public ASN1Primitive getObject(int derTagNo)
- throws IOException
- {
- if (derTagNo >= 0x1f)
- {
- throw new IOException("unsupported tag number");
- }
-
- byte[] orig = this.getEncoded();
- byte[] tmp = replaceTagNumber(derTagNo, orig);
-
- if ((orig[0] & BERTags.CONSTRUCTED) != 0)
- {
- tmp[0] |= BERTags.CONSTRUCTED;
- }
-
- return new ASN1InputStream(tmp).readObject();
- }
-
- int encodedLength()
- throws IOException
- {
- return StreamUtil.calculateTagLength(tag) + StreamUtil.calculateBodyLength(octets.length) + octets.length;
+ return bOut.toByteArray();
}
/* (non-Javadoc)
@@ -204,64 +121,4 @@ public class DERApplicationSpecific
out.writeEncoded(classBits, tag, octets);
}
-
- boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERApplicationSpecific))
- {
- return false;
- }
-
- DERApplicationSpecific other = (DERApplicationSpecific)o;
-
- return isConstructed == other.isConstructed
- && tag == other.tag
- && Arrays.areEqual(octets, other.octets);
- }
-
- public int hashCode()
- {
- return (isConstructed ? 1 : 0) ^ tag ^ Arrays.hashCode(octets);
- }
-
- private byte[] replaceTagNumber(int newTag, byte[] input)
- throws IOException
- {
- int tagNo = input[0] & 0x1f;
- int index = 1;
- //
- // with tagged object tag number is bottom 5 bits, or stored at the start of the content
- //
- if (tagNo == 0x1f)
- {
- tagNo = 0;
-
- int b = input[index++] & 0xff;
-
- // X.690-0207 8.1.2.4.2
- // "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
- if ((b & 0x7f) == 0) // Note: -1 will pass
- {
- throw new ASN1ParsingException("corrupted stream - invalid high tag number found");
- }
-
- while ((b >= 0) && ((b & 0x80) != 0))
- {
- tagNo |= (b & 0x7f);
- tagNo <<= 7;
- b = input[index++] & 0xff;
- }
-
- tagNo |= (b & 0x7f);
- }
-
- byte[] tmp = new byte[input.length - index + 1];
-
- System.arraycopy(input, index, tmp, 1, tmp.length - 1);
-
- tmp[0] = (byte)newTag;
-
- return tmp;
- }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERBMPString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERBMPString.java
index 635300b4..e689985c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERBMPString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERBMPString.java
@@ -5,13 +5,13 @@ import java.io.IOException;
import org.bouncycastle.util.Arrays;
/**
- * DER BMPString object.
+ * Carrier class for DER encoding BMPString object.
*/
public class DERBMPString
extends ASN1Primitive
implements ASN1String
{
- private char[] string;
+ private final char[] string;
/**
* return a BMP String from the given object.
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java
index 4852a796..d74bc00e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java
@@ -1,97 +1,13 @@
package org.bouncycastle.asn1;
-import java.io.ByteArrayOutputStream;
-import java.io.EOFException;
import java.io.IOException;
-import java.io.InputStream;
-
-import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.io.Streams;
+/**
+ * A BIT STRING with DER encoding.
+ */
public class DERBitString
- extends ASN1Primitive
- implements ASN1String
+ extends ASN1BitString
{
- private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
-
- protected byte[] data;
- protected int padBits;
-
- /**
- * @param bitString an int containing the BIT STRING
- * @return the correct number of pad bits for a bit string defined in
- * a 32 bit constant
- */
- static protected int getPadBits(
- int bitString)
- {
- int val = 0;
- for (int i = 3; i >= 0; i--)
- {
- //
- // this may look a little odd, but if it isn't done like this pre jdk1.2
- // JVM's break!
- //
- if (i != 0)
- {
- if ((bitString >> (i * 8)) != 0)
- {
- val = (bitString >> (i * 8)) & 0xFF;
- break;
- }
- }
- else
- {
- if (bitString != 0)
- {
- val = bitString & 0xFF;
- break;
- }
- }
- }
-
- if (val == 0)
- {
- return 7;
- }
-
-
- int bits = 1;
-
- while (((val <<= 1) & 0xFF) != 0)
- {
- bits++;
- }
-
- return 8 - bits;
- }
-
- /**
- * @param bitString an int containing the BIT STRING
- * @return the correct number of bytes for a bit string defined in
- * a 32 bit constant
- */
- static protected byte[] getBytes(int bitString)
- {
- int bytes = 4;
- for (int i = 3; i >= 1; i--)
- {
- if ((bitString & (0xFF << (i * 8))) != 0)
- {
- break;
- }
- bytes--;
- }
-
- byte[] result = new byte[bytes];
- for (int i = 0; i < bytes; i++)
- {
- result[i] = (byte) ((bitString >> (i * 8)) & 0xFF);
- }
-
- return result;
- }
-
/**
* return a Bit String from the passed in object
*
@@ -106,6 +22,10 @@ public class DERBitString
{
return (DERBitString)obj;
}
+ if (obj instanceof DLBitString)
+ {
+ return new DERBitString(((DLBitString)obj).data, ((DLBitString)obj).padBits);
+ }
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
@@ -140,9 +60,16 @@ public class DERBitString
byte data,
int padBits)
{
- this.data = new byte[1];
- this.data[0] = data;
- this.padBits = padBits;
+ this(toByteArray(data), padBits);
+ }
+
+ private static byte[] toByteArray(byte data)
+ {
+ byte[] rv = new byte[1];
+
+ rv[0] = data;
+
+ return rv;
}
/**
@@ -153,8 +80,7 @@ public class DERBitString
byte[] data,
int padBits)
{
- this.data = data;
- this.padBits = padBits;
+ super(data, padBits);
}
public DERBitString(
@@ -166,42 +92,14 @@ public class DERBitString
public DERBitString(
int value)
{
- this.data = getBytes(value);
- this.padBits = getPadBits(value);
+ super(getBytes(value), getPadBits(value));
}
public DERBitString(
ASN1Encodable obj)
throws IOException
{
- this.data = obj.toASN1Primitive().getEncoded(ASN1Encoding.DER);
- this.padBits = 0;
- }
-
- public byte[] getBytes()
- {
- return data;
- }
-
- public int getPadBits()
- {
- return padBits;
- }
-
-
- /**
- * @return the value of the bit string as an int (truncating if necessary)
- */
- public int intValue()
- {
- int value = 0;
-
- for (int i = 0; i != data.length && i != 4; i++)
- {
- value |= (data[i] & 0xff) << (8 * i);
- }
-
- return value;
+ super(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER), 0);
}
boolean isConstructed()
@@ -218,64 +116,15 @@ public class DERBitString
ASN1OutputStream out)
throws IOException
{
- byte[] bytes = new byte[getBytes().length + 1];
+ byte[] string = derForm(data, padBits);
+ byte[] bytes = new byte[string.length + 1];
bytes[0] = (byte)getPadBits();
- System.arraycopy(getBytes(), 0, bytes, 1, bytes.length - 1);
+ System.arraycopy(string, 0, bytes, 1, bytes.length - 1);
out.writeEncoded(BERTags.BIT_STRING, bytes);
}
- public int hashCode()
- {
- return padBits ^ Arrays.hashCode(data);
- }
-
- protected boolean asn1Equals(
- ASN1Primitive o)
- {
- if (!(o instanceof DERBitString))
- {
- return false;
- }
-
- DERBitString other = (DERBitString)o;
-
- return this.padBits == other.padBits
- && Arrays.areEqual(this.data, other.data);
- }
-
- public String getString()
- {
- StringBuffer buf = new StringBuffer("#");
- ByteArrayOutputStream bOut = new ByteArrayOutputStream();
- ASN1OutputStream aOut = new ASN1OutputStream(bOut);
-
- try
- {
- aOut.writeObject(this);
- }
- catch (IOException e)
- {
- throw new RuntimeException("internal error encoding BitString");
- }
-
- byte[] string = bOut.toByteArray();
-
- for (int i = 0; i != string.length; i++)
- {
- buf.append(table[(string[i] >>> 4) & 0xf]);
- buf.append(table[string[i] & 0xf]);
- }
-
- return buf.toString();
- }
-
- public String toString()
- {
- return getString();
- }
-
static DERBitString fromOctetString(byte[] bytes)
{
if (bytes.length < 1)
@@ -293,26 +142,4 @@ public class DERBitString
return new DERBitString(data, padBits);
}
-
- static DERBitString fromInputStream(int length, InputStream stream)
- throws IOException
- {
- if (length < 1)
- {
- throw new IllegalArgumentException("truncated BIT STRING detected");
- }
-
- int padBits = stream.read();
- byte[] data = new byte[length - 1];
-
- if (data.length != 0)
- {
- if (Streams.readFully(stream, data) != data.length)
- {
- throw new EOFException("EOF encountered in middle of BIT STRING");
- }
- }
-
- return new DERBitString(data, padBits);
- }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DEREncodableVector.java b/bcprov/src/main/java/org/bouncycastle/asn1/DEREncodableVector.java
index 919ff72d..ff1059ac 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DEREncodableVector.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DEREncodableVector.java
@@ -2,7 +2,7 @@ package org.bouncycastle.asn1;
/**
* a general class for building up a vector of DER encodable objects -
- * this will eventually be superceded by ASN1EncodableVector so you should
+ * this will eventually be superseded by ASN1EncodableVector so you should
* use that class in preference.
*/
public class DEREncodableVector
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERExternal.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERExternal.java
index aed1d27f..f6c45d31 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERExternal.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERExternal.java
@@ -32,7 +32,7 @@ public class DERExternal
offset++;
enc = getObjFromVector(vector, offset);
}
- if (!(enc instanceof DERTaggedObject))
+ if (!(enc instanceof ASN1TaggedObject))
{
dataValueDescriptor = (ASN1Primitive) enc;
offset++;
@@ -44,11 +44,11 @@ public class DERExternal
throw new IllegalArgumentException("input vector too large");
}
- if (!(enc instanceof DERTaggedObject))
+ if (!(enc instanceof ASN1TaggedObject))
{
throw new IllegalArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External");
}
- DERTaggedObject obj = (DERTaggedObject)enc;
+ ASN1TaggedObject obj = (ASN1TaggedObject)enc;
setEncoding(obj.getTagNo());
externalContent = obj.getObject();
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERExternalParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERExternalParser.java
index b19c84d5..98d02e73 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERExternalParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERExternalParser.java
@@ -2,13 +2,18 @@ package org.bouncycastle.asn1;
import java.io.IOException;
+/**
+ * Parser DER EXTERNAL tagged objects.
+ */
public class DERExternalParser
implements ASN1Encodable, InMemoryRepresentable
{
private ASN1StreamParser _parser;
/**
- *
+ * Base constructor.
+ *
+ * @param parser the underlying parser to read the DER EXTERNAL from.
*/
public DERExternalParser(ASN1StreamParser parser)
{
@@ -21,6 +26,12 @@ public class DERExternalParser
return _parser.readObject();
}
+ /**
+ * Return an in-memory, encodable, representation of the EXTERNAL object.
+ *
+ * @return a DERExternal.
+ * @throws IOException if there is an issue loading the data.
+ */
public ASN1Primitive getLoadedObject()
throws IOException
{
@@ -33,20 +44,25 @@ public class DERExternalParser
throw new ASN1Exception(e.getMessage(), e);
}
}
-
+
+ /**
+ * Return an DERExternal representing this parser and its contents.
+ *
+ * @return an DERExternal
+ */
public ASN1Primitive toASN1Primitive()
{
- try
+ try
{
return getLoadedObject();
}
- catch (IOException ioe)
+ catch (IOException ioe)
{
throw new ASN1ParsingException("unable to get DER object", ioe);
}
- catch (IllegalArgumentException ioe)
+ catch (IllegalArgumentException ioe)
{
throw new ASN1ParsingException("unable to get DER object", ioe);
}
}
-}
+} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralString.java
index c6354f46..9addf700 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERGeneralString.java
@@ -5,12 +5,22 @@ import java.io.IOException;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Strings;
+/**
+ * Carrier class for a DER encoding GeneralString
+ */
public class DERGeneralString
extends ASN1Primitive
implements ASN1String
{
- private byte[] string;
-
+ private final byte[] string;
+
+ /**
+ * return a GeneralString from the given object.
+ *
+ * @param obj the object we want converted.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return a DERBMPString instance, or null.
+ */
public static DERGeneralString getInstance(
Object obj)
{
@@ -35,6 +45,16 @@ public class DERGeneralString
+ obj.getClass().getName());
}
+ /**
+ * return a GeneralString from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return a DERGeneralString instance.
+ */
public static DERGeneralString getInstance(
ASN1TaggedObject obj,
boolean explicit)
@@ -56,11 +76,21 @@ public class DERGeneralString
this.string = string;
}
+ /**
+ * Construct a GeneralString from the passed in String.
+ *
+ * @param string the string to be contained in this object.
+ */
public DERGeneralString(String string)
{
this.string = Strings.toByteArray(string);
}
-
+
+ /**
+ * Return a Java String representation of our contained String.
+ *
+ * @return a Java String representing our contents.
+ */
public String getString()
{
return Strings.fromByteArray(string);
@@ -71,6 +101,11 @@ public class DERGeneralString
return getString();
}
+ /**
+ * Return a byte array representation of our contained String.
+ *
+ * @return a byte array representing our contents.
+ */
public byte[] getOctets()
{
return Arrays.clone(string);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERGraphicString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERGraphicString.java
new file mode 100644
index 00000000..01baf0f9
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERGraphicString.java
@@ -0,0 +1,124 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Strings;
+
+public class DERGraphicString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ private final byte[] string;
+
+ /**
+ * return a Graphic String from the passed in object
+ *
+ * @param obj a DERGraphicString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return a DERGraphicString instance, or null.
+ */
+ public static DERGraphicString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERGraphicString)
+ {
+ return (DERGraphicString)obj;
+ }
+
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (DERGraphicString)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return a Graphic String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return a DERGraphicString instance, or null.
+ */
+ public static DERGraphicString getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof DERGraphicString)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return new DERGraphicString(((ASN1OctetString)o).getOctets());
+ }
+ }
+
+ /**
+ * basic constructor - with bytes.
+ * @param string the byte encoding of the characters making up the string.
+ */
+ public DERGraphicString(
+ byte[] string)
+ {
+ this.string = Arrays.clone(string);
+ }
+
+ public byte[] getOctets()
+ {
+ return Arrays.clone(string);
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
+ }
+
+ void encode(
+ ASN1OutputStream out)
+ throws IOException
+ {
+ out.writeEncoded(BERTags.GRAPHIC_STRING, string);
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(string);
+ }
+
+ boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (!(o instanceof DERGraphicString))
+ {
+ return false;
+ }
+
+ DERGraphicString s = (DERGraphicString)o;
+
+ return Arrays.areEqual(string, s.string);
+ }
+
+ public String getString()
+ {
+ return Strings.fromByteArray(string);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERIA5String.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERIA5String.java
index 1c533b10..0336e6b7 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERIA5String.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERIA5String.java
@@ -12,7 +12,7 @@ public class DERIA5String
extends ASN1Primitive
implements ASN1String
{
- private byte[] string;
+ private final byte[] string;
/**
* return a IA5 string from the passed in object
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERNumericString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERNumericString.java
index e1b1276d..ed287e56 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERNumericString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERNumericString.java
@@ -12,7 +12,7 @@ public class DERNumericString
extends ASN1Primitive
implements ASN1String
{
- private byte[] string;
+ private final byte[] string;
/**
* return a Numeric string from the passed in object
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DEROctetString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DEROctetString.java
index 988186fb..1201c74e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DEROctetString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DEROctetString.java
@@ -2,10 +2,15 @@ package org.bouncycastle.asn1;
import java.io.IOException;
+/**
+ * Carrier class for a DER encoding OCTET STRING
+ */
public class DEROctetString
extends ASN1OctetString
{
/**
+ * Base constructor.
+ *
* @param string the octets making up the octet string.
*/
public DEROctetString(
@@ -14,6 +19,11 @@ public class DEROctetString
super(string);
}
+ /**
+ * Constructor from the encoding of an ASN.1 object.
+ *
+ * @param obj the object to be encoded.
+ */
public DEROctetString(
ASN1Encodable obj)
throws IOException
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DEROctetStringParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/DEROctetStringParser.java
index e6e20686..58be862d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DEROctetStringParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DEROctetStringParser.java
@@ -3,6 +3,9 @@ package org.bouncycastle.asn1;
import java.io.IOException;
import java.io.InputStream;
+/**
+ * Parse for DER encoded OCTET STRINGS
+ */
public class DEROctetStringParser
implements ASN1OctetStringParser
{
@@ -14,17 +17,33 @@ public class DEROctetStringParser
this.stream = stream;
}
+ /**
+ * Return an InputStream representing the contents of the OCTET STRING.
+ *
+ * @return an InputStream with its source as the OCTET STRING content.
+ */
public InputStream getOctetStream()
{
return stream;
}
+ /**
+ * Return an in-memory, encodable, representation of the OCTET STRING.
+ *
+ * @return a DEROctetString.
+ * @throws IOException if there is an issue loading the data.
+ */
public ASN1Primitive getLoadedObject()
throws IOException
{
return new DEROctetString(stream.toByteArray());
}
-
+
+ /**
+ * Return an DEROctetString representing this parser and its contents.
+ *
+ * @return an DEROctetString
+ */
public ASN1Primitive toASN1Primitive()
{
try
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERPrintableString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERPrintableString.java
index 7d56b492..805ad30e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERPrintableString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERPrintableString.java
@@ -12,9 +12,7 @@ public class DERPrintableString
extends ASN1Primitive
implements ASN1String
{
- // BEGIN android-changed
private final byte[] string;
- // END android-changed
/**
* return a printable string from the passed in object.
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERSequence.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERSequence.java
index ad48a833..b631064d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERSequence.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERSequence.java
@@ -17,6 +17,7 @@ public class DERSequence
/**
* create a sequence containing one object
+ * @param obj the object to go in the sequence.
*/
public DERSequence(
ASN1Encodable obj)
@@ -26,6 +27,7 @@ public class DERSequence
/**
* create a sequence containing a vector of objects.
+ * @param v the vector of objects to make up the sequence.
*/
public DERSequence(
ASN1EncodableVector v)
@@ -35,6 +37,7 @@ public class DERSequence
/**
* create a sequence containing an array of objects.
+ * @param array the array of objects to make up the sequence.
*/
public DERSequence(
ASN1Encodable[] array)
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERSet.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERSet.java
index c1faf849..ac58eacf 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERSet.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERSet.java
@@ -19,7 +19,8 @@ public class DERSet
}
/**
- * @param obj - a single object that makes up the set.
+ * create a set containing one object
+ * @param obj the object to go in the set
*/
public DERSet(
ASN1Encodable obj)
@@ -28,7 +29,8 @@ public class DERSet
}
/**
- * @param v - a vector of objects making up the set.
+ * create a set containing a vector of objects.
+ * @param v the vector of objects to make up the set.
*/
public DERSet(
ASN1EncodableVector v)
@@ -37,7 +39,8 @@ public class DERSet
}
/**
- * create a set from an array of objects.
+ * create a set containing an array of objects.
+ * @param a the array of objects to make up the set.
*/
public DERSet(
ASN1Encodable[] a)
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java
index 783cd336..30744c69 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java
@@ -13,7 +13,7 @@ public class DERT61String
extends ASN1Primitive
implements ASN1String
{
- private byte[] string;
+ private final byte[] string;
/**
* return a T61 string from the passed in object.
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERUTF8String.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERUTF8String.java
index f54d1dbb..d1fffa67 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERUTF8String.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERUTF8String.java
@@ -12,7 +12,7 @@ public class DERUTF8String
extends ASN1Primitive
implements ASN1String
{
- private byte[] string;
+ private final byte[] string;
/**
* Return an UTF8 string from the passed in object.
@@ -73,7 +73,7 @@ public class DERUTF8String
}
}
- /**
+ /*
* Basic constructor - byte encoded string.
*/
DERUTF8String(byte[] string)
@@ -83,6 +83,8 @@ public class DERUTF8String
/**
* Basic constructor
+ *
+ * @param string the string to be carried in the UTF8String object,
*/
public DERUTF8String(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 0d447df7..85390990 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java
@@ -13,7 +13,7 @@ public class DERUniversalString
implements ASN1String
{
private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
- private byte[] string;
+ private final byte[] string;
/**
* return a Universal String from the passed in object.
@@ -73,6 +73,8 @@ public class DERUniversalString
/**
* basic constructor - byte encoded string.
+ *
+ * @param string the byte encoding of the string to be carried in the UniversalString object,
*/
public DERUniversalString(
byte[] string)
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERVideotexString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERVideotexString.java
new file mode 100644
index 00000000..da231e15
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERVideotexString.java
@@ -0,0 +1,124 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Strings;
+
+public class DERVideotexString
+ extends ASN1Primitive
+ implements ASN1String
+{
+ private final byte[] string;
+
+ /**
+ * return a Videotex String from the passed in object
+ *
+ * @param obj a DERVideotexString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return a DERVideotexString instance, or null.
+ */
+ public static DERVideotexString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DERVideotexString)
+ {
+ return (DERVideotexString)obj;
+ }
+
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (DERVideotexString)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
+ }
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return a Videotex String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return a DERVideotexString instance, or null.
+ */
+ public static DERVideotexString getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof DERVideotexString)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return new DERVideotexString(((ASN1OctetString)o).getOctets());
+ }
+ }
+
+ /**
+ * basic constructor - with bytes.
+ * @param string the byte encoding of the characters making up the string.
+ */
+ public DERVideotexString(
+ byte[] string)
+ {
+ this.string = Arrays.clone(string);
+ }
+
+ public byte[] getOctets()
+ {
+ return Arrays.clone(string);
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
+ }
+
+ void encode(
+ ASN1OutputStream out)
+ throws IOException
+ {
+ out.writeEncoded(BERTags.VIDEOTEX_STRING, string);
+ }
+
+ public int hashCode()
+ {
+ return Arrays.hashCode(string);
+ }
+
+ boolean asn1Equals(
+ ASN1Primitive o)
+ {
+ if (!(o instanceof DERVideotexString))
+ {
+ return false;
+ }
+
+ DERVideotexString s = (DERVideotexString)o;
+
+ return Arrays.areEqual(string, s.string);
+ }
+
+ public String getString()
+ {
+ return Strings.fromByteArray(string);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERVisibleString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERVisibleString.java
index 6eb282cc..5932c977 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERVisibleString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERVisibleString.java
@@ -15,7 +15,7 @@ public class DERVisibleString
extends ASN1Primitive
implements ASN1String
{
- private byte[] string;
+ private final byte[] string;
/**
* Return a Visible String from the passed in object.
@@ -73,7 +73,7 @@ public class DERVisibleString
}
}
- /**
+ /*
* Basic constructor - byte encoded string.
*/
DERVisibleString(
@@ -84,6 +84,8 @@ public class DERVisibleString
/**
* Basic constructor
+ *
+ * @param string the string to be carried in the VisibleString object,
*/
public DERVisibleString(
String string)
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLBitString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLBitString.java
new file mode 100644
index 00000000..c81f0ab9
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLBitString.java
@@ -0,0 +1,145 @@
+package org.bouncycastle.asn1;
+
+import java.io.IOException;
+
+/**
+ * A Definite length BIT STRING
+ */
+public class DLBitString
+ extends ASN1BitString
+{
+ /**
+ * return a Bit String that can be definite-length encoded from the passed in object.
+ *
+ * @param obj a DL or DER BitString or an object that can be converted into one.
+ * @exception IllegalArgumentException if the object cannot be converted.
+ * @return an ASN1BitString instance, or null.
+ */
+ public static ASN1BitString getInstance(
+ Object obj)
+ {
+ if (obj == null || obj instanceof DLBitString)
+ {
+ return (DLBitString)obj;
+ }
+ if (obj instanceof DERBitString)
+ {
+ return (DERBitString)obj;
+ }
+
+ throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
+ }
+
+ /**
+ * return a Bit String from a tagged object.
+ *
+ * @param obj the tagged object holding the object we want
+ * @param explicit true if the object is meant to be explicitly
+ * tagged false otherwise.
+ * @exception IllegalArgumentException if the tagged object cannot
+ * be converted.
+ * @return an ASN1BitString instance, or null.
+ */
+ public static ASN1BitString getInstance(
+ ASN1TaggedObject obj,
+ boolean explicit)
+ {
+ ASN1Primitive o = obj.getObject();
+
+ if (explicit || o instanceof DLBitString)
+ {
+ return getInstance(o);
+ }
+ else
+ {
+ return fromOctetString(((ASN1OctetString)o).getOctets());
+ }
+ }
+
+ protected DLBitString(
+ byte data,
+ int padBits)
+ {
+ this(toByteArray(data), padBits);
+ }
+
+ private static byte[] toByteArray(byte data)
+ {
+ byte[] rv = new byte[1];
+
+ rv[0] = data;
+
+ return rv;
+ }
+
+ /**
+ * @param data the octets making up the bit string.
+ * @param padBits the number of extra bits at the end of the string.
+ */
+ public DLBitString(
+ byte[] data,
+ int padBits)
+ {
+ super(data, padBits);
+ }
+
+ public DLBitString(
+ byte[] data)
+ {
+ this(data, 0);
+ }
+
+ public DLBitString(
+ int value)
+ {
+ super(getBytes(value), getPadBits(value));
+ }
+
+ public DLBitString(
+ ASN1Encodable obj)
+ throws IOException
+ {
+ super(obj.toASN1Primitive().getEncoded(ASN1Encoding.DER), 0);
+ }
+
+ boolean isConstructed()
+ {
+ return false;
+ }
+
+ int encodedLength()
+ {
+ return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1;
+ }
+
+ void encode(
+ ASN1OutputStream out)
+ 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(BERTags.BIT_STRING, bytes);
+ }
+
+ static DLBitString fromOctetString(byte[] bytes)
+ {
+ if (bytes.length < 1)
+ {
+ throw new IllegalArgumentException("truncated BIT STRING detected");
+ }
+
+ int padBits = bytes[0];
+ byte[] data = new byte[bytes.length - 1];
+
+ if (data.length != 0)
+ {
+ System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
+ }
+
+ return new DLBitString(data, padBits);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLSequence.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLSequence.java
index b5cc59a2..65acd274 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DLSequence.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLSequence.java
@@ -19,7 +19,8 @@ public class DLSequence
}
/**
- * Create a sequence containing one object
+ * create a sequence containing one object
+ * @param obj the object to go in the sequence.
*/
public DLSequence(
ASN1Encodable obj)
@@ -28,7 +29,8 @@ public class DLSequence
}
/**
- * Create a sequence containing a vector of objects.
+ * create a sequence containing a vector of objects.
+ * @param v the vector of objects to make up the sequence.
*/
public DLSequence(
ASN1EncodableVector v)
@@ -37,7 +39,8 @@ public class DLSequence
}
/**
- * Create a sequence containing an array of objects.
+ * create a sequence containing an array of objects.
+ * @param array the array of objects to make up the sequence.
*/
public DLSequence(
ASN1Encodable[] array)
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/InMemoryRepresentable.java b/bcprov/src/main/java/org/bouncycastle/asn1/InMemoryRepresentable.java
index 9374ab76..734298b9 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/InMemoryRepresentable.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/InMemoryRepresentable.java
@@ -9,6 +9,7 @@ public interface InMemoryRepresentable
{
/**
* Get the in-memory representation of the ASN.1 object.
+ * @return an ASN1Primitive representing the loaded object.
* @throws IOException for bad input data.
*/
ASN1Primitive getLoadedObject()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/OIDTokenizer.java b/bcprov/src/main/java/org/bouncycastle/asn1/OIDTokenizer.java
index 54679447..4c896ad2 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/OIDTokenizer.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/OIDTokenizer.java
@@ -1,7 +1,7 @@
package org.bouncycastle.asn1;
/**
- * class for breaking up an OID into it's component tokens, ala
+ * Class for breaking up an OID into it's component tokens, ala
* java.util.StringTokenizer. We need this class as some of the
* lightweight Java environment don't support classes like
* StringTokenizer.
@@ -11,6 +11,11 @@ public class OIDTokenizer
private String oid;
private int index;
+ /**
+ * Base constructor.
+ *
+ * @param oid the string representation of the OID.
+ */
public OIDTokenizer(
String oid)
{
@@ -18,11 +23,21 @@ public class OIDTokenizer
this.index = 0;
}
+ /**
+ * Return whether or not there are more tokens in this tokenizer.
+ *
+ * @return true if there are more tokens, false otherwise.
+ */
public boolean hasMoreTokens()
{
return (index != -1);
}
+ /**
+ * Return the next token in the underlying String.
+ *
+ * @return the next token.
+ */
public String nextToken()
{
if (index == -1)
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 16a67682..5b95b79e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
@@ -3,9 +3,7 @@ package org.bouncycastle.asn1.bc;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
/**
- * iso.org.dod.internet.private.enterprise.legion-of-the-bouncy-castle
- * <p>
- * 1.3.6.1.4.1.22554
+ * Object Identifiers belonging to iso.org.dod.internet.private.enterprise.legion-of-the-bouncy-castle (1.3.6.1.4.1.22554)
*/
public interface BCObjectIdentifiers
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/AttributeTable.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/AttributeTable.java
index 3b8e0bed..7550282a 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/cms/AttributeTable.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/AttributeTable.java
@@ -216,9 +216,9 @@ public class AttributeTable
/**
* Return a new table with the passed in attribute added.
*
- * @param attrType
- * @param attrValue
- * @return
+ * @param attrType the type of the attribute to add.
+ * @param attrValue the value corresponding to the attribute (will be wrapped in a SET).
+ * @return a new table with the extra attribute in it.
*/
public AttributeTable add(ASN1ObjectIdentifier attrType, ASN1Encodable attrValue)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/CMSAlgorithmProtection.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/CMSAlgorithmProtection.java
new file mode 100644
index 00000000..d18fe4bc
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/CMSAlgorithmProtection.java
@@ -0,0 +1,136 @@
+package org.bouncycastle.asn1.cms;
+
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.ASN1TaggedObject;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.asn1.DERTaggedObject;
+import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+
+/**
+ * From RFC 6211
+ * <pre>
+ * CMSAlgorithmProtection ::= SEQUENCE {
+ * digestAlgorithm DigestAlgorithmIdentifier,
+ * signatureAlgorithm [1] SignatureAlgorithmIdentifier OPTIONAL,
+ * macAlgorithm [2] MessageAuthenticationCodeAlgorithm
+ * OPTIONAL
+ * }
+ * (WITH COMPONENTS { signatureAlgorithm PRESENT,
+ * macAlgorithm ABSENT } |
+ * WITH COMPONENTS { signatureAlgorithm ABSENT,
+ * macAlgorithm PRESENT })
+ * </pre>
+ */
+public class CMSAlgorithmProtection
+ extends ASN1Object
+{
+ public static final int SIGNATURE = 1;
+ public static final int MAC = 2;
+
+ private final AlgorithmIdentifier digestAlgorithm;
+ private final AlgorithmIdentifier signatureAlgorithm;
+ private final AlgorithmIdentifier macAlgorithm;
+
+ public CMSAlgorithmProtection(AlgorithmIdentifier digestAlgorithm, int type, AlgorithmIdentifier algorithmIdentifier)
+ {
+ if (digestAlgorithm == null || algorithmIdentifier == null)
+ {
+ throw new NullPointerException("AlgorithmIdentifiers cannot be null");
+ }
+
+ this.digestAlgorithm = digestAlgorithm;
+
+ if (type == 1)
+ {
+ this.signatureAlgorithm = algorithmIdentifier;
+ this.macAlgorithm = null;
+ }
+ else if (type == 2)
+ {
+ this.signatureAlgorithm = null;
+ this.macAlgorithm = algorithmIdentifier;
+ }
+ else
+ {
+ throw new IllegalArgumentException("Unknown type: " + type);
+ }
+ }
+
+ private CMSAlgorithmProtection(ASN1Sequence sequence)
+ {
+ if (sequence.size() != 2)
+ {
+ throw new IllegalArgumentException("Sequence wrong size: One of signatureAlgorithm or macAlgorithm must be present");
+ }
+
+ this.digestAlgorithm = AlgorithmIdentifier.getInstance(sequence.getObjectAt(0));
+
+ ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(sequence.getObjectAt(1));
+ if (tagged.getTagNo() == 1)
+ {
+ this.signatureAlgorithm = AlgorithmIdentifier.getInstance(tagged, false);
+ this.macAlgorithm = null;
+ }
+ else if (tagged.getTagNo() == 2)
+ {
+ this.signatureAlgorithm = null;
+
+ this.macAlgorithm = AlgorithmIdentifier.getInstance(tagged, false);
+ }
+ else
+ {
+ throw new IllegalArgumentException("Unknown tag found: " + tagged.getTagNo());
+ }
+ }
+
+ public static CMSAlgorithmProtection getInstance(
+ Object obj)
+ {
+ if (obj instanceof CMSAlgorithmProtection)
+ {
+ return (CMSAlgorithmProtection)obj;
+ }
+ else if (obj != null)
+ {
+ return new CMSAlgorithmProtection(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+
+ public AlgorithmIdentifier getDigestAlgorithm()
+ {
+ return digestAlgorithm;
+ }
+
+ public AlgorithmIdentifier getMacAlgorithm()
+ {
+ return macAlgorithm;
+ }
+
+ public AlgorithmIdentifier getSignatureAlgorithm()
+ {
+ return signatureAlgorithm;
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+
+ v.add(digestAlgorithm);
+ if (signatureAlgorithm != null)
+ {
+ v.add(new DERTaggedObject(false, 1, signatureAlgorithm));
+ }
+ if (macAlgorithm != null)
+ {
+ v.add(new DERTaggedObject(false, 2, macAlgorithm));
+ }
+
+ return new DERSequence(v);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/cms/CMSAttributes.java b/bcprov/src/main/java/org/bouncycastle/asn1/cms/CMSAttributes.java
index d2fc7d1a..71c85fbe 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/cms/CMSAttributes.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/CMSAttributes.java
@@ -5,13 +5,15 @@ 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.
* <pre>
* contentType ::= 1.2.840.113549.1.9.3
* messageDigest ::= 1.2.840.113549.1.9.4
* signingTime ::= 1.2.840.113549.1.9.5
* counterSignature ::= 1.2.840.113549.1.9.6
*
- * contentHint ::= 1.2.840.113549.1.9.16.2.4
+ * contentHint ::= 1.2.840.113549.1.9.16.2.4
+ * cmsAlgorithmProtect := 1.2.840.113549.1.9.52
* </pre>
*/
@@ -27,4 +29,7 @@ public interface CMSAttributes
public static final 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> */
public static final ASN1ObjectIdentifier contentHint = PKCSObjectIdentifiers.id_aa_contentHint;
+
+ public static final ASN1ObjectIdentifier cmsAlgorithmProtect = PKCSObjectIdentifiers.id_aa_cmsAlgorithmProtect;
+
}
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 8c7fcc2d..70278970 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/cms/SignedData.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/SignedData.java
@@ -34,7 +34,7 @@ import org.bouncycastle.asn1.DERTaggedObject;
* SignerInfos ::= SET OF SignerInfo
* </pre>
* <p>
- * The version calculation uses following ruleset from RFC 3852 section 5.1:
+ * The version calculation uses following ruleset from RFC 5652 section 5.1:
* <pre>
* IF ((certificates is present) AND
* (any certificates with a type of other are present)) OR
@@ -54,7 +54,6 @@ import org.bouncycastle.asn1.DERTaggedObject;
* ELSE version MUST be 1
* </pre>
* <p>
- * @todo Check possible update for this to RFC 5652 level
*/
public class SignedData
extends ASN1Object
@@ -84,7 +83,8 @@ public class SignedData
* </ul>
*
* @param o the object we want converted.
- * @exception IllegalArgumentException if the object cannot be converted.
+ * @return a reference that can be assigned to SignedData (may be null)
+ * @throws IllegalArgumentException if the object cannot be converted.
*/
public static SignedData getInstance(
Object o)
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 42090458..486eae2d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/cms/SignerInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/cms/SignerInfo.java
@@ -39,7 +39,7 @@ import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
*
* -----------------------------------------
*
- * RFC 5256:
+ * RFC 5652:
*
* SignerInfo ::= SEQUENCE {
* version CMSVersion,
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 098656c0..284751eb 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/misc/MiscObjectIdentifiers.java
@@ -63,4 +63,33 @@ public interface MiscObjectIdentifiers
static final ASN1ObjectIdentifier entrust = new ASN1ObjectIdentifier("1.2.840.113533.7");
/** NortelNetworks Entrust VersionExtension OID: 1.2.840.113533.7.65.0 */
static final ASN1ObjectIdentifier entrustVersionExtension = entrust.branch("65.0");
+
+ /** cast5CBC OBJECT IDENTIFIER ::= {iso(1) member-body(2) us(840) nt(113533) nsn(7) algorithms(66) 10} SEE RFC 2984 */
+ ASN1ObjectIdentifier cast5CBC = entrust.branch("66.10");
+
+ //
+ // Ascom
+ //
+ ASN1ObjectIdentifier as_sys_sec_alg_ideaCBC = new ASN1ObjectIdentifier("1.3.6.1.4.1.188.7.1.1.2");
+
+ //
+ // Peter Gutmann's Cryptlib
+ //
+ ASN1ObjectIdentifier cryptlib = new ASN1ObjectIdentifier("1.3.6.1.4.1.3029");
+
+ ASN1ObjectIdentifier cryptlib_algorithm = cryptlib.branch("1");
+ ASN1ObjectIdentifier cryptlib_algorithm_blowfish_ECB = cryptlib_algorithm.branch("1.1");
+ ASN1ObjectIdentifier cryptlib_algorithm_blowfish_CBC = cryptlib_algorithm.branch("1.2");
+ ASN1ObjectIdentifier cryptlib_algorithm_blowfish_CFB = cryptlib_algorithm.branch("1.3");
+ ASN1ObjectIdentifier cryptlib_algorithm_blowfish_OFB = cryptlib_algorithm.branch("1.4");
+
+ //
+ // Blake2b
+ //
+ ASN1ObjectIdentifier blake2 = new ASN1ObjectIdentifier("1.3.6.1.4.1.1722.12.2");
+
+ ASN1ObjectIdentifier id_blake2b160 = blake2.branch("1.5");
+ ASN1ObjectIdentifier id_blake2b256 = blake2.branch("1.8");
+ ASN1ObjectIdentifier id_blake2b384 = blake2.branch("1.12");
+ ASN1ObjectIdentifier id_blake2b512 = blake2.branch("1.16");
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTNamedCurves.java b/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTNamedCurves.java
index ba7e5187..19077e4c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTNamedCurves.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTNamedCurves.java
@@ -17,42 +17,38 @@ public class NISTNamedCurves
static final Hashtable objIds = new Hashtable();
static final Hashtable names = new Hashtable();
- static void defineCurve(String name, ASN1ObjectIdentifier oid)
+ static void defineCurveAlias(String name, ASN1ObjectIdentifier oid)
{
- objIds.put(name, oid);
+ objIds.put(name.toUpperCase(), oid);
names.put(oid, name);
}
static
{
- defineCurve("B-571", SECObjectIdentifiers.sect571r1);
- defineCurve("B-409", SECObjectIdentifiers.sect409r1);
- defineCurve("B-283", SECObjectIdentifiers.sect283r1);
- defineCurve("B-233", SECObjectIdentifiers.sect233r1);
- defineCurve("B-163", SECObjectIdentifiers.sect163r2);
- defineCurve("K-571", SECObjectIdentifiers.sect571k1);
- defineCurve("K-409", SECObjectIdentifiers.sect409k1);
- defineCurve("K-283", SECObjectIdentifiers.sect283k1);
- defineCurve("K-233", SECObjectIdentifiers.sect233k1);
- defineCurve("K-163", SECObjectIdentifiers.sect163k1);
- defineCurve("P-521", SECObjectIdentifiers.secp521r1);
- defineCurve("P-384", SECObjectIdentifiers.secp384r1);
- defineCurve("P-256", SECObjectIdentifiers.secp256r1);
- defineCurve("P-224", SECObjectIdentifiers.secp224r1);
- defineCurve("P-192", SECObjectIdentifiers.secp192r1);
+ defineCurveAlias("B-163", SECObjectIdentifiers.sect163r2);
+ defineCurveAlias("B-233", SECObjectIdentifiers.sect233r1);
+ defineCurveAlias("B-283", SECObjectIdentifiers.sect283r1);
+ defineCurveAlias("B-409", SECObjectIdentifiers.sect409r1);
+ defineCurveAlias("B-571", SECObjectIdentifiers.sect571r1);
+
+ defineCurveAlias("K-163", SECObjectIdentifiers.sect163k1);
+ defineCurveAlias("K-233", SECObjectIdentifiers.sect233k1);
+ defineCurveAlias("K-283", SECObjectIdentifiers.sect283k1);
+ defineCurveAlias("K-409", SECObjectIdentifiers.sect409k1);
+ defineCurveAlias("K-571", SECObjectIdentifiers.sect571k1);
+
+ defineCurveAlias("P-192", SECObjectIdentifiers.secp192r1);
+ defineCurveAlias("P-224", SECObjectIdentifiers.secp224r1);
+ defineCurveAlias("P-256", SECObjectIdentifiers.secp256r1);
+ defineCurveAlias("P-384", SECObjectIdentifiers.secp384r1);
+ defineCurveAlias("P-521", SECObjectIdentifiers.secp521r1);
}
public static X9ECParameters getByName(
String name)
{
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)objIds.get(Strings.toUpperCase(name));
-
- if (oid != null)
- {
- return getByOID(oid);
- }
-
- return null;
+ ASN1ObjectIdentifier oid = getOID(name);
+ return oid == null ? null : getByOID(oid);
}
/**
@@ -94,6 +90,6 @@ public class NISTNamedCurves
*/
public static Enumeration getNames()
{
- return objIds.keys();
+ return names.elements();
}
}
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 e3613c68..0de40f20 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
@@ -31,6 +31,19 @@ public interface NISTObjectIdentifiers
/** 2.16.840.1.101.3.4.2.6 */
static final ASN1ObjectIdentifier id_sha512_256 = hashAlgs.branch("6");
+ /** 2.16.840.1.101.3.4.2.7 */
+ static final ASN1ObjectIdentifier id_sha3_224 = hashAlgs.branch("7");
+ /** 2.16.840.1.101.3.4.2.8 */
+ static final ASN1ObjectIdentifier id_sha3_256 = hashAlgs.branch("8");
+ /** 2.16.840.1.101.3.4.2.9 */
+ static final ASN1ObjectIdentifier id_sha3_384 = hashAlgs.branch("9");
+ /** 2.16.840.1.101.3.4.2.10 */
+ static final ASN1ObjectIdentifier id_sha3_512 = hashAlgs.branch("10");
+ /** 2.16.840.1.101.3.4.2.11 */
+ static final ASN1ObjectIdentifier id_shake128 = hashAlgs.branch("11");
+ /** 2.16.840.1.101.3.4.2.12 */
+ static final ASN1ObjectIdentifier id_shake256 = hashAlgs.branch("12");
+
/** 2.16.840.1.101.3.4.1 */
static final ASN1ObjectIdentifier aes = nistAlgorithm.branch("1");
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 06208731..747277c3 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java
@@ -9,6 +9,9 @@ import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
+/**
+ * CRL Bag for PKCS#12
+ */
public class CRLBag
extends ASN1Object
{
@@ -44,12 +47,12 @@ public class CRLBag
this.crlValue = crlValue;
}
- public ASN1ObjectIdentifier getcrlId()
+ public ASN1ObjectIdentifier getCrlId()
{
return crlId;
}
- public ASN1Encodable getCRLValue()
+ public ASN1Encodable getCrlValue()
{
return crlValue;
}
@@ -58,7 +61,7 @@ public class CRLBag
* <pre>
* CRLBag ::= SEQUENCE {
* crlId BAG-TYPE.&amp;id ({CRLTypes}),
- * crlValue [0] EXPLICIT BAG-TYPE.&amp;Type ({CRLTypes}{@crlId})
+ * crlValue [0] EXPLICIT BAG-TYPE.&amp;Type ({CRLTypes}{&#64;crlId})
* }
*
* x509CRL BAG-TYPE ::= {OCTET STRING IDENTIFIED BY {certTypes 1}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBES2Algorithms.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBES2Algorithms.java
deleted file mode 100644
index db44a82a..00000000
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBES2Algorithms.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.bouncycastle.asn1.pkcs;
-
-import java.util.Enumeration;
-
-import org.bouncycastle.asn1.ASN1EncodableVector;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.ASN1Primitive;
-import org.bouncycastle.asn1.ASN1Sequence;
-import org.bouncycastle.asn1.DERSequence;
-import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-
-/**
- * @deprecated - use AlgorithmIdentifier and PBES2Parameters
- */
-public class PBES2Algorithms
- extends AlgorithmIdentifier implements PKCSObjectIdentifiers
-{
- private ASN1ObjectIdentifier objectId;
- private KeyDerivationFunc func;
- private EncryptionScheme scheme;
-
- public PBES2Algorithms(
- ASN1Sequence obj)
- {
- super(obj);
-
- Enumeration e = obj.getObjects();
-
- objectId = (ASN1ObjectIdentifier)e.nextElement();
-
- ASN1Sequence seq = (ASN1Sequence)e.nextElement();
-
- e = seq.getObjects();
-
- ASN1Sequence funcSeq = (ASN1Sequence)e.nextElement();
-
- if (funcSeq.getObjectAt(0).equals(id_PBKDF2))
- {
- func = new KeyDerivationFunc(id_PBKDF2, PBKDF2Params.getInstance(funcSeq.getObjectAt(1)));
- }
- else
- {
- func = KeyDerivationFunc.getInstance(funcSeq);
- }
-
- scheme = EncryptionScheme.getInstance(e.nextElement());
- }
-
- public ASN1ObjectIdentifier getObjectId()
- {
- return objectId;
- }
-
- public KeyDerivationFunc getKeyDerivationFunc()
- {
- return func;
- }
-
- public EncryptionScheme getEncryptionScheme()
- {
- return scheme;
- }
-
- public ASN1Primitive getASN1Primitive()
- {
- ASN1EncodableVector v = new ASN1EncodableVector();
- ASN1EncodableVector subV = new ASN1EncodableVector();
-
- v.add(objectId);
-
- subV.add(func);
- subV.add(scheme);
- v.add(new DERSequence(subV));
-
- return new DERSequence(v);
- }
-}
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 92c4e8f1..6a6ad559 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
@@ -13,6 +13,7 @@ import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.util.Arrays;
/**
* <pre>
@@ -31,19 +32,19 @@ public class PBKDF2Params
{
private static final AlgorithmIdentifier algid_hmacWithSHA1 = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA1, DERNull.INSTANCE);
- private ASN1OctetString octStr;
- private ASN1Integer iterationCount;
- private ASN1Integer keyLength;
- private AlgorithmIdentifier prf;
+ private final ASN1OctetString octStr;
+ private final ASN1Integer iterationCount;
+ private final ASN1Integer keyLength;
+ private final AlgorithmIdentifier prf;
/**
* Create PBKDF2Params from the passed in object,
*
- * @param obj either PBKDF2Params or an ASN2Sequence.
+ * @param obj either PBKDF2Params or an ASN1Sequence.
* @return a PBKDF2Params instance.
*/
public static PBKDF2Params getInstance(
- Object obj)
+ Object obj)
{
if (obj instanceof PBKDF2Params)
{
@@ -61,72 +62,77 @@ public class PBKDF2Params
/**
* Create a PBKDF2Params with the specified salt, iteration count, and algid-hmacWithSHA1 for the prf.
*
- * @param salt input salt.
+ * @param salt input salt.
* @param iterationCount input iteration count.
*/
public PBKDF2Params(
- byte[] salt,
- int iterationCount)
+ byte[] salt,
+ int iterationCount)
{
- this.octStr = new DEROctetString(salt);
- this.iterationCount = new ASN1Integer(iterationCount);
+ this(salt, iterationCount, 0);
}
/**
* Create a PBKDF2Params with the specified salt, iteration count, keyLength, and algid-hmacWithSHA1 for the prf.
*
- * @param salt input salt.
+ * @param salt input salt.
* @param iterationCount input iteration count.
- * @param keyLength intended key length to be produced.
+ * @param keyLength intended key length to be produced.
*/
public PBKDF2Params(
- byte[] salt,
- int iterationCount,
- int keyLength)
+ byte[] salt,
+ int iterationCount,
+ int keyLength)
{
- this(salt, iterationCount);
-
- this.keyLength = new ASN1Integer(keyLength);
+ this(salt, iterationCount, keyLength, null);
}
/**
* Create a PBKDF2Params with the specified salt, iteration count, keyLength, and a defined prf.
*
- * @param salt input salt.
+ * @param salt input salt.
* @param iterationCount input iteration count.
- * @param keyLength intended key length to be produced.
- * @param prf the pseudo-random function to use.
+ * @param keyLength intended key length to be produced.
+ * @param prf the pseudo-random function to use.
*/
public PBKDF2Params(
- byte[] salt,
- int iterationCount,
- int keyLength,
+ byte[] salt,
+ int iterationCount,
+ int keyLength,
AlgorithmIdentifier prf)
{
- this(salt, iterationCount);
+ this.octStr = new DEROctetString(Arrays.clone(salt));
+ this.iterationCount = new ASN1Integer(iterationCount);
+
+ if (keyLength > 0)
+ {
+ this.keyLength = new ASN1Integer(keyLength);
+ }
+ else
+ {
+ this.keyLength = null;
+ }
- this.keyLength = new ASN1Integer(keyLength);
this.prf = prf;
}
/**
* Create a PBKDF2Params with the specified salt, iteration count, and a defined prf.
*
- * @param salt input salt.
+ * @param salt input salt.
* @param iterationCount input iteration count.
- * @param prf the pseudo-random function to use.
+ * @param prf the pseudo-random function to use.
*/
public PBKDF2Params(
- byte[] salt,
- int iterationCount,
+ byte[] salt,
+ int iterationCount,
AlgorithmIdentifier prf)
{
- this(salt, iterationCount);
- this.prf = prf;
+ this(salt, iterationCount, 0, prf);
}
private PBKDF2Params(
- ASN1Sequence seq)
+ ASN1Sequence seq)
{
Enumeration e = seq.getObjects();
@@ -158,6 +164,15 @@ public class PBKDF2Params
{
prf = AlgorithmIdentifier.getInstance(o);
}
+ else
+ {
+ prf = null;
+ }
+ }
+ else
+ {
+ keyLength = null;
+ prf = null;
}
}
@@ -228,7 +243,7 @@ public class PBKDF2Params
*/
public ASN1Primitive toASN1Primitive()
{
- ASN1EncodableVector v = new ASN1EncodableVector();
+ ASN1EncodableVector v = new ASN1EncodableVector();
v.add(octStr);
v.add(iterationCount);
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 82f1f94d..5dbddc3c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
@@ -120,34 +120,34 @@ public interface PKCSObjectIdentifiers
static final ASN1ObjectIdentifier md5 = digestAlgorithm.branch("5");
/** 1.2.840.113549.2.7 */
- static final ASN1ObjectIdentifier id_hmacWithSHA1 = digestAlgorithm.branch("7");
+ static final ASN1ObjectIdentifier id_hmacWithSHA1 = digestAlgorithm.branch("7").intern();
/** 1.2.840.113549.2.8 */
- static final ASN1ObjectIdentifier id_hmacWithSHA224 = digestAlgorithm.branch("8");
+ static final ASN1ObjectIdentifier id_hmacWithSHA224 = digestAlgorithm.branch("8").intern();
/** 1.2.840.113549.2.9 */
- static final ASN1ObjectIdentifier id_hmacWithSHA256 = digestAlgorithm.branch("9");
+ static final ASN1ObjectIdentifier id_hmacWithSHA256 = digestAlgorithm.branch("9").intern();
/** 1.2.840.113549.2.10 */
- static final ASN1ObjectIdentifier id_hmacWithSHA384 = digestAlgorithm.branch("10");
+ static final ASN1ObjectIdentifier id_hmacWithSHA384 = digestAlgorithm.branch("10").intern();
/** 1.2.840.113549.2.11 */
- static final ASN1ObjectIdentifier id_hmacWithSHA512 = digestAlgorithm.branch("11");
+ static final ASN1ObjectIdentifier id_hmacWithSHA512 = digestAlgorithm.branch("11").intern();
//
// pkcs-7 OBJECT IDENTIFIER ::= {
// iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 7 }
//
/** pkcs#7: 1.2.840.113549.1.7 */
- static final ASN1ObjectIdentifier pkcs_7 = new ASN1ObjectIdentifier("1.2.840.113549.1.7");
+ static final ASN1ObjectIdentifier pkcs_7 = new ASN1ObjectIdentifier("1.2.840.113549.1.7").intern();
/** PKCS#7: 1.2.840.113549.1.7.1 */
- static final ASN1ObjectIdentifier data = new ASN1ObjectIdentifier("1.2.840.113549.1.7.1");
+ static final ASN1ObjectIdentifier data = new ASN1ObjectIdentifier("1.2.840.113549.1.7.1").intern();
/** PKCS#7: 1.2.840.113549.1.7.2 */
- static final ASN1ObjectIdentifier signedData = new ASN1ObjectIdentifier("1.2.840.113549.1.7.2");
+ static final ASN1ObjectIdentifier signedData = new ASN1ObjectIdentifier("1.2.840.113549.1.7.2").intern();
/** PKCS#7: 1.2.840.113549.1.7.3 */
- static final ASN1ObjectIdentifier envelopedData = new ASN1ObjectIdentifier("1.2.840.113549.1.7.3");
+ static final ASN1ObjectIdentifier envelopedData = new ASN1ObjectIdentifier("1.2.840.113549.1.7.3").intern();
/** PKCS#7: 1.2.840.113549.1.7.4 */
- static final ASN1ObjectIdentifier signedAndEnvelopedData = new ASN1ObjectIdentifier("1.2.840.113549.1.7.4");
+ static final ASN1ObjectIdentifier signedAndEnvelopedData = new ASN1ObjectIdentifier("1.2.840.113549.1.7.4").intern();
/** PKCS#7: 1.2.840.113549.1.7.5 */
- static final ASN1ObjectIdentifier digestedData = new ASN1ObjectIdentifier("1.2.840.113549.1.7.5");
+ static final ASN1ObjectIdentifier digestedData = new ASN1ObjectIdentifier("1.2.840.113549.1.7.5").intern();
/** PKCS#7: 1.2.840.113549.1.7.76 */
- static final ASN1ObjectIdentifier encryptedData = new ASN1ObjectIdentifier("1.2.840.113549.1.7.6");
+ static final ASN1ObjectIdentifier encryptedData = new ASN1ObjectIdentifier("1.2.840.113549.1.7.6").intern();
//
// pkcs-9 OBJECT IDENTIFIER ::= {
@@ -157,37 +157,37 @@ public interface PKCSObjectIdentifiers
static final ASN1ObjectIdentifier pkcs_9 = new ASN1ObjectIdentifier("1.2.840.113549.1.9");
/** PKCS#9: 1.2.840.113549.1.9.1 */
- static final ASN1ObjectIdentifier pkcs_9_at_emailAddress = pkcs_9.branch("1");
+ static final ASN1ObjectIdentifier pkcs_9_at_emailAddress = pkcs_9.branch("1").intern();
/** PKCS#9: 1.2.840.113549.1.9.2 */
- static final ASN1ObjectIdentifier pkcs_9_at_unstructuredName = pkcs_9.branch("2");
+ static final ASN1ObjectIdentifier pkcs_9_at_unstructuredName = pkcs_9.branch("2").intern();
/** PKCS#9: 1.2.840.113549.1.9.3 */
- static final ASN1ObjectIdentifier pkcs_9_at_contentType = pkcs_9.branch("3");
+ static final ASN1ObjectIdentifier pkcs_9_at_contentType = pkcs_9.branch("3").intern();
/** PKCS#9: 1.2.840.113549.1.9.4 */
- static final ASN1ObjectIdentifier pkcs_9_at_messageDigest = pkcs_9.branch("4");
+ static final ASN1ObjectIdentifier pkcs_9_at_messageDigest = pkcs_9.branch("4").intern();
/** PKCS#9: 1.2.840.113549.1.9.5 */
- static final ASN1ObjectIdentifier pkcs_9_at_signingTime = pkcs_9.branch("5");
+ static final ASN1ObjectIdentifier pkcs_9_at_signingTime = pkcs_9.branch("5").intern();
/** PKCS#9: 1.2.840.113549.1.9.6 */
- static final ASN1ObjectIdentifier pkcs_9_at_counterSignature = pkcs_9.branch("6");
+ static final ASN1ObjectIdentifier pkcs_9_at_counterSignature = pkcs_9.branch("6").intern();
/** PKCS#9: 1.2.840.113549.1.9.7 */
- static final ASN1ObjectIdentifier pkcs_9_at_challengePassword = pkcs_9.branch("7");
+ static final ASN1ObjectIdentifier pkcs_9_at_challengePassword = pkcs_9.branch("7").intern();
/** PKCS#9: 1.2.840.113549.1.9.8 */
- static final ASN1ObjectIdentifier pkcs_9_at_unstructuredAddress = pkcs_9.branch("8");
+ static final ASN1ObjectIdentifier pkcs_9_at_unstructuredAddress = pkcs_9.branch("8").intern();
/** PKCS#9: 1.2.840.113549.1.9.9 */
- static final ASN1ObjectIdentifier pkcs_9_at_extendedCertificateAttributes = pkcs_9.branch("9");
+ static final ASN1ObjectIdentifier pkcs_9_at_extendedCertificateAttributes = pkcs_9.branch("9").intern();
/** PKCS#9: 1.2.840.113549.1.9.13 */
- static final ASN1ObjectIdentifier pkcs_9_at_signingDescription = pkcs_9.branch("13");
+ static final ASN1ObjectIdentifier pkcs_9_at_signingDescription = pkcs_9.branch("13").intern();
/** PKCS#9: 1.2.840.113549.1.9.14 */
- static final ASN1ObjectIdentifier pkcs_9_at_extensionRequest = pkcs_9.branch("14");
+ static final ASN1ObjectIdentifier pkcs_9_at_extensionRequest = pkcs_9.branch("14").intern();
/** PKCS#9: 1.2.840.113549.1.9.15 */
- static final ASN1ObjectIdentifier pkcs_9_at_smimeCapabilities = pkcs_9.branch("15");
+ static final ASN1ObjectIdentifier pkcs_9_at_smimeCapabilities = pkcs_9.branch("15").intern();
/** PKCS#9: 1.2.840.113549.1.9.16 */
- static final ASN1ObjectIdentifier id_smime = pkcs_9.branch("16");
+ static final ASN1ObjectIdentifier id_smime = pkcs_9.branch("16").intern();
/** PKCS#9: 1.2.840.113549.1.9.20 */
- static final ASN1ObjectIdentifier pkcs_9_at_friendlyName = pkcs_9.branch("20");
+ static final ASN1ObjectIdentifier pkcs_9_at_friendlyName = pkcs_9.branch("20").intern();
/** PKCS#9: 1.2.840.113549.1.9.21 */
- static final ASN1ObjectIdentifier pkcs_9_at_localKeyId = pkcs_9.branch("21");
+ static final ASN1ObjectIdentifier pkcs_9_at_localKeyId = pkcs_9.branch("21").intern();
/** PKCS#9: 1.2.840.113549.1.9.22.1
* @deprecated use x509Certificate instead */
@@ -196,14 +196,19 @@ public interface PKCSObjectIdentifiers
/** PKCS#9: 1.2.840.113549.1.9.22 */
static final ASN1ObjectIdentifier certTypes = pkcs_9.branch("22");
/** PKCS#9: 1.2.840.113549.1.9.22.1 */
- static final ASN1ObjectIdentifier x509Certificate = certTypes.branch("1");
+ static final ASN1ObjectIdentifier x509Certificate = certTypes.branch("1").intern();
/** PKCS#9: 1.2.840.113549.1.9.22.2 */
- static final ASN1ObjectIdentifier sdsiCertificate = certTypes.branch("2");
+ static final ASN1ObjectIdentifier sdsiCertificate = certTypes.branch("2").intern();
/** PKCS#9: 1.2.840.113549.1.9.23 */
static final ASN1ObjectIdentifier crlTypes = pkcs_9.branch("23");
/** PKCS#9: 1.2.840.113549.1.9.23.1 */
- static final ASN1ObjectIdentifier x509Crl = crlTypes.branch("1");
+ static final ASN1ObjectIdentifier x509Crl = crlTypes.branch("1").intern();
+
+ /** RFC 6211 - id-aa-cmsAlgorithmProtect OBJECT IDENTIFIER ::= {
+ iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
+ pkcs9(9) 52 } */
+ ASN1ObjectIdentifier id_aa_cmsAlgorithmProtect = pkcs_9.branch("52").intern();
//
// SMIME capability sub oids.
@@ -238,6 +243,17 @@ public interface PKCSObjectIdentifiers
static final ASN1ObjectIdentifier id_alg = id_smime.branch("3");
/** PKCS#9: 1.2.840.113549.1.9.16.3.9 */
static final ASN1ObjectIdentifier id_alg_PWRI_KEK = id_alg.branch("9");
+ /**
+ * <pre>
+ * -- RSA-KEM Key Transport Algorithm
+ *
+ * id-rsa-kem OID ::= {
+ * iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
+ * pkcs-9(9) smime(16) alg(3) 14
+ * }
+ * </pre>
+ */
+ static final ASN1ObjectIdentifier id_rsa_KEM = id_alg.branch("14");
//
// id-cti OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
@@ -392,5 +408,9 @@ public interface PKCSObjectIdentifiers
static final ASN1ObjectIdentifier id_alg_CMS3DESwrap = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.6");
/** PKCS#9: 1.2.840.113549.1.9.16.3.7 */
static final ASN1ObjectIdentifier id_alg_CMSRC2wrap = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.7");
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.5 */
+ static final ASN1ObjectIdentifier id_alg_ESDH = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.5");
+ /** PKCS#9: 1.2.840.113549.1.9.16.3.10 */
+ static final ASN1ObjectIdentifier id_alg_SSDH = new ASN1ObjectIdentifier("1.2.840.113549.1.9.16.3.10");
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/sec/SECNamedCurves.java b/bcprov/src/main/java/org/bouncycastle/asn1/sec/SECNamedCurves.java
index ed7a8d82..1cdaf129 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/sec/SECNamedCurves.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/sec/SECNamedCurves.java
@@ -7,9 +7,9 @@ import java.util.Hashtable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.x9.X9ECParameters;
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.ECPoint;
import org.bouncycastle.math.ec.endo.GLVTypeBEndomorphism;
import org.bouncycastle.math.ec.endo.GLVTypeBParameters;
import org.bouncycastle.util.Strings;
@@ -51,7 +51,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "09487239995A5EE76B55F9C2F098"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "09487239995A5EE76B55F9C2F098"
+ "A89CE5AF8724C0A23E0E0FF77500"));
@@ -77,7 +77,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "4BA30AB5E892B4E1649DD0928643"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "4BA30AB5E892B4E1649DD0928643"
+ "ADCD46F5882E3747DEF36E956E97"));
@@ -103,7 +103,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "161FF7528B899B2D0C28607CA52C5B86"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "161FF7528B899B2D0C28607CA52C5B86"
+ "CF5AC8395BAFEB13C02DA292DDED7A83"));
@@ -129,7 +129,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "7B6AA5D85E572983E6FB32A7CDEBC140"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "7B6AA5D85E572983E6FB32A7CDEBC140"
+ "27B6916A894D3AEE7106FE805FC34B44"));
@@ -168,7 +168,7 @@ public class SECNamedCurves
ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
// ECPoint G = curve.decodePoint(Hex.decode("02"
// + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB"
+ "938CF935318FDCED6BC28286531733C3F03C4FEE"));
@@ -194,7 +194,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "4A96B5688EF573284664698968C38BB913CBFC82"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "4A96B5688EF573284664698968C38BB913CBFC82"
+ "23A628553168947D59DCC912042351377AC5FB32"));
@@ -220,7 +220,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "52DCB034293A117E1F4FF11B30F7199D3144CE6D"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "52DCB034293A117E1F4FF11B30F7199D3144CE6D"
+ "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E"));
@@ -259,7 +259,7 @@ public class SECNamedCurves
ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D"
+ "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D"));
@@ -285,7 +285,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"
+ "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"));
@@ -324,7 +324,7 @@ public class SECNamedCurves
ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C"
+ "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5"));
@@ -350,7 +350,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"
+ "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"));
@@ -389,7 +389,7 @@ public class SECNamedCurves
ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
//ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"
+ "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"));
@@ -415,7 +415,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"
+ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"));
@@ -441,7 +441,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"
+ "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"));
@@ -468,7 +468,7 @@ public class SECNamedCurves
//ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"
+ "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650"));
@@ -495,7 +495,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "009D73616F35F4AB1407D73562C10F"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "009D73616F35F4AB1407D73562C10F"
+ "00A52830277958EE84D1315ED31886"));
@@ -522,7 +522,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "01A57A6A7B26CA5EF52FCDB8164797"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "01A57A6A7B26CA5EF52FCDB8164797"
+ "00B3ADC94ED1FE674C06E695BABA1D"));
@@ -551,7 +551,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "0081BAF91FDF9833C40F9C181343638399"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "0081BAF91FDF9833C40F9C181343638399"
+ "078C6E7EA38C001F73C8134B1B4EF9E150"));
@@ -580,7 +580,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "0356DCD8F2F95031AD652D23951BB366A8"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "0356DCD8F2F95031AD652D23951BB366A8"
+ "0648F06D867940A5366D9E265DE9EB240F"));
@@ -609,7 +609,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8"
+ "0289070FB05D38FF58321F2E800536D538CCDAA3D9"));
@@ -638,7 +638,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "0369979697AB43897789566789567F787A7876A654"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "0369979697AB43897789566789567F787A7876A654"
+ "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883"));
@@ -667,7 +667,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "03F0EBA16286A2D57EA0991168D4994637E8343E36"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "03F0EBA16286A2D57EA0991168D4994637E8343E36"
+ "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1"));
@@ -694,7 +694,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1"
+ "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05"));
@@ -721,7 +721,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F"
+ "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C"));
@@ -748,7 +748,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126"
+ "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3"));
@@ -775,7 +775,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B"
+ "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052"));
@@ -802,7 +802,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC"
+ "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA"));
@@ -831,7 +831,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836"
+ "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259"));
@@ -860,7 +860,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053"
+ "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4"));
@@ -887,7 +887,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746"
+ "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B"));
@@ -914,7 +914,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.F2m(m, k, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7"
+ "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706"));
@@ -943,7 +943,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972"
+ "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3"));
@@ -972,7 +972,7 @@ public class SECNamedCurves
ECCurve curve = configureCurve(new ECCurve.F2m(m, k1, k2, k3, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19"));
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19"
+ "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B"));
@@ -987,7 +987,7 @@ public class SECNamedCurves
static void defineCurve(String name, ASN1ObjectIdentifier oid, X9ECParametersHolder holder)
{
- objIds.put(name, oid);
+ objIds.put(name.toLowerCase(), oid);
names.put(oid, name);
curves.put(oid, holder);
}
@@ -1033,14 +1033,8 @@ public class SECNamedCurves
public static X9ECParameters getByName(
String name)
{
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)objIds.get(Strings.toLowerCase(name));
-
- if (oid != null)
- {
- return getByOID(oid);
- }
-
- return null;
+ ASN1ObjectIdentifier oid = getOID(name);
+ return oid == null ? null : getByOID(oid);
}
/**
@@ -1053,13 +1047,7 @@ public class SECNamedCurves
ASN1ObjectIdentifier oid)
{
X9ECParametersHolder holder = (X9ECParametersHolder)curves.get(oid);
-
- if (holder != null)
- {
- return holder.getParameters();
- }
-
- return null;
+ return holder == null ? null : holder.getParameters();
}
/**
@@ -1089,6 +1077,6 @@ public class SECNamedCurves
*/
public static Enumeration getNames()
{
- return objIds.keys();
+ return names.elements();
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/sec/SECObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/sec/SECObjectIdentifiers.java
index fb60aca6..1ddc17d0 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/sec/SECObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/sec/SECObjectIdentifiers.java
@@ -84,4 +84,25 @@ public interface SECObjectIdentifiers
/** secp256r1 OID: 1.3.132.0.prime256v1 */
static final ASN1ObjectIdentifier secp256r1 = X9ObjectIdentifiers.prime256v1;
+ static final ASN1ObjectIdentifier secg_scheme = new ASN1ObjectIdentifier("1.3.132.1");
+
+ static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha224kdf_scheme = secg_scheme.branch("11.0");
+ static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha256kdf_scheme = secg_scheme.branch("11.1");
+ static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha384kdf_scheme = secg_scheme.branch("11.2");
+ static final ASN1ObjectIdentifier dhSinglePass_stdDH_sha512kdf_scheme = secg_scheme.branch("11.3");
+
+ static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha224kdf_scheme = secg_scheme.branch("14.0");
+ static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha256kdf_scheme = secg_scheme.branch("14.1");
+ static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha384kdf_scheme = secg_scheme.branch("14.2");
+ static final ASN1ObjectIdentifier dhSinglePass_cofactorDH_sha512kdf_scheme = secg_scheme.branch("14.3");
+
+ static final ASN1ObjectIdentifier mqvSinglePass_sha224kdf_scheme = secg_scheme.branch("15.0");
+ static final ASN1ObjectIdentifier mqvSinglePass_sha256kdf_scheme = secg_scheme.branch("15.1");
+ static final ASN1ObjectIdentifier mqvSinglePass_sha384kdf_scheme = secg_scheme.branch("15.2");
+ static final ASN1ObjectIdentifier mqvSinglePass_sha512kdf_scheme = secg_scheme.branch("15.3");
+
+ static final ASN1ObjectIdentifier mqvFull_sha224kdf_scheme = secg_scheme.branch("16.0");
+ static final ASN1ObjectIdentifier mqvFull_sha256kdf_scheme = secg_scheme.branch("16.1");
+ static final ASN1ObjectIdentifier mqvFull_sha384kdf_scheme = secg_scheme.branch("16.2");
+ static final ASN1ObjectIdentifier mqvFull_sha512kdf_scheme = secg_scheme.branch("16.3");
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java b/bcprov/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java
index 8a454f27..1330d256 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java
@@ -3,6 +3,7 @@ package org.bouncycastle.asn1.util;
import java.io.IOException;
import java.util.Enumeration;
+import org.bouncycastle.asn1.ASN1ApplicationSpecific;
import org.bouncycastle.asn1.ASN1Boolean;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Enumerated;
@@ -25,13 +26,16 @@ import org.bouncycastle.asn1.DERApplicationSpecific;
import org.bouncycastle.asn1.DERBMPString;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERExternal;
+import org.bouncycastle.asn1.DERGraphicString;
import org.bouncycastle.asn1.DERIA5String;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DERPrintableString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERT61String;
import org.bouncycastle.asn1.DERUTF8String;
+import org.bouncycastle.asn1.DERVideotexString;
import org.bouncycastle.asn1.DERVisibleString;
+import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
public class ASN1Dump
@@ -50,7 +54,7 @@ public class ASN1Dump
ASN1Primitive obj,
StringBuffer buf)
{
- String nl = System.getProperty("line.separator");
+ String nl = Strings.lineSeparator();
if (obj instanceof ASN1Sequence)
{
Enumeration e = ((ASN1Sequence)obj).getObjects();
@@ -237,6 +241,14 @@ public class ASN1Dump
{
buf.append(indent + "T61String(" + ((DERT61String)obj).getString() + ") " + nl);
}
+ else if (obj instanceof DERGraphicString)
+ {
+ buf.append(indent + "GraphicString(" + ((DERGraphicString)obj).getString() + ") " + nl);
+ }
+ else if (obj instanceof DERVideotexString)
+ {
+ buf.append(indent + "VideotexString(" + ((DERVideotexString)obj).getString() + ") " + nl);
+ }
else if (obj instanceof ASN1UTCTime)
{
buf.append(indent + "UTCTime(" + ((ASN1UTCTime)obj).getTime() + ") " + nl);
@@ -286,7 +298,7 @@ public class ASN1Dump
private static String outputApplicationSpecific(String type, String indent, boolean verbose, ASN1Primitive obj, String nl)
{
- DERApplicationSpecific app = (DERApplicationSpecific)obj;
+ ASN1ApplicationSpecific app = ASN1ApplicationSpecific.getInstance(obj);
StringBuffer buf = new StringBuffer();
if (app.isConstructed())
@@ -353,7 +365,7 @@ public class ASN1Dump
private static String dumpBinaryDataAsString(String indent, byte[] bytes)
{
- String nl = System.getProperty("line.separator");
+ String nl = Strings.lineSeparator();
StringBuffer buf = new StringBuffer();
indent += TAB;
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 7f283f97..b4b2bd43 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/AttributeTypeAndValue.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/AttributeTypeAndValue.java
@@ -8,6 +8,9 @@ import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERSequence;
+/**
+ * Holding class for the AttributeTypeAndValue structures that make up an RDN.
+ */
public class AttributeTypeAndValue
extends ASN1Object
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/DirectoryString.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/DirectoryString.java
index cf7563e2..39312dec 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/DirectoryString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/DirectoryString.java
@@ -12,6 +12,9 @@ import org.bouncycastle.asn1.DERT61String;
import org.bouncycastle.asn1.DERUTF8String;
import org.bouncycastle.asn1.DERUniversalString;
+/**
+ * The DirectoryString CHOICE object.
+ */
public class DirectoryString
extends ASN1Object
implements ASN1Choice, ASN1String
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 f51c2619..6a1b318f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/RDN.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/RDN.java
@@ -9,6 +9,9 @@ import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERSet;
+/**
+ * Holding class for a single Relative Distinguished Name (RDN).
+ */
public class RDN
extends ASN1Object
{
@@ -105,12 +108,12 @@ public class RDN
* <pre>
* RelativeDistinguishedName ::=
* SET OF AttributeTypeAndValue
-
+ *
* AttributeTypeAndValue ::= SEQUENCE {
* type AttributeType,
* value AttributeValue }
* </pre>
- * @return this object as an ASN1Primitive type
+ * @return this object as its ASN1Primitive type
*/
public ASN1Primitive toASN1Primitive()
{
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 50e57c51..67c5cd1c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500Name.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500Name.java
@@ -13,6 +13,7 @@ import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x500.style.BCStyle;
/**
+ * The X.500 Name object.
* <pre>
* Name ::= CHOICE {
* RDNSequence }
@@ -38,6 +39,9 @@ public class X500Name
private X500NameStyle style;
private RDN[] rdns;
+ /**
+ * @deprecated use the getInstance() method that takes a style.
+ */
public X500Name(X500NameStyle style, X500Name name)
{
this.rdns = name.rdns;
@@ -80,7 +84,7 @@ public class X500Name
{
if (obj instanceof X500Name)
{
- return getInstance(style, ((X500Name)obj).toASN1Primitive());
+ return new X500Name(style, (X500Name)obj);
}
else if (obj != null)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500NameBuilder.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500NameBuilder.java
index 7c9506a9..d019aaac 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500NameBuilder.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500NameBuilder.java
@@ -6,21 +6,39 @@ import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.x500.style.BCStyle;
+/**
+ * A builder class for making X.500 Name objects.
+ */
public class X500NameBuilder
{
private X500NameStyle template;
private Vector rdns = new Vector();
+ /**
+ * Constructor using the default style (BCStyle).
+ */
public X500NameBuilder()
{
this(BCStyle.INSTANCE);
}
+ /**
+ * Constructor using a specified style.
+ *
+ * @param template the style template for string to DN conversion.
+ */
public X500NameBuilder(X500NameStyle template)
{
this.template = template;
}
+ /**
+ * Add an RDN based on a single OID and a string representation of its value.
+ *
+ * @param oid the OID for this RDN.
+ * @param value the string representation of the value the OID refers to.
+ * @return the current builder instance.
+ */
public X500NameBuilder addRDN(ASN1ObjectIdentifier oid, String value)
{
this.addRDN(oid, template.stringToValue(oid, value));
@@ -28,6 +46,13 @@ public class X500NameBuilder
return this;
}
+ /**
+ * Add an RDN based on a single OID and an ASN.1 value.
+ *
+ * @param oid the OID for this RDN.
+ * @param value the ASN.1 value the OID refers to.
+ * @return the current builder instance.
+ */
public X500NameBuilder addRDN(ASN1ObjectIdentifier oid, ASN1Encodable value)
{
rdns.addElement(new RDN(oid, value));
@@ -35,6 +60,12 @@ public class X500NameBuilder
return this;
}
+ /**
+ * Add an RDN based on the passed in AttributeTypeAndValue.
+ *
+ * @param attrTAndV the AttributeTypeAndValue to build the RDN from.
+ * @return the current builder instance.
+ */
public X500NameBuilder addRDN(AttributeTypeAndValue attrTAndV)
{
rdns.addElement(new RDN(attrTAndV));
@@ -42,6 +73,13 @@ public class X500NameBuilder
return this;
}
+ /**
+ * Add a multi-valued RDN made up of the passed in OIDs and associated string values.
+ *
+ * @param oids the OIDs making up the RDN.
+ * @param values the string representation of the values the OIDs refer to.
+ * @return the current builder instance.
+ */
public X500NameBuilder addMultiValuedRDN(ASN1ObjectIdentifier[] oids, String[] values)
{
ASN1Encodable[] vals = new ASN1Encodable[values.length];
@@ -54,6 +92,13 @@ public class X500NameBuilder
return addMultiValuedRDN(oids, vals);
}
+ /**
+ * Add a multi-valued RDN made up of the passed in OIDs and associated ASN.1 values.
+ *
+ * @param oids the OIDs making up the RDN.
+ * @param values the ASN.1 values the OIDs refer to.
+ * @return the current builder instance.
+ */
public X500NameBuilder addMultiValuedRDN(ASN1ObjectIdentifier[] oids, ASN1Encodable[] values)
{
AttributeTypeAndValue[] avs = new AttributeTypeAndValue[oids.length];
@@ -66,6 +111,12 @@ public class X500NameBuilder
return addMultiValuedRDN(avs);
}
+ /**
+ * Add an RDN based on the passed in AttributeTypeAndValues.
+ *
+ * @param attrTAndVs the AttributeTypeAndValues to build the RDN from.
+ * @return the current builder instance.
+ */
public X500NameBuilder addMultiValuedRDN(AttributeTypeAndValue[] attrTAndVs)
{
rdns.addElement(new RDN(attrTAndVs));
@@ -73,6 +124,11 @@ public class X500NameBuilder
return this;
}
+ /**
+ * Build an X.500 name for the current builder state.
+ *
+ * @return a new X.500 name.
+ */
public X500Name build()
{
RDN[] vals = new RDN[rdns.size()];
@@ -84,4 +140,4 @@ public class X500NameBuilder
return new X500Name(template, vals);
}
-}
+} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500NameStyle.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500NameStyle.java
index 704ea72e..8a87fb43 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500NameStyle.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/X500NameStyle.java
@@ -4,11 +4,11 @@ import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
/**
- * It turns out that the number of standard ways the fields in a DN should be
- * encoded into their ASN.1 counterparts is rapidly approaching the
- * number of machines on the internet. By default the X500Name class
- * will produce UTF8Strings in line with the current recommendations (RFC 3280).
- * <p>
+ * This interface provides a profile to conform to when
+ * DNs are being converted into strings and back. The idea being that we'll be able to deal with
+ * the number of standard ways the fields in a DN should be
+ * encoded into their ASN.1 counterparts - a number that is rapidly approaching the
+ * number of machines on the internet.
*/
public interface X500NameStyle
{
@@ -76,4 +76,4 @@ public interface X500NameStyle
* @return an array of String aliases for the OID, zero length if there are none.
*/
String[] oidToAttrNames(ASN1ObjectIdentifier oid);
-}
+} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/AbstractX500NameStyle.java
index 9792d40e..a97b17d2 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
@@ -6,6 +6,7 @@ import java.util.Hashtable;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ASN1ParsingException;
import org.bouncycastle.asn1.DERUTF8String;
import org.bouncycastle.asn1.x500.AttributeTypeAndValue;
import org.bouncycastle.asn1.x500.RDN;
@@ -101,7 +102,7 @@ public abstract class AbstractX500NameStyle
}
catch (IOException e)
{
- throw new RuntimeException("can't recode value for oid " + oid.getId());
+ throw new ASN1ParsingException("can't recode value for oid " + oid.getId());
}
}
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 1c2a9269..34b43856 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
@@ -19,37 +19,37 @@ public class BCStyle
/**
* country code - StringType(SIZE(2))
*/
- public static final ASN1ObjectIdentifier C = new ASN1ObjectIdentifier("2.5.4.6");
+ public static final ASN1ObjectIdentifier C = new ASN1ObjectIdentifier("2.5.4.6").intern();
/**
* organization - StringType(SIZE(1..64))
*/
- public static final ASN1ObjectIdentifier O = new ASN1ObjectIdentifier("2.5.4.10");
+ public static final ASN1ObjectIdentifier O = new ASN1ObjectIdentifier("2.5.4.10").intern();
/**
* organizational unit name - StringType(SIZE(1..64))
*/
- public static final ASN1ObjectIdentifier OU = new ASN1ObjectIdentifier("2.5.4.11");
+ public static final ASN1ObjectIdentifier OU = new ASN1ObjectIdentifier("2.5.4.11").intern();
/**
* Title
*/
- public static final ASN1ObjectIdentifier T = new ASN1ObjectIdentifier("2.5.4.12");
+ public static final ASN1ObjectIdentifier T = new ASN1ObjectIdentifier("2.5.4.12").intern();
/**
* common name - StringType(SIZE(1..64))
*/
- public static final ASN1ObjectIdentifier CN = new ASN1ObjectIdentifier("2.5.4.3");
+ public static final ASN1ObjectIdentifier CN = new ASN1ObjectIdentifier("2.5.4.3").intern();
/**
* device serial number name - StringType(SIZE(1..64))
*/
- public static final ASN1ObjectIdentifier SN = new ASN1ObjectIdentifier("2.5.4.5");
+ public static final ASN1ObjectIdentifier SN = new ASN1ObjectIdentifier("2.5.4.5").intern();
/**
* street - StringType(SIZE(1..64))
*/
- public static final ASN1ObjectIdentifier STREET = new ASN1ObjectIdentifier("2.5.4.9");
+ public static final ASN1ObjectIdentifier STREET = new ASN1ObjectIdentifier("2.5.4.9").intern();
/**
* device serial number name - StringType(SIZE(1..64))
@@ -59,95 +59,95 @@ public class BCStyle
/**
* locality name - StringType(SIZE(1..64))
*/
- public static final ASN1ObjectIdentifier L = new ASN1ObjectIdentifier("2.5.4.7");
+ public static final ASN1ObjectIdentifier L = new ASN1ObjectIdentifier("2.5.4.7").intern();
/**
* state, or province name - StringType(SIZE(1..64))
*/
- public static final ASN1ObjectIdentifier ST = new ASN1ObjectIdentifier("2.5.4.8");
+ public static final ASN1ObjectIdentifier ST = new ASN1ObjectIdentifier("2.5.4.8").intern();
/**
* Naming attributes of type X520name
*/
- public static final ASN1ObjectIdentifier SURNAME = new ASN1ObjectIdentifier("2.5.4.4");
- public static final ASN1ObjectIdentifier GIVENNAME = new ASN1ObjectIdentifier("2.5.4.42");
- public static final ASN1ObjectIdentifier INITIALS = new ASN1ObjectIdentifier("2.5.4.43");
- public static final ASN1ObjectIdentifier GENERATION = new ASN1ObjectIdentifier("2.5.4.44");
- public static final ASN1ObjectIdentifier UNIQUE_IDENTIFIER = new ASN1ObjectIdentifier("2.5.4.45");
+ public static final ASN1ObjectIdentifier SURNAME = new ASN1ObjectIdentifier("2.5.4.4").intern();
+ public static final ASN1ObjectIdentifier GIVENNAME = new ASN1ObjectIdentifier("2.5.4.42").intern();
+ public static final ASN1ObjectIdentifier INITIALS = new ASN1ObjectIdentifier("2.5.4.43").intern();
+ public static final ASN1ObjectIdentifier GENERATION = new ASN1ObjectIdentifier("2.5.4.44").intern();
+ public static final ASN1ObjectIdentifier UNIQUE_IDENTIFIER = new ASN1ObjectIdentifier("2.5.4.45").intern();
/**
* businessCategory - DirectoryString(SIZE(1..128)
*/
public static final ASN1ObjectIdentifier BUSINESS_CATEGORY = new ASN1ObjectIdentifier(
- "2.5.4.15");
+ "2.5.4.15").intern();
/**
* postalCode - DirectoryString(SIZE(1..40)
*/
public static final ASN1ObjectIdentifier POSTAL_CODE = new ASN1ObjectIdentifier(
- "2.5.4.17");
+ "2.5.4.17").intern();
/**
* dnQualifier - DirectoryString(SIZE(1..64)
*/
public static final ASN1ObjectIdentifier DN_QUALIFIER = new ASN1ObjectIdentifier(
- "2.5.4.46");
+ "2.5.4.46").intern();
/**
* RFC 3039 Pseudonym - DirectoryString(SIZE(1..64)
*/
public static final ASN1ObjectIdentifier PSEUDONYM = new ASN1ObjectIdentifier(
- "2.5.4.65");
+ "2.5.4.65").intern();
/**
* RFC 3039 DateOfBirth - GeneralizedTime - YYYYMMDD000000Z
*/
public static final ASN1ObjectIdentifier DATE_OF_BIRTH = new ASN1ObjectIdentifier(
- "1.3.6.1.5.5.7.9.1");
+ "1.3.6.1.5.5.7.9.1").intern();
/**
* RFC 3039 PlaceOfBirth - DirectoryString(SIZE(1..128)
*/
public static final ASN1ObjectIdentifier PLACE_OF_BIRTH = new ASN1ObjectIdentifier(
- "1.3.6.1.5.5.7.9.2");
+ "1.3.6.1.5.5.7.9.2").intern();
/**
* RFC 3039 Gender - PrintableString (SIZE(1)) -- "M", "F", "m" or "f"
*/
public static final ASN1ObjectIdentifier GENDER = new ASN1ObjectIdentifier(
- "1.3.6.1.5.5.7.9.3");
+ "1.3.6.1.5.5.7.9.3").intern();
/**
* RFC 3039 CountryOfCitizenship - PrintableString (SIZE (2)) -- ISO 3166
* codes only
*/
public static final ASN1ObjectIdentifier COUNTRY_OF_CITIZENSHIP = new ASN1ObjectIdentifier(
- "1.3.6.1.5.5.7.9.4");
+ "1.3.6.1.5.5.7.9.4").intern();
/**
* RFC 3039 CountryOfResidence - PrintableString (SIZE (2)) -- ISO 3166
* codes only
*/
public static final ASN1ObjectIdentifier COUNTRY_OF_RESIDENCE = new ASN1ObjectIdentifier(
- "1.3.6.1.5.5.7.9.5");
+ "1.3.6.1.5.5.7.9.5").intern();
/**
* ISIS-MTT NameAtBirth - DirectoryString(SIZE(1..64)
*/
- public static final ASN1ObjectIdentifier NAME_AT_BIRTH = new ASN1ObjectIdentifier("1.3.36.8.3.14");
+ public static final ASN1ObjectIdentifier NAME_AT_BIRTH = new ASN1ObjectIdentifier("1.3.36.8.3.14").intern();
/**
* RFC 3039 PostalAddress - SEQUENCE SIZE (1..6) OF
* DirectoryString(SIZE(1..30))
*/
- public static final ASN1ObjectIdentifier POSTAL_ADDRESS = new ASN1ObjectIdentifier("2.5.4.16");
+ public static final ASN1ObjectIdentifier POSTAL_ADDRESS = new ASN1ObjectIdentifier("2.5.4.16").intern();
/**
* RFC 2256 dmdName
*/
- public static final ASN1ObjectIdentifier DMD_NAME = new ASN1ObjectIdentifier("2.5.4.54");
+ public static final ASN1ObjectIdentifier DMD_NAME = new ASN1ObjectIdentifier("2.5.4.54").intern();
/**
* id-at-telephoneNumber
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/RFC4519Style.java b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/RFC4519Style.java
index 13f6ef1e..2a40fb03 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/RFC4519Style.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x500/style/RFC4519Style.java
@@ -13,49 +13,49 @@ import org.bouncycastle.asn1.x500.X500NameStyle;
public class RFC4519Style
extends AbstractX500NameStyle
{
- public static final ASN1ObjectIdentifier businessCategory = new ASN1ObjectIdentifier("2.5.4.15");
- public static final ASN1ObjectIdentifier c = new ASN1ObjectIdentifier("2.5.4.6");
- public static final ASN1ObjectIdentifier cn = new ASN1ObjectIdentifier("2.5.4.3");
- public static final ASN1ObjectIdentifier dc = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.25");
- public static final ASN1ObjectIdentifier description = new ASN1ObjectIdentifier("2.5.4.13");
- public static final ASN1ObjectIdentifier destinationIndicator = new ASN1ObjectIdentifier("2.5.4.27");
- public static final ASN1ObjectIdentifier distinguishedName = new ASN1ObjectIdentifier("2.5.4.49");
- public static final ASN1ObjectIdentifier dnQualifier = new ASN1ObjectIdentifier("2.5.4.46");
- public static final ASN1ObjectIdentifier enhancedSearchGuide = new ASN1ObjectIdentifier("2.5.4.47");
- public static final ASN1ObjectIdentifier facsimileTelephoneNumber = new ASN1ObjectIdentifier("2.5.4.23");
- public static final ASN1ObjectIdentifier generationQualifier = new ASN1ObjectIdentifier("2.5.4.44");
- public static final ASN1ObjectIdentifier givenName = new ASN1ObjectIdentifier("2.5.4.42");
- public static final ASN1ObjectIdentifier houseIdentifier = new ASN1ObjectIdentifier("2.5.4.51");
- public static final ASN1ObjectIdentifier initials = new ASN1ObjectIdentifier("2.5.4.43");
- public static final ASN1ObjectIdentifier internationalISDNNumber = new ASN1ObjectIdentifier("2.5.4.25");
- public static final ASN1ObjectIdentifier l = new ASN1ObjectIdentifier("2.5.4.7");
- public static final ASN1ObjectIdentifier member = new ASN1ObjectIdentifier("2.5.4.31");
- public static final ASN1ObjectIdentifier name = new ASN1ObjectIdentifier("2.5.4.41");
- public static final ASN1ObjectIdentifier o = new ASN1ObjectIdentifier("2.5.4.10");
- public static final ASN1ObjectIdentifier ou = new ASN1ObjectIdentifier("2.5.4.11");
- public static final ASN1ObjectIdentifier owner = new ASN1ObjectIdentifier("2.5.4.32");
- public static final ASN1ObjectIdentifier physicalDeliveryOfficeName = new ASN1ObjectIdentifier("2.5.4.19");
- public static final ASN1ObjectIdentifier postalAddress = new ASN1ObjectIdentifier("2.5.4.16");
- public static final ASN1ObjectIdentifier postalCode = new ASN1ObjectIdentifier("2.5.4.17");
- public static final ASN1ObjectIdentifier postOfficeBox = new ASN1ObjectIdentifier("2.5.4.18");
- public static final ASN1ObjectIdentifier preferredDeliveryMethod = new ASN1ObjectIdentifier("2.5.4.28");
- public static final ASN1ObjectIdentifier registeredAddress = new ASN1ObjectIdentifier("2.5.4.26");
- public static final ASN1ObjectIdentifier roleOccupant = new ASN1ObjectIdentifier("2.5.4.33");
- public static final ASN1ObjectIdentifier searchGuide = new ASN1ObjectIdentifier("2.5.4.14");
- public static final ASN1ObjectIdentifier seeAlso = new ASN1ObjectIdentifier("2.5.4.34");
- public static final ASN1ObjectIdentifier serialNumber = new ASN1ObjectIdentifier("2.5.4.5");
- public static final ASN1ObjectIdentifier sn = new ASN1ObjectIdentifier("2.5.4.4");
- public static final ASN1ObjectIdentifier st = new ASN1ObjectIdentifier("2.5.4.8");
- public static final ASN1ObjectIdentifier street = new ASN1ObjectIdentifier("2.5.4.9");
- public static final ASN1ObjectIdentifier telephoneNumber = new ASN1ObjectIdentifier("2.5.4.20");
- public static final ASN1ObjectIdentifier teletexTerminalIdentifier = new ASN1ObjectIdentifier("2.5.4.22");
- public static final ASN1ObjectIdentifier telexNumber = new ASN1ObjectIdentifier("2.5.4.21");
- public static final ASN1ObjectIdentifier title = new ASN1ObjectIdentifier("2.5.4.12");
- public static final ASN1ObjectIdentifier uid = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.1");
- public static final ASN1ObjectIdentifier uniqueMember = new ASN1ObjectIdentifier("2.5.4.50");
- public static final ASN1ObjectIdentifier userPassword = new ASN1ObjectIdentifier("2.5.4.35");
- public static final ASN1ObjectIdentifier x121Address = new ASN1ObjectIdentifier("2.5.4.24");
- public static final ASN1ObjectIdentifier x500UniqueIdentifier = new ASN1ObjectIdentifier("2.5.4.45");
+ public static final ASN1ObjectIdentifier businessCategory = new ASN1ObjectIdentifier("2.5.4.15").intern();
+ public static final ASN1ObjectIdentifier c = new ASN1ObjectIdentifier("2.5.4.6").intern();
+ public static final ASN1ObjectIdentifier cn = new ASN1ObjectIdentifier("2.5.4.3").intern();
+ public static final ASN1ObjectIdentifier dc = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.25").intern();
+ public static final ASN1ObjectIdentifier description = new ASN1ObjectIdentifier("2.5.4.13").intern();
+ public static final ASN1ObjectIdentifier destinationIndicator = new ASN1ObjectIdentifier("2.5.4.27").intern();
+ public static final ASN1ObjectIdentifier distinguishedName = new ASN1ObjectIdentifier("2.5.4.49").intern();
+ public static final ASN1ObjectIdentifier dnQualifier = new ASN1ObjectIdentifier("2.5.4.46").intern();
+ public static final ASN1ObjectIdentifier enhancedSearchGuide = new ASN1ObjectIdentifier("2.5.4.47").intern();
+ public static final ASN1ObjectIdentifier facsimileTelephoneNumber = new ASN1ObjectIdentifier("2.5.4.23").intern();
+ public static final ASN1ObjectIdentifier generationQualifier = new ASN1ObjectIdentifier("2.5.4.44").intern();
+ public static final ASN1ObjectIdentifier givenName = new ASN1ObjectIdentifier("2.5.4.42").intern();
+ public static final ASN1ObjectIdentifier houseIdentifier = new ASN1ObjectIdentifier("2.5.4.51").intern();
+ public static final ASN1ObjectIdentifier initials = new ASN1ObjectIdentifier("2.5.4.43").intern();
+ public static final ASN1ObjectIdentifier internationalISDNNumber = new ASN1ObjectIdentifier("2.5.4.25").intern();
+ public static final ASN1ObjectIdentifier l = new ASN1ObjectIdentifier("2.5.4.7").intern();
+ public static final ASN1ObjectIdentifier member = new ASN1ObjectIdentifier("2.5.4.31").intern();
+ public static final ASN1ObjectIdentifier name = new ASN1ObjectIdentifier("2.5.4.41").intern();
+ public static final ASN1ObjectIdentifier o = new ASN1ObjectIdentifier("2.5.4.10").intern();
+ public static final ASN1ObjectIdentifier ou = new ASN1ObjectIdentifier("2.5.4.11").intern();
+ public static final ASN1ObjectIdentifier owner = new ASN1ObjectIdentifier("2.5.4.32").intern();
+ public static final ASN1ObjectIdentifier physicalDeliveryOfficeName = new ASN1ObjectIdentifier("2.5.4.19").intern();
+ public static final ASN1ObjectIdentifier postalAddress = new ASN1ObjectIdentifier("2.5.4.16").intern();
+ public static final ASN1ObjectIdentifier postalCode = new ASN1ObjectIdentifier("2.5.4.17").intern();
+ public static final ASN1ObjectIdentifier postOfficeBox = new ASN1ObjectIdentifier("2.5.4.18").intern();
+ public static final ASN1ObjectIdentifier preferredDeliveryMethod = new ASN1ObjectIdentifier("2.5.4.28").intern();
+ public static final ASN1ObjectIdentifier registeredAddress = new ASN1ObjectIdentifier("2.5.4.26").intern();
+ public static final ASN1ObjectIdentifier roleOccupant = new ASN1ObjectIdentifier("2.5.4.33").intern();
+ public static final ASN1ObjectIdentifier searchGuide = new ASN1ObjectIdentifier("2.5.4.14").intern();
+ public static final ASN1ObjectIdentifier seeAlso = new ASN1ObjectIdentifier("2.5.4.34").intern();
+ public static final ASN1ObjectIdentifier serialNumber = new ASN1ObjectIdentifier("2.5.4.5").intern();
+ public static final ASN1ObjectIdentifier sn = new ASN1ObjectIdentifier("2.5.4.4").intern();
+ public static final ASN1ObjectIdentifier st = new ASN1ObjectIdentifier("2.5.4.8").intern();
+ public static final ASN1ObjectIdentifier street = new ASN1ObjectIdentifier("2.5.4.9").intern();
+ public static final ASN1ObjectIdentifier telephoneNumber = new ASN1ObjectIdentifier("2.5.4.20").intern();
+ public static final ASN1ObjectIdentifier teletexTerminalIdentifier = new ASN1ObjectIdentifier("2.5.4.22").intern();
+ public static final ASN1ObjectIdentifier telexNumber = new ASN1ObjectIdentifier("2.5.4.21").intern();
+ public static final ASN1ObjectIdentifier title = new ASN1ObjectIdentifier("2.5.4.12").intern();
+ public static final ASN1ObjectIdentifier uid = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.1").intern();
+ public static final ASN1ObjectIdentifier uniqueMember = new ASN1ObjectIdentifier("2.5.4.50").intern();
+ public static final ASN1ObjectIdentifier userPassword = new ASN1ObjectIdentifier("2.5.4.35").intern();
+ public static final ASN1ObjectIdentifier x121Address = new ASN1ObjectIdentifier("2.5.4.24").intern();
+ public static final ASN1ObjectIdentifier x500UniqueIdentifier = new ASN1ObjectIdentifier("2.5.4.45").intern();
/**
* default look up table translating OID values into their common symbols following
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 bb90030c..54eaa329 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/AlgorithmIdentifier.java
@@ -7,15 +7,13 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
-import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DERSequence;
public class AlgorithmIdentifier
extends ASN1Object
{
- private ASN1ObjectIdentifier objectId;
+ private ASN1ObjectIdentifier algorithm;
private ASN1Encodable parameters;
- private boolean parametersDefined = false;
public static AlgorithmIdentifier getInstance(
ASN1TaggedObject obj,
@@ -23,60 +21,37 @@ public class AlgorithmIdentifier
{
return getInstance(ASN1Sequence.getInstance(obj, explicit));
}
-
+
public static AlgorithmIdentifier getInstance(
Object obj)
{
- if (obj== null || obj instanceof AlgorithmIdentifier)
+ if (obj instanceof AlgorithmIdentifier)
{
return (AlgorithmIdentifier)obj;
}
-
- // TODO: delete
- if (obj instanceof ASN1ObjectIdentifier)
- {
- return new AlgorithmIdentifier((ASN1ObjectIdentifier)obj);
- }
-
- // TODO: delete
- if (obj instanceof String)
+ else if (obj != null)
{
- return new AlgorithmIdentifier((String)obj);
+ return new AlgorithmIdentifier(ASN1Sequence.getInstance(obj));
}
- return new AlgorithmIdentifier(ASN1Sequence.getInstance(obj));
+ return null;
}
public AlgorithmIdentifier(
- ASN1ObjectIdentifier objectId)
- {
- this.objectId = objectId;
- }
-
- /**
- * @deprecated use ASN1ObjectIdentifier
- * @param objectId
- */
- public AlgorithmIdentifier(
- String objectId)
+ ASN1ObjectIdentifier algorithm)
{
- this.objectId = new ASN1ObjectIdentifier(objectId);
+ this.algorithm = algorithm;
}
public AlgorithmIdentifier(
- ASN1ObjectIdentifier objectId,
+ ASN1ObjectIdentifier algorithm,
ASN1Encodable parameters)
{
- parametersDefined = true;
- this.objectId = objectId;
+ this.algorithm = algorithm;
this.parameters = parameters;
}
- /**
- * @deprecated use AlgorithmIdentifier.getInstance()
- * @param seq
- */
- public AlgorithmIdentifier(
+ private AlgorithmIdentifier(
ASN1Sequence seq)
{
if (seq.size() < 1 || seq.size() > 2)
@@ -84,12 +59,11 @@ public class AlgorithmIdentifier
throw new IllegalArgumentException("Bad sequence size: "
+ seq.size());
}
-
- objectId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
+
+ algorithm = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
if (seq.size() == 2)
{
- parametersDefined = true;
parameters = seq.getObjectAt(1);
}
else
@@ -100,16 +74,7 @@ public class AlgorithmIdentifier
public ASN1ObjectIdentifier getAlgorithm()
{
- return new ASN1ObjectIdentifier(objectId.getId());
- }
-
- /**
- * @deprecated use getAlgorithm
- * @return
- */
- public ASN1ObjectIdentifier getObjectId()
- {
- return objectId;
+ return algorithm;
}
public ASN1Encodable getParameters()
@@ -129,18 +94,11 @@ public class AlgorithmIdentifier
{
ASN1EncodableVector v = new ASN1EncodableVector();
- v.add(objectId);
+ v.add(algorithm);
- if (parametersDefined)
+ if (parameters != null)
{
- if (parameters != null)
- {
- v.add(parameters);
- }
- else
- {
- v.add(DERNull.INSTANCE);
- }
+ v.add(parameters);
}
return new DERSequence(v);
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 1ee6aa5a..dd3422f6 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLDistPoint.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/CRLDistPoint.java
@@ -6,6 +6,7 @@ import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.util.Strings;
public class CRLDistPoint
extends ASN1Object
@@ -84,7 +85,7 @@ public class CRLDistPoint
public String toString()
{
StringBuffer buf = new StringBuffer();
- String sep = System.getProperty("line.separator");
+ String sep = Strings.lineSeparator();
buf.append("CRLDistPoint:");
buf.append(sep);
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 ab73dfbb..48e5640d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/DistributionPoint.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/DistributionPoint.java
@@ -8,6 +8,7 @@ import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
+import org.bouncycastle.util.Strings;
/**
* The DistributionPoint object.
@@ -121,7 +122,7 @@ public class DistributionPoint
public String toString()
{
- String sep = System.getProperty("line.separator");
+ String sep = Strings.lineSeparator();
StringBuffer buf = new StringBuffer();
buf.append("DistributionPoint: [");
buf.append(sep);
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/DistributionPointName.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/DistributionPointName.java
index ee06efdc..f69ccb3a 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/DistributionPointName.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/DistributionPointName.java
@@ -7,6 +7,7 @@ import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERTaggedObject;
+import org.bouncycastle.util.Strings;
/**
* The DistributionPointName object.
@@ -105,7 +106,7 @@ public class DistributionPointName
public String toString()
{
- String sep = System.getProperty("line.separator");
+ String sep = Strings.lineSeparator();
StringBuffer buf = new StringBuffer();
buf.append("DistributionPointName: [");
buf.append(sep);
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 4d566b18..456e3d32 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extension.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extension.java
@@ -22,157 +22,157 @@ public class Extension
/**
* Subject Directory Attributes
*/
- public static final ASN1ObjectIdentifier subjectDirectoryAttributes = new ASN1ObjectIdentifier("2.5.29.9");
+ public static final ASN1ObjectIdentifier subjectDirectoryAttributes = new ASN1ObjectIdentifier("2.5.29.9").intern();
/**
* Subject Key Identifier
*/
- public static final ASN1ObjectIdentifier subjectKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.14");
+ public static final ASN1ObjectIdentifier subjectKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.14").intern();
/**
* Key Usage
*/
- public static final ASN1ObjectIdentifier keyUsage = new ASN1ObjectIdentifier("2.5.29.15");
+ public static final ASN1ObjectIdentifier keyUsage = new ASN1ObjectIdentifier("2.5.29.15").intern();
/**
* Private Key Usage Period
*/
- public static final ASN1ObjectIdentifier privateKeyUsagePeriod = new ASN1ObjectIdentifier("2.5.29.16");
+ public static final ASN1ObjectIdentifier privateKeyUsagePeriod = new ASN1ObjectIdentifier("2.5.29.16").intern();
/**
* Subject Alternative Name
*/
- public static final ASN1ObjectIdentifier subjectAlternativeName = new ASN1ObjectIdentifier("2.5.29.17");
+ public static final ASN1ObjectIdentifier subjectAlternativeName = new ASN1ObjectIdentifier("2.5.29.17").intern();
/**
* Issuer Alternative Name
*/
- public static final ASN1ObjectIdentifier issuerAlternativeName = new ASN1ObjectIdentifier("2.5.29.18");
+ public static final ASN1ObjectIdentifier issuerAlternativeName = new ASN1ObjectIdentifier("2.5.29.18").intern();
/**
* Basic Constraints
*/
- public static final ASN1ObjectIdentifier basicConstraints = new ASN1ObjectIdentifier("2.5.29.19");
+ public static final ASN1ObjectIdentifier basicConstraints = new ASN1ObjectIdentifier("2.5.29.19").intern();
/**
* CRL Number
*/
- public static final ASN1ObjectIdentifier cRLNumber = new ASN1ObjectIdentifier("2.5.29.20");
+ public static final ASN1ObjectIdentifier cRLNumber = new ASN1ObjectIdentifier("2.5.29.20").intern();
/**
* Reason code
*/
- public static final ASN1ObjectIdentifier reasonCode = new ASN1ObjectIdentifier("2.5.29.21");
+ public static final ASN1ObjectIdentifier reasonCode = new ASN1ObjectIdentifier("2.5.29.21").intern();
/**
* Hold Instruction Code
*/
- public static final ASN1ObjectIdentifier instructionCode = new ASN1ObjectIdentifier("2.5.29.23");
+ public static final ASN1ObjectIdentifier instructionCode = new ASN1ObjectIdentifier("2.5.29.23").intern();
/**
* Invalidity Date
*/
- public static final ASN1ObjectIdentifier invalidityDate = new ASN1ObjectIdentifier("2.5.29.24");
+ public static final ASN1ObjectIdentifier invalidityDate = new ASN1ObjectIdentifier("2.5.29.24").intern();
/**
* Delta CRL indicator
*/
- public static final ASN1ObjectIdentifier deltaCRLIndicator = new ASN1ObjectIdentifier("2.5.29.27");
+ public static final ASN1ObjectIdentifier deltaCRLIndicator = new ASN1ObjectIdentifier("2.5.29.27").intern();
/**
* Issuing Distribution Point
*/
- public static final ASN1ObjectIdentifier issuingDistributionPoint = new ASN1ObjectIdentifier("2.5.29.28");
+ public static final ASN1ObjectIdentifier issuingDistributionPoint = new ASN1ObjectIdentifier("2.5.29.28").intern();
/**
* Certificate Issuer
*/
- public static final ASN1ObjectIdentifier certificateIssuer = new ASN1ObjectIdentifier("2.5.29.29");
+ public static final ASN1ObjectIdentifier certificateIssuer = new ASN1ObjectIdentifier("2.5.29.29").intern();
/**
* Name Constraints
*/
- public static final ASN1ObjectIdentifier nameConstraints = new ASN1ObjectIdentifier("2.5.29.30");
+ public static final ASN1ObjectIdentifier nameConstraints = new ASN1ObjectIdentifier("2.5.29.30").intern();
/**
* CRL Distribution Points
*/
- public static final ASN1ObjectIdentifier cRLDistributionPoints = new ASN1ObjectIdentifier("2.5.29.31");
+ public static final ASN1ObjectIdentifier cRLDistributionPoints = new ASN1ObjectIdentifier("2.5.29.31").intern();
/**
* Certificate Policies
*/
- public static final ASN1ObjectIdentifier certificatePolicies = new ASN1ObjectIdentifier("2.5.29.32");
+ public static final ASN1ObjectIdentifier certificatePolicies = new ASN1ObjectIdentifier("2.5.29.32").intern();
/**
* Policy Mappings
*/
- public static final ASN1ObjectIdentifier policyMappings = new ASN1ObjectIdentifier("2.5.29.33");
+ public static final ASN1ObjectIdentifier policyMappings = new ASN1ObjectIdentifier("2.5.29.33").intern();
/**
* Authority Key Identifier
*/
- public static final ASN1ObjectIdentifier authorityKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.35");
+ public static final ASN1ObjectIdentifier authorityKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.35").intern();
/**
* Policy Constraints
*/
- public static final ASN1ObjectIdentifier policyConstraints = new ASN1ObjectIdentifier("2.5.29.36");
+ public static final ASN1ObjectIdentifier policyConstraints = new ASN1ObjectIdentifier("2.5.29.36").intern();
/**
* Extended Key Usage
*/
- public static final ASN1ObjectIdentifier extendedKeyUsage = new ASN1ObjectIdentifier("2.5.29.37");
+ public static final ASN1ObjectIdentifier extendedKeyUsage = new ASN1ObjectIdentifier("2.5.29.37").intern();
/**
* Freshest CRL
*/
- public static final ASN1ObjectIdentifier freshestCRL = new ASN1ObjectIdentifier("2.5.29.46");
+ public static final ASN1ObjectIdentifier freshestCRL = new ASN1ObjectIdentifier("2.5.29.46").intern();
/**
* Inhibit Any Policy
*/
- public static final ASN1ObjectIdentifier inhibitAnyPolicy = new ASN1ObjectIdentifier("2.5.29.54");
+ public static final ASN1ObjectIdentifier inhibitAnyPolicy = new ASN1ObjectIdentifier("2.5.29.54").intern();
/**
* Authority Info Access
*/
- public static final ASN1ObjectIdentifier authorityInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.1");
+ public static final ASN1ObjectIdentifier authorityInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.1").intern();
/**
* Subject Info Access
*/
- public static final ASN1ObjectIdentifier subjectInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.11");
+ public static final ASN1ObjectIdentifier subjectInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.11").intern();
/**
* Logo Type
*/
- public static final ASN1ObjectIdentifier logoType = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.12");
+ public static final ASN1ObjectIdentifier logoType = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.12").intern();
/**
* BiometricInfo
*/
- public static final ASN1ObjectIdentifier biometricInfo = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.2");
+ public static final ASN1ObjectIdentifier biometricInfo = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.2").intern();
/**
* QCStatements
*/
- public static final ASN1ObjectIdentifier qCStatements = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.3");
+ public static final ASN1ObjectIdentifier qCStatements = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.3").intern();
/**
* Audit identity extension in attribute certificates.
*/
- public static final ASN1ObjectIdentifier auditIdentity = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.4");
+ public static final ASN1ObjectIdentifier auditIdentity = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.4").intern();
/**
* NoRevAvail extension in attribute certificates.
*/
- public static final ASN1ObjectIdentifier noRevAvail = new ASN1ObjectIdentifier("2.5.29.56");
+ public static final ASN1ObjectIdentifier noRevAvail = new ASN1ObjectIdentifier("2.5.29.56").intern();
/**
* TargetInformation extension in attribute certificates.
*/
- public static final ASN1ObjectIdentifier targetInformation = new ASN1ObjectIdentifier("2.5.29.55");
+ public static final ASN1ObjectIdentifier targetInformation = new ASN1ObjectIdentifier("2.5.29.55").intern();
private ASN1ObjectIdentifier extnId;
private boolean critical;
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 270ef1c4..d20e62f5 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/ExtensionsGenerator.java
@@ -66,6 +66,23 @@ public class ExtensionsGenerator
}
/**
+ * Add a given extension.
+ *
+ * @param extension the full extension value.
+ */
+ public void addExtension(
+ Extension extension)
+ {
+ if (extensions.containsKey(extension.getExtnId()))
+ {
+ throw new IllegalArgumentException("extension " + extension.getExtnId() + " already added");
+ }
+
+ extOrdering.addElement(extension.getExtnId());
+ extensions.put(extension.getExtnId(), extension);
+ }
+
+ /**
* 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/GeneralNames.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralNames.java
index 7118d107..405f6e4e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralNames.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/GeneralNames.java
@@ -6,6 +6,7 @@ import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.util.Strings;
public class GeneralNames
extends ASN1Object
@@ -92,7 +93,7 @@ public class GeneralNames
public String toString()
{
StringBuffer buf = new StringBuffer();
- String sep = System.getProperty("line.separator");
+ String sep = Strings.lineSeparator();
buf.append("GeneralNames:");
buf.append(sep);
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 1f29162b..c24b788e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/IssuingDistributionPoint.java
@@ -8,6 +8,7 @@ import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
+import org.bouncycastle.util.Strings;
/**
* <pre>
@@ -219,7 +220,7 @@ public class IssuingDistributionPoint
public String toString()
{
- String sep = System.getProperty("line.separator");
+ String sep = Strings.lineSeparator();
StringBuffer buf = new StringBuffer();
buf.append("IssuingDistributionPoint: [");
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 01980bec..01c9aa2a 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyPurposeId.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/KeyPurposeId.java
@@ -145,6 +145,11 @@ public class KeyPurposeId
return null;
}
+ public ASN1ObjectIdentifier toOID()
+ {
+ return id;
+ }
+
public ASN1Primitive toASN1Primitive()
{
return id;
@@ -154,4 +159,9 @@ public class KeyPurposeId
{
return id.getId();
}
+
+ public String toString()
+ {
+ return id.toString();
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraintValidator.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraintValidator.java
new file mode 100644
index 00000000..4596fe0c
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraintValidator.java
@@ -0,0 +1,18 @@
+package org.bouncycastle.asn1.x509;
+
+public interface NameConstraintValidator
+{
+ void checkPermitted(GeneralName name)
+ throws NameConstraintValidatorException;
+
+ void checkExcluded(GeneralName name)
+ throws NameConstraintValidatorException;
+
+ void intersectPermittedSubtree(GeneralSubtree permitted);
+
+ void intersectPermittedSubtree(GeneralSubtree[] permitted);
+
+ void intersectEmptyPermittedSubtree(int nameType);
+
+ void addExcludedSubtree(GeneralSubtree subtree);
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraintValidatorException.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraintValidatorException.java
new file mode 100644
index 00000000..517fddb0
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraintValidatorException.java
@@ -0,0 +1,10 @@
+package org.bouncycastle.asn1.x509;
+
+public class NameConstraintValidatorException
+ extends Exception
+{
+ public NameConstraintValidatorException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
new file mode 100644
index 00000000..0f15dae1
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/PKIXNameConstraintValidator.java
@@ -0,0 +1,1920 @@
+package org.bouncycastle.asn1.x509;
+
+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.util.Arrays;
+import org.bouncycastle.util.Integers;
+import org.bouncycastle.util.Strings;
+
+public class PKIXNameConstraintValidator
+ implements NameConstraintValidator
+{
+ private Set excludedSubtreesDN = new HashSet();
+
+ private Set excludedSubtreesDNS = new HashSet();
+
+ private Set excludedSubtreesEmail = new HashSet();
+
+ private Set excludedSubtreesURI = new HashSet();
+
+ private Set excludedSubtreesIP = new HashSet();
+
+ private Set permittedSubtreesDN;
+
+ private Set permittedSubtreesDNS;
+
+ private Set permittedSubtreesEmail;
+
+ private Set permittedSubtreesURI;
+
+ private Set permittedSubtreesIP;
+
+ public PKIXNameConstraintValidator()
+ {
+ }
+
+ /**
+ * Checks if the given GeneralName is in the permitted set.
+ *
+ * @param name The GeneralName
+ * @throws NameConstraintValidatorException If the <code>name</code>
+ */
+ public void checkPermitted(GeneralName name)
+ throws NameConstraintValidatorException
+ {
+ switch (name.getTagNo())
+ {
+ case GeneralName.rfc822Name:
+ checkPermittedEmail(permittedSubtreesEmail,
+ extractNameAsString(name));
+ break;
+ case GeneralName.dNSName:
+ checkPermittedDNS(permittedSubtreesDNS, DERIA5String.getInstance(
+ name.getName()).getString());
+ break;
+ case GeneralName.directoryName:
+ checkPermittedDN(X500Name.getInstance(name.getName()));
+ break;
+ case GeneralName.uniformResourceIdentifier:
+ checkPermittedURI(permittedSubtreesURI, DERIA5String.getInstance(
+ name.getName()).getString());
+ break;
+ case GeneralName.iPAddress:
+ byte[] ip = ASN1OctetString.getInstance(name.getName()).getOctets();
+
+ checkPermittedIP(permittedSubtreesIP, ip);
+ }
+ }
+
+ /**
+ * Check if the given GeneralName is contained in the excluded set.
+ *
+ * @param name The GeneralName.
+ * @throws NameConstraintValidatorException If the <code>name</code> is
+ * excluded.
+ */
+ public void checkExcluded(GeneralName name)
+ throws NameConstraintValidatorException
+ {
+ switch (name.getTagNo())
+ {
+ case GeneralName.rfc822Name:
+ checkExcludedEmail(excludedSubtreesEmail, extractNameAsString(name));
+ break;
+ case GeneralName.dNSName:
+ checkExcludedDNS(excludedSubtreesDNS, DERIA5String.getInstance(
+ name.getName()).getString());
+ break;
+ case GeneralName.directoryName:
+ checkExcludedDN(X500Name.getInstance(name.getName()));
+ break;
+ case GeneralName.uniformResourceIdentifier:
+ checkExcludedURI(excludedSubtreesURI, DERIA5String.getInstance(
+ name.getName()).getString());
+ break;
+ case GeneralName.iPAddress:
+ byte[] ip = ASN1OctetString.getInstance(name.getName()).getOctets();
+
+ checkExcludedIP(excludedSubtreesIP, ip);
+ }
+ }
+
+ public void intersectPermittedSubtree(GeneralSubtree permitted)
+ {
+ intersectPermittedSubtree(new GeneralSubtree[]{permitted});
+ }
+
+ /**
+ * Updates the permitted set of these name constraints with the intersection
+ * with the given subtree.
+ *
+ * @param permitted The permitted subtrees
+ */
+ public void intersectPermittedSubtree(GeneralSubtree[] permitted)
+ {
+ Map subtreesMap = new HashMap();
+
+ // group in sets in a map ordered by tag no.
+ for (int i = 0; i != permitted.length; i++)
+ {
+ GeneralSubtree subtree = permitted[i];
+ Integer tagNo = Integers.valueOf(subtree.getBase().getTagNo());
+ if (subtreesMap.get(tagNo) == null)
+ {
+ subtreesMap.put(tagNo, new HashSet());
+ }
+ ((Set)subtreesMap.get(tagNo)).add(subtree);
+ }
+
+ for (Iterator it = subtreesMap.entrySet().iterator(); it.hasNext(); )
+ {
+ Map.Entry entry = (Map.Entry)it.next();
+
+ // go through all subtree groups
+ switch (((Integer)entry.getKey()).intValue())
+ {
+ case GeneralName.rfc822Name:
+ permittedSubtreesEmail = intersectEmail(permittedSubtreesEmail,
+ (Set)entry.getValue());
+ break;
+ case GeneralName.dNSName:
+ permittedSubtreesDNS = intersectDNS(permittedSubtreesDNS,
+ (Set)entry.getValue());
+ break;
+ case GeneralName.directoryName:
+ permittedSubtreesDN = intersectDN(permittedSubtreesDN,
+ (Set)entry.getValue());
+ break;
+ case GeneralName.uniformResourceIdentifier:
+ permittedSubtreesURI = intersectURI(permittedSubtreesURI,
+ (Set)entry.getValue());
+ break;
+ case GeneralName.iPAddress:
+ permittedSubtreesIP = intersectIP(permittedSubtreesIP,
+ (Set)entry.getValue());
+ }
+ }
+ }
+
+ public void intersectEmptyPermittedSubtree(int nameType)
+ {
+ switch (nameType)
+ {
+ case GeneralName.rfc822Name:
+ permittedSubtreesEmail = new HashSet();
+ break;
+ case GeneralName.dNSName:
+ permittedSubtreesDNS = new HashSet();
+ break;
+ case GeneralName.directoryName:
+ permittedSubtreesDN = new HashSet();
+ break;
+ case GeneralName.uniformResourceIdentifier:
+ permittedSubtreesURI = new HashSet();
+ break;
+ case GeneralName.iPAddress:
+ permittedSubtreesIP = new HashSet();
+ }
+ }
+
+ /**
+ * Adds a subtree to the excluded set of these name constraints.
+ *
+ * @param subtree A subtree with an excluded GeneralName.
+ */
+ public void addExcludedSubtree(GeneralSubtree subtree)
+ {
+ GeneralName base = subtree.getBase();
+
+ switch (base.getTagNo())
+ {
+ case GeneralName.rfc822Name:
+ excludedSubtreesEmail = unionEmail(excludedSubtreesEmail,
+ extractNameAsString(base));
+ break;
+ case GeneralName.dNSName:
+ excludedSubtreesDNS = unionDNS(excludedSubtreesDNS,
+ extractNameAsString(base));
+ break;
+ case GeneralName.directoryName:
+ excludedSubtreesDN = unionDN(excludedSubtreesDN,
+ (ASN1Sequence)base.getName().toASN1Primitive());
+ break;
+ case GeneralName.uniformResourceIdentifier:
+ excludedSubtreesURI = unionURI(excludedSubtreesURI,
+ extractNameAsString(base));
+ break;
+ case GeneralName.iPAddress:
+ excludedSubtreesIP = unionIP(excludedSubtreesIP, ASN1OctetString
+ .getInstance(base.getName()).getOctets());
+ break;
+ }
+ }
+
+ public int hashCode()
+ {
+ return hashCollection(excludedSubtreesDN)
+ + hashCollection(excludedSubtreesDNS)
+ + hashCollection(excludedSubtreesEmail)
+ + hashCollection(excludedSubtreesIP)
+ + hashCollection(excludedSubtreesURI)
+ + hashCollection(permittedSubtreesDN)
+ + hashCollection(permittedSubtreesDNS)
+ + hashCollection(permittedSubtreesEmail)
+ + hashCollection(permittedSubtreesIP)
+ + hashCollection(permittedSubtreesURI);
+ }
+
+ 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);
+ }
+
+ 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;
+ }
+
+ private void checkPermittedDN(X500Name dns)
+ throws NameConstraintValidatorException
+ {
+ checkPermittedDN(permittedSubtreesDN, ASN1Sequence.getInstance(dns.toASN1Primitive()));
+ }
+
+ private void checkExcludedDN(X500Name dns)
+ throws NameConstraintValidatorException
+ {
+ checkExcludedDN(excludedSubtreesDN, ASN1Sequence.getInstance(dns));
+ }
+
+ private static boolean withinDNSubtree(
+ ASN1Sequence dns,
+ ASN1Sequence subtree)
+ {
+ if (subtree.size() < 1)
+ {
+ return false;
+ }
+
+ if (subtree.size() > dns.size())
+ {
+ return false;
+ }
+
+ for (int j = subtree.size() - 1; j >= 0; j--)
+ {
+ if (!subtree.getObjectAt(j).equals(dns.getObjectAt(j)))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private void checkPermittedDN(Set permitted, ASN1Sequence dns)
+ throws NameConstraintValidatorException
+ {
+ if (permitted == null)
+ {
+ return;
+ }
+
+ if (permitted.isEmpty() && dns.size() == 0)
+ {
+ return;
+ }
+ Iterator it = permitted.iterator();
+
+ while (it.hasNext())
+ {
+ ASN1Sequence subtree = (ASN1Sequence)it.next();
+
+ if (withinDNSubtree(dns, subtree))
+ {
+ return;
+ }
+ }
+
+ throw new NameConstraintValidatorException(
+ "Subject distinguished name is not from a permitted subtree");
+ }
+
+ private void checkExcludedDN(Set excluded, ASN1Sequence dns)
+ throws NameConstraintValidatorException
+ {
+ if (excluded.isEmpty())
+ {
+ return;
+ }
+
+ Iterator it = excluded.iterator();
+
+ while (it.hasNext())
+ {
+ ASN1Sequence subtree = (ASN1Sequence)it.next();
+
+ if (withinDNSubtree(dns, subtree))
+ {
+ throw new NameConstraintValidatorException(
+ "Subject distinguished name is from an excluded subtree");
+ }
+ }
+ }
+
+ private Set intersectDN(Set permitted, Set dns)
+ {
+ Set intersect = new HashSet();
+ for (Iterator it = dns.iterator(); it.hasNext(); )
+ {
+ ASN1Sequence dn = ASN1Sequence.getInstance(((GeneralSubtree)it
+ .next()).getBase().getName().toASN1Primitive());
+ if (permitted == null)
+ {
+ if (dn != null)
+ {
+ intersect.add(dn);
+ }
+ }
+ else
+ {
+ Iterator _iter = permitted.iterator();
+ while (_iter.hasNext())
+ {
+ ASN1Sequence subtree = (ASN1Sequence)_iter.next();
+
+ if (withinDNSubtree(dn, subtree))
+ {
+ intersect.add(dn);
+ }
+ else if (withinDNSubtree(subtree, dn))
+ {
+ intersect.add(subtree);
+ }
+ }
+ }
+ }
+ return intersect;
+ }
+
+ private Set unionDN(Set excluded, ASN1Sequence dn)
+ {
+ if (excluded.isEmpty())
+ {
+ if (dn == null)
+ {
+ return excluded;
+ }
+ excluded.add(dn);
+
+ return excluded;
+ }
+ else
+ {
+ Set intersect = new HashSet();
+
+ Iterator it = excluded.iterator();
+ while (it.hasNext())
+ {
+ ASN1Sequence subtree = (ASN1Sequence)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 NameConstraintValidatorException
+ {
+ if (permitted == null)
+ {
+ return;
+ }
+
+ Iterator it = permitted.iterator();
+
+ while (it.hasNext())
+ {
+ String str = ((String)it.next());
+
+ if (emailIsConstrained(email, str))
+ {
+ return;
+ }
+ }
+
+ if (email.length() == 0 && permitted.size() == 0)
+ {
+ return;
+ }
+
+ throw new NameConstraintValidatorException(
+ "Subject email address is not from a permitted subtree.");
+ }
+
+ private void checkExcludedEmail(Set excluded, String email)
+ throws NameConstraintValidatorException
+ {
+ if (excluded.isEmpty())
+ {
+ return;
+ }
+
+ Iterator it = excluded.iterator();
+
+ while (it.hasNext())
+ {
+ String str = (String)it.next();
+
+ if (emailIsConstrained(email, str))
+ {
+ throw new NameConstraintValidatorException(
+ "Email address is from an excluded subtree.");
+ }
+ }
+ }
+
+ /**
+ * Checks if the IP <code>ip</code> is included in the permitted set
+ * <code>permitted</code>.
+ *
+ * @param permitted A <code>Set</code> of permitted IP addresses with
+ * their subnet mask as byte arrays.
+ * @param ip The IP address.
+ * @throws NameConstraintValidatorException if the IP is not permitted.
+ */
+ private void checkPermittedIP(Set permitted, byte[] ip)
+ throws NameConstraintValidatorException
+ {
+ if (permitted == null)
+ {
+ return;
+ }
+
+ Iterator it = permitted.iterator();
+
+ while (it.hasNext())
+ {
+ byte[] ipWithSubnet = (byte[])it.next();
+
+ if (isIPConstrained(ip, ipWithSubnet))
+ {
+ return;
+ }
+ }
+ if (ip.length == 0 && permitted.size() == 0)
+ {
+ return;
+ }
+ throw new NameConstraintValidatorException(
+ "IP is not from a permitted subtree.");
+ }
+
+ /**
+ * Checks if the IP <code>ip</code> is included in the excluded set
+ * <code>excluded</code>.
+ *
+ * @param excluded A <code>Set</code> of excluded IP addresses with their
+ * subnet mask as byte arrays.
+ * @param ip The IP address.
+ * @throws NameConstraintValidatorException if the IP is excluded.
+ */
+ private void checkExcludedIP(Set excluded, byte[] ip)
+ throws NameConstraintValidatorException
+ {
+ if (excluded.isEmpty())
+ {
+ return;
+ }
+
+ Iterator it = excluded.iterator();
+
+ while (it.hasNext())
+ {
+ byte[] ipWithSubnet = (byte[])it.next();
+
+ if (isIPConstrained(ip, ipWithSubnet))
+ {
+ throw new NameConstraintValidatorException(
+ "IP is from an excluded subtree.");
+ }
+ }
+ }
+
+ /**
+ * Checks if the IP address <code>ip</code> is constrained by
+ * <code>constraint</code>.
+ *
+ * @param ip The IP address.
+ * @param constraint The constraint. This is an IP address concatenated with
+ * its subnetmask.
+ * @return <code>true</code> if constrained, <code>false</code>
+ * otherwise.
+ */
+ private boolean isIPConstrained(byte ip[], byte[] constraint)
+ {
+ int ipLength = ip.length;
+
+ if (ipLength != (constraint.length / 2))
+ {
+ return false;
+ }
+
+ byte[] subnetMask = new byte[ipLength];
+ System.arraycopy(constraint, ipLength, subnetMask, 0, ipLength);
+
+ byte[] permittedSubnetAddress = new byte[ipLength];
+
+ byte[] ipSubnetAddress = new byte[ipLength];
+
+ // the resulting IP address by applying the subnet mask
+ for (int i = 0; i < ipLength; i++)
+ {
+ permittedSubnetAddress[i] = (byte)(constraint[i] & subnetMask[i]);
+ ipSubnetAddress[i] = (byte)(ip[i] & subnetMask[i]);
+ }
+
+ return Arrays.areEqual(permittedSubnetAddress, ipSubnetAddress);
+ }
+
+ private boolean emailIsConstrained(String email, String constraint)
+ {
+ String sub = email.substring(email.indexOf('@') + 1);
+ // a particular mailbox
+ if (constraint.indexOf('@') != -1)
+ {
+ if (email.equalsIgnoreCase(constraint))
+ {
+ return true;
+ }
+ }
+ // on particular host
+ else if (!(constraint.charAt(0) == '.'))
+ {
+ if (sub.equalsIgnoreCase(constraint))
+ {
+ return true;
+ }
+ }
+ // address in sub domain
+ else if (withinDomain(sub, constraint))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean withinDomain(String testDomain, String domain)
+ {
+ String tempDomain = domain;
+ if (tempDomain.startsWith("."))
+ {
+ tempDomain = tempDomain.substring(1);
+ }
+ String[] domainParts = Strings.split(tempDomain, '.');
+ String[] testDomainParts = Strings.split(testDomain, '.');
+ // must have at least one subdomain
+ if (testDomainParts.length <= domainParts.length)
+ {
+ return false;
+ }
+ int d = testDomainParts.length - domainParts.length;
+ for (int i = -1; i < domainParts.length; i++)
+ {
+ if (i == -1)
+ {
+ if (testDomainParts[i + d].equals(""))
+ {
+ return false;
+ }
+ }
+ else if (!domainParts[i].equalsIgnoreCase(testDomainParts[i + d]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void checkPermittedDNS(Set permitted, String dns)
+ throws NameConstraintValidatorException
+ {
+ if (permitted == null)
+ {
+ return;
+ }
+
+ Iterator it = permitted.iterator();
+
+ while (it.hasNext())
+ {
+ String str = ((String)it.next());
+
+ // is sub domain
+ if (withinDomain(dns, str) || dns.equalsIgnoreCase(str))
+ {
+ return;
+ }
+ }
+ if (dns.length() == 0 && permitted.size() == 0)
+ {
+ return;
+ }
+ throw new NameConstraintValidatorException(
+ "DNS is not from a permitted subtree.");
+ }
+
+ private void checkExcludedDNS(Set excluded, String dns)
+ throws NameConstraintValidatorException
+ {
+ if (excluded.isEmpty())
+ {
+ return;
+ }
+
+ Iterator it = excluded.iterator();
+
+ while (it.hasNext())
+ {
+ String str = ((String)it.next());
+
+ // is sub domain or the same
+ if (withinDomain(dns, str) || dns.equalsIgnoreCase(str))
+ {
+ throw new NameConstraintValidatorException(
+ "DNS is from an excluded subtree.");
+ }
+ }
+ }
+
+ /**
+ * The common part of <code>email1</code> and <code>email2</code> is
+ * added to the union <code>union</code>. If <code>email1</code> and
+ * <code>email2</code> have nothing in common they are added both.
+ *
+ * @param email1 Email address constraint 1.
+ * @param email2 Email address constraint 2.
+ * @param union The union.
+ */
+ private void unionEmail(String email1, String email2, Set union)
+ {
+ // email1 is a particular address
+ if (email1.indexOf('@') != -1)
+ {
+ String _sub = email1.substring(email1.indexOf('@') + 1);
+ // both are a particular mailbox
+ if (email2.indexOf('@') != -1)
+ {
+ if (email1.equalsIgnoreCase(email2))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(_sub, email2))
+ {
+ union.add(email2);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ // email2 specifies a particular host
+ else
+ {
+ if (_sub.equalsIgnoreCase(email2))
+ {
+ union.add(email2);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ }
+ // email1 specifies a domain
+ else if (email1.startsWith("."))
+ {
+ if (email2.indexOf('@') != -1)
+ {
+ String _sub = email2.substring(email1.indexOf('@') + 1);
+ if (withinDomain(_sub, email1))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(email1, email2)
+ || email1.equalsIgnoreCase(email2))
+ {
+ union.add(email2);
+ }
+ else if (withinDomain(email2, email1))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ else
+ {
+ if (withinDomain(email2, email1))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ }
+ // email specifies a host
+ else
+ {
+ if (email2.indexOf('@') != -1)
+ {
+ String _sub = email2.substring(email1.indexOf('@') + 1);
+ if (_sub.equalsIgnoreCase(email1))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(email1, email2))
+ {
+ union.add(email2);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ // email2 specifies a particular host
+ else
+ {
+ if (email1.equalsIgnoreCase(email2))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ }
+ }
+
+ private void unionURI(String email1, String email2, Set union)
+ {
+ // email1 is a particular address
+ if (email1.indexOf('@') != -1)
+ {
+ String _sub = email1.substring(email1.indexOf('@') + 1);
+ // both are a particular mailbox
+ if (email2.indexOf('@') != -1)
+ {
+ if (email1.equalsIgnoreCase(email2))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(_sub, email2))
+ {
+ union.add(email2);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ // email2 specifies a particular host
+ else
+ {
+ if (_sub.equalsIgnoreCase(email2))
+ {
+ union.add(email2);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ }
+ // email1 specifies a domain
+ else if (email1.startsWith("."))
+ {
+ if (email2.indexOf('@') != -1)
+ {
+ String _sub = email2.substring(email1.indexOf('@') + 1);
+ if (withinDomain(_sub, email1))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(email1, email2)
+ || email1.equalsIgnoreCase(email2))
+ {
+ union.add(email2);
+ }
+ else if (withinDomain(email2, email1))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ else
+ {
+ if (withinDomain(email2, email1))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ }
+ // email specifies a host
+ else
+ {
+ if (email2.indexOf('@') != -1)
+ {
+ String _sub = email2.substring(email1.indexOf('@') + 1);
+ if (_sub.equalsIgnoreCase(email1))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(email1, email2))
+ {
+ union.add(email2);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ // email2 specifies a particular host
+ else
+ {
+ if (email1.equalsIgnoreCase(email2))
+ {
+ union.add(email1);
+ }
+ else
+ {
+ union.add(email1);
+ union.add(email2);
+ }
+ }
+ }
+ }
+
+ private Set intersectDNS(Set permitted, Set dnss)
+ {
+ Set intersect = new HashSet();
+ for (Iterator it = dnss.iterator(); it.hasNext(); )
+ {
+ String dns = extractNameAsString(((GeneralSubtree)it.next())
+ .getBase());
+ if (permitted == null)
+ {
+ if (dns != null)
+ {
+ intersect.add(dns);
+ }
+ }
+ else
+ {
+ Iterator _iter = permitted.iterator();
+ while (_iter.hasNext())
+ {
+ String _permitted = (String)_iter.next();
+
+ if (withinDomain(_permitted, dns))
+ {
+ intersect.add(_permitted);
+ }
+ else if (withinDomain(dns, _permitted))
+ {
+ intersect.add(dns);
+ }
+ }
+ }
+ }
+
+ return intersect;
+ }
+
+ private Set unionDNS(Set excluded, String dns)
+ {
+ if (excluded.isEmpty())
+ {
+ if (dns == null)
+ {
+ return excluded;
+ }
+ excluded.add(dns);
+
+ return excluded;
+ }
+ else
+ {
+ Set union = new HashSet();
+
+ Iterator _iter = excluded.iterator();
+ while (_iter.hasNext())
+ {
+ String _permitted = (String)_iter.next();
+
+ if (withinDomain(_permitted, dns))
+ {
+ union.add(dns);
+ }
+ else if (withinDomain(dns, _permitted))
+ {
+ union.add(_permitted);
+ }
+ else
+ {
+ union.add(_permitted);
+ union.add(dns);
+ }
+ }
+
+ return union;
+ }
+ }
+
+ /**
+ * The most restricting part from <code>email1</code> and
+ * <code>email2</code> is added to the intersection <code>intersect</code>.
+ *
+ * @param email1 Email address constraint 1.
+ * @param email2 Email address constraint 2.
+ * @param intersect The intersection.
+ */
+ private void intersectEmail(String email1, String email2, Set intersect)
+ {
+ // email1 is a particular address
+ if (email1.indexOf('@') != -1)
+ {
+ String _sub = email1.substring(email1.indexOf('@') + 1);
+ // both are a particular mailbox
+ if (email2.indexOf('@') != -1)
+ {
+ if (email1.equalsIgnoreCase(email2))
+ {
+ intersect.add(email1);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(_sub, email2))
+ {
+ intersect.add(email1);
+ }
+ }
+ // email2 specifies a particular host
+ else
+ {
+ if (_sub.equalsIgnoreCase(email2))
+ {
+ intersect.add(email1);
+ }
+ }
+ }
+ // email specifies a domain
+ else if (email1.startsWith("."))
+ {
+ if (email2.indexOf('@') != -1)
+ {
+ String _sub = email2.substring(email1.indexOf('@') + 1);
+ if (withinDomain(_sub, email1))
+ {
+ intersect.add(email2);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(email1, email2)
+ || email1.equalsIgnoreCase(email2))
+ {
+ intersect.add(email1);
+ }
+ else if (withinDomain(email2, email1))
+ {
+ intersect.add(email2);
+ }
+ }
+ else
+ {
+ if (withinDomain(email2, email1))
+ {
+ intersect.add(email2);
+ }
+ }
+ }
+ // email1 specifies a host
+ else
+ {
+ if (email2.indexOf('@') != -1)
+ {
+ String _sub = email2.substring(email2.indexOf('@') + 1);
+ if (_sub.equalsIgnoreCase(email1))
+ {
+ intersect.add(email2);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(email1, email2))
+ {
+ intersect.add(email1);
+ }
+ }
+ // email2 specifies a particular host
+ else
+ {
+ if (email1.equalsIgnoreCase(email2))
+ {
+ intersect.add(email1);
+ }
+ }
+ }
+ }
+
+ private void checkExcludedURI(Set excluded, String uri)
+ throws NameConstraintValidatorException
+ {
+ if (excluded.isEmpty())
+ {
+ return;
+ }
+
+ Iterator it = excluded.iterator();
+
+ while (it.hasNext())
+ {
+ String str = ((String)it.next());
+
+ if (isUriConstrained(uri, str))
+ {
+ throw new NameConstraintValidatorException(
+ "URI is from an excluded subtree.");
+ }
+ }
+ }
+
+ private Set intersectURI(Set permitted, Set uris)
+ {
+ Set intersect = new HashSet();
+ for (Iterator it = uris.iterator(); it.hasNext(); )
+ {
+ String uri = extractNameAsString(((GeneralSubtree)it.next())
+ .getBase());
+ if (permitted == null)
+ {
+ if (uri != null)
+ {
+ intersect.add(uri);
+ }
+ }
+ else
+ {
+ Iterator _iter = permitted.iterator();
+ while (_iter.hasNext())
+ {
+ String _permitted = (String)_iter.next();
+ intersectURI(_permitted, uri, intersect);
+ }
+ }
+ }
+ return intersect;
+ }
+
+ private Set unionURI(Set excluded, String uri)
+ {
+ if (excluded.isEmpty())
+ {
+ if (uri == null)
+ {
+ return excluded;
+ }
+ excluded.add(uri);
+
+ return excluded;
+ }
+ else
+ {
+ Set union = new HashSet();
+
+ Iterator _iter = excluded.iterator();
+ while (_iter.hasNext())
+ {
+ String _excluded = (String)_iter.next();
+
+ unionURI(_excluded, uri, union);
+ }
+
+ return union;
+ }
+ }
+
+ private void intersectURI(String email1, String email2, Set intersect)
+ {
+ // email1 is a particular address
+ if (email1.indexOf('@') != -1)
+ {
+ String _sub = email1.substring(email1.indexOf('@') + 1);
+ // both are a particular mailbox
+ if (email2.indexOf('@') != -1)
+ {
+ if (email1.equalsIgnoreCase(email2))
+ {
+ intersect.add(email1);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(_sub, email2))
+ {
+ intersect.add(email1);
+ }
+ }
+ // email2 specifies a particular host
+ else
+ {
+ if (_sub.equalsIgnoreCase(email2))
+ {
+ intersect.add(email1);
+ }
+ }
+ }
+ // email specifies a domain
+ else if (email1.startsWith("."))
+ {
+ if (email2.indexOf('@') != -1)
+ {
+ String _sub = email2.substring(email1.indexOf('@') + 1);
+ if (withinDomain(_sub, email1))
+ {
+ intersect.add(email2);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(email1, email2)
+ || email1.equalsIgnoreCase(email2))
+ {
+ intersect.add(email1);
+ }
+ else if (withinDomain(email2, email1))
+ {
+ intersect.add(email2);
+ }
+ }
+ else
+ {
+ if (withinDomain(email2, email1))
+ {
+ intersect.add(email2);
+ }
+ }
+ }
+ // email1 specifies a host
+ else
+ {
+ if (email2.indexOf('@') != -1)
+ {
+ String _sub = email2.substring(email2.indexOf('@') + 1);
+ if (_sub.equalsIgnoreCase(email1))
+ {
+ intersect.add(email2);
+ }
+ }
+ // email2 specifies a domain
+ else if (email2.startsWith("."))
+ {
+ if (withinDomain(email1, email2))
+ {
+ intersect.add(email1);
+ }
+ }
+ // email2 specifies a particular host
+ else
+ {
+ if (email1.equalsIgnoreCase(email2))
+ {
+ intersect.add(email1);
+ }
+ }
+ }
+ }
+
+ private void checkPermittedURI(Set permitted, String uri)
+ throws NameConstraintValidatorException
+ {
+ if (permitted == null)
+ {
+ return;
+ }
+
+ Iterator it = permitted.iterator();
+
+ while (it.hasNext())
+ {
+ String str = ((String)it.next());
+
+ if (isUriConstrained(uri, str))
+ {
+ return;
+ }
+ }
+ if (uri.length() == 0 && permitted.size() == 0)
+ {
+ return;
+ }
+ throw new NameConstraintValidatorException(
+ "URI is not from a permitted subtree.");
+ }
+
+ private boolean isUriConstrained(String uri, String constraint)
+ {
+ String host = extractHostFromURL(uri);
+ // a host
+ if (!constraint.startsWith("."))
+ {
+ if (host.equalsIgnoreCase(constraint))
+ {
+ return true;
+ }
+ }
+
+ // in sub domain or domain
+ else if (withinDomain(host, constraint))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ private static String extractHostFromURL(String url)
+ {
+ // see RFC 1738
+ // remove ':' after protocol, e.g. http:
+ String sub = url.substring(url.indexOf(':') + 1);
+ // extract host from Common Internet Scheme Syntax, e.g. http://
+ if (sub.indexOf("//") != -1)
+ {
+ sub = sub.substring(sub.indexOf("//") + 2);
+ }
+ // first remove port, e.g. http://test.com:21
+ if (sub.lastIndexOf(':') != -1)
+ {
+ sub = sub.substring(0, sub.lastIndexOf(':'));
+ }
+ // remove user and password, e.g. http://john:password@test.com
+ sub = sub.substring(sub.indexOf(':') + 1);
+ sub = sub.substring(sub.indexOf('@') + 1);
+ // remove local parts, e.g. http://test.com/bla
+ if (sub.indexOf('/') != -1)
+ {
+ sub = sub.substring(0, sub.indexOf('/'));
+ }
+ return sub;
+ }
+
+ private String extractNameAsString(GeneralName name)
+ {
+ return DERIA5String.getInstance(name.getName()).getString();
+ }
+
+ /**
+ * Returns the maximum IP address.
+ *
+ * @param ip1 The first IP address.
+ * @param ip2 The second IP address.
+ * @return The maximum IP address.
+ */
+ private static byte[] max(byte[] ip1, byte[] ip2)
+ {
+ for (int i = 0; i < ip1.length; i++)
+ {
+ if ((ip1[i] & 0xFFFF) > (ip2[i] & 0xFFFF))
+ {
+ return ip1;
+ }
+ }
+ return ip2;
+ }
+
+ /**
+ * Returns the minimum IP address.
+ *
+ * @param ip1 The first IP address.
+ * @param ip2 The second IP address.
+ * @return The minimum IP address.
+ */
+ private static byte[] min(byte[] ip1, byte[] ip2)
+ {
+ for (int i = 0; i < ip1.length; i++)
+ {
+ if ((ip1[i] & 0xFFFF) < (ip2[i] & 0xFFFF))
+ {
+ return ip1;
+ }
+ }
+ return ip2;
+ }
+
+ /**
+ * Compares IP address <code>ip1</code> with <code>ip2</code>. If ip1
+ * is equal to ip2 0 is returned. If ip1 is bigger 1 is returned, -1
+ * otherwise.
+ *
+ * @param ip1 The first IP address.
+ * @param ip2 The second IP address.
+ * @return 0 if ip1 is equal to ip2, 1 if ip1 is bigger, -1 otherwise.
+ */
+ private static int compareTo(byte[] ip1, byte[] ip2)
+ {
+ if (Arrays.areEqual(ip1, ip2))
+ {
+ return 0;
+ }
+ if (Arrays.areEqual(max(ip1, ip2), ip1))
+ {
+ return 1;
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the logical OR of the IP addresses <code>ip1</code> and
+ * <code>ip2</code>.
+ *
+ * @param ip1 The first IP address.
+ * @param ip2 The second IP address.
+ * @return The OR of <code>ip1</code> and <code>ip2</code>.
+ */
+ private static byte[] or(byte[] ip1, byte[] ip2)
+ {
+ byte[] temp = new byte[ip1.length];
+ for (int i = 0; i < ip1.length; i++)
+ {
+ temp[i] = (byte)(ip1[i] | ip2[i]);
+ }
+ return temp;
+ }
+
+ private int hashCollection(Collection coll)
+ {
+ if (coll == null)
+ {
+ return 0;
+ }
+ int hash = 0;
+ Iterator it1 = coll.iterator();
+ while (it1.hasNext())
+ {
+ Object o = it1.next();
+ if (o instanceof byte[])
+ {
+ hash += Arrays.hashCode((byte[])o);
+ }
+ else
+ {
+ hash += o.hashCode();
+ }
+ }
+ return hash;
+ }
+
+ private boolean collectionsAreEqual(Collection coll1, Collection coll2)
+ {
+ if (coll1 == coll2)
+ {
+ return true;
+ }
+ if (coll1 == null || coll2 == null)
+ {
+ return false;
+ }
+ if (coll1.size() != coll2.size())
+ {
+ return false;
+ }
+ Iterator it1 = coll1.iterator();
+
+ while (it1.hasNext())
+ {
+ Object a = it1.next();
+ Iterator it2 = coll2.iterator();
+ boolean found = false;
+ while (it2.hasNext())
+ {
+ Object b = it2.next();
+ if (equals(a, b))
+ {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean equals(Object o1, Object o2)
+ {
+ if (o1 == o2)
+ {
+ return true;
+ }
+ if (o1 == null || o2 == null)
+ {
+ return false;
+ }
+ if (o1 instanceof byte[] && o2 instanceof byte[])
+ {
+ return Arrays.areEqual((byte[])o1, (byte[])o2);
+ }
+ else
+ {
+ return o1.equals(o2);
+ }
+ }
+
+ /**
+ * Stringifies an IPv4 or v6 address with subnet mask.
+ *
+ * @param ip The IP with subnet mask.
+ * @return The stringified IP address.
+ */
+ private String stringifyIP(byte[] ip)
+ {
+ 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;
+ }
+}
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 d1de26fc..97f752ae 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyInformation.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyInformation.java
@@ -65,11 +65,13 @@ public class PolicyInformation
return policyQualifiers;
}
- /*
+ /*
+ * <pre>
* PolicyInformation ::= SEQUENCE {
* policyIdentifier CertPolicyId,
* policyQualifiers SEQUENCE SIZE (1..MAX) OF
* PolicyQualifierInfo OPTIONAL }
+ * </pre>
*/
public ASN1Primitive toASN1Primitive()
{
@@ -84,4 +86,31 @@ public class PolicyInformation
return new DERSequence(v);
}
+
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append("Policy information: ");
+ sb.append(policyIdentifier);
+
+ if (policyQualifiers != null)
+ {
+ StringBuffer p = new StringBuffer();
+ for (int i = 0; i < policyQualifiers.size(); i++)
+ {
+ if (p.length() != 0)
+ {
+ p.append(", ");
+ }
+ p.append(PolicyQualifierInfo.getInstance(policyQualifiers.getObjectAt(i)));
+ }
+
+ sb.append("[");
+ sb.append(p);
+ sb.append("]");
+ }
+
+ return sb.toString();
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierId.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierId.java
new file mode 100644
index 00000000..82835f6a
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierId.java
@@ -0,0 +1,31 @@
+
+package org.bouncycastle.asn1.x509;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+
+/**
+ * PolicyQualifierId, used in the CertificatePolicies
+ * X509V3 extension.
+ *
+ * <pre>
+ * id-qt OBJECT IDENTIFIER ::= { id-pkix 2 }
+ * id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 }
+ * id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 }
+ * PolicyQualifierId ::=
+ * OBJECT IDENTIFIER (id-qt-cps | id-qt-unotice)
+ * </pre>
+ */
+public class PolicyQualifierId extends ASN1ObjectIdentifier
+{
+ private static final String id_qt = "1.3.6.1.5.5.7.2";
+
+ private PolicyQualifierId(String id)
+ {
+ super(id);
+ }
+
+ public static final PolicyQualifierId id_qt_cps =
+ new PolicyQualifierId(id_qt + ".1");
+ public static final PolicyQualifierId id_qt_unotice =
+ new PolicyQualifierId(id_qt + ".2");
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
new file mode 100644
index 00000000..2f79a963
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/PolicyQualifierInfo.java
@@ -0,0 +1,117 @@
+package org.bouncycastle.asn1.x509;
+
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Object;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DERIA5String;
+import org.bouncycastle.asn1.DERSequence;
+
+/**
+ * Policy qualifiers, used in the X509V3 CertificatePolicies
+ * extension.
+ *
+ * <pre>
+ * PolicyQualifierInfo ::= SEQUENCE {
+ * policyQualifierId PolicyQualifierId,
+ * qualifier ANY DEFINED BY policyQualifierId }
+ *
+ * PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
+ * </pre>
+ */
+public class PolicyQualifierInfo
+ extends ASN1Object
+{
+ private ASN1ObjectIdentifier policyQualifierId;
+ private ASN1Encodable qualifier;
+
+ /**
+ * Creates a new <code>PolicyQualifierInfo</code> instance.
+ *
+ * @param policyQualifierId a <code>PolicyQualifierId</code> value
+ * @param qualifier the qualifier, defined by the above field.
+ */
+ public PolicyQualifierInfo(
+ ASN1ObjectIdentifier policyQualifierId,
+ ASN1Encodable qualifier)
+ {
+ this.policyQualifierId = policyQualifierId;
+ this.qualifier = qualifier;
+ }
+
+ /**
+ * Creates a new <code>PolicyQualifierInfo</code> containing a
+ * cPSuri qualifier.
+ *
+ * @param cps the CPS (certification practice statement) uri as a
+ * <code>String</code>.
+ */
+ public PolicyQualifierInfo(
+ String cps)
+ {
+ policyQualifierId = PolicyQualifierId.id_qt_cps;
+ qualifier = new DERIA5String (cps);
+ }
+
+ /**
+ * Creates a new <code>PolicyQualifierInfo</code> instance.
+ *
+ * @param as <code>PolicyQualifierInfo</code> X509 structure
+ * encoded as an ASN1Sequence.
+ * @deprecated use PolicyQualifierInfo.getInstance()
+ */
+ public PolicyQualifierInfo(
+ ASN1Sequence as)
+ {
+ if (as.size() != 2)
+ {
+ throw new IllegalArgumentException("Bad sequence size: "
+ + as.size());
+ }
+
+ policyQualifierId = ASN1ObjectIdentifier.getInstance(as.getObjectAt(0));
+ qualifier = as.getObjectAt(1);
+ }
+
+ public static PolicyQualifierInfo getInstance(
+ Object obj)
+ {
+ if (obj instanceof PolicyQualifierInfo)
+ {
+ return (PolicyQualifierInfo)obj;
+ }
+ else if (obj != null)
+ {
+ return new PolicyQualifierInfo(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+
+ public ASN1ObjectIdentifier getPolicyQualifierId()
+ {
+ return policyQualifierId;
+ }
+
+ public ASN1Encodable getQualifier()
+ {
+ return qualifier;
+ }
+
+ /**
+ * Returns a DER-encodable representation of this instance.
+ *
+ * @return a <code>ASN1Primitive</code> value
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector dev = new ASN1EncodableVector();
+ dev.add(policyQualifierId);
+ dev.add(qualifier);
+
+ return new DERSequence(dev);
+ }
+}
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 9e09cd72..0938a948 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo.java
@@ -64,6 +64,9 @@ public class SubjectPublicKeyInfo
this.algId = algId;
}
+ /**
+ @deprecated use SubjectPublicKeyInfo.getInstance()
+ */
public SubjectPublicKeyInfo(
ASN1Sequence seq)
{
@@ -104,7 +107,7 @@ public class SubjectPublicKeyInfo
public ASN1Primitive parsePublicKey()
throws IOException
{
- ASN1InputStream aIn = new ASN1InputStream(keyData.getBytes());
+ ASN1InputStream aIn = new ASN1InputStream(keyData.getOctets());
return aIn.readObject();
}
@@ -121,7 +124,7 @@ public class SubjectPublicKeyInfo
public ASN1Primitive getPublicKey()
throws IOException
{
- ASN1InputStream aIn = new ASN1InputStream(keyData.getBytes());
+ ASN1InputStream aIn = new ASN1InputStream(keyData.getOctets());
return aIn.readObject();
}
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 5fdbcd67..23f99d0a 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertList.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertList.java
@@ -1,6 +1,7 @@
package org.bouncycastle.asn1.x509;
import java.util.Enumeration;
+import java.util.NoSuchElementException;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1GeneralizedTime;
@@ -132,7 +133,7 @@ public class TBSCertList
public Object nextElement()
{
- return null; // TODO: check exception handling
+ throw new NoSuchElementException("Empty Enumeration");
}
}
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 e1c7a54b..e58220e6 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java
@@ -6,22 +6,22 @@ public interface X509ObjectIdentifiers
{
/** Subject RDN components: commonName = 2.5.4.3 */
- static final ASN1ObjectIdentifier commonName = new ASN1ObjectIdentifier("2.5.4.3");
+ static final ASN1ObjectIdentifier commonName = new ASN1ObjectIdentifier("2.5.4.3").intern();
/** Subject RDN components: countryName = 2.5.4.6 */
- static final ASN1ObjectIdentifier countryName = new ASN1ObjectIdentifier("2.5.4.6");
+ static final ASN1ObjectIdentifier countryName = new ASN1ObjectIdentifier("2.5.4.6").intern();
/** Subject RDN components: localityName = 2.5.4.7 */
- static final ASN1ObjectIdentifier localityName = new ASN1ObjectIdentifier("2.5.4.7");
+ static final ASN1ObjectIdentifier localityName = new ASN1ObjectIdentifier("2.5.4.7").intern();
/** Subject RDN components: stateOrProvinceName = 2.5.4.8 */
- static final ASN1ObjectIdentifier stateOrProvinceName = new ASN1ObjectIdentifier("2.5.4.8");
+ static final ASN1ObjectIdentifier stateOrProvinceName = new ASN1ObjectIdentifier("2.5.4.8").intern();
/** Subject RDN components: organization = 2.5.4.10 */
- static final ASN1ObjectIdentifier organization = new ASN1ObjectIdentifier("2.5.4.10");
+ static final ASN1ObjectIdentifier organization = new ASN1ObjectIdentifier("2.5.4.10").intern();
/** Subject RDN components: organizationalUnitName = 2.5.4.11 */
- static final ASN1ObjectIdentifier organizationalUnitName = new ASN1ObjectIdentifier("2.5.4.11");
+ static final ASN1ObjectIdentifier organizationalUnitName = new ASN1ObjectIdentifier("2.5.4.11").intern();
/** Subject RDN components: telephone_number = 2.5.4.20 */
- static final ASN1ObjectIdentifier id_at_telephoneNumber = new ASN1ObjectIdentifier("2.5.4.20");
+ static final ASN1ObjectIdentifier id_at_telephoneNumber = new ASN1ObjectIdentifier("2.5.4.20").intern();
/** Subject RDN components: name = 2.5.4.41 */
- static final ASN1ObjectIdentifier id_at_name = new ASN1ObjectIdentifier("2.5.4.41");
+ static final ASN1ObjectIdentifier id_at_name = new ASN1ObjectIdentifier("2.5.4.41").intern();
/**
* id-SHA1 OBJECT IDENTIFIER ::=
@@ -29,7 +29,7 @@ public interface X509ObjectIdentifiers
* <p>
* OID: 1.3.14.3.2.27
*/
- static final ASN1ObjectIdentifier id_SHA1 = new ASN1ObjectIdentifier("1.3.14.3.2.26");
+ static final ASN1ObjectIdentifier id_SHA1 = new ASN1ObjectIdentifier("1.3.14.3.2.26").intern();
/**
* ripemd160 OBJECT IDENTIFIER ::=
@@ -37,7 +37,7 @@ public interface X509ObjectIdentifiers
* <p>
* OID: 1.3.36.3.2.1
*/
- static final ASN1ObjectIdentifier ripemd160 = new ASN1ObjectIdentifier("1.3.36.3.2.1");
+ static final ASN1ObjectIdentifier ripemd160 = new ASN1ObjectIdentifier("1.3.36.3.2.1").intern();
/**
* ripemd160WithRSAEncryption OBJECT IDENTIFIER ::=
@@ -45,11 +45,11 @@ public interface X509ObjectIdentifiers
* <p>
* OID: 1.3.36.3.3.1.2
*/
- static final ASN1ObjectIdentifier ripemd160WithRSAEncryption = new ASN1ObjectIdentifier("1.3.36.3.3.1.2");
+ static final ASN1ObjectIdentifier ripemd160WithRSAEncryption = new ASN1ObjectIdentifier("1.3.36.3.3.1.2").intern();
/** OID: 2.5.8.1.1 */
- static final ASN1ObjectIdentifier id_ea_rsa = new ASN1ObjectIdentifier("2.5.8.1.1");
+ static final ASN1ObjectIdentifier id_ea_rsa = new ASN1ObjectIdentifier("2.5.8.1.1").intern();
/** id-pkix OID: 1.3.6.1.5.5.7
*/
@@ -70,9 +70,9 @@ public interface X509ObjectIdentifiers
/** id-pkix OID: 1.3.6.1.5.5.7.48 */
static final ASN1ObjectIdentifier id_ad = id_pkix.branch("48");
/** id-ad-caIssuers OID: 1.3.6.1.5.5.7.48.2 */
- static final ASN1ObjectIdentifier id_ad_caIssuers = id_ad.branch("2");
+ static final ASN1ObjectIdentifier id_ad_caIssuers = id_ad.branch("2").intern();
/** id-ad-ocsp OID: 1.3.6.1.5.5.7.48.1 */
- static final ASN1ObjectIdentifier id_ad_ocsp = id_ad.branch("1");
+ static final ASN1ObjectIdentifier id_ad_ocsp = id_ad.branch("1").intern();
/** OID for ocsp uri in AuthorityInformationAccess extension */
static final ASN1ObjectIdentifier ocspAccessMethod = id_ad_ocsp;
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 509111ad..abff3635 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHDomainParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHDomainParameters.java
@@ -12,6 +12,9 @@ import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERSequence;
+/**
+ * @deprecated use DomainParameters
+ */
public class DHDomainParameters
extends ASN1Object
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHPublicKey.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHPublicKey.java
index 7c6d217e..a74188ac 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHPublicKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHPublicKey.java
@@ -1,20 +1,41 @@
package org.bouncycastle.asn1.x9;
+import java.math.BigInteger;
+
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1TaggedObject;
+/**
+ * X9.42 definition of a DHPublicKey
+ * <pre>
+ * DHPublicKey ::= INTEGER
+ * </pre>
+ */
public class DHPublicKey
extends ASN1Object
{
private ASN1Integer y;
+ /**
+ * Return a DHPublicKey from the passed in tagged object.
+ *
+ * @param obj a tagged object.
+ * @param explicit true if the contents of the object is explictly tagged, false otherwise.
+ * @return a DHPublicKey
+ */
public static DHPublicKey getInstance(ASN1TaggedObject obj, boolean explicit)
{
return getInstance(ASN1Integer.getInstance(obj, explicit));
}
+ /**
+ * Return a DHPublicKey from the passed in object.
+ *
+ * @param obj an object for conversion or a byte[].
+ * @return a DHPublicKey
+ */
public static DHPublicKey getInstance(Object obj)
{
if (obj == null || obj instanceof DHPublicKey)
@@ -30,7 +51,7 @@ public class DHPublicKey
throw new IllegalArgumentException("Invalid DHPublicKey: " + obj.getClass().getName());
}
- public DHPublicKey(ASN1Integer y)
+ private DHPublicKey(ASN1Integer y)
{
if (y == null)
{
@@ -40,13 +61,38 @@ public class DHPublicKey
this.y = y;
}
- public ASN1Integer getY()
+ /**
+ * Base constructor.
+ *
+ * @param y the public value Y.
+ */
+ public DHPublicKey(BigInteger y)
{
- return this.y;
+ if (y == null)
+ {
+ throw new IllegalArgumentException("'y' cannot be null");
+ }
+
+ this.y = new ASN1Integer(y);
+ }
+
+ /**
+ * Return the public value Y for the key.
+ *
+ * @return the Y value.
+ */
+ public BigInteger getY()
+ {
+ return this.y.getPositiveValue();
}
+ /**
+ * Return an ASN.1 primitive representation of this object.
+ *
+ * @return an ASN1Integer.
+ */
public ASN1Primitive toASN1Primitive()
{
return this.y;
}
-}
+} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHValidationParms.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHValidationParms.java
index b3020e0a..db384590 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHValidationParms.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/DHValidationParms.java
@@ -9,6 +9,9 @@ import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERSequence;
+/**
+ * @deprecated use ValidationParams
+ */
public class DHValidationParms extends ASN1Object
{
private DERBitString seed;
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/DomainParameters.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/DomainParameters.java
new file mode 100644
index 00000000..e23f1b84
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/DomainParameters.java
@@ -0,0 +1,223 @@
+package org.bouncycastle.asn1.x9;
+
+import java.math.BigInteger;
+import java.util.Enumeration;
+
+import org.bouncycastle.asn1.ASN1Encodable;
+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.DERSequence;
+
+/**
+ * X9.44 Diffie-Hellman domain parameters.
+ * <pre>
+ * DomainParameters ::= SEQUENCE {
+ * p INTEGER, -- odd prime, p=jq +1
+ * g INTEGER, -- generator, g
+ * q INTEGER, -- factor of p-1
+ * j INTEGER OPTIONAL, -- subgroup factor, j>= 2
+ * validationParams ValidationParams OPTIONAL
+ * }
+ * </pre>
+ */
+public class DomainParameters
+ extends ASN1Object
+{
+ private final ASN1Integer p, g, q, j;
+ private final ValidationParams validationParams;
+
+ /**
+ * Return a DomainParameters object from the passed in tagged object.
+ *
+ * @param obj a tagged object.
+ * @param explicit true if the contents of the object is explictly tagged, false otherwise.
+ * @return a DomainParameters
+ */
+ public static DomainParameters getInstance(ASN1TaggedObject obj, boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ /**
+ * Return a DomainParameters object from the passed in object.
+ *
+ * @param obj an object for conversion or a byte[].
+ * @return a DomainParameters
+ */
+ public static DomainParameters getInstance(Object obj)
+ {
+ if (obj instanceof DomainParameters)
+ {
+ return (DomainParameters)obj;
+ }
+ else if (obj != null)
+ {
+ return new DomainParameters(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ /**
+ * Base constructor - the full domain parameter set.
+ *
+ * @param p the prime p defining the Galois field.
+ * @param g the generator of the multiplicative subgroup of order g.
+ * @param q specifies the prime factor of p - 1
+ * @param j optionally specifies the value that satisfies the equation p = jq+1
+ * @param validationParams parameters for validating these domain parameters.
+ */
+ public DomainParameters(BigInteger p, BigInteger g, BigInteger q, BigInteger j,
+ ValidationParams validationParams)
+ {
+ if (p == null)
+ {
+ throw new IllegalArgumentException("'p' cannot be null");
+ }
+ if (g == null)
+ {
+ throw new IllegalArgumentException("'g' cannot be null");
+ }
+ if (q == null)
+ {
+ throw new IllegalArgumentException("'q' cannot be null");
+ }
+
+ this.p = new ASN1Integer(p);
+ this.g = new ASN1Integer(g);
+ this.q = new ASN1Integer(q);
+
+ if (j != null)
+ {
+ this.j = new ASN1Integer(j);
+ }
+ else
+ {
+ this.j = null;
+ }
+ this.validationParams = validationParams;
+ }
+
+ private DomainParameters(ASN1Sequence seq)
+ {
+ if (seq.size() < 3 || seq.size() > 5)
+ {
+ throw new IllegalArgumentException("Bad sequence size: " + seq.size());
+ }
+
+ Enumeration e = seq.getObjects();
+ this.p = ASN1Integer.getInstance(e.nextElement());
+ this.g = ASN1Integer.getInstance(e.nextElement());
+ this.q = ASN1Integer.getInstance(e.nextElement());
+
+ ASN1Encodable next = getNext(e);
+
+ if (next != null && next instanceof ASN1Integer)
+ {
+ this.j = ASN1Integer.getInstance(next);
+ next = getNext(e);
+ }
+ else
+ {
+ this.j = null;
+ }
+
+ if (next != null)
+ {
+ this.validationParams = ValidationParams.getInstance(next.toASN1Primitive());
+ }
+ else
+ {
+ this.validationParams = null;
+ }
+ }
+
+ private static ASN1Encodable getNext(Enumeration e)
+ {
+ return e.hasMoreElements() ? (ASN1Encodable)e.nextElement() : null;
+ }
+
+ /**
+ * Return the prime p defining the Galois field.
+ *
+ * @return the prime p.
+ */
+ public BigInteger getP()
+ {
+ return this.p.getPositiveValue();
+ }
+
+ /**
+ * Return the generator of the multiplicative subgroup of order g.
+ *
+ * @return the generator g.
+ */
+ public BigInteger getG()
+ {
+ return this.g.getPositiveValue();
+ }
+
+ /**
+ * Return q, the prime factor of p - 1
+ *
+ * @return q value
+ */
+ public BigInteger getQ()
+ {
+ return this.q.getPositiveValue();
+ }
+
+ /**
+ * Return the value that satisfies the equation p = jq+1 (if present).
+ *
+ * @return j value or null.
+ */
+ public BigInteger getJ()
+ {
+ if (this.j == null)
+ {
+ return null;
+ }
+
+ return this.j.getPositiveValue();
+ }
+
+ /**
+ * Return the validation parameters for this set (if present).
+ *
+ * @return validation parameters, or null if absent.
+ */
+ public ValidationParams getValidationParams()
+ {
+ return this.validationParams;
+ }
+
+ /**
+ * Return an ASN.1 primitive representation of this object.
+ *
+ * @return a DERSequence containing the parameter values.
+ */
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ v.add(this.p);
+ v.add(this.g);
+ v.add(this.q);
+
+ if (this.j != null)
+ {
+ v.add(this.j);
+ }
+
+ if (this.validationParams != null)
+ {
+ v.add(this.validationParams);
+ }
+
+ return new DERSequence(v);
+ }
+} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
index cf3c7603..5abcca9f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/ECNamedCurveTable.java
@@ -4,6 +4,10 @@ import java.util.Enumeration;
import java.util.Vector;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+// BEGIN android-removed
+// import org.bouncycastle.asn1.anssi.ANSSINamedCurves;
+// import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
+// END android-removed
import org.bouncycastle.asn1.nist.NISTNamedCurves;
import org.bouncycastle.asn1.sec.SECNamedCurves;
// BEGIN android-removed
@@ -32,18 +36,23 @@ public class ECNamedCurveTable
ecP = SECNamedCurves.getByName(name);
}
+ if (ecP == null)
+ {
+ ecP = NISTNamedCurves.getByName(name);
+ }
+
// BEGIN android-removed
// if (ecP == null)
// {
// ecP = TeleTrusTNamedCurves.getByName(name);
// }
+ //
+ // if (ecP == null)
+ // {
+ // ecP = ANSSINamedCurves.getByName(name);
+ // }
// END android-removed
- if (ecP == null)
- {
- ecP = NISTNamedCurves.getByName(name);
- }
-
return ecP;
}
@@ -63,19 +72,63 @@ public class ECNamedCurveTable
oid = SECNamedCurves.getOID(name);
}
+ if (oid == null)
+ {
+ oid = NISTNamedCurves.getOID(name);
+ }
+
// BEGIN android-removed
// if (oid == null)
// {
// oid = TeleTrusTNamedCurves.getOID(name);
// }
+ //
+ // if (oid == null)
+ // {
+ // oid = ANSSINamedCurves.getOID(name);
+ // }
// END android-removed
- if (oid == null)
+ return oid;
+ }
+
+ /**
+ * return a X9ECParameters object representing the passed in named
+ * curve.
+ *
+ * @param oid the object id of the curve requested
+ * @return a standard name for the curve.
+ */
+ public static String getName(
+ ASN1ObjectIdentifier oid)
+ {
+ String name = NISTNamedCurves.getName(oid);
+
+ if (name == null)
{
- oid = NISTNamedCurves.getOID(name);
+ name = SECNamedCurves.getName(oid);
}
- return oid;
+ // BEGIN android-removed
+ // if (name == null)
+ // {
+ // name = TeleTrusTNamedCurves.getName(oid);
+ // }
+ // END android-removed
+
+ if (name == null)
+ {
+ name = X962NamedCurves.getName(oid);
+ }
+
+ // BEGIN android-removed
+ // if (name == null)
+ // {
+ // name = ECGOST3410NamedCurves.getName(oid);
+ // }
+ // END android-removed
+
+ return name;
}
/**
@@ -95,15 +148,20 @@ public class ECNamedCurveTable
ecP = SECNamedCurves.getByOID(oid);
}
+ // NOTE: All the NIST curves are currently from SEC, so no point in redundant OID lookup
+
// BEGIN android-removed
// if (ecP == null)
// {
// ecP = TeleTrusTNamedCurves.getByOID(oid);
// }
+ //
+ // if (ecP == null)
+ // {
+ // ecP = ANSSINamedCurves.getByOID(oid);
+ // }
// END android-removed
- // NOTE: All the NIST curves are currently from SEC, so no point in redundant OID lookup
-
return ecP;
}
@@ -121,6 +179,7 @@ public class ECNamedCurveTable
addEnumeration(v, NISTNamedCurves.getNames());
// BEGIN android-removed
// addEnumeration(v, TeleTrusTNamedCurves.getNames());
+ // addEnumeration(v, ANSSINamedCurves.getNames());
// END android-removed
return v.elements();
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java
new file mode 100644
index 00000000..34ad746a
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java
@@ -0,0 +1,99 @@
+package org.bouncycastle.asn1.x9;
+
+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;
+
+/**
+ * ValidationParams ::= SEQUENCE {
+ * seed BIT STRING,
+ * pgenCounter INTEGER
+ * }
+ */
+public class ValidationParams
+ extends ASN1Object
+{
+ private DERBitString seed;
+ private ASN1Integer pgenCounter;
+
+ public static ValidationParams getInstance(ASN1TaggedObject obj, boolean explicit)
+ {
+ return getInstance(ASN1Sequence.getInstance(obj, explicit));
+ }
+
+ public static ValidationParams getInstance(Object obj)
+ {
+ if (obj instanceof ValidationParams)
+ {
+ return (ValidationParams)obj;
+ }
+ else if (obj != null)
+ {
+ return new ValidationParams(ASN1Sequence.getInstance(obj));
+ }
+
+ return null;
+ }
+
+ public ValidationParams(byte[] seed, int pgenCounter)
+ {
+ if (seed == null)
+ {
+ throw new IllegalArgumentException("'seed' cannot be null");
+ }
+
+ this.seed = new DERBitString(seed);
+ this.pgenCounter = new ASN1Integer(pgenCounter);
+ }
+
+ public ValidationParams(DERBitString seed, ASN1Integer pgenCounter)
+ {
+ if (seed == null)
+ {
+ throw new IllegalArgumentException("'seed' cannot be null");
+ }
+ if (pgenCounter == null)
+ {
+ throw new IllegalArgumentException("'pgenCounter' cannot be null");
+ }
+
+ this.seed = seed;
+ this.pgenCounter = pgenCounter;
+ }
+
+ private ValidationParams(ASN1Sequence seq)
+ {
+ if (seq.size() != 2)
+ {
+ throw new IllegalArgumentException("Bad sequence size: " + seq.size());
+ }
+
+ this.seed = DERBitString.getInstance(seq.getObjectAt(0));
+ this.pgenCounter = ASN1Integer.getInstance(seq.getObjectAt(1));
+ }
+
+ public byte[] getSeed()
+ {
+ return this.seed.getBytes();
+ }
+
+ public BigInteger getPgenCounter()
+ {
+ return this.pgenCounter.getPositiveValue();
+ }
+
+ public ASN1Primitive toASN1Primitive()
+ {
+ ASN1EncodableVector v = new ASN1EncodableVector();
+ 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 25312feb..84574a3a 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962NamedCurves.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962NamedCurves.java
@@ -30,7 +30,7 @@ public class X962NamedCurves
return new X9ECParameters(
cFp192v1,
- cFp192v1.decodePoint(
+ new X9ECPoint(cFp192v1,
Hex.decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")),
n, h,
Hex.decode("3045AE6FC8422f64ED579528D38120EAE12196D5"));
@@ -52,7 +52,7 @@ public class X962NamedCurves
return new X9ECParameters(
cFp192v2,
- cFp192v2.decodePoint(
+ new X9ECPoint(cFp192v2,
Hex.decode("03eea2bae7e1497842f2de7769cfe9c989c072ad696f48034a")),
n, h,
Hex.decode("31a92ee2029fd10d901b113e990710f0d21ac6b6"));
@@ -74,7 +74,7 @@ public class X962NamedCurves
return new X9ECParameters(
cFp192v3,
- cFp192v3.decodePoint(
+ new X9ECPoint(cFp192v3,
Hex.decode("027d29778100c65a1da1783716588dce2b8b4aee8e228f1896")),
n, h,
Hex.decode("c469684435deb378c4b65ca9591e2a5763059a2e"));
@@ -96,7 +96,7 @@ public class X962NamedCurves
return new X9ECParameters(
cFp239v1,
- cFp239v1.decodePoint(
+ new X9ECPoint(cFp239v1,
Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")),
n, h,
Hex.decode("e43bb460f0b80cc0c0b075798e948060f8321b7d"));
@@ -118,7 +118,7 @@ public class X962NamedCurves
return new X9ECParameters(
cFp239v2,
- cFp239v2.decodePoint(
+ new X9ECPoint(cFp239v2,
Hex.decode("0238af09d98727705120c921bb5e9e26296a3cdcf2f35757a0eafd87b830e7")),
n, h,
Hex.decode("e8b4011604095303ca3b8099982be09fcb9ae616"));
@@ -140,7 +140,7 @@ public class X962NamedCurves
return new X9ECParameters(
cFp239v3,
- cFp239v3.decodePoint(
+ new X9ECPoint(cFp239v3,
Hex.decode("036768ae8e18bb92cfcf005c949aa2c6d94853d0e660bbf854b1c9505fe95a")),
n, h,
Hex.decode("7d7374168ffe3471b60a857686a19475d3bfa2ff"));
@@ -162,7 +162,7 @@ public class X962NamedCurves
return new X9ECParameters(
cFp256v1,
- cFp256v1.decodePoint(
+ new X9ECPoint(cFp256v1,
Hex.decode("036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296")),
n, h,
Hex.decode("c49d360886e704936a6678e1139d26b7819f7e90"));
@@ -188,7 +188,7 @@ public class X962NamedCurves
return new X9ECParameters(
c2m163v1,
- c2m163v1.decodePoint(
+ new X9ECPoint(c2m163v1,
Hex.decode("0307AF69989546103D79329FCC3D74880F33BBE803CB")),
c2m163v1n, c2m163v1h,
Hex.decode("D2C0FB15760860DEF1EEF4D696E6768756151754"));
@@ -211,7 +211,7 @@ public class X962NamedCurves
return new X9ECParameters(
c2m163v2,
- c2m163v2.decodePoint(
+ new X9ECPoint(c2m163v2,
Hex.decode("030024266E4EB5106D0A964D92C4860E2671DB9B6CC5")),
c2m163v2n, c2m163v2h,
null);
@@ -234,7 +234,7 @@ public class X962NamedCurves
return new X9ECParameters(
c2m163v3,
- c2m163v3.decodePoint(
+ new X9ECPoint(c2m163v3,
Hex.decode("0202F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB")),
c2m163v3n, c2m163v3h,
null);
@@ -257,7 +257,7 @@ public class X962NamedCurves
return new X9ECParameters(
c2m176w1,
- c2m176w1.decodePoint(
+ new X9ECPoint(c2m176w1,
Hex.decode("038D16C2866798B600F9F08BB4A8E860F3298CE04A5798")),
c2m176w1n, c2m176w1h,
null);
@@ -280,7 +280,7 @@ public class X962NamedCurves
return new X9ECParameters(
c2m191v1,
- c2m191v1.decodePoint(
+ new X9ECPoint(c2m191v1,
Hex.decode("0236B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D")),
c2m191v1n, c2m191v1h,
Hex.decode("4E13CA542744D696E67687561517552F279A8C84"));
@@ -303,7 +303,7 @@ public class X962NamedCurves
return new X9ECParameters(
c2m191v2,
- c2m191v2.decodePoint(
+ new X9ECPoint(c2m191v2,
Hex.decode("023809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10")),
c2m191v2n, c2m191v2h,
null);
@@ -326,7 +326,7 @@ public class X962NamedCurves
return new X9ECParameters(
c2m191v3,
- c2m191v3.decodePoint(
+ new X9ECPoint(c2m191v3,
Hex.decode("03375D4CE24FDE434489DE8746E71786015009E66E38A926DD")),
c2m191v3n, c2m191v3h,
null);
@@ -349,7 +349,7 @@ public class X962NamedCurves
return new X9ECParameters(
c2m208w1,
- c2m208w1.decodePoint(
+ new X9ECPoint(c2m208w1,
Hex.decode("0289FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A")),
c2m208w1n, c2m208w1h,
null);
@@ -372,7 +372,7 @@ public class X962NamedCurves
return new X9ECParameters(
c2m239v1,
- c2m239v1.decodePoint(
+ new X9ECPoint(c2m239v1,
Hex.decode("0257927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D")),
c2m239v1n, c2m239v1h,
null);
@@ -395,7 +395,7 @@ public class X962NamedCurves
return new X9ECParameters(
c2m239v2,
- c2m239v2.decodePoint(
+ new X9ECPoint(c2m239v2,
Hex.decode("0228F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205")),
c2m239v2n, c2m239v2h,
null);
@@ -418,7 +418,7 @@ public class X962NamedCurves
return new X9ECParameters(
c2m239v3,
- c2m239v3.decodePoint(
+ new X9ECPoint(c2m239v3,
Hex.decode("0370F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92")),
c2m239v3n, c2m239v3h,
null);
@@ -441,7 +441,7 @@ public class X962NamedCurves
return new X9ECParameters(
c2m272w1,
- c2m272w1.decodePoint(
+ new X9ECPoint(c2m272w1,
Hex.decode("026108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D")),
c2m272w1n, c2m272w1h,
null);
@@ -464,7 +464,7 @@ public class X962NamedCurves
return new X9ECParameters(
c2m304w1,
- c2m304w1.decodePoint(
+ new X9ECPoint(c2m304w1,
Hex.decode("02197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614")),
c2m304w1n, c2m304w1h,
null);
@@ -487,7 +487,7 @@ public class X962NamedCurves
return new X9ECParameters(
c2m359v1,
- c2m359v1.decodePoint(
+ new X9ECPoint(c2m359v1,
Hex.decode("033C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097")),
c2m359v1n, c2m359v1h,
null);
@@ -510,7 +510,7 @@ public class X962NamedCurves
return new X9ECParameters(
c2m368w1,
- c2m368w1.decodePoint(
+ new X9ECPoint(c2m368w1,
Hex.decode("021085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F")),
c2m368w1n, c2m368w1h,
null);
@@ -533,7 +533,7 @@ public class X962NamedCurves
return new X9ECParameters(
c2m431r1,
- c2m431r1.decodePoint(
+ new X9ECPoint(c2m431r1,
Hex.decode("02120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7")),
c2m431r1n, c2m431r1h,
null);
@@ -546,7 +546,7 @@ public class X962NamedCurves
static void defineCurve(String name, ASN1ObjectIdentifier oid, X9ECParametersHolder holder)
{
- objIds.put(name, oid);
+ objIds.put(name.toLowerCase(), oid);
names.put(oid, name);
curves.put(oid, holder);
}
@@ -581,14 +581,8 @@ public class X962NamedCurves
public static X9ECParameters getByName(
String name)
{
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)objIds.get(Strings.toLowerCase(name));
-
- if (oid != null)
- {
- return getByOID(oid);
- }
-
- return null;
+ ASN1ObjectIdentifier oid = getOID(name);
+ return oid == null ? null : getByOID(oid);
}
/**
@@ -601,13 +595,7 @@ public class X962NamedCurves
ASN1ObjectIdentifier oid)
{
X9ECParametersHolder holder = (X9ECParametersHolder)curves.get(oid);
-
- if (holder != null)
- {
- return holder.getParameters();
- }
-
- return null;
+ return holder == null ? null : holder.getParameters();
}
/**
@@ -637,6 +625,6 @@ public class X962NamedCurves
*/
public static Enumeration getNames()
{
- return objIds.keys();
+ return names.elements();
}
}
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 a4348dec..a06aa85f 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962Parameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962Parameters.java
@@ -1,5 +1,7 @@
package org.bouncycastle.asn1.x9;
+import java.io.IOException;
+
import org.bouncycastle.asn1.ASN1Choice;
import org.bouncycastle.asn1.ASN1Null;
import org.bouncycastle.asn1.ASN1Object;
@@ -7,6 +9,9 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1TaggedObject;
+/**
+ * The Parameters ASN.1 CHOICE from X9.62.
+ */
public class X962Parameters
extends ASN1Object
implements ASN1Choice
@@ -25,7 +30,19 @@ public class X962Parameters
{
return new X962Parameters((ASN1Primitive)obj);
}
-
+
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return new X962Parameters(ASN1Primitive.fromByteArray((byte[])obj));
+ }
+ catch (IOException e)
+ {
+ throw new IllegalArgumentException("unable to parse encoded data: " + e.getMessage());
+ }
+ }
+
throw new IllegalArgumentException("unknown object in getInstance()");
}
@@ -49,6 +66,15 @@ public class X962Parameters
}
public X962Parameters(
+ ASN1Null obj)
+ {
+ this.params = obj;
+ }
+
+ /**
+ * @deprecated use getInstance()
+ */
+ public X962Parameters(
ASN1Primitive obj)
{
this.params = obj;
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 302c1300..85163651 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParameters.java
@@ -26,7 +26,7 @@ public class X9ECParameters
private X9FieldID fieldID;
private ECCurve curve;
- private ECPoint g;
+ private X9ECPoint g;
private BigInteger n;
private BigInteger h;
private byte[] seed;
@@ -49,11 +49,11 @@ public class X9ECParameters
if (p instanceof X9ECPoint)
{
- this.g = ((X9ECPoint)p).getPoint();
+ this.g = ((X9ECPoint)p);
}
else
{
- this.g = new X9ECPoint(curve, (ASN1OctetString)p).getPoint();
+ this.g = new X9ECPoint(curve, (ASN1OctetString)p);
}
this.n = ((ASN1Integer)seq.getObjectAt(4)).getValue();
@@ -85,7 +85,16 @@ public class X9ECParameters
ECPoint g,
BigInteger n)
{
- this(curve, g, n, ONE, null);
+ this(curve, g, n, null, null);
+ }
+
+ public X9ECParameters(
+ ECCurve curve,
+ X9ECPoint g,
+ BigInteger n,
+ BigInteger h)
+ {
+ this(curve, g, n, h, null);
}
public X9ECParameters(
@@ -104,8 +113,18 @@ public class X9ECParameters
BigInteger h,
byte[] seed)
{
+ this(curve, new X9ECPoint(g), n, h, seed);
+ }
+
+ public X9ECParameters(
+ ECCurve curve,
+ X9ECPoint g,
+ BigInteger n,
+ BigInteger h,
+ byte[] seed)
+ {
this.curve = curve;
- this.g = g.normalize();
+ this.g = g;
this.n = n;
this.h = h;
this.seed = seed;
@@ -144,7 +163,7 @@ public class X9ECParameters
public ECPoint getG()
{
- return g;
+ return g.getPoint();
}
public BigInteger getN()
@@ -154,11 +173,6 @@ public class X9ECParameters
public BigInteger getH()
{
- if (h == null)
- {
- return ONE; // TODO - this should be calculated, it will cause issues with custom curves.
- }
-
return h;
}
@@ -168,6 +182,36 @@ public class X9ECParameters
}
/**
+ * Return the ASN.1 entry representing the Curve.
+ *
+ * @return the X9Curve for the curve in these parameters.
+ */
+ public X9Curve getCurveEntry()
+ {
+ return new X9Curve(curve, seed);
+ }
+
+ /**
+ * Return the ASN.1 entry representing the FieldID.
+ *
+ * @return the X9FieldID for the FieldID in these parameters.
+ */
+ public X9FieldID getFieldIDEntry()
+ {
+ return fieldID;
+ }
+
+ /**
+ * Return the ASN.1 entry representing the base point G.
+ *
+ * @return the X9ECPoint for the base point in these parameters.
+ */
+ public X9ECPoint getBaseEntry()
+ {
+ return g;
+ }
+
+ /**
* Produce an object suitable for an ASN1OutputStream.
* <pre>
* ECParameters ::= SEQUENCE {
@@ -184,10 +228,10 @@ public class X9ECParameters
{
ASN1EncodableVector v = new ASN1EncodableVector();
- v.add(new ASN1Integer(1));
+ v.add(new ASN1Integer(ONE));
v.add(fieldID);
v.add(new X9Curve(curve, seed));
- v.add(new X9ECPoint(g));
+ v.add(g);
v.add(new ASN1Integer(n));
if (h != null)
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParametersHolder.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParametersHolder.java
index 47361f89..96130c6a 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParametersHolder.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECParametersHolder.java
@@ -4,7 +4,7 @@ public abstract class X9ECParametersHolder
{
private X9ECParameters params;
- public X9ECParameters getParameters()
+ public synchronized X9ECParameters getParameters()
{
if (params == null)
{
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 cbb91160..57b0fda4 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECPoint.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECPoint.java
@@ -6,6 +6,7 @@ import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.util.Arrays;
/**
* class for describing an ECPoint as a DER object.
@@ -13,26 +14,61 @@ import org.bouncycastle.math.ec.ECPoint;
public class X9ECPoint
extends ASN1Object
{
- ECPoint p;
+ private final ASN1OctetString encoding;
+
+ private ECCurve c;
+ private ECPoint p;
public X9ECPoint(
ECPoint p)
{
+ this(p, false);
+ }
+
+ public X9ECPoint(
+ ECPoint p,
+ boolean compressed)
+ {
this.p = p.normalize();
+ this.encoding = new DEROctetString(p.getEncoded(compressed));
+ }
+
+ public X9ECPoint(
+ ECCurve c,
+ byte[] encoding)
+ {
+ this.c = c;
+ this.encoding = new DEROctetString(Arrays.clone(encoding));
}
public X9ECPoint(
ECCurve c,
ASN1OctetString s)
{
- this.p = c.decodePoint(s.getOctets());
+ this(c, s.getOctets());
+ }
+
+ public byte[] getPointEncoding()
+ {
+ return Arrays.clone(encoding.getOctets());
}
public ECPoint getPoint()
{
+ if (p == null)
+ {
+ p = c.decodePoint(encoding.getOctets()).normalize();
+ }
+
return p;
}
+ public boolean isPointCompressed()
+ {
+ byte[] octets = encoding.getOctets();
+ return octets != null && octets.length > 0 && (octets[0] == 2 || octets[0] == 3);
+ }
+
/**
* Produce an object suitable for an ASN1OutputStream.
* <pre>
@@ -43,6 +79,6 @@ public class X9ECPoint
*/
public ASN1Primitive toASN1Primitive()
{
- return new DEROctetString(p.getEncoded());
+ return encoding;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java
index 53a4373c..1317b4ab 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ObjectIdentifiers.java
@@ -204,4 +204,21 @@ public interface X9ObjectIdentifiers
static final ASN1ObjectIdentifier mqv2 = x9_42_schemes.branch("7");
/** X9.42 MQV1 OID: 1.2.840.10046.3.8 */
static final ASN1ObjectIdentifier mqv1 = x9_42_schemes.branch("8");
+
+ /**
+ * X9.44
+ * <pre>
+ * x9-44 OID ::= {
+ * iso(1) identified-organization(3) tc68(133) country(16) x9(840)
+ * x9Standards(9) x9-44(44)
+ * }
+ * </pre>
+ */
+
+ ASN1ObjectIdentifier x9_44 = new ASN1ObjectIdentifier("1.3.133.16.840.9.44");
+
+ ASN1ObjectIdentifier x9_44_components = x9_44.branch("1");
+
+ ASN1ObjectIdentifier id_kdf_kdf2 = x9_44_components.branch("1");
+ ASN1ObjectIdentifier id_kdf_kdf3 = x9_44_components.branch("2");
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java
index 39f59da8..8ab2cdc5 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java
@@ -115,7 +115,14 @@ public class BufferedBlockCipher
if (pgpCFB)
{
- leftOver = total % buf.length - (cipher.getBlockSize() + 2);
+ if (forEncryption)
+ {
+ leftOver = total % buf.length - (cipher.getBlockSize() + 2);
+ }
+ else
+ {
+ leftOver = total % buf.length;
+ }
}
else
{
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/GeneralDigest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/GeneralDigest.java
index 29692bad..011e97c5 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/GeneralDigest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/GeneralDigest.java
@@ -70,39 +70,44 @@ public abstract class GeneralDigest
int inOff,
int len)
{
+ len = Math.max(0, len);
+
//
// fill the current word
//
- while ((xBufOff != 0) && (len > 0))
+ int i = 0;
+ if (xBufOff != 0)
{
- update(in[inOff]);
-
- inOff++;
- len--;
+ while (i < len)
+ {
+ xBuf[xBufOff++] = in[inOff + i++];
+ if (xBufOff == 4)
+ {
+ processWord(xBuf, 0);
+ xBufOff = 0;
+ break;
+ }
+ }
}
//
// process whole words.
//
- while (len > xBuf.length)
+ int limit = ((len - i) & ~3) + i;
+ for (; i < limit; i += 4)
{
- processWord(in, inOff);
-
- inOff += xBuf.length;
- len -= xBuf.length;
- byteCount += xBuf.length;
+ processWord(in, inOff + i);
}
//
// load in the remainder.
//
- while (len > 0)
+ while (i < len)
{
- update(in[inOff]);
-
- inOff++;
- len--;
+ xBuf[xBufOff++] = in[inOff + i++];
}
+
+ byteCount += len;
}
public void finish()
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 3b4b2e6e..e3c596d9 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java
@@ -3,15 +3,21 @@ package org.bouncycastle.crypto.ec;
import java.math.BigInteger;
import java.util.Enumeration;
import java.util.Hashtable;
+import java.util.Vector;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.sec.SECObjectIdentifiers;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.asn1.x9.X9ECParametersHolder;
+import org.bouncycastle.asn1.x9.X9ECPoint;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;
// BEGIN android-removed
// import org.bouncycastle.math.ec.custom.djb.Curve25519;
+// import org.bouncycastle.math.ec.custom.sec.SecP128R1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecP160K1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecP160R1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecP160R2Curve;
// END android-removed
import org.bouncycastle.math.ec.custom.sec.SecP192K1Curve;
import org.bouncycastle.math.ec.custom.sec.SecP192R1Curve;
@@ -21,6 +27,26 @@ import org.bouncycastle.math.ec.custom.sec.SecP256K1Curve;
import org.bouncycastle.math.ec.custom.sec.SecP256R1Curve;
import org.bouncycastle.math.ec.custom.sec.SecP384R1Curve;
import org.bouncycastle.math.ec.custom.sec.SecP521R1Curve;
+// BEGIN android-removed
+// import org.bouncycastle.math.ec.custom.sec.SecT113R1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT113R2Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT131R1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT131R2Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT163K1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT163R1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT163R2Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT193R1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT193R2Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT233K1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT233R1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT239K1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT283K1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT283R1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT409K1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT409R1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT571K1Curve;
+// import org.bouncycastle.math.ec.custom.sec.SecT571R1Curve;
+// END android-removed
import org.bouncycastle.math.ec.endo.GLVTypeBEndomorphism;
import org.bouncycastle.math.ec.endo.GLVTypeBParameters;
import org.bouncycastle.util.Strings;
@@ -44,24 +70,100 @@ public class CustomNamedCurves
// */
// static X9ECParametersHolder curve25519 = new X9ECParametersHolder()
// {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = null;
+ // ECCurve curve = configureCurve(new Curve25519());
+ //
+ // /*
+ // * NOTE: Curve25519 was specified in Montgomery form. Rewriting in Weierstrass form
+ // * involves substitution of variables, so the base-point x coordinate is 9 + (486662 / 3).
+ // *
+ // * The Curve25519 paper doesn't say which of the two possible y values the base
+ // * point has. The choice here is guided by language in the Ed25519 paper.
+ // *
+ // * (The other possible y value is 5F51E65E475F794B1FE122D388B72EB36DC2B28192839E4DD6163A5D81312C14)
+ // */
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD245A"
+ // + "20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9"));
+ //
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
+ //
+ // /*
+ // * secp128r1
+ // */
+ // static X9ECParametersHolder secp128r1 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = Hex.decode("000E0D4D696E6768756151750CC03A4473D03679");
+ // ECCurve curve = configureCurve(new SecP128R1Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "161FF7528B899B2D0C28607CA52C5B86"
+ // + "CF5AC8395BAFEB13C02DA292DDED7A83"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
+ //
+ // /*
+ // * secp160k1
+ // */
+ // static X9ECParametersHolder secp160k1 = new X9ECParametersHolder()
+ // {
// protected X9ECParameters createParameters()
// {
// byte[] S = null;
- // ECCurve curve = configureCurve(new Curve25519());
+ // 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);
+ // ECCurve curve = configureCurveGLV(new SecP160K1Curve(), glv);
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB"
+ // + "938CF935318FDCED6BC28286531733C3F03C4FEE"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
//
- // /*
- // * NOTE: Curve25519 was specified in Montgomery form. Rewriting in Weierstrass form
- // * involves substitution of variables, so the base-point x coordinate is 9 + (486662 / 3).
- // *
- // * The Curve25519 paper doesn't say which of the two possible y values the base
- // * point has. The choice here is guided by language in the Ed25519 paper.
- // *
- // * (The other possible y value is 5F51E65E475F794B1FE122D388B72EB36DC2B28192839E4DD6163A5D81312C14)
- // */
- // ECPoint G = curve.decodePoint(Hex.decode("04"
- // + "2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD245A"
- // + "20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9"));
+ // /*
+ // * secp160r1
+ // */
+ // static X9ECParametersHolder secp160r1 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = Hex.decode("1053CDE42C14D696E67687561517533BF3F83345");
+ // ECCurve curve = configureCurve(new SecP160R1Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "4A96B5688EF573284664698968C38BB913CBFC82"
+ // + "23A628553168947D59DCC912042351377AC5FB32"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
//
+ // /*
+ // * secp160r2
+ // */
+ // static X9ECParametersHolder secp160r2 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = Hex.decode("B99B99B099B323E02709A4D696E6768756151751");
+ // ECCurve curve = configureCurve(new SecP160R2Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "52DCB034293A117E1F4FF11B30F7199D3144CE6D"
+ // + "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E"));
// return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
// }
// };
@@ -88,7 +190,7 @@ public class CustomNamedCurves
new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16),
208);
ECCurve curve = configureCurveGLV(new SecP192K1Curve(), glv);
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D"
+ "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D"));
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -104,7 +206,7 @@ public class CustomNamedCurves
{
byte[] S = Hex.decode("3045AE6FC8422F64ED579528D38120EAE12196D5");
ECCurve curve = configureCurve(new SecP192R1Curve());
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"
+ "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811"));
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -132,7 +234,7 @@ public class CustomNamedCurves
new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16),
240);
ECCurve curve = configureCurveGLV(new SecP224K1Curve(), glv);
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C"
+ "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5"));
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -148,7 +250,7 @@ public class CustomNamedCurves
{
byte[] S = Hex.decode("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5");
ECCurve curve = configureCurve(new SecP224R1Curve());
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"
+ "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34"));
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -176,7 +278,7 @@ public class CustomNamedCurves
new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16),
272);
ECCurve curve = configureCurveGLV(new SecP256K1Curve(), glv);
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"
+ "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"));
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -192,7 +294,7 @@ public class CustomNamedCurves
{
byte[] S = Hex.decode("C49D360886E704936A6678E1139D26B7819F7E90");
ECCurve curve = configureCurve(new SecP256R1Curve());
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"
+ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"));
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -208,7 +310,7 @@ public class CustomNamedCurves
{
byte[] S = Hex.decode("A335926AA319A27A1D00896A6773A4827ACDAC73");
ECCurve curve = configureCurve(new SecP384R1Curve());
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"
+ "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F"));
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
@@ -224,36 +326,338 @@ public class CustomNamedCurves
{
byte[] S = Hex.decode("D09E8800291CB85396CC6717393284AAA0DA64BA");
ECCurve curve = configureCurve(new SecP521R1Curve());
- ECPoint G = curve.decodePoint(Hex.decode("04"
+ X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"
+ "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650"));
return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
}
};
+ // BEGIN android-removed
+ // /*
+ // * sect113r1
+ // */
+ // static X9ECParametersHolder sect113r1 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = Hex.decode("10E723AB14D696E6768756151756FEBF8FCB49A9");
+ // ECCurve curve = configureCurve(new SecT113R1Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "009D73616F35F4AB1407D73562C10F"
+ // + "00A52830277958EE84D1315ED31886"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
+
+ // /*
+ // * sect113r2
+ // */
+ // static X9ECParametersHolder sect113r2 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = Hex.decode("10C0FB15760860DEF1EEF4D696E676875615175D");
+ // ECCurve curve = configureCurve(new SecT113R2Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "01A57A6A7B26CA5EF52FCDB8164797"
+ // + "00B3ADC94ED1FE674C06E695BABA1D"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
+
+ // /*
+ // * sect131r1
+ // */
+ // static X9ECParametersHolder sect131r1 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = Hex.decode("4D696E676875615175985BD3ADBADA21B43A97E2");
+ // ECCurve curve = configureCurve(new SecT131R1Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "0081BAF91FDF9833C40F9C181343638399"
+ // + "078C6E7EA38C001F73C8134B1B4EF9E150"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
+
+ // /*
+ // * sect131r2
+ // */
+ // static X9ECParametersHolder sect131r2 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = Hex.decode("985BD3ADBAD4D696E676875615175A21B43A97E3");
+ // ECCurve curve = configureCurve(new SecT131R2Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "0356DCD8F2F95031AD652D23951BB366A8"
+ // + "0648F06D867940A5366D9E265DE9EB240F"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
+
+ // /*
+ // * sect163k1
+ // */
+ // static X9ECParametersHolder sect163k1 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = null;
+ // ECCurve curve = configureCurve(new SecT163K1Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8"
+ // + "0289070FB05D38FF58321F2E800536D538CCDAA3D9"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
+
+ // /*
+ // * sect163r1
+ // */
+ // static X9ECParametersHolder sect163r1 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = Hex.decode("24B7B137C8A14D696E6768756151756FD0DA2E5C");
+ // ECCurve curve = configureCurve(new SecT163R1Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "0369979697AB43897789566789567F787A7876A654"
+ // + "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
+
+ // /*
+ // * sect163r2
+ // */
+ // static X9ECParametersHolder sect163r2 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = Hex.decode("85E25BFE5C86226CDB12016F7553F9D0E693A268");
+ // ECCurve curve = configureCurve(new SecT163R2Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "03F0EBA16286A2D57EA0991168D4994637E8343E36"
+ // + "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
+
+ // /*
+ // * sect193r1
+ // */
+ // static X9ECParametersHolder sect193r1 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = Hex.decode("103FAEC74D696E676875615175777FC5B191EF30");
+ // ECCurve curve = configureCurve(new SecT193R1Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1"
+ // + "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
+
+ // /*
+ // * sect193r2
+ // */
+ // static X9ECParametersHolder sect193r2 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = Hex.decode("10B7B4D696E676875615175137C8A16FD0DA2211");
+ // ECCurve curve = configureCurve(new SecT193R2Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F"
+ // + "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
+
+ // /*
+ // * sect233k1
+ // */
+ // static X9ECParametersHolder sect233k1 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = null;
+ // ECCurve curve = configureCurve(new SecT233K1Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126"
+ // + "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
+
+ // /*
+ // * sect233r1
+ // */
+ // static X9ECParametersHolder sect233r1 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = Hex.decode("74D59FF07F6B413D0EA14B344B20A2DB049B50C3");
+ // ECCurve curve = configureCurve(new SecT233R1Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B"
+ // + "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
+
+ // /*
+ // * sect239k1
+ // */
+ // static X9ECParametersHolder sect239k1 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = null;
+ // ECCurve curve = configureCurve(new SecT239K1Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC"
+ // + "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
+
+ // /*
+ // * sect283k1
+ // */
+ // static X9ECParametersHolder sect283k1 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = null;
+ // ECCurve curve = configureCurve(new SecT283K1Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836"
+ // + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
+
+ // /*
+ // * sect283r1
+ // */
+ // static X9ECParametersHolder sect283r1 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = Hex.decode("77E2B07370EB0F832A6DD5B62DFC88CD06BB84BE");
+ // ECCurve curve = configureCurve(new SecT283R1Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053"
+ // + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
+
+ // /*
+ // * sect409k1
+ // */
+ // static X9ECParametersHolder sect409k1 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = null;
+ // ECCurve curve = configureCurve(new SecT409K1Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746"
+ // + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
+
+ // /*
+ // * sect409r1
+ // */
+ // static X9ECParametersHolder sect409r1 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = Hex.decode("4099B5A457F9D69F79213D094C4BCD4D4262210B");
+ // ECCurve curve = configureCurve(new SecT409R1Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7"
+ // + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
+
+ // /*
+ // * sect571k1
+ // */
+ // static X9ECParametersHolder sect571k1 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = null;
+ // ECCurve curve = configureCurve(new SecT571K1Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972"
+ // + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
+
+ // /*
+ // * sect571r1
+ // */
+ // static X9ECParametersHolder sect571r1 = new X9ECParametersHolder()
+ // {
+ // protected X9ECParameters createParameters()
+ // {
+ // byte[] S = Hex.decode("2AA058F73A0E33AB486B0F610410C53A7F132310");
+ // ECCurve curve = configureCurve(new SecT571R1Curve());
+ // X9ECPoint G = new X9ECPoint(curve, Hex.decode("04"
+ // + "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19"
+ // + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B"));
+ // return new X9ECParameters(curve, G, curve.getOrder(), curve.getCofactor(), S);
+ // }
+ // };
+ // END android-removed
+
+
static final Hashtable nameToCurve = new Hashtable();
static final Hashtable nameToOID = new Hashtable();
static final Hashtable oidToCurve = new Hashtable();
static final Hashtable oidToName = new Hashtable();
+ static final Vector names = new Vector();
static void defineCurve(String name, X9ECParametersHolder holder)
{
+ names.addElement(name);
+ name = Strings.toLowerCase(name);
nameToCurve.put(name, holder);
}
static void defineCurveWithOID(String name, ASN1ObjectIdentifier oid, X9ECParametersHolder holder)
{
- nameToCurve.put(name, holder);
- nameToOID.put(name, oid);
+ names.addElement(name);
oidToName.put(oid, name);
oidToCurve.put(oid, holder);
+ name = Strings.toLowerCase(name);
+ nameToOID.put(name, oid);
+ nameToCurve.put(name, holder);
}
- static void defineCurveAlias(String alias, ASN1ObjectIdentifier oid)
+ static void defineCurveAlias(String name, ASN1ObjectIdentifier oid)
{
- alias = Strings.toLowerCase(alias);
- nameToOID.put(alias, oid);
- nameToCurve.put(alias, oidToCurve.get(oid));
+ Object curve = oidToCurve.get(oid);
+ if (curve == null)
+ {
+ throw new IllegalStateException();
+ }
+
+ name = Strings.toLowerCase(name);
+ nameToOID.put(name, oid);
+ nameToCurve.put(name, curve);
}
static
@@ -262,6 +666,17 @@ public class CustomNamedCurves
// defineCurve("curve25519", curve25519);
// END android-removed
+// defineCurveWithOID("secp112r1", SECObjectIdentifiers.secp112r1, secp112r1);
+// defineCurveWithOID("secp112r2", SECObjectIdentifiers.secp112r2, secp112r2);
+ // BEGIN android-removed
+ // defineCurveWithOID("secp128r1", SECObjectIdentifiers.secp128r1, secp128r1);
+ // END android-removed
+// defineCurveWithOID("secp128r2", SECObjectIdentifiers.secp128r2, secp128r2);
+ // BEGIN android-removed
+ // defineCurveWithOID("secp160k1", SECObjectIdentifiers.secp160k1, secp160k1);
+ // defineCurveWithOID("secp160r1", SECObjectIdentifiers.secp160r1, secp160r1);
+ // defineCurveWithOID("secp160r2", SECObjectIdentifiers.secp160r2, secp160r2);
+ // END android-removed
defineCurveWithOID("secp192k1", SECObjectIdentifiers.secp192k1, secp192k1);
defineCurveWithOID("secp192r1", SECObjectIdentifiers.secp192r1, secp192r1);
defineCurveWithOID("secp224k1", SECObjectIdentifiers.secp224k1, secp224k1);
@@ -271,6 +686,39 @@ public class CustomNamedCurves
defineCurveWithOID("secp384r1", SECObjectIdentifiers.secp384r1, secp384r1);
defineCurveWithOID("secp521r1", SECObjectIdentifiers.secp521r1, secp521r1);
+ // BEGIN android-removed
+ // defineCurveWithOID("sect113r1", SECObjectIdentifiers.sect113r1, sect113r1);
+ // defineCurveWithOID("sect113r2", SECObjectIdentifiers.sect113r2, sect113r2);
+ // defineCurveWithOID("sect131r1", SECObjectIdentifiers.sect131r1, sect131r1);
+ // defineCurveWithOID("sect131r2", SECObjectIdentifiers.sect131r2, sect131r2);
+ // defineCurveWithOID("sect163k1", SECObjectIdentifiers.sect163k1, sect163k1);
+ // defineCurveWithOID("sect163r1", SECObjectIdentifiers.sect163r1, sect163r1);
+ // defineCurveWithOID("sect163r2", SECObjectIdentifiers.sect163r2, sect163r2);
+ // defineCurveWithOID("sect193r1", SECObjectIdentifiers.sect193r1, sect193r1);
+ // defineCurveWithOID("sect193r2", SECObjectIdentifiers.sect193r2, sect193r2);
+ // defineCurveWithOID("sect233k1", SECObjectIdentifiers.sect233k1, sect233k1);
+ // defineCurveWithOID("sect233r1", SECObjectIdentifiers.sect233r1, sect233r1);
+ // defineCurveWithOID("sect239k1", SECObjectIdentifiers.sect239k1, sect239k1);
+ // defineCurveWithOID("sect283k1", SECObjectIdentifiers.sect283k1, sect283k1);
+ // defineCurveWithOID("sect283r1", SECObjectIdentifiers.sect283r1, sect283r1);
+ // defineCurveWithOID("sect409k1", SECObjectIdentifiers.sect409k1, sect409k1);
+ // defineCurveWithOID("sect409r1", SECObjectIdentifiers.sect409r1, sect409r1);
+ // defineCurveWithOID("sect571k1", SECObjectIdentifiers.sect571k1, sect571k1);
+ // defineCurveWithOID("sect571r1", SECObjectIdentifiers.sect571r1, sect571r1);
+
+ // defineCurveAlias("B-163", SECObjectIdentifiers.sect163r2);
+ // defineCurveAlias("B-233", SECObjectIdentifiers.sect233r1);
+ // defineCurveAlias("B-283", SECObjectIdentifiers.sect283r1);
+ // defineCurveAlias("B-409", SECObjectIdentifiers.sect409r1);
+ // defineCurveAlias("B-571", SECObjectIdentifiers.sect571r1);
+
+ // defineCurveAlias("K-163", SECObjectIdentifiers.sect163k1);
+ // defineCurveAlias("K-233", SECObjectIdentifiers.sect233k1);
+ // defineCurveAlias("K-283", SECObjectIdentifiers.sect283k1);
+ // defineCurveAlias("K-409", SECObjectIdentifiers.sect409k1);
+ // defineCurveAlias("K-571", SECObjectIdentifiers.sect571k1);
+ // END android-removed
+
defineCurveAlias("P-192", SECObjectIdentifiers.secp192r1);
defineCurveAlias("P-224", SECObjectIdentifiers.secp224r1);
defineCurveAlias("P-256", SECObjectIdentifiers.secp256r1);
@@ -321,6 +769,6 @@ public class CustomNamedCurves
*/
public static Enumeration getNames()
{
- return nameToCurve.keys();
+ return names.elements();
}
}
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 7ba71c73..71ca7f7d 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
@@ -18,15 +18,20 @@ public class PKCS1Encoding
implements AsymmetricBlockCipher
{
/**
+ * @deprecated use NOT_STRICT_LENGTH_ENABLED_PROPERTY
+ */
+ public static final String STRICT_LENGTH_ENABLED_PROPERTY = "org.bouncycastle.pkcs1.strict";
+
+ /**
* some providers fail to include the leading zero in PKCS1 encoded blocks. If you need to
- * work with one of these set the system property org.bouncycastle.pkcs1.strict to false.
+ * work with one of these set the system property org.bouncycastle.pkcs1.not_strict to true.
* <p>
- * The system property is checked during construction of the encoding object, it is set to
- * true by default.
+ * The system property is checked during construction of the encoding object, it is set to
+ * false by default.
* </p>
*/
- public static final String STRICT_LENGTH_ENABLED_PROPERTY = "org.bouncycastle.pkcs1.strict";
-
+ public static final String NOT_STRICT_LENGTH_ENABLED_PROPERTY = "org.bouncycastle.pkcs1.not_strict";
+
private static final int HEADER_LENGTH = 10;
private SecureRandom random;
@@ -97,6 +102,18 @@ public class PKCS1Encoding
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 strict == null || strict.equals("true");
}
@@ -121,8 +138,11 @@ public class PKCS1Encoding
}
else
{
- this.random = new SecureRandom();
kParam = (AsymmetricKeyParameter)param;
+ if (!kParam.isPrivate() && forEncryption)
+ {
+ this.random = new SecureRandom();
+ }
}
engine.init(forEncryption, param);
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 a0fd0840..924dff35 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java
@@ -5,6 +5,7 @@ import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.params.KeyParameter;
+import org.bouncycastle.util.Pack;
/**
* an implementation of the AES (Rijndael), from FIPS-197.
@@ -230,12 +231,22 @@ private static final int[] Tinv0 =
private static final int m1 = 0x80808080;
private static final int m2 = 0x7f7f7f7f;
private static final int m3 = 0x0000001b;
+ private static final int m4 = 0xC0C0C0C0;
+ private static final int m5 = 0x3f3f3f3f;
private static int FFmulX(int x)
{
return (((x & m2) << 1) ^ (((x & m1) >>> 7) * m3));
}
+ private static int FFmulX2(int x)
+ {
+ int t0 = (x & m5) << 2;
+ int t1 = (x & m4);
+ t1 ^= (t1 >>> 1);
+ return t0 ^ (t1 >>> 2) ^ (t1 >>> 5);
+ }
+
/*
The following defines provide alternative definitions of FFmulX that might
give improved performance if a fast 32-bit multiply is not available.
@@ -248,12 +259,13 @@ private static final int[] Tinv0 =
private static int inv_mcol(int x)
{
- int f2 = FFmulX(x);
- int f4 = FFmulX(f2);
- int f8 = FFmulX(f4);
- int f9 = x ^ f8;
-
- return f2 ^ f4 ^ f8 ^ shift(f2 ^ f9, 8) ^ shift(f4 ^ f9, 16) ^ shift(f9, 24);
+ int t0, t1;
+ t0 = x;
+ t1 = t0 ^ shift(t0, 8);
+ t0 ^= FFmulX(t1);
+ t1 ^= FFmulX2(t0);
+ t0 ^= t1 ^ shift(t1, 16);
+ return t0;
}
private static int subWord(int x)
@@ -267,59 +279,128 @@ private static final int[] Tinv0 =
* AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits
* This code is written assuming those are the only possible values
*/
- private int[][] generateWorkingKey(
- byte[] key,
- boolean forEncryption)
+ private int[][] generateWorkingKey(byte[] key, boolean forEncryption)
{
- int KC = key.length / 4; // key length in words
- int t;
-
- if (((KC != 4) && (KC != 6) && (KC != 8)) || ((KC * 4) != key.length))
+ int keyLen = key.length;
+ if (keyLen < 16 || keyLen > 32 || (keyLen & 7) != 0)
{
throw new IllegalArgumentException("Key length not 128/192/256 bits.");
}
+ int KC = keyLen >>> 2;
ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes
int[][] W = new int[ROUNDS+1][4]; // 4 words in a block
-
- //
- // copy the key into the round key array
- //
-
- t = 0;
- int i = 0;
- while (i < key.length)
+
+ switch (KC)
+ {
+ 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;
+
+ for (int i = 1; i <= 10; ++i)
{
- W[t >> 2][t & 3] = (key[i]&0xff) | ((key[i+1]&0xff) << 8) | ((key[i+2]&0xff) << 16) | (key[i+3] << 24);
- i+=4;
- t++;
+ 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;
}
-
- //
- // while not enough round key material calculated
- // calculate new values
- //
- int k = (ROUNDS + 1) << 2;
- for (i = KC; (i < k); i++)
+
+ 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 temp = W[(i-1)>>2][(i-1)&3];
- if ((i % KC) == 0)
- {
- temp = subWord(shift(temp, 8)) ^ rcon[(i / KC)-1];
- }
- else if ((KC > 6) && ((i % KC) == 4))
- {
- temp = subWord(temp);
- }
-
- W[i>>2][i&3] = W[(i - KC)>>2][(i-KC)&3] ^ temp;
+ 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;
}
+ 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;
+
+ 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)
+ {
+ 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;
+ }
+
+ 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;
+
+ break;
+ }
+ default:
+ {
+ throw new IllegalStateException("Should never get here");
+ }
+ }
+
if (!forEncryption)
{
for (int j = 1; j < ROUNDS; j++)
{
- for (i = 0; i < 4; i++)
+ for (int i = 0; i < 4; i++)
{
W[j][i] = inv_mcol(W[j][i]);
}
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 e2b00d3a..11e1bce8 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java
@@ -557,12 +557,22 @@ public class AESFastEngine
private static final int m1 = 0x80808080;
private static final int m2 = 0x7f7f7f7f;
private static final int m3 = 0x0000001b;
+ private static final int m4 = 0xC0C0C0C0;
+ private static final int m5 = 0x3f3f3f3f;
private static int FFmulX(int x)
{
return (((x & m2) << 1) ^ (((x & m1) >>> 7) * m3));
}
+ private static int FFmulX2(int x)
+ {
+ int t0 = (x & m5) << 2;
+ int t1 = (x & m4);
+ t1 ^= (t1 >>> 1);
+ return t0 ^ (t1 >>> 2) ^ (t1 >>> 5);
+ }
+
/*
The following defines provide alternative definitions of FFmulX that might
give improved performance if a fast 32-bit multiply is not available.
@@ -575,12 +585,13 @@ public class AESFastEngine
private static int inv_mcol(int x)
{
- int f2 = FFmulX(x);
- int f4 = FFmulX(f2);
- int f8 = FFmulX(f4);
- int f9 = x ^ f8;
-
- return f2 ^ f4 ^ f8 ^ shift(f2 ^ f9, 8) ^ shift(f4 ^ f9, 16) ^ shift(f9, 24);
+ int t0, t1;
+ t0 = x;
+ t1 = t0 ^ shift(t0, 8);
+ t0 ^= FFmulX(t1);
+ t1 ^= FFmulX2(t0);
+ t0 ^= t1 ^ shift(t1, 16);
+ return t0;
}
private static int subWord(int x)
@@ -596,59 +607,128 @@ public class AESFastEngine
* AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits
* This code is written assuming those are the only possible values
*/
- private int[][] generateWorkingKey(
- byte[] key,
- boolean forEncryption)
+ private int[][] generateWorkingKey(byte[] key, boolean forEncryption)
{
- int KC = key.length / 4; // key length in words
- int t;
-
- if (((KC != 4) && (KC != 6) && (KC != 8)) || ((KC * 4) != key.length))
+ int keyLen = key.length;
+ if (keyLen < 16 || keyLen > 32 || (keyLen & 7) != 0)
{
throw new IllegalArgumentException("Key length not 128/192/256 bits.");
}
+ int KC = keyLen >>> 2;
ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes
int[][] W = new int[ROUNDS+1][4]; // 4 words in a block
-
- //
- // copy the key into the round key array
- //
-
- t = 0;
- int i = 0;
- while (i < key.length)
+
+ switch (KC)
+ {
+ case 4:
{
- W[t >> 2][t & 3] = (key[i]&0xff) | ((key[i+1]&0xff) << 8) | ((key[i+2]&0xff) << 16) | (key[i+3] << 24);
- i+=4;
- t++;
+ 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;
+
+ 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;
+ }
+
+ break;
}
-
- //
- // while not enough round key material calculated
- // calculate new values
- //
- int k = (ROUNDS + 1) << 2;
- for (i = KC; (i < k); i++)
+ case 6:
{
- int temp = W[(i - 1) >> 2][(i - 1) & 3];
- if ((i % KC) == 0)
+ 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)
{
- temp = subWord(shift(temp, 8)) ^ rcon[(i / KC) - 1];
+ 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;
}
- else if ((KC > 6) && ((i % KC) == 4))
+
+ 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;
+
+ 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)
{
- temp = subWord(temp);
+ 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;
}
- W[i >> 2][i & 3] = W[(i - KC) >> 2][(i - KC) & 3] ^ temp;
+ 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;
+
+ break;
+ }
+ default:
+ {
+ throw new IllegalStateException("Should never get here");
+ }
}
if (!forEncryption)
{
for (int j = 1; j < ROUNDS; j++)
{
- for (i = 0; i < 4; i++)
+ for (int i = 0; i < 4; i++)
{
W[j][i] = inv_mcol(W[j][i]);
}
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 197b151b..ba75c8d7 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
@@ -17,12 +17,11 @@ import org.bouncycastle.util.Arrays;
/**
* Wrap keys according to
- * <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-smime-key-wrap-01.txt">
- * draft-ietf-smime-key-wrap-01.txt</A>.
+ * <A HREF="https://www.ietf.org/rfc/rfc3217.txt">
+ * RFC 3217</A>.
* <p>
* Note:
* <ul>
- * <li>this is based on a draft, and as such is subject to change - don't use this class for anything requiring long term storage.
* <li>if you are using this to wrap triple-des keys you need to set the
* parity bits on the key and, if it's a two-key triple-des key, pad it
* yourself.
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 c9765bf8..d74e2b3c 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RSABlindedEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RSABlindedEngine.java
@@ -110,6 +110,11 @@ public class RSABlindedEngine
BigInteger rInv = r.modInverse(m);
result = blindedResult.multiply(rInv).mod(m);
+ // defence against Arjen Lenstra’s CRT attack
+ if (!input.equals(result.modPow(e, m)))
+ {
+ throw new IllegalStateException("RSA engine faulty decryption/signing detected");
+ }
}
else
{
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java
index 3cab983d..19a2ecfd 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/DESedeKeyGenerator.java
@@ -6,6 +6,8 @@ import org.bouncycastle.crypto.params.DESedeParameters;
public class DESedeKeyGenerator
extends DESKeyGenerator
{
+ private static final int MAX_IT = 20;
+
/**
* initialise the key generator - if strength is set to zero
* the key generated will be 192 bits in size, otherwise
@@ -42,6 +44,7 @@ public class DESedeKeyGenerator
public byte[] generateKey()
{
byte[] newKey = new byte[strength];
+ int count = 0;
do
{
@@ -49,7 +52,12 @@ public class DESedeKeyGenerator
DESedeParameters.setOddParity(newKey);
}
- while (DESedeParameters.isWeakKey(newKey, 0, newKey.length));
+ while (++count < MAX_IT && (DESedeParameters.isWeakKey(newKey, 0, newKey.length) || !DESedeParameters.isRealEDEKey(newKey, 0)));
+
+ if (DESedeParameters.isWeakKey(newKey, 0, newKey.length) || !DESedeParameters.isRealEDEKey(newKey, 0))
+ {
+ throw new IllegalStateException("Unable to generate DES-EDE key");
+ }
return newKey;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAParametersGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAParametersGenerator.java
index 36b41cc7..61b4bea9 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAParametersGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAParametersGenerator.java
@@ -19,17 +19,17 @@ import org.bouncycastle.util.encoders.Hex;
*/
public class DSAParametersGenerator
{
- private Digest digest;
- private int L, N;
- private int certainty;
- private SecureRandom random;
-
private static final BigInteger ZERO = BigInteger.valueOf(0);
private static final BigInteger ONE = BigInteger.valueOf(1);
private static final BigInteger TWO = BigInteger.valueOf(2);
- private boolean use186_3;
- private int usageIndex;
+ private Digest digest;
+ private int L, N;
+ private int certainty;
+ private int iterations;
+ private SecureRandom random;
+ private boolean use186_3;
+ private int usageIndex;
public DSAParametersGenerator()
{
@@ -55,11 +55,13 @@ public class DSAParametersGenerator
int certainty,
SecureRandom random)
{
- this.use186_3 = false;
this.L = size;
this.N = getDefaultN(size);
this.certainty = certainty;
+ this.iterations = Math.max(getMinimumIterations(L), (certainty + 1) / 2);
this.random = random;
+ this.use186_3 = false;
+ this.usageIndex = -1;
}
/**
@@ -73,13 +75,7 @@ public class DSAParametersGenerator
public void init(
DSAParameterGenerationParameters params)
{
- // TODO Should we enforce the minimum 'certainty' values as per C.3 Table C.1?
- this.use186_3 = true;
- this.L = params.getL();
- this.N = params.getN();
- this.certainty = params.getCertainty();
- this.random = params.getRandom();
- this.usageIndex = params.getUsageIndex();
+ int L = params.getL(), N = params.getN();
if ((L < 1024 || L > 3072) || L % 1024 != 0)
{
@@ -102,6 +98,14 @@ public class DSAParametersGenerator
{
throw new IllegalStateException("Digest output size too small for value of N");
}
+
+ this.L = L;
+ this.N = N;
+ this.certainty = params.getCertainty();
+ this.iterations = Math.max(getMinimumIterations(L), (certainty + 1) / 2);
+ this.random = params.getRandom();
+ this.use186_3 = true;
+ this.usageIndex = params.getUsageIndex();
}
/**
@@ -137,10 +141,10 @@ public class DSAParametersGenerator
{
random.nextBytes(seed);
- hash(digest, seed, part1);
+ hash(digest, seed, part1, 0);
System.arraycopy(seed, 0, part2, 0, seed.length);
inc(part2);
- hash(digest, part2, part2);
+ hash(digest, part2, part2, 0);
for (int i = 0; i != u.length; i++)
{
@@ -152,7 +156,7 @@ public class DSAParametersGenerator
BigInteger q = new BigInteger(1, u);
- if (!q.isProbablePrime(certainty))
+ if (!isProbablePrime(q))
{
continue;
}
@@ -162,18 +166,20 @@ public class DSAParametersGenerator
for (int counter = 0; counter < 4096; ++counter)
{
- for (int k = 0; k < n; k++)
{
- inc(offset);
- hash(digest, offset, part1);
- System.arraycopy(part1, 0, w, w.length - (k + 1) * part1.length, part1.length);
- }
+ for (int k = 1; k <= n; k++)
+ {
+ inc(offset);
+ hash(digest, offset, w, w.length - k * part1.length);
+ }
- inc(offset);
- hash(digest, offset, part1);
- System.arraycopy(part1, part1.length - ((w.length - (n) * part1.length)), w, 0, w.length - n * part1.length);
+ int remaining = w.length - (n * part1.length);
+ inc(offset);
+ hash(digest, offset, part1, 0);
+ System.arraycopy(part1, part1.length - remaining, w, 0, remaining);
- w[0] |= (byte)0x80;
+ w[0] |= (byte)0x80;
+ }
BigInteger x = new BigInteger(1, w);
@@ -186,7 +192,7 @@ public class DSAParametersGenerator
continue;
}
- if (p.isProbablePrime(certainty))
+ if (isProbablePrime(p))
{
BigInteger g = calculateGenerator_FIPS186_2(p, q, random);
@@ -238,6 +244,7 @@ public class DSAParametersGenerator
// 4. b = L - 1 - (n * outlen).
int b = (L - 1) % outlen;
+ byte[] w = new byte[L / 8];
byte[] output = new byte[d.getDigestSize()];
for (;;)
{
@@ -245,16 +252,15 @@ public class DSAParametersGenerator
random.nextBytes(seed);
// 6. U = Hash (domain_parameter_seed) mod 2^(N–1).
- hash(d, seed, output);
+ hash(d, seed, output, 0);
BigInteger U = new BigInteger(1, output).mod(ONE.shiftLeft(N - 1));
// 7. q = 2^(N–1) + U + 1 – ( U mod 2).
- BigInteger q = ONE.shiftLeft(N - 1).add(U).add(ONE).subtract(U.mod(TWO));
+ BigInteger q = U.setBit(0).setBit(N - 1);
// 8. Test whether or not q is prime as specified in Appendix C.3.
- // TODO Review C.3 for primality checking
- if (!q.isProbablePrime(certainty))
+ if (!isProbablePrime(q))
{
// 9. If q is not a prime, then go to step 5.
continue;
@@ -271,24 +277,23 @@ public class DSAParametersGenerator
// 11.1 For j = 0 to n do
// Vj = Hash ((domain_parameter_seed + offset + j) mod 2^seedlen).
// 11.2 W = V0 + (V1 ∗ 2^outlen) + ... + (V^(n–1) ∗ 2^((n–1) ∗ outlen)) + ((Vn mod 2^b) ∗ 2^(n ∗ outlen)).
- // TODO Assemble w as a byte array
- BigInteger W = ZERO;
- for (int j = 0, exp = 0; j <= n; ++j, exp += outlen)
{
- inc(offset);
- hash(d, offset, output);
-
- BigInteger Vj = new BigInteger(1, output);
- if (j == n)
+ for (int j = 1; j <= n; ++j)
{
- Vj = Vj.mod(ONE.shiftLeft(b));
+ inc(offset);
+ hash(d, offset, w, w.length - j * output.length);
}
- W = W.add(Vj.shiftLeft(exp));
+ int remaining = w.length - (n * output.length);
+ inc(offset);
+ hash(d, offset, output, 0);
+ System.arraycopy(output, output.length - remaining, w, 0, remaining);
+
+// 11.3 X = W + 2^(L–1). Comment: 0 ≤ W < 2^(L–1); hence, 2^(L–1) ≤ X < 2^L.
+ w[0] |= (byte)0x80;
}
-// 11.3 X = W + 2^(L–1). Comment: 0 ≤ W < 2L–1; hence, 2L–1 ≤ X < 2L.
- BigInteger X = W.add(ONE.shiftLeft(L - 1));
+ BigInteger X = new BigInteger(1, w);
// 11.4 c = X mod 2q.
BigInteger c = X.mod(q.shiftLeft(1));
@@ -296,15 +301,14 @@ public class DSAParametersGenerator
// 11.5 p = X - (c - 1). Comment: p ≡ 1 (mod 2q).
BigInteger p = X.subtract(c.subtract(ONE));
-// 11.6 If (p < 2^(L - 1)), then go to step 11.9
+// 11.6 If (p < 2^(L-1)), then go to step 11.9
if (p.bitLength() != L)
{
continue;
}
// 11.7 Test whether or not p is prime as specified in Appendix C.3.
- // TODO Review C.3 for primality checking
- if (p.isProbablePrime(certainty))
+ if (isProbablePrime(p))
{
// 11.8 If p is determined to be prime, then return VALID and the values of p, q and
// (optionally) the values of domain_parameter_seed and counter.
@@ -331,6 +335,16 @@ public class DSAParametersGenerator
}
}
+ private boolean isProbablePrime(BigInteger x)
+ {
+ /*
+ * TODO Use Primes class for FIPS 186-4 C.3 primality checking - but it breaks existing
+ * tests using FixedSecureRandom
+ */
+// return !Primes.hasAnySmallFactors(x) && Primes.isMRProbablePrime(x, random, iterations);
+ return x.isProbablePrime(certainty);
+ }
+
private static BigInteger calculateGenerator_FIPS186_3_Unverifiable(BigInteger p, BigInteger q,
SecureRandom r)
{
@@ -354,7 +368,7 @@ public class DSAParametersGenerator
for (int count = 1; count < (1 << 16); ++count)
{
inc(U);
- hash(d, U, w);
+ hash(d, U, w, 0);
BigInteger W = new BigInteger(1, w);
BigInteger g = W.modPow(e, p);
if (g.compareTo(TWO) >= 0)
@@ -366,10 +380,10 @@ public class DSAParametersGenerator
return null;
}
- private static void hash(Digest d, byte[] input, byte[] output)
+ private static void hash(Digest d, byte[] input, byte[] output, int outputPos)
{
d.update(input, 0, input.length);
- d.doFinal(output, 0);
+ d.doFinal(output, outputPos);
}
private static int getDefaultN(int L)
@@ -377,6 +391,12 @@ public class DSAParametersGenerator
return L > 1024 ? 256 : 160;
}
+ private static int getMinimumIterations(int L)
+ {
+ // Values based on FIPS 186-4 C.3 Table C.1
+ return L <= 1024 ? 40 : (48 + 8 * ((L - 1) / 1024));
+ }
+
private static void inc(byte[] buf)
{
for (int i = buf.length - 1; i >= 0; --i)
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 4f46a38d..c7660719 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/ECKeyPairGenerator.java
@@ -56,12 +56,6 @@ public class ECKeyPairGenerator
continue;
}
- /*
- * Require a minimum weight of the NAF representation, since low-weight primes may be
- * weak against a version of the number-field-sieve for the discrete-logarithm-problem.
- *
- * See "The number field sieve for integers of low weight", Oliver Schirokauer.
- */
if (WNafUtil.getNafWeight(d) < minWeight)
{
continue;
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 082a1c8a..9a2239e2 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java
@@ -10,6 +10,7 @@ import org.bouncycastle.crypto.digests.AndroidDigestFactory;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
+import org.bouncycastle.util.Arrays;
/**
* Generator for PBE derived keys and ivs as defined by PKCS 5 V2.0 Scheme 2.
@@ -116,7 +117,7 @@ public class PKCS5S2ParametersGenerator
{
keySize = keySize / 8;
- byte[] dKey = generateDerivedKey(keySize);
+ byte[] dKey = Arrays.copyOfRange(generateDerivedKey(keySize), 0, keySize);
return new KeyParameter(dKey, 0, keySize);
}
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 7277045e..f23f654b 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/RSAKeyPairGenerator.java
@@ -8,6 +8,7 @@ import org.bouncycastle.crypto.KeyGenerationParameters;
import org.bouncycastle.crypto.params.RSAKeyGenerationParameters;
import org.bouncycastle.crypto.params.RSAKeyParameters;
import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
+import org.bouncycastle.math.Primes;
import org.bouncycastle.math.ec.WNafUtil;
/**
@@ -19,10 +20,12 @@ public class RSAKeyPairGenerator
private static final BigInteger ONE = BigInteger.valueOf(1);
private RSAKeyGenerationParameters param;
+ private int iterations;
public void init(KeyGenerationParameters param)
{
this.param = (RSAKeyGenerationParameters)param;
+ this.iterations = getNumberOfIterations(this.param.getStrength(), this.param.getCertainty());
}
public AsymmetricCipherKeyPair generateKeyPair()
@@ -30,36 +33,46 @@ public class RSAKeyPairGenerator
AsymmetricCipherKeyPair result = null;
boolean done = false;
- while (!done)
+ //
+ // p and q values should have a length of half the strength in bits
+ //
+ int strength = param.getStrength();
+ int pbitlength = (strength + 1) / 2;
+ int qbitlength = strength - pbitlength;
+ int mindiffbits = (strength / 2) - 100;
+
+ if (mindiffbits < strength / 3)
{
- BigInteger p, q, n, d, e, pSub1, qSub1, phi, lcm, dLowerBound;
+ mindiffbits = strength / 3;
+ }
- //
- // p and q values should have a length of half the strength in bits
- //
- int strength = param.getStrength();
- int pbitlength = (strength + 1) / 2;
- int qbitlength = strength - pbitlength;
- int mindiffbits = strength / 3;
- int minWeight = strength >> 2;
+ int minWeight = strength >> 2;
- e = param.getPublicExponent();
+ // d lower bound is 2^(strength / 2)
+ BigInteger dLowerBound = BigInteger.valueOf(2).pow(strength / 2);
+ // squared bound (sqrt(2)*2^(nlen/2-1))^2
+ BigInteger squaredBound = ONE.shiftLeft(strength - 1);
+ // 2^(nlen/2 - 100)
+ BigInteger minDiff = ONE.shiftLeft(mindiffbits);
- // TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes)
- // (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm")
+ while (!done)
+ {
+ BigInteger p, q, n, d, e, pSub1, qSub1, gcd, lcm;
- p = chooseRandomPrime(pbitlength, e);
+ e = param.getPublicExponent();
+
+ p = chooseRandomPrime(pbitlength, e, squaredBound);
//
// generate a modulus of the required length
//
- for (;;)
+ for (; ; )
{
- q = chooseRandomPrime(qbitlength, e);
+ q = chooseRandomPrime(qbitlength, e, squaredBound);
// p and q should not be too close together (or equal!)
BigInteger diff = q.subtract(p).abs();
- if (diff.bitLength() < mindiffbits)
+ if (diff.bitLength() < mindiffbits || diff.compareTo(minDiff) <= 0)
{
continue;
}
@@ -80,14 +93,14 @@ public class RSAKeyPairGenerator
}
/*
- * Require a minimum weight of the NAF representation, since low-weight composites may
+ * Require a minimum weight of the NAF representation, since low-weight composites may
* be weak against a version of the number-field-sieve for factoring.
*
* See "The number field sieve for integers of low weight", Oliver Schirokauer.
*/
if (WNafUtil.getNafWeight(n) < minWeight)
{
- p = chooseRandomPrime(pbitlength, e);
+ p = chooseRandomPrime(pbitlength, e, squaredBound);
continue;
}
@@ -96,26 +109,22 @@ public class RSAKeyPairGenerator
if (p.compareTo(q) < 0)
{
- phi = p;
+ gcd = p;
p = q;
- q = phi;
+ q = gcd;
}
pSub1 = p.subtract(ONE);
qSub1 = q.subtract(ONE);
- phi = pSub1.multiply(qSub1);
- lcm = phi.divide(pSub1.gcd(qSub1));
+ gcd = pSub1.gcd(qSub1);
+ lcm = pSub1.divide(gcd).multiply(qSub1);
//
// calculate the private exponent
//
d = e.modInverse(lcm);
- // if d is less than or equal to dLowerBound, we need to start over
- // also, for backward compatibility, if d is not the same as
- // e.modInverse(phi), we need to start over
-
- if (d.bitLength() <= qbitlength || !d.equals(e.modInverse(phi)))
+ if (d.compareTo(dLowerBound) <= 0)
{
continue;
}
@@ -143,33 +152,80 @@ public class RSAKeyPairGenerator
/**
* Choose a random prime value for use with RSA
- *
+ *
* @param bitlength the bit-length of the returned prime
- * @param e the RSA public exponent
- * @return a prime p, with (p-1) relatively prime to e
+ * @param e the RSA public exponent
+ * @return A prime p, with (p-1) relatively prime to e
*/
- protected BigInteger chooseRandomPrime(int bitlength, BigInteger e)
+ protected BigInteger chooseRandomPrime(int bitlength, BigInteger e, BigInteger sqrdBound)
{
- for (;;)
+ for (int i = 0; i != 5 * bitlength; i++)
{
BigInteger p = new BigInteger(bitlength, 1, param.getRandom());
-
+
if (p.mod(e).equals(ONE))
{
continue;
}
-
- if (!p.isProbablePrime(param.getCertainty()))
+
+ if (p.multiply(p).compareTo(sqrdBound) < 0)
+ {
+ continue;
+ }
+
+ if (!isProbablePrime(p))
{
continue;
}
- if (!e.gcd(p.subtract(ONE)).equals(ONE))
+ if (!e.gcd(p.subtract(ONE)).equals(ONE))
{
continue;
}
-
+
return p;
}
+
+ throw new IllegalStateException("unable to generate prime number for RSA key");
+ }
+
+ protected boolean isProbablePrime(BigInteger x)
+ {
+ /*
+ * Primes class for FIPS 186-4 C.3 primality checking
+ */
+ return !Primes.hasAnySmallFactors(x) && Primes.isMRProbablePrime(x, param.getRandom(), iterations);
+ }
+
+ private static int getNumberOfIterations(int bits, int certainty)
+ {
+ /*
+ * NOTE: We enforce a minimum 'certainty' of 100 for bits >= 1024 (else 80). Where the
+ * certainty is higher than the FIPS 186-4 tables (C.2/C.3) cater to, extra iterations
+ * are added at the "worst case rate" for the excess.
+ */
+ if (bits >= 1536)
+ {
+ return certainty <= 100 ? 3
+ : certainty <= 128 ? 4
+ : 4 + (certainty - 128 + 1) / 2;
+ }
+ else if (bits >= 1024)
+ {
+ return certainty <= 100 ? 4
+ : certainty <= 112 ? 5
+ : 5 + (certainty - 112 + 1) / 2;
+ }
+ else if (bits >= 512)
+ {
+ return certainty <= 80 ? 5
+ : certainty <= 100 ? 7
+ : 7 + (certainty - 100 + 1) / 2;
+ }
+ else
+ {
+ return certainty <= 80 ? 40
+ : 40 + (certainty - 80 + 1) / 2;
+ }
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java
index 7f870ca2..088c7283 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java
@@ -87,7 +87,7 @@ public class CCMBlockCipher
}
else
{
- throw new IllegalArgumentException("invalid parameters passed to CCM");
+ throw new IllegalArgumentException("invalid parameters passed to CCM: " + params.getClass().getName());
}
// NOTE: Very basic support for key re-use, but no performance gain from it
@@ -277,7 +277,9 @@ public class CCMBlockCipher
calculateMac(in, inOff, inLen, macBlock);
- ctrCipher.processBlock(macBlock, 0, macBlock, 0); // S0
+ byte[] encMac = new byte[blockSize];
+
+ ctrCipher.processBlock(macBlock, 0, encMac, 0); // S0
while (inIndex < (inOff + inLen - blockSize)) // S1...
{
@@ -294,7 +296,7 @@ public class CCMBlockCipher
System.arraycopy(block, 0, output, outIndex, inLen + inOff - inIndex);
- System.arraycopy(macBlock, 0, output, outOff + inLen, macSize);
+ System.arraycopy(encMac, 0, output, outOff + inLen, macSize);
}
else
{
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java
index 9e8c3c30..ed89ef7d 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java
@@ -362,21 +362,30 @@ public class GCMBlockCipher
}
int extra = bufOff;
- if (!forEncryption)
+
+ if (forEncryption)
+ {
+ if (out.length < (outOff + extra + macSize))
+ {
+ throw new OutputLengthException("Output buffer too short");
+ }
+ }
+ else
{
if (extra < macSize)
{
throw new InvalidCipherTextException("data too short");
}
extra -= macSize;
- }
- if (extra > 0)
- {
if (out.length < (outOff + extra))
{
throw new OutputLengthException("Output buffer too short");
}
+ }
+
+ if (extra > 0)
+ {
gCTRPartial(bufBlock, 0, extra, out, outOff);
}
@@ -442,10 +451,6 @@ public class GCMBlockCipher
if (forEncryption)
{
- if (out.length < (outOff + extra + macSize))
- {
- throw new OutputLengthException("Output buffer too short");
- }
// Append T to the message
System.arraycopy(macBlock, 0, out, outOff + bufOff, macSize);
resultLen += macSize;
@@ -550,16 +555,11 @@ public class GCMBlockCipher
private byte[] getNextCounterBlock()
{
- for (int i = 15; i >= 12; --i)
- {
- byte b = (byte)((counter[i] + 1) & 0xff);
- counter[i] = b;
-
- if (b != 0)
- {
- break;
- }
- }
+ int c = 1;
+ c += counter[15] & 0xFF; counter[15] = (byte)c; c >>>= 8;
+ c += counter[14] & 0xFF; counter[14] = (byte)c; c >>>= 8;
+ c += counter[13] & 0xFF; counter[13] = (byte)c; c >>>= 8;
+ c += counter[12] & 0xFF; counter[12] = (byte)c;
byte[] tmp = new byte[BLOCK_SIZE];
// TODO Sure would be nice if ciphers could operate on int[]
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java
index fbc8bf45..ae4256f6 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java
@@ -6,6 +6,7 @@ import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.SkippingStreamCipher;
import org.bouncycastle.crypto.StreamBlockCipher;
import org.bouncycastle.crypto.params.ParametersWithIV;
+import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Pack;
/**
@@ -18,7 +19,7 @@ public class SICBlockCipher
{
private final BlockCipher cipher;
private final int blockSize;
-
+
private byte[] IV;
private byte[] counter;
private byte[] counterOut;
@@ -49,8 +50,19 @@ public class SICBlockCipher
if (params instanceof ParametersWithIV)
{
ParametersWithIV ivParam = (ParametersWithIV)params;
- byte[] iv = ivParam.getIV();
- System.arraycopy(iv, 0, IV, 0, IV.length);
+ this.IV = Arrays.clone(ivParam.getIV());
+
+ if (blockSize < IV.length)
+ {
+ throw new IllegalArgumentException("CTR/SIC mode requires IV no greater than: " + blockSize + " bytes.");
+ }
+
+ int maxCounterSize = (8 > blockSize / 2) ? blockSize / 2 : 8;
+
+ if (blockSize - IV.length > maxCounterSize)
+ {
+ throw new IllegalArgumentException("CTR/SIC mode requires IV of at least: " + (blockSize - maxCounterSize) + " bytes.");
+ }
// if null it's an IV changed only.
if (ivParam.getParameters() != null)
@@ -62,7 +74,7 @@ public class SICBlockCipher
}
else
{
- throw new IllegalArgumentException("SIC mode requires ParametersWithIV");
+ throw new IllegalArgumentException("CTR/SIC mode requires ParametersWithIV");
}
}
@@ -100,94 +112,63 @@ public class SICBlockCipher
{
byteCount = 0;
- incrementCounter();
+ incrementCounterAt(0);
+
+ checkCounter();
}
return rv;
}
- private void incrementCounterPow2(int pow2Div8)
+ private void checkCounter()
{
- // increment counter by 1 << 8 * pow2Div8
- for (int i = counter.length - (1 + pow2Div8); i >= 0 && ++counter[i] == 0; i--)
- {
- ; // do nothing - pre-increment and test for 0 in counter does the job.
- }
- }
-
- private void incrementCounter(int offSet)
- {
- byte old = counter[counter.length - 1];
-
- counter[counter.length - 1] += offSet;
-
- if (old != 0 && counter[counter.length - 1] < old)
+ // if the IV is the same as the blocksize we assume the user knows what they are doing
+ if (IV.length < blockSize)
{
- incrementCounterPow2(1);
+ for (int i = 0; i != IV.length; i++)
+ {
+ if (counter[i] != IV[i])
+ {
+ throw new IllegalStateException("Counter in CTR/SIC mode out of range.");
+ }
+ }
}
}
- private void incrementCounter()
+ private void incrementCounterAt(int pos)
{
- // increment counter by 1.
- for (int i = counter.length - 1; i >= 0 && ++counter[i] == 0; i--)
+ int i = counter.length - pos;
+ while (--i >= 0)
{
- ; // do nothing - pre-increment and test for 0 in counter does the job.
+ if (++counter[i] != 0)
+ {
+ break;
+ }
}
}
- private void decrementCounterPow2(int pow2Div8)
+ private void incrementCounter(int offSet)
{
- if (counter[pow2Div8] == 0)
- {
- boolean nonZero = false;
-
- for (int i = counter.length - (1 + pow2Div8); i > 0; i--)
- {
- if (counter[i] != 0)
- {
- nonZero = true;
- }
- }
+ byte old = counter[counter.length - 1];
- if (!nonZero)
- {
- throw new IllegalStateException("attempt to reduce counter past zero.");
- }
- }
+ counter[counter.length - 1] += offSet;
- // decrement counter by 1.
- for (int i = counter.length - (1 + pow2Div8); i >= 0 && --counter[i] == -1; i--)
+ if (old != 0 && counter[counter.length - 1] < old)
{
- ;
+ incrementCounterAt(1);
}
}
- private void decrementCounter()
+ private void decrementCounterAt(int pos)
{
- if (counter[0] == 0)
+ int i = counter.length - pos;
+ while (--i >= 0)
{
- boolean nonZero = false;
-
- for (int i = counter.length - 1; i > 0; i--)
- {
- if (counter[i] != 0)
- {
- nonZero = true;
- }
- }
-
- if (!nonZero)
+ if (--counter[i] != -1)
{
- throw new IllegalStateException("attempt to reduce counter past zero.");
+ return;
}
}
-
- // decrement counter by 1.
- for (int i = counter.length - 1; i >= 0 && --counter[i] == -1; i--)
- {
- ;
- }
}
private void adjustCounter(long n)
@@ -196,62 +177,45 @@ public class SICBlockCipher
{
long numBlocks = (n + byteCount) / blockSize;
- if (numBlocks > 255)
+ long rem = numBlocks;
+ if (rem > 255)
{
- long gap = numBlocks;
-
for (int i = 5; i >= 1; i--)
{
long diff = 1L << (8 * i);
-
- while (gap >= diff)
+ while (rem >= diff)
{
- incrementCounterPow2(i);
-
- gap -= diff;
+ incrementCounterAt(i);
+ rem -= diff;
}
}
-
- incrementCounter((int)gap);
- }
- else
- {
- incrementCounter((int)numBlocks);
}
+ incrementCounter((int)rem);
+
byteCount = (int)((n + byteCount) - (blockSize * numBlocks));
}
else
{
long numBlocks = (-n - byteCount) / blockSize;
- if (numBlocks > 255)
+ long rem = numBlocks;
+ if (rem > 255)
{
- long gap = numBlocks;
-
for (int i = 5; i >= 1; i--)
{
long diff = 1L << (8 * i);
-
- while (gap > diff)
+ while (rem > diff)
{
- decrementCounterPow2(i);
-
- gap -= diff;
+ decrementCounterAt(i);
+ rem -= diff;
}
}
-
- for (long i = 0; i != gap; i++)
- {
- decrementCounter();
- }
}
- else
+
+ for (long i = 0; i != rem; i++)
{
- for (long i = 0; i != numBlocks; i++)
- {
- decrementCounter();
- }
+ decrementCounterAt(0);
}
int gap = (int)(byteCount + n + (blockSize * numBlocks));
@@ -262,7 +226,7 @@ public class SICBlockCipher
}
else
{
- decrementCounter();
+ decrementCounterAt(0);
byteCount = blockSize + gap;
}
}
@@ -270,7 +234,8 @@ public class SICBlockCipher
public void reset()
{
- System.arraycopy(IV, 0, counter, 0, counter.length);
+ Arrays.fill(counter, (byte)0);
+ System.arraycopy(IV, 0, counter, 0, IV.length);
cipher.reset();
this.byteCount = 0;
}
@@ -279,6 +244,8 @@ public class SICBlockCipher
{
adjustCounter(numberOfBytes);
+ checkCounter();
+
cipher.processBlock(counter, 0, counterOut, 0);
return numberOfBytes;
@@ -293,13 +260,21 @@ public class SICBlockCipher
public long getPosition()
{
- byte[] res = new byte[IV.length];
+ byte[] res = new byte[counter.length];
System.arraycopy(counter, 0, res, 0, res.length);
for (int i = res.length - 1; i >= 1; i--)
{
- int v = (res[i] & 0xff) - (IV[i] & 0xff);
+ int v;
+ if (i < IV.length)
+ {
+ v = (res[i] & 0xff) - (IV[i] & 0xff);
+ }
+ else
+ {
+ v = (res[i] & 0xff);
+ }
if (v < 0)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMUtil.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/gcm/GCMUtil.java
index 58f40788..f08f71f3 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
@@ -123,9 +123,9 @@ public abstract class GCMUtil
r13 ^= (r03 & m1);
int m2 = (r03 << 31) >> 8;
- r03 = (r03 >>> 1) | (r02 << 63);
- r02 = (r02 >>> 1) | (r01 << 63);
- r01 = (r01 >>> 1) | (r00 << 63);
+ r03 = (r03 >>> 1) | (r02 << 31);
+ r02 = (r02 >>> 1) | (r01 << 31);
+ r01 = (r01 >>> 1) | (r00 << 31);
r00 = (r00 >>> 1) ^ (m2 & E1);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/DESedeParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/DESedeParameters.java
index 3a4bbfca..5b2d0d46 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/DESedeParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/DESedeParameters.java
@@ -54,4 +54,53 @@ public class DESedeParameters
{
return isWeakKey(key, offset, key.length - offset);
}
+
+ /**
+ * return true if the passed in key is a real 2/3 part DES-EDE key.
+ *
+ * @param key bytes making up the key
+ * @param offset offset into the byte array the key starts at
+ */
+ public static boolean isRealEDEKey(byte[] key, int offset)
+ {
+ return key.length == 16 ? isReal2Key(key, offset) : isReal3Key(key, offset);
+ }
+
+ /**
+ * return true if the passed in key is a real 2 part DES-EDE key.
+ *
+ * @param key bytes making up the key
+ * @param offset offset into the byte array the key starts at
+ */
+ public static boolean isReal2Key(byte[] key, int offset)
+ {
+ boolean isValid = false;
+ for (int i = offset; i != offset + 8; i++)
+ {
+ if (key[i] != key[i + 8])
+ {
+ isValid = true;
+ }
+ }
+
+ return isValid;
+ }
+
+ /**
+ * return true if the passed in key is a real 3 part DES-EDE key.
+ *
+ * @param key bytes making up the key
+ * @param offset offset into the byte array the key starts at
+ */
+ public static boolean isReal3Key(byte[] key, int offset)
+ {
+ boolean diff12 = false, diff13 = false, diff23 = false;
+ for (int i = offset; i != offset + 8; i++)
+ {
+ diff12 |= (key[i] != key[i + 8]);
+ diff13 |= (key[i] != key[i + 16]);
+ diff23 |= (key[i + 8] != key[i + 16]);
+ }
+ return diff12 && diff13 && diff23;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/KDFParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/KDFParameters.java
new file mode 100644
index 00000000..f3bac647
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/KDFParameters.java
@@ -0,0 +1,31 @@
+package org.bouncycastle.crypto.params;
+
+import org.bouncycastle.crypto.DerivationParameters;
+
+/**
+ * parameters for Key derivation functions for IEEE P1363a
+ */
+public class KDFParameters
+ implements DerivationParameters
+{
+ byte[] iv;
+ byte[] shared;
+
+ public KDFParameters(
+ byte[] shared,
+ byte[] iv)
+ {
+ this.shared = shared;
+ this.iv = iv;
+ }
+
+ public byte[] getSharedSecret()
+ {
+ return shared;
+ }
+
+ public byte[] getIV()
+ {
+ return iv;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/RC2Parameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/RC2Parameters.java
index dc33ec5b..ea98de2c 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/RC2Parameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/RC2Parameters.java
@@ -1,11 +1,8 @@
package org.bouncycastle.crypto.params;
-import org.bouncycastle.crypto.CipherParameters;
-
public class RC2Parameters
- implements CipherParameters
+ extends KeyParameter
{
- private byte[] key;
private int bits;
public RC2Parameters(
@@ -18,15 +15,8 @@ public class RC2Parameters
byte[] key,
int bits)
{
- this.key = new byte[key.length];
+ super(key);
this.bits = bits;
-
- System.arraycopy(key, 0, this.key, 0, key.length);
- }
-
- public byte[] getKey()
- {
- return key;
}
public int getEffectiveKeyBits()
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 5fce1121..adb2558a 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java
@@ -12,6 +12,8 @@ import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.math.ec.ECAlgorithms;
import org.bouncycastle.math.ec.ECConstants;
+import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECMultiplier;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.math.ec.FixedPointCombMultiplier;
@@ -159,7 +161,7 @@ public class ECDSASigner
ECPoint G = ec.getG();
ECPoint Q = ((ECPublicKeyParameters)key).getQ();
- ECPoint point = ECAlgorithms.sumOfTwoMultiplies(G, u1, Q, u2).normalize();
+ ECPoint point = ECAlgorithms.sumOfTwoMultiplies(G, u1, Q, u2);
// components must be bogus.
if (point.isInfinity())
@@ -167,8 +169,44 @@ public class ECDSASigner
return false;
}
- BigInteger v = point.getAffineXCoord().toBigInteger().mod(n);
+ /*
+ * If possible, avoid normalizing the point (to save a modular inversion in the curve field).
+ *
+ * There are ~cofactor elements of the curve field that reduce (modulo the group order) to 'r'.
+ * If the cofactor is known and small, we generate those possible field values and project each
+ * of them to the same "denominator" (depending on the particular projective coordinates in use)
+ * as the calculated point.X. If any of the projected values matches point.X, then we have:
+ * (point.X / Denominator mod p) mod n == r
+ * as required, and verification succeeds.
+ *
+ * Based on an original idea by Gregory Maxwell (https://github.com/gmaxwell), as implemented in
+ * the libsecp256k1 project (https://github.com/bitcoin/secp256k1).
+ */
+ ECCurve curve = point.getCurve();
+ if (curve != null)
+ {
+ BigInteger cofactor = curve.getCofactor();
+ if (cofactor != null && cofactor.compareTo(EIGHT) <= 0)
+ {
+ ECFieldElement D = getDenominator(curve.getCoordinateSystem(), point);
+ if (D != null && !D.isZero())
+ {
+ ECFieldElement X = point.getXCoord();
+ while (curve.isValidFieldElement(r))
+ {
+ ECFieldElement R = curve.fromBigInteger(r).multiply(D);
+ if (R.equals(X))
+ {
+ return true;
+ }
+ r = r.add(n);
+ }
+ return false;
+ }
+ }
+ }
+ BigInteger v = point.normalize().getAffineXCoord().toBigInteger().mod(n);
return v.equals(r);
}
@@ -190,6 +228,23 @@ public class ECDSASigner
return new FixedPointCombMultiplier();
}
+ protected ECFieldElement getDenominator(int coordinateSystem, ECPoint p)
+ {
+ switch (coordinateSystem)
+ {
+ case ECCurve.COORD_HOMOGENEOUS:
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ case ECCurve.COORD_SKEWED:
+ return p.getZCoord(0);
+ case ECCurve.COORD_JACOBIAN:
+ case ECCurve.COORD_JACOBIAN_CHUDNOVSKY:
+ case ECCurve.COORD_JACOBIAN_MODIFIED:
+ return p.getZCoord(0).square();
+ default:
+ return null;
+ }
+ }
+
protected SecureRandom initSecureRandom(boolean needed, SecureRandom provided)
{
return !needed ? null : (provided != null) ? provided : new SecureRandom();
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 2b333213..042c68ef 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java
@@ -22,10 +22,10 @@ import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.DSAParameter;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
-import org.bouncycastle.asn1.x9.DHDomainParameters;
import org.bouncycastle.asn1.x9.DHPublicKey;
-import org.bouncycastle.asn1.x9.DHValidationParms;
+import org.bouncycastle.asn1.x9.DomainParameters;
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
+import org.bouncycastle.asn1.x9.ValidationParams;
import org.bouncycastle.asn1.x9.X962Parameters;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.asn1.x9.X9ECPoint;
@@ -98,26 +98,26 @@ public class PublicKeyFactory
{
DHPublicKey dhPublicKey = DHPublicKey.getInstance(keyInfo.parsePublicKey());
- BigInteger y = dhPublicKey.getY().getValue();
+ BigInteger y = dhPublicKey.getY();
- DHDomainParameters dhParams = DHDomainParameters.getInstance(algId.getParameters());
+ DomainParameters dhParams = DomainParameters.getInstance(algId.getParameters());
- BigInteger p = dhParams.getP().getValue();
- BigInteger g = dhParams.getG().getValue();
- BigInteger q = dhParams.getQ().getValue();
+ BigInteger p = dhParams.getP();
+ BigInteger g = dhParams.getG();
+ BigInteger q = dhParams.getQ();
BigInteger j = null;
if (dhParams.getJ() != null)
{
- j = dhParams.getJ().getValue();
+ j = dhParams.getJ();
}
DHValidationParameters validation = null;
- DHValidationParms dhValidationParms = dhParams.getValidationParms();
+ ValidationParams dhValidationParms = dhParams.getValidationParams();
if (dhValidationParms != null)
{
- byte[] seed = dhValidationParms.getSeed().getBytes();
- BigInteger pgenCounter = dhValidationParms.getPgenCounter().getValue();
+ byte[] seed = dhValidationParms.getSeed();
+ BigInteger pgenCounter = dhValidationParms.getPgenCounter();
// TODO Check pgenCounter size?
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PBKDFKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PBKDFKey.java
new file mode 100644
index 00000000..ae3d2ebd
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PBKDFKey.java
@@ -0,0 +1,11 @@
+package org.bouncycastle.jcajce;
+
+import javax.crypto.SecretKey;
+
+/**
+ * Base interface for keys associated with various password based key derivation functions (PBKDF).
+ */
+public interface PBKDFKey
+ extends SecretKey
+{
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKCS12Key.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKCS12Key.java
new file mode 100644
index 00000000..db63ecdb
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKCS12Key.java
@@ -0,0 +1,82 @@
+package org.bouncycastle.jcajce;
+
+import org.bouncycastle.crypto.PBEParametersGenerator;
+
+/**
+ * A password based key for use with PKCS#12.
+ */
+public class PKCS12Key
+ implements PBKDFKey
+{
+ private final char[] password;
+ private final boolean useWrongZeroLengthConversion;
+ /**
+ * Basic constructor for a password based key - secret key generation parameters will be passed separately..
+ *
+ * @param password password to use.
+ */
+ public PKCS12Key(char[] password)
+ {
+ this(password, false);
+ }
+
+ /**
+ * Unfortunately there seems to be some confusion about how to handle zero length
+ * passwords.
+ *
+ * @param password password to use.
+ * @param useWrongZeroLengthConversion use the incorrect encoding approach (add pad bytes)
+ */
+ public PKCS12Key(char[] password, boolean useWrongZeroLengthConversion)
+ {
+ this.password = new char[password.length];
+ this.useWrongZeroLengthConversion = useWrongZeroLengthConversion;
+
+ System.arraycopy(password, 0, this.password, 0, password.length);
+ }
+
+ /**
+ * Return a reference to the char[] array holding the password.
+ *
+ * @return a reference to the password array.
+ */
+ public char[] getPassword()
+ {
+ return password;
+ }
+
+ /**
+ * Return the password based key derivation function this key is for,
+ *
+ * @return the string "PKCS12"
+ */
+ public String getAlgorithm()
+ {
+ return "PKCS12";
+ }
+
+ /**
+ * Return the format encoding.
+ *
+ * @return the string "PKCS12", representing the char[] to byte[] conversion.
+ */
+ public String getFormat()
+ {
+ return "PKCS12";
+ }
+
+ /**
+ * Return the password converted to bytes.
+ *
+ * @return the password converted to a byte array.
+ */
+ public byte[] getEncoded()
+ {
+ if (useWrongZeroLengthConversion && password.length == 0)
+ {
+ return new byte[2];
+ }
+
+ return PBEParametersGenerator.PKCS12PasswordToBytes(password);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKCS12KeyWithParameters.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKCS12KeyWithParameters.java
new file mode 100644
index 00000000..bd055966
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKCS12KeyWithParameters.java
@@ -0,0 +1,69 @@
+package org.bouncycastle.jcajce;
+
+import javax.crypto.interfaces.PBEKey;
+
+import org.bouncycastle.util.Arrays;
+
+/**
+ * A password based key for use with PKCS#12 with full PBE parameters.
+ */
+public class PKCS12KeyWithParameters
+ extends PKCS12Key
+ implements PBEKey
+{
+ private final byte[] salt;
+ private final int iterationCount;
+
+ /**
+ * Basic constructor for a password based key with generation parameters.
+ *
+ * @param password password to use.
+ * @param salt salt for generation algorithm
+ * @param iterationCount iteration count for generation algorithm.
+ */
+ public PKCS12KeyWithParameters(char[] password, byte[] salt, int iterationCount)
+ {
+ super(password);
+
+ this.salt = Arrays.clone(salt);
+ this.iterationCount = iterationCount;
+ }
+
+
+ /**
+ * Basic constructor for a password based key with generation parameters, specifying the wrong conversion for
+ * zero length passwords.
+ *
+ * @param password password to use.
+ * @param salt salt for generation algorithm
+ * @param iterationCount iteration count for generation algorithm.
+ * @param useWrongZeroLengthConversion use the incorrect encoding approach (add pad bytes)
+ */
+ public PKCS12KeyWithParameters(char[] password, boolean useWrongZeroLengthConversion, byte[] salt, int iterationCount)
+ {
+ super(password, useWrongZeroLengthConversion);
+
+ this.salt = Arrays.clone(salt);
+ this.iterationCount = iterationCount;
+ }
+
+ /**
+ * Return the salt to use in the key derivation function.
+ *
+ * @return the salt to use in the KDF.
+ */
+ public byte[] getSalt()
+ {
+ return salt;
+ }
+
+ /**
+ * Return the iteration count to use in the key derivation function.
+ *
+ * @return the iteration count to use in the KDF.
+ */
+ public int getIterationCount()
+ {
+ return iterationCount;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStore.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStore.java
index b3447207..1592055f 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStore.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStore.java
@@ -7,9 +7,21 @@ import org.bouncycastle.util.Selector;
import org.bouncycastle.util.Store;
import org.bouncycastle.util.StoreException;
+/**
+ * Generic interface for a PKIX based CRL store.
+ *
+ * @param <T> the CRL type.
+ */
public interface PKIXCRLStore<T extends CRL>
extends Store<T>
{
+ /**
+ * Return the matches associated with the passed in selector.
+ *
+ * @param selector the selector defining the match criteria.
+ * @return a collection of matches with the selector, an empty selector if there are none.
+ * @throws StoreException in the event of an issue doing a match.
+ */
Collection<T> getMatches(Selector<T> selector)
throws StoreException;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStoreSelector.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStoreSelector.java
index 9c684332..e7dbcce0 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStoreSelector.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCRLStoreSelector.java
@@ -25,6 +25,9 @@ import org.bouncycastle.util.Selector;
public class PKIXCRLStoreSelector<T extends CRL>
implements Selector<T>
{
+ /**
+ * Builder for a PKIXCRLStoreSelector.
+ */
public static class Builder
{
private final CRLSelector baseSelector;
@@ -35,9 +38,14 @@ public class PKIXCRLStoreSelector<T extends CRL>
private byte[] issuingDistributionPoint = null;
private boolean issuingDistributionPointEnabled = false;
- public Builder(CRLSelector certSelector)
+ /**
+ * Constructor initializing a builder with a CertSelector.
+ *
+ * @param crlSelector the CertSelector to copy the match details from.
+ */
+ public Builder(CRLSelector crlSelector)
{
- this.baseSelector = (CRLSelector)certSelector.clone();
+ this.baseSelector = (CRLSelector)crlSelector.clone();
}
@@ -124,6 +132,11 @@ public class PKIXCRLStoreSelector<T extends CRL>
this.issuingDistributionPoint = Arrays.clone(issuingDistributionPoint);
}
+ /**
+ * Build a selector.
+ *
+ * @return a new PKIXCRLStoreSelector
+ */
public PKIXCRLStoreSelector<? extends CRL> build()
{
return new PKIXCRLStoreSelector(this);
@@ -291,23 +304,44 @@ public class PKIXCRLStoreSelector<T extends CRL>
public X509Certificate getCertificateChecking()
{
- return ((X509CRLSelector)baseSelector).getCertificateChecking();
+ if (baseSelector instanceof X509CRLSelector)
+ {
+ return ((X509CRLSelector)baseSelector).getCertificateChecking();
+ }
+
+ return null;
}
public static Collection<? extends CRL> getCRLs(final PKIXCRLStoreSelector selector, CertStore certStore)
throws CertStoreException
{
- return certStore.getCRLs(new CRLSelector()
+ return certStore.getCRLs(new SelectorClone(selector));
+ }
+
+ private static class SelectorClone
+ extends X509CRLSelector
+ {
+ private final PKIXCRLStoreSelector selector;
+
+ SelectorClone(PKIXCRLStoreSelector selector)
{
- public boolean match(CRL crl)
- {
- return selector.match(crl);
- }
+ this.selector = selector;
- public Object clone()
+ if (selector.baseSelector instanceof X509CRLSelector)
{
- return this;
+ X509CRLSelector baseSelector = (X509CRLSelector)selector.baseSelector;
+
+ this.setCertificateChecking(baseSelector.getCertificateChecking());
+ this.setDateAndTime(baseSelector.getDateAndTime());
+ this.setIssuers(baseSelector.getIssuers());
+ this.setMinCRLNumber(baseSelector.getMinCRL());
+ this.setMaxCRLNumber(baseSelector.getMaxCRL());
}
- });
+ }
+
+ public boolean match(CRL crl)
+ {
+ return (selector == null) ? (crl != null) : selector.match(crl);
+ }
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStore.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStore.java
index 092872f1..853e2d11 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStore.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStore.java
@@ -7,9 +7,21 @@ import org.bouncycastle.util.Selector;
import org.bouncycastle.util.Store;
import org.bouncycastle.util.StoreException;
+/**
+ * Generic interface for a PKIX based certificate store.
+ *
+ * @param <T> the certificate type.
+ */
public interface PKIXCertStore<T extends Certificate>
extends Store<T>
{
+ /**
+ * Return the matches associated with the passed in selector.
+ *
+ * @param selector the selector defining the match criteria.
+ * @return a collection of matches with the selector, an empty selector if there are none.
+ * @throws StoreException in the event of an issue doing a match.
+ */
Collection<T> getMatches(Selector<T> selector)
throws StoreException;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStoreSelector.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStoreSelector.java
index 1775de72..faf25d1a 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStoreSelector.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXCertStoreSelector.java
@@ -1,9 +1,11 @@
package org.bouncycastle.jcajce;
+import java.io.IOException;
import java.security.cert.CertSelector;
import java.security.cert.CertStore;
import java.security.cert.CertStoreException;
import java.security.cert.Certificate;
+import java.security.cert.X509CertSelector;
import java.util.Collection;
import org.bouncycastle.util.Selector;
@@ -16,15 +18,28 @@ import org.bouncycastle.util.Selector;
public class PKIXCertStoreSelector<T extends Certificate>
implements Selector<T>
{
+ /**
+ * Builder for a PKIXCertStoreSelector.
+ */
public static class Builder
{
private final CertSelector baseSelector;
+ /**
+ * Constructor initializing a builder with a CertSelector.
+ *
+ * @param certSelector the CertSelector to copy the match details from.
+ */
public Builder(CertSelector certSelector)
{
this.baseSelector = (CertSelector)certSelector.clone();
}
+ /**
+ * Build a selector.
+ *
+ * @return a new PKIXCertStoreSelector
+ */
public PKIXCertStoreSelector<? extends Certificate> build()
{
return new PKIXCertStoreSelector(baseSelector);
@@ -51,17 +66,54 @@ public class PKIXCertStoreSelector<T extends Certificate>
public static Collection<? extends Certificate> getCertificates(final PKIXCertStoreSelector selector, CertStore certStore)
throws CertStoreException
{
- return certStore.getCertificates(new CertSelector()
+ return certStore.getCertificates(new SelectorClone(selector));
+ }
+
+ private static class SelectorClone
+ extends X509CertSelector
+ {
+ private final PKIXCertStoreSelector selector;
+
+ SelectorClone(PKIXCertStoreSelector selector)
{
- public boolean match(Certificate certificate)
- {
- return (selector == null) ? true : selector.match(certificate);
- }
+ this.selector = selector;
- public Object clone()
+ if (selector.baseSelector instanceof X509CertSelector)
{
- return this;
+ X509CertSelector baseSelector = (X509CertSelector)selector.baseSelector;
+
+ this.setAuthorityKeyIdentifier(baseSelector.getAuthorityKeyIdentifier());
+ this.setBasicConstraints(baseSelector.getBasicConstraints());
+ this.setCertificate(baseSelector.getCertificate());
+ this.setCertificateValid(baseSelector.getCertificateValid());
+ this.setKeyUsage(baseSelector.getKeyUsage());
+ this.setMatchAllSubjectAltNames(baseSelector.getMatchAllSubjectAltNames());
+ this.setPrivateKeyValid(baseSelector.getPrivateKeyValid());
+ this.setSerialNumber(baseSelector.getSerialNumber());
+ this.setSubjectKeyIdentifier(baseSelector.getSubjectKeyIdentifier());
+ this.setSubjectPublicKey(baseSelector.getSubjectPublicKey());
+
+ try
+ {
+ this.setExtendedKeyUsage(baseSelector.getExtendedKeyUsage());
+ this.setIssuer(baseSelector.getIssuerAsBytes());
+ this.setNameConstraints(baseSelector.getNameConstraints());
+ this.setPathToNames(baseSelector.getPathToNames());
+ this.setPolicy(baseSelector.getPolicy());
+ this.setSubject(baseSelector.getSubjectAsBytes());
+ this.setSubjectAlternativeNames(baseSelector.getSubjectAlternativeNames());
+ this.setSubjectPublicKeyAlgID(baseSelector.getSubjectPublicKeyAlgID());
+ }
+ catch (IOException e)
+ {
+ throw new IllegalStateException("base selector invalid: " + e.getMessage(), e);
+ }
}
- });
+ }
+
+ public boolean match(Certificate certificate)
+ {
+ return (selector == null) ? (certificate != null) : selector.match(certificate);
+ }
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedBuilderParameters.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedBuilderParameters.java
index 3369d0d2..382a23c2 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedBuilderParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedBuilderParameters.java
@@ -11,11 +11,14 @@ import java.util.Set;
/**
* This class contains extended parameters for PKIX certification path builders.
*
- * @see java.security.cert.PKIXBuilderParameters
+ * @see PKIXBuilderParameters
*/
public class PKIXExtendedBuilderParameters
implements CertPathParameters
{
+ /**
+ * Builder for a PKIXExtendedBuilderParameters object.
+ */
public static class Builder
{
private final PKIXExtendedParameters baseParameters;
@@ -64,7 +67,7 @@ public class PKIXExtendedBuilderParameters
*
* @param maxPathLength the maximum number of non-self-issued intermediate
* certificates in the certification path
- * @throws java.security.InvalidParameterException if <code>maxPathLength</code> is set
+ * @throws InvalidParameterException if <code>maxPathLength</code> is set
* to a value less than -1
*
* @see #getMaxPathLength
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedParameters.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedParameters.java
index 3a86f2a6..cd24f069 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKIXExtendedParameters.java
@@ -27,7 +27,7 @@ public class PKIXExtendedParameters
* 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 java.security.cert.PKIXParameters#setDate(java.util.Date)} method, so this
+ * with the {@link PKIXParameters#setDate(Date)} method, so this
* methods sets the Date when <em>all</em> certificates must have been
* valid.
*/
@@ -40,15 +40,15 @@ public class PKIXExtendedParameters
* 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 java.security.cert.PKIXParameters#setDate(java.util.Date)} method sets the time, when
- * the <em>end certificate</em> must have been valid.
- * <p>
- * It is used e.g.
+ * {@link PKIXParameters#setDate(Date)} method sets the time, when
+ * the <em>end certificate</em> must have been valid. <p/> It is used e.g.
* in the German signature law.
- * </p>
*/
public static final int CHAIN_VALIDITY_MODEL = 1;
+ /**
+ * Builder for a PKIXExtendedParameters object.
+ */
public static class Builder
{
private final PKIXParameters baseParameters;
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DH.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DH.java
index d43924d0..889d957d 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DH.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DH.java
@@ -24,6 +24,10 @@ public class DH
provider.addAlgorithm("KeyAgreement.DH", PREFIX + "KeyAgreementSpi");
provider.addAlgorithm("Alg.Alias.KeyAgreement.DIFFIEHELLMAN", "DH");
+ // BEGIN android-removed
+ // provider.addAlgorithm("KeyAgreement", PKCSObjectIdentifiers.id_alg_ESDH, PREFIX + "KeyAgreementSpi$DHwithRFC2631KDF");
+ // provider.addAlgorithm("KeyAgreement", PKCSObjectIdentifiers.id_alg_SSDH, PREFIX + "KeyAgreementSpi$DHwithRFC2631KDF");
+ // END android-removed
provider.addAlgorithm("KeyFactory.DH", PREFIX + "KeyFactorySpi");
provider.addAlgorithm("Alg.Alias.KeyFactory.DIFFIEHELLMAN", "DH");
@@ -34,12 +38,22 @@ public class DH
provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator.DIFFIEHELLMAN", "DH");
provider.addAlgorithm("AlgorithmParameterGenerator.DH", PREFIX + "AlgorithmParameterGeneratorSpi");
-
+
// BEGIN android-removed
+ // provider.addAlgorithm("Cipher.IES", PREFIX + "IESCipher$IES");
+ // provider.addAlgorithm("Cipher.IESwithAES", PREFIX + "IESCipher$IESwithAES");
+ // provider.addAlgorithm("Cipher.IESWITHAES", PREFIX + "IESCipher$IESwithAES");
+ // provider.addAlgorithm("Cipher.IESWITHDESEDE", PREFIX + "IESCipher$IESwithDESede");
+ //
// provider.addAlgorithm("Cipher.DHIES", PREFIX + "IESCipher$IES");
// provider.addAlgorithm("Cipher.DHIESwithAES", PREFIX + "IESCipher$IESwithAES");
// provider.addAlgorithm("Cipher.DHIESWITHAES", PREFIX + "IESCipher$IESwithAES");
// provider.addAlgorithm("Cipher.DHIESWITHDESEDE", PREFIX + "IESCipher$IESwithDESede");
+ //
+ // provider.addAlgorithm("Cipher.OLDDHIES", PREFIX + "IESCipher$OldIES");
+ // provider.addAlgorithm("Cipher.OLDDHIESwithAES", PREFIX + "IESCipher$OldIESwithAES");
+ // provider.addAlgorithm("Cipher.OLDDHIESWITHAES", PREFIX + "IESCipher$OldIESwithAES");
+ // provider.addAlgorithm("Cipher.OLDDHIESWITHDESEDE", PREFIX + "IESCipher$OldIESwithDESede");
// END android-removed
registerOid(provider, PKCSObjectIdentifiers.dhKeyAgreement, "DH", new KeyFactorySpi());
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java
index 1266abd0..91500c9c 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java
@@ -3,12 +3,16 @@ package org.bouncycastle.jcajce.provider.asymmetric;
// BEGIN android-removed
// import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
// import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
+// import org.bouncycastle.asn1.sec.SECObjectIdentifiers;
// import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
// END android-removed
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi;
import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
import org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider;
+// BEGIN android-removed
+// import org.bouncycastle.util.Properties;
+// END android-removed
public class EC
{
@@ -23,31 +27,116 @@ public class EC
public void configure(ConfigurableProvider provider)
{
+ // BEGIN android-removed
+ // provider.addAlgorithm("AlgorithmParameters.EC", PREFIX + "AlgorithmParametersSpi");
+ // END android-removed
+
provider.addAlgorithm("KeyAgreement.ECDH", PREFIX + "KeyAgreementSpi$DH");
// BEGIN android-removed
// provider.addAlgorithm("KeyAgreement.ECDHC", PREFIX + "KeyAgreementSpi$DHC");
- // provider.addAlgorithm("KeyAgreement.ECMQV", PREFIX + "KeyAgreementSpi$MQV");
- // provider.addAlgorithm("KeyAgreement." + X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA1KDF");
- // provider.addAlgorithm("KeyAgreement." + X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA1KDF");
+ // provider.addAlgorithm("KeyAgreement.ECCDH", PREFIX + "KeyAgreementSpi$DHC");
+ //
+ // provider.addAlgorithm("KeyAgreement." + X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA1KDFAndSharedInfo");
+ // provider.addAlgorithm("KeyAgreement." + X9ObjectIdentifiers.dhSinglePass_cofactorDH_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA1KDFAndSharedInfo");
+ //
+ // provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.dhSinglePass_stdDH_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA224KDFAndSharedInfo");
+ // provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.dhSinglePass_cofactorDH_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA224KDFAndSharedInfo");
+ //
+ // provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.dhSinglePass_stdDH_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA256KDFAndSharedInfo");
+ // provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.dhSinglePass_cofactorDH_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA256KDFAndSharedInfo");
+ //
+ // provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.dhSinglePass_stdDH_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA384KDFAndSharedInfo");
+ // provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.dhSinglePass_cofactorDH_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA384KDFAndSharedInfo");
+ //
+ // provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.dhSinglePass_stdDH_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$DHwithSHA512KDFAndSharedInfo");
+ // provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.dhSinglePass_cofactorDH_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$CDHwithSHA512KDFAndSharedInfo");
+ //
// provider.addAlgorithm("KeyAgreement.ECDHWITHSHA1KDF", PREFIX + "KeyAgreementSpi$DHwithSHA1KDF");
+ //
+ // provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA1CKDF");
+ // provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA256CKDF");
+ // provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA384CKDF");
+ // provider.addAlgorithm("KeyAgreement.ECCDHWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$DHwithSHA512CKDF");
// END android-removed
registerOid(provider, X9ObjectIdentifiers.id_ecPublicKey, "EC", new KeyFactorySpi.EC());
- // TODO Should this be an alias for ECDH?
+ // BEGIN android-added
+ // We were having this one in 1.52. As of 1.54 this one is under
+ // if (!Properties.isOverrideSet("org.bouncycastle.ec.disable_mqv"))
+ // below
registerOid(provider, X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, "EC", new KeyFactorySpi.EC());
+ // END android-added
+
// BEGIN android-removed
+ // registerOid(provider, X9ObjectIdentifiers.dhSinglePass_cofactorDH_sha1kdf_scheme, "EC", new KeyFactorySpi.EC());
// registerOid(provider, X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV());
//
+ // registerOid(provider, SECObjectIdentifiers.dhSinglePass_stdDH_sha224kdf_scheme, "EC", new KeyFactorySpi.EC());
+ // registerOid(provider, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha224kdf_scheme, "EC", new KeyFactorySpi.EC());
+ //
+ // registerOid(provider, SECObjectIdentifiers.dhSinglePass_stdDH_sha256kdf_scheme, "EC", new KeyFactorySpi.EC());
+ // registerOid(provider, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha256kdf_scheme, "EC", new KeyFactorySpi.EC());
+ //
+ // registerOid(provider, SECObjectIdentifiers.dhSinglePass_stdDH_sha384kdf_scheme, "EC", new KeyFactorySpi.EC());
+ // registerOid(provider, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha384kdf_scheme, "EC", new KeyFactorySpi.EC());
+ //
+ // registerOid(provider, SECObjectIdentifiers.dhSinglePass_stdDH_sha512kdf_scheme, "EC", new KeyFactorySpi.EC());
+ // registerOid(provider, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha512kdf_scheme, "EC", new KeyFactorySpi.EC());
+ //
// // Android comment: the registration below is causing CTS tests to fail and doesn't seem
// // to be implemented by bouncycastle (so looks like an bug in bouncycastle).
+ // // TODO(26929227): check this still happens
// registerOidAlgorithmParameters(provider, X9ObjectIdentifiers.id_ecPublicKey, "EC");
- // END android-removed
- // TODO Should this be an alias for ECDH?
- // BEGIN android-removed
- // // Android comment: the registration below is causing CTS tests to fail and doesn't seem
- // // to be implemented by bouncycastle (so looks like an bug in bouncycastle).
+ //
// registerOidAlgorithmParameters(provider, X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, "EC");
- // registerOidAlgorithmParameters(provider, X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, "EC");
+ // registerOidAlgorithmParameters(provider, X9ObjectIdentifiers.dhSinglePass_cofactorDH_sha1kdf_scheme, "EC");
+ //
+ // registerOidAlgorithmParameters(provider, SECObjectIdentifiers.dhSinglePass_stdDH_sha224kdf_scheme, "EC");
+ // registerOidAlgorithmParameters(provider, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha224kdf_scheme, "EC");
+ //
+ // registerOidAlgorithmParameters(provider, SECObjectIdentifiers.dhSinglePass_stdDH_sha256kdf_scheme, "EC");
+ // registerOidAlgorithmParameters(provider, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha256kdf_scheme, "EC");
+ //
+ // registerOidAlgorithmParameters(provider, SECObjectIdentifiers.dhSinglePass_stdDH_sha384kdf_scheme, "EC");
+ // registerOidAlgorithmParameters(provider, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha384kdf_scheme, "EC");
+ //
+ // registerOidAlgorithmParameters(provider, SECObjectIdentifiers.dhSinglePass_stdDH_sha512kdf_scheme, "EC");
+ // registerOidAlgorithmParameters(provider, SECObjectIdentifiers.dhSinglePass_cofactorDH_sha512kdf_scheme, "EC");
+ //
+ // if (!Properties.isOverrideSet("org.bouncycastle.ec.disable_mqv"))
+ // {
+ // provider.addAlgorithm("KeyAgreement.ECMQV", PREFIX + "KeyAgreementSpi$MQV");
+ //
+ // provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA1CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA1CKDF");
+ // provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA224CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA224CKDF");
+ // provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA256CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA256CKDF");
+ // provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA384CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA384CKDF");
+ // provider.addAlgorithm("KeyAgreement.ECMQVWITHSHA512CKDF", PREFIX + "KeyAgreementSpi$MQVwithSHA512CKDF");
+ //
+ // provider.addAlgorithm("KeyAgreement." + X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA1KDFAndSharedInfo");
+ // provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA224KDFAndSharedInfo");
+ // provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha256kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA256KDFAndSharedInfo");
+ // provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA384KDFAndSharedInfo");
+ // provider.addAlgorithm("KeyAgreement." + SECObjectIdentifiers.mqvSinglePass_sha512kdf_scheme, PREFIX + "KeyAgreementSpi$MQVwithSHA512KDFAndSharedInfo");
+ //
+ // registerOid(provider, X9ObjectIdentifiers.dhSinglePass_stdDH_sha1kdf_scheme, "EC", new KeyFactorySpi.EC());
+ // registerOidAlgorithmParameters(provider, X9ObjectIdentifiers.mqvSinglePass_sha1kdf_scheme, "EC");
+ //
+ // registerOid(provider, SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV());
+ // registerOidAlgorithmParameters(provider, SECObjectIdentifiers.mqvSinglePass_sha256kdf_scheme, "EC");
+ //
+ // registerOid(provider, SECObjectIdentifiers.mqvSinglePass_sha256kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV());
+ // registerOidAlgorithmParameters(provider, SECObjectIdentifiers.mqvSinglePass_sha224kdf_scheme, "EC");
+ //
+ // registerOid(provider, SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV());
+ // registerOidAlgorithmParameters(provider, SECObjectIdentifiers.mqvSinglePass_sha384kdf_scheme, "EC");
+ //
+ // registerOid(provider, SECObjectIdentifiers.mqvSinglePass_sha512kdf_scheme, "ECMQV", new KeyFactorySpi.ECMQV());
+ // registerOidAlgorithmParameters(provider, SECObjectIdentifiers.mqvSinglePass_sha512kdf_scheme, "EC");
+ //
+ // provider.addAlgorithm("KeyFactory.ECMQV", PREFIX + "KeyFactorySpi$ECMQV");
+ // provider.addAlgorithm("KeyPairGenerator.ECMQV", PREFIX + "KeyPairGeneratorSpi$ECMQV");
+ // }
// END android-removed
provider.addAlgorithm("KeyFactory.EC", PREFIX + "KeyFactorySpi$EC");
@@ -55,7 +144,6 @@ public class EC
// provider.addAlgorithm("KeyFactory.ECDSA", PREFIX + "KeyFactorySpi$ECDSA");
// provider.addAlgorithm("KeyFactory.ECDH", PREFIX + "KeyFactorySpi$ECDH");
// provider.addAlgorithm("KeyFactory.ECDHC", PREFIX + "KeyFactorySpi$ECDHC");
- // provider.addAlgorithm("KeyFactory.ECMQV", PREFIX + "KeyFactorySpi$ECMQV");
// END android-removed
provider.addAlgorithm("KeyPairGenerator.EC", PREFIX + "KeyPairGeneratorSpi$EC");
@@ -65,7 +153,6 @@ public class EC
// provider.addAlgorithm("KeyPairGenerator.ECDHWITHSHA1KDF", PREFIX + "KeyPairGeneratorSpi$ECDH");
// provider.addAlgorithm("KeyPairGenerator.ECDHC", PREFIX + "KeyPairGeneratorSpi$ECDHC");
// provider.addAlgorithm("KeyPairGenerator.ECIES", PREFIX + "KeyPairGeneratorSpi$ECDH");
- // provider.addAlgorithm("KeyPairGenerator.ECMQV", PREFIX + "KeyPairGeneratorSpi$ECMQV");
//
// provider.addAlgorithm("Cipher.ECIES", PREFIX + "IESCipher$ECIES");
// provider.addAlgorithm("Cipher.ECIESwithAES", PREFIX + "IESCipher$ECIESwithAES");
@@ -76,6 +163,16 @@ public class EC
// provider.addAlgorithm("Cipher.ECIESWITHAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC");
// provider.addAlgorithm("Cipher.ECIESwithDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC");
// provider.addAlgorithm("Cipher.ECIESWITHDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC");
+ //
+ // provider.addAlgorithm("Cipher.OldECIES", PREFIX + "IESCipher$OldECIES");
+ // provider.addAlgorithm("Cipher.OldECIESwithAES", PREFIX + "IESCipher$OldECIESwithAES");
+ // provider.addAlgorithm("Cipher.OldECIESWITHAES", PREFIX + "IESCipher$OldECIESwithAES");
+ // provider.addAlgorithm("Cipher.OldECIESwithDESEDE", PREFIX + "IESCipher$OldECIESwithDESede");
+ // provider.addAlgorithm("Cipher.OldECIESWITHDESEDE", PREFIX + "IESCipher$OldECIESwithDESede");
+ // provider.addAlgorithm("Cipher.OldECIESwithAES-CBC", PREFIX + "IESCipher$OldECIESwithAESCBC");
+ // provider.addAlgorithm("Cipher.OldECIESWITHAES-CBC", PREFIX + "IESCipher$OldECIESwithAESCBC");
+ // provider.addAlgorithm("Cipher.OldECIESwithDESEDE-CBC", PREFIX + "IESCipher$OldECIESwithDESedeCBC");
+ // provider.addAlgorithm("Cipher.OldECIESWITHDESEDE-CBC", PREFIX + "IESCipher$OldECIESwithDESedeCBC");
// END android-removed
provider.addAlgorithm("Signature.ECDSA", PREFIX + "SignatureSpi$ecDSA");
@@ -91,12 +188,19 @@ public class EC
// BEGIN android-removed
// provider.addAlgorithm("Alg.Alias.Signature." + TeleTrusTObjectIdentifiers.ecSignWithSha1, "ECDSA");
//
- // provider.addAlgorithm("Signature.DETECDSA", PREFIX + "SignatureSpi$ecDetDSA");
- // provider.addAlgorithm("Signature.SHA1WITHDETECDSA", PREFIX + "SignatureSpi$ecDetDSA");
- // provider.addAlgorithm("Signature.SHA224WITHDETECDSA", PREFIX + "SignatureSpi$ecDetDSA224");
- // provider.addAlgorithm("Signature.SHA256WITHDETECDSA", PREFIX + "SignatureSpi$ecDetDSA256");
- // provider.addAlgorithm("Signature.SHA384WITHDETECDSA", PREFIX + "SignatureSpi$ecDetDSA384");
- // provider.addAlgorithm("Signature.SHA512WITHDETECDSA", PREFIX + "SignatureSpi$ecDetDSA512");
+ // provider.addAlgorithm("Signature.ECDDSA", PREFIX + "SignatureSpi$ecDetDSA");
+ // provider.addAlgorithm("Signature.SHA1WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA");
+ // provider.addAlgorithm("Signature.SHA224WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA224");
+ // provider.addAlgorithm("Signature.SHA256WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA256");
+ // provider.addAlgorithm("Signature.SHA384WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA384");
+ // provider.addAlgorithm("Signature.SHA512WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA512");
+ //
+ // provider.addAlgorithm("Alg.Alias.Signature.DETECDSA", "ECDDSA");
+ // provider.addAlgorithm("Alg.Alias.Signature.SHA1WITHDETECDSA", "SHA1WITHECDDSA");
+ // provider.addAlgorithm("Alg.Alias.Signature.SHA224WITHDETECDSA", "SHA224WITHECDDSA");
+ // provider.addAlgorithm("Alg.Alias.Signature.SHA256WITHDETECDSA", "SHA256WITHECDDSA");
+ // provider.addAlgorithm("Alg.Alias.Signature.SHA384WITHDETECDSA", "SHA384WITHECDDSA");
+ // provider.addAlgorithm("Alg.Alias.Signature.SHA512WITHDETECDSA", "SHA512WITHECDDSA");
// END android-removed
addSignatureAlgorithm(provider, "SHA224", "ECDSA", PREFIX + "SignatureSpi$ecDSA224", X9ObjectIdentifiers.ecdsa_with_SHA224);
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 37ca5139..5098c33d 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
@@ -53,12 +53,12 @@ public class RSA
// END android-changed
// BEGIN android-removed
// provider.addAlgorithm("Cipher.RSA/PKCS1", PREFIX + "CipherSpi$PKCS1v1_5Padding");
- // provider.addAlgorithm("Cipher.1.2.840.113549.1.1.1", PREFIX + "CipherSpi$PKCS1v1_5Padding");
- // provider.addAlgorithm("Cipher.2.5.8.1.1", PREFIX + "CipherSpi$PKCS1v1_5Padding");
+ // provider.addAlgorithm("Cipher", PKCSObjectIdentifiers.rsaEncryption, PREFIX + "CipherSpi$PKCS1v1_5Padding");
+ // provider.addAlgorithm("Cipher", X509ObjectIdentifiers.id_ea_rsa, PREFIX + "CipherSpi$PKCS1v1_5Padding");
// provider.addAlgorithm("Cipher.RSA/1", PREFIX + "CipherSpi$PKCS1v1_5Padding_PrivateOnly");
// provider.addAlgorithm("Cipher.RSA/2", PREFIX + "CipherSpi$PKCS1v1_5Padding_PublicOnly");
// provider.addAlgorithm("Cipher.RSA/OAEP", PREFIX + "CipherSpi$OAEPPadding");
- // provider.addAlgorithm("Cipher." + PKCSObjectIdentifiers.id_RSAES_OAEP, PREFIX + "CipherSpi$OAEPPadding");
+ // provider.addAlgorithm("Cipher", PKCSObjectIdentifiers.id_RSAES_OAEP, PREFIX + "CipherSpi$OAEPPadding");
// provider.addAlgorithm("Cipher.RSA/ISO9796-1", PREFIX + "CipherSpi$ISO9796d1Padding");
// END android-removed
@@ -86,20 +86,10 @@ public class RSA
// registerOidAlgorithmParameters(provider, PKCSObjectIdentifiers.id_RSAES_OAEP, "OAEP");
// registerOidAlgorithmParameters(provider, PKCSObjectIdentifiers.id_RSASSA_PSS, "PSS");
//
- //
// provider.addAlgorithm("Signature.RSASSA-PSS", PREFIX + "PSSSignatureSpi$PSSwithRSA");
// provider.addAlgorithm("Signature." + PKCSObjectIdentifiers.id_RSASSA_PSS, PREFIX + "PSSSignatureSpi$PSSwithRSA");
// provider.addAlgorithm("Signature.OID." + PKCSObjectIdentifiers.id_RSASSA_PSS, PREFIX + "PSSSignatureSpi$PSSwithRSA");
//
- // provider.addAlgorithm("Signature.SHA224WITHRSAANDMGF1", PREFIX + "PSSSignatureSpi$SHA224withRSA");
- // provider.addAlgorithm("Signature.SHA256WITHRSAANDMGF1", PREFIX + "PSSSignatureSpi$SHA256withRSA");
- // provider.addAlgorithm("Signature.SHA384WITHRSAANDMGF1", PREFIX + "PSSSignatureSpi$SHA384withRSA");
- // provider.addAlgorithm("Signature.SHA512WITHRSAANDMGF1", PREFIX + "PSSSignatureSpi$SHA512withRSA");
- // provider.addAlgorithm("Signature.SHA224withRSA/PSS", PREFIX + "PSSSignatureSpi$SHA224withRSA");
- // provider.addAlgorithm("Signature.SHA256withRSA/PSS", PREFIX + "PSSSignatureSpi$SHA256withRSA");
- // provider.addAlgorithm("Signature.SHA384withRSA/PSS", PREFIX + "PSSSignatureSpi$SHA384withRSA");
- // provider.addAlgorithm("Signature.SHA512withRSA/PSS", PREFIX + "PSSSignatureSpi$SHA512withRSA");
- //
// provider.addAlgorithm("Signature.RSA", PREFIX + "DigestSignatureSpi$noneRSA");
// provider.addAlgorithm("Signature.RAWRSASSA-PSS", PREFIX + "PSSSignatureSpi$nonePSS");
//
@@ -111,11 +101,12 @@ public class RSA
// provider.addAlgorithm("Alg.Alias.Signature.NONEWITHRSAANDMGF1", "RAWRSASSA-PSS");
// provider.addAlgorithm("Alg.Alias.Signature.RSAPSS", "RSASSA-PSS");
//
- //
- // provider.addAlgorithm("Alg.Alias.Signature.SHA224withRSAandMGF1", "SHA224withRSA/PSS");
- // provider.addAlgorithm("Alg.Alias.Signature.SHA256withRSAandMGF1", "SHA256withRSA/PSS");
- // provider.addAlgorithm("Alg.Alias.Signature.SHA384withRSAandMGF1", "SHA384withRSA/PSS");
- // provider.addAlgorithm("Alg.Alias.Signature.SHA512withRSAandMGF1", "SHA512withRSA/PSS");
+ // addPSSSignature(provider, "SHA224", PREFIX + "PSSSignatureSpi$SHA224withRSA");
+ // addPSSSignature(provider, "SHA256", PREFIX + "PSSSignatureSpi$SHA256withRSA");
+ // addPSSSignature(provider, "SHA384", PREFIX + "PSSSignatureSpi$SHA384withRSA");
+ // addPSSSignature(provider, "SHA512", PREFIX + "PSSSignatureSpi$SHA512withRSA");
+ // addPSSSignature(provider, "SHA512(224)", PREFIX + "PSSSignatureSpi$SHA512_224withRSA");
+ // addPSSSignature(provider, "SHA512(256)", PREFIX + "PSSSignatureSpi$SHA512_256withRSA");
//
// if (provider.hasAlgorithm("MessageDigest", "MD2"))
// {
@@ -131,9 +122,8 @@ public class RSA
if (provider.hasAlgorithm("MessageDigest", "MD5"))
{
addDigestSignature(provider, "MD5", PREFIX + "DigestSignatureSpi$MD5", PKCSObjectIdentifiers.md5WithRSAEncryption);
- // END android-removed
- // provider.addAlgorithm("Signature.MD5withRSA/ISO9796-2", PREFIX + "ISOSignatureSpi$MD5WithRSAEncryption");
- // provider.addAlgorithm("Alg.Alias.Signature.MD5WithRSA/ISO9796-2", "MD5withRSA/ISO9796-2");
+ // BEGIN android-removed
+ // addISO9796Signature(provider, "MD5", PREFIX + "ISOSignatureSpi$MD5WithRSAEncryption");
// END android-removed
}
@@ -142,24 +132,19 @@ public class RSA
// BEGIN android-removed
// provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA1withRSA/PSS", "PSS");
// provider.addAlgorithm("Alg.Alias.AlgorithmParameters.SHA1WITHRSAANDMGF1", "PSS");
- // provider.addAlgorithm("Signature.SHA1withRSA/PSS", PREFIX + "PSSSignatureSpi$SHA1withRSA");
- // provider.addAlgorithm("Alg.Alias.Signature.SHA1withRSAandMGF1", "SHA1withRSA/PSS");
- // provider.addAlgorithm("Alg.Alias.Signature.SHA1WITHRSAANDMGF1", "SHA1withRSA/PSS");
+ //
+ // addPSSSignature(provider, "SHA1", PREFIX + "PSSSignatureSpi$SHA1withRSA");
// END android-removed
-
addDigestSignature(provider, "SHA1", PREFIX + "DigestSignatureSpi$SHA1", PKCSObjectIdentifiers.sha1WithRSAEncryption);
-
// BEGIN android-removed
- // provider.addAlgorithm("Alg.Alias.Signature.SHA1WithRSA/ISO9796-2", "SHA1withRSA/ISO9796-2");
- // provider.addAlgorithm("Signature.SHA1withRSA/ISO9796-2", PREFIX + "ISOSignatureSpi$SHA1WithRSAEncryption");
+ // addISO9796Signature(provider, "SHA1", PREFIX + "ISOSignatureSpi$SHA1WithRSAEncryption");
// END android-removed
+
provider.addAlgorithm("Alg.Alias.Signature." + OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA");
provider.addAlgorithm("Alg.Alias.Signature.OID." + OIWObjectIdentifiers.sha1WithRSA, "SHA1WITHRSA");
// BEGIN android-removed
- // provider.addAlgorithm("Alg.Alias.Signature.SHA1withRSA/X9.31", "SHA1WITHRSA/X9.31");
- // provider.addAlgorithm("Alg.Alias.Signature.SHA1WithRSA/X9.31", "SHA1WITHRSA/X9.31");
- // provider.addAlgorithm("Signature.SHA1WITHRSA/X9.31", PREFIX + "X931SignatureSpi$SHA1WithRSAEncryption");
+ // addX931Signature(provider, "SHA1", PREFIX + "X931SignatureSpi$SHA1WithRSAEncryption");
// END android-removed
}
@@ -169,18 +154,22 @@ public class RSA
addDigestSignature(provider, "SHA512", PREFIX + "DigestSignatureSpi$SHA512", PKCSObjectIdentifiers.sha512WithRSAEncryption);
// BEGIN android-removed
- // provider.addAlgorithm("Alg.Alias.Signature.SHA224withRSA/X9.31", "SHA224WITHRSA/X9.31");
- // provider.addAlgorithm("Alg.Alias.Signature.SHA224WithRSA/X9.31", "SHA224WITHRSA/X9.31");
- // provider.addAlgorithm("Signature.SHA224WITHRSA/X9.31", PREFIX + "X931SignatureSpi$SHA224WithRSAEncryption");
- // provider.addAlgorithm("Alg.Alias.Signature.SHA256withRSA/X9.31", "SHA256WITHRSA/X9.31");
- // provider.addAlgorithm("Alg.Alias.Signature.SHA256WithRSA/X9.31", "SHA256WITHRSA/X9.31");
- // provider.addAlgorithm("Signature.SHA256WITHRSA/X9.31", PREFIX + "X931SignatureSpi$SHA256WithRSAEncryption");
- // provider.addAlgorithm("Alg.Alias.Signature.SHA384withRSA/X9.31", "SHA384WITHRSA/X9.31");
- // provider.addAlgorithm("Alg.Alias.Signature.SHA384WithRSA/X9.31", "SHA384WITHRSA/X9.31");
- // provider.addAlgorithm("Signature.SHA384WITHRSA/X9.31", PREFIX + "X931SignatureSpi$SHA384WithRSAEncryption");
- // provider.addAlgorithm("Alg.Alias.Signature.SHA512withRSA/X9.31", "SHA512WITHRSA/X9.31");
- // provider.addAlgorithm("Alg.Alias.Signature.SHA512WithRSA/X9.31", "SHA512WITHRSA/X9.31");
- // provider.addAlgorithm("Signature.SHA512WITHRSA/X9.31", PREFIX + "X931SignatureSpi$SHA512WithRSAEncryption");
+ // addDigestSignature(provider, "SHA512(224)", PREFIX + "DigestSignatureSpi$SHA512_224", null);
+ // addDigestSignature(provider, "SHA512(256)", PREFIX + "DigestSignatureSpi$SHA512_256", null);
+
+ // addISO9796Signature(provider, "SHA224", PREFIX + "ISOSignatureSpi$SHA224WithRSAEncryption");
+ // addISO9796Signature(provider, "SHA256", PREFIX + "ISOSignatureSpi$SHA256WithRSAEncryption");
+ // addISO9796Signature(provider, "SHA384", PREFIX + "ISOSignatureSpi$SHA384WithRSAEncryption");
+ // addISO9796Signature(provider, "SHA512", PREFIX + "ISOSignatureSpi$SHA512WithRSAEncryption");
+ // addISO9796Signature(provider, "SHA512(224)", PREFIX + "ISOSignatureSpi$SHA512_224WithRSAEncryption");
+ // addISO9796Signature(provider, "SHA512(256)", PREFIX + "ISOSignatureSpi$SHA512_256WithRSAEncryption");
+ //
+ // addX931Signature(provider, "SHA224", PREFIX + "X931SignatureSpi$SHA224WithRSAEncryption");
+ // addX931Signature(provider, "SHA256", PREFIX + "X931SignatureSpi$SHA256WithRSAEncryption");
+ // addX931Signature(provider, "SHA384", PREFIX + "X931SignatureSpi$SHA384WithRSAEncryption");
+ // addX931Signature(provider, "SHA512", PREFIX + "X931SignatureSpi$SHA512WithRSAEncryption");
+ // addX931Signature(provider, "SHA512(224)", PREFIX + "X931SignatureSpi$SHA512_224WithRSAEncryption");
+ // addX931Signature(provider, "SHA512(256)", PREFIX + "X931SignatureSpi$SHA512_256WithRSAEncryption");
//
// if (provider.hasAlgorithm("MessageDigest", "RIPEMD128"))
// {
@@ -246,5 +235,37 @@ public class RSA
provider.addAlgorithm("Alg.Alias.Signature.OID." + oid, mainName);
}
}
+
+ private void addISO9796Signature(
+ ConfigurableProvider provider,
+ String digest,
+ String className)
+ {
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSA/ISO9796-2", digest + "WITHRSA/ISO9796-2");
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSA/ISO9796-2", digest + "WITHRSA/ISO9796-2");
+ provider.addAlgorithm("Signature." + digest + "WITHRSA/ISO9796-2", className);
+ }
+
+ private void addPSSSignature(
+ ConfigurableProvider provider,
+ String digest,
+ String className)
+ {
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSA/PSS", digest + "WITHRSAANDMGF1");
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSA/PSS", digest + "WITHRSAANDMGF1");
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSAandMGF1", digest + "WITHRSAANDMGF1");
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSAAndMGF1", digest + "WITHRSAANDMGF1");
+ provider.addAlgorithm("Signature." + digest + "WITHRSAANDMGF1", className);
+ }
+
+ private void addX931Signature(
+ ConfigurableProvider provider,
+ String digest,
+ String className)
+ {
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "withRSA/X9.31", digest + "WITHRSA/X9.31");
+ provider.addAlgorithm("Alg.Alias.Signature." + digest + "WithRSA/X9.31", digest + "WITHRSA/X9.31");
+ provider.addAlgorithm("Signature." + digest + "WITHRSA/X9.31", className);
+ }
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParametersSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParametersSpi.java
index c7711238..608171bf 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParametersSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/AlgorithmParametersSpi.java
@@ -73,7 +73,7 @@ public class AlgorithmParametersSpi
Class paramSpec)
throws InvalidParameterSpecException
{
- if (paramSpec == DHParameterSpec.class)
+ if (paramSpec == DHParameterSpec.class || paramSpec == AlgorithmParameterSpec.class)
{
return currentSpec;
}
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 d5516dce..6fb54b67 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
@@ -20,6 +20,7 @@ import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x9.DHDomainParameters;
+import org.bouncycastle.asn1.x9.DomainParameters;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.crypto.params.DHPrivateKeyParameters;
import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
@@ -82,9 +83,9 @@ public class BCDHPrivateKey
}
else if (id.equals(X9ObjectIdentifiers.dhpublicnumber))
{
- DHDomainParameters params = DHDomainParameters.getInstance(seq);
+ DomainParameters params = DomainParameters.getInstance(seq);
- this.dhSpec = new DHParameterSpec(params.getP().getValue(), params.getG().getValue());
+ this.dhSpec = new DHParameterSpec(params.getP(), params.getG());
}
else
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java
index 0697f757..ef743095 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
@@ -17,6 +17,7 @@ import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x9.DHDomainParameters;
+import org.bouncycastle.asn1.x9.DomainParameters;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.crypto.params.DHPublicKeyParameters;
import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
@@ -96,9 +97,9 @@ public class BCDHPublicKey
}
else if (id.equals(X9ObjectIdentifiers.dhpublicnumber))
{
- DHDomainParameters params = DHDomainParameters.getInstance(seq);
+ DomainParameters params = DomainParameters.getInstance(seq);
- this.dhSpec = new DHParameterSpec(params.getP().getValue(), params.getG().getValue());
+ this.dhSpec = new DHParameterSpec(params.getP(), params.getG());
}
else
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java
index f2b5314f..3de8ffe5 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java
@@ -4,9 +4,9 @@ import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
+import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
-import java.util.Hashtable;
import javax.crypto.SecretKey;
import javax.crypto.ShortBufferException;
@@ -15,9 +15,13 @@ import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import javax.crypto.spec.SecretKeySpec;
-import org.bouncycastle.crypto.params.DESParameters;
-import org.bouncycastle.util.Integers;
-import org.bouncycastle.util.Strings;
+import org.bouncycastle.crypto.DerivationFunction;
+// BEGIN android-removed
+// import org.bouncycastle.crypto.agreement.kdf.DHKEKGenerator;
+// END android-removed
+import org.bouncycastle.crypto.digests.SHA1Digest;
+import org.bouncycastle.jcajce.provider.asymmetric.util.BaseAgreementSpi;
+import org.bouncycastle.jcajce.spec.UserKeyingMaterialSpec;
/**
* Diffie-Hellman key agreement. There's actually a better way of doing this
@@ -25,29 +29,25 @@ import org.bouncycastle.util.Strings;
* details.
*/
public class KeyAgreementSpi
- extends javax.crypto.KeyAgreementSpi
+ extends BaseAgreementSpi
{
private BigInteger x;
private BigInteger p;
private BigInteger g;
- private BigInteger result;
- private static final Hashtable algorithms = new Hashtable();
+ public KeyAgreementSpi()
+ {
+ super("Diffie-Hellman", null);
+ }
- static
+ public KeyAgreementSpi(
+ String kaAlgorithm,
+ DerivationFunction kdf)
{
- Integer i64 = Integers.valueOf(64);
- Integer i192 = Integers.valueOf(192);
- Integer i128 = Integers.valueOf(128);
- Integer i256 = Integers.valueOf(256);
-
- algorithms.put("DES", i64);
- algorithms.put("DESEDE", i192);
- algorithms.put("BLOWFISH", i128);
- algorithms.put("AES", i256);
+ super(kaAlgorithm, kdf);
}
- private byte[] bigIntToBytes(
+ protected byte[] bigIntToBytes(
BigInteger r)
{
//
@@ -122,7 +122,7 @@ public class KeyAgreementSpi
throw new IllegalStateException("Diffie-Hellman not initialised.");
}
- return bigIntToBytes(result);
+ return super.engineGenerateSecret();
}
protected int engineGenerateSecret(
@@ -135,45 +135,27 @@ public class KeyAgreementSpi
throw new IllegalStateException("Diffie-Hellman not initialised.");
}
- byte[] secret = bigIntToBytes(result);
-
- if (sharedSecret.length - offset < secret.length)
- {
- throw new ShortBufferException("DHKeyAgreement - buffer too short");
- }
-
- System.arraycopy(secret, 0, sharedSecret, offset, secret.length);
-
- return secret.length;
+ return super.engineGenerateSecret(sharedSecret, offset);
}
protected SecretKey engineGenerateSecret(
- String algorithm)
+ String algorithm)
+ throws NoSuchAlgorithmException
{
if (x == null)
{
throw new IllegalStateException("Diffie-Hellman not initialised.");
}
- String algKey = Strings.toUpperCase(algorithm);
byte[] res = bigIntToBytes(result);
- if (algorithms.containsKey(algKey))
+ // for JSSE compatibility
+ if (algorithm.equals("TlsPremasterSecret"))
{
- Integer length = (Integer)algorithms.get(algKey);
-
- byte[] key = new byte[length.intValue() / 8];
- System.arraycopy(res, 0, key, 0, key.length);
-
- if (algKey.startsWith("DES"))
- {
- DESParameters.setOddParity(key);
- }
-
- return new SecretKeySpec(key, algorithm);
+ return new SecretKeySpec(trimZeroes(res), algorithm);
}
- return new SecretKeySpec(res, algorithm);
+ return super.engineGenerateSecret(algorithm);
}
protected void engineInit(
@@ -190,14 +172,23 @@ public class KeyAgreementSpi
if (params != null)
{
- if (!(params instanceof DHParameterSpec))
+ if (params instanceof DHParameterSpec) // p, g override.
+ {
+ DHParameterSpec p = (DHParameterSpec)params;
+
+ this.p = p.getP();
+ this.g = p.getG();
+ }
+ else if (params instanceof UserKeyingMaterialSpec)
+ {
+ this.p = privKey.getParams().getP();
+ this.g = privKey.getParams().getG();
+ this.ukmParameters = ((UserKeyingMaterialSpec)params).getUserKeyingMaterial();
+ }
+ else
{
throw new InvalidAlgorithmParameterException("DHKeyAgreement only accepts DHParameterSpec");
}
- DHParameterSpec p = (DHParameterSpec)params;
-
- this.p = p.getP();
- this.g = p.getG();
}
else
{
@@ -224,4 +215,15 @@ public class KeyAgreementSpi
this.g = privKey.getParams().getG();
this.x = this.result = privKey.getX();
}
+
+ // BEGIN android-removed
+ // public static class DHwithRFC2631KDF
+ // extends KeyAgreementSpi
+ // {
+ // public DHwithRFC2631KDF()
+ // {
+ // super("DHwithRFC2631KDF", new DHKEKGenerator(new SHA1Digest()));
+ // }
+ // }
+ // END android-removed
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParametersSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParametersSpi.java
index 57224797..c6aac7c0 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParametersSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/AlgorithmParametersSpi.java
@@ -69,7 +69,7 @@ public class AlgorithmParametersSpi
Class paramSpec)
throws InvalidParameterSpecException
{
- if (paramSpec == DSAParameterSpec.class)
+ if (paramSpec == DSAParameterSpec.class || paramSpec == AlgorithmParameterSpec.class)
{
return currentSpec;
}
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 e66330b3..3a7b3121 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
@@ -18,6 +18,7 @@ import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.crypto.params.DSAPublicKeyParameters;
import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
+import org.bouncycastle.util.Strings;
public class BCDSAPublicKey
implements DSAPublicKey
@@ -119,7 +120,7 @@ public class BCDSAPublicKey
public String toString()
{
StringBuffer buf = new StringBuffer();
- String nl = System.getProperty("line.separator");
+ String nl = Strings.lineSeparator();
buf.append("DSA Public Key").append(nl);
buf.append(" y: ").append(this.getY().toString(16)).append(nl);
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
new file mode 100644
index 00000000..6af71e80
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
@@ -0,0 +1,167 @@
+package org.bouncycastle.jcajce.provider.asymmetric.ec;
+
+import java.io.IOException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+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.jcajce.provider.asymmetric.util.EC5Util;
+import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.math.ec.ECCurve;
+
+public class AlgorithmParametersSpi
+ extends java.security.AlgorithmParametersSpi
+{
+ private ECParameterSpec ecParameterSpec;
+ private String curveName;
+
+ protected boolean isASN1FormatString(String format)
+ {
+ return format == null || format.equals("ASN.1");
+ }
+
+ @Override
+ protected void engineInit(AlgorithmParameterSpec algorithmParameterSpec)
+ throws InvalidParameterSpecException
+ {
+ if (algorithmParameterSpec instanceof ECGenParameterSpec)
+ {
+ ECGenParameterSpec ecGenParameterSpec = (ECGenParameterSpec)algorithmParameterSpec;
+ X9ECParameters params = ECUtils.getDomainParametersFromGenSpec(ecGenParameterSpec);
+
+ if (params == null)
+ {
+ throw new InvalidParameterSpecException("EC curve name not recognized: " + ecGenParameterSpec.getName());
+ }
+ curveName = ecGenParameterSpec.getName();
+ ecParameterSpec = EC5Util.convertToSpec(params);
+ }
+ else if (algorithmParameterSpec instanceof ECParameterSpec)
+ {
+ curveName = null;
+ ecParameterSpec = (ECParameterSpec)algorithmParameterSpec;
+ }
+ else
+ {
+ throw new InvalidParameterSpecException("AlgorithmParameterSpec class not recognized: " + algorithmParameterSpec.getClass().getName());
+ }
+ }
+
+ @Override
+ protected void engineInit(byte[] bytes)
+ throws IOException
+ {
+ engineInit(bytes, "ASN.1");
+ }
+
+ @Override
+ protected void engineInit(byte[] bytes, String format)
+ throws IOException
+ {
+ if (isASN1FormatString(format))
+ {
+ X962Parameters params = X962Parameters.getInstance(bytes);
+
+ ECCurve curve = EC5Util.getCurve(BouncyCastleProvider.CONFIGURATION, params);
+
+ if (params.isNamedCurve())
+ {
+ curveName = ECNamedCurveTable.getName(ASN1ObjectIdentifier.getInstance(params.getParameters()));
+ }
+
+ ecParameterSpec = EC5Util.convertToSpec(params, curve);
+ }
+ else
+ {
+ throw new IOException("Unknown encoded parameters format in AlgorithmParameters object: " + format);
+ }
+ }
+
+ @Override
+ protected <T extends AlgorithmParameterSpec> T engineGetParameterSpec(Class<T> paramSpec)
+ throws InvalidParameterSpecException
+ {
+ if (ECParameterSpec.class.isAssignableFrom(paramSpec) || paramSpec == AlgorithmParameterSpec.class)
+ {
+ return (T)ecParameterSpec;
+ }
+ else if (ECGenParameterSpec.class.isAssignableFrom(paramSpec))
+ {
+ if (curveName != null)
+ {
+ ASN1ObjectIdentifier namedCurveOid = ECUtil.getNamedCurveOid(curveName);
+
+ if (namedCurveOid != null)
+ {
+ return (T)new ECGenParameterSpec(namedCurveOid.getId());
+ }
+ return (T)new ECGenParameterSpec(curveName);
+ }
+ else
+ {
+ ASN1ObjectIdentifier namedCurveOid = ECUtil.getNamedCurveOid(EC5Util.convertSpec(ecParameterSpec, false));
+
+ if (namedCurveOid != null)
+ {
+ return (T)new ECGenParameterSpec(namedCurveOid.getId());
+ }
+ }
+ }
+ throw new InvalidParameterSpecException("EC AlgorithmParameters cannot convert to " + paramSpec.getName());
+ }
+
+ @Override
+ protected byte[] engineGetEncoded()
+ throws IOException
+ {
+ return engineGetEncoded("ASN.1");
+ }
+
+ @Override
+ protected byte[] engineGetEncoded(String format)
+ throws IOException
+ {
+ if (isASN1FormatString(format))
+ {
+ X962Parameters params;
+
+ if (ecParameterSpec == null) // implicitly CA
+ {
+ params = new X962Parameters(DERNull.INSTANCE);
+ }
+ else if (curveName != null)
+ {
+ params = new X962Parameters(ECUtil.getNamedCurveOid(curveName));
+ }
+ else
+ {
+ org.bouncycastle.jce.spec.ECParameterSpec ecSpec = EC5Util.convertSpec(ecParameterSpec, false);
+ X9ECParameters ecP = new X9ECParameters(
+ ecSpec.getCurve(),
+ ecSpec.getG(),
+ ecSpec.getN(),
+ ecSpec.getH(),
+ ecSpec.getSeed());
+
+ params = new X962Parameters(ecP);
+ }
+
+ return params.getEncoded();
+ }
+
+ throw new IOException("Unknown parameters format in AlgorithmParameters object: " + format);
+ }
+
+ @Override
+ protected String engineToString()
+ {
+ return "EC AlgorithmParameters ";
+ }
+}
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 c9ad4455..e69942a2 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
@@ -35,6 +35,7 @@ import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECNamedCurveSpec;
import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.util.Strings;
public class BCECPrivateKey
implements ECPrivateKey, org.bouncycastle.jce.interfaces.ECPrivateKey, PKCS12BagAttributeCarrier, ECPointEncoder
@@ -210,38 +211,8 @@ public class BCECPrivateKey
{
X962Parameters params = X962Parameters.getInstance(info.getPrivateKeyAlgorithm().getParameters());
- if (params.isNamedCurve())
- {
- ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters());
- X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid);
- EllipticCurve ellipticCurve = EC5Util.convertCurve(ecP.getCurve(), ecP.getSeed());
-
- ecSpec = new ECNamedCurveSpec(
- ECUtil.getCurveName(oid),
- ellipticCurve,
- new ECPoint(
- ecP.getG().getAffineXCoord().toBigInteger(),
- ecP.getG().getAffineYCoord().toBigInteger()),
- ecP.getN(),
- ecP.getH());
- }
- else if (params.isImplicitlyCA())
- {
- ecSpec = null;
- }
- else
- {
- X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
- EllipticCurve ellipticCurve = EC5Util.convertCurve(ecP.getCurve(), ecP.getSeed());
-
- this.ecSpec = new ECParameterSpec(
- ellipticCurve,
- new ECPoint(
- ecP.getG().getAffineXCoord().toBigInteger(),
- ecP.getG().getAffineYCoord().toBigInteger()),
- ecP.getN(),
- ecP.getH().intValue());
- }
+ ECCurve curve = EC5Util.getCurve(configuration, params);
+ ecSpec = EC5Util.convertToSpec(params, curve);
ASN1Encodable privKey = info.parsePrivateKey();
if (privKey instanceof ASN1Integer)
@@ -418,7 +389,7 @@ public class BCECPrivateKey
public String toString()
{
StringBuffer buf = new StringBuffer();
- String nl = System.getProperty("line.separator");
+ String nl = Strings.lineSeparator();
buf.append("EC Private Key").append(nl);
buf.append(" S: ").append(this.d.toString(16)).append(nl);
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 ac0ddf5b..c3f0dd02 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
@@ -34,8 +34,7 @@ import org.bouncycastle.jce.interfaces.ECPointEncoder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
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 BCECPublicKey
implements ECPublicKey, org.bouncycastle.jce.interfaces.ECPublicKey, ECPointEncoder
@@ -202,46 +201,8 @@ public class BCECPublicKey
private void populateFromPubKeyInfo(SubjectPublicKeyInfo info)
{
X962Parameters params = new X962Parameters((ASN1Primitive)info.getAlgorithm().getParameters());
- ECCurve curve;
- EllipticCurve ellipticCurve;
-
- if (params.isNamedCurve())
- {
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
- X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid);
-
- curve = ecP.getCurve();
- ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed());
-
- ecSpec = new ECNamedCurveSpec(
- ECUtil.getCurveName(oid),
- ellipticCurve,
- new ECPoint(
- ecP.getG().getAffineXCoord().toBigInteger(),
- ecP.getG().getAffineYCoord().toBigInteger()),
- ecP.getN(),
- ecP.getH());
- }
- else if (params.isImplicitlyCA())
- {
- ecSpec = null;
- curve = configuration.getEcImplicitlyCa().getCurve();
- }
- else
- {
- X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
-
- curve = ecP.getCurve();
- ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed());
-
- this.ecSpec = new ECParameterSpec(
- ellipticCurve,
- new ECPoint(
- ecP.getG().getAffineXCoord().toBigInteger(),
- ecP.getG().getAffineYCoord().toBigInteger()),
- ecP.getN(),
- ecP.getH().intValue());
- }
+ ECCurve curve = EC5Util.getCurve(configuration, params);
+ ecSpec = EC5Util.convertToSpec(params, curve);
DERBitString bits = info.getPublicKeyData();
byte[] data = bits.getBytes();
@@ -267,6 +228,7 @@ public class BCECPublicKey
}
}
}
+
X9ECPoint derQ = new X9ECPoint(curve, key);
this.q = derQ.getPoint();
@@ -398,7 +360,7 @@ public class BCECPublicKey
public String toString()
{
StringBuffer buf = new StringBuffer();
- String nl = System.getProperty("line.separator");
+ String nl = Strings.lineSeparator();
buf.append("EC Public Key").append(nl);
buf.append(" X: ").append(this.q.getAffineXCoord().toBigInteger().toString(16)).append(nl);
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
new file mode 100644
index 00000000..dc92e0e4
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
@@ -0,0 +1,45 @@
+package org.bouncycastle.jcajce.provider.asymmetric.ec;
+
+import java.security.spec.ECGenParameterSpec;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+
+class ECUtils
+{
+ static X9ECParameters getDomainParametersFromGenSpec(ECGenParameterSpec genSpec)
+ {
+ return getDomainParametersFromName(genSpec.getName());
+ }
+
+ static X9ECParameters getDomainParametersFromName(String curveName)
+ {
+ X9ECParameters domainParameters;
+ try
+ {
+ if (curveName.charAt(0) >= '0' && curveName.charAt(0) <= '2')
+ {
+ ASN1ObjectIdentifier oidID = new ASN1ObjectIdentifier(curveName);
+ domainParameters = ECUtil.getNamedCurveByOid(oidID);
+ }
+ else
+ {
+ if (curveName.indexOf(' ') > 0)
+ {
+ curveName = curveName.substring(curveName.indexOf(' ') + 1);
+ domainParameters = ECUtil.getNamedCurveByName(curveName);
+ }
+ else
+ {
+ domainParameters = ECUtil.getNamedCurveByName(curveName);
+ }
+ }
+ }
+ catch (IllegalArgumentException ex)
+ {
+ domainParameters = ECUtil.getNamedCurveByName(curveName);
+ }
+ return domainParameters;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java
index 754b4cae..004e2873 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java
@@ -4,21 +4,11 @@ import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
-import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
-import java.util.Hashtable;
-import javax.crypto.SecretKey;
-import javax.crypto.ShortBufferException;
-import javax.crypto.spec.SecretKeySpec;
-
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
-import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
-import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x9.X9IntegerConverter;
import org.bouncycastle.crypto.BasicAgreement;
import org.bouncycastle.crypto.CipherParameters;
@@ -27,11 +17,16 @@ import org.bouncycastle.crypto.agreement.ECDHBasicAgreement;
// BEGIN android-removed
// import org.bouncycastle.crypto.agreement.ECDHCBasicAgreement;
// import org.bouncycastle.crypto.agreement.ECMQVBasicAgreement;
-// import org.bouncycastle.crypto.agreement.kdf.DHKDFParameters;
-// import org.bouncycastle.crypto.agreement.kdf.ECDHKEKGenerator;
+// import org.bouncycastle.crypto.agreement.kdf.ConcatenationKDFGenerator;
// END android-removed
import org.bouncycastle.crypto.digests.SHA1Digest;
-import org.bouncycastle.crypto.params.DESParameters;
+import org.bouncycastle.crypto.digests.SHA224Digest;
+import org.bouncycastle.crypto.digests.SHA256Digest;
+import org.bouncycastle.crypto.digests.SHA384Digest;
+import org.bouncycastle.crypto.digests.SHA512Digest;
+// BEGIN android-removed
+// import org.bouncycastle.crypto.generators.KDF2BytesGenerator;
+// END android-removed
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
@@ -39,15 +34,18 @@ import org.bouncycastle.crypto.params.ECPublicKeyParameters;
// import org.bouncycastle.crypto.params.MQVPrivateParameters;
// import org.bouncycastle.crypto.params.MQVPublicParameters;
// END android-removed
+import org.bouncycastle.jcajce.provider.asymmetric.util.BaseAgreementSpi;
import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+// BEGIN android-removed
+// import org.bouncycastle.jcajce.spec.MQVParameterSpec;
+// END android-removed
+import org.bouncycastle.jcajce.spec.UserKeyingMaterialSpec;
import org.bouncycastle.jce.interfaces.ECPrivateKey;
import org.bouncycastle.jce.interfaces.ECPublicKey;
// BEGIN android-removed
// import org.bouncycastle.jce.interfaces.MQVPrivateKey;
// import org.bouncycastle.jce.interfaces.MQVPublicKey;
// END android-removed
-import org.bouncycastle.util.Integers;
-import org.bouncycastle.util.Strings;
/**
* Diffie-Hellman key agreement using elliptic curve keys, ala IEEE P1363
@@ -56,65 +54,34 @@ import org.bouncycastle.util.Strings;
* Also, MQV key agreement per SEC-1
*/
public class KeyAgreementSpi
- extends javax.crypto.KeyAgreementSpi
+ extends BaseAgreementSpi
{
private static final X9IntegerConverter converter = new X9IntegerConverter();
- private static final Hashtable algorithms = new Hashtable();
- private static final Hashtable oids = new Hashtable();
- private static final Hashtable des = new Hashtable();
-
- static
- {
- Integer i64 = Integers.valueOf(64);
- Integer i128 = Integers.valueOf(128);
- Integer i192 = Integers.valueOf(192);
- Integer i256 = Integers.valueOf(256);
-
- algorithms.put(NISTObjectIdentifiers.id_aes128_CBC.getId(), i128);
- algorithms.put(NISTObjectIdentifiers.id_aes192_CBC.getId(), i192);
- algorithms.put(NISTObjectIdentifiers.id_aes256_CBC.getId(), i256);
- algorithms.put(NISTObjectIdentifiers.id_aes128_wrap.getId(), i128);
- algorithms.put(NISTObjectIdentifiers.id_aes192_wrap.getId(), i192);
- algorithms.put(NISTObjectIdentifiers.id_aes256_wrap.getId(), i256);
- algorithms.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId(), i192);
- algorithms.put(PKCSObjectIdentifiers.des_EDE3_CBC.getId(), i192);
- algorithms.put(OIWObjectIdentifiers.desCBC.getId(), i64);
-
- oids.put("DESEDE", PKCSObjectIdentifiers.des_EDE3_CBC);
- oids.put("AES", NISTObjectIdentifiers.id_aes256_CBC);
- oids.put("DES", OIWObjectIdentifiers.desCBC);
-
- des.put("DES", "DES");
- des.put("DESEDE", "DES");
- des.put(OIWObjectIdentifiers.desCBC.getId(), "DES");
- des.put(PKCSObjectIdentifiers.des_EDE3_CBC.getId(), "DES");
- des.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId(), "DES");
- }
private String kaAlgorithm;
- private BigInteger result;
+
private ECDomainParameters parameters;
private BasicAgreement agreement;
+
// BEGIN android-removed
- // private DerivationFunction kdf;
+ // private MQVParameterSpec mqvParameters;
// END android-removed
- private byte[] bigIntToBytes(
- BigInteger r)
- {
- return converter.integerToBytes(r, converter.getByteLength(parameters.getCurve()));
- }
-
protected KeyAgreementSpi(
String kaAlgorithm,
BasicAgreement agreement,
DerivationFunction kdf)
{
+ super(kaAlgorithm, kdf);
+
this.kaAlgorithm = kaAlgorithm;
this.agreement = agreement;
- // BEGIN android-removed
- // this.kdf = kdf;
- // END android-removed
+ }
+
+ protected byte[] bigIntToBytes(
+ BigInteger r)
+ {
+ return converter.integerToBytes(r, converter.getByteLength(parameters.getCurve()));
}
protected Key engineDoPhase(
@@ -138,19 +105,25 @@ public class KeyAgreementSpi
// {
// if (!(key instanceof MQVPublicKey))
// {
- // throw new InvalidKeyException(kaAlgorithm + " key agreement requires "
- // + getSimpleName(MQVPublicKey.class) + " for doPhase");
- // }
+ // ECPublicKeyParameters staticKey = (ECPublicKeyParameters)
+ // ECUtil.generatePublicKeyParameter((PublicKey)key);
+ // ECPublicKeyParameters ephemKey = (ECPublicKeyParameters)
+ // ECUtil.generatePublicKeyParameter(mqvParameters.getOtherPartyEphemeralKey());
//
- // MQVPublicKey mqvPubKey = (MQVPublicKey)key;
- // ECPublicKeyParameters staticKey = (ECPublicKeyParameters)
- // ECUtil.generatePublicKeyParameter(mqvPubKey.getStaticKey());
- // ECPublicKeyParameters ephemKey = (ECPublicKeyParameters)
- // ECUtil.generatePublicKeyParameter(mqvPubKey.getEphemeralKey());
+ // pubKey = new MQVPublicParameters(staticKey, ephemKey);
+ // }
+ // else
+ // {
+ // MQVPublicKey mqvPubKey = (MQVPublicKey)key;
+ // ECPublicKeyParameters staticKey = (ECPublicKeyParameters)
+ // ECUtil.generatePublicKeyParameter(mqvPubKey.getStaticKey());
+ // ECPublicKeyParameters ephemKey = (ECPublicKeyParameters)
+ // ECUtil.generatePublicKeyParameter(mqvPubKey.getEphemeralKey());
//
- // pubKey = new MQVPublicParameters(staticKey, ephemKey);
+ // pubKey = new MQVPublicParameters(staticKey, ephemKey);
//
- // // TODO Validate that all the keys are using the same parameters?
+ // // TODO Validate that all the keys are using the same parameters?
+ // }
// }
// else
// END android-removed
@@ -179,102 +152,20 @@ public class KeyAgreementSpi
return null;
}
- protected byte[] engineGenerateSecret()
- throws IllegalStateException
- {
- // BEGIN android-removed
- // if (kdf != null)
- // {
- // throw new UnsupportedOperationException(
- // "KDF can only be used when algorithm is known");
- // }
- // END android-removed
-
- return bigIntToBytes(result);
- }
-
- protected int engineGenerateSecret(
- byte[] sharedSecret,
- int offset)
- throws IllegalStateException, ShortBufferException
- {
- byte[] secret = engineGenerateSecret();
-
- if (sharedSecret.length - offset < secret.length)
- {
- throw new ShortBufferException(kaAlgorithm + " key agreement: need " + secret.length + " bytes");
- }
-
- System.arraycopy(secret, 0, sharedSecret, offset, secret.length);
-
- return secret.length;
- }
-
- protected SecretKey engineGenerateSecret(
- String algorithm)
- throws NoSuchAlgorithmException
- {
- byte[] secret = bigIntToBytes(result);
- String algKey = Strings.toUpperCase(algorithm);
- String oidAlgorithm = algorithm;
-
- if (oids.containsKey(algKey))
- {
- oidAlgorithm = ((ASN1ObjectIdentifier)oids.get(algKey)).getId();
- }
-
- // BEGIN android-removed
- // if (kdf != null)
- // {
- // if (!algorithms.containsKey(oidAlgorithm))
- // {
- // throw new NoSuchAlgorithmException("unknown algorithm encountered: " + algorithm);
- // }
- //
- // int keySize = ((Integer)algorithms.get(oidAlgorithm)).intValue();
- //
- // DHKDFParameters params = new DHKDFParameters(new ASN1ObjectIdentifier(oidAlgorithm), keySize, secret);
- //
- // byte[] keyBytes = new byte[keySize / 8];
- // kdf.init(params);
- // kdf.generateBytes(keyBytes, 0, keyBytes.length);
- // secret = keyBytes;
- // }
- // else
- // END android-removed
- {
- if (algorithms.containsKey(oidAlgorithm))
- {
- Integer length = (Integer)algorithms.get(oidAlgorithm);
-
- byte[] key = new byte[length.intValue() / 8];
-
- System.arraycopy(secret, 0, key, 0, key.length);
-
- secret = key;
- }
- }
-
- if (des.containsKey(oidAlgorithm))
- {
- DESParameters.setOddParity(secret);
- }
-
- return new SecretKeySpec(secret, algorithm);
- }
-
protected void engineInit(
Key key,
AlgorithmParameterSpec params,
SecureRandom random)
throws InvalidKeyException, InvalidAlgorithmParameterException
{
- if (params != null)
+ // BEGIN android-changed
+ if (params != null && !(params instanceof UserKeyingMaterialSpec))
+ // END android-changed
{
throw new InvalidAlgorithmParameterException("No algorithm parameters supported");
}
- initFromKey(key);
+ initFromKey(key, params);
}
protected void engineInit(
@@ -282,32 +173,57 @@ public class KeyAgreementSpi
SecureRandom random)
throws InvalidKeyException
{
- initFromKey(key);
+ initFromKey(key, null);
}
- private void initFromKey(Key key)
+ private void initFromKey(Key key, AlgorithmParameterSpec parameterSpec)
throws InvalidKeyException
{
// BEGIN android-removed
// if (agreement instanceof ECMQVBasicAgreement)
// {
- // if (!(key instanceof MQVPrivateKey))
+ // mqvParameters = null;
+ // if (!(key instanceof MQVPrivateKey) && !(parameterSpec instanceof MQVParameterSpec))
// {
// throw new InvalidKeyException(kaAlgorithm + " key agreement requires "
- // + getSimpleName(MQVPrivateKey.class) + " for initialisation");
+ // + getSimpleName(MQVParameterSpec.class) + " for initialisation");
// }
//
- // MQVPrivateKey mqvPrivKey = (MQVPrivateKey)key;
- // ECPrivateKeyParameters staticPrivKey = (ECPrivateKeyParameters)
- // ECUtil.generatePrivateKeyParameter(mqvPrivKey.getStaticPrivateKey());
- // ECPrivateKeyParameters ephemPrivKey = (ECPrivateKeyParameters)
- // ECUtil.generatePrivateKeyParameter(mqvPrivKey.getEphemeralPrivateKey());
+ // ECPrivateKeyParameters staticPrivKey;
+ // ECPrivateKeyParameters ephemPrivKey;
+ // ECPublicKeyParameters ephemPubKey;
+ // if (key instanceof MQVPrivateKey)
+ // {
+ // MQVPrivateKey mqvPrivKey = (MQVPrivateKey)key;
+ // staticPrivKey = (ECPrivateKeyParameters)
+ // ECUtil.generatePrivateKeyParameter(mqvPrivKey.getStaticPrivateKey());
+ // ephemPrivKey = (ECPrivateKeyParameters)
+ // ECUtil.generatePrivateKeyParameter(mqvPrivKey.getEphemeralPrivateKey());
//
- // ECPublicKeyParameters ephemPubKey = null;
- // if (mqvPrivKey.getEphemeralPublicKey() != null)
+ // ephemPubKey = null;
+ // if (mqvPrivKey.getEphemeralPublicKey() != null)
+ // {
+ // ephemPubKey = (ECPublicKeyParameters)
+ // ECUtil.generatePublicKeyParameter(mqvPrivKey.getEphemeralPublicKey());
+ // }
+ // }
+ // else
// {
- // ephemPubKey = (ECPublicKeyParameters)
- // ECUtil.generatePublicKeyParameter(mqvPrivKey.getEphemeralPublicKey());
+ // MQVParameterSpec mqvParameterSpec = (MQVParameterSpec)parameterSpec;
+ //
+ // staticPrivKey = (ECPrivateKeyParameters)
+ // ECUtil.generatePrivateKeyParameter((PrivateKey)key);
+ // ephemPrivKey = (ECPrivateKeyParameters)
+ // ECUtil.generatePrivateKeyParameter(mqvParameterSpec.getEphemeralPrivateKey());
+ //
+ // ephemPubKey = null;
+ // if (mqvParameterSpec.getEphemeralPublicKey() != null)
+ // {
+ // ephemPubKey = (ECPublicKeyParameters)
+ // ECUtil.generatePublicKeyParameter(mqvParameterSpec.getEphemeralPublicKey());
+ // }
+ // mqvParameters = mqvParameterSpec;
+ // ukmParameters = mqvParameterSpec.getUserKeyingMaterial();
// }
//
// MQVPrivateParameters localParams = new MQVPrivateParameters(staticPrivKey, ephemPrivKey, ephemPubKey);
@@ -328,7 +244,7 @@ public class KeyAgreementSpi
ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)ECUtil.generatePrivateKeyParameter((PrivateKey)key);
this.parameters = privKey.getParameters();
-
+ ukmParameters = (parameterSpec instanceof UserKeyingMaterialSpec) ? ((UserKeyingMaterialSpec)parameterSpec).getUserKeyingMaterial() : null;
agreement.init(privKey);
}
}
@@ -373,17 +289,223 @@ public class KeyAgreementSpi
// {
// public DHwithSHA1KDF()
// {
- // super("ECDHwithSHA1KDF", new ECDHBasicAgreement(), new ECDHKEKGenerator(new SHA1Digest()));
+ // super("ECDHwithSHA1KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()));
// }
// }
//
- // public static class MQVwithSHA1KDF
+ // public static class DHwithSHA1KDFAndSharedInfo
// extends KeyAgreementSpi
// {
- // public MQVwithSHA1KDF()
+ // public DHwithSHA1KDFAndSharedInfo()
// {
- // super("ECMQVwithSHA1KDF", new ECMQVBasicAgreement(), new ECDHKEKGenerator(new SHA1Digest()));
+ // super("ECDHwithSHA1KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()));
+ // }
+ // }
+ //
+ // public static class CDHwithSHA1KDFAndSharedInfo
+ // extends KeyAgreementSpi
+ // {
+ // public CDHwithSHA1KDFAndSharedInfo()
+ // {
+ // super("ECCDHwithSHA1KDF", new ECDHCBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()));
+ // }
+ // }
+ //
+ // public static class DHwithSHA224KDFAndSharedInfo
+ // extends KeyAgreementSpi
+ // {
+ // public DHwithSHA224KDFAndSharedInfo()
+ // {
+ // super("ECDHwithSHA224KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA224Digest()));
+ // }
+ // }
+ //
+ // public static class CDHwithSHA224KDFAndSharedInfo
+ // extends KeyAgreementSpi
+ // {
+ // public CDHwithSHA224KDFAndSharedInfo()
+ // {
+ // super("ECCDHwithSHA224KDF", new ECDHCBasicAgreement(), new KDF2BytesGenerator(new SHA224Digest()));
+ // }
+ // }
+ //
+ // public static class DHwithSHA256KDFAndSharedInfo
+ // extends KeyAgreementSpi
+ // {
+ // public DHwithSHA256KDFAndSharedInfo()
+ // {
+ // super("ECDHwithSHA256KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA256Digest()));
+ // }
+ // }
+ //
+ // public static class CDHwithSHA256KDFAndSharedInfo
+ // extends KeyAgreementSpi
+ // {
+ // public CDHwithSHA256KDFAndSharedInfo()
+ // {
+ // super("ECCDHwithSHA256KDF", new ECDHCBasicAgreement(), new KDF2BytesGenerator(new SHA256Digest()));
+ // }
+ // }
+ //
+ // public static class DHwithSHA384KDFAndSharedInfo
+ // extends KeyAgreementSpi
+ // {
+ // public DHwithSHA384KDFAndSharedInfo()
+ // {
+ // super("ECDHwithSHA384KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA384Digest()));
+ // }
+ // }
+ //
+ // public static class CDHwithSHA384KDFAndSharedInfo
+ // extends KeyAgreementSpi
+ // {
+ // public CDHwithSHA384KDFAndSharedInfo()
+ // {
+ // super("ECCDHwithSHA384KDF", new ECDHCBasicAgreement(), new KDF2BytesGenerator(new SHA384Digest()));
+ // }
+ // }
+ //
+ // public static class DHwithSHA512KDFAndSharedInfo
+ // extends KeyAgreementSpi
+ // {
+ // public DHwithSHA512KDFAndSharedInfo()
+ // {
+ // super("ECDHwithSHA512KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA512Digest()));
+ // }
+ // }
+ //
+ // public static class CDHwithSHA512KDFAndSharedInfo
+ // extends KeyAgreementSpi
+ // {
+ // public CDHwithSHA512KDFAndSharedInfo()
+ // {
+ // super("ECCDHwithSHA512KDF", new ECDHCBasicAgreement(), new KDF2BytesGenerator(new SHA512Digest()));
+ // }
+ // }
+ //
+ // public static class MQVwithSHA1KDFAndSharedInfo
+ // extends KeyAgreementSpi
+ // {
+ // public MQVwithSHA1KDFAndSharedInfo()
+ // {
+ // super("ECMQVwithSHA1KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()));
+ // }
+ // }
+ //
+ // public static class MQVwithSHA224KDFAndSharedInfo
+ // extends KeyAgreementSpi
+ // {
+ // public MQVwithSHA224KDFAndSharedInfo()
+ // {
+ // super("ECMQVwithSHA224KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(new SHA224Digest()));
+ // }
+ // }
+ //
+ // public static class MQVwithSHA256KDFAndSharedInfo
+ // extends KeyAgreementSpi
+ // {
+ // public MQVwithSHA256KDFAndSharedInfo()
+ // {
+ // super("ECMQVwithSHA256KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(new SHA256Digest()));
+ // }
+ // }
+ //
+ // public static class MQVwithSHA384KDFAndSharedInfo
+ // extends KeyAgreementSpi
+ // {
+ // public MQVwithSHA384KDFAndSharedInfo()
+ // {
+ // super("ECMQVwithSHA384KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(new SHA384Digest()));
+ // }
+ // }
+ //
+ // public static class MQVwithSHA512KDFAndSharedInfo
+ // extends KeyAgreementSpi
+ // {
+ // public MQVwithSHA512KDFAndSharedInfo()
+ // {
+ // super("ECMQVwithSHA512KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(new SHA512Digest()));
+ // }
+ // }
+ //
+ // public static class DHwithSHA1CKDF
+ // extends KeyAgreementSpi
+ // {
+ // public DHwithSHA1CKDF()
+ // {
+ // super("ECDHwithSHA1CKDF", new ECDHCBasicAgreement(), new ConcatenationKDFGenerator(new SHA1Digest()));
+ // }
+ // }
+ //
+ // public static class DHwithSHA256CKDF
+ // extends KeyAgreementSpi
+ // {
+ // public DHwithSHA256CKDF()
+ // {
+ // super("ECDHwithSHA256CKDF", new ECDHCBasicAgreement(), new ConcatenationKDFGenerator(new SHA256Digest()));
+ // }
+ // }
+ //
+ // public static class DHwithSHA384CKDF
+ // extends KeyAgreementSpi
+ // {
+ // public DHwithSHA384CKDF()
+ // {
+ // super("ECDHwithSHA384CKDF", new ECDHCBasicAgreement(), new ConcatenationKDFGenerator(new SHA384Digest()));
+ // }
+ // }
+ //
+ // public static class DHwithSHA512CKDF
+ // extends KeyAgreementSpi
+ // {
+ // public DHwithSHA512CKDF()
+ // {
+ // super("ECDHwithSHA512CKDF", new ECDHCBasicAgreement(), new ConcatenationKDFGenerator(new SHA512Digest()));
+ // }
+ // }
+ //
+ // public static class MQVwithSHA1CKDF
+ // extends KeyAgreementSpi
+ // {
+ // public MQVwithSHA1CKDF()
+ // {
+ // super("ECMQVwithSHA1CKDF", new ECMQVBasicAgreement(), new ConcatenationKDFGenerator(new SHA1Digest()));
+ // }
+ // }
+ //
+ // public static class MQVwithSHA224CKDF
+ // extends KeyAgreementSpi
+ // {
+ // public MQVwithSHA224CKDF()
+ // {
+ // super("ECMQVwithSHA224CKDF", new ECMQVBasicAgreement(), new ConcatenationKDFGenerator(new SHA224Digest()));
+ // }
+ // }
+ //
+ // public static class MQVwithSHA256CKDF
+ // extends KeyAgreementSpi
+ // {
+ // public MQVwithSHA256CKDF()
+ // {
+ // super("ECMQVwithSHA256CKDF", new ECMQVBasicAgreement(), new ConcatenationKDFGenerator(new SHA256Digest()));
+ // }
+ // }
+ //
+ // public static class MQVwithSHA384CKDF
+ // extends KeyAgreementSpi
+ // {
+ // public MQVwithSHA384CKDF()
+ // {
+ // super("ECMQVwithSHA384CKDF", new ECMQVBasicAgreement(), new ConcatenationKDFGenerator(new SHA384Digest()));
+ // }
+ // }
+ //
+ // public static class MQVwithSHA512CKDF
+ // extends KeyAgreementSpi
+ // {
+ // public MQVwithSHA512CKDF()
+ // {
+ // super("ECMQVwithSHA512CKDF", new ECMQVBasicAgreement(), new ConcatenationKDFGenerator(new SHA512Digest()));
// }
// }
- // END android-removed
}
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 d8585187..9a9c46be 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
@@ -212,7 +212,7 @@ public abstract class KeyPairGeneratorSpi
{
// NOTE: Don't bother with custom curves here as the curve will be converted to JCE type shortly
- X9ECParameters p = ECNamedCurveTable.getByName(curveName);
+ X9ECParameters p = ECUtils.getDomainParametersFromName(curveName);
if (p == null)
{
try
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java
index baee6d52..de5a9aa5 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java
@@ -90,7 +90,7 @@ public abstract class AlgorithmParametersSpi
Class paramSpec)
throws InvalidParameterSpecException
{
- if (paramSpec == OAEPParameterSpec.class && currentSpec != null)
+ if (paramSpec == OAEPParameterSpec.class || paramSpec == AlgorithmParameterSpec.class)
{
return currentSpec;
}
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 9b70d74d..d81d1976 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
@@ -12,6 +12,7 @@ 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.util.Strings;
/**
* A provider representation for a RSA private key, with CRT factors included.
@@ -224,7 +225,7 @@ public class BCRSAPrivateCrtKey
public String toString()
{
StringBuffer buf = new StringBuffer();
- String nl = System.getProperty("line.separator");
+ String nl = Strings.lineSeparator();
buf.append("RSA Private CRT Key").append(nl);
buf.append(" modulus: ").append(this.getModulus().toString(16)).append(nl);
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 6f5292ce..669cf2ba 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
@@ -15,6 +15,7 @@ import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.crypto.params.RSAKeyParameters;
import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
+import org.bouncycastle.util.Strings;
public class BCRSAPublicKey
implements RSAPublicKey
@@ -134,7 +135,7 @@ public class BCRSAPublicKey
public String toString()
{
StringBuffer buf = new StringBuffer();
- String nl = System.getProperty("line.separator");
+ String nl = Strings.lineSeparator();
buf.append("RSA Public Key").append(nl);
buf.append(" modulus: ").append(this.getModulus().toString(16)).append(nl);
@@ -153,11 +154,7 @@ public class BCRSAPublicKey
{
algorithmIdentifier = AlgorithmIdentifier.getInstance(in.readObject());
}
- catch (OptionalDataException e)
- {
- algorithmIdentifier = DEFAULT_ALGORITHM_IDENTIFIER;
- }
- catch (EOFException e)
+ catch (Exception e)
{
algorithmIdentifier = DEFAULT_ALGORITHM_IDENTIFIER;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java
index aceb5ee0..81e50132 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java
@@ -37,7 +37,6 @@ import org.bouncycastle.jcajce.provider.asymmetric.util.BaseCipherSpi;
import org.bouncycastle.jcajce.provider.util.DigestFactory;
import org.bouncycastle.jcajce.util.BCJcaJceHelper;
import org.bouncycastle.jcajce.util.JcaJceHelper;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.Strings;
public class CipherSpi
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java
index 123ed415..9616a99b 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java
@@ -25,6 +25,9 @@ import org.bouncycastle.asn1.x509.DigestInfo;
import org.bouncycastle.crypto.AsymmetricBlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.Digest;
+// BEGIN android-added
+import org.bouncycastle.crypto.digests.AndroidDigestFactory;
+// END android-added
// BEGIN android-removed
// import org.bouncycastle.crypto.digests.MD2Digest;
// import org.bouncycastle.crypto.digests.MD4Digest;
@@ -38,10 +41,8 @@ import org.bouncycastle.crypto.Digest;
// import org.bouncycastle.crypto.digests.SHA256Digest;
// import org.bouncycastle.crypto.digests.SHA384Digest;
// import org.bouncycastle.crypto.digests.SHA512Digest;
+// import org.bouncycastle.crypto.digests.SHA512tDigest;
// END android-removed
-// BEGIN android-added
-import org.bouncycastle.crypto.digests.AndroidDigestFactory;
-// END android-added
import org.bouncycastle.crypto.encodings.PKCS1Encoding;
import org.bouncycastle.crypto.engines.RSABlindedEngine;
import org.bouncycastle.util.Arrays;
@@ -312,6 +313,24 @@ public class DigestSignatureSpi
}
// BEGIN android-removed
+ // static public class SHA512_224
+ // extends DigestSignatureSpi
+ // {
+ // public SHA512_224()
+ // {
+ // super(NISTObjectIdentifiers.id_sha512_224, new SHA512tDigest(224), new PKCS1Encoding(new RSABlindedEngine()));
+ // }
+ // }
+
+ // static public class SHA512_256
+ // extends DigestSignatureSpi
+ // {
+ // public SHA512_256()
+ // {
+ // super(NISTObjectIdentifiers.id_sha512_256, new SHA512tDigest(256), new PKCS1Encoding(new RSABlindedEngine()));
+ // }
+ // }
+
// static public class MD2
// extends DigestSignatureSpi
// {
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 f779a66a..88f83a0c 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
@@ -43,7 +43,10 @@ public class KeyPairGeneratorSpi
SecureRandom random)
{
param = new RSAKeyGenerationParameters(defaultPublicExponent,
- random, strength, defaultTests);
+ // BEGIN android-changed
+ // Was: random, strength, defaultTests);
+ (random != null) ? random : new SecureRandom(), strength, defaultTests);
+ // END android-changed
engine.init(param);
}
@@ -61,7 +64,11 @@ public class KeyPairGeneratorSpi
param = new RSAKeyGenerationParameters(
rsaParams.getPublicExponent(),
- random, rsaParams.getKeysize(), defaultTests);
+ // BEGIN android-changed
+ // TODO(27063703): check whether this change is correct
+ // Was: random, rsaParams.getKeysize(), defaultTests);
+ (random != null) ? random : new SecureRandom(), rsaParams.getKeysize(), defaultTests);
+ // END android-changed
engine.init(param);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java
new file mode 100644
index 00000000..16e73481
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java
@@ -0,0 +1,323 @@
+package org.bouncycastle.jcajce.provider.asymmetric.util;
+
+import java.math.BigInteger;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import javax.crypto.KeyAgreementSpi;
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+// BEGIN android-removed
+// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+// import org.bouncycastle.asn1.gnu.GNUObjectIdentifiers;
+// END android-removed
+import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers;
+import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
+import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import org.bouncycastle.asn1.ntt.NTTObjectIdentifiers;
+import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.crypto.DerivationFunction;
+// BEGIN android-removed
+// import org.bouncycastle.crypto.agreement.kdf.DHKDFParameters;
+// import org.bouncycastle.crypto.agreement.kdf.DHKEKGenerator;
+// END android-removed
+import org.bouncycastle.crypto.params.DESParameters;
+import org.bouncycastle.crypto.params.KDFParameters;
+import org.bouncycastle.util.Integers;
+import org.bouncycastle.util.Strings;
+
+public abstract class BaseAgreementSpi
+ extends KeyAgreementSpi
+{
+ private static final Map<String, ASN1ObjectIdentifier> defaultOids = new HashMap<String, ASN1ObjectIdentifier>();
+ private static final Map<String, Integer> keySizes = new HashMap<String, Integer>();
+ private static final Map<String, String> nameTable = new HashMap<String, String>();
+
+ private static final Hashtable oids = new Hashtable();
+ private static final Hashtable des = new Hashtable();
+
+ static
+ {
+ Integer i64 = Integers.valueOf(64);
+ Integer i128 = Integers.valueOf(128);
+ Integer i192 = Integers.valueOf(192);
+ Integer i256 = Integers.valueOf(256);
+
+ keySizes.put("DES", i64);
+ keySizes.put("DESEDE", i192);
+ keySizes.put("BLOWFISH", i128);
+ keySizes.put("AES", i256);
+
+ keySizes.put(NISTObjectIdentifiers.id_aes128_ECB.getId(), i128);
+ keySizes.put(NISTObjectIdentifiers.id_aes192_ECB.getId(), i192);
+ keySizes.put(NISTObjectIdentifiers.id_aes256_ECB.getId(), i256);
+ keySizes.put(NISTObjectIdentifiers.id_aes128_CBC.getId(), i128);
+ keySizes.put(NISTObjectIdentifiers.id_aes192_CBC.getId(), i192);
+ keySizes.put(NISTObjectIdentifiers.id_aes256_CBC.getId(), i256);
+ keySizes.put(NISTObjectIdentifiers.id_aes128_CFB.getId(), i128);
+ keySizes.put(NISTObjectIdentifiers.id_aes192_CFB.getId(), i192);
+ keySizes.put(NISTObjectIdentifiers.id_aes256_CFB.getId(), i256);
+ keySizes.put(NISTObjectIdentifiers.id_aes128_OFB.getId(), i128);
+ keySizes.put(NISTObjectIdentifiers.id_aes192_OFB.getId(), i192);
+ keySizes.put(NISTObjectIdentifiers.id_aes256_OFB.getId(), i256);
+ keySizes.put(NISTObjectIdentifiers.id_aes128_wrap.getId(), i128);
+ keySizes.put(NISTObjectIdentifiers.id_aes192_wrap.getId(), i192);
+ keySizes.put(NISTObjectIdentifiers.id_aes256_wrap.getId(), i256);
+ keySizes.put(NISTObjectIdentifiers.id_aes128_CCM.getId(), i128);
+ keySizes.put(NISTObjectIdentifiers.id_aes192_CCM.getId(), i192);
+ keySizes.put(NISTObjectIdentifiers.id_aes256_CCM.getId(), i256);
+ keySizes.put(NISTObjectIdentifiers.id_aes128_GCM.getId(), i128);
+ keySizes.put(NISTObjectIdentifiers.id_aes192_GCM.getId(), i192);
+ keySizes.put(NISTObjectIdentifiers.id_aes256_GCM.getId(), i256);
+ keySizes.put(NTTObjectIdentifiers.id_camellia128_wrap.getId(), i128);
+ keySizes.put(NTTObjectIdentifiers.id_camellia192_wrap.getId(), i192);
+ keySizes.put(NTTObjectIdentifiers.id_camellia256_wrap.getId(), i256);
+ keySizes.put(KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap.getId(), i128);
+
+ keySizes.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId(), i192);
+ keySizes.put(PKCSObjectIdentifiers.des_EDE3_CBC.getId(), i192);
+ keySizes.put(OIWObjectIdentifiers.desCBC.getId(), i64);
+
+ keySizes.put(PKCSObjectIdentifiers.id_hmacWithSHA1.getId(), Integers.valueOf(160));
+ keySizes.put(PKCSObjectIdentifiers.id_hmacWithSHA256.getId(), i256);
+ keySizes.put(PKCSObjectIdentifiers.id_hmacWithSHA384.getId(), Integers.valueOf(384));
+ keySizes.put(PKCSObjectIdentifiers.id_hmacWithSHA512.getId(), Integers.valueOf(512));
+
+ defaultOids.put("DESEDE", PKCSObjectIdentifiers.des_EDE3_CBC);
+ defaultOids.put("AES", NISTObjectIdentifiers.id_aes256_CBC);
+ defaultOids.put("CAMELLIA", NTTObjectIdentifiers.id_camellia256_cbc);
+ defaultOids.put("SEED", KISAObjectIdentifiers.id_seedCBC);
+ defaultOids.put("DES", OIWObjectIdentifiers.desCBC);
+
+ nameTable.put(MiscObjectIdentifiers.cast5CBC.getId(), "CAST5");
+ nameTable.put(MiscObjectIdentifiers.as_sys_sec_alg_ideaCBC.getId(), "IDEA");
+ nameTable.put(MiscObjectIdentifiers.cryptlib_algorithm_blowfish_ECB.getId(), "Blowfish");
+ nameTable.put(MiscObjectIdentifiers.cryptlib_algorithm_blowfish_CBC.getId(), "Blowfish");
+ nameTable.put(MiscObjectIdentifiers.cryptlib_algorithm_blowfish_CFB.getId(), "Blowfish");
+ nameTable.put(MiscObjectIdentifiers.cryptlib_algorithm_blowfish_OFB.getId(), "Blowfish");
+ nameTable.put(OIWObjectIdentifiers.desECB.getId(), "DES");
+ nameTable.put(OIWObjectIdentifiers.desCBC.getId(), "DES");
+ nameTable.put(OIWObjectIdentifiers.desCFB.getId(), "DES");
+ nameTable.put(OIWObjectIdentifiers.desOFB.getId(), "DES");
+ nameTable.put(OIWObjectIdentifiers.desEDE.getId(), "DESede");
+ nameTable.put(PKCSObjectIdentifiers.des_EDE3_CBC.getId(), "DESede");
+ nameTable.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId(), "DESede");
+ nameTable.put(PKCSObjectIdentifiers.id_alg_CMSRC2wrap.getId(), "RC2");
+ nameTable.put(PKCSObjectIdentifiers.id_hmacWithSHA1.getId(), "HmacSHA1");
+ nameTable.put(PKCSObjectIdentifiers.id_hmacWithSHA224.getId(), "HmacSHA224");
+ nameTable.put(PKCSObjectIdentifiers.id_hmacWithSHA256.getId(), "HmacSHA256");
+ nameTable.put(PKCSObjectIdentifiers.id_hmacWithSHA384.getId(), "HmacSHA384");
+ nameTable.put(PKCSObjectIdentifiers.id_hmacWithSHA512.getId(), "HmacSHA512");
+ nameTable.put(NTTObjectIdentifiers.id_camellia128_cbc.getId(), "Camellia");
+ nameTable.put(NTTObjectIdentifiers.id_camellia192_cbc.getId(), "Camellia");
+ nameTable.put(NTTObjectIdentifiers.id_camellia256_cbc.getId(), "Camellia");
+ nameTable.put(NTTObjectIdentifiers.id_camellia128_wrap.getId(), "Camellia");
+ nameTable.put(NTTObjectIdentifiers.id_camellia192_wrap.getId(), "Camellia");
+ nameTable.put(NTTObjectIdentifiers.id_camellia256_wrap.getId(), "Camellia");
+ nameTable.put(KISAObjectIdentifiers.id_npki_app_cmsSeed_wrap.getId(), "SEED");
+ nameTable.put(KISAObjectIdentifiers.id_seedCBC.getId(), "SEED");
+ nameTable.put(KISAObjectIdentifiers.id_seedMAC.getId(), "SEED");
+ // BEGIN android-removed
+ // nameTable.put(CryptoProObjectIdentifiers.gostR28147_gcfb.getId(), "GOST28147");
+ // END android-removed
+
+ nameTable.put(NISTObjectIdentifiers.id_aes128_wrap.getId(), "AES");
+ nameTable.put(NISTObjectIdentifiers.id_aes128_CCM.getId(), "AES");
+ nameTable.put(NISTObjectIdentifiers.id_aes128_CCM.getId(), "AES");
+
+ oids.put("DESEDE", PKCSObjectIdentifiers.des_EDE3_CBC);
+ oids.put("AES", NISTObjectIdentifiers.id_aes256_CBC);
+ oids.put("DES", OIWObjectIdentifiers.desCBC);
+
+ des.put("DES", "DES");
+ des.put("DESEDE", "DES");
+ des.put(OIWObjectIdentifiers.desCBC.getId(), "DES");
+ des.put(PKCSObjectIdentifiers.des_EDE3_CBC.getId(), "DES");
+ des.put(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId(), "DES");
+ }
+
+ private final String kaAlgorithm;
+ private final DerivationFunction kdf;
+
+ protected BigInteger result;
+ protected byte[] ukmParameters;
+
+ public BaseAgreementSpi(String kaAlgorithm, DerivationFunction kdf)
+ {
+ this.kaAlgorithm = kaAlgorithm;
+ this.kdf = kdf;
+ }
+
+ protected static String getAlgorithm(String algDetails)
+ {
+ if (algDetails.indexOf('[') > 0)
+ {
+ return algDetails.substring(0, algDetails.indexOf('['));
+ }
+
+ if (algDetails.startsWith(NISTObjectIdentifiers.aes.getId()))
+ {
+ return "AES";
+ }
+ // BEGIN android-removed
+ // if (algDetails.startsWith(GNUObjectIdentifiers.Serpent.getId()))
+ // {
+ // return "Serpent";
+ // }
+ // END android-removed
+
+ String name = (String)nameTable.get(Strings.toUpperCase(algDetails));
+
+ if (name != null)
+ {
+ return name;
+ }
+
+ return algDetails;
+ }
+
+ protected static int getKeySize(String algDetails)
+ {
+ if (algDetails.indexOf('[') > 0)
+ {
+ return (Integer.parseInt(algDetails.substring(algDetails.indexOf('[') + 1, algDetails.indexOf(']'))) + 7) / 8;
+ }
+
+ String algKey = Strings.toUpperCase(algDetails);
+ if (!keySizes.containsKey(algKey))
+ {
+ return -1;
+ }
+
+ return ((Integer)keySizes.get(algKey)).intValue();
+ }
+
+ protected static byte[] trimZeroes(byte[] secret)
+ {
+ if (secret[0] != 0)
+ {
+ return secret;
+ }
+ else
+ {
+ int ind = 0;
+ while (ind < secret.length && secret[ind] == 0)
+ {
+ ind++;
+ }
+
+ byte[] rv = new byte[secret.length - ind];
+
+ System.arraycopy(secret, ind, rv, 0, rv.length);
+
+ return rv;
+ }
+ }
+
+ protected byte[] engineGenerateSecret()
+ throws IllegalStateException
+ {
+ if (kdf != null)
+ {
+ throw new UnsupportedOperationException(
+ "KDF can only be used when algorithm is known");
+ }
+
+ return bigIntToBytes(result);
+ }
+
+ protected int engineGenerateSecret(
+ byte[] sharedSecret,
+ int offset)
+ throws IllegalStateException, ShortBufferException
+ {
+ byte[] secret = engineGenerateSecret();
+
+ if (sharedSecret.length - offset < secret.length)
+ {
+ throw new ShortBufferException(kaAlgorithm + " key agreement: need " + secret.length + " bytes");
+ }
+
+ System.arraycopy(secret, 0, sharedSecret, offset, secret.length);
+
+ return secret.length;
+ }
+
+ protected SecretKey engineGenerateSecret(
+ String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ byte[] secret = bigIntToBytes(result);
+ String algKey = Strings.toUpperCase(algorithm);
+ String oidAlgorithm = algorithm;
+
+ if (oids.containsKey(algKey))
+ {
+ oidAlgorithm = ((ASN1ObjectIdentifier)oids.get(algKey)).getId();
+ }
+
+ int keySize = getKeySize(oidAlgorithm);
+ if (kdf != null)
+ {
+ if (keySize < 0)
+ {
+ throw new NoSuchAlgorithmException("unknown algorithm encountered: " + oidAlgorithm);
+ }
+ byte[] keyBytes = new byte[keySize / 8];
+
+ // BEGIN android-removed
+ // if (kdf instanceof DHKEKGenerator)
+ // {
+ // ASN1ObjectIdentifier oid;
+ // try
+ // {
+ // oid = new ASN1ObjectIdentifier(oidAlgorithm);
+ // }
+ // catch (IllegalArgumentException e)
+ // {
+ // throw new NoSuchAlgorithmException("no OID for algorithm: " + oidAlgorithm);
+ // }
+ // DHKDFParameters params = new DHKDFParameters(oid, keySize, secret, ukmParameters);
+
+ // kdf.init(params);
+ // }
+ // else
+ // END android-removed
+ {
+ KDFParameters params = new KDFParameters(secret, ukmParameters);
+
+ kdf.init(params);
+ }
+
+ kdf.generateBytes(keyBytes, 0, keyBytes.length);
+
+ secret = keyBytes;
+ }
+ else
+ {
+ if (keySize > 0)
+ {
+ byte[] keyBytes = new byte[keySize / 8];
+
+ System.arraycopy(secret, 0, keyBytes, 0, keyBytes.length);
+
+ secret = keyBytes;
+ }
+ }
+
+ if (des.containsKey(oidAlgorithm))
+ {
+ DESParameters.setOddParity(secret);
+ }
+
+ return new SecretKeySpec(secret, getAlgorithm(algorithm));
+ }
+
+ protected abstract byte[] bigIntToBytes(BigInteger result);
+}
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 d5b62fe8..0f25888a 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
@@ -11,13 +11,20 @@ import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
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.jcajce.provider.config.ProviderConfiguration;
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import org.bouncycastle.jce.spec.ECNamedCurveSpec;
import org.bouncycastle.math.ec.ECAlgorithms;
import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.math.field.FiniteField;
+import org.bouncycastle.math.field.Polynomial;
+import org.bouncycastle.math.field.PolynomialExtensionField;
+import org.bouncycastle.util.Arrays;
public class EC5Util
{
@@ -38,34 +45,111 @@ public class EC5Util
}
}
- public static EllipticCurve convertCurve(
- ECCurve curve,
- byte[] seed)
+ public static ECCurve getCurve(
+ ProviderConfiguration configuration,
+ X962Parameters params)
{
- // TODO: the Sun EC implementation doesn't currently handle the seed properly
- // so at the moment it's set to null. Should probably look at making this configurable
- if (ECAlgorithms.isFpCurve(curve))
+ ECCurve curve;
+
+ if (params.isNamedCurve())
{
- return new EllipticCurve(new ECFieldFp(curve.getField().getCharacteristic()), curve.getA().toBigInteger(), curve.getB().toBigInteger(), null);
+ ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters());
+ X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid);
+
+ curve = ecP.getCurve();
+ }
+ else if (params.isImplicitlyCA())
+ {
+ curve = configuration.getEcImplicitlyCa().getCurve();
}
else
{
- ECCurve.F2m curveF2m = (ECCurve.F2m)curve;
- int ks[];
-
- if (curveF2m.isTrinomial())
+ X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
+
+ curve = ecP.getCurve();
+ }
+
+ return curve;
+ }
+
+ public static ECParameterSpec convertToSpec(
+ X962Parameters params, ECCurve curve)
+ {
+ ECParameterSpec ecSpec;
+ EllipticCurve ellipticCurve;
+
+ if (params.isNamedCurve())
+ {
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
+ X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid);
+
+ ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed());
+
+ ecSpec = new ECNamedCurveSpec(
+ ECUtil.getCurveName(oid),
+ ellipticCurve,
+ new ECPoint(
+ ecP.getG().getAffineXCoord().toBigInteger(),
+ ecP.getG().getAffineYCoord().toBigInteger()),
+ ecP.getN(),
+ ecP.getH());
+ }
+ else if (params.isImplicitlyCA())
+ {
+ ecSpec = null;
+ }
+ else
+ {
+ X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
+
+ ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed());
+
+ if (ecP.getH() != null)
{
- ks = new int[] { curveF2m.getK1() };
-
- return new EllipticCurve(new ECFieldF2m(curveF2m.getM(), ks), curve.getA().toBigInteger(), curve.getB().toBigInteger(), null);
+ ecSpec = new ECParameterSpec(
+ ellipticCurve,
+ new ECPoint(
+ ecP.getG().getAffineXCoord().toBigInteger(),
+ ecP.getG().getAffineYCoord().toBigInteger()),
+ ecP.getN(),
+ ecP.getH().intValue());
}
else
{
- ks = new int[] { curveF2m.getK3(), curveF2m.getK2(), curveF2m.getK1() };
-
- return new EllipticCurve(new ECFieldF2m(curveF2m.getM(), ks), curve.getA().toBigInteger(), curve.getB().toBigInteger(), null);
- }
+ ecSpec = new ECParameterSpec(
+ ellipticCurve,
+ new ECPoint(
+ ecP.getG().getAffineXCoord().toBigInteger(),
+ ecP.getG().getAffineYCoord().toBigInteger()),
+ ecP.getN(), 1); // TODO: not strictly correct... need to fix the test data...
+ }
}
+
+ return ecSpec;
+ }
+
+ public static ECParameterSpec convertToSpec(
+ X9ECParameters domainParameters)
+ {
+ return new ECParameterSpec(
+ convertCurve(domainParameters.getCurve(), null), // JDK 1.5 has trouble with this if it's not null...
+ new ECPoint(
+ domainParameters.getG().getAffineXCoord().toBigInteger(),
+ domainParameters.getG().getAffineYCoord().toBigInteger()),
+ domainParameters.getN(),
+ domainParameters.getH().intValue());
+ }
+
+ public static EllipticCurve convertCurve(
+ ECCurve curve,
+ byte[] seed)
+ {
+ ECField field = convertField(curve.getField());
+ BigInteger a = curve.getA().toBigInteger(), b = curve.getB().toBigInteger();
+
+ // TODO: the Sun EC implementation doesn't currently handle the seed properly
+ // so at the moment it's set to null. Should probably look at making this configurable
+ return new EllipticCurve(field, a, b, null);
}
public static ECCurve convertCurve(
@@ -95,6 +179,21 @@ public class EC5Util
}
}
+ public static ECField convertField(FiniteField field)
+ {
+ if (ECAlgorithms.isFpField(field))
+ {
+ return new ECFieldFp(field.getCharacteristic());
+ }
+ else //if (ECAlgorithms.isF2mField(curveField))
+ {
+ Polynomial poly = ((PolynomialExtensionField)field).getMinimalPolynomial();
+ int[] exponents = poly.getExponentsPresent();
+ int[] ks = Arrays.reverse(Arrays.copyOfRange(exponents, 1, exponents.length - 1));
+ return new ECFieldF2m(poly.getDegree(), ks);
+ }
+ }
+
public static ECParameterSpec convertSpec(
EllipticCurve ellipticCurve,
org.bouncycastle.jce.spec.ECParameterSpec spec)
@@ -149,6 +248,6 @@ public class EC5Util
ECPoint point,
boolean withCompression)
{
- return curve.createPoint(point.getAffineX(), point.getAffineY(), withCompression);
+ 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 b8ef3985..561259ad 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
@@ -4,9 +4,11 @@ import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.PrivateKey;
import java.security.PublicKey;
+import java.util.Enumeration;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
// BEGIN android-removed
+// import org.bouncycastle.asn1.anssi.ANSSINamedCurves;
// import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
// END android-removed
import org.bouncycastle.asn1.nist.NISTNamedCurves;
@@ -16,8 +18,8 @@ import org.bouncycastle.asn1.sec.SECNamedCurves;
// import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves;
// END android-removed
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
+import org.bouncycastle.asn1.x9.ECNamedCurveTable;
import org.bouncycastle.asn1.x9.X962NamedCurves;
-import org.bouncycastle.asn1.x9.X962Parameters;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.ec.CustomNamedCurves;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
@@ -240,10 +242,40 @@ public class ECUtil
}
public static ASN1ObjectIdentifier getNamedCurveOid(
- String name)
+ String curveName)
+ {
+ String name;
+
+ if (curveName.indexOf(' ') > 0)
+ {
+ name = curveName.substring(curveName.indexOf(' ') + 1);
+ }
+ else
+ {
+ name = curveName;
+ }
+
+ try
+ {
+ if (name.charAt(0) >= '0' && name.charAt(0) <= '2')
+ {
+ return new ASN1ObjectIdentifier(name);
+ }
+ else
+ {
+ return lookupOidByName(name);
+ }
+ }
+ catch (IllegalArgumentException ex)
+ {
+ return lookupOidByName(name);
+ }
+ }
+
+ private static ASN1ObjectIdentifier lookupOidByName(String name)
{
ASN1ObjectIdentifier oid = X962NamedCurves.getOID(name);
-
+
if (oid == null)
{
oid = SECNamedCurves.getOID(name);
@@ -260,12 +292,37 @@ public class ECUtil
// {
// oid = ECGOST3410NamedCurves.getOID(name);
// }
+ // if (oid == null)
+ // {
+ // oid = ANSSINamedCurves.getOID(name);
+ // }
// END android-removed
}
return oid;
}
-
+
+ public static ASN1ObjectIdentifier getNamedCurveOid(
+ ECParameterSpec ecParameterSpec)
+ {
+ for (Enumeration names = ECNamedCurveTable.getNames(); names.hasMoreElements();)
+ {
+ String name = (String)names.nextElement();
+
+ X9ECParameters params = ECNamedCurveTable.getByName(name);
+
+ if (params.getN().equals(ecParameterSpec.getN())
+ && params.getH().equals(ecParameterSpec.getH())
+ && params.getCurve().equals(ecParameterSpec.getCurve())
+ && params.getG().equals(ecParameterSpec.getG()))
+ {
+ return org.bouncycastle.asn1.x9.ECNamedCurveTable.getOID(name);
+ }
+ }
+
+ return null;
+ }
+
public static X9ECParameters getNamedCurveByOid(
ASN1ObjectIdentifier oid)
{
@@ -293,6 +350,33 @@ public class ECUtil
return params;
}
+ public static X9ECParameters getNamedCurveByName(
+ String curveName)
+ {
+ X9ECParameters params = CustomNamedCurves.getByName(curveName);
+
+ if (params == null)
+ {
+ params = X962NamedCurves.getByName(curveName);
+ if (params == null)
+ {
+ params = SECNamedCurves.getByName(curveName);
+ }
+ if (params == null)
+ {
+ params = NISTNamedCurves.getByName(curveName);
+ }
+ // BEGIN android-removed
+ // if (params == null)
+ // {
+ // params = TeleTrusTNamedCurves.getByName(curveName);
+ // }
+ // END android-removed
+ }
+
+ return params;
+ }
+
public static String getCurveName(
ASN1ObjectIdentifier oid)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java
index 03a1fe83..2203ce79 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java
@@ -24,6 +24,8 @@ import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.SignedData;
import org.bouncycastle.asn1.x509.Certificate;
import org.bouncycastle.asn1.x509.CertificateList;
+import org.bouncycastle.jcajce.util.BCJcaJceHelper;
+import org.bouncycastle.jcajce.util.JcaJceHelper;
/**
* class for dealing with X509 certificates.
@@ -35,6 +37,8 @@ import org.bouncycastle.asn1.x509.CertificateList;
public class CertificateFactory
extends CertificateFactorySpi
{
+ private final JcaJceHelper bcHelper = new BCJcaJceHelper();
+
private static final PEMUtil PEM_CERT_PARSER = new PEMUtil("CERTIFICATE");
private static final PEMUtil PEM_CRL_PARSER = new PEMUtil("CRL");
@@ -64,7 +68,7 @@ public class CertificateFactory
}
}
- return new X509CertificateObject(
+ return new X509CertificateObject(bcHelper,
Certificate.getInstance(seq));
}
@@ -79,7 +83,7 @@ public class CertificateFactory
if (obj instanceof ASN1Sequence)
{
- return new X509CertificateObject(
+ return new X509CertificateObject(bcHelper,
Certificate.getInstance(obj));
}
}
@@ -96,7 +100,7 @@ public class CertificateFactory
if (seq != null)
{
- return new X509CertificateObject(
+ return new X509CertificateObject(bcHelper,
Certificate.getInstance(seq));
}
@@ -106,7 +110,7 @@ public class CertificateFactory
protected CRL createCRL(CertificateList c)
throws CRLException
{
- return new X509CRLObject(c);
+ return new X509CRLObject(bcHelper, c);
}
private CRL readPEMCRL(
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 0b53bd37..5a94c638 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
@@ -23,6 +23,7 @@ import org.bouncycastle.asn1.x509.Extensions;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.TBSCertList;
+import org.bouncycastle.util.Strings;
/**
* The following extensions are listed in RFC 2459 as relevant to CRL Entries
@@ -188,7 +189,7 @@ class X509CRLEntryObject extends X509CRLEntry
}
catch (Exception e)
{
- throw new RuntimeException("error encoding " + e.toString());
+ throw new IllegalStateException("Exception encoding: " + e.toString());
}
}
@@ -258,7 +259,7 @@ class X509CRLEntryObject extends X509CRLEntry
public String toString()
{
StringBuffer buf = new StringBuffer();
- String nl = System.getProperty("line.separator");
+ String nl = Strings.lineSeparator();
buf.append(" userCertificate: ").append(this.getSerialNumber()).append(nl);
buf.append(" revocationDate: ").append(this.getRevocationDate()).append(nl);
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 cd877d04..dc8930b3 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
@@ -6,6 +6,7 @@ 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;
@@ -40,8 +41,9 @@ 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.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
/**
@@ -56,6 +58,7 @@ import org.bouncycastle.util.encoders.Hex;
class X509CRLObject
extends X509CRL
{
+ private JcaJceHelper bcHelper;
private CertificateList c;
private String sigAlgName;
private byte[] sigAlgParams;
@@ -80,9 +83,11 @@ class X509CRLObject
}
protected X509CRLObject(
+ JcaJceHelper bcHelper,
CertificateList c)
throws CRLException
{
+ this.bcHelper = bcHelper;
this.c = c;
try
@@ -202,21 +207,45 @@ class X509CRLObject
}
public void verify(PublicKey key)
- throws CRLException, NoSuchAlgorithmException,
- InvalidKeyException, NoSuchProviderException, SignatureException
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException
{
- verify(key, BouncyCastleProvider.PROVIDER_NAME);
+ 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
+ InvalidKeyException, NoSuchProviderException, SignatureException
{
- if (!c.getSignatureAlgorithm().equals(c.getTBSCertList().getSignature()))
+ Signature sig;
+
+ if (sigProvider != null)
{
- throw new CRLException("Signature algorithm on CertificateList does not match TBSCertList.");
+ sig = Signature.getInstance(getSigAlgName(), sigProvider);
+ }
+ else
+ {
+ sig = Signature.getInstance(getSigAlgName());
}
+ doVerify(key, sig);
+ }
+
+ public void verify(PublicKey key, Provider sigProvider)
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException
+ {
Signature sig;
if (sigProvider != null)
@@ -228,6 +257,18 @@ class X509CRLObject
sig = Signature.getInstance(getSigAlgName());
}
+ doVerify(key, sig);
+ }
+
+ private void doVerify(PublicKey key, Signature sig)
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException
+ {
+ if (!c.getSignatureAlgorithm().equals(c.getTBSCertList().getSignature()))
+ {
+ throw new CRLException("Signature algorithm on CertificateList does not match TBSCertList.");
+ }
+
sig.initVerify(key);
sig.update(this.getTBSCertList());
@@ -354,7 +395,7 @@ class X509CRLObject
public byte[] getSignature()
{
- return c.getSignature().getBytes();
+ return c.getSignature().getOctets();
}
public String getSigAlgName()
@@ -389,7 +430,7 @@ class X509CRLObject
public String toString()
{
StringBuffer buf = new StringBuffer();
- String nl = System.getProperty("line.separator");
+ String nl = Strings.lineSeparator();
buf.append(" Version: ").append(this.getVersion()).append(
nl);
@@ -520,7 +561,7 @@ class X509CRLObject
{
if (!cert.getType().equals("X.509"))
{
- throw new RuntimeException("X.509 CRL used with non X.509 Cert");
+ throw new IllegalArgumentException("X.509 CRL used with non X.509 Cert");
}
Enumeration certs = c.getRevokedCertificateEnumeration();
@@ -561,7 +602,7 @@ class X509CRLObject
}
catch (CertificateEncodingException e)
{
- throw new RuntimeException("Cannot process certificate");
+ throw new IllegalArgumentException("Cannot process certificate: " + e.getMessage());
}
}
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 3157ea67..51213d42 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
@@ -9,10 +9,10 @@ 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.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
@@ -30,6 +30,7 @@ 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;
@@ -59,17 +60,19 @@ import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.asn1.x509.X509Name;
// END android-added
import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
+import org.bouncycastle.jcajce.util.JcaJceHelper;
import org.bouncycastle.jce.X509Principal;
import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Integers;
+import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
class X509CertificateObject
extends X509Certificate
implements PKCS12BagAttributeCarrier
{
+ private JcaJceHelper bcHelper;
private org.bouncycastle.asn1.x509.Certificate c;
private BasicConstraints basicConstraints;
private boolean[] keyUsage;
@@ -79,9 +82,11 @@ class X509CertificateObject
private PKCS12BagAttributeCarrier attrCarrier = new PKCS12BagAttributeCarrierImpl();
public X509CertificateObject(
+ JcaJceHelper bcHelper,
org.bouncycastle.asn1.x509.Certificate c)
throws CertificateParsingException
{
+ this.bcHelper = bcHelper;
this.c = c;
try
@@ -103,7 +108,7 @@ class X509CertificateObject
byte[] bytes = this.getExtensionBytes("2.5.29.15");
if (bytes != null)
{
- DERBitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes));
+ ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes));
bytes = bits.getBytes();
int length = (bytes.length * 8) - bits.getPadBits();
@@ -233,7 +238,7 @@ class X509CertificateObject
public byte[] getSignature()
{
- return c.getSignature().getBytes();
+ return c.getSignature().getOctets();
}
/**
@@ -566,38 +571,41 @@ class X509CertificateObject
return true;
}
- if (!(o instanceof Certificate))
+ if (o instanceof X509CertificateObject)
{
- return false;
- }
-
- Certificate other = (Certificate)o;
+ X509CertificateObject other = (X509CertificateObject)o;
- try
- {
- byte[] b1 = this.getEncoded();
- byte[] b2 = other.getEncoded();
+ if (this.hashValueSet && other.hashValueSet)
+ {
+ if (this.hashValue != other.hashValue)
+ {
+ return false;
+ }
+ }
- return Arrays.areEqual(b1, b2);
- }
- catch (CertificateEncodingException e)
- {
- return false;
+ return this.c.equals(other.c);
}
+
+ return super.equals(o);
}
-
+
public synchronized int hashCode()
{
if (!hashValueSet)
{
- hashValue = calculateHashCode();
+ hashValue = super.hashCode();
hashValueSet = true;
}
return hashValue;
}
-
- private int calculateHashCode()
+
+ /**
+ * Returns the original hash code for Certificates pre-JDK 1.8.
+ *
+ * @return the pre-JDK 1.8 hashcode calculation.
+ */
+ public int originalHashCode()
{
try
{
@@ -636,7 +644,7 @@ class X509CertificateObject
public String toString()
{
StringBuffer buf = new StringBuffer();
- String nl = System.getProperty("line.separator");
+ String nl = Strings.lineSeparator();
buf.append(" [0] Version: ").append(this.getVersion()).append(nl);
buf.append(" SerialNumber: ").append(this.getSerialNumber()).append(nl);
@@ -739,7 +747,7 @@ class X509CertificateObject
try
{
- signature = Signature.getInstance(sigName, BouncyCastleProvider.PROVIDER_NAME);
+ signature = bcHelper.createSignature(sigName);
}
catch (Exception e)
{
@@ -758,7 +766,7 @@ class X509CertificateObject
String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
Signature signature;
- if (sigProvider != null)
+ if (sigProvider != null)
{
signature = Signature.getInstance(sigName, sigProvider);
}
@@ -770,6 +778,27 @@ class X509CertificateObject
checkSignature(key, signature);
}
+ public final void verify(
+ PublicKey key,
+ Provider sigProvider)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException
+ {
+ String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
+ Signature signature;
+
+ if (sigProvider != null)
+ {
+ signature = Signature.getInstance(sigName, sigProvider);
+ }
+ else
+ {
+ signature = Signature.getInstance(sigName);
+ }
+
+ checkSignature(key, signature);
+ }
+
private void checkSignature(
PublicKey key,
Signature signature)
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 123ff7de..5fb3ffc9 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
@@ -33,6 +33,8 @@ public interface ConfigurableProvider
void addAlgorithm(String key, String value);
+ void addAlgorithm(String type, ASN1ObjectIdentifier oid, String className);
+
boolean hasAlgorithm(String type, String name);
void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter);
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA1.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA1.java
index c7502c77..1fdadc24 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA1.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA1.java
@@ -195,6 +195,8 @@ public class SHA1
provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA1", PREFIX + "$PBKDF2WithHmacSHA1UTF8");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2WithHmacSHA1AndUTF8", "PBKDF2WithHmacSHA1");
provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA1And8BIT", PREFIX + "$PBKDF2WithHmacSHA18BIT");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2withASCII", "PBKDF2WithHmacSHA1And8BIT");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2with8BIT", "PBKDF2WithHmacSHA1And8BIT");
}
}
}
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 53548f05..ed0fadce 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
@@ -32,8 +32,10 @@ import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Hashtable;
import java.util.Map;
+import java.util.Set;
import java.util.Vector;
import javax.crypto.Cipher;
@@ -89,8 +91,8 @@ import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.SHA1Digest;
+import org.bouncycastle.jcajce.PKCS12Key;
import org.bouncycastle.jcajce.PKCS12StoreParameter;
-import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey;
// BEGIN android-removed
// import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec;
// END android-removed
@@ -216,8 +218,7 @@ public class PKCS12KeyStoreSpi
{
try
{
- SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
- (ASN1Sequence)ASN1Primitive.fromByteArray(pubKey.getEncoded()));
+ SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded());
return new SubjectKeyIdentifier(getDigest(info));
}
@@ -275,7 +276,8 @@ public class PKCS12KeyStoreSpi
/**
* this is not quite complete - we should follow up on the chain, a bit
- * tricky if a certificate appears in more than one chain...
+ * tricky if a certificate appears in more than one chain... the store method
+ * now prunes out unused certificates from the chain map if they are present.
*/
public void engineDeleteEntry(
String alias)
@@ -450,14 +452,21 @@ public class PKCS12KeyStoreSpi
}
}
- cs.addElement(c);
- if (nextC != c) // self signed - end of the chain
+ if (cs.contains(c))
{
- c = nextC;
+ c = null; // we've got a certificate chain loop time to stop
}
else
{
- c = null;
+ cs.addElement(c);
+ if (nextC != c) // self signed - end of the chain
+ {
+ c = nextC;
+ }
+ else
+ {
+ c = null;
+ }
}
}
@@ -605,23 +614,15 @@ public class PKCS12KeyStoreSpi
if (algorithm.on(PKCSObjectIdentifiers.pkcs_12PbeIds))
{
PKCS12PBEParams pbeParams = PKCS12PBEParams.getInstance(algId.getParameters());
-
- PBEKeySpec pbeSpec = new PBEKeySpec(password);
- PrivateKey out;
-
- SecretKeyFactory keyFact = helper.createSecretKeyFactory(
- algorithm.getId());
PBEParameterSpec defParams = new PBEParameterSpec(
pbeParams.getIV(),
pbeParams.getIterations().intValue());
- SecretKey k = keyFact.generateSecret(pbeSpec);
-
- ((BCPBEKey)k).setTryWrongPKCS12Zero(wrongPKCS12Zero);
-
Cipher cipher = helper.createCipher(algorithm.getId());
- cipher.init(Cipher.UNWRAP_MODE, k, defParams);
+ PKCS12Key key = new PKCS12Key(password, wrongPKCS12Zero);
+
+ cipher.init(Cipher.UNWRAP_MODE, key, defParams);
// we pass "" as the key algorithm type as it is unknown at this point
return (PrivateKey)cipher.unwrap(data, "", Cipher.PRIVATE_KEY);
@@ -692,13 +693,10 @@ public class PKCS12KeyStoreSpi
try
{
- SecretKeyFactory keyFact = helper.createSecretKeyFactory(algorithm.getId());
PBEParameterSpec defParams = new PBEParameterSpec(
pbeParams.getIV(),
pbeParams.getIterations().intValue());
- BCPBEKey key = (BCPBEKey)keyFact.generateSecret(pbeSpec);
-
- key.setTryWrongPKCS12Zero(wrongPKCS12Zero);
+ PKCS12Key key = new PKCS12Key(password, wrongPKCS12Zero);
Cipher cipher = helper.createCipher(algorithm.getId());
@@ -1281,7 +1279,6 @@ public class PKCS12KeyStoreSpi
//
ASN1EncodableVector keyS = new ASN1EncodableVector();
-
Enumeration ks = keys.keys();
while (ks.hasMoreElements())
@@ -1531,6 +1528,8 @@ public class PKCS12KeyStoreSpi
}
}
+ Set usedSet = getUsedCertificateSet();
+
cs = chainCerts.keys();
while (cs.hasMoreElements())
{
@@ -1539,6 +1538,11 @@ public class PKCS12KeyStoreSpi
CertId certId = (CertId)cs.nextElement();
Certificate cert = (Certificate)chainCerts.get(certId);
+ if (!usedSet.contains(cert))
+ {
+ continue;
+ }
+
if (doneCerts.get(cert) != null)
{
continue;
@@ -1657,6 +1661,34 @@ public class PKCS12KeyStoreSpi
asn1Out.writeObject(pfx);
}
+ private Set getUsedCertificateSet()
+ {
+ Set usedSet = new HashSet();
+
+ for (Enumeration en = keys.keys(); en.hasMoreElements();)
+ {
+ String alias = (String)en.nextElement();
+
+ Certificate[] certs = engineGetCertificateChain(alias);
+
+ for (int i = 0; i != certs.length; i++)
+ {
+ usedSet.add(certs[i]);
+ }
+ }
+
+ for (Enumeration en = certs.keys(); en.hasMoreElements();)
+ {
+ String alias = (String)en.nextElement();
+
+ Certificate cert = engineGetCertificate(alias);
+
+ usedSet.add(cert);
+ }
+
+ return usedSet;
+ }
+
private byte[] calculatePbeMac(
ASN1ObjectIdentifier oid,
byte[] salt,
@@ -1666,15 +1698,12 @@ public class PKCS12KeyStoreSpi
byte[] data)
throws Exception
{
- SecretKeyFactory keyFact = helper.createSecretKeyFactory(oid.getId());
PBEParameterSpec defParams = new PBEParameterSpec(salt, itCount);
- PBEKeySpec pbeSpec = new PBEKeySpec(password);
- BCPBEKey key = (BCPBEKey)keyFact.generateSecret(pbeSpec);
- key.setTryWrongPKCS12Zero(wrongPkcs12Zero);
Mac mac = helper.createMac(oid.getId());
- mac.init(key, defParams);
+ mac.init(new PKCS12Key(password, wrongPkcs12Zero), defParams);
mac.update(data);
+
return mac.doFinal();
}
@@ -1776,7 +1805,7 @@ public class PKCS12KeyStoreSpi
keySizes.put(new ASN1ObjectIdentifier("1.2.840.113533.7.66.10"), Integers.valueOf(128));
- keySizes.put(PKCSObjectIdentifiers.des_EDE3_CBC.getId(), Integers.valueOf(192));
+ keySizes.put(PKCSObjectIdentifiers.des_EDE3_CBC, Integers.valueOf(192));
keySizes.put(NISTObjectIdentifiers.id_aes128_CBC, Integers.valueOf(128));
keySizes.put(NISTObjectIdentifiers.id_aes192_CBC, Integers.valueOf(192));
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 d476df8f..0328ac8b 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
@@ -1,8 +1,6 @@
package org.bouncycastle.jcajce.provider.symmetric;
import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
// BEGIN android-added
import java.security.NoSuchAlgorithmException;
// END android-added
@@ -14,9 +12,7 @@ import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidParameterSpecException;
-// BEGIN android-removed
-// import javax.crypto.spec.IvParameterSpec;
-// END android-removed
+import javax.crypto.spec.IvParameterSpec;
// BEGIN android-added
import javax.crypto.NoSuchPaddingException;
@@ -60,7 +56,6 @@ import org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher;
import org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider;
import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters;
import org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory;
-import org.bouncycastle.util.Integers;
public final class AES
{
@@ -136,7 +131,7 @@ public final class AES
// {
// public CCM()
// {
- // super(new CCMBlockCipher(new AESFastEngine()));
+ // super(new CCMBlockCipher(new AESFastEngine()), false, 16);
// }
// }
//
@@ -217,7 +212,67 @@ public final class AES
super(new CBCBlockCipher(new AESFastEngine()));
}
}
-
+
+ /**
+ * PBEWithSHA1AES-CBC
+ */
+ static public class PBEWithSHA1AESCBC128
+ extends BaseBlockCipher
+ {
+ public PBEWithSHA1AESCBC128()
+ {
+ super(new CBCBlockCipher(new AESFastEngine()), PKCS12, SHA1, 128, 16);
+ }
+ }
+
+ static public class PBEWithSHA1AESCBC192
+ extends BaseBlockCipher
+ {
+ public PBEWithSHA1AESCBC192()
+ {
+ super(new CBCBlockCipher(new AESFastEngine()), PKCS12, SHA1, 192, 16);
+ }
+ }
+
+ static public class PBEWithSHA1AESCBC256
+ extends BaseBlockCipher
+ {
+ public PBEWithSHA1AESCBC256()
+ {
+ super(new CBCBlockCipher(new AESFastEngine()), PKCS12, SHA1, 256, 16);
+ }
+ }
+
+ /**
+ * PBEWithSHA256AES-CBC
+ */
+ static public class PBEWithSHA256AESCBC128
+ extends BaseBlockCipher
+ {
+ public PBEWithSHA256AESCBC128()
+ {
+ super(new CBCBlockCipher(new AESFastEngine()), PKCS12, SHA256, 128, 16);
+ }
+ }
+
+ static public class PBEWithSHA256AESCBC192
+ extends BaseBlockCipher
+ {
+ public PBEWithSHA256AESCBC192()
+ {
+ super(new CBCBlockCipher(new AESFastEngine()), PKCS12, SHA256, 192, 16);
+ }
+ }
+
+ static public class PBEWithSHA256AESCBC256
+ extends BaseBlockCipher
+ {
+ public PBEWithSHA256AESCBC256()
+ {
+ super(new CBCBlockCipher(new AESFastEngine()), PKCS12, SHA256, 256, 16);
+ }
+ }
+
public static class KeyGen
extends BaseKeyGenerator
{
@@ -504,19 +559,13 @@ public final class AES
protected void engineInit(AlgorithmParameterSpec paramSpec)
throws InvalidParameterSpecException
{
- if (gcmSpecClass != null)
+ if (GcmSpecUtil.isGcmSpec(paramSpec))
{
- try
- {
- Method tLen = gcmSpecClass.getDeclaredMethod("getTLen", new Class[0]);
- Method iv= gcmSpecClass.getDeclaredMethod("getIV", new Class[0]);
-
- gcmParams = 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.");
- }
+ gcmParams = GcmSpecUtil.extractGcmParameters(paramSpec);
+ }
+ else
+ {
+ throw new InvalidParameterSpecException("AlgorithmParameterSpec class not recognized: " + paramSpec.getClass().getName());
}
}
@@ -562,25 +611,20 @@ public final class AES
protected AlgorithmParameterSpec localEngineGetParameterSpec(Class paramSpec)
throws InvalidParameterSpecException
{
- if (gcmSpecClass != null)
+ if (paramSpec == AlgorithmParameterSpec.class || GcmSpecUtil.isGcmSpec(paramSpec))
{
- try
- {
- 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)
+ if (GcmSpecUtil.gcmSpecExists())
{
- throw new InvalidParameterSpecException("no constructor found!"); // should never happen
- }
- catch (Exception e)
- {
- throw new InvalidParameterSpecException("construction failed: " + e.getMessage()); // should never happen
+ return GcmSpecUtil.extractGcmSpec(gcmParams.toASN1Primitive());
}
+ return new IvParameterSpec(gcmParams.getNonce());
+ }
+ if (paramSpec == IvParameterSpec.class)
+ {
+ return new IvParameterSpec(gcmParams.getNonce());
}
- throw new InvalidParameterSpecException("unknown parameter spec: " + paramSpec.getName());
+ throw new InvalidParameterSpecException("AlgorithmParameterSpec not recognized: " + paramSpec.getName());
}
}
@@ -589,19 +633,26 @@ public final class AES
// extends BaseAlgorithmParameters
// {
// private CCMParameters ccmParams;
- //
+ //
// protected void engineInit(AlgorithmParameterSpec paramSpec)
// throws InvalidParameterSpecException
// {
- // throw new InvalidParameterSpecException("No supported AlgorithmParameterSpec for AES parameter generation.");
+ // if (GcmSpecUtil.isGcmSpec(paramSpec))
+ // {
+ // ccmParams = CCMParameters.getInstance(GcmSpecUtil.extractGcmParameters(paramSpec));
+ // }
+ // else
+ // {
+ // throw new InvalidParameterSpecException("AlgorithmParameterSpec class not recognized: " + paramSpec.getClass().getName());
+ // }
// }
- //
+ //
// protected void engineInit(byte[] params)
// throws IOException
// {
// ccmParams = CCMParameters.getInstance(params);
// }
- //
+ //
// protected void engineInit(byte[] params, String format)
// throws IOException
// {
@@ -609,16 +660,16 @@ public final class AES
// {
// throw new IOException("unknown format specified");
// }
- //
+ //
// ccmParams = CCMParameters.getInstance(params);
// }
- //
+ //
// protected byte[] engineGetEncoded()
// throws IOException
// {
// return ccmParams.getEncoded();
// }
- //
+ //
// protected byte[] engineGetEncoded(String format)
// throws IOException
// {
@@ -626,37 +677,32 @@ public final class AES
// {
// throw new IOException("unknown format specified");
// }
- //
+ //
// return ccmParams.getEncoded();
// }
- //
+ //
// protected String engineToString()
// {
// return "CCM";
// }
- //
+ //
// protected AlgorithmParameterSpec localEngineGetParameterSpec(Class paramSpec)
// throws InvalidParameterSpecException
// {
- // if (gcmSpecClass != null)
+ // if (paramSpec == AlgorithmParameterSpec.class || GcmSpecUtil.isGcmSpec(paramSpec))
// {
- // try
- // {
- // Constructor constructor = gcmSpecClass.getConstructor(new Class[] { Integer.TYPE, byte[].class });
- //
- // return (AlgorithmParameterSpec)constructor.newInstance(new Object[] { Integers.valueOf(ccmParams.getIcvLen() * 8), ccmParams.getNonce() });
- // }
- // catch (NoSuchMethodException e)
- // {
- // throw new InvalidParameterSpecException("no constructor found!"); // should never happen
- // }
- // catch (Exception e)
+ // if (GcmSpecUtil.gcmSpecExists())
// {
- // throw new InvalidParameterSpecException("construction failed: " + e.getMessage()); // should never happen
+ // return GcmSpecUtil.extractGcmSpec(ccmParams.toASN1Primitive());
// }
+ // return new IvParameterSpec(ccmParams.getNonce());
// }
- //
- // throw new InvalidParameterSpecException("unknown parameter spec: " + paramSpec.getName());
+ // if (paramSpec == IvParameterSpec.class)
+ // {
+ // return new IvParameterSpec(ccmParams.getNonce());
+ // }
+ //
+ // throw new InvalidParameterSpecException("AlgorithmParameterSpec not recognized: " + paramSpec.getName());
// }
// }
// END android-removed
@@ -713,38 +759,39 @@ public final class AES
provider.addAlgorithm("Alg.Alias.Cipher." + wrongAES192, "AES");
provider.addAlgorithm("Alg.Alias.Cipher." + wrongAES256, "AES");
// BEGIN android-removed
- // provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes128_ECB, PREFIX + "$ECB");
- // provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes192_ECB, PREFIX + "$ECB");
- // provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes256_ECB, PREFIX + "$ECB");
- // provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes128_CBC, PREFIX + "$CBC");
- // provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes192_CBC, PREFIX + "$CBC");
- // provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes256_CBC, PREFIX + "$CBC");
- // provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes128_OFB, PREFIX + "$OFB");
- // provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes192_OFB, PREFIX + "$OFB");
- // provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes256_OFB, PREFIX + "$OFB");
- // provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes128_CFB, PREFIX + "$CFB");
- // provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes192_CFB, PREFIX + "$CFB");
- // provider.addAlgorithm("Cipher." + NISTObjectIdentifiers.id_aes256_CFB, PREFIX + "$CFB");
+ // provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes128_ECB, PREFIX + "$ECB");
+ // provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes192_ECB, PREFIX + "$ECB");
+ // provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes256_ECB, PREFIX + "$ECB");
+ // provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes128_CBC, PREFIX + "$CBC");
+ // provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes192_CBC, PREFIX + "$CBC");
+ // provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes256_CBC, PREFIX + "$CBC");
+ // provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes128_OFB, PREFIX + "$OFB");
+ // provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes192_OFB, PREFIX + "$OFB");
+ // provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes256_OFB, PREFIX + "$OFB");
+ // provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes128_CFB, PREFIX + "$CFB");
+ // provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes192_CFB, PREFIX + "$CFB");
+ // provider.addAlgorithm("Cipher", NISTObjectIdentifiers.id_aes256_CFB, PREFIX + "$CFB");
// END android-removed
provider.addAlgorithm("Cipher.AESWRAP", PREFIX + "$Wrap");
- provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes128_wrap, "AESWRAP");
- provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes192_wrap, "AESWRAP");
- provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes256_wrap, "AESWRAP");
+ provider.addAlgorithm("Alg.Alias.Cipher", NISTObjectIdentifiers.id_aes128_wrap, "AESWRAP");
+ provider.addAlgorithm("Alg.Alias.Cipher", NISTObjectIdentifiers.id_aes192_wrap, "AESWRAP");
+ provider.addAlgorithm("Alg.Alias.Cipher", NISTObjectIdentifiers.id_aes256_wrap, "AESWRAP");
+ provider.addAlgorithm("Alg.Alias.Cipher.AESKW", "AESWRAP");
// BEGIN android-removed
// provider.addAlgorithm("Cipher.AESRFC3211WRAP", PREFIX + "$RFC3211Wrap");
// provider.addAlgorithm("Cipher.AESRFC5649WRAP", PREFIX + "$RFC5649Wrap");
- //
+ //
// provider.addAlgorithm("AlgorithmParameterGenerator.CCM", PREFIX + "$AlgParamGenCCM");
// provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes128_CCM, "CCM");
// provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes192_CCM, "CCM");
// provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes256_CCM, "CCM");
- //
+ //
// provider.addAlgorithm("Cipher.CCM", PREFIX + "$CCM");
- // provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes128_CCM, "CCM");
- // provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes192_CCM, "CCM");
- // provider.addAlgorithm("Alg.Alias.Cipher." + NISTObjectIdentifiers.id_aes256_CCM, "CCM");
- //
+ // provider.addAlgorithm("Alg.Alias.Cipher", NISTObjectIdentifiers.id_aes128_CCM, "CCM");
+ // provider.addAlgorithm("Alg.Alias.Cipher", NISTObjectIdentifiers.id_aes192_CCM, "CCM");
+ // provider.addAlgorithm("Alg.Alias.Cipher", NISTObjectIdentifiers.id_aes256_CCM, "CCM");
+ //
// provider.addAlgorithm("AlgorithmParameterGenerator.GCM", PREFIX + "$AlgParamGenGCM");
// provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes128_GCM, "GCM");
// provider.addAlgorithm("Alg.Alias.AlgorithmParameterGenerator." + NISTObjectIdentifiers.id_aes192_GCM, "GCM");
@@ -763,45 +810,45 @@ public final class AES
// provider.addAlgorithm("KeyGenerator." + wrongAES128, PREFIX + "$KeyGen128");
// provider.addAlgorithm("KeyGenerator." + wrongAES192, PREFIX + "$KeyGen192");
// provider.addAlgorithm("KeyGenerator." + wrongAES256, PREFIX + "$KeyGen256");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes128_ECB, PREFIX + "$KeyGen128");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes128_CBC, PREFIX + "$KeyGen128");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes128_OFB, PREFIX + "$KeyGen128");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes128_CFB, PREFIX + "$KeyGen128");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes192_ECB, PREFIX + "$KeyGen192");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes192_CBC, PREFIX + "$KeyGen192");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes192_OFB, PREFIX + "$KeyGen192");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes192_CFB, PREFIX + "$KeyGen192");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes256_ECB, PREFIX + "$KeyGen256");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes256_CBC, PREFIX + "$KeyGen256");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes256_OFB, PREFIX + "$KeyGen256");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes256_CFB, PREFIX + "$KeyGen256");
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes128_ECB, PREFIX + "$KeyGen128");
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes128_CBC, PREFIX + "$KeyGen128");
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes128_OFB, PREFIX + "$KeyGen128");
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes128_CFB, PREFIX + "$KeyGen128");
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes192_ECB, PREFIX + "$KeyGen192");
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes192_CBC, PREFIX + "$KeyGen192");
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes192_OFB, PREFIX + "$KeyGen192");
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes192_CFB, PREFIX + "$KeyGen192");
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes256_ECB, PREFIX + "$KeyGen256");
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes256_CBC, PREFIX + "$KeyGen256");
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes256_OFB, PREFIX + "$KeyGen256");
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes256_CFB, PREFIX + "$KeyGen256");
// provider.addAlgorithm("KeyGenerator.AESWRAP", PREFIX + "$KeyGen");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes128_wrap, PREFIX + "$KeyGen128");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes192_wrap, PREFIX + "$KeyGen192");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes256_wrap, PREFIX + "$KeyGen256");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes128_GCM, PREFIX + "$KeyGen128");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes192_GCM, PREFIX + "$KeyGen192");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes256_GCM, PREFIX + "$KeyGen256");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes128_CCM, PREFIX + "$KeyGen128");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes192_CCM, PREFIX + "$KeyGen192");
- // provider.addAlgorithm("KeyGenerator." + NISTObjectIdentifiers.id_aes256_CCM, PREFIX + "$KeyGen256");
- //
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes128_wrap, PREFIX + "$KeyGen128");
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes192_wrap, PREFIX + "$KeyGen192");
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes256_wrap, PREFIX + "$KeyGen256");
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes128_GCM, PREFIX + "$KeyGen128");
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes192_GCM, PREFIX + "$KeyGen192");
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes256_GCM, PREFIX + "$KeyGen256");
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes128_CCM, PREFIX + "$KeyGen128");
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes192_CCM, PREFIX + "$KeyGen192");
+ // provider.addAlgorithm("KeyGenerator", NISTObjectIdentifiers.id_aes256_CCM, PREFIX + "$KeyGen256");
+ //
// provider.addAlgorithm("Mac.AESCMAC", PREFIX + "$AESCMAC");
// END android-removed
- provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc.getId(), "PBEWITHSHAAND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc.getId(), "PBEWITHSHAAND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc.getId(), "PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc.getId(), "PBEWITHSHA256AND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc.getId(), "PBEWITHSHA256AND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.Cipher." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc.getId(), "PBEWITHSHA256AND256BITAES-CBC-BC");
-
- provider.addAlgorithm("Cipher.PBEWITHSHAAND128BITAES-CBC-BC", PREFIX + "$PBEWithAESCBC");
- provider.addAlgorithm("Cipher.PBEWITHSHAAND192BITAES-CBC-BC", PREFIX + "$PBEWithAESCBC");
- provider.addAlgorithm("Cipher.PBEWITHSHAAND256BITAES-CBC-BC", PREFIX + "$PBEWithAESCBC");
- provider.addAlgorithm("Cipher.PBEWITHSHA256AND128BITAES-CBC-BC", PREFIX + "$PBEWithAESCBC");
- provider.addAlgorithm("Cipher.PBEWITHSHA256AND192BITAES-CBC-BC", PREFIX + "$PBEWithAESCBC");
- provider.addAlgorithm("Cipher.PBEWITHSHA256AND256BITAES-CBC-BC", PREFIX + "$PBEWithAESCBC");
+ provider.addAlgorithm("Alg.Alias.Cipher", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc, "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc, "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc, "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc, "PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc, "PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc, "PBEWITHSHA256AND256BITAES-CBC-BC");
+
+ provider.addAlgorithm("Cipher.PBEWITHSHAAND128BITAES-CBC-BC", PREFIX + "$PBEWithSHA1AESCBC128");
+ provider.addAlgorithm("Cipher.PBEWITHSHAAND192BITAES-CBC-BC", PREFIX + "$PBEWithSHA1AESCBC192");
+ provider.addAlgorithm("Cipher.PBEWITHSHAAND256BITAES-CBC-BC", PREFIX + "$PBEWithSHA1AESCBC256");
+ provider.addAlgorithm("Cipher.PBEWITHSHA256AND128BITAES-CBC-BC", PREFIX + "$PBEWithSHA256AESCBC128");
+ provider.addAlgorithm("Cipher.PBEWITHSHA256AND192BITAES-CBC-BC", PREFIX + "$PBEWithSHA256AESCBC192");
+ provider.addAlgorithm("Cipher.PBEWITHSHA256AND256BITAES-CBC-BC", PREFIX + "$PBEWithSHA256AESCBC256");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC");
@@ -809,10 +856,25 @@ public final class AES
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-CBC-BC","PBEWITHSHAAND128BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-CBC-BC","PBEWITHSHAAND192BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-CBC-BC","PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND128BITAES-BC","PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND192BITAES-BC", "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND256BITAES-BC", "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITAES-BC","PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND192BITAES-BC","PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND256BITAES-BC","PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND128BITAES-BC","PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND192BITAES-BC","PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-1AND256BITAES-BC","PBEWITHSHAAND256BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-CBC-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-CBC-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-CBC-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
-
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND128BITAES-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND192BITAES-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA256AND256BITAES-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND128BITAES-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND192BITAES-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA-256AND256BITAES-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
+
provider.addAlgorithm("Cipher.PBEWITHMD5AND128BITAES-CBC-OPENSSL", PREFIX + "$PBEWithAESCBC");
provider.addAlgorithm("Cipher.PBEWITHMD5AND192BITAES-CBC-OPENSSL", PREFIX + "$PBEWithAESCBC");
provider.addAlgorithm("Cipher.PBEWITHMD5AND256BITAES-CBC-OPENSSL", PREFIX + "$PBEWithAESCBC");
@@ -836,12 +898,15 @@ public final class AES
provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-CBC-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-CBC-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-CBC-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc.getId(), "PBEWITHSHAAND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc.getId(), "PBEWITHSHAAND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc.getId(), "PBEWITHSHAAND256BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc.getId(), "PBEWITHSHA256AND128BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc.getId(), "PBEWITHSHA256AND192BITAES-CBC-BC");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc.getId(), "PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND128BITAES-BC","PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND192BITAES-BC","PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA-256AND256BITAES-BC","PBEWITHSHA256AND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes128_cbc, "PBEWITHSHAAND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes192_cbc, "PBEWITHSHAAND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha1_pkcs12_aes256_cbc, "PBEWITHSHAAND256BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes128_cbc, "PBEWITHSHA256AND128BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes192_cbc, "PBEWITHSHA256AND192BITAES-CBC-BC");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory", BCObjectIdentifiers.bc_pbe_sha256_pkcs12_aes256_cbc, "PBEWITHSHA256AND256BITAES-CBC-BC");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND128BITAES-CBC-BC", "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAAND192BITAES-CBC-BC", "PKCS12PBE");
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/ARC4.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/ARC4.java
index 9de8ef0c..c780d12c 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/ARC4.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/ARC4.java
@@ -68,7 +68,7 @@ public final class ARC4
{
public PBEWithSHAAnd128Bit()
{
- super(new RC4Engine(), 0);
+ super(new RC4Engine(), 0, 128, SHA1);
}
}
@@ -80,7 +80,7 @@ public final class ARC4
{
public PBEWithSHAAnd40Bit()
{
- super(new RC4Engine(), 0);
+ super(new RC4Engine(), 0, 40, SHA1);
}
}
@@ -96,7 +96,7 @@ public final class ARC4
public void configure(ConfigurableProvider provider)
{
provider.addAlgorithm("Cipher.ARC4", PREFIX + "$Base");
- provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.rc4, "ARC4");
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.rc4, "ARC4");
provider.addAlgorithm("Alg.Alias.Cipher.ARCFOUR", "ARC4");
provider.addAlgorithm("Alg.Alias.Cipher.RC4", "ARC4");
provider.addAlgorithm("KeyGenerator.ARC4", PREFIX + "$KeyGen");
@@ -113,14 +113,14 @@ public final class ARC4
provider.addAlgorithm("Cipher.PBEWITHSHAAND128BITRC4", PREFIX + "$PBEWithSHAAnd128Bit");
provider.addAlgorithm("Cipher.PBEWITHSHAAND40BITRC4", PREFIX + "$PBEWithSHAAnd40Bit");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4, "PBEWITHSHAAND128BITRC4");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC4, "PBEWITHSHAAND40BITRC4");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory", PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4, "PBEWITHSHAAND128BITRC4");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory", PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC4, "PBEWITHSHAAND40BITRC4");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITRC4", "PBEWITHSHAAND128BITRC4");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND40BITRC4", "PBEWITHSHAAND40BITRC4");
- provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4, "PBEWITHSHAAND128BITRC4");
- provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC4, "PBEWITHSHAAND40BITRC4");
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC4, "PBEWITHSHAAND128BITRC4");
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC4, "PBEWITHSHAAND40BITRC4");
}
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java
index 0e374876..c0a09499 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Blowfish.java
@@ -1,11 +1,18 @@
package org.bouncycastle.jcajce.provider.symmetric;
+import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import org.bouncycastle.crypto.CipherKeyGenerator;
import org.bouncycastle.crypto.engines.BlowfishEngine;
+// BEGIN android-removed
+// import org.bouncycastle.crypto.macs.CMac;
+// END android-removed
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
import org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher;
import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator;
+// BEGIN android-removed
+// import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac;
+// END android-removed
import org.bouncycastle.jcajce.provider.symmetric.util.IvAlgorithmParameters;
import org.bouncycastle.jcajce.provider.util.AlgorithmProvider;
@@ -33,6 +40,17 @@ public final class Blowfish
}
}
+ // BEGIN android-removed
+ // public static class CMAC
+ // extends BaseMac
+ // {
+ // public CMAC()
+ // {
+ // super(new CMac(new BlowfishEngine()));
+ // }
+ // }
+ // END android-removed
+
public static class KeyGen
extends BaseKeyGenerator
{
@@ -62,15 +80,17 @@ public final class Blowfish
public void configure(ConfigurableProvider provider)
{
-
+ // BEGIN android-removed
+ // provider.addAlgorithm("Mac.BLOWFISHCMAC", PREFIX + "$CMAC");
+ // END android-removed
provider.addAlgorithm("Cipher.BLOWFISH", PREFIX + "$ECB");
// BEGIN android-removed
- // provider.addAlgorithm("Cipher.1.3.6.1.4.1.3029.1.2", PREFIX + "$CBC");
+ // provider.addAlgorithm("Cipher", MiscObjectIdentifiers.cryptlib_algorithm_blowfish_CBC, PREFIX + "$CBC");
// END android-removed
provider.addAlgorithm("KeyGenerator.BLOWFISH", PREFIX + "$KeyGen");
- provider.addAlgorithm("Alg.Alias.KeyGenerator.1.3.6.1.4.1.3029.1.2", "BLOWFISH");
+ provider.addAlgorithm("Alg.Alias.KeyGenerator", MiscObjectIdentifiers.cryptlib_algorithm_blowfish_CBC, "BLOWFISH");
provider.addAlgorithm("AlgorithmParameters.BLOWFISH", PREFIX + "$AlgParams");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters.1.3.6.1.4.1.3029.1.2", "BLOWFISH");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters", MiscObjectIdentifiers.cryptlib_algorithm_blowfish_CBC, "BLOWFISH");
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DES.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DES.java
index b4c7c06e..5a4f8cda 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DES.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DES.java
@@ -405,7 +405,7 @@ public final class DES
// {
// public PBEWithMD2()
// {
- // super(new CBCBlockCipher(new DESEngine()));
+ // super(new CBCBlockCipher(new DESEngine()), PKCS5S1, MD2, 64, 8);
// }
// }
// END android-removed
@@ -418,7 +418,7 @@ public final class DES
{
public PBEWithMD5()
{
- super(new CBCBlockCipher(new DESEngine()));
+ super(new CBCBlockCipher(new DESEngine()), PKCS5S1, MD5, 64, 8);
}
}
@@ -430,7 +430,7 @@ public final class DES
{
public PBEWithSHA1()
{
- super(new CBCBlockCipher(new DESEngine()));
+ super(new CBCBlockCipher(new DESEngine()), PKCS5S1, SHA1, 64, 8);
}
}
@@ -449,7 +449,7 @@ public final class DES
provider.addAlgorithm("Cipher.DES", PREFIX + "$ECB");
// BEGIN android-removed
- // provider.addAlgorithm("Cipher." + OIWObjectIdentifiers.desCBC, PREFIX + "$CBC");
+ // provider.addAlgorithm("Cipher", OIWObjectIdentifiers.desCBC, PREFIX + "$CBC");
//
// addAlias(provider, OIWObjectIdentifiers.desCBC, "DES");
//
@@ -486,7 +486,7 @@ public final class DES
// END android-removed
provider.addAlgorithm("AlgorithmParameters.DES", PACKAGE + ".util.IvAlgorithmParameters");
- provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + OIWObjectIdentifiers.desCBC, "DES");
+ provider.addAlgorithm("Alg.Alias.AlgorithmParameters", OIWObjectIdentifiers.desCBC, "DES");
// BEGIN android-removed
// provider.addAlgorithm("AlgorithmParameterGenerator.DES", PREFIX + "$AlgParamGen");
@@ -498,13 +498,19 @@ public final class DES
provider.addAlgorithm("Cipher.PBEWITHSHA1ANDDES", PREFIX + "$PBEWithSHA1");
// BEGIN android-removed
- // provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithMD2AndDES_CBC, "PBEWITHMD2ANDDES");
+ // provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithMD2AndDES_CBC, "PBEWITHMD2ANDDES");
// END android-removed
- provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC, "PBEWITHMD5ANDDES");
- provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC, "PBEWITHSHA1ANDDES");
-
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithMD5AndDES_CBC, "PBEWITHMD5ANDDES");
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithSHA1AndDES_CBC, "PBEWITHSHA1ANDDES");
+
+ // BEGIN android-removed
+ // provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHMD2ANDDES-CBC", "PBEWITHMD2ANDDES");
+ // BEGIN android-removed
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHMD5ANDDES-CBC", "PBEWITHMD5ANDDES");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1ANDDES-CBC", "PBEWITHSHA1ANDDES");
+
// BEGIN android-removed
- // provider.addAlgorithm("SecretKeyFactory.PBEWITHMD2ANDDES", PREFIX + "$PBEWithMD2KeyFactory");
+ // provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHMD2ANDDES-CBC", "PBEWITHMD2ANDDES");
// END android-removed
provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5ANDDES", PREFIX + "$PBEWithMD5KeyFactory");
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHA1ANDDES", PREFIX + "$PBEWithSHA1KeyFactory");
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 7b3addd7..64d8972a 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
@@ -105,7 +105,7 @@ public final class DESede
super(new CBCBlockCipherMac(new DESedeEngine(), 64, new ISO7816d4Padding()));
}
}
-
+
public static class CBCMAC
extends BaseMac
{
@@ -125,7 +125,7 @@ public final class DESede
// }
// }
// END android-removed
-
+
public static class Wrap
extends BaseWrapCipher
{
@@ -134,7 +134,7 @@ public final class DESede
super(new DESedeWrapEngine());
}
}
-
+
// BEGIN android-removed
// public static class RFC3211
// extends BaseWrapCipher
@@ -218,7 +218,7 @@ public final class DESede
{
public PBEWithSHAAndDES3Key()
{
- super(new CBCBlockCipher(new DESedeEngine()));
+ super(new CBCBlockCipher(new DESedeEngine()), PKCS12, SHA1, 192, 8);
}
}
@@ -230,7 +230,7 @@ public final class DESede
{
public PBEWithSHAAndDES2Key()
{
- super(new CBCBlockCipher(new DESedeEngine()));
+ super(new CBCBlockCipher(new DESedeEngine()), PKCS12, SHA1, 128, 8);
}
}
@@ -381,7 +381,7 @@ public final class DESede
{
provider.addAlgorithm("Cipher.DESEDE", PREFIX + "$ECB");
// BEGIN android-removed
- // provider.addAlgorithm("Cipher." + PKCSObjectIdentifiers.des_EDE3_CBC, PREFIX + "$CBC");
+ // provider.addAlgorithm("Cipher", PKCSObjectIdentifiers.des_EDE3_CBC, PREFIX + "$CBC");
// END android-removed
provider.addAlgorithm("Cipher.DESEDEWRAP", PREFIX + "$Wrap");
// BEGIN android-changed
@@ -389,6 +389,7 @@ public final class DESede
// END android-changed
// BEGIN android-removed
// provider.addAlgorithm("Cipher.DESEDERFC3211WRAP", PREFIX + "$RFC3211");
+ // provider.addAlgorithm("Alg.Alias.Cipher.DESEDERFC3217WRAP", "DESEDEWRAP");
// END android-removed
provider.addAlgorithm("Alg.Alias.Cipher.TDEA", "DESEDE");
@@ -411,11 +412,16 @@ public final class DESede
// BEGIN android-removed
// provider.addAlgorithm("Cipher.BROKENPBEWITHSHAAND2-KEYTRIPLEDES-CBC", PREFIX + "$BrokePBEWithSHAAndDES2Key");
// END android-removed
- 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", PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithSHAAnd2_KeyTripleDES_CBC, "PBEWITHSHAAND2-KEYTRIPLEDES-CBC");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1ANDDESEDE", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND3-KEYTRIPLEDES-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND2-KEYTRIPLEDES-CBC", "PBEWITHSHAAND2-KEYTRIPLEDES-CBC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND3-KEYDESEDE-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAAND2-KEYDESEDE-CBC", "PBEWITHSHAAND2-KEYTRIPLEDES-CBC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND3-KEYDESEDE-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND2-KEYDESEDE-CBC", "PBEWITHSHAAND2-KEYTRIPLEDES-CBC");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1ANDDESEDE-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC");
}
provider.addAlgorithm("KeyGenerator.DESEDE", PREFIX + "$KeyGenerator");
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/GcmSpecUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/GcmSpecUtil.java
new file mode 100644
index 00000000..5ccc8ff0
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/GcmSpecUtil.java
@@ -0,0 +1,78 @@
+package org.bouncycastle.jcajce.provider.symmetric;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+import org.bouncycastle.asn1.ASN1Primitive;
+import org.bouncycastle.asn1.cms.GCMParameters;
+import org.bouncycastle.util.Integers;
+
+class GcmSpecUtil
+{
+ static final Class gcmSpecClass = lookup("javax.crypto.spec.GCMParameterSpec");
+
+ static boolean gcmSpecExists()
+ {
+ return gcmSpecClass != null;
+ }
+
+ static boolean isGcmSpec(AlgorithmParameterSpec paramSpec)
+ {
+ return gcmSpecClass != null && gcmSpecClass.isInstance(paramSpec);
+ }
+
+ static boolean isGcmSpec(Class paramSpecClass)
+ {
+ return gcmSpecClass == paramSpecClass;
+ }
+
+ static AlgorithmParameterSpec extractGcmSpec(ASN1Primitive spec)
+ throws InvalidParameterSpecException
+ {
+ try
+ {
+ GCMParameters gcmParams = GCMParameters.getInstance(spec);
+ Constructor constructor = gcmSpecClass.getConstructor(new Class[]{Integer.TYPE, byte[].class});
+
+ return (AlgorithmParameterSpec)constructor.newInstance(new Object[] { Integers.valueOf(gcmParams.getIcvLen() * 8), gcmParams.getNonce() });
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw new InvalidParameterSpecException("No constructor found!"); // should never happen
+ }
+ catch (Exception e)
+ {
+ throw new InvalidParameterSpecException("Construction failed: " + e.getMessage()); // should never happen
+ }
+ }
+
+ static GCMParameters extractGcmParameters(AlgorithmParameterSpec paramSpec)
+ throws InvalidParameterSpecException
+ {
+ try
+ {
+ Method tLen = gcmSpecClass.getDeclaredMethod("getTLen", new Class[0]);
+ Method iv= gcmSpecClass.getDeclaredMethod("getIV", new Class[0]);
+
+ return new GCMParameters((byte[])iv.invoke(paramSpec, new Object[0]), ((Integer)tLen.invoke(paramSpec, new Object[0])).intValue() / 8);
+ }
+ catch (Exception e)
+ {
+ throw new InvalidParameterSpecException("Cannot process GCMParameterSpec");
+ }
+ }
+
+ private static Class lookup(String className)
+ {
+ try
+ {
+ return GcmSpecUtil.class.getClassLoader().loadClass(className);
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+}
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 4056aa79..343fa0c7 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
@@ -144,7 +144,7 @@ public final class RC2
{
public PBEWithMD5AndRC2()
{
- super(new CBCBlockCipher(new RC2Engine()));
+ super(new CBCBlockCipher(new RC2Engine()), PKCS5S1, MD5, 64, 8);
}
}
@@ -156,7 +156,7 @@ public final class RC2
{
public PBEWithSHA1AndRC2()
{
- super(new CBCBlockCipher(new RC2Engine()));
+ super(new CBCBlockCipher(new RC2Engine()), PKCS5S1, SHA1, 64, 8);
}
}
@@ -168,7 +168,7 @@ public final class RC2
{
public PBEWithSHAAnd128BitRC2()
{
- super(new CBCBlockCipher(new RC2Engine()));
+ super(new CBCBlockCipher(new RC2Engine()), PKCS12, SHA1, 128, 8);
}
}
@@ -180,7 +180,7 @@ public final class RC2
{
public PBEWithSHAAnd40BitRC2()
{
- super(new CBCBlockCipher(new RC2Engine()));
+ super(new CBCBlockCipher(new RC2Engine()), PKCS12, SHA1, 40, 8);
}
}
@@ -465,7 +465,6 @@ public final class RC2
public void configure(ConfigurableProvider provider)
{
-
// BEGIN android-removed
// provider.addAlgorithm("AlgorithmParameterGenerator.RC2", PREFIX + "$AlgParamGen");
// provider.addAlgorithm("AlgorithmParameterGenerator.1.2.840.113549.3.2", PREFIX + "$AlgParamGen");
@@ -478,8 +477,8 @@ public final class RC2
//
// provider.addAlgorithm("Cipher.RC2", PREFIX + "$ECB");
// provider.addAlgorithm("Cipher.RC2WRAP", PREFIX + "$Wrap");
- // provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.id_alg_CMSRC2wrap, "RC2WRAP");
- // provider.addAlgorithm("Cipher.1.2.840.113549.3.2", PREFIX + "$CBC");
+ // provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.id_alg_CMSRC2wrap, "RC2WRAP");
+ // provider.addAlgorithm("Cipher", PKCSObjectIdentifiers.RC2_CBC, PREFIX + "$CBC");
//
// provider.addAlgorithm("Mac.RC2MAC", PREFIX + "$CBCMAC");
// provider.addAlgorithm("Alg.Alias.Mac.RC2", "RC2MAC");
@@ -494,12 +493,12 @@ public final class RC2
provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHSHA1ANDRC2-CBC", "PBEWITHSHA1ANDRC2");
// BEGIN android-removed
- // provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD2AndRC2_CBC, "PBEWITHMD2ANDRC2");
+ // provider.addAlgorithm("Alg.Alias.SecretKeyFactory", PKCSObjectIdentifiers.pbeWithMD2AndRC2_CBC, "PBEWITHMD2ANDRC2");
// END android-removed
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithMD5AndRC2_CBC, "PBEWITHMD5ANDRC2");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory", PKCSObjectIdentifiers.pbeWithMD5AndRC2_CBC, "PBEWITHMD5ANDRC2");
- provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.pbeWithSHA1AndRC2_CBC, "PBEWITHSHA1ANDRC2");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory", PKCSObjectIdentifiers.pbeWithSHA1AndRC2_CBC, "PBEWITHSHA1ANDRC2");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.12.1.5", "PBEWITHSHAAND128BITRC2-CBC");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory.1.2.840.113549.1.12.1.6", "PBEWITHSHAAND40BITRC2-CBC");
@@ -511,28 +510,31 @@ public final class RC2
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND128BITRC2-CBC", PREFIX + "$PBEWithSHAAnd128BitKeyFactory");
provider.addAlgorithm("SecretKeyFactory.PBEWITHSHAAND40BITRC2-CBC", PREFIX + "$PBEWithSHAAnd40BitKeyFactory");
-
+
// BEGIN android-removed
- // provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithMD2AndRC2_CBC, "PBEWITHMD2ANDRC2");
+ // provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithMD2AndRC2_CBC, "PBEWITHMD2ANDRC2");
// END android-removed
- provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithMD5AndRC2_CBC, "PBEWITHMD5ANDRC2");
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithMD5AndRC2_CBC, "PBEWITHMD5ANDRC2");
- provider.addAlgorithm("Alg.Alias.Cipher." + PKCSObjectIdentifiers.pbeWithSHA1AndRC2_CBC, "PBEWITHSHA1ANDRC2");
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithSHA1AndRC2_CBC, "PBEWITHSHA1ANDRC2");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.5", "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.1.2.840.113549.1.12.1.6", "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWithSHAAnd3KeyTripleDES", "PKCS12PBE");
- provider.addAlgorithm("Alg.Alias.Cipher.1.2.840.113549.1.12.1.5", "PBEWITHSHAAND128BITRC2-CBC");
- provider.addAlgorithm("Alg.Alias.Cipher.1.2.840.113549.1.12.1.6", "PBEWITHSHAAND40BITRC2-CBC");
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC2_CBC, "PBEWITHSHAAND128BITRC2-CBC");
+ provider.addAlgorithm("Alg.Alias.Cipher", PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC, "PBEWITHSHAAND40BITRC2-CBC");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND128BITRC2-CBC", "PBEWITHSHAAND128BITRC2-CBC");
provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1AND40BITRC2-CBC", "PBEWITHSHAAND40BITRC2-CBC");
provider.addAlgorithm("Cipher.PBEWITHSHA1ANDRC2", PREFIX + "$PBEWithSHA1AndRC2");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHAANDRC2-CBC", "PBEWITHSHA1ANDRC2");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHSHA1ANDRC2-CBC", "PBEWITHSHA1ANDRC2");
provider.addAlgorithm("Cipher.PBEWITHSHAAND128BITRC2-CBC", PREFIX + "$PBEWithSHAAnd128BitRC2");
provider.addAlgorithm("Cipher.PBEWITHSHAAND40BITRC2-CBC", PREFIX + "$PBEWithSHAAnd40BitRC2");
provider.addAlgorithm("Cipher.PBEWITHMD5ANDRC2", PREFIX + "$PBEWithMD5AndRC2");
+ provider.addAlgorithm("Alg.Alias.Cipher.PBEWITHMD5ANDRC2-CBC", "PBEWITHMD5ANDRC2");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHA1ANDRC2", "PKCS12PBE");
provider.addAlgorithm("Alg.Alias.AlgorithmParameters.PBEWITHSHAANDRC2", "PKCS12PBE");
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SymmetricAlgorithmProvider.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SymmetricAlgorithmProvider.java
index fc34865f..7ac79e7e 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SymmetricAlgorithmProvider.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/SymmetricAlgorithmProvider.java
@@ -7,6 +7,19 @@ abstract class SymmetricAlgorithmProvider
extends AlgorithmProvider
{
// BEGIN android-removed
+ // protected void addCMacAlgorithm(
+ // ConfigurableProvider provider,
+ // String algorithm,
+ // String algorithmClassName,
+ // String keyGeneratorClassName)
+ // {
+ // provider.addAlgorithm("Mac." + algorithm + "-CMAC", algorithmClassName);
+ // provider.addAlgorithm("Alg.Alias.Mac." + algorithm + "CMAC", algorithm + "-CMAC");
+ //
+ // provider.addAlgorithm("KeyGenerator." + algorithm + "-CMAC", keyGeneratorClassName);
+ // provider.addAlgorithm("Alg.Alias.KeyGenerator." + algorithm + "CMAC", algorithm + "-CMAC");
+ // }
+ //
// protected void addGMacAlgorithm(
// ConfigurableProvider provider,
// String algorithm,
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Twofish.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Twofish.java
index e2b2efd8..c666ac14 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Twofish.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/Twofish.java
@@ -102,7 +102,7 @@ public final class Twofish
{
public PBEWithSHA()
{
- super(new CBCBlockCipher(new TwofishEngine()));
+ super(new CBCBlockCipher(new TwofishEngine()), PKCS12, SHA1, 256, 16);
}
}
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 0e933b71..da2b4d56 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
@@ -18,6 +18,7 @@ import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.ShortBufferException;
+import javax.crypto.interfaces.PBEKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEParameterSpec;
// BEGIN android-removed
@@ -69,10 +70,15 @@ import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.crypto.params.RC2Parameters;
// BEGIN android-removed
// import org.bouncycastle.crypto.params.RC5Parameters;
+// import org.bouncycastle.jcajce.PBKDF1Key;
+// import org.bouncycastle.jcajce.PBKDF1KeyWithParameters;
+// END android-removed
+import org.bouncycastle.jcajce.PKCS12Key;
+import org.bouncycastle.jcajce.PKCS12KeyWithParameters;
+// BEGIN android-removed
// import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec;
// import org.bouncycastle.jcajce.spec.RepeatedSecretKeySpec;
// END android-removed
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.Strings;
public class BaseBlockCipher
@@ -90,12 +96,12 @@ public class BaseBlockCipher
// RC2ParameterSpec.class,
// RC5ParameterSpec.class,
// END android-removed
+ gcmSpecClass,
IvParameterSpec.class,
PBEParameterSpec.class,
// BEGIN android-removed
- // GOST28147ParameterSpec.class,
+ // GOST28147ParameterSpec.class
// END android-removed
- gcmSpecClass
};
private BlockCipher baseEngine;
@@ -104,10 +110,14 @@ public class BaseBlockCipher
private ParametersWithIV ivParam;
private AEADParameters aeadParams;
+ private int keySizeInBits;
+ private int scheme = -1;
+ private int digest;
+
private int ivLength = 0;
private boolean padded;
-
+ private boolean fixedIv = true;
private PBEParameterSpec pbeSpec = null;
private String pbeAlgorithm = null;
@@ -136,6 +146,23 @@ public class BaseBlockCipher
}
protected BaseBlockCipher(
+ BlockCipher engine,
+ int scheme,
+ int digest,
+ int keySizeInBits,
+ int ivLength)
+ {
+ baseEngine = engine;
+
+ this.scheme = scheme;
+ this.digest = digest;
+ this.keySizeInBits = keySizeInBits;
+ this.ivLength = ivLength;
+
+ cipher = new BufferedGenericBlockCipher(engine);
+ }
+
+ protected BaseBlockCipher(
BlockCipherProvider provider)
{
baseEngine = provider.get();
@@ -153,6 +180,17 @@ public class BaseBlockCipher
}
protected BaseBlockCipher(
+ AEADBlockCipher engine,
+ boolean fixedIv,
+ int ivLength)
+ {
+ this.baseEngine = engine.getUnderlyingCipher();
+ this.fixedIv = fixedIv;
+ this.ivLength = ivLength;
+ this.cipher = new AEADGenericBlockCipher(engine);
+ }
+
+ protected BaseBlockCipher(
org.bouncycastle.crypto.BlockCipher engine,
int ivLength)
{
@@ -239,7 +277,7 @@ public class BaseBlockCipher
try
{
engineParams = createParametersInstance("GCM");
- engineParams.init(new GCMParameters(aeadParams.getNonce(), aeadParams.getMacSize()).getEncoded());
+ engineParams.init(new GCMParameters(aeadParams.getNonce(), aeadParams.getMacSize() / 8).getEncoded());
}
catch (Exception e)
{
@@ -322,6 +360,7 @@ public class BaseBlockCipher
// {
// throw new IllegalArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)");
// }
+ // fixedIv = false;
// cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
// new SICBlockCipher(baseEngine)));
// }
@@ -329,6 +368,7 @@ public class BaseBlockCipher
else if (modeName.startsWith("CTR"))
{
ivLength = baseEngine.getBlockSize();
+ fixedIv = false;
cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
new SICBlockCipher(baseEngine)));
}
@@ -478,7 +518,81 @@ public class BaseBlockCipher
//
// a note on iv's - if ivLength is zero the IV gets ignored (we don't use it).
//
- if (key instanceof BCPBEKey)
+ if (scheme == PKCS12 || key instanceof PKCS12Key)
+ {
+ SecretKey k;
+ try
+ {
+ k = (SecretKey)key;
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeyException("PKCS12 requires a SecretKey/PBEKey");
+ }
+
+ if (params instanceof PBEParameterSpec)
+ {
+ pbeSpec = (PBEParameterSpec)params;
+ }
+
+ if (k instanceof PBEKey && pbeSpec == null)
+ {
+ // BEGIN android-added
+ if (((PBEKey)k).getSalt() == null) {
+ // TODO(27061541): check whether this is the correct fix
+ throw new InvalidAlgorithmParameterException("Parameters for the algorithm are null "
+ + "and the PBEKey has null salt");
+ }
+ // END android-added
+ pbeSpec = new PBEParameterSpec(((PBEKey)k).getSalt(), ((PBEKey)k).getIterationCount());
+ }
+
+ if (pbeSpec == null && !(k instanceof PBEKey))
+ {
+ throw new InvalidKeyException("Algorithm requires a PBE key");
+ }
+ if (key instanceof BCPBEKey)
+ {
+ if (((BCPBEKey)key).getParam() != null)
+ {
+ param = ((BCPBEKey)key).getParam();
+ }
+ else
+ {
+ param = PBE.Util.makePBEParameters(k.getEncoded(), PKCS12, digest, keySizeInBits, ivLength * 8, pbeSpec, cipher.getAlgorithmName());
+ }
+ }
+ else
+ {
+ param = PBE.Util.makePBEParameters(k.getEncoded(), PKCS12, digest, keySizeInBits, ivLength * 8, pbeSpec, cipher.getAlgorithmName());
+ }
+ if (param instanceof ParametersWithIV)
+ {
+ ivParam = (ParametersWithIV)param;
+ }
+ }
+ // BEGIN android-removed
+ // else if (key instanceof PBKDF1Key)
+ // {
+ // PBKDF1Key k = (PBKDF1Key)key;
+
+ // if (params instanceof PBEParameterSpec)
+ // {
+ // pbeSpec = (PBEParameterSpec)params;
+ // }
+ // if (k instanceof PBKDF1KeyWithParameters && pbeSpec == null)
+ // {
+ // pbeSpec = new PBEParameterSpec(((PBKDF1KeyWithParameters)k).getSalt(), ((PBKDF1KeyWithParameters)k).getIterationCount());
+ // }
+
+ // param = PBE.Util.makePBEParameters(k.getEncoded(), PKCS5S1, digest, keySizeInBits, ivLength * 8, pbeSpec, cipher.getAlgorithmName());
+ // if (param instanceof ParametersWithIV)
+ // {
+ // ivParam = (ParametersWithIV)param;
+ // }
+ // }
+ // END android-removed
+ else if (key instanceof BCPBEKey)
{
BCPBEKey k = (BCPBEKey)key;
@@ -493,27 +607,7 @@ public class BaseBlockCipher
if (k.getParam() != null)
{
- param = k.getParam();
- if (params instanceof IvParameterSpec)
- {
- IvParameterSpec iv = (IvParameterSpec)params;
-
- param = new ParametersWithIV(param, iv.getIV());
- }
- // BEGIN android-removed
- // else if (params instanceof GOST28147ParameterSpec)
- // {
- // // need to pick up IV and SBox.
- // GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params;
- //
- // param = new ParametersWithSBox(param, gost28147Param.getSbox());
- //
- // if (gost28147Param.getIV() != null && ivLength != 0)
- // {
- // param = new ParametersWithIV(param, gost28147Param.getIV());
- // }
- // }
- // END android-removed
+ param = adjustParameters(params, k.getParam());
}
else if (params instanceof PBEParameterSpec)
{
@@ -530,33 +624,59 @@ public class BaseBlockCipher
ivParam = (ParametersWithIV)param;
}
}
- else if (params == null)
+ else if (key instanceof PBEKey)
{
+ PBEKey k = (PBEKey)key;
+ pbeSpec = (PBEParameterSpec)params;
+ if (k instanceof PKCS12KeyWithParameters && pbeSpec == null)
+ {
+ pbeSpec = new PBEParameterSpec(k.getSalt(), k.getIterationCount());
+ }
+
+ param = PBE.Util.makePBEParameters(k.getEncoded(), scheme, digest, keySizeInBits, ivLength * 8, pbeSpec, cipher.getAlgorithmName());
+ if (param instanceof ParametersWithIV)
+ {
+ ivParam = (ParametersWithIV)param;
+ }
+ }
+ // BEGIN android-changed
+ // Was: else if (!(key instanceof RepeatedSecretKeySpec))
+ else
+ // END android-changed
+ {
+ if (scheme == PKCS5S1 || scheme == PKCS5S1_UTF8 || scheme == PKCS5S2 || scheme == PKCS5S2_UTF8)
+ {
+ throw new InvalidKeyException("Algorithm requires a PBE key");
+ }
param = new KeyParameter(key.getEncoded());
}
- else if (params instanceof IvParameterSpec)
+ // BEGIN android-removed
+ // else
+ // {
+ // param = null;
+ // }
+ // END android-removed
+
+ if (params instanceof IvParameterSpec)
{
if (ivLength != 0)
{
IvParameterSpec p = (IvParameterSpec)params;
- if (p.getIV().length != ivLength && !isAEADModeName(modeName))
+ if (p.getIV().length != ivLength && !(cipher instanceof AEADGenericBlockCipher) && fixedIv)
{
throw new InvalidAlgorithmParameterException("IV must be " + ivLength + " bytes long.");
}
- // BEGIN android-removed
- // if (key instanceof RepeatedSecretKeySpec)
- // {
- // param = new ParametersWithIV(null, p.getIV());
- // ivParam = (ParametersWithIV)param;
- // }
- // else
- // END android-removed
+ if (param instanceof ParametersWithIV)
+ {
+ param = new ParametersWithIV(((ParametersWithIV)param).getParameters(), p.getIV());
+ }
+ else
{
- param = new ParametersWithIV(new KeyParameter(key.getEncoded()), p.getIV());
- ivParam = (ParametersWithIV)param;
+ param = new ParametersWithIV(param, p.getIV());
}
+ ivParam = (ParametersWithIV)param;
}
else
{
@@ -564,8 +684,6 @@ public class BaseBlockCipher
{
throw new InvalidAlgorithmParameterException("ECB mode does not use an IV");
}
-
- param = new KeyParameter(key.getEncoded());
}
}
// BEGIN android-removed
@@ -578,7 +696,14 @@ public class BaseBlockCipher
//
// if (gost28147Param.getIV() != null && ivLength != 0)
// {
- // param = new ParametersWithIV(param, gost28147Param.getIV());
+ // if (param instanceof ParametersWithIV)
+ // {
+ // param = new ParametersWithIV(((ParametersWithIV)param).getParameters(), gost28147Param.getIV());
+ // }
+ // else
+ // {
+ // param = new ParametersWithIV(param, gost28147Param.getIV());
+ // }
// ivParam = (ParametersWithIV)param;
// }
// }
@@ -590,7 +715,14 @@ public class BaseBlockCipher
//
// if (rc2Param.getIV() != null && ivLength != 0)
// {
- // param = new ParametersWithIV(param, rc2Param.getIV());
+ // if (param instanceof ParametersWithIV)
+ // {
+ // param = new ParametersWithIV(((ParametersWithIV)param).getParameters(), rc2Param.getIV());
+ // }
+ // else
+ // {
+ // param = new ParametersWithIV(param, rc2Param.getIV());
+ // }
// ivParam = (ParametersWithIV)param;
// }
// }
@@ -622,7 +754,14 @@ public class BaseBlockCipher
// }
// if ((rc5Param.getIV() != null) && (ivLength != 0))
// {
- // param = new ParametersWithIV(param, rc5Param.getIV());
+ // if (param instanceof ParametersWithIV)
+ // {
+ // param = new ParametersWithIV(((ParametersWithIV)param).getParameters(), rc5Param.getIV());
+ // }
+ // else
+ // {
+ // param = new ParametersWithIV(param, rc5Param.getIV());
+ // }
// ivParam = (ParametersWithIV)param;
// }
// }
@@ -639,23 +778,23 @@ public class BaseBlockCipher
Method tLen = gcmSpecClass.getDeclaredMethod("getTLen", new Class[0]);
Method iv= gcmSpecClass.getDeclaredMethod("getIV", new Class[0]);
- // BEGIN android-removed
- // if (key instanceof RepeatedSecretKeySpec)
- // {
- // param = aeadParams = new AEADParameters(null, ((Integer)tLen.invoke(params, new Object[0])).intValue(), (byte[])iv.invoke(params, new Object[0]));
- // }
- // else
- // END android-removed
+ KeyParameter keyParam;
+ if (param instanceof ParametersWithIV)
+ {
+ keyParam = (KeyParameter)((ParametersWithIV)param).getParameters();
+ }
+ else
{
- param = aeadParams = new AEADParameters(new KeyParameter(key.getEncoded()), ((Integer)tLen.invoke(params, new Object[0])).intValue(), (byte[])iv.invoke(params, new Object[0]));
+ keyParam = (KeyParameter)param;
}
+ param = aeadParams = 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.");
}
}
- else
+ else if (params != null && !(params instanceof PBEParameterSpec))
{
throw new InvalidAlgorithmParameterException("unknown parameter type.");
}
@@ -704,12 +843,75 @@ public class BaseBlockCipher
throw new InvalidParameterException("unknown opmode " + opmode + " passed");
}
}
- catch (Exception e)
+ catch (final Exception e)
{
- throw new InvalidKeyException(e.getMessage());
+ throw new InvalidKeyException(e.getMessage())
+ {
+ public Throwable getCause()
+ {
+ return e;
+ }
+ };
}
}
+ private CipherParameters adjustParameters(AlgorithmParameterSpec params, CipherParameters param)
+ {
+ CipherParameters key;
+
+ if (param instanceof ParametersWithIV)
+ {
+ key = ((ParametersWithIV)param).getParameters();
+ if (params instanceof IvParameterSpec)
+ {
+ IvParameterSpec iv = (IvParameterSpec)params;
+
+ ivParam = new ParametersWithIV(key, iv.getIV());
+ param = ivParam;
+ }
+ // BEGIN android-removed
+ // else if (params instanceof GOST28147ParameterSpec)
+ // {
+ // // need to pick up IV and SBox.
+ // GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params;
+ //
+ // param = new ParametersWithSBox(param, gost28147Param.getSbox());
+ //
+ // if (gost28147Param.getIV() != null && ivLength != 0)
+ // {
+ // ivParam = new ParametersWithIV(key, gost28147Param.getIV());
+ // param = ivParam;
+ // }
+ // }
+ // END android-removed
+ }
+ else
+ {
+ if (params instanceof IvParameterSpec)
+ {
+ IvParameterSpec iv = (IvParameterSpec)params;
+
+ ivParam = new ParametersWithIV(param, iv.getIV());
+ param = ivParam;
+ }
+ // BEGIN android-removed
+ // else if (params instanceof GOST28147ParameterSpec)
+ // {
+ // // need to pick up IV and SBox.
+ // GOST28147ParameterSpec gost28147Param = (GOST28147ParameterSpec)params;
+ //
+ // param = new ParametersWithSBox(param, gost28147Param.getSbox());
+ //
+ // if (gost28147Param.getIV() != null && ivLength != 0)
+ // {
+ // param = new ParametersWithIV(param, gost28147Param.getIV());
+ // }
+ // }
+ // END android-removed
+ }
+ return param;
+ }
+
protected void engineInit(
int opmode,
Key key,
@@ -820,13 +1022,19 @@ public class BaseBlockCipher
int outputOffset)
throws ShortBufferException
{
+ if (outputOffset + cipher.getUpdateOutputSize(inputLen) > output.length)
+ {
+ throw new ShortBufferException("output buffer too short for input.");
+ }
+
try
{
return cipher.processBytes(input, inputOffset, inputLen, output, outputOffset);
}
catch (DataLengthException e)
{
- throw new ShortBufferException(e.getMessage());
+ // should never occur
+ throw new IllegalStateException(e.toString());
}
}
@@ -873,10 +1081,15 @@ public class BaseBlockCipher
int outputOffset)
throws IllegalBlockSizeException, BadPaddingException, ShortBufferException
{
- try
+ int len = 0;
+
+ if (outputOffset + engineGetOutputSize(inputLen) > output.length)
{
- int len = 0;
+ throw new ShortBufferException("output buffer too short for input.");
+ }
+ try
+ {
if (inputLen != 0)
{
len = cipher.processBytes(input, inputOffset, inputLen, output, outputOffset);
@@ -886,7 +1099,7 @@ public class BaseBlockCipher
}
catch (OutputLengthException e)
{
- throw new ShortBufferException(e.getMessage());
+ throw new IllegalBlockSizeException(e.getMessage());
}
catch (DataLengthException e)
{
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 d014972e..f6076170 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
@@ -9,6 +9,8 @@ import java.util.Iterator;
import java.util.Map;
import javax.crypto.MacSpi;
+import javax.crypto.SecretKey;
+import javax.crypto.interfaces.PBEKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEParameterSpec;
@@ -18,6 +20,9 @@ import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
// BEGIN android-removed
// import org.bouncycastle.crypto.params.SkeinParameters;
+// END android-removed
+import org.bouncycastle.jcajce.PKCS12Key;
+// BEGIN android-removed
// import org.bouncycastle.jcajce.spec.SkeinParameterSpec;
// END android-removed
@@ -26,7 +31,7 @@ public class BaseMac
{
private Mac macEngine;
- private int pbeType = PKCS12;
+ private int scheme = PKCS12;
private int pbeHash = SHA1;
private int keySize = 160;
@@ -38,12 +43,12 @@ public class BaseMac
protected BaseMac(
Mac macEngine,
- int pbeType,
+ int scheme,
int pbeHash,
int keySize)
{
this.macEngine = macEngine;
- this.pbeType = pbeType;
+ this.scheme = scheme;
this.pbeHash = pbeHash;
this.keySize = keySize;
}
@@ -60,7 +65,54 @@ public class BaseMac
throw new InvalidKeyException("key is null");
}
- if (key instanceof BCPBEKey)
+ if (key instanceof PKCS12Key)
+ {
+ SecretKey k;
+ PBEParameterSpec pbeSpec;
+
+ try
+ {
+ k = (SecretKey)key;
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeyException("PKCS12 requires a SecretKey/PBEKey");
+ }
+
+ try
+ {
+ pbeSpec = (PBEParameterSpec)params;
+ }
+ catch (Exception e)
+ {
+ throw new InvalidAlgorithmParameterException("PKCS12 requires a PBEParameterSpec");
+ }
+
+ if (k instanceof PBEKey && pbeSpec == null)
+ {
+ pbeSpec = new PBEParameterSpec(((PBEKey)k).getSalt(), ((PBEKey)k).getIterationCount());
+ }
+
+ int digest = SHA1;
+ int keySize = 160;
+ // BEGIN android-removed
+ // if (macEngine.getAlgorithmName().startsWith("GOST"))
+ // {
+ // digest = GOST3411;
+ // keySize = 256;
+ // }
+ // BEGIN android-changed
+ // Was: else if (macEngine.getAlgorithmName().startsWith("SHA256"))
+ if (macEngine.getAlgorithmName().startsWith("SHA256"))
+ // END android-changed
+ {
+ digest = SHA256;
+ keySize = 256;
+ }
+ // TODO: add correct handling for other digests
+ param = PBE.Util.makePBEMacParameters(k, PKCS12, digest, keySize, pbeSpec);
+ }
+ else if (key instanceof BCPBEKey)
{
BCPBEKey k = (BCPBEKey)key;
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 fba61b8d..ea3ac5b0 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
@@ -5,7 +5,6 @@ import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
import java.security.Key;
-import java.security.Provider;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
@@ -25,7 +24,8 @@ import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.StreamCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.jcajce.PKCS12Key;
+import org.bouncycastle.jcajce.PKCS12KeyWithParameters;
public class BaseStreamCipher
extends BaseWrapCipher
@@ -45,6 +45,8 @@ public class BaseStreamCipher
};
private StreamCipher cipher;
+ private int keySizeInBits;
+ private int digest;
private ParametersWithIV ivParam;
private int ivLength = 0;
@@ -56,8 +58,19 @@ public class BaseStreamCipher
StreamCipher engine,
int ivLength)
{
+ this(engine, ivLength, -1, -1);
+ }
+
+ protected BaseStreamCipher(
+ StreamCipher engine,
+ int ivLength,
+ int keySizeInBits,
+ int digest)
+ {
cipher = engine;
this.ivLength = ivLength;
+ this.keySizeInBits = keySizeInBits;
+ this.digest = digest;
}
protected int engineGetBlockSize()
@@ -152,7 +165,18 @@ public class BaseStreamCipher
throw new InvalidKeyException("Key for algorithm " + key.getAlgorithm() + " not suitable for symmetric enryption.");
}
- if (key instanceof BCPBEKey)
+ if (key instanceof PKCS12Key)
+ {
+ PKCS12Key k = (PKCS12Key)key;
+ pbeSpec = (PBEParameterSpec)params;
+ if (k instanceof PKCS12KeyWithParameters && pbeSpec == null)
+ {
+ pbeSpec = new PBEParameterSpec(((PKCS12KeyWithParameters)k).getSalt(), ((PKCS12KeyWithParameters)k).getIterationCount());
+ }
+
+ param = PBE.Util.makePBEParameters(k.getEncoded(), PKCS12, digest, keySizeInBits, ivLength * 8, pbeSpec, cipher.getAlgorithmName());
+ }
+ else if (key instanceof BCPBEKey)
{
BCPBEKey k = (BCPBEKey)key;
@@ -187,6 +211,10 @@ public class BaseStreamCipher
}
else if (params == null)
{
+ if (digest > 0)
+ {
+ throw new InvalidKeyException("Algorithm requires a PBE key");
+ }
param = new KeyParameter(key.getEncoded());
}
else if (params instanceof IvParameterSpec)
@@ -314,15 +342,21 @@ public class BaseStreamCipher
int outputOffset)
throws ShortBufferException
{
+ if (outputOffset + inputLen > output.length)
+ {
+ throw new ShortBufferException("output buffer too short for input.");
+ }
+
try
{
- cipher.processBytes(input, inputOffset, inputLen, output, outputOffset);
+ cipher.processBytes(input, inputOffset, inputLen, output, outputOffset);
- return inputLen;
+ return inputLen;
}
catch (DataLengthException e)
{
- throw new ShortBufferException(e.getMessage());
+ // should never happen
+ throw new IllegalStateException(e.getMessage());
}
}
@@ -350,8 +384,14 @@ public class BaseStreamCipher
int inputOffset,
int inputLen,
byte[] output,
- int outputOffset)
+ int outputOffset)
+ throws ShortBufferException
{
+ if (outputOffset + inputLen > output.length)
+ {
+ throw new ShortBufferException("output buffer too short for input.");
+ }
+
if (inputLen != 0)
{
cipher.processBytes(input, inputOffset, inputLen, output, outputOffset);
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 a26d9807..ece0d146 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
@@ -8,9 +8,7 @@ import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
-import java.security.Provider;
import java.security.SecureRandom;
-import java.security.Security;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
@@ -40,6 +38,7 @@ import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.jcajce.util.BCJcaJceHelper;
import org.bouncycastle.jcajce.util.JcaJceHelper;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.util.Arrays;
public abstract class BaseWrapCipher
extends CipherSpi
@@ -97,7 +96,7 @@ public abstract class BaseWrapCipher
protected byte[] engineGetIV()
{
- return (byte[])iv.clone();
+ return Arrays.clone(iv);
}
protected int engineGetKeySize(
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 c39a2d3d..8fead80a 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
@@ -1,7 +1,9 @@
package org.bouncycastle.jcajce.provider.symmetric.util;
+import java.security.InvalidAlgorithmParameterException;
import java.security.spec.AlgorithmParameterSpec;
+import javax.crypto.SecretKey;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
@@ -176,6 +178,70 @@ public interface PBE
}
/**
+ * construct a key and iv (if necessary) suitable for use with a
+ * Cipher.
+ */
+ public static CipherParameters makePBEParameters(
+ byte[] pbeKey,
+ int scheme,
+ int digest,
+ int keySize,
+ int ivSize,
+ AlgorithmParameterSpec spec,
+ String targetAlgorithm)
+ throws InvalidAlgorithmParameterException
+ {
+ if ((spec == null) || !(spec instanceof PBEParameterSpec))
+ {
+ throw new InvalidAlgorithmParameterException("Need a PBEParameter spec with a PBE key.");
+ }
+
+ PBEParameterSpec pbeParam = (PBEParameterSpec)spec;
+ PBEParametersGenerator generator = makePBEGenerator(scheme, digest);
+ byte[] key = pbeKey;
+ CipherParameters param;
+
+// if (pbeKey.shouldTryWrongPKCS12())
+// {
+// key = new byte[2];
+// }
+
+ generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount());
+
+ if (ivSize != 0)
+ {
+ param = generator.generateDerivedParameters(keySize, ivSize);
+ }
+ else
+ {
+ param = generator.generateDerivedParameters(keySize);
+ }
+
+ if (targetAlgorithm.startsWith("DES"))
+ {
+ if (param instanceof ParametersWithIV)
+ {
+ KeyParameter kParam = (KeyParameter)((ParametersWithIV)param).getParameters();
+
+ DESParameters.setOddParity(kParam.getKey());
+ }
+ else
+ {
+ KeyParameter kParam = (KeyParameter)param;
+
+ DESParameters.setOddParity(kParam.getKey());
+ }
+ }
+
+ for (int i = 0; i != key.length; i++)
+ {
+ key[i] = 0;
+ }
+
+ return param;
+ }
+
+ /**
* construct a key and iv (if necessary) suitable for use with a
* Cipher.
*/
@@ -252,11 +318,6 @@ public interface PBE
PBEParametersGenerator generator = makePBEGenerator(pbeKey.getType(), pbeKey.getDigest());
byte[] key = pbeKey.getEncoded();
CipherParameters param;
-
- if (pbeKey.shouldTryWrongPKCS12())
- {
- key = new byte[2];
- }
generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount());
@@ -269,7 +330,36 @@ public interface PBE
return param;
}
-
+
+ /**
+ * generate a PBE based key suitable for a MAC algorithm, the
+ * key size is chosen according the MAC size, or the hashing algorithm,
+ * whichever is greater.
+ */
+ public static CipherParameters makePBEMacParameters(
+ PBEKeySpec keySpec,
+ int type,
+ int hash,
+ int keySize)
+ {
+ PBEParametersGenerator generator = makePBEGenerator(type, hash);
+ byte[] key;
+ CipherParameters param;
+
+ key = convertPassword(type, keySpec);
+
+ generator.init(key, keySpec.getSalt(), keySpec.getIterationCount());
+
+ param = generator.generateDerivedMacParameters(keySize);
+
+ for (int i = 0; i != key.length; i++)
+ {
+ key[i] = 0;
+ }
+
+ return param;
+ }
+
/**
* construct a key and iv (if necessary) suitable for use with a
* Cipher.
@@ -306,31 +396,30 @@ public interface PBE
return param;
}
-
/**
* generate a PBE based key suitable for a MAC algorithm, the
* key size is chosen according the MAC size, or the hashing algorithm,
* whichever is greater.
*/
public static CipherParameters makePBEMacParameters(
- PBEKeySpec keySpec,
+ SecretKey key,
int type,
int hash,
- int keySize)
+ int keySize,
+ PBEParameterSpec pbeSpec)
{
PBEParametersGenerator generator = makePBEGenerator(type, hash);
- byte[] key;
CipherParameters param;
- key = convertPassword(type, keySpec);
+ byte[] keyBytes = key.getEncoded();
- generator.init(key, keySpec.getSalt(), keySpec.getIterationCount());
+ generator.init(key.getEncoded(), pbeSpec.getSalt(), pbeSpec.getIterationCount());
param = generator.generateDerivedMacParameters(keySize);
- for (int i = 0; i != key.length; i++)
+ for (int i = 0; i != keyBytes.length; i++)
{
- key[i] = 0;
+ keyBytes[i] = 0;
}
return param;
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/util/DigestFactory.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/util/DigestFactory.java
index 19ca6b1d..ce8bb363 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/util/DigestFactory.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/util/DigestFactory.java
@@ -17,6 +17,7 @@ import org.bouncycastle.crypto.Digest;
// import org.bouncycastle.crypto.digests.SHA256Digest;
// import org.bouncycastle.crypto.digests.SHA384Digest;
// import org.bouncycastle.crypto.digests.SHA512Digest;
+// import org.bouncycastle.crypto.digests.SHA512tDigest;
// END android-removed
// BEGIN android-added
import org.bouncycastle.crypto.digests.AndroidDigestFactory;
@@ -31,7 +32,11 @@ public class DigestFactory
private static Set sha256 = new HashSet();
private static Set sha384 = new HashSet();
private static Set sha512 = new HashSet();
-
+ // BEGIN android-removed
+ // private static Set sha512_224 = new HashSet();
+ // private static Set sha512_256 = new HashSet();
+ // END android-removed
+
private static Map oids = new HashMap();
static
@@ -59,6 +64,16 @@ public class DigestFactory
sha512.add("SHA-512");
sha512.add(NISTObjectIdentifiers.id_sha512.getId());
+ // BEGIN android-removed
+ // sha512_224.add("SHA512(224)");
+ // sha512_224.add("SHA-512(224)");
+ // sha512_224.add(NISTObjectIdentifiers.id_sha512_224.getId());
+
+ // sha512_256.add("SHA512(256)");
+ // sha512_256.add("SHA-512(256)");
+ // sha512_256.add(NISTObjectIdentifiers.id_sha512_256.getId());
+ // END android-removed
+
oids.put("MD5", PKCSObjectIdentifiers.md5);
oids.put(PKCSObjectIdentifiers.md5.getId(), PKCSObjectIdentifiers.md5);
@@ -80,7 +95,15 @@ public class DigestFactory
oids.put("SHA512", NISTObjectIdentifiers.id_sha512);
oids.put("SHA-512", NISTObjectIdentifiers.id_sha512);
- oids.put(NISTObjectIdentifiers.id_sha512.getId(), NISTObjectIdentifiers.id_sha512);
+ oids.put(NISTObjectIdentifiers.id_sha512.getId(), NISTObjectIdentifiers.id_sha512);
+
+ oids.put("SHA512(224)", NISTObjectIdentifiers.id_sha512_224);
+ oids.put("SHA-512(224)", NISTObjectIdentifiers.id_sha512_224);
+ oids.put(NISTObjectIdentifiers.id_sha512_224.getId(), NISTObjectIdentifiers.id_sha512_224);
+
+ oids.put("SHA512(256)", NISTObjectIdentifiers.id_sha512_256);
+ oids.put("SHA-512(256)", NISTObjectIdentifiers.id_sha512_256);
+ oids.put(NISTObjectIdentifiers.id_sha512_256.getId(), NISTObjectIdentifiers.id_sha512_256);
}
public static Digest getDigest(
@@ -124,7 +147,17 @@ public class DigestFactory
return AndroidDigestFactory.getSHA512();
// END android-changed
}
-
+ // BEGIN android-removed
+ // if (sha512_224.contains(digestName))
+ // {
+ // return new SHA512tDigest(224);
+ // }
+ // if (sha512_256.contains(digestName))
+ // {
+ // return new SHA512tDigest(256);
+ // }
+ // END android-removed
+
return null;
}
@@ -137,6 +170,10 @@ public class DigestFactory
|| (sha256.contains(digest1) && sha256.contains(digest2))
|| (sha384.contains(digest1) && sha384.contains(digest2))
|| (sha512.contains(digest1) && sha512.contains(digest2))
+ // BEGIN android-removed
+ // || (sha512_224.contains(digest1) && sha512_224.contains(digest2))
+ // || (sha512_256.contains(digest1) && sha512_256.contains(digest2))
+ // END android-removed
|| (md5.contains(digest1) && md5.contains(digest2));
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/spec/PBKDF2KeySpec.java b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/PBKDF2KeySpec.java
index 09a9bd0b..df0c1454 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/spec/PBKDF2KeySpec.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/PBKDF2KeySpec.java
@@ -18,7 +18,7 @@ public class PBKDF2KeySpec
* @param password password to use as the seed of the PBE key generator.
* @param salt salt to use in the generator,
* @param iterationCount iteration count to use in the generator.
- * @param keySize size of the key to be generated.
+ * @param keySize size of the key to be generated (in bits).
* @param prf identifier and parameters for the PRF algorithm to use.
*/
public PBKDF2KeySpec(char[] password, byte[] salt, int iterationCount, int keySize, AlgorithmIdentifier prf)
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/spec/UserKeyingMaterialSpec.java b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/UserKeyingMaterialSpec.java
new file mode 100644
index 00000000..d8135310
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/UserKeyingMaterialSpec.java
@@ -0,0 +1,21 @@
+package org.bouncycastle.jcajce.spec;
+
+import java.security.spec.AlgorithmParameterSpec;
+
+import org.bouncycastle.util.Arrays;
+
+public class UserKeyingMaterialSpec
+ implements AlgorithmParameterSpec
+{
+ private final byte[] userKeyingMaterial;
+
+ public UserKeyingMaterialSpec(byte[] userKeyingMaterial)
+ {
+ this.userKeyingMaterial = Arrays.clone(userKeyingMaterial);
+ }
+
+ public byte[] getUserKeyingMaterial()
+ {
+ return Arrays.clone(userKeyingMaterial);
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/AlgorithmParametersUtils.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/AlgorithmParametersUtils.java
new file mode 100644
index 00000000..4a1a92a5
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/AlgorithmParametersUtils.java
@@ -0,0 +1,68 @@
+/***************************************************************/
+/****** DO NOT EDIT THIS CLASS bc-java SOURCE FILE ******/
+/***************************************************************/
+package org.bouncycastle.jcajce.util;
+
+import java.io.IOException;
+import java.security.AlgorithmParameters;
+
+import org.bouncycastle.asn1.ASN1Encodable;
+import org.bouncycastle.asn1.ASN1Primitive;
+
+/**
+ * General JCA/JCE utility methods.
+ */
+public class AlgorithmParametersUtils
+{
+
+
+ private AlgorithmParametersUtils()
+ {
+
+ }
+
+ /**
+ * Extract an ASN.1 encodable from an AlgorithmParameters object.
+ *
+ * @param params the object to get the encoding used to create the return value.
+ * @return an ASN.1 object representing the primitives making up the params parameter.
+ * @throws IOException if an encoding cannot be extracted.
+ */
+ public static ASN1Encodable extractParameters(AlgorithmParameters params)
+ throws IOException
+ {
+ // we try ASN.1 explicitly first just in case and then role back to the default.
+ ASN1Encodable asn1Params;
+ try
+ {
+ asn1Params = ASN1Primitive.fromByteArray(params.getEncoded("ASN.1"));
+ }
+ catch (Exception ex)
+ {
+ asn1Params = ASN1Primitive.fromByteArray(params.getEncoded());
+ }
+
+ return asn1Params;
+ }
+
+ /**
+ * Load an AlgorithmParameters object with the passed in ASN.1 encodable - if possible.
+ *
+ * @param params the AlgorithmParameters object to be initialised.
+ * @param sParams the ASN.1 encodable to initialise params with.
+ * @throws IOException if the parameters cannot be initialised.
+ */
+ public static void loadParameters(AlgorithmParameters params, ASN1Encodable sParams)
+ throws IOException
+ {
+ // we try ASN.1 explicitly first just in case and then role back to the default.
+ try
+ {
+ params.init(sParams.toASN1Primitive().getEncoded(), "ASN.1");
+ }
+ catch (Exception ex)
+ {
+ params.init(sParams.toASN1Primitive().getEncoded());
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/JcaJceUtils.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/JcaJceUtils.java
index a082d897..51486012 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/JcaJceUtils.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/JcaJceUtils.java
@@ -32,6 +32,7 @@ public class JcaJceUtils
* @param params the object to get the encoding used to create the return value.
* @return an ASN.1 object representing the primitives making up the params parameter.
* @throws IOException if an encoding cannot be extracted.
+ * @deprecated use AlgorithmParametersUtils.extractParameters(AlgorithmParameters params)
*/
public static ASN1Encodable extractParameters(AlgorithmParameters params)
throws IOException
@@ -56,6 +57,7 @@ public class JcaJceUtils
* @param params the AlgorithmParameters object to be initialised.
* @param sParams the ASN.1 encodable to initialise params with.
* @throws IOException if the parameters cannot be initialised.
+ * @deprecated use AlgorithmParametersUtils.loadParameters(AlgorithmParameters params, ASN1Encodable sParams)
*/
public static void loadParameters(AlgorithmParameters params, ASN1Encodable sParams)
throws IOException
@@ -76,6 +78,7 @@ public class JcaJceUtils
*
* @param digestAlgOID the OID of the digest algorithm of interest.
* @return a string representing the standard name - the OID as a string if none available.
+ * @deprecated use MessageDigestUtils,getDigestName()
*/
public static String getDigestAlgName(
ASN1ObjectIdentifier digestAlgOID)
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/MessageDigestUtils.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/MessageDigestUtils.java
new file mode 100644
index 00000000..80ce603f
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/MessageDigestUtils.java
@@ -0,0 +1,63 @@
+package org.bouncycastle.jcajce.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+// BEGIN android-removed
+// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+// import org.bouncycastle.asn1.gnu.GNUObjectIdentifiers;
+// import org.bouncycastle.asn1.iso.ISOIECObjectIdentifiers;
+// END android-removed
+import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
+import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+// BEGIN android-removed
+// import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
+// END android-removed
+
+public class MessageDigestUtils
+{
+ private static Map<ASN1ObjectIdentifier, String> digestOidMap = new HashMap<ASN1ObjectIdentifier, String>();
+
+ static
+ {
+ // BEGIN android-removed
+ // digestOidMap.put(PKCSObjectIdentifiers.md2, "MD2");
+ // digestOidMap.put(PKCSObjectIdentifiers.md4, "MD4");
+ // END android-removed
+ digestOidMap.put(PKCSObjectIdentifiers.md5, "MD5");
+ digestOidMap.put(OIWObjectIdentifiers.idSHA1, "SHA-1");
+ digestOidMap.put(NISTObjectIdentifiers.id_sha224, "SHA-224");
+ digestOidMap.put(NISTObjectIdentifiers.id_sha256, "SHA-256");
+ digestOidMap.put(NISTObjectIdentifiers.id_sha384, "SHA-384");
+ digestOidMap.put(NISTObjectIdentifiers.id_sha512, "SHA-512");
+ // BEGIN android-removed
+ // digestOidMap.put(TeleTrusTObjectIdentifiers.ripemd128, "RIPEMD-128");
+ // digestOidMap.put(TeleTrusTObjectIdentifiers.ripemd160, "RIPEMD-160");
+ // digestOidMap.put(TeleTrusTObjectIdentifiers.ripemd256, "RIPEMD-128");
+ // digestOidMap.put(ISOIECObjectIdentifiers.ripemd128, "RIPEMD-128");
+ // digestOidMap.put(ISOIECObjectIdentifiers.ripemd160, "RIPEMD-160");
+ // digestOidMap.put(CryptoProObjectIdentifiers.gostR3411, "GOST3411");
+ // digestOidMap.put(GNUObjectIdentifiers.Tiger_192, "Tiger");
+ // digestOidMap.put(ISOIECObjectIdentifiers.whirlpool, "Whirlpool");
+ // END android-removed
+ }
+
+ /**
+ * Attempt to find a standard JCA name for the digest represented by the passed in OID.
+ *
+ * @param digestAlgOID the OID of the digest algorithm of interest.
+ * @return a string representing the standard name - the OID as a string if none available.
+ */
+ public static String getDigestName(ASN1ObjectIdentifier digestAlgOID)
+ {
+ String name = (String)digestOidMap.get(digestAlgOID); // for pre 1.5 JDK
+ if (name != null)
+ {
+ return name;
+ }
+
+ return digestAlgOID.getId();
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java b/bcprov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java
index 36706950..0c41c882 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/PKCS10CertificationRequest.java
@@ -363,7 +363,7 @@ public class PKCS10CertificationRequest
try
{
ASN1Sequence seq = (ASN1Sequence)ASN1Primitive.fromByteArray(key.getEncoded());
- this.reqInfo = new CertificationRequestInfo(subject, new SubjectPublicKeyInfo(seq), attributes);
+ this.reqInfo = new CertificationRequestInfo(subject, SubjectPublicKeyInfo.getInstance(seq), attributes);
}
catch (IOException e)
{
@@ -414,7 +414,7 @@ public class PKCS10CertificationRequest
try
{
- X509EncodedKeySpec xspec = new X509EncodedKeySpec(new DERBitString(subjectPKInfo).getBytes());
+ X509EncodedKeySpec xspec = new X509EncodedKeySpec(new DERBitString(subjectPKInfo).getOctets());
AlgorithmIdentifier keyAlg = subjectPKInfo.getAlgorithm();
try
{
@@ -432,9 +432,9 @@ public class PKCS10CertificationRequest
//
// try an alternate
//
- if (keyAlgorithms.get(keyAlg.getObjectId()) != null)
+ if (keyAlgorithms.get(keyAlg.getAlgorithm()) != null)
{
- String keyAlgorithm = (String)keyAlgorithms.get(keyAlg.getObjectId());
+ String keyAlgorithm = (String)keyAlgorithms.get(keyAlg.getAlgorithm());
if (provider == null)
{
@@ -507,9 +507,9 @@ public class PKCS10CertificationRequest
//
// try an alternate
//
- if (oids.get(sigAlgId.getObjectId()) != null)
+ if (oids.get(sigAlgId.getAlgorithm()) != null)
{
- String signatureAlgorithm = (String)oids.get(sigAlgId.getObjectId());
+ String signatureAlgorithm = (String)oids.get(sigAlgId.getAlgorithm());
if (provider == null)
{
@@ -539,7 +539,7 @@ public class PKCS10CertificationRequest
throw new SignatureException("exception encoding TBS cert request - " + e);
}
- return sig.verify(sigBits.getBytes());
+ return sig.verify(sigBits.getOctets());
}
/**
@@ -596,14 +596,14 @@ public class PKCS10CertificationRequest
if (params != null && !DERNull.INSTANCE.equals(params))
{
- if (sigAlgId.getObjectId().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
+ if (sigAlgId.getAlgorithm().equals(PKCSObjectIdentifiers.id_RSASSA_PSS))
{
RSASSAPSSparams rsaParams = RSASSAPSSparams.getInstance(params);
- return getDigestAlgName(rsaParams.getHashAlgorithm().getObjectId()) + "withRSAandMGF1";
+ return getDigestAlgName(rsaParams.getHashAlgorithm().getAlgorithm()) + "withRSAandMGF1";
}
}
- return sigAlgId.getObjectId().getId();
+ return sigAlgId.getAlgorithm().getId();
}
private static String getDigestAlgName(
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java b/bcprov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java
index 39dd35ad..f8a1a6fd 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/netscape/NetscapeCertRequest.java
@@ -86,9 +86,8 @@ public class NetscapeCertRequest
+ spkac.size());
}
- sigAlg = new AlgorithmIdentifier((ASN1Sequence)spkac
- .getObjectAt(1));
- sigBits = ((DERBitString)spkac.getObjectAt(2)).getBytes();
+ sigAlg = AlgorithmIdentifier.getInstance(spkac.getObjectAt(1));
+ sigBits = ((DERBitString)spkac.getObjectAt(2)).getOctets();
//
// PublicKeyAndChallenge ::= SEQUENCE {
@@ -110,14 +109,13 @@ public class NetscapeCertRequest
//could potentially alter the bytes
content = new DERBitString(pkac);
- SubjectPublicKeyInfo pubkeyinfo = new SubjectPublicKeyInfo(
- (ASN1Sequence)pkac.getObjectAt(0));
+ SubjectPublicKeyInfo pubkeyinfo = SubjectPublicKeyInfo.getInstance(pkac.getObjectAt(0));
X509EncodedKeySpec xspec = new X509EncodedKeySpec(new DERBitString(
pubkeyinfo).getBytes());
- keyAlg = pubkeyinfo.getAlgorithmId();
- pubkey = KeyFactory.getInstance(keyAlg.getObjectId().getId(), "BC")
+ keyAlg = pubkeyinfo.getAlgorithm();
+ pubkey = KeyFactory.getInstance(keyAlg.getAlgorithm().getId(), "BC")
.generatePublic(xspec);
}
@@ -205,7 +203,7 @@ public class NetscapeCertRequest
// Verify the signature .. shows the response was generated
// by someone who knew the associated private key
//
- Signature sig = Signature.getInstance(sigAlg.getObjectId().getId(),
+ Signature sig = Signature.getInstance(sigAlg.getAlgorithm().getId(),
"BC");
sig.initVerify(pubkey);
sig.update(content.getBytes());
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 82c6a5a8..00f23e8d 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java
@@ -44,7 +44,7 @@ import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
public final class BouncyCastleProvider extends Provider
implements ConfigurableProvider
{
- private static String info = "BouncyCastle Security Provider v1.52";
+ private static String info = "BouncyCastle Security Provider v1.54";
public static final String PROVIDER_NAME = "BC";
@@ -74,8 +74,8 @@ public final class BouncyCastleProvider extends Provider
// BEGIN android-removed
// "AES", "ARC4", "Blowfish", "Camellia", "CAST5", "CAST6", "ChaCha", "DES", "DESede",
// "GOST28147", "Grainv1", "Grain128", "HC128", "HC256", "IDEA", "Noekeon", "RC2", "RC5",
- // "RC6", "Rijndael", "Salsa20", "SEED", "Serpent", "Shacal2", "Skipjack", "TEA", "Twofish", "Threefish",
- // "VMPC", "VMPCKSA3", "XTEA", "XSalsa20"
+ // "RC6", "Rijndael", "Salsa20", "SEED", "Serpent", "Shacal2", "Skipjack", "SM4", "TEA", "Twofish", "Threefish",
+ // "VMPC", "VMPCKSA3", "XTEA", "XSalsa20", "OpenSSLPBKDF"
// END android-removed
// BEGIN android-added
"AES", "ARC4", "Blowfish", "DES", "DESede", "RC2", "Twofish",
@@ -116,7 +116,8 @@ public final class BouncyCastleProvider extends Provider
private static final String[] DIGESTS =
{
// BEGIN android-removed
- // "GOST3411", "MD2", "MD4", "MD5", "SHA1", "RIPEMD128", "RIPEMD160", "RIPEMD256", "RIPEMD320", "SHA224", "SHA256", "SHA384", "SHA512", "SHA3", "Skein", "SM3", "Tiger", "Whirlpool"
+ // "GOST3411", "Keccak", "MD2", "MD4", "MD5", "SHA1", "RIPEMD128", "RIPEMD160", "RIPEMD256", "RIPEMD320", "SHA224",
+ // "SHA256", "SHA384", "SHA512", "SHA3", "Skein", "SM3", "Tiger", "Whirlpool", "Blake2b"
// END android-removed
// BEGIN android-added
"MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512",
@@ -139,7 +140,7 @@ public final class BouncyCastleProvider extends Provider
*/
public BouncyCastleProvider()
{
- super(PROVIDER_NAME, 1.52, info);
+ super(PROVIDER_NAME, 1.54, info);
AccessController.doPrivileged(new PrivilegedAction()
{
@@ -276,6 +277,12 @@ public final class BouncyCastleProvider extends Provider
put(key, value);
}
+ public void addAlgorithm(String type, ASN1ObjectIdentifier oid, String className)
+ {
+ addAlgorithm(type + "." + oid, className);
+ addAlgorithm(type + ".OID." + oid, className);
+ }
+
public void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter)
{
keyInfoConverters.put(oid, keyInfoConverter);
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 f53f3ac7..b6a9d6a5 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/CertPathValidatorUtilities.java
@@ -35,6 +35,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+
import javax.security.auth.x500.X500Principal;
import org.bouncycastle.asn1.ASN1Encodable;
@@ -720,14 +721,7 @@ class CertPathValidatorUtilities
for (int j = 0; j < genNames.length; j++)
{
- // BEGIN android-removed
- // PKIXCRLStore store = namedCRLStoreMap.get(genNames[i]);
- // END android-removed
- // BEGIN android-added
- // Seems like a bug, unless there should be a guarantee that j < i,
- // However, it's breaking the tests.
PKIXCRLStore store = namedCRLStoreMap.get(genNames[j]);
- // END android-added
if (store != null)
{
stores.add(store);
@@ -900,25 +894,16 @@ class CertPathValidatorUtilities
{
return;
}
- // BEGIN android-removed
- // X500Name certIssuer = X500Name.getInstance(crl_entry.getCertificateIssuer().getEncoded());
- // END android-removed
- // BEGIN android-added
- // The original code throws null pointer exception for OpenSSLX509CRL,
- // which uses the implementation for getCertificateIssuer() in X509CRL, method
- // whose reference implementation has the following JavaDoc: "If the certificate
- // issuer is also the CRL issuer, this method returns null."
- X500Name certIssuer = null;
- X500Principal certificateIssuerPrincipal = crl_entry.getCertificateIssuer();
- if (certificateIssuerPrincipal != null) {
- certIssuer = X500Name.getInstance(certificateIssuerPrincipal.getEncoded());
- }
- // END android-added
-
- if (certIssuer == null)
+ X500Principal certificateIssuer = crl_entry.getCertificateIssuer();
+ X500Name certIssuer;
+ if (certificateIssuer == null)
{
certIssuer = PrincipalUtils.getIssuerPrincipal(crl);
}
+ else
+ {
+ certIssuer = X500Name.getInstance(certificateIssuer.getEncoded());
+ }
if (! PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(certIssuer))
{
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 f5af73a8..20ca6f27 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPrivateKey.java
@@ -39,6 +39,7 @@ import org.bouncycastle.jce.interfaces.ECPointEncoder;
import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
import org.bouncycastle.jce.spec.ECNamedCurveSpec;
import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.util.Strings;
public class JCEECPrivateKey
implements ECPrivateKey, org.bouncycastle.jce.interfaces.ECPrivateKey, PKCS12BagAttributeCarrier, ECPointEncoder
@@ -432,7 +433,7 @@ public class JCEECPrivateKey
public String toString()
{
StringBuffer buf = new StringBuffer();
- String nl = System.getProperty("line.separator");
+ String nl = Strings.lineSeparator();
buf.append("EC Private Key").append(nl);
buf.append(" S: ").append(this.d.toString(16)).append(nl);
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 10dfb48e..94fb7289 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPublicKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCEECPublicKey.java
@@ -46,6 +46,7 @@ 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
implements ECPublicKey, org.bouncycastle.jce.interfaces.ECPublicKey, ECPointEncoder
@@ -191,7 +192,8 @@ public class JCEECPublicKey
private void populateFromPubKeyInfo(SubjectPublicKeyInfo info)
{
- // if (info.getAlgorithmId().getObjectId().equals(CryptoProObjectIdentifiers.gostR3410_2001))
+ // BEGIN android-removed
+ // if (info.getAlgorithmId().getAlgorithm().equals(CryptoProObjectIdentifiers.gostR3410_2001))
// {
// DERBitString bits = info.getPublicKeyData();
// ASN1OctetString key;
@@ -478,7 +480,7 @@ public class JCEECPublicKey
public String toString()
{
StringBuffer buf = new StringBuffer();
- String nl = System.getProperty("line.separator");
+ String nl = Strings.lineSeparator();
buf.append("EC Public Key").append(nl);
buf.append(" X: ").append(this.q.getAffineXCoord().toBigInteger().toString(16)).append(nl);
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java
index f9bb5dd3..40f007f3 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPrivateCrtKey.java
@@ -12,6 +12,7 @@ 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.util.Strings;
/**
* A provider representation for a RSA private key, with CRT factors included.
@@ -224,7 +225,7 @@ public class JCERSAPrivateCrtKey
public String toString()
{
StringBuffer buf = new StringBuffer();
- String nl = System.getProperty("line.separator");
+ String nl = Strings.lineSeparator();
buf.append("RSA Private CRT Key").append(nl);
buf.append(" modulus: ").append(this.getModulus().toString(16)).append(nl);
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPublicKey.java
index a09295d5..adf0e3e8 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPublicKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JCERSAPublicKey.java
@@ -5,14 +5,13 @@ import java.math.BigInteger;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.RSAPublicKeySpec;
-import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.asn1.x509.RSAPublicKeyStructure;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.crypto.params.RSAKeyParameters;
import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
+import org.bouncycastle.util.Strings;
public class JCERSAPublicKey
implements RSAPublicKey
@@ -48,7 +47,7 @@ public class JCERSAPublicKey
{
try
{
- RSAPublicKeyStructure pubKey = new RSAPublicKeyStructure((ASN1Sequence)info.parsePublicKey());
+ org.bouncycastle.asn1.pkcs.RSAPublicKey pubKey = org.bouncycastle.asn1.pkcs.RSAPublicKey.getInstance(info.parsePublicKey());
this.modulus = pubKey.getModulus();
this.publicExponent = pubKey.getPublicExponent();
@@ -91,7 +90,7 @@ public class JCERSAPublicKey
public byte[] getEncoded()
{
- return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKeyStructure(getModulus(), getPublicExponent()));
+ return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new org.bouncycastle.asn1.pkcs.RSAPublicKey(getModulus(), getPublicExponent()));
}
public int hashCode()
@@ -120,7 +119,7 @@ public class JCERSAPublicKey
public String toString()
{
StringBuffer buf = new StringBuffer();
- String nl = System.getProperty("line.separator");
+ String nl = Strings.lineSeparator();
buf.append("RSA Public Key").append(nl);
buf.append(" modulus: ").append(this.getModulus().toString(16)).append(nl);
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/JDKDSAPublicKey.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/JDKDSAPublicKey.java
index 80bbf3c5..95a1ad74 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/JDKDSAPublicKey.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/JDKDSAPublicKey.java
@@ -18,6 +18,7 @@ import org.bouncycastle.asn1.x509.DSAParameter;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.crypto.params.DSAPublicKeyParameters;
+import org.bouncycastle.util.Strings;
public class JDKDSAPublicKey
implements DSAPublicKey
@@ -126,7 +127,7 @@ public class JDKDSAPublicKey
public String toString()
{
StringBuffer buf = new StringBuffer();
- String nl = System.getProperty("line.separator");
+ String nl = Strings.lineSeparator();
buf.append("DSA Public Key").append(nl);
buf.append(" y: ").append(this.getY().toString(16)).append(nl);
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 b7133951..dfe9cef5 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathBuilderSpi.java
@@ -44,16 +44,6 @@ public class PKIXCertPathBuilderSpi
public CertPathBuilderResult engineBuild(CertPathParameters params)
throws CertPathBuilderException, InvalidAlgorithmParameterException
{
- if (!(params instanceof PKIXBuilderParameters)
- && !(params instanceof ExtendedPKIXBuilderParameters)
- && !(params instanceof PKIXExtendedBuilderParameters))
- {
- throw new InvalidAlgorithmParameterException(
- "Parameters must be an instance of "
- + PKIXBuilderParameters.class.getName() + " or "
- + PKIXExtendedBuilderParameters.class.getName() + ".");
- }
-
PKIXExtendedBuilderParameters paramsPKIX;
if (params instanceof PKIXBuilderParameters)
{
@@ -81,10 +71,17 @@ public class PKIXCertPathBuilderSpi
paramsPKIX = paramsBldrPKIXBldr.build();
}
- else
+ else if (params instanceof PKIXExtendedBuilderParameters)
{
paramsPKIX = (PKIXExtendedBuilderParameters)params;
}
+ else
+ {
+ throw new InvalidAlgorithmParameterException(
+ "Parameters must be an instance of "
+ + PKIXBuilderParameters.class.getName() + " or "
+ + PKIXExtendedBuilderParameters.class.getName() + ".");
+ }
Collection targets;
Iterator targetIter;
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 3fdedad0..5d49d889 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/PKIXCertPathValidatorSpi.java
@@ -25,6 +25,7 @@ import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
+import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.jcajce.PKIXExtendedBuilderParameters;
import org.bouncycastle.jcajce.PKIXExtendedParameters;
import org.bouncycastle.jcajce.util.BCJcaJceHelper;
@@ -56,12 +57,6 @@ public class PKIXCertPathValidatorSpi
throws CertPathValidatorException,
InvalidAlgorithmParameterException
{
- if (!(params instanceof CertPathParameters))
- {
- throw new InvalidAlgorithmParameterException("Parameters must be a " + PKIXParameters.class.getName()
- + " instance.");
- }
-
PKIXExtendedParameters paramsPKIX;
if (params instanceof PKIXParameters)
{
@@ -81,18 +76,14 @@ public class PKIXCertPathValidatorSpi
{
paramsPKIX = ((PKIXExtendedBuilderParameters)params).getBaseParameters();
}
- // BEGIN android-changed
- // else
else if (params instanceof PKIXExtendedParameters)
- // END android-changed
{
paramsPKIX = (PKIXExtendedParameters)params;
}
- // BEGIN android-added
- else {
- throw new InvalidAlgorithmParameterException("Expecting PKIX algorithm parameters");
+ else
+ {
+ throw new InvalidAlgorithmParameterException("Parameters must be a " + PKIXParameters.class.getName() + " instance.");
}
- // END android-added
if (paramsPKIX.getTrustAnchors() == null)
{
@@ -112,7 +103,7 @@ public class PKIXCertPathValidatorSpi
if (certs.isEmpty())
{
- throw new CertPathValidatorException("Certification path is empty.", null, certPath, 0);
+ throw new CertPathValidatorException("Certification path is empty.", null, certPath, -1);
}
// BEGIN android-added
{
@@ -476,6 +467,7 @@ public class PKIXCertPathValidatorSpi
criticalExtensions.remove(RFC3280CertPathUtilities.SUBJECT_ALTERNATIVE_NAME);
criticalExtensions.remove(RFC3280CertPathUtilities.NAME_CONSTRAINTS);
criticalExtensions.remove(RFC3280CertPathUtilities.CRL_DISTRIBUTION_POINTS);
+ criticalExtensions.remove(Extension.extendedKeyUsage.getId());
}
else
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLEntryObject.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLEntryObject.java
index 7e76a897..d5e23382 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLEntryObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLEntryObject.java
@@ -24,6 +24,7 @@ import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.TBSCertList;
import org.bouncycastle.asn1.x509.X509Extension;
+import org.bouncycastle.util.Strings;
/**
* The following extensions are listed in RFC 2459 as relevant to CRL Entries
@@ -259,7 +260,7 @@ public class X509CRLEntryObject extends X509CRLEntry
public String toString()
{
StringBuffer buf = new StringBuffer();
- String nl = System.getProperty("line.separator");
+ String nl = Strings.lineSeparator();
buf.append(" userCertificate: ").append(this.getSerialNumber()).append(nl);
buf.append(" revocationDate: ").append(this.getRevocationDate()).append(nl);
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 c9ee77c8..b6885ace 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java
@@ -6,6 +6,7 @@ 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;
@@ -41,6 +42,7 @@ import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.IssuingDistributionPoint;
import org.bouncycastle.asn1.x509.TBSCertList;
import org.bouncycastle.jce.X509Principal;
+import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
/**
@@ -201,21 +203,45 @@ public class X509CRLObject
}
public void verify(PublicKey key)
- throws CRLException, NoSuchAlgorithmException,
- InvalidKeyException, NoSuchProviderException, SignatureException
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, NoSuchProviderException, SignatureException
{
- verify(key, BouncyCastleProvider.PROVIDER_NAME);
+ Signature sig;
+
+ try
+ {
+ sig = Signature.getInstance(getSigAlgName(), BouncyCastleProvider.PROVIDER_NAME);
+ }
+ catch (Exception e)
+ {
+ sig = Signature.getInstance(getSigAlgName());
+ }
+
+ doVerify(key, sig);
}
public void verify(PublicKey key, String sigProvider)
throws CRLException, NoSuchAlgorithmException,
- InvalidKeyException, NoSuchProviderException, SignatureException
+ InvalidKeyException, NoSuchProviderException, SignatureException
{
- if (!c.getSignatureAlgorithm().equals(c.getTBSCertList().getSignature()))
+ Signature sig;
+
+ if (sigProvider != null)
{
- throw new CRLException("Signature algorithm on CertificateList does not match TBSCertList.");
+ sig = Signature.getInstance(getSigAlgName(), sigProvider);
+ }
+ else
+ {
+ sig = Signature.getInstance(getSigAlgName());
}
+ doVerify(key, sig);
+ }
+
+ public void verify(PublicKey key, Provider sigProvider)
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException
+ {
Signature sig;
if (sigProvider != null)
@@ -227,6 +253,18 @@ public class X509CRLObject
sig = Signature.getInstance(getSigAlgName());
}
+ doVerify(key, sig);
+ }
+
+ private void doVerify(PublicKey key, Signature sig)
+ throws CRLException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException
+ {
+ if (!c.getSignatureAlgorithm().equals(c.getTBSCertList().getSignature()))
+ {
+ throw new CRLException("Signature algorithm on CertificateList does not match TBSCertList.");
+ }
+
sig.initVerify(key);
sig.update(this.getTBSCertList());
@@ -353,7 +391,7 @@ public class X509CRLObject
public byte[] getSignature()
{
- return c.getSignature().getBytes();
+ return c.getSignature().getOctets();
}
public String getSigAlgName()
@@ -388,7 +426,7 @@ public class X509CRLObject
public String toString()
{
StringBuffer buf = new StringBuffer();
- String nl = System.getProperty("line.separator");
+ String nl = Strings.lineSeparator();
buf.append(" Version: ").append(this.getVersion()).append(
nl);
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java
index 0ae61d23..09703f4c 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java
@@ -32,6 +32,7 @@ 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;
@@ -65,6 +66,7 @@ import org.bouncycastle.jce.X509Principal;
import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Integers;
+import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
public class X509CertificateObject
@@ -104,7 +106,7 @@ public class X509CertificateObject
byte[] bytes = this.getExtensionBytes("2.5.29.15");
if (bytes != null)
{
- DERBitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes));
+ ASN1BitString bits = DERBitString.getInstance(ASN1Primitive.fromByteArray(bytes));
bytes = bits.getBytes();
int length = (bytes.length * 8) - bits.getPadBits();
@@ -234,7 +236,7 @@ public class X509CertificateObject
public byte[] getSignature()
{
- return c.getSignature().getBytes();
+ return c.getSignature().getOctets();
}
/**
@@ -664,7 +666,7 @@ public class X509CertificateObject
public String toString()
{
StringBuffer buf = new StringBuffer();
- String nl = System.getProperty("line.separator");
+ String nl = Strings.lineSeparator();
buf.append(" [0] Version: ").append(this.getVersion()).append(nl);
buf.append(" SerialNumber: ").append(this.getSerialNumber()).append(nl);
@@ -783,12 +785,42 @@ public class X509CertificateObject
throws CertificateException, NoSuchAlgorithmException,
InvalidKeyException, NoSuchProviderException, SignatureException
{
- String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
- Signature signature = Signature.getInstance(sigName, sigProvider);
+ String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
+ Signature signature;
+
+ if (sigProvider != null)
+ {
+ signature = Signature.getInstance(sigName, sigProvider);
+ }
+ else
+ {
+ signature = Signature.getInstance(sigName);
+ }
checkSignature(key, signature);
}
+ public final void verify(
+ PublicKey key,
+ Provider sigProvider)
+ throws CertificateException, NoSuchAlgorithmException,
+ InvalidKeyException, SignatureException
+ {
+ String sigName = X509SignatureUtil.getSignatureName(c.getSignatureAlgorithm());
+ Signature signature;
+
+ if (sigProvider != null)
+ {
+ signature = Signature.getInstance(sigName, sigProvider);
+ }
+ else
+ {
+ signature = Signature.getInstance(sigName);
+ }
+
+ checkSignature(key, signature);
+ }
+
private void checkSignature(
PublicKey key,
Signature signature)
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/spec/ECNamedCurveSpec.java b/bcprov/src/main/java/org/bouncycastle/jce/spec/ECNamedCurveSpec.java
index c1b5ccc6..36aa595e 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/spec/ECNamedCurveSpec.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/spec/ECNamedCurveSpec.java
@@ -1,6 +1,7 @@
package org.bouncycastle.jce.spec;
import java.math.BigInteger;
+import java.security.spec.ECField;
import java.security.spec.ECFieldF2m;
import java.security.spec.ECFieldFp;
import java.security.spec.ECPoint;
@@ -8,6 +9,10 @@ import java.security.spec.EllipticCurve;
import org.bouncycastle.math.ec.ECAlgorithms;
import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.math.field.FiniteField;
+import org.bouncycastle.math.field.Polynomial;
+import org.bouncycastle.math.field.PolynomialExtensionField;
+import org.bouncycastle.util.Arrays;
/**
* specification signifying that the curve parameters can also be
@@ -22,29 +27,24 @@ public class ECNamedCurveSpec
ECCurve curve,
byte[] seed)
{
- if (ECAlgorithms.isFpCurve(curve))
+ ECField field = convertField(curve.getField());
+ BigInteger a = curve.getA().toBigInteger(), b = curve.getB().toBigInteger();
+ return new EllipticCurve(field, a, b, seed);
+ }
+
+ private static ECField convertField(FiniteField field)
+ {
+ if (ECAlgorithms.isFpField(field))
{
- return new EllipticCurve(new ECFieldFp(curve.getField().getCharacteristic()), curve.getA().toBigInteger(), curve.getB().toBigInteger(), seed);
+ return new ECFieldFp(field.getCharacteristic());
}
- else
+ else //if (ECAlgorithms.isF2mField(curveField))
{
- ECCurve.F2m curveF2m = (ECCurve.F2m)curve;
- int ks[];
-
- if (curveF2m.isTrinomial())
- {
- ks = new int[] { curveF2m.getK1() };
-
- return new EllipticCurve(new ECFieldF2m(curveF2m.getM(), ks), curve.getA().toBigInteger(), curve.getB().toBigInteger(), seed);
- }
- else
- {
- ks = new int[] { curveF2m.getK3(), curveF2m.getK2(), curveF2m.getK1() };
-
- return new EllipticCurve(new ECFieldF2m(curveF2m.getM(), ks), curve.getA().toBigInteger(), curve.getB().toBigInteger(), seed);
- }
+ Polynomial poly = ((PolynomialExtensionField)field).getMinimalPolynomial();
+ int[] exponents = poly.getExponentsPresent();
+ int[] ks = Arrays.reverse(Arrays.copyOfRange(exponents, 1, exponents.length - 1));
+ return new ECFieldF2m(poly.getDegree(), ks);
}
-
}
private static ECPoint convertPoint(
diff --git a/bcprov/src/main/java/org/bouncycastle/math/Primes.java b/bcprov/src/main/java/org/bouncycastle/math/Primes.java
new file mode 100644
index 00000000..dc4c017c
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/math/Primes.java
@@ -0,0 +1,674 @@
+package org.bouncycastle.math;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
+import org.bouncycastle.crypto.Digest;
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.BigIntegers;
+
+/**
+ * Utility methods for generating primes and testing for primality.
+ */
+public abstract class Primes
+{
+ public static final int SMALL_FACTOR_LIMIT = 211;
+
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+ private static final BigInteger TWO = BigInteger.valueOf(2);
+ private static final BigInteger THREE = BigInteger.valueOf(3);
+
+ /**
+ * Used to return the output from the
+ * {@linkplain Primes#enhancedMRProbablePrimeTest(BigInteger, SecureRandom, int) Enhanced
+ * Miller-Rabin Probabilistic Primality Test}
+ */
+ public static class MROutput
+ {
+ private static MROutput probablyPrime()
+ {
+ return new MROutput(false, null);
+ }
+
+ private static MROutput provablyCompositeWithFactor(BigInteger factor)
+ {
+ return new MROutput(true, factor);
+ }
+
+ private static MROutput provablyCompositeNotPrimePower()
+ {
+ return new MROutput(true, null);
+ }
+
+ private boolean provablyComposite;
+ private BigInteger factor;
+
+ private MROutput(boolean provablyComposite, BigInteger factor)
+ {
+ this.provablyComposite = provablyComposite;
+ this.factor = factor;
+ }
+
+ public BigInteger getFactor()
+ {
+ return factor;
+ }
+
+ public boolean isProvablyComposite()
+ {
+ return provablyComposite;
+ }
+
+ public boolean isNotPrimePower()
+ {
+ return provablyComposite && factor == null;
+ }
+ }
+
+ /**
+ * Used to return the output from the
+ * {@linkplain Primes#generateSTRandomPrime(Digest, int, byte[]) Shawe-Taylor Random_Prime
+ * Routine}
+ */
+ public static class STOutput
+ {
+ private BigInteger prime;
+ private byte[] primeSeed;
+ private int primeGenCounter;
+
+ private STOutput(BigInteger prime, byte[] primeSeed, int primeGenCounter)
+ {
+ this.prime = prime;
+ this.primeSeed = primeSeed;
+ this.primeGenCounter = primeGenCounter;
+ }
+
+ public BigInteger getPrime()
+ {
+ return prime;
+ }
+
+ public byte[] getPrimeSeed()
+ {
+ return primeSeed;
+ }
+
+ public int getPrimeGenCounter()
+ {
+ return primeGenCounter;
+ }
+ }
+
+ /**
+ * FIPS 186-4 C.6 Shawe-Taylor Random_Prime Routine
+ *
+ * Construct a provable prime number using a hash function.
+ *
+ * @param hash
+ * the {@link Digest} instance to use (as "Hash()"). Cannot be null.
+ * @param length
+ * the length (in bits) of the prime to be generated. Must be at least 2.
+ * @param inputSeed
+ * the seed to be used for the generation of the requested prime. Cannot be null or
+ * empty.
+ * @return an {@link STOutput} instance containing the requested prime.
+ */
+ public static STOutput generateSTRandomPrime(Digest hash, int length, byte[] inputSeed)
+ {
+ if (hash == null)
+ {
+ throw new IllegalArgumentException("'hash' cannot be null");
+ }
+ if (length < 2)
+ {
+ throw new IllegalArgumentException("'length' must be >= 2");
+ }
+ if (inputSeed == null || inputSeed.length == 0)
+ {
+ throw new IllegalArgumentException("'inputSeed' cannot be null or empty");
+ }
+
+ return implSTRandomPrime(hash, length, Arrays.clone(inputSeed));
+ }
+
+ /**
+ * FIPS 186-4 C.3.2 Enhanced Miller-Rabin Probabilistic Primality Test
+ *
+ * Run several iterations of the Miller-Rabin algorithm with randomly-chosen bases. This is an
+ * alternative to {@link #isMRProbablePrime(BigInteger, SecureRandom, int)} that provides more
+ * information about a composite candidate, which may be useful when generating or validating
+ * RSA moduli.
+ *
+ * @param candidate
+ * the {@link BigInteger} instance to test for primality.
+ * @param random
+ * the source of randomness to use to choose bases.
+ * @param iterations
+ * the number of randomly-chosen bases to perform the test for.
+ * @return an {@link MROutput} instance that can be further queried for details.
+ */
+ public static MROutput enhancedMRProbablePrimeTest(BigInteger candidate, SecureRandom random, int iterations)
+ {
+ checkCandidate(candidate, "candidate");
+
+ if (random == null)
+ {
+ throw new IllegalArgumentException("'random' cannot be null");
+ }
+ if (iterations < 1)
+ {
+ throw new IllegalArgumentException("'iterations' must be > 0");
+ }
+
+ if (candidate.bitLength() == 2)
+ {
+ return MROutput.probablyPrime();
+ }
+ if (!candidate.testBit(0))
+ {
+ return MROutput.provablyCompositeWithFactor(TWO);
+ }
+
+ BigInteger w = candidate;
+ BigInteger wSubOne = candidate.subtract(ONE);
+ BigInteger wSubTwo = candidate.subtract(TWO);
+
+ int a = wSubOne.getLowestSetBit();
+ BigInteger m = wSubOne.shiftRight(a);
+
+ for (int i = 0; i < iterations; ++i)
+ {
+ BigInteger b = BigIntegers.createRandomInRange(TWO, wSubTwo, random);
+ BigInteger g = b.gcd(w);
+
+ if (g.compareTo(ONE) > 0)
+ {
+ return MROutput.provablyCompositeWithFactor(g);
+ }
+
+ BigInteger z = b.modPow(m, w);
+
+ if (z.equals(ONE) || z.equals(wSubOne))
+ {
+ continue;
+ }
+
+ boolean primeToBase = false;
+
+ BigInteger x = z;
+ for (int j = 1; j < a; ++j)
+ {
+ z = z.modPow(TWO, w);
+
+ if (z.equals(wSubOne))
+ {
+ primeToBase = true;
+ break;
+ }
+
+ if (z.equals(ONE))
+ {
+ break;
+ }
+
+ x = z;
+ }
+
+ if (!primeToBase)
+ {
+ if (!z.equals(ONE))
+ {
+ x = z;
+ z = z.modPow(TWO, w);
+
+ if (!z.equals(ONE))
+ {
+ x = z;
+ }
+ }
+
+ g = x.subtract(ONE).gcd(w);
+
+ if (g.compareTo(ONE) > 0)
+ {
+ return MROutput.provablyCompositeWithFactor(g);
+ }
+
+ return MROutput.provablyCompositeNotPrimePower();
+ }
+ }
+
+ return MROutput.probablyPrime();
+ }
+
+ /**
+ * A fast check for small divisors, up to some implementation-specific limit.
+ *
+ * @param candidate
+ * the {@link BigInteger} instance to test for division by small factors.
+ *
+ * @return <code>true</code> if the candidate is found to have any small factors,
+ * <code>false</code> otherwise.
+ */
+ public static boolean hasAnySmallFactors(BigInteger candidate)
+ {
+ checkCandidate(candidate, "candidate");
+
+ return implHasAnySmallFactors(candidate);
+ }
+
+ /**
+ * FIPS 186-4 C.3.1 Miller-Rabin Probabilistic Primality Test
+ *
+ * Run several iterations of the Miller-Rabin algorithm with randomly-chosen bases.
+ *
+ * @param candidate
+ * the {@link BigInteger} instance to test for primality.
+ * @param random
+ * the source of randomness to use to choose bases.
+ * @param iterations
+ * the number of randomly-chosen bases to perform the test for.
+ * @return <code>false</code> if any witness to compositeness is found amongst the chosen bases
+ * (so <code>candidate</code> is definitely NOT prime), or else <code>true</code>
+ * (indicating primality with some probability dependent on the number of iterations
+ * that were performed).
+ */
+ public static boolean isMRProbablePrime(BigInteger candidate, SecureRandom random, int iterations)
+ {
+ checkCandidate(candidate, "candidate");
+
+ if (random == null)
+ {
+ throw new IllegalArgumentException("'random' cannot be null");
+ }
+ if (iterations < 1)
+ {
+ throw new IllegalArgumentException("'iterations' must be > 0");
+ }
+
+ if (candidate.bitLength() == 2)
+ {
+ return true;
+ }
+ if (!candidate.testBit(0))
+ {
+ return false;
+ }
+
+ BigInteger w = candidate;
+ BigInteger wSubOne = candidate.subtract(ONE);
+ BigInteger wSubTwo = candidate.subtract(TWO);
+
+ int a = wSubOne.getLowestSetBit();
+ BigInteger m = wSubOne.shiftRight(a);
+
+ for (int i = 0; i < iterations; ++i)
+ {
+ BigInteger b = BigIntegers.createRandomInRange(TWO, wSubTwo, random);
+
+ if (!implMRProbablePrimeToBase(w, wSubOne, m, a, b))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * FIPS 186-4 C.3.1 Miller-Rabin Probabilistic Primality Test (to a fixed base).
+ *
+ * Run a single iteration of the Miller-Rabin algorithm against the specified base.
+ *
+ * @param candidate
+ * the {@link BigInteger} instance to test for primality.
+ * @param base
+ * the base value to use for this iteration.
+ * @return <code>false</code> if the specified base is a witness to compositeness (so
+ * <code>candidate</code> is definitely NOT prime), or else <code>true</code>.
+ */
+ public static boolean isMRProbablePrimeToBase(BigInteger candidate, BigInteger base)
+ {
+ checkCandidate(candidate, "candidate");
+ checkCandidate(base, "base");
+
+ if (base.compareTo(candidate.subtract(ONE)) >= 0)
+ {
+ throw new IllegalArgumentException("'base' must be < ('candidate' - 1)");
+ }
+
+ if (candidate.bitLength() == 2)
+ {
+ return true;
+ }
+
+ BigInteger w = candidate;
+ BigInteger wSubOne = candidate.subtract(ONE);
+
+ int a = wSubOne.getLowestSetBit();
+ BigInteger m = wSubOne.shiftRight(a);
+
+ return implMRProbablePrimeToBase(w, wSubOne, m, a, base);
+ }
+
+ private static void checkCandidate(BigInteger n, String name)
+ {
+ if (n == null || n.signum() < 1 || n.bitLength() < 2)
+ {
+ throw new IllegalArgumentException("'" + name + "' must be non-null and >= 2");
+ }
+ }
+
+ private static boolean implHasAnySmallFactors(BigInteger x)
+ {
+ /*
+ * Bundle trial divisors into ~32-bit moduli then use fast tests on the ~32-bit remainders.
+ */
+ int m = 2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23;
+ int r = x.mod(BigInteger.valueOf(m)).intValue();
+ if ((r % 2) == 0 || (r % 3) == 0 || (r % 5) == 0 || (r % 7) == 0 || (r % 11) == 0 || (r % 13) == 0
+ || (r % 17) == 0 || (r % 19) == 0 || (r % 23) == 0)
+ {
+ return true;
+ }
+
+ m = 29 * 31 * 37 * 41 * 43;
+ r = x.mod(BigInteger.valueOf(m)).intValue();
+ if ((r % 29) == 0 || (r % 31) == 0 || (r % 37) == 0 || (r % 41) == 0 || (r % 43) == 0)
+ {
+ return true;
+ }
+
+ m = 47 * 53 * 59 * 61 * 67;
+ r = x.mod(BigInteger.valueOf(m)).intValue();
+ if ((r % 47) == 0 || (r % 53) == 0 || (r % 59) == 0 || (r % 61) == 0 || (r % 67) == 0)
+ {
+ return true;
+ }
+
+ m = 71 * 73 * 79 * 83;
+ r = x.mod(BigInteger.valueOf(m)).intValue();
+ if ((r % 71) == 0 || (r % 73) == 0 || (r % 79) == 0 || (r % 83) == 0)
+ {
+ return true;
+ }
+
+ m = 89 * 97 * 101 * 103;
+ r = x.mod(BigInteger.valueOf(m)).intValue();
+ if ((r % 89) == 0 || (r % 97) == 0 || (r % 101) == 0 || (r % 103) == 0)
+ {
+ return true;
+ }
+
+ m = 107 * 109 * 113 * 127;
+ r = x.mod(BigInteger.valueOf(m)).intValue();
+ if ((r % 107) == 0 || (r % 109) == 0 || (r % 113) == 0 || (r % 127) == 0)
+ {
+ return true;
+ }
+
+ m = 131 * 137 * 139 * 149;
+ r = x.mod(BigInteger.valueOf(m)).intValue();
+ if ((r % 131) == 0 || (r % 137) == 0 || (r % 139) == 0 || (r % 149) == 0)
+ {
+ return true;
+ }
+
+ m = 151 * 157 * 163 * 167;
+ r = x.mod(BigInteger.valueOf(m)).intValue();
+ if ((r % 151) == 0 || (r % 157) == 0 || (r % 163) == 0 || (r % 167) == 0)
+ {
+ return true;
+ }
+
+ m = 173 * 179 * 181 * 191;
+ r = x.mod(BigInteger.valueOf(m)).intValue();
+ if ((r % 173) == 0 || (r % 179) == 0 || (r % 181) == 0 || (r % 191) == 0)
+ {
+ return true;
+ }
+
+ m = 193 * 197 * 199 * 211;
+ r = x.mod(BigInteger.valueOf(m)).intValue();
+ if ((r % 193) == 0 || (r % 197) == 0 || (r % 199) == 0 || (r % 211) == 0)
+ {
+ return true;
+ }
+
+ /*
+ * NOTE: Unit tests depend on SMALL_FACTOR_LIMIT matching the
+ * highest small factor tested here.
+ */
+ return false;
+ }
+
+ private static boolean implMRProbablePrimeToBase(BigInteger w, BigInteger wSubOne, BigInteger m, int a, BigInteger b)
+ {
+ BigInteger z = b.modPow(m, w);
+
+ if (z.equals(ONE) || z.equals(wSubOne))
+ {
+ return true;
+ }
+
+ boolean result = false;
+
+ for (int j = 1; j < a; ++j)
+ {
+ z = z.modPow(TWO, w);
+
+ if (z.equals(wSubOne))
+ {
+ result = true;
+ break;
+ }
+
+ if (z.equals(ONE))
+ {
+ return false;
+ }
+ }
+
+ return result;
+ }
+
+ private static STOutput implSTRandomPrime(Digest d, int length, byte[] primeSeed)
+ {
+ int dLen = d.getDigestSize();
+
+ if (length < 33)
+ {
+ int primeGenCounter = 0;
+
+ byte[] c0 = new byte[dLen];
+ byte[] c1 = new byte[dLen];
+
+ for (;;)
+ {
+ hash(d, primeSeed, c0, 0);
+ inc(primeSeed, 1);
+
+ hash(d, primeSeed, c1, 0);
+ inc(primeSeed, 1);
+
+ int c = extract32(c0) ^ extract32(c1);
+ c &= (-1 >>> (32 - length));
+ c |= (1 << (length - 1)) | 1;
+
+ ++primeGenCounter;
+
+ long c64 = c & 0xFFFFFFFFL;
+ if (isPrime32(c64))
+ {
+ return new STOutput(BigInteger.valueOf(c64), primeSeed, primeGenCounter);
+ }
+
+ if (primeGenCounter > (4 * length))
+ {
+ throw new IllegalStateException("Too many iterations in Shawe-Taylor Random_Prime Routine");
+ }
+ }
+ }
+
+ STOutput rec = implSTRandomPrime(d, (length + 3) / 2, primeSeed);
+
+ BigInteger c0 = rec.getPrime();
+ primeSeed = rec.getPrimeSeed();
+ int primeGenCounter = rec.getPrimeGenCounter();
+
+ int outlen = 8 * dLen;
+ int iterations = (length - 1) / outlen;
+
+ int oldCounter = primeGenCounter;
+
+ BigInteger x = hashGen(d, primeSeed, iterations + 1);
+ x = x.mod(ONE.shiftLeft(length - 1)).setBit(length - 1);
+
+ BigInteger c0x2 = c0.shiftLeft(1);
+ BigInteger tx2 = x.subtract(ONE).divide(c0x2).add(ONE).shiftLeft(1);
+ int dt = 0;
+
+ BigInteger c = tx2.multiply(c0).add(ONE);
+
+ /*
+ * TODO Since the candidate primes are generated by constant steps ('c0x2'), sieving could
+ * be used here in place of the 'hasAnySmallFactors' approach.
+ */
+ for (;;)
+ {
+ if (c.bitLength() > length)
+ {
+ tx2 = ONE.shiftLeft(length - 1).subtract(ONE).divide(c0x2).add(ONE).shiftLeft(1);
+ c = tx2.multiply(c0).add(ONE);
+ }
+
+ ++primeGenCounter;
+
+ /*
+ * This is an optimization of the original algorithm, using trial division to screen out
+ * many non-primes quickly.
+ *
+ * NOTE: 'primeSeed' is still incremented as if we performed the full check!
+ */
+ if (!implHasAnySmallFactors(c))
+ {
+ BigInteger a = hashGen(d, primeSeed, iterations + 1);
+ a = a.mod(c.subtract(THREE)).add(TWO);
+
+ tx2 = tx2.add(BigInteger.valueOf(dt));
+ dt = 0;
+
+ BigInteger z = a.modPow(tx2, c);
+
+ if (c.gcd(z.subtract(ONE)).equals(ONE) && z.modPow(c0, c).equals(ONE))
+ {
+ return new STOutput(c, primeSeed, primeGenCounter);
+ }
+ }
+ else
+ {
+ inc(primeSeed, iterations + 1);
+ }
+
+ if (primeGenCounter >= ((4 * length) + oldCounter))
+ {
+ throw new IllegalStateException("Too many iterations in Shawe-Taylor Random_Prime Routine");
+ }
+
+ dt += 2;
+ c = c.add(c0x2);
+ }
+ }
+
+ private static int extract32(byte[] bs)
+ {
+ int result = 0;
+
+ int count = Math.min(4, bs.length);
+ for (int i = 0; i < count; ++i)
+ {
+ int b = bs[bs.length - (i + 1)] & 0xFF;
+ result |= (b << (8 * i));
+ }
+
+ return result;
+ }
+
+ private static void hash(Digest d, byte[] input, byte[] output, int outPos)
+ {
+ d.update(input, 0, input.length);
+ d.doFinal(output, outPos);
+ }
+
+ private static BigInteger hashGen(Digest d, byte[] seed, int count)
+ {
+ int dLen = d.getDigestSize();
+ int pos = count * dLen;
+ byte[] buf = new byte[pos];
+ for (int i = 0; i < count; ++i)
+ {
+ pos -= dLen;
+ hash(d, seed, buf, pos);
+ inc(seed, 1);
+ }
+ return new BigInteger(1, buf);
+ }
+
+ private static void inc(byte[] seed, int c)
+ {
+ int pos = seed.length;
+ while (c > 0 && --pos >= 0)
+ {
+ c += (seed[pos] & 0xFF);
+ seed[pos] = (byte)c;
+ c >>>= 8;
+ }
+ }
+
+ private static boolean isPrime32(long x)
+ {
+ if (x >>> 32 != 0L)
+ {
+ throw new IllegalArgumentException("Size limit exceeded");
+ }
+
+ /*
+ * Use wheel factorization with 2, 3, 5 to select trial divisors.
+ */
+
+ if (x <= 5L)
+ {
+ return x == 2L || x == 3L || x == 5L;
+ }
+
+ if ((x & 1L) == 0L || (x % 3L) == 0L || (x % 5L) == 0L)
+ {
+ return false;
+ }
+
+ long[] ds = new long[]{ 1L, 7L, 11L, 13L, 17L, 19L, 23L, 29L };
+ long base = 0L;
+ for (int pos = 1;; pos = 0)
+ {
+ /*
+ * Trial division by wheel-selected divisors
+ */
+ while (pos < ds.length)
+ {
+ long d = base + ds[pos];
+ if (x % d == 0L)
+ {
+ return x < 30L;
+ }
+ ++pos;
+ }
+
+ base += 30L;
+
+ if (base * base >= x)
+ {
+ return true;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/ECAlgorithms.java b/bcprov/src/main/java/org/bouncycastle/math/ec/ECAlgorithms.java
index 7165bab3..f8bf1eb5 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/ECAlgorithms.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/ECAlgorithms.java
@@ -11,14 +11,23 @@ public class ECAlgorithms
{
public static boolean isF2mCurve(ECCurve c)
{
- FiniteField field = c.getField();
+ return isF2mField(c.getField());
+ }
+
+ public static boolean isF2mField(FiniteField field)
+ {
return field.getDimension() > 1 && field.getCharacteristic().equals(ECConstants.TWO)
&& field instanceof PolynomialExtensionField;
}
public static boolean isFpCurve(ECCurve c)
{
- return c.getField().getDimension() == 1;
+ return isFpField(c.getField());
+ }
+
+ public static boolean isFpField(FiniteField field)
+ {
+ return field.getDimension() == 1;
}
public static ECPoint sumOfMultiplies(ECPoint[] ps, BigInteger[] ks)
@@ -65,9 +74,9 @@ public class ECAlgorithms
Q = importPoint(cp, Q);
// Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick
- if (cp instanceof ECCurve.F2m)
+ if (cp instanceof ECCurve.AbstractF2m)
{
- ECCurve.F2m f2mCurve = (ECCurve.F2m)cp;
+ ECCurve.AbstractF2m f2mCurve = (ECCurve.AbstractF2m)cp;
if (f2mCurve.isKoblitz())
{
return validatePoint(P.multiply(a).add(Q.multiply(b)));
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/ECConstants.java b/bcprov/src/main/java/org/bouncycastle/math/ec/ECConstants.java
index 864f746d..53e60f73 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/ECConstants.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/ECConstants.java
@@ -9,4 +9,5 @@ public interface ECConstants
public static final BigInteger TWO = BigInteger.valueOf(2);
public static final BigInteger THREE = BigInteger.valueOf(3);
public static final BigInteger FOUR = BigInteger.valueOf(4);
+ public static final BigInteger EIGHT = BigInteger.valueOf(8);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java b/bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java
index 0dc68535..7f3197bc 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java
@@ -75,9 +75,13 @@ public abstract class ECCurve
throw new IllegalStateException("implementation returned current curve");
}
- c.coord = coord;
- c.endomorphism = endomorphism;
- c.multiplier = multiplier;
+ // NOTE: Synchronization added to keep FindBugsâ„¢ happy
+ synchronized (c)
+ {
+ c.coord = coord;
+ c.endomorphism = endomorphism;
+ c.multiplier = multiplier;
+ }
return c;
}
@@ -100,7 +104,9 @@ public abstract class ECCurve
public abstract ECFieldElement fromBigInteger(BigInteger x);
- public Config configure()
+ public abstract boolean isValidFieldElement(BigInteger x);
+
+ public synchronized Config configure()
{
return new Config(this.coord, this.endomorphism, this.multiplier);
}
@@ -497,10 +503,15 @@ public abstract class ECCurve
super(FiniteFields.getPrimeField(q));
}
+ public boolean isValidFieldElement(BigInteger x)
+ {
+ return x != null && x.signum() >= 0 && x.compareTo(this.getField().getCharacteristic()) < 0;
+ }
+
protected ECPoint decompressPoint(int yTilde, BigInteger X1)
{
ECFieldElement x = this.fromBigInteger(X1);
- ECFieldElement rhs = x.square().add(a).multiply(x).add(b);
+ ECFieldElement rhs = x.square().add(this.a).multiply(x).add(this.b);
ECFieldElement y = rhs.sqrt();
/*
@@ -526,7 +537,7 @@ public abstract class ECCurve
*/
public static class Fp extends AbstractFp
{
- private static final int FP_DEFAULT_COORDS = COORD_JACOBIAN_MODIFIED;
+ private static final int FP_DEFAULT_COORDS = ECCurve.COORD_JACOBIAN_MODIFIED;
BigInteger q, r;
ECPoint.Fp infinity;
@@ -573,17 +584,17 @@ public abstract class ECCurve
protected ECCurve cloneCurve()
{
- return new Fp(q, r, a, b, order, cofactor);
+ return new Fp(this.q, this.r, this.a, this.b, this.order, this.cofactor);
}
public boolean supportsCoordinateSystem(int coord)
{
switch (coord)
{
- case COORD_AFFINE:
- case COORD_HOMOGENEOUS:
- case COORD_JACOBIAN:
- case COORD_JACOBIAN_MODIFIED:
+ case ECCurve.COORD_AFFINE:
+ case ECCurve.COORD_HOMOGENEOUS:
+ case ECCurve.COORD_JACOBIAN:
+ case ECCurve.COORD_JACOBIAN_MODIFIED:
return true;
default:
return false;
@@ -617,13 +628,13 @@ public abstract class ECCurve
public ECPoint importPoint(ECPoint p)
{
- if (this != p.getCurve() && this.getCoordinateSystem() == COORD_JACOBIAN && !p.isInfinity())
+ if (this != p.getCurve() && this.getCoordinateSystem() == ECCurve.COORD_JACOBIAN && !p.isInfinity())
{
switch (p.getCurve().getCoordinateSystem())
{
- case COORD_JACOBIAN:
- case COORD_JACOBIAN_CHUDNOVSKY:
- case COORD_JACOBIAN_MODIFIED:
+ case ECCurve.COORD_JACOBIAN:
+ case ECCurve.COORD_JACOBIAN_CHUDNOVSKY:
+ case ECCurve.COORD_JACOBIAN_MODIFIED:
return new ECPoint.Fp(this,
fromBigInteger(p.x.toBigInteger()),
fromBigInteger(p.y.toBigInteger()),
@@ -645,6 +656,18 @@ public abstract class ECCurve
public static abstract class AbstractF2m extends ECCurve
{
+ public static BigInteger inverse(int m, int[] ks, BigInteger x)
+ {
+ return new LongArray(x).modInverse(m, ks).toBigInteger();
+ }
+
+ /**
+ * The auxiliary values <code>s<sub>0</sub></code> and
+ * <code>s<sub>1</sub></code> used for partial modular reduction for
+ * Koblitz curves.
+ */
+ private BigInteger[] si = null;
+
private static FiniteField buildField(int m, int k1, int k2, int k3)
{
if (k1 == 0)
@@ -679,6 +702,173 @@ 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)
+ {
+ ECFieldElement X = this.fromBigInteger(x), Y = this.fromBigInteger(y);
+
+ int coord = this.getCoordinateSystem();
+
+ switch (coord)
+ {
+ case ECCurve.COORD_LAMBDA_AFFINE:
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ {
+ if (X.isZero())
+ {
+ if (!Y.square().equals(this.getB()))
+ {
+ throw new IllegalArgumentException();
+ }
+ }
+ /*
+ * NOTE: A division could be avoided using a projective result, except at present
+ * callers will expect that the result is already normalized.
+ */
+// else if (coord == COORD_LAMBDA_PROJECTIVE)
+// {
+// ECFieldElement Z = X;
+// X = X.square();
+// Y = Y.add(X);
+// return createRawPoint(X, Y, new ECFieldElement[]{ Z }, withCompression);
+// }
+ else
+ {
+ // Y becomes Lambda (X + Y/X) here
+ Y = Y.divide(X).add(X);
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ return this.createRawPoint(X, Y, withCompression);
+ }
+
+ /**
+ * Decompresses a compressed point P = (xp, yp) (X9.62 s 4.2.2).
+ *
+ * @param yTilde
+ * ~yp, an indication bit for the decompression of yp.
+ * @param X1
+ * The field element xp.
+ * @return the decompressed point.
+ */
+ protected ECPoint decompressPoint(int yTilde, BigInteger X1)
+ {
+ ECFieldElement x = this.fromBigInteger(X1), y = null;
+ if (x.isZero())
+ {
+ y = this.getB().sqrt();
+ }
+ else
+ {
+ ECFieldElement beta = x.square().invert().multiply(this.getB()).add(this.getA()).add(x);
+ ECFieldElement z = solveQuadraticEquation(beta);
+ if (z != null)
+ {
+ if (z.testBitZero() != (yTilde == 1))
+ {
+ z = z.addOne();
+ }
+
+ switch (this.getCoordinateSystem())
+ {
+ case ECCurve.COORD_LAMBDA_AFFINE:
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ {
+ y = z.add(x);
+ break;
+ }
+ default:
+ {
+ y = z.multiply(x);
+ break;
+ }
+ }
+ }
+ }
+
+ if (y == null)
+ {
+ throw new IllegalArgumentException("Invalid point compression");
+ }
+
+ return this.createRawPoint(x, y, true);
+ }
+
+ /**
+ * Solves a quadratic equation <code>z<sup>2</sup> + z = beta</code>(X9.62
+ * D.1.6) The other solution is <code>z + 1</code>.
+ *
+ * @param beta
+ * The value to solve the quadratic equation for.
+ * @return the solution for <code>z<sup>2</sup> + z = beta</code> or
+ * <code>null</code> if no solution exists.
+ */
+ private ECFieldElement solveQuadraticEquation(ECFieldElement beta)
+ {
+ if (beta.isZero())
+ {
+ return beta;
+ }
+
+ ECFieldElement gamma, z, zeroElement = this.fromBigInteger(ECConstants.ZERO);
+
+ int m = this.getFieldSize();
+ Random rand = new Random();
+ do
+ {
+ ECFieldElement t = this.fromBigInteger(new BigInteger(m, rand));
+ z = zeroElement;
+ ECFieldElement w = beta;
+ for (int i = 1; i < m; i++)
+ {
+ ECFieldElement w2 = w.square();
+ z = z.square().add(w2.multiply(t));
+ w = w2.add(beta);
+ }
+ if (!w.isZero())
+ {
+ return null;
+ }
+ gamma = z.square().add(z);
+ }
+ while (gamma.isZero());
+
+ return z;
+ }
+
+ /**
+ * @return the auxiliary values <code>s<sub>0</sub></code> and
+ * <code>s<sub>1</sub></code> used for partial modular reduction for
+ * Koblitz curves.
+ */
+ synchronized BigInteger[] getSi()
+ {
+ if (si == null)
+ {
+ si = Tnaf.getSi(this);
+ }
+ return si;
+ }
+
+ /**
+ * Returns true if this is a Koblitz curve (ABC curve).
+ * @return true if this is a Koblitz curve (ABC curve), false otherwise
+ */
+ public boolean isKoblitz()
+ {
+ return this.order != null && this.cofactor != null && this.b.isOne() && (this.a.isZero() || this.a.isOne());
+ }
}
/**
@@ -687,7 +877,7 @@ public abstract class ECCurve
*/
public static class F2m extends AbstractF2m
{
- private static final int F2M_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE;
+ private static final int F2M_DEFAULT_COORDS = ECCurve.COORD_LAMBDA_PROJECTIVE;
/**
* The exponent <code>m</code> of <code>F<sub>2<sup>m</sup></sub></code>.
@@ -726,19 +916,6 @@ public abstract class ECCurve
private ECPoint.F2m infinity; // can't be final - JDK 1.1
/**
- * The parameter <code>&mu;</code> of the elliptic curve if this is
- * a Koblitz curve.
- */
- private byte mu = 0;
-
- /**
- * The auxiliary values <code>s<sub>0</sub></code> and
- * <code>s<sub>1</sub></code> used for partial modular reduction for
- * Koblitz curves.
- */
- private BigInteger[] si = null;
-
- /**
* Constructor for Trinomial Polynomial Basis (TPB).
* @param m The exponent <code>m</code> of
* <code>F<sub>2<sup>m</sup></sub></code>.
@@ -887,16 +1064,16 @@ public abstract class ECCurve
protected ECCurve cloneCurve()
{
- return new F2m(m, k1, k2, k3, a, b, order, cofactor);
+ return new F2m(this.m, this.k1, this.k2, this.k3, this.a, this.b, this.order, this.cofactor);
}
public boolean supportsCoordinateSystem(int coord)
{
switch (coord)
{
- case COORD_AFFINE:
- case COORD_HOMOGENEOUS:
- case COORD_LAMBDA_PROJECTIVE:
+ case ECCurve.COORD_AFFINE:
+ case ECCurve.COORD_HOMOGENEOUS:
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
return true;
default:
return false;
@@ -923,38 +1100,6 @@ public abstract class ECCurve
return new ECFieldElement.F2m(this.m, this.k1, this.k2, this.k3, x);
}
- public ECPoint createPoint(BigInteger x, BigInteger y, boolean withCompression)
- {
- ECFieldElement X = fromBigInteger(x), Y = fromBigInteger(y);
-
- switch (this.getCoordinateSystem())
- {
- case COORD_LAMBDA_AFFINE:
- case COORD_LAMBDA_PROJECTIVE:
- {
- if (X.isZero())
- {
- if (!Y.square().equals(this.getB()))
- {
- throw new IllegalArgumentException();
- }
- }
- else
- {
- // Y becomes Lambda (X + Y/X) here
- Y = Y.divide(X).add(X);
- }
- break;
- }
- default:
- {
- break;
- }
- }
-
- return createRawPoint(X, Y, withCompression);
- }
-
protected ECPoint createRawPoint(ECFieldElement x, ECFieldElement y, boolean withCompression)
{
return new ECPoint.F2m(this, x, y, withCompression);
@@ -970,140 +1115,6 @@ public abstract class ECCurve
return infinity;
}
- /**
- * Returns true if this is a Koblitz curve (ABC curve).
- * @return true if this is a Koblitz curve (ABC curve), false otherwise
- */
- public boolean isKoblitz()
- {
- return order != null && cofactor != null && b.isOne() && (a.isZero() || a.isOne());
- }
-
- /**
- * Returns the parameter <code>&mu;</code> of the elliptic curve.
- * @return <code>&mu;</code> of the elliptic curve.
- * @throws IllegalArgumentException if the given ECCurve is not a
- * Koblitz curve.
- */
- synchronized byte getMu()
- {
- if (mu == 0)
- {
- mu = Tnaf.getMu(this);
- }
- return mu;
- }
-
- /**
- * @return the auxiliary values <code>s<sub>0</sub></code> and
- * <code>s<sub>1</sub></code> used for partial modular reduction for
- * Koblitz curves.
- */
- synchronized BigInteger[] getSi()
- {
- if (si == null)
- {
- si = Tnaf.getSi(this);
- }
- return si;
- }
-
- /**
- * Decompresses a compressed point P = (xp, yp) (X9.62 s 4.2.2).
- *
- * @param yTilde
- * ~yp, an indication bit for the decompression of yp.
- * @param X1
- * The field element xp.
- * @return the decompressed point.
- */
- protected ECPoint decompressPoint(int yTilde, BigInteger X1)
- {
- ECFieldElement x = fromBigInteger(X1), y = null;
- if (x.isZero())
- {
- y = b.sqrt();
- }
- else
- {
- ECFieldElement beta = x.square().invert().multiply(b).add(a).add(x);
- ECFieldElement z = solveQuadraticEquation(beta);
- if (z != null)
- {
- if (z.testBitZero() != (yTilde == 1))
- {
- z = z.addOne();
- }
-
- switch (this.getCoordinateSystem())
- {
- case COORD_LAMBDA_AFFINE:
- case COORD_LAMBDA_PROJECTIVE:
- {
- y = z.add(x);
- break;
- }
- default:
- {
- y = z.multiply(x);
- break;
- }
- }
- }
- }
-
- if (y == null)
- {
- throw new IllegalArgumentException("Invalid point compression");
- }
-
- return this.createRawPoint(x, y, true);
- }
-
- /**
- * Solves a quadratic equation <code>z<sup>2</sup> + z = beta</code>(X9.62
- * D.1.6) The other solution is <code>z + 1</code>.
- *
- * @param beta
- * The value to solve the quadratic equation for.
- * @return the solution for <code>z<sup>2</sup> + z = beta</code> or
- * <code>null</code> if no solution exists.
- */
- private ECFieldElement solveQuadraticEquation(ECFieldElement beta)
- {
- if (beta.isZero())
- {
- return beta;
- }
-
- ECFieldElement zeroElement = fromBigInteger(ECConstants.ZERO);
-
- ECFieldElement z = null;
- ECFieldElement gamma = null;
-
- Random rand = new Random();
- do
- {
- ECFieldElement t = fromBigInteger(new BigInteger(m, rand));
- z = zeroElement;
- ECFieldElement w = beta;
- for (int i = 1; i <= m - 1; i++)
- {
- ECFieldElement w2 = w.square();
- z = z.square().add(w2.multiply(t));
- w = w2.add(beta);
- }
- if (!w.isZero())
- {
- return null;
- }
- gamma = z.square().add(z);
- }
- while (gamma.isZero());
-
- return z;
- }
-
public int getM()
{
return m;
@@ -1139,7 +1150,7 @@ public abstract class ECCurve
*/
public BigInteger getN()
{
- return order;
+ return this.order;
}
/**
@@ -1147,7 +1158,7 @@ public abstract class ECCurve
*/
public BigInteger getH()
{
- return cofactor;
+ return this.cofactor;
}
}
}
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 59438826..18409c09 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/ECFieldElement.java
@@ -59,6 +59,16 @@ public abstract class ECFieldElement
return square().add(x.multiply(y));
}
+ public ECFieldElement squarePow(int pow)
+ {
+ ECFieldElement r = this;
+ for (int i = 0; i < pow; ++i)
+ {
+ r = r.square();
+ }
+ return r;
+ }
+
public boolean testBitZero()
{
return toBigInteger().testBit(0);
@@ -548,6 +558,11 @@ public abstract class ECFieldElement
int k3,
BigInteger x)
{
+ if (x == null || x.signum() < 0 || x.bitLength() > m)
+ {
+ throw new IllegalArgumentException("x value invalid in F2m field element");
+ }
+
if ((k2 == 0) && (k3 == 0))
{
this.representation = TPB;
@@ -766,6 +781,11 @@ public abstract class ECFieldElement
return new F2m(m, ks, aa);
}
+ public ECFieldElement squarePow(int pow)
+ {
+ return pow < 1 ? this : new F2m(m, ks, x.modSquareN(pow, m, ks));
+ }
+
public ECFieldElement invert()
{
return new ECFieldElement.F2m(this.m, this.ks, this.x.modInverse(m, ks));
@@ -773,14 +793,7 @@ public abstract class ECFieldElement
public ECFieldElement sqrt()
{
- LongArray x1 = this.x;
- if (x1.isOne() || x1.isZero())
- {
- return this;
- }
-
- LongArray x2 = x1.modSquareN(m - 1, m, ks);
- return new ECFieldElement.F2m(m, ks, x2);
+ return (x.isZero() || x.isOne()) ? this : squarePow(m - 1);
}
/**
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 4db27e04..0ea5026c 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/ECPoint.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/ECPoint.java
@@ -181,19 +181,19 @@ public abstract class ECPoint
int zsLen = zs.length;
if (zsLen == 0)
{
- return zs;
+ return EMPTY_ZS;
}
ECFieldElement[] copy = new ECFieldElement[zsLen];
System.arraycopy(zs, 0, copy, 0, zsLen);
return copy;
}
- protected final ECFieldElement getRawXCoord()
+ public final ECFieldElement getRawXCoord()
{
return x;
}
- protected final ECFieldElement getRawYCoord()
+ public final ECFieldElement getRawYCoord()
{
return y;
}
@@ -1175,6 +1175,8 @@ public abstract class ECPoint
{
switch (coord)
{
+ case ECCurve.COORD_AFFINE:
+ break;
case ECCurve.COORD_HOMOGENEOUS:
ECFieldElement Z1Sq = Z1.square();
X1 = X1.multiply(Z1);
@@ -1187,6 +1189,8 @@ public abstract class ECPoint
case ECCurve.COORD_JACOBIAN_MODIFIED:
W1 = getJacobianModifiedW();
break;
+ default:
+ throw new IllegalStateException("unsupported coordinate system");
}
}
@@ -1418,6 +1422,153 @@ public abstract class ECPoint
ECFieldElement rhs = X.add(A).multiply(X.square()).add(B);
return lhs.equals(rhs);
}
+
+ public ECPoint scaleX(ECFieldElement scale)
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ int coord = this.getCurveCoordinateSystem();
+
+ switch (coord)
+ {
+ case ECCurve.COORD_LAMBDA_AFFINE:
+ {
+ // Y is actually Lambda (X + Y/X) here
+ ECFieldElement X = this.getRawXCoord(), L = this.getRawYCoord(); // earlier JDK
+
+ ECFieldElement X2 = X.multiply(scale);
+ ECFieldElement L2 = L.add(X).divide(scale).add(X2);
+
+ return this.getCurve().createRawPoint(X, L2, this.getRawZCoords(), this.withCompression); // earlier JDK
+ }
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ {
+ // Y is actually Lambda (X + Y/X) here
+ ECFieldElement X = this.getRawXCoord(), L = this.getRawYCoord(), Z = this.getRawZCoords()[0]; // earlier JDK
+
+ // We scale the Z coordinate also, to avoid an inversion
+ ECFieldElement X2 = X.multiply(scale.square());
+ ECFieldElement L2 = L.add(X).add(X2);
+ ECFieldElement Z2 = Z.multiply(scale);
+
+ return this.getCurve().createRawPoint(X2, L2, new ECFieldElement[]{ Z2 }, this.withCompression); // earlier JDK
+ }
+ default:
+ {
+ return super.scaleX(scale);
+ }
+ }
+ }
+
+ public ECPoint scaleY(ECFieldElement scale)
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ int coord = this.getCurveCoordinateSystem();
+
+ switch (coord)
+ {
+ case ECCurve.COORD_LAMBDA_AFFINE:
+ case ECCurve.COORD_LAMBDA_PROJECTIVE:
+ {
+ ECFieldElement X = this.getRawXCoord(), L = this.getRawYCoord(); // earlier JDK
+
+ // Y is actually Lambda (X + Y/X) here
+ ECFieldElement L2 = L.add(X).multiply(scale).add(X);
+
+ return this.getCurve().createRawPoint(X, L2, this.getRawZCoords(), this.withCompression); // earlier JDK
+ }
+ default:
+ {
+ return super.scaleY(scale);
+ }
+ }
+ }
+
+ public ECPoint subtract(ECPoint b)
+ {
+ if (b.isInfinity())
+ {
+ return this;
+ }
+
+ // Add -b
+ return this.add(b.negate());
+ }
+
+ public ECPoint.AbstractF2m tau()
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ ECCurve curve = this.getCurve();
+ int coord = curve.getCoordinateSystem();
+
+ ECFieldElement X1 = this.x;
+
+ switch (coord)
+ {
+ case ECCurve.COORD_AFFINE:
+ case ECCurve.COORD_LAMBDA_AFFINE:
+ {
+ ECFieldElement Y1 = this.y;
+ return (ECPoint.AbstractF2m)curve.createRawPoint(X1.square(), Y1.square(), this.withCompression);
+ }
+ 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);
+ }
+ default:
+ {
+ throw new IllegalStateException("unsupported coordinate system");
+ }
+ }
+ }
+
+ public ECPoint.AbstractF2m tauPow(int pow)
+ {
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ ECCurve curve = this.getCurve();
+ int coord = curve.getCoordinateSystem();
+
+ ECFieldElement X1 = this.x;
+
+ switch (coord)
+ {
+ case ECCurve.COORD_AFFINE:
+ case ECCurve.COORD_LAMBDA_AFFINE:
+ {
+ ECFieldElement Y1 = this.y;
+ return (ECPoint.AbstractF2m)curve.createRawPoint(X1.squarePow(pow), Y1.squarePow(pow), this.withCompression);
+ }
+ 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);
+ }
+ default:
+ {
+ throw new IllegalStateException("unsupported coordinate system");
+ }
+ }
+ }
}
/**
@@ -1520,74 +1671,6 @@ public abstract class ECPoint
}
}
- public ECPoint scaleX(ECFieldElement scale)
- {
- if (this.isInfinity())
- {
- return this;
- }
-
- int coord = this.getCurveCoordinateSystem();
-
- switch (coord)
- {
- case ECCurve.COORD_LAMBDA_AFFINE:
- {
- // Y is actually Lambda (X + Y/X) here
- ECFieldElement X = this.getRawXCoord(), L = this.getRawYCoord(); // earlier JDK
-
- ECFieldElement X2 = X.multiply(scale);
- ECFieldElement L2 = L.add(X).divide(scale).add(X2);
-
- return this.getCurve().createRawPoint(X, L2, this.getRawZCoords(), this.withCompression); // earlier JDK
- }
- case ECCurve.COORD_LAMBDA_PROJECTIVE:
- {
- // Y is actually Lambda (X + Y/X) here
- ECFieldElement X = this.getRawXCoord(), L = this.getRawYCoord(), Z = this.getRawZCoords()[0]; // earlier JDK
-
- // We scale the Z coordinate also, to avoid an inversion
- ECFieldElement X2 = X.multiply(scale.square());
- ECFieldElement L2 = L.add(X).add(X2);
- ECFieldElement Z2 = Z.multiply(scale);
-
- return this.getCurve().createRawPoint(X2, L2, new ECFieldElement[]{ Z2 }, this.withCompression); // earlier JDK
- }
- default:
- {
- return super.scaleX(scale);
- }
- }
- }
-
- public ECPoint scaleY(ECFieldElement scale)
- {
- if (this.isInfinity())
- {
- return this;
- }
-
- int coord = this.getCurveCoordinateSystem();
-
- switch (coord)
- {
- case ECCurve.COORD_LAMBDA_AFFINE:
- case ECCurve.COORD_LAMBDA_PROJECTIVE:
- {
- ECFieldElement X = this.getRawXCoord(), L = this.getRawYCoord(); // earlier JDK
-
- // Y is actually Lambda (X + Y/X) here
- ECFieldElement L2 = L.add(X).multiply(scale).add(X);
-
- return this.getCurve().createRawPoint(X, L2, this.getRawZCoords(), this.withCompression); // earlier JDK
- }
- default:
- {
- return super.scaleY(scale);
- }
- }
- }
-
protected boolean getCompressionYTilde()
{
ECFieldElement X = this.getRawXCoord();
@@ -1613,45 +1696,8 @@ public abstract class ECPoint
}
}
- /**
- * Check, if two <code>ECPoint</code>s can be added or subtracted.
- * @param a The first <code>ECPoint</code> to check.
- * @param b The second <code>ECPoint</code> to check.
- * @throws IllegalArgumentException if <code>a</code> and <code>b</code>
- * cannot be added.
- */
- private static void checkPoints(ECPoint a, ECPoint b)
- {
- // Check, if points are on the same curve
- if (a.curve != b.curve)
- {
- throw new IllegalArgumentException("Only points on the same "
- + "curve can be added or subtracted");
- }
-
-// ECFieldElement.F2m.checkFieldElements(a.x, b.x);
- }
-
- /* (non-Javadoc)
- * @see org.bouncycastle.math.ec.ECPoint#add(org.bouncycastle.math.ec.ECPoint)
- */
public ECPoint add(ECPoint b)
{
- checkPoints(this, b);
- return addSimple((ECPoint.F2m)b);
- }
-
- /**
- * Adds another <code>ECPoints.F2m</code> to <code>this</code> without
- * checking if both points are on the same curve. Used by multiplication
- * algorithms, because there all points are a multiple of the same point
- * and hence the checks can be omitted.
- * @param b The other <code>ECPoints.F2m</code> to add to
- * <code>this</code>.
- * @return <code>this + b</code>
- */
- public ECPoint.F2m addSimple(ECPoint.F2m b)
- {
if (this.isInfinity())
{
return b;
@@ -1679,10 +1725,10 @@ public abstract class ECPoint
{
if (dy.isZero())
{
- return (ECPoint.F2m)twice();
+ return twice();
}
- return (ECPoint.F2m)curve.getInfinity();
+ return curve.getInfinity();
}
ECFieldElement L = dy.divide(dx);
@@ -1710,10 +1756,10 @@ public abstract class ECPoint
{
if (U.isZero())
{
- return (ECPoint.F2m)twice();
+ return twice();
}
- return (ECPoint.F2m)curve.getInfinity();
+ return curve.getInfinity();
}
ECFieldElement VSq = V.square();
@@ -1735,10 +1781,10 @@ public abstract class ECPoint
{
if (X2.isZero())
{
- return (ECPoint.F2m)curve.getInfinity();
+ return curve.getInfinity();
}
- return b.addSimple(this);
+ return b.add(this);
}
ECFieldElement L1 = this.y, Z1 = this.zs[0];
@@ -1767,10 +1813,10 @@ public abstract class ECPoint
{
if (A.isZero())
{
- return (ECPoint.F2m)twice();
+ return twice();
}
- return (ECPoint.F2m)curve.getInfinity();
+ return curve.getInfinity();
}
ECFieldElement X3, L3, Z3;
@@ -1831,68 +1877,6 @@ public abstract class ECPoint
}
}
- /* (non-Javadoc)
- * @see org.bouncycastle.math.ec.ECPoint#subtract(org.bouncycastle.math.ec.ECPoint)
- */
- public ECPoint subtract(ECPoint b)
- {
- checkPoints(this, b);
- return subtractSimple((ECPoint.F2m)b);
- }
-
- /**
- * Subtracts another <code>ECPoints.F2m</code> from <code>this</code>
- * without checking if both points are on the same curve. Used by
- * multiplication algorithms, because there all points are a multiple
- * of the same point and hence the checks can be omitted.
- * @param b The other <code>ECPoints.F2m</code> to subtract from
- * <code>this</code>.
- * @return <code>this - b</code>
- */
- public ECPoint.F2m subtractSimple(ECPoint.F2m b)
- {
- if (b.isInfinity())
- {
- return this;
- }
-
- // Add -b
- return addSimple((ECPoint.F2m)b.negate());
- }
-
- public ECPoint.F2m tau()
- {
- if (this.isInfinity())
- {
- return this;
- }
-
- ECCurve curve = this.getCurve();
- int coord = curve.getCoordinateSystem();
-
- ECFieldElement X1 = this.x;
-
- switch (coord)
- {
- case ECCurve.COORD_AFFINE:
- case ECCurve.COORD_LAMBDA_AFFINE:
- {
- ECFieldElement Y1 = this.y;
- return new ECPoint.F2m(curve, X1.square(), Y1.square(), this.withCompression);
- }
- case ECCurve.COORD_HOMOGENEOUS:
- case ECCurve.COORD_LAMBDA_PROJECTIVE:
- {
- ECFieldElement Y1 = this.y, Z1 = this.zs[0];
- return new ECPoint.F2m(curve, X1.square(), Y1.square(), new ECFieldElement[]{ Z1.square() }, this.withCompression);
- }
- default:
- {
- throw new IllegalStateException("unsupported coordinate system");
- }
- }
- }
-
public ECPoint twice()
{
if (this.isInfinity())
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/LongArray.java b/bcprov/src/main/java/org/bouncycastle/math/ec/LongArray.java
index e3069dc0..b963118a 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/LongArray.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/LongArray.java
@@ -4,15 +4,17 @@ import org.bouncycastle.util.Arrays;
import java.math.BigInteger;
-class LongArray
+class LongArray implements Cloneable
{
// private static long DEINTERLEAVE_MASK = 0x5555555555555555L;
/*
* This expands 8 bit indices into 16 bit contents (high bit 14), by inserting 0s between bits.
* In a binary field, this operation is the same as squaring an 8 bit number.
+ *
+ * NOTE: All entries are positive so sign-extension is not an issue.
*/
- private static final int[] INTERLEAVE2_TABLE = new int[]
+ private static final short[] INTERLEAVE2_TABLE = new short[]
{
0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015,
0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055,
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/Tnaf.java b/bcprov/src/main/java/org/bouncycastle/math/ec/Tnaf.java
index 236bbc8e..aef0cf79 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/Tnaf.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/Tnaf.java
@@ -386,11 +386,11 @@ class Tnaf
/**
* Applies the operation <code>&tau;()</code> to an
- * <code>ECPoint.F2m</code>.
- * @param p The ECPoint.F2m to which <code>&tau;()</code> is applied.
+ * <code>ECPoint.AbstractF2m</code>.
+ * @param p The ECPoint.AbstractF2m to which <code>&tau;()</code> is applied.
* @return <code>&tau;(p)</code>
*/
- public static ECPoint.F2m tau(ECPoint.F2m p)
+ public static ECPoint.AbstractF2m tau(ECPoint.AbstractF2m p)
{
return p.tau();
}
@@ -405,7 +405,7 @@ class Tnaf
* @throws IllegalArgumentException if the given ECCurve is not a Koblitz
* curve.
*/
- public static byte getMu(ECCurve.F2m curve)
+ public static byte getMu(ECCurve.AbstractF2m curve)
{
if (!curve.isKoblitz())
{
@@ -420,6 +420,16 @@ class Tnaf
return 1;
}
+ public static byte getMu(ECFieldElement curveA)
+ {
+ return (byte)(curveA.isZero() ? -1 : 1);
+ }
+
+ public static byte getMu(int curveA)
+ {
+ return (byte)(curveA == 0 ? -1 : 1);
+ }
+
/**
* Calculates the Lucas Sequence elements <code>U<sub>k-1</sub></code> and
* <code>U<sub>k</sub></code> or <code>V<sub>k-1</sub></code> and
@@ -525,16 +535,16 @@ class Tnaf
* @throws IllegalArgumentException if <code>curve</code> is not a
* Koblitz curve (Anomalous Binary Curve, ABC).
*/
- public static BigInteger[] getSi(ECCurve.F2m curve)
+ public static BigInteger[] getSi(ECCurve.AbstractF2m curve)
{
if (!curve.isKoblitz())
{
throw new IllegalArgumentException("si is defined for Koblitz curves only");
}
- int m = curve.getM();
+ int m = curve.getFieldSize();
int a = curve.getA().toBigInteger().intValue();
- byte mu = curve.getMu();
+ byte mu = getMu(a);
int shifts = getShiftsForCofactor(curve.getCofactor());
int index = m + 3 - a;
BigInteger[] ui = getLucas(mu, index, false);
@@ -550,6 +560,24 @@ class Tnaf
return new BigInteger[] { dividend0, dividend1 };
}
+ public static BigInteger[] getSi(int fieldSize, int curveA, BigInteger cofactor)
+ {
+ byte mu = getMu(curveA);
+ int shifts = getShiftsForCofactor(cofactor);
+ int index = fieldSize + 3 - curveA;
+ BigInteger[] ui = getLucas(mu, index, false);
+ if (mu == 1)
+ {
+ ui[0] = ui[0].negate();
+ ui[1] = ui[1].negate();
+ }
+
+ BigInteger dividend0 = ECConstants.ONE.add(ui[1]).shiftRight(shifts);
+ BigInteger dividend1 = ECConstants.ONE.add(ui[0]).shiftRight(shifts).negate();
+
+ return new BigInteger[] { dividend0, dividend1 };
+ }
+
protected static int getShiftsForCofactor(BigInteger h)
{
if (h != null)
@@ -616,70 +644,77 @@ class Tnaf
}
/**
- * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.F2m ECPoint.F2m}
+ * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.AbstractF2m ECPoint.AbstractF2m}
* by a <code>BigInteger</code> using the reduced <code>&tau;</code>-adic
* NAF (RTNAF) method.
- * @param p The ECPoint.F2m to multiply.
+ * @param p The ECPoint.AbstractF2m to multiply.
* @param k The <code>BigInteger</code> by which to multiply <code>p</code>.
* @return <code>k * p</code>
*/
- public static ECPoint.F2m multiplyRTnaf(ECPoint.F2m p, BigInteger k)
+ public static ECPoint.AbstractF2m multiplyRTnaf(ECPoint.AbstractF2m p, BigInteger k)
{
- ECCurve.F2m curve = (ECCurve.F2m) p.getCurve();
- int m = curve.getM();
- byte a = (byte) curve.getA().toBigInteger().intValue();
- byte mu = curve.getMu();
+ ECCurve.AbstractF2m curve = (ECCurve.AbstractF2m) p.getCurve();
+ int m = curve.getFieldSize();
+ int a = curve.getA().toBigInteger().intValue();
+ byte mu = getMu(a);
BigInteger[] s = curve.getSi();
- ZTauElement rho = partModReduction(k, m, a, s, mu, (byte)10);
+ ZTauElement rho = partModReduction(k, m, (byte)a, s, mu, (byte)10);
return multiplyTnaf(p, rho);
}
/**
- * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.F2m ECPoint.F2m}
+ * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.AbstractF2m ECPoint.AbstractF2m}
* by an element <code>&lambda;</code> of <code><b>Z</b>[&tau;]</code>
* using the <code>&tau;</code>-adic NAF (TNAF) method.
- * @param p The ECPoint.F2m to multiply.
+ * @param p The ECPoint.AbstractF2m to multiply.
* @param lambda The element <code>&lambda;</code> of
* <code><b>Z</b>[&tau;]</code>.
* @return <code>&lambda; * p</code>
*/
- public static ECPoint.F2m multiplyTnaf(ECPoint.F2m p, ZTauElement lambda)
+ public static ECPoint.AbstractF2m multiplyTnaf(ECPoint.AbstractF2m p, ZTauElement lambda)
{
- ECCurve.F2m curve = (ECCurve.F2m)p.getCurve();
- byte mu = curve.getMu();
+ ECCurve.AbstractF2m curve = (ECCurve.AbstractF2m)p.getCurve();
+ byte mu = getMu(curve.getA());
byte[] u = tauAdicNaf(mu, lambda);
- ECPoint.F2m q = multiplyFromTnaf(p, u);
+ ECPoint.AbstractF2m q = multiplyFromTnaf(p, u);
return q;
}
/**
- * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.F2m ECPoint.F2m}
+ * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.AbstractF2m ECPoint.AbstractF2m}
* by an element <code>&lambda;</code> of <code><b>Z</b>[&tau;]</code>
* using the <code>&tau;</code>-adic NAF (TNAF) method, given the TNAF
* of <code>&lambda;</code>.
- * @param p The ECPoint.F2m to multiply.
+ * @param p The ECPoint.AbstractF2m to multiply.
* @param u The the TNAF of <code>&lambda;</code>..
* @return <code>&lambda; * p</code>
*/
- public static ECPoint.F2m multiplyFromTnaf(ECPoint.F2m p, byte[] u)
+ public static ECPoint.AbstractF2m multiplyFromTnaf(ECPoint.AbstractF2m p, byte[] u)
{
- ECCurve.F2m curve = (ECCurve.F2m)p.getCurve();
- ECPoint.F2m q = (ECPoint.F2m) curve.getInfinity();
+ ECCurve curve = p.getCurve();
+ ECPoint.AbstractF2m q = (ECPoint.AbstractF2m)curve.getInfinity();
+ ECPoint.AbstractF2m pNeg = (ECPoint.AbstractF2m)p.negate();
+ int tauCount = 0;
for (int i = u.length - 1; i >= 0; i--)
{
- q = tau(q);
- if (u[i] == 1)
- {
- q = (ECPoint.F2m)q.addSimple(p);
- }
- else if (u[i] == -1)
+ ++tauCount;
+ byte ui = u[i];
+ if (ui != 0)
{
- q = (ECPoint.F2m)q.subtractSimple(p);
+ q = q.tauPow(tauCount);
+ tauCount = 0;
+
+ ECPoint x = ui > 0 ? p : pNeg;
+ q = (ECPoint.AbstractF2m)q.add(x);
}
}
+ if (tauCount > 0)
+ {
+ q = q.tauPow(tauCount);
+ }
return q;
}
@@ -794,26 +829,17 @@ class Tnaf
* @param a The parameter <code>a</code> of the elliptic curve.
* @return The precomputation array for <code>p</code>.
*/
- public static ECPoint.F2m[] getPreComp(ECPoint.F2m p, byte a)
+ public static ECPoint.AbstractF2m[] getPreComp(ECPoint.AbstractF2m p, byte a)
{
- ECPoint.F2m[] pu;
- pu = new ECPoint.F2m[16];
- pu[1] = p;
- byte[][] alphaTnaf;
- if (a == 0)
- {
- alphaTnaf = Tnaf.alpha0Tnaf;
- }
- else
- {
- // a == 1
- alphaTnaf = Tnaf.alpha1Tnaf;
- }
+ byte[][] alphaTnaf = (a == 0) ? Tnaf.alpha0Tnaf : Tnaf.alpha1Tnaf;
+
+ ECPoint.AbstractF2m[] pu = new ECPoint.AbstractF2m[(alphaTnaf.length + 1) >>> 1];
+ pu[0] = p;
int precompLen = alphaTnaf.length;
- for (int i = 3; i < precompLen; i = i + 2)
+ for (int i = 3; i < precompLen; i += 2)
{
- pu[i] = Tnaf.multiplyFromTnaf(p, alphaTnaf[i]);
+ pu[i >>> 1] = Tnaf.multiplyFromTnaf(p, alphaTnaf[i]);
}
p.getCurve().normalizeAll(pu);
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/WTauNafMultiplier.java b/bcprov/src/main/java/org/bouncycastle/math/ec/WTauNafMultiplier.java
index 93d03b46..7974e1d3 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/WTauNafMultiplier.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/WTauNafMultiplier.java
@@ -12,26 +12,26 @@ public class WTauNafMultiplier extends AbstractECMultiplier
static final String PRECOMP_NAME = "bc_wtnaf";
/**
- * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.F2m ECPoint.F2m}
+ * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.AbstractF2m ECPoint.AbstractF2m}
* by <code>k</code> using the reduced <code>&tau;</code>-adic NAF (RTNAF)
* method.
- * @param p The ECPoint.F2m to multiply.
+ * @param point The ECPoint.AbstractF2m to multiply.
* @param k The integer by which to multiply <code>k</code>.
* @return <code>p</code> multiplied by <code>k</code>.
*/
protected ECPoint multiplyPositive(ECPoint point, BigInteger k)
{
- if (!(point instanceof ECPoint.F2m))
+ if (!(point instanceof ECPoint.AbstractF2m))
{
- throw new IllegalArgumentException("Only ECPoint.F2m can be " +
+ throw new IllegalArgumentException("Only ECPoint.AbstractF2m can be " +
"used in WTauNafMultiplier");
}
- ECPoint.F2m p = (ECPoint.F2m)point;
- ECCurve.F2m curve = (ECCurve.F2m)p.getCurve();
- int m = curve.getM();
+ ECPoint.AbstractF2m p = (ECPoint.AbstractF2m)point;
+ ECCurve.AbstractF2m curve = (ECCurve.AbstractF2m)p.getCurve();
+ int m = curve.getFieldSize();
byte a = curve.getA().toBigInteger().byteValue();
- byte mu = curve.getMu();
+ byte mu = Tnaf.getMu(a);
BigInteger[] s = curve.getSi();
ZTauElement rho = Tnaf.partModReduction(k, m, a, s, mu, (byte)10);
@@ -40,16 +40,16 @@ public class WTauNafMultiplier extends AbstractECMultiplier
}
/**
- * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.F2m ECPoint.F2m}
+ * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.AbstractF2m ECPoint.AbstractF2m}
* by an element <code>&lambda;</code> of <code><b>Z</b>[&tau;]</code> using
* the <code>&tau;</code>-adic NAF (TNAF) method.
- * @param p The ECPoint.F2m to multiply.
+ * @param p The ECPoint.AbstractF2m to multiply.
* @param lambda The element <code>&lambda;</code> of
* <code><b>Z</b>[&tau;]</code> of which to compute the
* <code>[&tau;]</code>-adic NAF.
* @return <code>p</code> multiplied by <code>&lambda;</code>.
*/
- private ECPoint.F2m multiplyWTnaf(ECPoint.F2m p, ZTauElement lambda,
+ private ECPoint.AbstractF2m multiplyWTnaf(ECPoint.AbstractF2m p, ZTauElement lambda,
PreCompInfo preCompInfo, byte a, byte mu)
{
ZTauElement[] alpha = (a == 0) ? Tnaf.alpha0 : Tnaf.alpha1;
@@ -63,20 +63,20 @@ public class WTauNafMultiplier extends AbstractECMultiplier
}
/**
- * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.F2m ECPoint.F2m}
+ * Multiplies a {@link org.bouncycastle.math.ec.ECPoint.AbstractF2m ECPoint.AbstractF2m}
* by an element <code>&lambda;</code> of <code><b>Z</b>[&tau;]</code>
* using the window <code>&tau;</code>-adic NAF (TNAF) method, given the
* WTNAF of <code>&lambda;</code>.
- * @param p The ECPoint.F2m to multiply.
+ * @param p The ECPoint.AbstractF2m to multiply.
* @param u The the WTNAF of <code>&lambda;</code>..
* @return <code>&lambda; * p</code>
*/
- private static ECPoint.F2m multiplyFromWTnaf(ECPoint.F2m p, byte[] u, PreCompInfo preCompInfo)
+ private static ECPoint.AbstractF2m multiplyFromWTnaf(ECPoint.AbstractF2m p, byte[] u, PreCompInfo preCompInfo)
{
- ECCurve.F2m curve = (ECCurve.F2m)p.getCurve();
+ ECCurve.AbstractF2m curve = (ECCurve.AbstractF2m)p.getCurve();
byte a = curve.getA().toBigInteger().byteValue();
- ECPoint.F2m[] pu;
+ ECPoint.AbstractF2m[] pu;
if ((preCompInfo == null) || !(preCompInfo instanceof WTauNafPreCompInfo))
{
pu = Tnaf.getPreComp(p, a);
@@ -90,25 +90,35 @@ public class WTauNafMultiplier extends AbstractECMultiplier
pu = ((WTauNafPreCompInfo)preCompInfo).getPreComp();
}
+ // TODO Include negations in precomp (optionally) and use from here
+ ECPoint.AbstractF2m[] puNeg = new ECPoint.AbstractF2m[pu.length];
+ for (int i = 0; i < pu.length; ++i)
+ {
+ puNeg[i] = (ECPoint.AbstractF2m)pu[i].negate();
+ }
+
+
// q = infinity
- ECPoint.F2m q = (ECPoint.F2m) p.getCurve().getInfinity();
+ ECPoint.AbstractF2m q = (ECPoint.AbstractF2m) p.getCurve().getInfinity();
+
+ int tauCount = 0;
for (int i = u.length - 1; i >= 0; i--)
{
- q = Tnaf.tau(q);
- byte ui = u[i];
+ ++tauCount;
+ int ui = u[i];
if (ui != 0)
{
- if (ui > 0)
- {
- q = q.addSimple(pu[ui]);
- }
- else
- {
- q = q.subtractSimple(pu[-ui]);
- }
+ q = q.tauPow(tauCount);
+ tauCount = 0;
+
+ ECPoint x = ui > 0 ? pu[ui >>> 1] : puNeg[(-ui) >>> 1];
+ q = (ECPoint.AbstractF2m)q.add(x);
}
}
-
+ if (tauCount > 0)
+ {
+ q = q.tauPow(tauCount);
+ }
return q;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/WTauNafPreCompInfo.java b/bcprov/src/main/java/org/bouncycastle/math/ec/WTauNafPreCompInfo.java
index 190eecba..58006600 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/WTauNafPreCompInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/WTauNafPreCompInfo.java
@@ -7,19 +7,17 @@ package org.bouncycastle.math.ec;
public class WTauNafPreCompInfo implements PreCompInfo
{
/**
- * Array holding the precomputed <code>ECPoint.F2m</code>s used for the
- * WTNAF multiplication in <code>
- * {@link org.bouncycastle.math.ec.multiplier.WTauNafMultiplier.multiply()
- * WTauNafMultiplier.multiply()}</code>.
+ * Array holding the precomputed <code>ECPoint.AbstractF2m</code>s used for the
+ * WTNAF multiplication.
*/
- protected ECPoint.F2m[] preComp = null;
+ protected ECPoint.AbstractF2m[] preComp = null;
- public ECPoint.F2m[] getPreComp()
+ public ECPoint.AbstractF2m[] getPreComp()
{
return preComp;
}
- public void setPreComp(ECPoint.F2m[] preComp)
+ public void setPreComp(ECPoint.AbstractF2m[] preComp)
{
this.preComp = preComp;
}
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 0032f357..642c44cd 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
@@ -130,10 +130,10 @@ public class SecP192K1FieldElement extends ECFieldElement
{
/*
* Raise this element to the exponent 2^190 - 2^30 - 2^10 - 2^6 - 2^5 - 2^4 - 2^1
- *
+ *
* Breaking up the exponent's binary representation into "repunits", we get:
* { 159 1s } { 1 0s } { 19 1s } { 1 0s } { 3 1s } { 3 0s} { 3 1s } { 1 0s }
- *
+ *
* Therefore we need an addition chain containing 3, 19, 159 (the lengths of the repunits)
* We use: 1, 2, [3], 6, 8, 16, [19], 35, 70, 140, [159]
*/
@@ -187,7 +187,7 @@ public class SecP192K1FieldElement extends ECFieldElement
int[] t2 = x3;
SecP192K1Field.square(t1, t2);
- return Nat192.eq(x1, t2) ? new SecP192K1FieldElement(t1) : null;
+ return Nat192.eq(x1, t2) ? new SecP192K1FieldElement(t1) : null;
}
public boolean equals(Object other)
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 eaa97277..e4ecf01d 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
@@ -10,14 +10,14 @@ 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)
@@ -27,7 +27,7 @@ public class SecP192K1Point extends ECPoint.AbstractFp
/**
* Create a point that encodes with or without point compresion.
- *
+ *
* @param curve
* the curve to use
* @param x
@@ -36,7 +36,7 @@ public class SecP192K1Point extends ECPoint.AbstractFp
* affine y co-ordinate
* @param withCompression
* if true encode with point compression
- *
+ *
* @deprecated per-point compression property will be removed, refer
* {@link #getEncoded(boolean)}
*/
@@ -210,7 +210,7 @@ public class SecP192K1Point extends ECPoint.AbstractFp
SecP192K1FieldElement X1 = (SecP192K1FieldElement)this.x, Z1 = (SecP192K1FieldElement)this.zs[0];
int c;
-
+
int[] Y1Squared = Nat192.create();
SecP192K1Field.square(Y1.x, Y1Squared);
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 c8f5eed5..75e2f5c2 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
@@ -168,7 +168,7 @@ public class SecP192R1Field
if (x != 0)
{
long xx06 = x & M;
-
+
cc += (z[0] & M) + xx06;
z[0] = (int)cc;
cc >>= 32;
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 3ed72f85..f60fc131 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
@@ -10,14 +10,14 @@ 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)
@@ -27,7 +27,7 @@ public class SecP192R1Point extends ECPoint.AbstractFp
/**
* Create a point that encodes with or without point compresion.
- *
+ *
* @param curve
* the curve to use
* @param x
@@ -36,7 +36,7 @@ public class SecP192R1Point extends ECPoint.AbstractFp
* affine y co-ordinate
* @param withCompression
* if true encode with point compression
- *
+ *
* @deprecated per-point compression property will be removed, refer
* {@link #getEncoded(boolean)}
*/
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 73f19993..8285a4e9 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
@@ -137,10 +137,10 @@ public class SecP224K1FieldElement extends ECFieldElement
* Q == 8m + 5, so we use Pocklington's method for this case.
*
* First, raise this element to the exponent 2^221 - 2^29 - 2^9 - 2^8 - 2^6 - 2^4 - 2^1 (i.e. m + 1)
- *
+ *
* Breaking up the exponent's binary representation into "repunits", we get:
* { 191 1s } { 1 0s } { 19 1s } { 2 0s } { 1 1s } { 1 0s} { 1 1s } { 1 0s} { 3 1s } { 1 0s}
- *
+ *
* Therefore we need an addition chain containing 1, 3, 19, 191 (the lengths of the repunits)
* We use: [1], 2, [3], 4, 8, 11, [19], 23, 42, 84, 107, [191]
*/
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 114623dc..a4d37b5f 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
@@ -10,14 +10,14 @@ 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)
@@ -27,7 +27,7 @@ public class SecP224K1Point extends ECPoint.AbstractFp
/**
* Create a point that encodes with or without point compresion.
- *
+ *
* @param curve
* the curve to use
* @param x
@@ -36,7 +36,7 @@ public class SecP224K1Point extends ECPoint.AbstractFp
* affine y co-ordinate
* @param withCompression
* if true encode with point compression
- *
+ *
* @deprecated per-point compression property will be removed, refer
* {@link #getEncoded(boolean)}
*/
@@ -210,7 +210,7 @@ public class SecP224K1Point extends ECPoint.AbstractFp
SecP224K1FieldElement X1 = (SecP224K1FieldElement)this.x, Z1 = (SecP224K1FieldElement)this.zs[0];
int c;
-
+
int[] Y1Squared = Nat224.create();
SecP224K1Field.square(Y1.x, Y1Squared);
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 02a86f0f..e05f6775 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
@@ -171,7 +171,7 @@ public class SecP224R1Field
if (x != 0)
{
long xx07 = x & M;
-
+
cc += (z[0] & M) - xx07;
z[0] = (int)cc;
cc >>= 32;
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 df10b9b4..31da6f60 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
@@ -10,14 +10,14 @@ 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)
@@ -27,7 +27,7 @@ public class SecP224R1Point extends ECPoint.AbstractFp
/**
* Create a point that encodes with or without point compresion.
- *
+ *
* @param curve
* the curve to use
* @param x
@@ -36,7 +36,7 @@ public class SecP224R1Point extends ECPoint.AbstractFp
* affine y co-ordinate
* @param withCompression
* if true encode with point compression
- *
+ *
* @deprecated per-point compression property will be removed, refer
* {@link #getEncoded(boolean)}
*/
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 0f7e2951..467b17f5 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
@@ -131,10 +131,10 @@ public class SecP256K1FieldElement extends ECFieldElement
{
/*
* Raise this element to the exponent 2^254 - 2^30 - 2^7 - 2^6 - 2^5 - 2^4 - 2^2
- *
+ *
* Breaking up the exponent's binary representation into "repunits", we get:
* { 223 1s } { 1 0s } { 22 1s } { 4 0s } { 2 1s } { 2 0s}
- *
+ *
* Therefore we need an addition chain containing 2, 22, 223 (the lengths of the repunits)
* We use: 1, [2], 3, 6, 9, 11, [22], 44, 88, 176, 220, [223]
*/
@@ -189,7 +189,7 @@ public class SecP256K1FieldElement extends ECFieldElement
int[] t2 = x2;
SecP256K1Field.square(t1, t2);
- return Nat256.eq(x1, t2) ? new SecP256K1FieldElement(t1) : null;
+ return Nat256.eq(x1, t2) ? new SecP256K1FieldElement(t1) : null;
}
public boolean equals(Object other)
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 f57b200a..43c9c558 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
@@ -10,14 +10,14 @@ 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)
@@ -27,7 +27,7 @@ public class SecP256K1Point extends ECPoint.AbstractFp
/**
* Create a point that encodes with or without point compresion.
- *
+ *
* @param curve
* the curve to use
* @param x
@@ -36,7 +36,7 @@ public class SecP256K1Point extends ECPoint.AbstractFp
* affine y co-ordinate
* @param withCompression
* if true encode with point compression
- *
+ *
* @deprecated per-point compression property will be removed, refer
* {@link #getEncoded(boolean)}
*/
@@ -210,7 +210,7 @@ public class SecP256K1Point extends ECPoint.AbstractFp
SecP256K1FieldElement X1 = (SecP256K1FieldElement)this.x, Z1 = (SecP256K1FieldElement)this.zs[0];
int c;
-
+
int[] Y1Squared = Nat256.create();
SecP256K1Field.square(Y1.x, Y1Squared);
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 985cb0e2..5a066d81 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
@@ -30,7 +30,7 @@ public class SecP256R1Field
public static void addExt(int[] xx, int[] yy, int[] zz)
{
int c = Nat.add(16, xx, yy, zz);
- if (c != 0 || ((zz[15] & PExt15) == PExt15 && Nat.gte(16, zz, PExt)))
+ if (c != 0 || (zz[15] == PExt15 && Nat.gte(16, zz, PExt)))
{
Nat.subFrom(16, PExt, zz);
}
@@ -78,7 +78,7 @@ public class SecP256R1Field
public static void multiplyAddToExt(int[] x, int[] y, int[] zz)
{
int c = Nat256.mulAddTo(x, y, zz);
- if (c != 0 || ((zz[15] & PExt15) == PExt15 && Nat.gte(16, zz, PExt)))
+ if (c != 0 || (zz[15] == PExt15 && Nat.gte(16, zz, PExt)))
{
Nat.subFrom(16, PExt, zz);
}
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 930fdc58..78b5ff8f 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
@@ -10,14 +10,14 @@ 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)
@@ -27,7 +27,7 @@ public class SecP256R1Point extends ECPoint.AbstractFp
/**
* Create a point that encodes with or without point compresion.
- *
+ *
* @param curve
* the curve to use
* @param x
@@ -36,7 +36,7 @@ public class SecP256R1Point extends ECPoint.AbstractFp
* affine y co-ordinate
* @param withCompression
* if true encode with point compression
- *
+ *
* @deprecated per-point compression property will be removed, refer
* {@link #getEncoded(boolean)}
*/
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 f321a105..fcbb8727 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
@@ -155,11 +155,11 @@ public class SecP384R1Field
public static void reduce32(int x, int[] z)
{
long cc = 0;
-
+
if (x != 0)
{
long xx12 = x & M;
-
+
cc += (z[0] & M) + xx12;
z[0] = (int)cc;
cc >>= 32;
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 89f6bf4f..32c3b3f0 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
@@ -10,14 +10,14 @@ 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)
@@ -27,7 +27,7 @@ public class SecP384R1Point extends ECPoint.AbstractFp
/**
* Create a point that encodes with or without point compresion.
- *
+ *
* @param curve
* the curve to use
* @param x
@@ -36,7 +36,7 @@ public class SecP384R1Point extends ECPoint.AbstractFp
* affine y co-ordinate
* @param withCompression
* if true encode with point compression
- *
+ *
* @deprecated per-point compression property will be removed, refer
* {@link #getEncoded(boolean)}
*/
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 d9737152..d0445fa7 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
@@ -9,14 +9,14 @@ 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)
@@ -26,7 +26,7 @@ public class SecP521R1Point extends ECPoint.AbstractFp
/**
* Create a point that encodes with or without point compresion.
- *
+ *
* @param curve
* the curve to use
* @param x
@@ -35,7 +35,7 @@ public class SecP521R1Point extends ECPoint.AbstractFp
* affine y co-ordinate
* @param withCompression
* if true encode with point compression
- *
+ *
* @deprecated per-point compression property will be removed, refer
* {@link #getEncoded(boolean)}
*/
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 ab710d1a..38591c05 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
@@ -26,9 +26,9 @@ public class GLVTypeBEndomorphism implements GLVEndomorphism
BigInteger b1 = calculateB(k, parameters.getG1(), bits);
BigInteger b2 = calculateB(k, parameters.getG2(), bits);
- BigInteger[] v1 = parameters.getV1(), v2 = parameters.getV2();
- BigInteger a = k.subtract((b1.multiply(v1[0])).add(b2.multiply(v2[0])));
- BigInteger b = (b1.multiply(v1[1])).add(b2.multiply(v2[1])).negate();
+ 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 };
}
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 f02a882f..92c175ab 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,19 +4,32 @@ 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[] v1, v2;
+ protected final BigInteger v1A, v1B, v2A, v2B;
protected final BigInteger g1, g2;
protected final int bits;
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.v1 = v1;
- this.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;
@@ -32,14 +45,40 @@ public class GLVTypeBParameters
return lambda;
}
+ /**
+ * @deprecated Use {@link #getV1A()} and {@link #getV1B()} instead.
+ */
public BigInteger[] getV1()
{
- return v1;
+ return new BigInteger[]{ v1A, v1B };
+ }
+
+ public BigInteger getV1A()
+ {
+ return v1A;
+ }
+
+ public BigInteger getV1B()
+ {
+ return v1B;
}
+ /**
+ * @deprecated Use {@link #getV2A()} and {@link #getV2B()} instead.
+ */
public BigInteger[] getV2()
{
- return v2;
+ return new BigInteger[]{ v2A, v2B };
+ }
+
+ public BigInteger getV2A()
+ {
+ return v2A;
+ }
+
+ public BigInteger getV2B()
+ {
+ return v2B;
}
public BigInteger getG1()
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 75e15434..2057c8bc 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat.java
@@ -211,6 +211,11 @@ public abstract class Nat
return new int[len];
}
+ public static long[] create64(int len)
+ {
+ return new long[len];
+ }
+
public static int dec(int len, int[] z)
{
for (int i = 0; i < len; ++i)
@@ -691,6 +696,17 @@ public abstract class Nat
return c >>> 31;
}
+ public static long shiftUpBit64(int len, long[] x, int xOff, long c, long[] z, int zOff)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ long next = x[xOff + i];
+ z[zOff + i] = (next << 1) | (c >>> 63);
+ c = next;
+ }
+ return c >>> 63;
+ }
+
public static int shiftUpBits(int len, int[] z, int bits, int c)
{
// assert bits > 0 && bits < 32;
@@ -715,6 +731,18 @@ public abstract class Nat
return c >>> -bits;
}
+ public static long shiftUpBits64(int len, long[] z, int zOff, int bits, long c)
+ {
+// assert bits > 0 && bits < 64;
+ for (int i = 0; i < len; ++i)
+ {
+ long next = z[zOff + i];
+ z[zOff + i] = (next << bits) | (c >>> -bits);
+ c = next;
+ }
+ return c >>> -bits;
+ }
+
public static int shiftUpBits(int len, int[] x, int bits, int c, int[] z)
{
// assert bits > 0 && bits < 32;
@@ -739,6 +767,18 @@ public abstract class Nat
return c >>> -bits;
}
+ public static long shiftUpBits64(int len, long[] x, int xOff, int bits, long c, long[] z, int zOff)
+ {
+// assert bits > 0 && bits < 64;
+ for (int i = 0; i < len; ++i)
+ {
+ long next = x[xOff + i];
+ z[zOff + i] = (next << bits) | (c >>> -bits);
+ c = next;
+ }
+ return c >>> -bits;
+ }
+
public static void square(int len, int[] x, int[] zz)
{
int extLen = len << 1;
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 e7e3dfa5..421883e0 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat192.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat192.java
@@ -144,16 +144,33 @@ public abstract class Nat192
z[5] = x[5];
}
+ public static void copy64(long[] x, long[] z)
+ {
+ z[0] = x[0];
+ z[1] = x[1];
+ z[2] = x[2];
+ }
+
public static int[] create()
{
return new int[6];
}
+ public static long[] create64()
+ {
+ return new long[3];
+ }
+
public static int[] createExt()
{
return new int[12];
}
+ public static long[] createExt64()
+ {
+ return new long[6];
+ }
+
public static boolean diff(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
{
boolean pos = gte(x, xOff, y, yOff);
@@ -180,6 +197,18 @@ public abstract class Nat192
return true;
}
+ public static boolean eq64(long[] x, long[] y)
+ {
+ for (int i = 2; i >= 0; --i)
+ {
+ if (x[i] != y[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
public static int[] fromBigInteger(BigInteger x)
{
if (x.signum() < 0 || x.bitLength() > 192)
@@ -197,6 +226,23 @@ public abstract class Nat192
return z;
}
+ public static long[] fromBigInteger64(BigInteger x)
+ {
+ if (x.signum() < 0 || x.bitLength() > 192)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ long[] z = create64();
+ int i = 0;
+ while (x.signum() != 0)
+ {
+ z[i++] = x.longValue();
+ x = x.shiftRight(64);
+ }
+ return z;
+ }
+
public static int getBit(int[] x, int bit)
{
if (bit == 0)
@@ -256,6 +302,22 @@ public abstract class Nat192
return true;
}
+ public static boolean isOne64(long[] x)
+ {
+ if (x[0] != 1L)
+ {
+ return false;
+ }
+ for (int i = 1; i < 3; ++i)
+ {
+ if (x[i] != 0L)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
public static boolean isZero(int[] x)
{
for (int i = 0; i < 6; ++i)
@@ -268,6 +330,18 @@ public abstract class Nat192
return true;
}
+ public static boolean isZero64(long[] x)
+ {
+ for (int i = 0; i < 3; ++i)
+ {
+ if (x[i] != 0L)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
public static void mul(int[] x, int[] y, int[] zz)
{
long y_0 = y[0] & M;
@@ -956,6 +1030,20 @@ public abstract class Nat192
return new BigInteger(1, bs);
}
+ public static BigInteger toBigInteger64(long[] x)
+ {
+ byte[] bs = new byte[24];
+ for (int i = 0; i < 3; ++i)
+ {
+ long x_i = x[i];
+ if (x_i != 0L)
+ {
+ Pack.longToBigEndian(x_i, bs, (2 - i) << 3);
+ }
+ }
+ return new BigInteger(1, bs);
+ }
+
public static void zero(int[] z)
{
z[0] = 0;
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 9886678a..db1daac0 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat256.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat256.java
@@ -238,16 +238,34 @@ public abstract class Nat256
z[7] = x[7];
}
+ public static void copy64(long[] x, long[] z)
+ {
+ z[0] = x[0];
+ z[1] = x[1];
+ z[2] = x[2];
+ z[3] = x[3];
+ }
+
public static int[] create()
{
return new int[8];
}
+ public static long[] create64()
+ {
+ return new long[4];
+ }
+
public static int[] createExt()
{
return new int[16];
}
+ public static long[] createExt64()
+ {
+ return new long[8];
+ }
+
public static boolean diff(int[] x, int xOff, int[] y, int yOff, int[] z, int zOff)
{
boolean pos = gte(x, xOff, y, yOff);
@@ -274,6 +292,18 @@ public abstract class Nat256
return true;
}
+ public static boolean eq64(long[] x, long[] y)
+ {
+ for (int i = 3; i >= 0; --i)
+ {
+ if (x[i] != y[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
public static int[] fromBigInteger(BigInteger x)
{
if (x.signum() < 0 || x.bitLength() > 256)
@@ -291,6 +321,23 @@ public abstract class Nat256
return z;
}
+ public static long[] fromBigInteger64(BigInteger x)
+ {
+ if (x.signum() < 0 || x.bitLength() > 256)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ long[] z = create64();
+ int i = 0;
+ while (x.signum() != 0)
+ {
+ z[i++] = x.longValue();
+ x = x.shiftRight(64);
+ }
+ return z;
+ }
+
public static int getBit(int[] x, int bit)
{
if (bit == 0)
@@ -350,6 +397,22 @@ public abstract class Nat256
return true;
}
+ public static boolean isOne64(long[] x)
+ {
+ if (x[0] != 1L)
+ {
+ return false;
+ }
+ for (int i = 1; i < 4; ++i)
+ {
+ if (x[i] != 0L)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
public static boolean isZero(int[] x)
{
for (int i = 0; i < 8; ++i)
@@ -362,6 +425,18 @@ public abstract class Nat256
return true;
}
+ public static boolean isZero64(long[] x)
+ {
+ for (int i = 0; i < 4; ++i)
+ {
+ if (x[i] != 0L)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
public static void mul(int[] x, int[] y, int[] zz)
{
long y_0 = y[0] & M;
@@ -1292,6 +1367,20 @@ public abstract class Nat256
return new BigInteger(1, bs);
}
+ public static BigInteger toBigInteger64(long[] x)
+ {
+ byte[] bs = new byte[32];
+ for (int i = 0; i < 4; ++i)
+ {
+ long x_i = x[i];
+ if (x_i != 0L)
+ {
+ Pack.longToBigEndian(x_i, bs, (3 - i) << 3);
+ }
+ }
+ return new BigInteger(1, bs);
+ }
+
public static void zero(int[] z)
{
z[0] = 0;
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Arrays.java b/bcprov/src/main/java/org/bouncycastle/util/Arrays.java
index 3c0646ab..99325a9f 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/Arrays.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/Arrays.java
@@ -1,7 +1,7 @@
package org.bouncycastle.util;
import java.math.BigInteger;
-import java.util.Iterator;
+import java.util.NoSuchElementException;
/**
* General array utilities.
@@ -324,7 +324,7 @@ public final class Arrays
return hc;
}
-
+
public static int hashCode(byte[] data, int off, int len)
{
if (data == null)
@@ -413,6 +413,50 @@ public final class Arrays
return hc;
}
+ public static int hashCode(long[] data)
+ {
+ if (data == null)
+ {
+ return 0;
+ }
+
+ int i = data.length;
+ int hc = i + 1;
+
+ while (--i >= 0)
+ {
+ long di = data[i];
+ hc *= 257;
+ hc ^= (int)di;
+ hc *= 257;
+ hc ^= (int)(di >>> 32);
+ }
+
+ return hc;
+ }
+
+ public static int hashCode(long[] data, int off, int len)
+ {
+ if (data == null)
+ {
+ return 0;
+ }
+
+ int i = len;
+ int hc = i + 1;
+
+ while (--i >= 0)
+ {
+ long di = data[off + i];
+ hc *= 257;
+ hc ^= (int)di;
+ hc *= 257;
+ hc ^= (int)(di >>> 32);
+ }
+
+ return hc;
+ }
+
public static int hashCode(short[][][] shorts)
{
int hc = 0;
@@ -488,6 +532,19 @@ public final class Arrays
return copy;
}
+ public static char[] clone(char[] data)
+ {
+ if (data == null)
+ {
+ return null;
+ }
+ char[] copy = new char[data.length];
+
+ System.arraycopy(data, 0, copy, 0, data.length);
+
+ return copy;
+ }
+
public static byte[] clone(byte[] data, byte[] existing)
{
if (data == null)
@@ -852,6 +909,10 @@ public final class Arrays
return rv;
}
+ else if (a == null)
+ {
+ return concatenate(b, c);
+ }
else if (b == null)
{
return concatenate(a, c);
@@ -970,6 +1031,24 @@ public final class Arrays
return result;
}
+ public static int[] reverse(int[] a)
+ {
+ if (a == null)
+ {
+ return null;
+ }
+
+ int p1 = 0, p2 = a.length;
+ int[] result = new int[p2];
+
+ while (--p2 >= 0)
+ {
+ result[p2] = a[p1++];
+ }
+
+ return result;
+ }
+
/**
* Iterator backed by a specific array.
*/
@@ -1000,6 +1079,11 @@ public final class Arrays
public T next()
{
+ if (position == dataArray.length)
+ {
+ throw new NoSuchElementException("Out of elements: " + position);
+ }
+
return dataArray[position++];
}
diff --git a/bcprov/src/main/java/org/bouncycastle/util/IPAddress.java b/bcprov/src/main/java/org/bouncycastle/util/IPAddress.java
index 9f5d1cbc..8af1709e 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/IPAddress.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/IPAddress.java
@@ -1,5 +1,8 @@
package org.bouncycastle.util;
+/**
+ * Utility methods for processing String objects containing IP addresses.
+ */
public class IPAddress
{
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Integers.java b/bcprov/src/main/java/org/bouncycastle/util/Integers.java
index f52baf52..cbae4a37 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/Integers.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/Integers.java
@@ -1,5 +1,8 @@
package org.bouncycastle.util;
+/**
+ * Utility methods for ints.
+ */
public class Integers
{
public static int rotateLeft(int i, int distance)
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Memoable.java b/bcprov/src/main/java/org/bouncycastle/util/Memoable.java
index ee0bedac..bf40f4eb 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/Memoable.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/Memoable.java
@@ -1,5 +1,9 @@
package org.bouncycastle.util;
+/**
+ * Interface for Memoable objects. Memoable objects allow the taking of a snapshot of their internal state
+ * via the copy() method and then reseting the object back to that state later using the reset() method.
+ */
public interface Memoable
{
/**
@@ -8,7 +12,7 @@ public interface Memoable
* The returned object may be used simply to store the state, or may be used as a similar object
* starting from the copied state.
*/
- public Memoable copy();
+ Memoable copy();
/**
* Restore a copied object state into this object.
@@ -19,5 +23,5 @@ public interface Memoable
* @throws ClassCastException if the provided object is not of the correct type.
* @throws MemoableResetException if the <b>other</b> parameter is in some other way invalid.
*/
- public void reset(Memoable other);
+ void reset(Memoable other);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Pack.java b/bcprov/src/main/java/org/bouncycastle/util/Pack.java
index 2f96af84..94ba17b1 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/Pack.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/Pack.java
@@ -1,5 +1,8 @@
package org.bouncycastle.util;
+/**
+ * Utility methods for converting byte arrays into ints and longs, and back again.
+ */
public abstract class Pack
{
public static int bigEndianToInt(byte[] bs, int off)
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Properties.java b/bcprov/src/main/java/org/bouncycastle/util/Properties.java
new file mode 100644
index 00000000..96cef357
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/util/Properties.java
@@ -0,0 +1,36 @@
+package org.bouncycastle.util;
+
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Utility method for accessing system properties.
+ */
+public class Properties
+{
+ public static boolean isOverrideSet(final String propertyName)
+ {
+ try
+ {
+ return "true".equals(AccessController.doPrivileged(new PrivilegedAction()
+ {
+ // JDK 1.4 compatibility
+ public Object run()
+ {
+ String value = System.getProperty(propertyName);
+ if (value == null)
+ {
+ return null;
+ }
+
+ return Strings.toLowerCase(value);
+ }
+ }));
+ }
+ catch (AccessControlException e)
+ {
+ return false;
+ }
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Selector.java b/bcprov/src/main/java/org/bouncycastle/util/Selector.java
index a3a5ec86..f3366c7d 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/Selector.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/Selector.java
@@ -1,8 +1,19 @@
package org.bouncycastle.util;
+/**
+ * Interface a selector from a store should conform to.
+ *
+ * @param <T> the type stored in the store.
+ */
public interface Selector<T>
extends Cloneable
{
+ /**
+ * Match the passed in object, returning true if it would be selected by this selector, false otherwise.
+ *
+ * @param obj the object to be matched.
+ * @return true if the object is a match for this selector, false otherwise.
+ */
boolean match(T obj);
Object clone();
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Store.java b/bcprov/src/main/java/org/bouncycastle/util/Store.java
index fd28b838..0f55039e 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/Store.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/Store.java
@@ -2,8 +2,21 @@ package org.bouncycastle.util;
import java.util.Collection;
+/**
+ * A generic interface describing a simple store of objects.
+ *
+ * @param <T> the object type stored.
+ */
public interface Store<T>
{
+ /**
+ * Return a possibly empty collection of objects that match the criteria implemented
+ * in the passed in Selector.
+ *
+ * @param selector the selector defining the match criteria.
+ * @return a collection of matching objects, empty if none available.
+ * @throws StoreException if there is a failure during matching.
+ */
Collection<T> getMatches(Selector<T> selector)
throws StoreException;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/util/StoreException.java b/bcprov/src/main/java/org/bouncycastle/util/StoreException.java
index 5ea09e80..7cca2716 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/StoreException.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/StoreException.java
@@ -1,14 +1,23 @@
package org.bouncycastle.util;
+/**
+ * Exception thrown if there's an issue doing a match in store.
+ */
public class StoreException
extends RuntimeException
{
private Throwable _e;
- public StoreException(String s, Throwable e)
+ /**
+ * Basic Constructor.
+ *
+ * @param msg message to be associated with this exception.
+ * @param cause the throwable that caused this exception to be raised.
+ */
+ public StoreException(String msg, Throwable cause)
{
- super(s);
- _e = e;
+ super(msg);
+ _e = cause;
}
public Throwable getCause()
diff --git a/bcprov/src/main/java/org/bouncycastle/util/StringList.java b/bcprov/src/main/java/org/bouncycastle/util/StringList.java
index e7334427..4eb85141 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/StringList.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/StringList.java
@@ -1,14 +1,34 @@
package org.bouncycastle.util;
+/**
+ * An interface defining a list of strings.
+ */
public interface StringList
extends Iterable<String>
{
+ /**
+ * Add a String to the list.
+ *
+ * @param s the String to add.
+ * @return true
+ */
boolean add(String s);
+ /**
+ * Get the string at index index.
+ *
+ * @param index the index position of the String of interest.
+ * @return the String at position index.
+ */
String get(int index);
int size();
+ /**
+ * Return the contents of the list as an array.
+ *
+ * @return an array of String.
+ */
String[] toStringArray();
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Strings.java b/bcprov/src/main/java/org/bouncycastle/util/Strings.java
index 44ff3aec..a42830b3 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/Strings.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/Strings.java
@@ -3,11 +3,46 @@ package org.bouncycastle.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Vector;
+/**
+ * String utilities.
+ */
public final class Strings
{
+ private static String LINE_SEPARATOR;
+
+ static
+ {
+ try
+ {
+ LINE_SEPARATOR = AccessController.doPrivileged(new PrivilegedAction<String>()
+ {
+ public String run()
+ {
+ // the easy way
+ return System.getProperty("line.separator");
+ }
+ });
+
+ }
+ catch (Exception e)
+ {
+ try
+ {
+ // the harder way
+ LINE_SEPARATOR = String.format("%n");
+ }
+ catch (Exception ef)
+ {
+ LINE_SEPARATOR = "\n"; // we're desperate use this...
+ }
+ }
+ }
+
public static String fromUTF8ByteArray(byte[] bytes)
{
int i = 0;
@@ -47,7 +82,7 @@ public final class Strings
if ((bytes[i] & 0xf0) == 0xf0)
{
- int codePoint = ((bytes[i] & 0x03) << 18) | ((bytes[i+1] & 0x3F) << 12) | ((bytes[i+2] & 0x3F) << 6) | (bytes[i+3] & 0x3F);
+ int codePoint = ((bytes[i] & 0x03) << 18) | ((bytes[i + 1] & 0x3F) << 12) | ((bytes[i + 2] & 0x3F) << 6) | (bytes[i + 3] & 0x3F);
int U = codePoint - 0x10000;
char W1 = (char)(0xD800 | (U >> 10));
char W2 = (char)(0xDC00 | (U & 0x3FF));
@@ -58,7 +93,7 @@ public final class Strings
else if ((bytes[i] & 0xe0) == 0xe0)
{
ch = (char)(((bytes[i] & 0x0f) << 12)
- | ((bytes[i + 1] & 0x3f) << 6) | (bytes[i + 2] & 0x3f));
+ | ((bytes[i + 1] & 0x3f) << 6) | (bytes[i + 2] & 0x3f));
i += 3;
}
else if ((bytes[i] & 0xd0) == 0xd0)
@@ -82,7 +117,7 @@ public final class Strings
return new String(cs);
}
-
+
public static byte[] toUTF8ByteArray(String string)
{
return toUTF8ByteArray(string.toCharArray());
@@ -100,7 +135,7 @@ public final class Strings
{
throw new IllegalStateException("cannot encode string to byte array!");
}
-
+
return bOut.toByteArray();
}
@@ -160,7 +195,7 @@ public final class Strings
/**
* A locale independent version of toUpperCase.
- *
+ *
* @param string input to be converted
* @return a US Ascii uppercase version
*/
@@ -168,7 +203,7 @@ public final class Strings
{
boolean changed = false;
char[] chars = string.toCharArray();
-
+
for (int i = 0; i != chars.length; i++)
{
char ch = chars[i];
@@ -178,18 +213,18 @@ public final class Strings
chars[i] = (char)(ch - 'a' + 'A');
}
}
-
+
if (changed)
{
return new String(chars);
}
-
+
return string;
}
-
+
/**
* A locale independent version of toLowerCase.
- *
+ *
* @param string input to be converted
* @return a US ASCII lowercase version
*/
@@ -197,7 +232,7 @@ public final class Strings
{
boolean changed = false;
char[] chars = string.toCharArray();
-
+
for (int i = 0; i != chars.length; i++)
{
char ch = chars[i];
@@ -207,12 +242,12 @@ public final class Strings
chars[i] = (char)(ch - 'A' + 'a');
}
}
-
+
if (changed)
{
return new String(chars);
}
-
+
return string;
}
@@ -284,7 +319,7 @@ public final class Strings
public static String[] split(String input, char delimiter)
{
- Vector v = new Vector();
+ Vector v = new Vector();
boolean moreTokens = true;
String subString;
@@ -318,6 +353,11 @@ public final class Strings
return new StringListImpl();
}
+ public static String lineSeparator()
+ {
+ return LINE_SEPARATOR;
+ }
+
private static class StringListImpl
extends ArrayList<String>
implements StringList
diff --git a/bcprov/src/main/java/org/bouncycastle/util/io/Streams.java b/bcprov/src/main/java/org/bouncycastle/util/io/Streams.java
index 0dea2369..f39e026e 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/io/Streams.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/io/Streams.java
@@ -10,7 +10,7 @@ import java.io.OutputStream;
*/
public final class Streams
{
- private static int BUFFER_SIZE = 512;
+ private static int BUFFER_SIZE = 4096;
/**
* Read stream till EOF is encountered.
@@ -133,11 +133,11 @@ public final class Streams
int numRead;
while ((numRead = inStr.read(bs, 0, bs.length)) >= 0)
{
- total += numRead;
- if (total > limit)
+ if ((limit - total) < numRead)
{
throw new StreamOverflowException("Data Overflow");
}
+ total += numRead;
outStr.write(bs, 0, numRead);
}
return total;
diff --git a/bcprov/src/main/java/org/bouncycastle/util/io/pem/PemWriter.java b/bcprov/src/main/java/org/bouncycastle/util/io/pem/PemWriter.java
index ccefa36e..b4964475 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/io/pem/PemWriter.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/io/pem/PemWriter.java
@@ -5,6 +5,7 @@ import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
+import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Base64;
/**
@@ -27,7 +28,7 @@ public class PemWriter
{
super(out);
- String nl = System.getProperty("line.separator");
+ String nl = Strings.lineSeparator();
if (nl != null)
{
nlLength = nl.length();
diff --git a/bcprov/src/main/java/org/bouncycastle/x509/AttributeCertificateHolder.java b/bcprov/src/main/java/org/bouncycastle/x509/AttributeCertificateHolder.java
index b00cd1d4..15375ab1 100644
--- a/bcprov/src/main/java/org/bouncycastle/x509/AttributeCertificateHolder.java
+++ b/bcprov/src/main/java/org/bouncycastle/x509/AttributeCertificateHolder.java
@@ -126,7 +126,7 @@ public class AttributeCertificateHolder
String digestAlgorithm, String otherObjectTypeID, byte[] objectDigest)
{
holder = new Holder(new ObjectDigestInfo(digestedObjectType,
- new ASN1ObjectIdentifier(otherObjectTypeID), new AlgorithmIdentifier(digestAlgorithm), Arrays
+ new ASN1ObjectIdentifier(otherObjectTypeID), new AlgorithmIdentifier(new ASN1ObjectIdentifier(digestAlgorithm)), Arrays
.clone(objectDigest)));
}
@@ -164,7 +164,7 @@ public class AttributeCertificateHolder
{
if (holder.getObjectDigestInfo() != null)
{
- return holder.getObjectDigestInfo().getDigestAlgorithm().getObjectId()
+ return holder.getObjectDigestInfo().getDigestAlgorithm().getAlgorithm()
.getId();
}
return null;
@@ -322,7 +322,7 @@ public class AttributeCertificateHolder
public Object clone()
{
return new AttributeCertificateHolder((ASN1Sequence)holder
- .toASN1Object());
+ .toASN1Primitive());
}
public boolean match(Certificate cert)
diff --git a/bcprov/src/main/java/org/bouncycastle/x509/X509Attribute.java b/bcprov/src/main/java/org/bouncycastle/x509/X509Attribute.java
index 95da2925..f5e9531b 100644
--- a/bcprov/src/main/java/org/bouncycastle/x509/X509Attribute.java
+++ b/bcprov/src/main/java/org/bouncycastle/x509/X509Attribute.java
@@ -11,6 +11,7 @@ import org.bouncycastle.asn1.x509.Attribute;
/**
* Class for carrying the values in an X.509 Attribute.
+ * @deprecated see X509CertificateHolder class in the PKIX package.
*/
public class X509Attribute
extends ASN1Object
diff --git a/bcprov/src/main/java/org/bouncycastle/x509/X509V1CertificateGenerator.java b/bcprov/src/main/java/org/bouncycastle/x509/X509V1CertificateGenerator.java
index f7ff3e43..01f4469f 100644
--- a/bcprov/src/main/java/org/bouncycastle/x509/X509V1CertificateGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/x509/X509V1CertificateGenerator.java
@@ -1,6 +1,5 @@
package org.bouncycastle.x509;
-import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
@@ -20,10 +19,8 @@ import java.util.Iterator;
import javax.security.auth.x500.X500Principal;
import org.bouncycastle.asn1.ASN1EncodableVector;
-import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
-import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
@@ -143,8 +140,7 @@ public class X509V1CertificateGenerator
{
try
{
- tbsGen.setSubjectPublicKeyInfo(new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream(
- new ByteArrayInputStream(key.getEncoded())).readObject()));
+ tbsGen.setSubjectPublicKeyInfo(SubjectPublicKeyInfo.getInstance(key.getEncoded()));
}
catch (Exception e)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/x509/X509V2AttributeCertificate.java b/bcprov/src/main/java/org/bouncycastle/x509/X509V2AttributeCertificate.java
index 14db8eab..61319a85 100644
--- a/bcprov/src/main/java/org/bouncycastle/x509/X509V2AttributeCertificate.java
+++ b/bcprov/src/main/java/org/bouncycastle/x509/X509V2AttributeCertificate.java
@@ -103,7 +103,7 @@ public class X509V2AttributeCertificate
public AttributeCertificateHolder getHolder()
{
- return new AttributeCertificateHolder((ASN1Sequence)cert.getAcinfo().getHolder().toASN1Object());
+ return new AttributeCertificateHolder((ASN1Sequence)cert.getAcinfo().getHolder().toASN1Primitive());
}
public AttributeCertificateIssuer getIssuer()
@@ -164,7 +164,7 @@ public class X509V2AttributeCertificate
public byte[] getSignature()
{
- return cert.getSignatureValue().getBytes();
+ return cert.getSignatureValue().getOctets();
}
public final void verify(
@@ -180,7 +180,7 @@ public class X509V2AttributeCertificate
throw new CertificateException("Signature algorithm in certificate info not same as outer certificate");
}
- signature = Signature.getInstance(cert.getSignatureAlgorithm().getObjectId().getId(), provider);
+ signature = Signature.getInstance(cert.getSignatureAlgorithm().getAlgorithm().getId(), provider);
signature.initVerify(key);
diff --git a/bcprov/src/main/java/org/bouncycastle/x509/extension/AuthorityKeyIdentifierStructure.java b/bcprov/src/main/java/org/bouncycastle/x509/extension/AuthorityKeyIdentifierStructure.java
index 2164d1fb..bcd59932 100644
--- a/bcprov/src/main/java/org/bouncycastle/x509/extension/AuthorityKeyIdentifierStructure.java
+++ b/bcprov/src/main/java/org/bouncycastle/x509/extension/AuthorityKeyIdentifierStructure.java
@@ -6,7 +6,6 @@ import java.security.PublicKey;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
-import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
@@ -15,7 +14,6 @@ import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.X509Extension;
-import org.bouncycastle.asn1.x509.X509Extensions;
import org.bouncycastle.jce.PrincipalUtil;
/**
@@ -70,32 +68,30 @@ public class AuthorityKeyIdentifierStructure
if (certificate.getVersion() != 3)
{
GeneralName genName = new GeneralName(PrincipalUtil.getIssuerX509Principal(certificate));
- SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
- (ASN1Sequence)new ASN1InputStream(certificate.getPublicKey().getEncoded()).readObject());
+ SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(certificate.getPublicKey().getEncoded());
return (ASN1Sequence)new AuthorityKeyIdentifier(
- info, new GeneralNames(genName), certificate.getSerialNumber()).toASN1Object();
+ info, new GeneralNames(genName), certificate.getSerialNumber()).toASN1Primitive();
}
else
{
GeneralName genName = new GeneralName(PrincipalUtil.getIssuerX509Principal(certificate));
- byte[] ext = certificate.getExtensionValue(X509Extensions.SubjectKeyIdentifier.getId());
+ byte[] ext = certificate.getExtensionValue(Extension.subjectKeyIdentifier.getId());
if (ext != null)
{
ASN1OctetString str = (ASN1OctetString)X509ExtensionUtil.fromExtensionValue(ext);
return (ASN1Sequence)new AuthorityKeyIdentifier(
- str.getOctets(), new GeneralNames(genName), certificate.getSerialNumber()).toASN1Object();
+ str.getOctets(), new GeneralNames(genName), certificate.getSerialNumber()).toASN1Primitive();
}
else
{
- SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
- (ASN1Sequence)new ASN1InputStream(certificate.getPublicKey().getEncoded()).readObject());
+ SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(certificate.getPublicKey().getEncoded());
return (ASN1Sequence)new AuthorityKeyIdentifier(
- info, new GeneralNames(genName), certificate.getSerialNumber()).toASN1Object();
+ info, new GeneralNames(genName), certificate.getSerialNumber()).toASN1Primitive();
}
}
}
@@ -111,10 +107,9 @@ public class AuthorityKeyIdentifierStructure
{
try
{
- SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
- (ASN1Sequence)new ASN1InputStream(pubKey.getEncoded()).readObject());
+ SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded());
- return (ASN1Sequence)new AuthorityKeyIdentifier(info).toASN1Object();
+ return (ASN1Sequence)new AuthorityKeyIdentifier(info).toASN1Primitive();
}
catch (Exception e)
{
diff --git a/bouncycastle.version b/bouncycastle.version
index 6bbeb95f..00639910 100644
--- a/bouncycastle.version
+++ b/bouncycastle.version
@@ -1,2 +1,2 @@
BOUNCYCASTLE_JDK=15on
-BOUNCYCASTLE_VERSION=152
+BOUNCYCASTLE_VERSION=154