summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergio Giro <sgiro@google.com>2017-01-04 18:16:22 +0000
committerSergio Giro <sgiro@google.com>2017-01-19 19:49:45 +0000
commit7dad97b63c47edea4e3afb374dcd00c7b7a1bdd4 (patch)
tree8ebc72ead6f9a80938fdba92e217da96ee451037
parentfba1a1dba277746d3be0667de9eb4b98494a1963 (diff)
parenteaf604a467ff401cd0e0f74051ff5afa9e07359d (diff)
downloadbouncycastle-7dad97b63c47edea4e3afb374dcd00c7b7a1bdd4.tar.gz
bouncycastle: upgrade to version 1.56
Merge remote-tracking branch 'aosp/upstream-master' into merge-to-156 Test: ran the following cts modules: CtsLibcoreFileIOTestCases CtsLibcoreJavaUtilCollectionsTestCases CtsLibcoreJsr166TestCases CtsLibcoreLegacy22TestCases CtsLibcoreOjTestCases CtsLibcoreOkHttpTestCases CtsLibcoreTestCases Bug: 31076342 Change-Id: Iceb926dc5a312b2047bf19d1c82fb16e42bc1461
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReqBuilder.java6
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cert/ocsp/RespID.java2
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/CMSAbsentContent.java2
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java2
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java4
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/PasswordRecipient.java30
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java7
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java20
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java33
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java13
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java45
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java3
-rw-r--r--bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecific.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java15
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1Exception.java19
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1Generator.java17
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java11
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java59
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1ParsingException.java19
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringGenerator.java32
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringParser.java19
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BEROutputStream.java14
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java11
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERSequenceParser.java20
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERSet.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERSetParser.java20
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/DLBitString.java11
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java25
-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.java62
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CertStatus.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/MacData.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/sec/SECNamedCurves.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/teletrust/TeleTrusTObjectIdentifiers.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java27
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/DistributionPoint.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/Extension.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraints.java43
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertList.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/X962NamedCurves.java24
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/X962Parameters.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECPoint.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/asn1/x9/X9IntegerConverter.java23
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/agreement/DHBasicAgreement.java10
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/digests/MD5Digest.java38
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA1Digest.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA224Digest.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA384Digest.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA512Digest.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java52
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java280
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java27
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeWrapEngine.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAParametersGenerator.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java44
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/DHPublicKeyParameters.java33
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/DSAPublicKeyParameters.java23
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/ECDomainParameters.java30
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/ECPublicKeyParameters.java27
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/RSAKeyParameters.java34
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java11
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/tls/CertificateType.java15
-rw-r--r--bcprov/src/main/java/org/bouncycastle/iana/AEADAlgorithm.java57
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/PKCS12Key.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DH.java12
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DSA.java19
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java27
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/RSA.java60
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/BCDHPublicKey.java25
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyAgreementSpi.java36
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyFactorySpi.java10
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyPairGeneratorSpi.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/BCDSAPublicKey.java88
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java133
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSAUtil.java36
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java15
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java73
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java18
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java47
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java119
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java51
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyAgreementSpi.java162
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java15
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyPairGeneratorSpi.java12
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java145
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/AlgorithmParametersSpi.java25
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/CipherSpi.java64
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/DigestSignatureSpi.java52
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseAgreementSpi.java16
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java10
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java8
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/DHUtil.java5
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java64
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java84
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/CertificateFactory.java77
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java16
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509CertificateObject.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java62
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ConfigurableProvider.java10
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ProviderConfiguration.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ProviderConfigurationPermission.java25
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA1.java338
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA224.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA256.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA384.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA512.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/keystore/pkcs12/PKCS12KeyStoreSpi.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java230
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/DESede.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java553
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/RC2.java62
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseBlockCipher.java122
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java82
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseSecretKeyFactory.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseWrapCipher.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/IvAlgorithmParameters.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/PBE.java47
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/util/BadBlockException.java21
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/provider/util/DigestFactory.java67
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/spec/AEADParameterSpec.java73
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/spec/PBKDF2KeySpec.java19
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/util/AlgorithmParametersUtils.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/util/BCJcaJceHelper.java10
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/util/JcaJceHelper.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/util/MessageDigestUtils.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java39
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java39
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java1
-rw-r--r--bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/WNafUtil.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/raw/Nat192.java28
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/raw/Nat224.java36
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/raw/Nat256.java44
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/Arrays.java88
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/Pack.java38
-rw-r--r--bcprov/src/main/java/org/bouncycastle/util/io/Streams.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/x509/X509V1CertificateGenerator.java16
-rw-r--r--bcprov/src/main/java/org/bouncycastle/x509/X509V3CertificateGenerator.java35
-rw-r--r--bouncycastle.version2
162 files changed, 3732 insertions, 1516 deletions
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReqBuilder.java b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReqBuilder.java
index b0cfb9ef..3f3c954a 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReqBuilder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/OCSPReqBuilder.java
@@ -75,9 +75,9 @@ public class OCSPReqBuilder
}
/**
- * Set the requestor name to the passed in X500Principal
+ * Set the requestor name to the passed in X500Name
*
- * @param requestorName a X500Principal representing the requestor name.
+ * @param requestorName an X500Name representing the requestor name.
*/
public OCSPReqBuilder setRequestorName(
X500Name requestorName)
@@ -176,7 +176,7 @@ public class OCSPReqBuilder
* Generate an unsigned request
*
* @return the OCSPReq
- * @throws org.bouncycastle.ocsp.OCSPException
+ * @throws org.bouncycastle.cert.ocsp.OCSPException
*/
public OCSPReq build()
throws OCSPException
diff --git a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/RespID.java b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/RespID.java
index a0fd765a..4cd19ef9 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/RespID.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cert/ocsp/RespID.java
@@ -48,7 +48,7 @@ public class RespID
{
if (!digCalc.getAlgorithmIdentifier().equals(HASH_SHA1))
{
- throw new IllegalArgumentException("only SHA-1 can be used with RespID");
+ throw new IllegalArgumentException("only SHA-1 can be used with RespID - found: " + digCalc.getAlgorithmIdentifier().getAlgorithm());
}
OutputStream digOut = digCalc.getOutputStream();
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/CMSAbsentContent.java b/bcpkix/src/main/java/org/bouncycastle/cms/CMSAbsentContent.java
index f256e2a2..242d64bb 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/CMSAbsentContent.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/CMSAbsentContent.java
@@ -17,7 +17,7 @@ public class CMSAbsentContent
public CMSAbsentContent()
{
- this(new ASN1ObjectIdentifier(CMSObjectIdentifiers.data.getId()));
+ this(CMSObjectIdentifiers.data);
}
public CMSAbsentContent(
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java b/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java
index e8ebc83e..780d4660 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/DefaultCMSSignatureEncryptionAlgorithmFinder.java
@@ -41,7 +41,7 @@ public class DefaultCMSSignatureEncryptionAlgorithmFinder
public AlgorithmIdentifier findEncryptionAlgorithm(AlgorithmIdentifier signatureAlgorithm)
{
- // RFC3370 section 3.2
+ // RFC3370 section 3.2 with RFC 5754 update
if (RSA_PKCS1d5.contains(signatureAlgorithm.getAlgorithm()))
{
return new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE);
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java b/bcpkix/src/main/java/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java
index ddfd2ebd..fb268b29 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/DefaultSignedAttributeTableGenerator.java
@@ -51,8 +51,8 @@ public class DefaultSignedAttributeTableGenerator
/**
* Create a standard attribute table from the passed in parameters - this will
- * normally include contentType, signingTime, and messageDigest. If the constructor
- * using an AttributeTable was used, entries in it for contentType, signingTime, and
+ * normally include contentType, signingTime, messageDigest, and CMS algorithm protection.
+ * If the constructor using an AttributeTable was used, entries in it for contentType, signingTime, and
* messageDigest will override the generated ones.
*
* @param parameters source parameters for table generation.
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/PasswordRecipient.java b/bcpkix/src/main/java/org/bouncycastle/cms/PasswordRecipient.java
index 7322fdcc..932c2762 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/PasswordRecipient.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/PasswordRecipient.java
@@ -1,5 +1,7 @@
package org.bouncycastle.cms;
+import org.bouncycastle.asn1.DERNull;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
public interface PasswordRecipient
@@ -8,6 +10,34 @@ public interface PasswordRecipient
public static final int PKCS5_SCHEME2 = 0;
public static final int PKCS5_SCHEME2_UTF8 = 1;
+ static final class PRF
+ {
+ public static final PRF HMacSHA1 = new PRF("HMacSHA1", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA1, DERNull.INSTANCE));
+ public static final PRF HMacSHA224 = new PRF("HMacSHA224", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA224, DERNull.INSTANCE));
+ public static final PRF HMacSHA256 = new PRF("HMacSHA256", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA256, DERNull.INSTANCE));
+ public static final PRF HMacSHA384 = new PRF("HMacSHA384", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA384, DERNull.INSTANCE));
+ public static final PRF HMacSHA512 = new PRF("HMacSHA512", new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA512, DERNull.INSTANCE));
+
+ private final String hmac;
+ final AlgorithmIdentifier prfAlgID;
+
+ private PRF(String hmac, AlgorithmIdentifier prfAlgID)
+ {
+ this.hmac = hmac;
+ this.prfAlgID = prfAlgID;
+ }
+
+ public String getName()
+ {
+ return hmac;
+ }
+
+ public AlgorithmIdentifier getAlgorithmID()
+ {
+ return prfAlgID;
+ }
+ }
+
byte[] calculateDerivedKey(int schemeID, AlgorithmIdentifier derivationAlgorithm, int keySize)
throws CMSException;
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java b/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java
index 7a47a2f8..ccb6e2cf 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/SignerInfoGeneratorBuilder.java
@@ -29,10 +29,11 @@ public class SignerInfoGeneratorBuilder
this(digestProvider, new DefaultCMSSignatureEncryptionAlgorithmFinder());
}
- /**
- * Base constructor.
+ /**
+ * Base constructor with a particular finder for signature algorithms.
*
- * @param digestProvider a provider of digest calculators for the algorithms required in the signature and attribute calculations.
+ * @param digestProvider a provider of digest calculators for the algorithms required in the signature and attribute calculations.
+ * @param sigEncAlgFinder finder for algorithm IDs to store for the signature encryption/signature algorithm field.
*/
public SignerInfoGeneratorBuilder(DigestCalculatorProvider digestProvider, CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder)
{
diff --git a/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java b/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java
index 4a0e7ca4..17a2f093 100644
--- a/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/cms/jcajce/JcaSignerInfoGeneratorBuilder.java
@@ -6,6 +6,8 @@ import java.security.cert.X509Certificate;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
import org.bouncycastle.cms.CMSAttributeTableGenerator;
+import org.bouncycastle.cms.CMSSignatureEncryptionAlgorithmFinder;
+import org.bouncycastle.cms.DefaultCMSSignatureEncryptionAlgorithmFinder;
import org.bouncycastle.cms.SignerInfoGenerator;
import org.bouncycastle.cms.SignerInfoGeneratorBuilder;
import org.bouncycastle.operator.ContentSigner;
@@ -16,9 +18,25 @@ public class JcaSignerInfoGeneratorBuilder
{
private SignerInfoGeneratorBuilder builder;
+ /**
+ * Base constructor.
+ *
+ * @param digestProvider a provider of digest calculators for the algorithms required in the signature and attribute calculations.
+ */
public JcaSignerInfoGeneratorBuilder(DigestCalculatorProvider digestProvider)
{
- builder = new SignerInfoGeneratorBuilder(digestProvider);
+ this(digestProvider, new DefaultCMSSignatureEncryptionAlgorithmFinder());
+ }
+
+ /**
+ * Base constructor with a particular finder for signature algorithms.
+ *
+ * @param digestProvider a provider of digest calculators for the algorithms required in the signature and attribute calculations.
+ * @param sigEncAlgFinder finder for algorithm IDs to store for the signature encryption/signature algorithm field.
+ */
+ public JcaSignerInfoGeneratorBuilder(DigestCalculatorProvider digestProvider, CMSSignatureEncryptionAlgorithmFinder sigEncAlgFinder)
+ {
+ builder = new SignerInfoGeneratorBuilder(digestProvider, sigEncAlgFinder);
}
/**
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
index dc2c431b..57920181 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultDigestAlgorithmIdentifierFinder.java
@@ -6,6 +6,8 @@ import java.util.Map;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERNull;
// BEGIN android-removed
+// import org.bouncycastle.asn1.bc.BCObjectIdentifiers;
+// import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
// END android-removed
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
@@ -51,6 +53,14 @@ public class DefaultDigestAlgorithmIdentifierFinder
digestOids.put(X9ObjectIdentifiers.ecdsa_with_SHA512, NISTObjectIdentifiers.id_sha512);
digestOids.put(X9ObjectIdentifiers.id_dsa_with_sha1, OIWObjectIdentifiers.idSHA1);
+ // BEGIN android-removed
+ // digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA1, OIWObjectIdentifiers.idSHA1);
+ // digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA224, NISTObjectIdentifiers.id_sha224);
+ // digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA256, NISTObjectIdentifiers.id_sha256);
+ // digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA384, NISTObjectIdentifiers.id_sha384);
+ // digestOids.put(BSIObjectIdentifiers.ecdsa_plain_SHA512, NISTObjectIdentifiers.id_sha512);
+ // END android-removed
+
digestOids.put(NISTObjectIdentifiers.dsa_with_sha224, NISTObjectIdentifiers.id_sha224);
digestOids.put(NISTObjectIdentifiers.dsa_with_sha256, NISTObjectIdentifiers.id_sha256);
digestOids.put(NISTObjectIdentifiers.dsa_with_sha384, NISTObjectIdentifiers.id_sha384);
@@ -63,8 +73,31 @@ public class DefaultDigestAlgorithmIdentifierFinder
//
// digestOids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, CryptoProObjectIdentifiers.gostR3411);
// digestOids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, CryptoProObjectIdentifiers.gostR3411);
+ // digestOids.put(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224, NISTObjectIdentifiers.id_sha3_224);
+ // digestOids.put(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_256, NISTObjectIdentifiers.id_sha3_256);
+ // digestOids.put(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_384, NISTObjectIdentifiers.id_sha3_384);
+ // digestOids.put(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512, NISTObjectIdentifiers.id_sha3_512);
+ // digestOids.put(NISTObjectIdentifiers.id_dsa_with_sha3_224, NISTObjectIdentifiers.id_sha3_224);
+ // digestOids.put(NISTObjectIdentifiers.id_dsa_with_sha3_256, NISTObjectIdentifiers.id_sha3_256);
+ // digestOids.put(NISTObjectIdentifiers.id_dsa_with_sha3_384, NISTObjectIdentifiers.id_sha3_384);
+ // digestOids.put(NISTObjectIdentifiers.id_dsa_with_sha3_512, NISTObjectIdentifiers.id_sha3_512);
+ // digestOids.put(NISTObjectIdentifiers.id_ecdsa_with_sha3_224, NISTObjectIdentifiers.id_sha3_224);
+ // digestOids.put(NISTObjectIdentifiers.id_ecdsa_with_sha3_256, NISTObjectIdentifiers.id_sha3_256);
+ // digestOids.put(NISTObjectIdentifiers.id_ecdsa_with_sha3_384, NISTObjectIdentifiers.id_sha3_384);
+ // digestOids.put(NISTObjectIdentifiers.id_ecdsa_with_sha3_512, NISTObjectIdentifiers.id_sha3_512);
+ //
+ // digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, TeleTrusTObjectIdentifiers.ripemd128);
+ // digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, TeleTrusTObjectIdentifiers.ripemd160);
+ // digestOids.put(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256, TeleTrusTObjectIdentifiers.ripemd256);
+ //
+ // digestOids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94, CryptoProObjectIdentifiers.gostR3411);
+ // digestOids.put(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001, CryptoProObjectIdentifiers.gostR3411);
+ //
+ // digestOids.put(BCObjectIdentifiers.sphincs256_with_SHA3_512, NISTObjectIdentifiers.id_sha3_512);
+ // digestOids.put(BCObjectIdentifiers.sphincs256_with_SHA512, NISTObjectIdentifiers.id_sha512);
// END android-removed
+
digestNameToOids.put("SHA-1", OIWObjectIdentifiers.idSHA1);
digestNameToOids.put("SHA-224", NISTObjectIdentifiers.id_sha224);
digestNameToOids.put("SHA-256", NISTObjectIdentifiers.id_sha256);
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
index f6a54821..77f358a0 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/DefaultSignatureAlgorithmIdentifierFinder.java
@@ -10,6 +10,7 @@ import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERNull;
// BEGIN android-removed
+// import org.bouncycastle.asn1.bc.BCObjectIdentifiers;
// import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
// import org.bouncycastle.asn1.eac.EACObjectIdentifiers;
@@ -84,6 +85,7 @@ public class DefaultSignatureAlgorithmIdentifierFinder
algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256);
algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384);
algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512);
+
// BEGIN android-removed
// algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
// algorithms.put("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
@@ -101,7 +103,10 @@ public class DefaultSignatureAlgorithmIdentifierFinder
// algorithms.put("SHA256WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_256);
// algorithms.put("SHA384WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_384);
// algorithms.put("SHA512WITHCVC-ECDSA", EACObjectIdentifiers.id_TA_ECDSA_SHA_512);
+ // algorithms.put("SHA3-512WITHSPHINCS256", BCObjectIdentifiers.sphincs256_with_SHA3_512);
+ // algorithms.put("SHA512WITHSPHINCS256", BCObjectIdentifiers.sphincs256_with_SHA512);
// END android-removed
+
//
// According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field.
// The parameters field SHALL be NULL for RSA based signature algorithms.
@@ -125,6 +130,14 @@ public class DefaultSignatureAlgorithmIdentifierFinder
// noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
// END android-removed
+ // BEGIN android-removed
+ //
+ // SPHINCS-256
+ //
+ // noParams.add(BCObjectIdentifiers.sphincs256_with_SHA512);
+ // noParams.add(BCObjectIdentifiers.sphincs256_with_SHA3_512);
+ // END android-removed
+
//
// PKCS 1.5 encrypted algorithms
//
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java
index 805dc479..74c0aa29 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/bc/BcDefaultDigestProvider.java
@@ -28,6 +28,9 @@ import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.digests.SHA224Digest;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.digests.SHA384Digest;
+// BEGIN android-removed
+// import org.bouncycastle.crypto.digests.SHA3Digest;
+// END android-removed
import org.bouncycastle.crypto.digests.SHA512Digest;
import org.bouncycastle.operator.OperatorCreationException;
@@ -75,14 +78,42 @@ public class BcDefaultDigestProvider
return new SHA512Digest();
}
});
- table.put(PKCSObjectIdentifiers.md5, new BcDigestProvider()
- {
- public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
- {
- return new MD5Digest();
- }
- });
// BEGIN android-removed
+ // table.put(NISTObjectIdentifiers.id_sha3_224, new BcDigestProvider()
+ // {
+ // public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ // {
+ // return new SHA3Digest(224);
+ // }
+ // });
+ // table.put(NISTObjectIdentifiers.id_sha3_256, new BcDigestProvider()
+ // {
+ // public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ // {
+ // return new SHA3Digest(256);
+ // }
+ // });
+ // table.put(NISTObjectIdentifiers.id_sha3_384, new BcDigestProvider()
+ // {
+ // public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ // {
+ // return new SHA3Digest(384);
+ // }
+ // });
+ // table.put(NISTObjectIdentifiers.id_sha3_512, new BcDigestProvider()
+ // {
+ // public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ // {
+ // return new SHA3Digest(512);
+ // }
+ // });
+ // table.put(PKCSObjectIdentifiers.md5, new BcDigestProvider()
+ // {
+ // public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
+ // {
+ // return new MD5Digest();
+ // }
+ // });
// table.put(PKCSObjectIdentifiers.md4, new BcDigestProvider()
// {
// public ExtendedDigest get(AlgorithmIdentifier digestAlgorithmIdentifier)
diff --git a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java
index 31af916f..55831943 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java
@@ -59,6 +59,7 @@ public class JcaContentSignerBuilder
try
{
final Signature sig = helper.createSignature(sigAlgId);
+ final AlgorithmIdentifier signatureAlgId = sigAlgId;
if (random != null)
{
@@ -75,7 +76,7 @@ public class JcaContentSignerBuilder
public AlgorithmIdentifier getAlgorithmIdentifier()
{
- return sigAlgId;
+ return signatureAlgId;
}
public OutputStream getOutputStream()
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 19d46ec9..532d3b51 100644
--- a/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java
+++ b/bcpkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java
@@ -383,7 +383,7 @@ class OperatorHelper
String name = MessageDigestUtils.getDigestName(oid);
int dIndex = name.indexOf('-');
- if (dIndex > 0)
+ if (dIndex > 0 && !name.startsWith("SHA3"))
{
return name.substring(0, dIndex) + name.substring(dIndex + 1);
}
@@ -394,7 +394,6 @@ class OperatorHelper
public X509Certificate convertCertificate(X509CertificateHolder certHolder)
throws CertificateException
{
-
try
{
CertificateFactory certFact = helper.createCertificateFactory("X.509");
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecific.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecific.java
index fca4e01a..c67e42f3 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecific.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ApplicationSpecific.java
@@ -21,7 +21,7 @@ public abstract class ASN1ApplicationSpecific
{
this.isConstructed = isConstructed;
this.tag = tag;
- this.octets = octets;
+ this.octets = Arrays.clone(octets);
}
/**
@@ -93,7 +93,7 @@ public abstract class ASN1ApplicationSpecific
*/
public byte[] getContents()
{
- return octets;
+ return Arrays.clone(octets);
}
/**
@@ -115,7 +115,7 @@ public abstract class ASN1ApplicationSpecific
public ASN1Primitive getObject()
throws IOException
{
- return new ASN1InputStream(getContents()).readObject();
+ return ASN1Primitive.fromByteArray(getContents());
}
/**
@@ -141,7 +141,7 @@ public abstract class ASN1ApplicationSpecific
tmp[0] |= BERTags.CONSTRUCTED;
}
- return new ASN1InputStream(tmp).readObject();
+ return ASN1Primitive.fromByteArray(tmp);
}
int encodedLength()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java
index 195b924f..ca192f31 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java
@@ -99,7 +99,18 @@ public class ASN1Enumerated
public ASN1Enumerated(
byte[] bytes)
{
- this.bytes = bytes;
+ if (bytes.length > 1)
+ {
+ if (bytes[0] == 0 && (bytes[1] & 0x80) == 0)
+ {
+ throw new IllegalArgumentException("malformed enumerated");
+ }
+ if (bytes[0] == (byte)0xff && (bytes[1] & 0x80) != 0)
+ {
+ throw new IllegalArgumentException("malformed enumerated");
+ }
+ }
+ this.bytes = Arrays.clone(bytes);
}
public BigInteger getValue()
@@ -148,7 +159,7 @@ public class ASN1Enumerated
{
if (enc.length > 1)
{
- return new ASN1Enumerated(Arrays.clone(enc));
+ return new ASN1Enumerated(enc);
}
if (enc.length == 0)
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Exception.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Exception.java
index dc0ee203..2696add7 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Exception.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Exception.java
@@ -2,22 +2,41 @@ package org.bouncycastle.asn1;
import java.io.IOException;
+/**
+ * Exception thrown in cases of corrupted or unexpected data in a stream.
+ */
public class ASN1Exception
extends IOException
{
private Throwable cause;
+ /**
+ * Base constructor
+ *
+ * @param message a message concerning the exception.
+ */
ASN1Exception(String message)
{
super(message);
}
+ /**
+ * Constructor when this exception is due to another one.
+ *
+ * @param message a message concerning the exception.
+ * @param cause the exception that caused this exception to be thrown.
+ */
ASN1Exception(String message, Throwable cause)
{
super(message);
this.cause = cause;
}
+ /**
+ * Return the underlying cause of this exception, if any.
+ *
+ * @return the exception causing this one, null if there isn't one.
+ */
public Throwable getCause()
{
return cause;
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Generator.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Generator.java
index 50cb7054..3817d82c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Generator.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Generator.java
@@ -2,14 +2,27 @@ package org.bouncycastle.asn1;
import java.io.OutputStream;
+/**
+ * Basic class for streaming generators.
+ */
public abstract class ASN1Generator
{
protected OutputStream _out;
-
+
+ /**
+ * Base constructor.
+ *
+ * @param out the end output stream that object encodings are written to.
+ */
public ASN1Generator(OutputStream out)
{
_out = out;
}
-
+
+ /**
+ * Return the actual stream object encodings are written to.
+ *
+ * @return the stream that is directly encoded to.
+ */
public abstract OutputStream getRawOutputStream();
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java
index c3c3f9cf..ab6d2020 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1Integer.java
@@ -89,6 +89,17 @@ public class ASN1Integer
ASN1Integer(byte[] bytes, boolean clone)
{
+ if (bytes.length > 1)
+ {
+ if (bytes[0] == 0 && (bytes[1] & 0x80) == 0)
+ {
+ throw new IllegalArgumentException("malformed integer");
+ }
+ if (bytes[0] == (byte)0xff && (bytes[1] & 0x80) != 0)
+ {
+ throw new IllegalArgumentException("malformed integer");
+ }
+ }
this.bytes = (clone) ? Arrays.clone(bytes) : bytes;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
index ac65d96f..50b8a491 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ObjectIdentifier.java
@@ -3,8 +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 java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.bouncycastle.util.Arrays;
@@ -20,9 +20,10 @@ public class ASN1ObjectIdentifier
/**
* return an OID from the passed in object
+ *
* @param obj an ASN1ObjectIdentifier or an object that can be converted into one.
- * @throws IllegalArgumentException if the object cannot be converted.
* @return an ASN1ObjectIdentifier instance, or null.
+ * @throws IllegalArgumentException if the object cannot be converted.
*/
public static ASN1ObjectIdentifier getInstance(
Object obj)
@@ -59,9 +60,9 @@ public class ASN1ObjectIdentifier
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
+ * @return an ASN1ObjectIdentifier instance, or null.
* @throws IllegalArgumentException if the tagged object cannot
* be converted.
- * @return an ASN1ObjectIdentifier instance, or null.
*/
public static ASN1ObjectIdentifier getInstance(
ASN1TaggedObject obj,
@@ -190,12 +191,12 @@ public class ASN1ObjectIdentifier
// END android-changed
}
- /**
- * Create an OID that creates a branch under the current one.
- *
- * @param branchID node numbers for the new branch.
- * @return the OID for the new created branch.
- */
+ /**
+ * Create an OID that creates a branch under the current one.
+ *
+ * @param branchID node numbers for the new branch.
+ * @return the OID for the new created branch.
+ */
ASN1ObjectIdentifier(ASN1ObjectIdentifier oid, String branchID)
{
if (!isValidBranchID(branchID, 0))
@@ -428,32 +429,29 @@ public class ASN1ObjectIdentifier
* 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()
{
- synchronized (pool)
+ final OidHandle hdl = new OidHandle(getBody());
+ ASN1ObjectIdentifier oid = pool.get(hdl);
+ if (oid == null)
{
- OidHandle hdl = new OidHandle(getBody());
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)pool.get(hdl);
-
- if (oid != null)
- {
- return oid;
- }
- else
+ oid = pool.putIfAbsent(hdl, this);
+ if (oid == null)
{
- pool.put(hdl, this);
- return this;
+ oid = this;
}
}
+ return oid;
}
- private static final Map pool = new HashMap();
+ private static final ConcurrentMap<OidHandle, ASN1ObjectIdentifier> pool = new ConcurrentHashMap<OidHandle, ASN1ObjectIdentifier>();
private static class OidHandle
{
- private int key;
+ private final int key;
private final byte[] enc;
OidHandle(byte[] enc)
@@ -480,17 +478,12 @@ public class ASN1ObjectIdentifier
static ASN1ObjectIdentifier fromOctetString(byte[] enc)
{
- OidHandle hdl = new OidHandle(enc);
-
- synchronized (pool)
+ final OidHandle hdl = new OidHandle(enc);
+ ASN1ObjectIdentifier oid = pool.get(hdl);
+ if (oid == null)
{
- ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)pool.get(hdl);
- if (oid != null)
- {
- return oid;
- }
+ return new ASN1ObjectIdentifier(enc);
}
-
- return new ASN1ObjectIdentifier(enc);
+ return oid;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java
index a3fa4a41..07811d71 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1OctetString.java
@@ -5,6 +5,7 @@ import java.io.IOException;
import java.io.InputStream;
import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
/**
@@ -248,6 +249,6 @@ public abstract class ASN1OctetString
public String toString()
{
- return "#"+new String(Hex.encode(string));
+ return "#"+ Strings.fromByteArray(Hex.encode(string));
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ParsingException.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ParsingException.java
index 995b5e93..509c213c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ParsingException.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1ParsingException.java
@@ -1,21 +1,40 @@
package org.bouncycastle.asn1;
+/**
+ * Exception thrown when correctly encoded, but unexpected data is found in a stream while building an object.
+ */
public class ASN1ParsingException
extends IllegalStateException
{
private Throwable cause;
+ /**
+ * Base constructor
+ *
+ * @param message a message concerning the exception.
+ */
public ASN1ParsingException(String message)
{
super(message);
}
+ /**
+ * Constructor when this exception is due to another one.
+ *
+ * @param message a message concerning the exception.
+ * @param cause the exception that caused this exception to be thrown.
+ */
public ASN1ParsingException(String message, Throwable cause)
{
super(message);
this.cause = cause;
}
+ /**
+ * Return the underlying cause of this exception, if any.
+ *
+ * @return the exception causing this one, null if there isn't one.
+ */
public Throwable getCause()
{
return cause;
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java
index 778bea74..808f478e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ASN1TaggedObject.java
@@ -143,6 +143,11 @@ public abstract class ASN1TaggedObject
return code;
}
+ /**
+ * Return the tag number associated with this object.
+ *
+ * @return the tag number.
+ */
public int getTagNo()
{
return tagNo;
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringGenerator.java b/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringGenerator.java
index b8df94af..55e695c7 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringGenerator.java
@@ -3,9 +3,19 @@ package org.bouncycastle.asn1;
import java.io.IOException;
import java.io.OutputStream;
+/**
+ * A generator for indefinite-length OCTET STRINGs
+ */
public class BEROctetStringGenerator
extends BERGenerator
{
+ /**
+ * Use the passed in stream as the target for the generator, writing out the header tag
+ * for a constructed OCTET STRING.
+ *
+ * @param out target stream
+ * @throws IOException if the target stream cannot be written to.
+ */
public BEROctetStringGenerator(OutputStream out)
throws IOException
{
@@ -14,6 +24,15 @@ public class BEROctetStringGenerator
writeBERHeader(BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
}
+ /**
+ * Use the passed in stream as the target for the generator, writing out the header tag
+ * for a tagged constructed OCTET STRING (possibly implicit).
+ *
+ * @param out target stream
+ * @param tagNo the tag number to introduce
+ * @param isExplicit true if this is an explicitly tagged object, false otherwise.
+ * @throws IOException if the target stream cannot be written to.
+ */
public BEROctetStringGenerator(
OutputStream out,
int tagNo,
@@ -24,12 +43,23 @@ public class BEROctetStringGenerator
writeBERHeader(BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
}
-
+
+ /**
+ * Return a stream representing the content target for this OCTET STRING
+ *
+ * @return an OutputStream which chunks data in blocks of 1000 (CER limit).
+ */
public OutputStream getOctetOutputStream()
{
return getOctetOutputStream(new byte[1000]); // limit for CER encoding.
}
+ /**
+ * Return a stream representing the content target for this OCTET STRING
+ *
+ * @param buf the buffer to use for chunking the data.
+ * @return an OutputStream which chunks data in blocks of buf length.
+ */
public OutputStream getOctetOutputStream(
byte[] buf)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringParser.java
index 1c7132e5..77a3049d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BEROctetStringParser.java
@@ -5,6 +5,9 @@ import java.io.InputStream;
import org.bouncycastle.util.io.Streams;
+/**
+ * A parser for indefinite-length OCTET STRINGs.
+ */
public class BEROctetStringParser
implements ASN1OctetStringParser
{
@@ -16,17 +19,33 @@ public class BEROctetStringParser
_parser = parser;
}
+ /**
+ * Return an InputStream representing the contents of the OCTET STRING.
+ *
+ * @return an InputStream with its source as the OCTET STRING content.
+ */
public InputStream getOctetStream()
{
return new ConstructedOctetStream(_parser);
}
+ /**
+ * Return an in-memory, encodable, representation of the OCTET STRING.
+ *
+ * @return a BEROctetString.
+ * @throws IOException if there is an issue loading the data.
+ */
public ASN1Primitive getLoadedObject()
throws IOException
{
return new BEROctetString(Streams.readAll(getOctetStream()));
}
+ /**
+ * Return an BEROctetString representing this parser and its contents.
+ *
+ * @return an BEROctetString
+ */
public ASN1Primitive toASN1Primitive()
{
try
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BEROutputStream.java b/bcprov/src/main/java/org/bouncycastle/asn1/BEROutputStream.java
index 7117d4fb..f6459b2e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BEROutputStream.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BEROutputStream.java
@@ -3,15 +3,29 @@ package org.bouncycastle.asn1;
import java.io.IOException;
import java.io.OutputStream;
+/**
+ * A class which writes indefinite and definite length objects,
+ */
public class BEROutputStream
extends DEROutputStream
{
+ /**
+ * Base constructor.
+ *
+ * @param os target output stream.
+ */
public BEROutputStream(
OutputStream os)
{
super(os);
}
+ /**
+ * Write out an ASN.1 object.
+ *
+ * @param obj the object to be encoded.
+ * @throws IOException if there is an issue on encoding or output of the object.
+ */
public void writeObject(
Object obj)
throws IOException
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java b/bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java
index 1af0a433..37599fbe 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/BERTaggedObject.java
@@ -127,7 +127,7 @@ public class BERTaggedObject
}
else
{
- throw new RuntimeException("not implemented: " + obj.getClass().getName());
+ throw new ASN1Exception("not implemented: " + obj.getClass().getName());
}
while (e.hasMoreElements())
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java
index d74bc00e..c789d7cd 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERBitString.java
@@ -26,6 +26,17 @@ public class DERBitString
{
return new DERBitString(((DLBitString)obj).data, ((DLBitString)obj).padBits);
}
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (DERBitString)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
+ }
+ }
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERSequenceParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERSequenceParser.java
index 376c1fd8..5503feb8 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERSequenceParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERSequenceParser.java
@@ -2,6 +2,9 @@ package org.bouncycastle.asn1;
import java.io.IOException;
+/**
+ * Parser class for DER SEQUENCEs.
+ */
public class DERSequenceParser
implements ASN1SequenceParser
{
@@ -12,18 +15,35 @@ public class DERSequenceParser
this._parser = parser;
}
+ /**
+ * Return the next object in the SEQUENCE.
+ *
+ * @return next object in SEQUENCE.
+ * @throws IOException if there is an issue loading the object.
+ */
public ASN1Encodable readObject()
throws IOException
{
return _parser.readObject();
}
+ /**
+ * Return an in memory, encodable, representation of the SEQUENCE.
+ *
+ * @return a DERSequence.
+ * @throws IOException if there is an issue loading the data.
+ */
public ASN1Primitive getLoadedObject()
throws IOException
{
return new DERSequence(_parser.readVector());
}
+ /**
+ * Return a DERSequence representing this parser and its contents.
+ *
+ * @return a DERSequence.
+ */
public ASN1Primitive toASN1Primitive()
{
try
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERSet.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERSet.java
index ac58eacf..1a72a0b1 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERSet.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERSet.java
@@ -4,7 +4,7 @@ import java.io.IOException;
import java.util.Enumeration;
/**
- * A DER encoded set object
+ * A DER encoded SET object
*/
public class DERSet
extends ASN1Set
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERSetParser.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERSetParser.java
index 17702fa4..d16cb157 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERSetParser.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERSetParser.java
@@ -2,6 +2,9 @@ package org.bouncycastle.asn1;
import java.io.IOException;
+/**
+ * Parser class for DER SETs.
+ */
public class DERSetParser
implements ASN1SetParser
{
@@ -12,18 +15,35 @@ public class DERSetParser
this._parser = parser;
}
+ /**
+ * Return the next object in the SET.
+ *
+ * @return next object in SET.
+ * @throws IOException if there is an issue loading the object.
+ */
public ASN1Encodable readObject()
throws IOException
{
return _parser.readObject();
}
+ /**
+ * Return an in memory, encodable, representation of the SET.
+ *
+ * @return a DERSet.
+ * @throws IOException if there is an issue loading the data.
+ */
public ASN1Primitive getLoadedObject()
throws IOException
{
return new DERSet(_parser.readVector(), false);
}
+ /**
+ * Return a DERSet representing this parser and its contents.
+ *
+ * @return a DERSet
+ */
public ASN1Primitive toASN1Primitive()
{
try
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERT61String.java
index 30744c69..c5c29137 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 final byte[] string;
+ private byte[] string;
/**
* return a T61 string from the passed in object.
@@ -79,7 +79,7 @@ public class DERT61String
public DERT61String(
byte[] string)
{
- this.string = string;
+ this.string = Arrays.clone(string);
}
/**
@@ -90,7 +90,7 @@ public class DERT61String
public DERT61String(
String string)
{
- this(Strings.toByteArray(string));
+ this.string = Strings.toByteArray(string);
}
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java
index 85390990..6b70faab 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DERUniversalString.java
@@ -79,7 +79,7 @@ public class DERUniversalString
public DERUniversalString(
byte[] string)
{
- this.string = string;
+ this.string = Arrays.clone(string);
}
public String getString()
@@ -94,7 +94,7 @@ public class DERUniversalString
}
catch (IOException e)
{
- throw new RuntimeException("internal error encoding BitString");
+ throw new ASN1ParsingException("internal error encoding BitString");
}
byte[] string = bOut.toByteArray();
@@ -115,7 +115,7 @@ public class DERUniversalString
public byte[] getOctets()
{
- return string;
+ return Arrays.clone(string);
}
boolean isConstructed()
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/DLBitString.java b/bcprov/src/main/java/org/bouncycastle/asn1/DLBitString.java
index c81f0ab9..f6cb49bd 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/DLBitString.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/DLBitString.java
@@ -26,6 +26,17 @@ public class DLBitString
{
return (DERBitString)obj;
}
+ if (obj instanceof byte[])
+ {
+ try
+ {
+ return (ASN1BitString)fromByteArray((byte[])obj);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
+ }
+ }
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
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 5b95b79e..a4f3f3b2 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/bc/BCObjectIdentifiers.java
@@ -66,4 +66,29 @@ public interface BCObjectIdentifiers
public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes192_cbc = bc_pbe_sha256_pkcs12.branch("1.22");
/** 1.3.6.1.4.1.22554.1.1.2.2.42 */
public static final ASN1ObjectIdentifier bc_pbe_sha256_pkcs12_aes256_cbc = bc_pbe_sha256_pkcs12.branch("1.42");
+
+ /**
+ * signature(2) algorithms
+ */
+ public static final ASN1ObjectIdentifier bc_sig = bc.branch("2");
+
+ // BEGIN android-removed
+ // /**
+ // * Sphincs-256
+ // */
+ // public static final ASN1ObjectIdentifier sphincs256 = bc_sig.branch("1");
+ // public static final ASN1ObjectIdentifier sphincs256_with_BLAKE512 = sphincs256.branch("1");
+ // public static final ASN1ObjectIdentifier sphincs256_with_SHA512 = sphincs256.branch("2");
+ // public static final ASN1ObjectIdentifier sphincs256_with_SHA3_512 = sphincs256.branch("3");
+
+ // /**
+ // * key_exchange(3) algorithms
+ // */
+ // public static final ASN1ObjectIdentifier bc_exch = bc.branch("3");
+
+ // /**
+ // * NewHope
+ // */
+ // public static final ASN1ObjectIdentifier newHope = bc_exch.branch("1");
+ // END android-removed
}
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 19077e4c..ba7e5187 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTNamedCurves.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTNamedCurves.java
@@ -17,38 +17,42 @@ public class NISTNamedCurves
static final Hashtable objIds = new Hashtable();
static final Hashtable names = new Hashtable();
- static void defineCurveAlias(String name, ASN1ObjectIdentifier oid)
+ static void defineCurve(String name, ASN1ObjectIdentifier oid)
{
- objIds.put(name.toUpperCase(), oid);
+ objIds.put(name, oid);
names.put(oid, name);
}
static
{
- 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);
+ defineCurve("B-571", SECObjectIdentifiers.sect571r1);
+ defineCurve("B-409", SECObjectIdentifiers.sect409r1);
+ defineCurve("B-283", SECObjectIdentifiers.sect283r1);
+ defineCurve("B-233", SECObjectIdentifiers.sect233r1);
+ defineCurve("B-163", SECObjectIdentifiers.sect163r2);
+ defineCurve("K-571", SECObjectIdentifiers.sect571k1);
+ defineCurve("K-409", SECObjectIdentifiers.sect409k1);
+ defineCurve("K-283", SECObjectIdentifiers.sect283k1);
+ defineCurve("K-233", SECObjectIdentifiers.sect233k1);
+ defineCurve("K-163", SECObjectIdentifiers.sect163k1);
+ defineCurve("P-521", SECObjectIdentifiers.secp521r1);
+ defineCurve("P-384", SECObjectIdentifiers.secp384r1);
+ defineCurve("P-256", SECObjectIdentifiers.secp256r1);
+ defineCurve("P-224", SECObjectIdentifiers.secp224r1);
+ defineCurve("P-192", SECObjectIdentifiers.secp192r1);
}
public static X9ECParameters getByName(
String name)
{
- ASN1ObjectIdentifier oid = getOID(name);
- return oid == null ? null : getByOID(oid);
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)objIds.get(Strings.toUpperCase(name));
+
+ if (oid != null)
+ {
+ return getByOID(oid);
+ }
+
+ return null;
}
/**
@@ -90,6 +94,6 @@ public class NISTNamedCurves
*/
public static Enumeration getNames()
{
- return names.elements();
+ return objIds.keys();
}
}
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 0de40f20..49c0e6d7 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/nist/NISTObjectIdentifiers.java
@@ -40,9 +40,17 @@ public interface NISTObjectIdentifiers
/** 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");
+ 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");
+ static final ASN1ObjectIdentifier id_shake256 = hashAlgs.branch("12");
+ /** 2.16.840.1.101.3.4.2.13 */
+ static final ASN1ObjectIdentifier id_hmacWithSHA3_224 = hashAlgs.branch("13");
+ /** 2.16.840.1.101.3.4.2.14 */
+ static final ASN1ObjectIdentifier id_hmacWithSHA3_256 = hashAlgs.branch("14");
+ /** 2.16.840.1.101.3.4.2.15 */
+ static final ASN1ObjectIdentifier id_hmacWithSHA3_384 = hashAlgs.branch("15");
+ /** 2.16.840.1.101.3.4.2.16 */
+ static final ASN1ObjectIdentifier id_hmacWithSHA3_512 = hashAlgs.branch("16");
/** 2.16.840.1.101.3.4.1 */
static final ASN1ObjectIdentifier aes = nistAlgorithm.branch("1");
@@ -61,7 +69,9 @@ public interface NISTObjectIdentifiers
static final ASN1ObjectIdentifier id_aes128_GCM = aes.branch("6");
/** 2.16.840.1.101.3.4.1.7 */
static final ASN1ObjectIdentifier id_aes128_CCM = aes.branch("7");
-
+ /** 2.16.840.1.101.3.4.1.28 */
+ static final ASN1ObjectIdentifier id_aes128_wrap_pad = aes.branch("8");
+
/** 2.16.840.1.101.3.4.1.21 */
static final ASN1ObjectIdentifier id_aes192_ECB = aes.branch("21");
/** 2.16.840.1.101.3.4.1.22 */
@@ -76,7 +86,9 @@ public interface NISTObjectIdentifiers
static final ASN1ObjectIdentifier id_aes192_GCM = aes.branch("26");
/** 2.16.840.1.101.3.4.1.27 */
static final ASN1ObjectIdentifier id_aes192_CCM = aes.branch("27");
-
+ /** 2.16.840.1.101.3.4.1.28 */
+ static final ASN1ObjectIdentifier id_aes192_wrap_pad = aes.branch("28");
+
/** 2.16.840.1.101.3.4.1.41 */
static final ASN1ObjectIdentifier id_aes256_ECB = aes.branch("41");
/** 2.16.840.1.101.3.4.1.42 */
@@ -91,19 +103,51 @@ public interface NISTObjectIdentifiers
static final ASN1ObjectIdentifier id_aes256_GCM = aes.branch("46");
/** 2.16.840.1.101.3.4.1.47 */
static final ASN1ObjectIdentifier id_aes256_CCM = aes.branch("47");
+ /** 2.16.840.1.101.3.4.1.48 */
+ static final ASN1ObjectIdentifier id_aes256_wrap_pad = aes.branch("48");
//
// signatures
//
/** 2.16.840.1.101.3.4.3 */
- static final ASN1ObjectIdentifier id_dsa_with_sha2 = nistAlgorithm.branch("3");
+ static final ASN1ObjectIdentifier sigAlgs = nistAlgorithm.branch("3");
+
+ static final ASN1ObjectIdentifier id_dsa_with_sha2 = sigAlgs;
/** 2.16.840.1.101.3.4.3.1 */
- static final ASN1ObjectIdentifier dsa_with_sha224 = id_dsa_with_sha2.branch("1");
+ static final ASN1ObjectIdentifier dsa_with_sha224 = sigAlgs.branch("1");
/** 2.16.840.1.101.3.4.3.2 */
- static final ASN1ObjectIdentifier dsa_with_sha256 = id_dsa_with_sha2.branch("2");
+ static final ASN1ObjectIdentifier dsa_with_sha256 = sigAlgs.branch("2");
/** 2.16.840.1.101.3.4.3.3 */
- static final ASN1ObjectIdentifier dsa_with_sha384 = id_dsa_with_sha2.branch("3");
+ static final ASN1ObjectIdentifier dsa_with_sha384 = sigAlgs.branch("3");
/** 2.16.840.1.101.3.4.3.4 */
- static final ASN1ObjectIdentifier dsa_with_sha512 = id_dsa_with_sha2.branch("4");
+ static final ASN1ObjectIdentifier dsa_with_sha512 = sigAlgs.branch("4");
+ /** 2.16.840.1.101.3.4.3.5 */
+ static final ASN1ObjectIdentifier id_dsa_with_sha3_224 = sigAlgs.branch("5");
+ /** 2.16.840.1.101.3.4.3.6 */
+ static final ASN1ObjectIdentifier id_dsa_with_sha3_256 = sigAlgs.branch("6");
+ /** 2.16.840.1.101.3.4.3.7 */
+ static final ASN1ObjectIdentifier id_dsa_with_sha3_384 = sigAlgs.branch("7");
+ /** 2.16.840.1.101.3.4.3.8 */
+ static final ASN1ObjectIdentifier id_dsa_with_sha3_512 = sigAlgs.branch("8");
+
+ // ECDSA with SHA-3
+ /** 2.16.840.1.101.3.4.3.9 */
+ static final ASN1ObjectIdentifier id_ecdsa_with_sha3_224 = sigAlgs.branch("9");
+ /** 2.16.840.1.101.3.4.3.10 */
+ static final ASN1ObjectIdentifier id_ecdsa_with_sha3_256 = sigAlgs.branch("10");
+ /** 2.16.840.1.101.3.4.3.11 */
+ static final ASN1ObjectIdentifier id_ecdsa_with_sha3_384 = sigAlgs.branch("11");
+ /** 2.16.840.1.101.3.4.3.12 */
+ static final ASN1ObjectIdentifier id_ecdsa_with_sha3_512 = sigAlgs.branch("12");
+
+ // RSA PKCS #1 v1.5 Signature with SHA-3 family.
+ /** 2.16.840.1.101.3.4.3.9 */
+ static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_224 = sigAlgs.branch("13");
+ /** 2.16.840.1.101.3.4.3.10 */
+ static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_256 = sigAlgs.branch("14");
+ /** 2.16.840.1.101.3.4.3.11 */
+ static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_384 = sigAlgs.branch("15");
+ /** 2.16.840.1.101.3.4.3.12 */
+ static final ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_512 = sigAlgs.branch("16");
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CertStatus.java b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CertStatus.java
index af530ae5..0b1db325 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CertStatus.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/ocsp/CertStatus.java
@@ -13,7 +13,7 @@ public class CertStatus
implements ASN1Choice
{
private int tagNo;
- private ASN1Encodable value;
+ private ASN1Encodable value;
/**
* create a CertStatus object with a tag of zero.
@@ -39,7 +39,7 @@ public class CertStatus
this.value = value;
}
- public CertStatus(
+ private CertStatus(
ASN1TaggedObject choice)
{
this.tagNo = choice.getTagNo();
@@ -54,6 +54,9 @@ public class CertStatus
break;
case 2:
value = DERNull.INSTANCE;
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown tag encountered: " + choice.getTagNo());
}
}
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 747277c3..49b2652c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CRLBag.java
@@ -6,6 +6,7 @@ import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
@@ -22,7 +23,7 @@ public class CRLBag
ASN1Sequence seq)
{
this.crlId = (ASN1ObjectIdentifier)seq.getObjectAt(0);
- this.crlValue = ((DERTaggedObject)seq.getObjectAt(1)).getObject();
+ this.crlValue = ((ASN1TaggedObject)seq.getObjectAt(1)).getObject();
}
public static CRLBag getInstance(Object o)
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
index fb418aeb..dca0719c 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/CertificationRequestInfo.java
@@ -6,6 +6,7 @@ import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1Set;
+import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.x500.X500Name;
@@ -116,7 +117,7 @@ public class CertificationRequestInfo
//
if (seq.size() > 3)
{
- DERTaggedObject tagobj = (DERTaggedObject)seq.getObjectAt(3);
+ ASN1TaggedObject tagobj = (ASN1TaggedObject)seq.getObjectAt(3);
attributes = ASN1Set.getInstance(tagobj, false);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/MacData.java b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/MacData.java
index 1d8f582c..63fa2e4e 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/MacData.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/MacData.java
@@ -11,6 +11,7 @@ import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x509.DigestInfo;
+import org.bouncycastle.util.Arrays;
public class MacData
extends ASN1Object
@@ -41,7 +42,7 @@ public class MacData
{
this.digInfo = DigestInfo.getInstance(seq.getObjectAt(0));
- this.salt = ((ASN1OctetString)seq.getObjectAt(1)).getOctets();
+ this.salt = Arrays.clone(((ASN1OctetString)seq.getObjectAt(1)).getOctets());
if (seq.size() == 3)
{
@@ -59,7 +60,7 @@ public class MacData
int iterationCount)
{
this.digInfo = digInfo;
- this.salt = salt;
+ this.salt = Arrays.clone(salt);
this.iterationCount = BigInteger.valueOf(iterationCount);
}
@@ -70,7 +71,7 @@ public class MacData
public byte[] getSalt()
{
- return salt;
+ return Arrays.clone(salt);
}
public BigInteger getIterationCount()
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 5dbddc3c..6e50f552 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers.java
@@ -41,6 +41,10 @@ public interface PKCSObjectIdentifiers
static final ASN1ObjectIdentifier sha512WithRSAEncryption = pkcs_1.branch("13");
/** PKCS#1: 1.2.840.113549.1.1.14 */
static final ASN1ObjectIdentifier sha224WithRSAEncryption = pkcs_1.branch("14");
+ /** PKCS#1: 1.2.840.113549.1.1.15 */
+ ASN1ObjectIdentifier sha512_224WithRSAEncryption = pkcs_1.branch("15");
+ /** PKCS#1: 1.2.840.113549.1.1.16 */
+ ASN1ObjectIdentifier sha512_256WithRSAEncryption = pkcs_1.branch("16");
//
// pkcs-3 OBJECT IDENTIFIER ::= {
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 1cdaf129..1d2c78cb 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/sec/SECNamedCurves.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/sec/SECNamedCurves.java
@@ -987,7 +987,7 @@ public class SECNamedCurves
static void defineCurve(String name, ASN1ObjectIdentifier oid, X9ECParametersHolder holder)
{
- objIds.put(name.toLowerCase(), oid);
+ objIds.put(name, oid);
names.put(oid, name);
curves.put(oid, holder);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/teletrust/TeleTrusTObjectIdentifiers.java b/bcprov/src/main/java/org/bouncycastle/asn1/teletrust/TeleTrusTObjectIdentifiers.java
index 2be7efec..c38eac74 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/teletrust/TeleTrusTObjectIdentifiers.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/teletrust/TeleTrusTObjectIdentifiers.java
@@ -3,9 +3,11 @@ package org.bouncycastle.asn1.teletrust;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
/**
+ * Object identifiers based on the TeleTrust branch.
+ * <pre>
* TeleTrusT:
* { iso(1) identifier-organization(3) teleTrust(36) algorithm(3)
- *
+ * </pre>
*/
public interface TeleTrusTObjectIdentifiers
{
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 1330d256..59c961f2 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/util/ASN1Dump.java
@@ -38,6 +38,9 @@ import org.bouncycastle.asn1.DERVisibleString;
import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
+/**
+ * Utility class for dumping ASN.1 objects as (hopefully) human friendly strings.
+ */
public class ASN1Dump
{
private static final String TAB = " ";
@@ -319,7 +322,7 @@ public class ASN1Dump
return buf.toString();
}
- return indent + type + " ApplicationSpecific[" + app.getApplicationTag() + "] (" + new String(Hex.encode(app.getContents())) + ")" + nl;
+ return indent + type + " ApplicationSpecific[" + app.getApplicationTag() + "] (" + Strings.fromByteArray(Hex.encode(app.getContents())) + ")" + nl;
}
/**
@@ -376,7 +379,7 @@ public class ASN1Dump
if (bytes.length - i > SAMPLE_SIZE)
{
buf.append(indent);
- buf.append(new String(Hex.encode(bytes, i, SAMPLE_SIZE)));
+ buf.append(Strings.fromByteArray(Hex.encode(bytes, i, SAMPLE_SIZE)));
buf.append(TAB);
buf.append(calculateAscString(bytes, i, SAMPLE_SIZE));
buf.append(nl);
@@ -384,7 +387,7 @@ public class ASN1Dump
else
{
buf.append(indent);
- buf.append(new String(Hex.encode(bytes, i, bytes.length - i)));
+ buf.append(Strings.fromByteArray(Hex.encode(bytes, i, bytes.length - i)));
for (int j = bytes.length - i; j != SAMPLE_SIZE; j++)
{
buf.append(" ");
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 34b43856..2ef24d36 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
@@ -78,59 +78,50 @@ public class BCStyle
/**
* businessCategory - DirectoryString(SIZE(1..128)
*/
- public static final ASN1ObjectIdentifier BUSINESS_CATEGORY = new ASN1ObjectIdentifier(
- "2.5.4.15").intern();
+ public static final ASN1ObjectIdentifier BUSINESS_CATEGORY = new ASN1ObjectIdentifier("2.5.4.15").intern();
/**
* postalCode - DirectoryString(SIZE(1..40)
*/
- public static final ASN1ObjectIdentifier POSTAL_CODE = new ASN1ObjectIdentifier(
- "2.5.4.17").intern();
+ public static final ASN1ObjectIdentifier POSTAL_CODE = new ASN1ObjectIdentifier("2.5.4.17").intern();
/**
* dnQualifier - DirectoryString(SIZE(1..64)
*/
- public static final ASN1ObjectIdentifier DN_QUALIFIER = new ASN1ObjectIdentifier(
- "2.5.4.46").intern();
+ public static final ASN1ObjectIdentifier DN_QUALIFIER = new ASN1ObjectIdentifier("2.5.4.46").intern();
/**
* RFC 3039 Pseudonym - DirectoryString(SIZE(1..64)
*/
- public static final ASN1ObjectIdentifier PSEUDONYM = new ASN1ObjectIdentifier(
- "2.5.4.65").intern();
+ public static final ASN1ObjectIdentifier PSEUDONYM = new ASN1ObjectIdentifier("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").intern();
+ public static final ASN1ObjectIdentifier DATE_OF_BIRTH = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.9.1").intern();
/**
* RFC 3039 PlaceOfBirth - DirectoryString(SIZE(1..128)
*/
- public static final ASN1ObjectIdentifier PLACE_OF_BIRTH = new ASN1ObjectIdentifier(
- "1.3.6.1.5.5.7.9.2").intern();
+ public static final ASN1ObjectIdentifier PLACE_OF_BIRTH = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.9.2").intern();
/**
* RFC 3039 Gender - PrintableString (SIZE(1)) -- "M", "F", "m" or "f"
*/
- public static final ASN1ObjectIdentifier GENDER = new ASN1ObjectIdentifier(
- "1.3.6.1.5.5.7.9.3").intern();
+ public static final ASN1ObjectIdentifier GENDER = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.9.3").intern();
/**
* RFC 3039 CountryOfCitizenship - PrintableString (SIZE (2)) -- ISO 3166
* codes only
*/
- public static final ASN1ObjectIdentifier COUNTRY_OF_CITIZENSHIP = new ASN1ObjectIdentifier(
- "1.3.6.1.5.5.7.9.4").intern();
+ public static final ASN1ObjectIdentifier COUNTRY_OF_CITIZENSHIP = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.9.4").intern();
/**
* RFC 3039 CountryOfResidence - PrintableString (SIZE (2)) -- ISO 3166
* codes only
*/
- public static final ASN1ObjectIdentifier COUNTRY_OF_RESIDENCE = new ASN1ObjectIdentifier(
- "1.3.6.1.5.5.7.9.5").intern();
+ public static final ASN1ObjectIdentifier COUNTRY_OF_RESIDENCE = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.9.5").intern();
/**
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 48e5640d..1a4c8dd2 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/DistributionPoint.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/DistributionPoint.java
@@ -66,6 +66,9 @@ public class DistributionPoint
break;
case 2:
cRLIssuer = GeneralNames.getInstance(t, false);
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown tag encountered in structure: " + t.getTagNo());
}
}
}
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 456e3d32..b8c0473a 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extension.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/Extension.java
@@ -174,6 +174,11 @@ public class Extension
*/
public static final ASN1ObjectIdentifier targetInformation = new ASN1ObjectIdentifier("2.5.29.55").intern();
+ /**
+ * Expired Certificates on CRL extension
+ */
+ public static final ASN1ObjectIdentifier expiredCertsOnCRL = new ASN1ObjectIdentifier("2.5.29.60").intern();
+
private ASN1ObjectIdentifier extnId;
private boolean critical;
private ASN1OctetString value;
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraints.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraints.java
index 0a923a85..88cfe3a9 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraints.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/NameConstraints.java
@@ -37,12 +37,14 @@ public class NameConstraints
ASN1TaggedObject o = ASN1TaggedObject.getInstance(e.nextElement());
switch (o.getTagNo())
{
- case 0:
- permitted = createArray(ASN1Sequence.getInstance(o, false));
- break;
- case 1:
- excluded = createArray(ASN1Sequence.getInstance(o, false));
- break;
+ case 0:
+ permitted = createArray(ASN1Sequence.getInstance(o, false));
+ break;
+ case 1:
+ excluded = createArray(ASN1Sequence.getInstance(o, false));
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown tag encountered: " + o.getTagNo());
}
}
}
@@ -62,15 +64,8 @@ public class NameConstraints
GeneralSubtree[] permitted,
GeneralSubtree[] excluded)
{
- if (permitted != null)
- {
- this.permitted = permitted;
- }
-
- if (excluded != null)
- {
- this.excluded = excluded;
- }
+ this.permitted = cloneSubtree(permitted);
+ this.excluded = cloneSubtree(excluded);
}
private GeneralSubtree[] createArray(ASN1Sequence subtree)
@@ -87,12 +82,12 @@ public class NameConstraints
public GeneralSubtree[] getPermittedSubtrees()
{
- return permitted;
+ return cloneSubtree(permitted);
}
public GeneralSubtree[] getExcludedSubtrees()
{
- return excluded;
+ return cloneSubtree(excluded);
}
/*
@@ -115,4 +110,18 @@ public class NameConstraints
return new DERSequence(v);
}
+
+ private static GeneralSubtree[] cloneSubtree(GeneralSubtree[] subtrees)
+ {
+ if (subtrees != null)
+ {
+ GeneralSubtree[] rv = new GeneralSubtree[subtrees.length];
+
+ System.arraycopy(subtrees, 0, rv, 0, rv.length);
+
+ return rv;
+ }
+
+ return null;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java
index 5f0cd079..52e35a15 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/SubjectKeyIdentifier.java
@@ -5,6 +5,7 @@ import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.util.Arrays;
/**
* The SubjectKeyIdentifier object.
@@ -47,22 +48,22 @@ public class SubjectKeyIdentifier
public SubjectKeyIdentifier(
byte[] keyid)
{
- this.keyidentifier = keyid;
+ this.keyidentifier = Arrays.clone(keyid);
}
protected SubjectKeyIdentifier(
ASN1OctetString keyid)
{
- this.keyidentifier = keyid.getOctets();
+ this(keyid.getOctets());
}
public byte[] getKeyIdentifier()
{
- return keyidentifier;
+ return Arrays.clone(keyidentifier);
}
public ASN1Primitive toASN1Primitive()
{
- return new DEROctetString(keyidentifier);
+ return new DEROctetString(getKeyIdentifier());
}
}
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 23f99d0a..c7682f1a 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertList.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertList.java
@@ -199,13 +199,13 @@ public class TBSCertList
}
if (seqPos < seq.size()
- && !(seq.getObjectAt(seqPos) instanceof DERTaggedObject))
+ && !(seq.getObjectAt(seqPos) instanceof ASN1TaggedObject))
{
revokedCertificates = ASN1Sequence.getInstance(seq.getObjectAt(seqPos++));
}
if (seqPos < seq.size()
- && seq.getObjectAt(seqPos) instanceof DERTaggedObject)
+ && seq.getObjectAt(seqPos) instanceof ASN1TaggedObject)
{
crlExtensions = Extensions.getInstance(ASN1Sequence.getInstance((ASN1TaggedObject)seq.getObjectAt(seqPos), true));
}
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java b/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java
index dc419649..f7f60050 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x509/TBSCertificate.java
@@ -77,7 +77,7 @@ public class TBSCertificate
//
// some certficates don't include a version number - we assume v1
//
- if (seq.getObjectAt(0) instanceof DERTaggedObject)
+ if (seq.getObjectAt(0) instanceof ASN1TaggedObject)
{
version = ASN1Integer.getInstance((ASN1TaggedObject)seq.getObjectAt(0), true);
}
@@ -109,7 +109,7 @@ public class TBSCertificate
for (int extras = seq.size() - (seqStart + 6) - 1; extras > 0; extras--)
{
- DERTaggedObject extra = (DERTaggedObject)seq.getObjectAt(seqStart + 6 + extras);
+ ASN1TaggedObject extra = (ASN1TaggedObject)seq.getObjectAt(seqStart + 6 + extras);
switch (extra.getTagNo())
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java
index 34ad746a..855974d2 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/ValidationParams.java
@@ -12,10 +12,13 @@ import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERSequence;
/**
+ * Diffie-Hellman domain validation parameters.
+ * <pre>
* ValidationParams ::= SEQUENCE {
* seed BIT STRING,
* pgenCounter INTEGER
* }
+ * </pre>
*/
public class ValidationParams
extends ASN1Object
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 84574a3a..022c0183 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962NamedCurves.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962NamedCurves.java
@@ -11,7 +11,7 @@ import org.bouncycastle.util.encoders.Hex;
/**
- * table of the current named curves defined in X.962 EC-DSA.
+ * Table of the current named curves defined in X.962 EC-DSA.
*/
public class X962NamedCurves
{
@@ -546,7 +546,7 @@ public class X962NamedCurves
static void defineCurve(String name, ASN1ObjectIdentifier oid, X9ECParametersHolder holder)
{
- objIds.put(name.toLowerCase(), oid);
+ objIds.put(name, oid);
names.put(oid, name);
curves.put(oid, holder);
}
@@ -581,8 +581,14 @@ public class X962NamedCurves
public static X9ECParameters getByName(
String name)
{
- ASN1ObjectIdentifier oid = getOID(name);
- return oid == null ? null : getByOID(oid);
+ ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)objIds.get(Strings.toLowerCase(name));
+
+ if (oid != null)
+ {
+ return getByOID(oid);
+ }
+
+ return null;
}
/**
@@ -595,7 +601,13 @@ public class X962NamedCurves
ASN1ObjectIdentifier oid)
{
X9ECParametersHolder holder = (X9ECParametersHolder)curves.get(oid);
- return holder == null ? null : holder.getParameters();
+
+ if (holder != null)
+ {
+ return holder.getParameters();
+ }
+
+ return null;
}
/**
@@ -625,6 +637,6 @@ public class X962NamedCurves
*/
public static Enumeration getNames()
{
- return names.elements();
+ return objIds.keys();
}
}
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 a06aa85f..2f26c66d 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962Parameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X962Parameters.java
@@ -37,7 +37,7 @@ public class X962Parameters
{
return new X962Parameters(ASN1Primitive.fromByteArray((byte[])obj));
}
- catch (IOException e)
+ catch (Exception e)
{
throw new IllegalArgumentException("unable to parse encoded data: " + e.getMessage());
}
@@ -107,6 +107,6 @@ public class X962Parameters
*/
public ASN1Primitive toASN1Primitive()
{
- return (ASN1Primitive)params;
+ return params;
}
}
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 57b0fda4..95fdc672 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECPoint.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9ECPoint.java
@@ -53,7 +53,7 @@ public class X9ECPoint
return Arrays.clone(encoding.getOctets());
}
- public ECPoint getPoint()
+ public synchronized ECPoint getPoint()
{
if (p == null)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9IntegerConverter.java b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9IntegerConverter.java
index 16a803cc..2851bcae 100644
--- a/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9IntegerConverter.java
+++ b/bcprov/src/main/java/org/bouncycastle/asn1/x9/X9IntegerConverter.java
@@ -5,20 +5,43 @@ import java.math.BigInteger;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECFieldElement;
+/**
+ * A class which converts integers to byte arrays, allowing padding and calculations
+ * to be done according the the filed size of the curve or field element involved.
+ */
public class X9IntegerConverter
{
+ /**
+ * Return the curve's field size in bytes.
+ *
+ * @param c the curve of interest.
+ * @return the field size in bytes (rounded up).
+ */
public int getByteLength(
ECCurve c)
{
return (c.getFieldSize() + 7) / 8;
}
+ /**
+ * Return the field element's field size in bytes.
+ *
+ * @param fe the field element of interest.
+ * @return the field size in bytes (rounded up).
+ */
public int getByteLength(
ECFieldElement fe)
{
return (fe.getFieldSize() + 7) / 8;
}
+ /**
+ * Convert an integer to a byte array, ensuring it is exactly qLength long.
+ *
+ * @param s the integer to be converted.
+ * @param qLength the length
+ * @return the resulting byte array.
+ */
public byte[] integerToBytes(
BigInteger s,
int qLength)
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/agreement/DHBasicAgreement.java b/bcprov/src/main/java/org/bouncycastle/crypto/agreement/DHBasicAgreement.java
index d2e2a09f..4dd80d0a 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/agreement/DHBasicAgreement.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/agreement/DHBasicAgreement.java
@@ -20,6 +20,8 @@ import org.bouncycastle.crypto.params.ParametersWithRandom;
public class DHBasicAgreement
implements BasicAgreement
{
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+
private DHPrivateKeyParameters key;
private DHParameters dhParams;
@@ -66,6 +68,12 @@ public class DHBasicAgreement
throw new IllegalArgumentException("Diffie-Hellman public key has wrong parameters.");
}
- return pub.getY().modPow(key.getX(), dhParams.getP());
+ BigInteger result = pub.getY().modPow(key.getX(), dhParams.getP());
+ if (result.compareTo(ONE) == 0)
+ {
+ throw new IllegalStateException("Shared key can't be 1");
+ }
+
+ return result;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java b/bcprov/src/main/java/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java
index 5aa2f2bb..45ff0d36 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/agreement/ECDHBasicAgreement.java
@@ -59,6 +59,11 @@ public class ECDHBasicAgreement
// Explicitly construct a public key using the private key's curve.
ECPoint pubPoint = myCurve.createPoint(peerPoint.getXCoord().toBigInteger(),
peerPoint.getYCoord().toBigInteger());
+ ECPublicKeyParameters pub = (ECPublicKeyParameters)pubKey;
+ if (!pub.getParameters().equals(key.getParameters()))
+ {
+ throw new IllegalStateException("ECDH public key has wrong domain parameters");
+ }
ECPoint P = pubPoint.multiply(key.getD()).normalize();
// END android-changed
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/MD5Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/MD5Digest.java
index ff9cedf0..417c4bad 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/MD5Digest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/MD5Digest.java
@@ -2,12 +2,14 @@ package org.bouncycastle.crypto.digests;
import org.bouncycastle.util.Memoable;
+import org.bouncycastle.util.Pack;
/**
* implementation of MD5 as outlined in "Handbook of Applied Cryptography", pages 346 - 347.
*/
public class MD5Digest
extends GeneralDigest
+ implements EncodableDigest
{
private static final int DIGEST_LENGTH = 16;
@@ -24,6 +26,22 @@ public class MD5Digest
reset();
}
+ public MD5Digest(byte[] encodedState)
+ {
+ super(encodedState);
+
+ H1 = Pack.bigEndianToInt(encodedState, 16);
+ H2 = Pack.bigEndianToInt(encodedState, 20);
+ H3 = Pack.bigEndianToInt(encodedState, 24);
+ H4 = Pack.bigEndianToInt(encodedState, 28);
+
+ xOff = Pack.bigEndianToInt(encodedState, 32);
+ for (int i = 0; i != xOff; i++)
+ {
+ X[i] = Pack.bigEndianToInt(encodedState, 36 + (i * 4));
+ }
+ }
+
/**
* Copy constructor. This will copy the state of the provided
* message digest.
@@ -320,4 +338,24 @@ public class MD5Digest
copyIn(d);
}
+
+ public byte[] getEncodedState()
+ {
+ byte[] state = new byte[36 + xOff * 4];
+
+ super.populateState(state);
+
+ Pack.intToBigEndian(H1, state, 16);
+ Pack.intToBigEndian(H2, state, 20);
+ Pack.intToBigEndian(H3, state, 24);
+ Pack.intToBigEndian(H4, state, 28);
+ Pack.intToBigEndian(xOff, state, 32);
+
+ for (int i = 0; i != xOff; i++)
+ {
+ Pack.intToBigEndian(X[i], state, 36 + (i * 4));
+ }
+
+ return state;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA1Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA1Digest.java
index 450dda46..b81e7c0a 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA1Digest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA1Digest.java
@@ -39,6 +39,11 @@ public class SHA1Digest
copyIn(t);
}
+ /**
+ * State constructor - create a digest initialised with the state of a previous one.
+ *
+ * @param encodedState the encoded state from the originating digest.
+ */
public SHA1Digest(byte[] encodedState)
{
super(encodedState);
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA224Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA224Digest.java
index 4f2b2842..c0fbd456 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA224Digest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA224Digest.java
@@ -63,6 +63,11 @@ public class SHA224Digest
xOff = t.xOff;
}
+ /**
+ * State constructor - create a digest initialised with the state of a previous one.
+ *
+ * @param encodedState the encoded state from the originating digest.
+ */
public SHA224Digest(byte[] encodedState)
{
super(encodedState);
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java
index 600d2343..c6e3d283 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java
@@ -63,6 +63,11 @@ public class SHA256Digest
xOff = t.xOff;
}
+ /**
+ * State constructor - create a digest initialised with the state of a previous one.
+ *
+ * @param encodedState the encoded state from the originating digest.
+ */
public SHA256Digest(byte[] encodedState)
{
super(encodedState);
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA384Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA384Digest.java
index fc9fa1e7..0c814b11 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA384Digest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA384Digest.java
@@ -36,6 +36,11 @@ public class SHA384Digest
super(t);
}
+ /**
+ * State constructor - create a digest initialised with the state of a previous one.
+ *
+ * @param encodedState the encoded state from the originating digest.
+ */
public SHA384Digest(byte[] encodedState)
{
restoreState(encodedState);
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA512Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA512Digest.java
index 644bafad..dea3d88e 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA512Digest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA512Digest.java
@@ -36,6 +36,11 @@ public class SHA512Digest
super(t);
}
+ /**
+ * State constructor - create a digest initialised with the state of a previous one.
+ *
+ * @param encodedState the encoded state from the originating digest.
+ */
public SHA512Digest(byte[] encodedState)
{
restoreState(encodedState);
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java b/bcprov/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java
index 4dbfbffd..b5505f43 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java
@@ -4,12 +4,17 @@ import java.security.SecureRandom;
import org.bouncycastle.crypto.AsymmetricBlockCipher;
import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.InvalidCipherTextException;
// BEGIN android-changed
import org.bouncycastle.crypto.digests.AndroidDigestFactory;
// END android-changed
import org.bouncycastle.crypto.params.ParametersWithRandom;
+// BEGIN android-removed
+// import org.bouncycastle.crypto.util.DigestFactory;
+// END android-remnoved
+import org.bouncycastle.util.Arrays;
/**
* Optimal Asymmetric Encryption Padding (OAEP) - see PKCS 1 V 2.
@@ -28,6 +33,7 @@ public class OAEPEncoding
AsymmetricBlockCipher cipher)
{
// BEGIN android-changed
+ // Was: this(cipher, DigestFactory.createSHA1(), null);
this(cipher, AndroidDigestFactory.getSHA1(), null);
// END android-changed
}
@@ -142,6 +148,11 @@ public class OAEPEncoding
int inLen)
throws InvalidCipherTextException
{
+ if (inLen > getInputBlockSize())
+ {
+ throw new DataLengthException("input data too long");
+ }
+
byte[] block = new byte[getInputBlockSize() + 1 + 2 * defHash.length];
//
@@ -210,28 +221,17 @@ public class OAEPEncoding
throws InvalidCipherTextException
{
byte[] data = engine.processBlock(in, inOff, inLen);
- byte[] block;
+ byte[] block = new byte[engine.getOutputBlockSize()];
//
// as we may have zeros in our leading bytes for the block we produced
// on encryption, we need to make sure our decrypted block comes back
// the same size.
//
- if (data.length < engine.getOutputBlockSize())
- {
- block = new byte[engine.getOutputBlockSize()];
- System.arraycopy(data, 0, block, block.length - data.length, data.length);
- }
- else
- {
- block = data;
- }
+ System.arraycopy(data, 0, block, block.length - data.length, data.length);
- if (block.length < (2 * defHash.length) + 1)
- {
- throw new InvalidCipherTextException("data too short");
- }
+ boolean shortData = (block.length < (2 * defHash.length) + 1);
//
// unmask the seed.
@@ -268,31 +268,29 @@ public class OAEPEncoding
}
}
- if (defHashWrong)
- {
- throw new InvalidCipherTextException("data hash wrong");
- }
-
//
// find the data block
//
- int start;
+ int start = block.length;
- for (start = 2 * defHash.length; start != block.length; start++)
+ for (int index = 2 * defHash.length; index != block.length; index++)
{
- if (block[start] != 0)
+ if (block[index] != 0 & start == block.length)
{
- break;
+ start = index;
}
}
- if (start >= (block.length - 1) || block[start] != 1)
- {
- throw new InvalidCipherTextException("data start wrong " + start);
- }
+ boolean dataStartWrong = (start > (block.length - 1) | block[start] != 1);
start++;
+ if (defHashWrong | shortData | dataStartWrong)
+ {
+ Arrays.fill(block, (byte)0);
+ throw new InvalidCipherTextException("data wrong");
+ }
+
//
// extract the data block
//
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 71ca7f7d..b36ae58c 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/encodings/PKCS1Encoding.java
@@ -9,6 +9,7 @@ import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.ParametersWithRandom;
+import org.bouncycastle.util.Arrays;
/**
* this does your basic PKCS 1 v1.5 padding - whether or not you should be using this
@@ -34,33 +35,35 @@ public class PKCS1Encoding
private static final int HEADER_LENGTH = 10;
- private SecureRandom random;
- private AsymmetricBlockCipher engine;
- private boolean forEncryption;
- private boolean forPrivateKey;
- private boolean useStrictLength;
- private int pLen = -1;
- private byte[] fallback = null;
+ private SecureRandom random;
+ private AsymmetricBlockCipher engine;
+ private boolean forEncryption;
+ private boolean forPrivateKey;
+ private boolean useStrictLength;
+ private int pLen = -1;
+ private byte[] fallback = null;
+ private byte[] blockBuffer;
/**
* Basic constructor.
+ *
* @param cipher
*/
public PKCS1Encoding(
- AsymmetricBlockCipher cipher)
+ AsymmetricBlockCipher cipher)
{
this.engine = cipher;
this.useStrictLength = useStrict();
- }
+ }
/**
* Constructor for decryption with a fixed plaintext length.
- *
+ *
* @param cipher The cipher to use for cryptographic operation.
- * @param pLen Length of the expected plaintext.
+ * @param pLen Length of the expected plaintext.
*/
public PKCS1Encoding(
- AsymmetricBlockCipher cipher,
+ AsymmetricBlockCipher cipher,
int pLen)
{
this.engine = cipher;
@@ -68,27 +71,24 @@ public class PKCS1Encoding
this.pLen = pLen;
}
- /**
- * Constructor for decryption with a fixed plaintext length and a fallback
- * value that is returned, if the padding is incorrect.
- *
- * @param cipher
- * The cipher to use for cryptographic operation.
- * @param fallback
- * The fallback value, we don't do an arraycopy here.
- */
- public PKCS1Encoding(
- AsymmetricBlockCipher cipher,
+ /**
+ * Constructor for decryption with a fixed plaintext length and a fallback
+ * value that is returned, if the padding is incorrect.
+ *
+ * @param cipher The cipher to use for cryptographic operation.
+ * @param fallback The fallback value, we don't do an arraycopy here.
+ */
+ public PKCS1Encoding(
+ AsymmetricBlockCipher cipher,
byte[] fallback)
{
- this.engine = cipher;
- this.useStrictLength = useStrict();
- this.fallback = fallback;
- this.pLen = fallback.length;
+ this.engine = cipher;
+ this.useStrictLength = useStrict();
+ this.fallback = fallback;
+ this.pLen = fallback.length;
}
-
-
+
//
// for J2ME compatibility
//
@@ -124,14 +124,14 @@ public class PKCS1Encoding
}
public void init(
- boolean forEncryption,
- CipherParameters param)
+ boolean forEncryption,
+ CipherParameters param)
{
- AsymmetricKeyParameter kParam;
+ AsymmetricKeyParameter kParam;
if (param instanceof ParametersWithRandom)
{
- ParametersWithRandom rParam = (ParametersWithRandom)param;
+ ParametersWithRandom rParam = (ParametersWithRandom)param;
this.random = rParam.getRandom();
kParam = (AsymmetricKeyParameter)rParam.getParameters();
@@ -149,11 +149,17 @@ public class PKCS1Encoding
this.forPrivateKey = kParam.isPrivate();
this.forEncryption = forEncryption;
+ this.blockBuffer = new byte[engine.getOutputBlockSize()];
+
+ if (pLen > 0 && fallback == null && random == null)
+ {
+ throw new IllegalArgumentException("encoder requires random");
+ }
}
public int getInputBlockSize()
{
- int baseBlockSize = engine.getInputBlockSize();
+ int baseBlockSize = engine.getInputBlockSize();
if (forEncryption)
{
@@ -167,7 +173,7 @@ public class PKCS1Encoding
public int getOutputBlockSize()
{
- int baseBlockSize = engine.getOutputBlockSize();
+ int baseBlockSize = engine.getOutputBlockSize();
if (forEncryption)
{
@@ -180,9 +186,9 @@ public class PKCS1Encoding
}
public byte[] processBlock(
- byte[] in,
- int inOff,
- int inLen)
+ byte[] in,
+ int inOff,
+ int inLen)
throws InvalidCipherTextException
{
if (forEncryption)
@@ -196,17 +202,17 @@ public class PKCS1Encoding
}
private byte[] encodeBlock(
- byte[] in,
- int inOff,
- int inLen)
+ byte[] in,
+ int inOff,
+ int inLen)
throws InvalidCipherTextException
{
if (inLen > getInputBlockSize())
{
throw new IllegalArgumentException("input data too large");
}
-
- byte[] block = new byte[engine.getInputBlockSize()];
+
+ byte[] block = new byte[engine.getInputBlockSize()];
if (forPrivateKey)
{
@@ -241,62 +247,63 @@ public class PKCS1Encoding
return engine.processBlock(block, 0, block.length);
}
-
+
/**
* Checks if the argument is a correctly PKCS#1.5 encoded Plaintext
* for encryption.
- *
+ *
* @param encoded The Plaintext.
- * @param pLen Expected length of the plaintext.
+ * @param pLen Expected length of the plaintext.
* @return Either 0, if the encoding is correct, or -1, if it is incorrect.
*/
- private static int checkPkcs1Encoding(byte[] encoded, int pLen) {
- int correct = 0;
- /*
+ private static int checkPkcs1Encoding(byte[] encoded, int pLen)
+ {
+ int correct = 0;
+ /*
* Check if the first two bytes are 0 2
*/
- correct |= (encoded[0] ^ 2);
+ correct |= (encoded[0] ^ 2);
/*
* Now the padding check, check for no 0 byte in the padding
*/
- int plen = encoded.length - (
- pLen /* Lenght of the PMS */
- + 1 /* Final 0-byte before PMS */
- );
-
- for (int i = 1; i < plen; i++) {
- int tmp = encoded[i];
- tmp |= tmp >> 1;
- tmp |= tmp >> 2;
- tmp |= tmp >> 4;
- correct |= (tmp & 1) - 1;
- }
+ int plen = encoded.length - (
+ pLen /* Lenght of the PMS */
+ + 1 /* Final 0-byte before PMS */
+ );
+
+ for (int i = 1; i < plen; i++)
+ {
+ int tmp = encoded[i];
+ tmp |= tmp >> 1;
+ tmp |= tmp >> 2;
+ tmp |= tmp >> 4;
+ correct |= (tmp & 1) - 1;
+ }
/*
* Make sure the padding ends with a 0 byte.
*/
- correct |= encoded[encoded.length - (pLen +1)];
+ correct |= encoded[encoded.length - (pLen + 1)];
/*
* Return 0 or 1, depending on the result.
*/
- correct |= correct >> 1;
- correct |= correct >> 2;
- correct |= correct >> 4;
- return ~((correct & 1) - 1);
- }
-
+ correct |= correct >> 1;
+ correct |= correct >> 2;
+ correct |= correct >> 4;
+ return ~((correct & 1) - 1);
+ }
+
/**
* Decode PKCS#1.5 encoding, and return a random value if the padding is not correct.
- *
- * @param in The encrypted block.
+ *
+ * @param in The encrypted block.
* @param inOff Offset in the encrypted block.
* @param inLen Length of the encrypted block.
- * //@param pLen Length of the desired output.
+ * //@param pLen Length of the desired output.
* @return The plaintext without padding, or a random value if the padding was incorrect.
- *
* @throws InvalidCipherTextException
*/
private byte[] decodeBlockOrRandom(byte[] in, int inOff, int inLen)
@@ -308,7 +315,7 @@ public class PKCS1Encoding
}
byte[] block = engine.processBlock(in, inOff, inLen);
- byte[] random = null;
+ byte[] random;
if (this.fallback == null)
{
random = new byte[this.pLen];
@@ -319,30 +326,12 @@ public class PKCS1Encoding
random = fallback;
}
- /*
- * TODO: This is a potential dangerous side channel. However, you can
- * fix this by changing the RSA engine in a way, that it will always
- * return blocks of the same length and prepend them with 0 bytes if
- * needed.
- */
- if (block.length < getOutputBlockSize())
- {
- throw new InvalidCipherTextException("block truncated");
- }
-
- /*
- * TODO: Potential side channel. Fix it by making the engine always
- * return blocks of the correct length.
- */
- if (useStrictLength && block.length != engine.getOutputBlockSize())
- {
- throw new InvalidCipherTextException("block incorrect size");
- }
+ byte[] data = (useStrictLength & (block.length != engine.getOutputBlockSize())) ? blockBuffer : block;
/*
* Check the padding.
*/
- int correct = PKCS1Encoding.checkPkcs1Encoding(block, this.pLen);
+ int correct = PKCS1Encoding.checkPkcs1Encoding(data, this.pLen);
/*
* Now, to a constant time constant memory copy of the decrypted value
@@ -351,52 +340,55 @@ public class PKCS1Encoding
byte[] result = new byte[this.pLen];
for (int i = 0; i < this.pLen; i++)
{
- result[i] = (byte)((block[i + (block.length - pLen)] & (~correct)) | (random[i] & correct));
+ result[i] = (byte)((data[i + (data.length - pLen)] & (~correct)) | (random[i] & correct));
}
+ Arrays.fill(data, (byte)0);
+
return result;
}
/**
- * @exception InvalidCipherTextException if the decrypted block is not in PKCS1 format.
+ * @throws InvalidCipherTextException if the decrypted block is not in PKCS1 format.
*/
private byte[] decodeBlock(
- byte[] in,
- int inOff,
- int inLen)
+ byte[] in,
+ int inOff,
+ int inLen)
throws InvalidCipherTextException
{
/*
* If the length of the expected plaintext is known, we use a constant-time decryption.
* If the decryption fails, we return a random value.
*/
- if (this.pLen != -1)
+ if (this.pLen != -1)
{
- return this.decodeBlockOrRandom(in, inOff, inLen);
- }
-
+ return this.decodeBlockOrRandom(in, inOff, inLen);
+ }
+
byte[] block = engine.processBlock(in, inOff, inLen);
+ boolean incorrectLength = (useStrictLength & (block.length != engine.getOutputBlockSize()));
+ byte[] data;
if (block.length < getOutputBlockSize())
{
- throw new InvalidCipherTextException("block truncated");
+ data = blockBuffer;
+ }
+ else
+ {
+ data = block;
}
- byte type = block[0];
+ byte type = data[0];
+ boolean badType;
if (forPrivateKey)
{
- if (type != 2)
- {
- throw new InvalidCipherTextException("unknown block type");
- }
+ badType = (type != 2);
}
else
{
- if (type != 1)
- {
- throw new InvalidCipherTextException("unknown block type");
- }
+ badType = (type != 1);
}
// BEGIN android-added
if ((type == 1 && forPrivateKey) || (type == 2 && !forPrivateKey))
@@ -405,41 +397,55 @@ public class PKCS1Encoding
}
// END android-added
- if (useStrictLength && block.length != engine.getOutputBlockSize())
- {
- throw new InvalidCipherTextException("block incorrect size");
- }
-
//
// find and extract the message block.
//
- int start;
-
- for (start = 1; start != block.length; start++)
- {
- byte pad = block[start];
-
- if (pad == 0)
- {
- break;
- }
- if (type == 1 && pad != (byte)0xff)
- {
- throw new InvalidCipherTextException("block padding incorrect");
- }
- }
+ int start = findStart(type, data);
start++; // data should start at the next byte
- if (start > block.length || start < HEADER_LENGTH)
+ if (badType | start < HEADER_LENGTH)
+ {
+ Arrays.fill(data, (byte)0);
+ throw new InvalidCipherTextException("block incorrect");
+ }
+
+ // if we get this far, it's likely to be a genuine encoding error
+ if (incorrectLength)
{
- throw new InvalidCipherTextException("no data in block");
+ Arrays.fill(data, (byte)0);
+ throw new InvalidCipherTextException("block incorrect size");
}
- byte[] result = new byte[block.length - start];
+ byte[] result = new byte[data.length - start];
- System.arraycopy(block, start, result, 0, result.length);
+ System.arraycopy(data, start, result, 0, result.length);
return result;
}
+
+ private int findStart(byte type, byte[] block)
+ throws InvalidCipherTextException
+ {
+ int start = -1;
+ boolean padErr = false;
+
+ for (int i = 1; i != block.length; i++)
+ {
+ byte pad = block[i];
+
+ if (pad == 0 & start < 0)
+ {
+ start = i;
+ }
+ padErr |= (type == 1 & start < 0 & pad != (byte)0xff);
+ }
+
+ if (padErr)
+ {
+ return -1;
+ }
+
+ return start;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java
index 924dff35..021b0f7d 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.Arrays;
import org.bouncycastle.util.Pack;
/**
@@ -415,6 +416,8 @@ private static final int[] Tinv0 =
private int C0, C1, C2, C3;
private boolean forEncryption;
+ private byte[] s;
+
private static final int BLOCK_SIZE = 16;
/**
@@ -440,6 +443,14 @@ private static final int[] Tinv0 =
{
WorkingKey = generateWorkingKey(((KeyParameter)params).getKey(), forEncryption);
this.forEncryption = forEncryption;
+ if (forEncryption)
+ {
+ s = Arrays.clone(S);
+ }
+ else
+ {
+ s = Arrays.clone(Si);
+ }
return;
}
@@ -578,10 +589,10 @@ private static final int[] Tinv0 =
// the final round's table is a simple function of S so we don't use a whole other four tables for it
- this.C0 = (S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((S[(r2>>16)&255]&255)<<16) ^ (S[(r3>>24)&255]<<24) ^ KW[r][0];
- this.C1 = (S[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (S[(r0>>24)&255]<<24) ^ KW[r][1];
- this.C2 = (S[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24) ^ KW[r][2];
- this.C3 = (S[r3&255]&255) ^ ((S[(r0>>8)&255]&255)<<8) ^ ((S[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24) ^ KW[r][3];
+ this.C0 = (S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((s[(r2>>16)&255]&255)<<16) ^ (s[(r3>>24)&255]<<24) ^ KW[r][0];
+ this.C1 = (s[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (s[(r0>>24)&255]<<24) ^ KW[r][1];
+ this.C2 = (s[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24) ^ KW[r][2];
+ this.C3 = (s[r3&255]&255) ^ ((s[(r0>>8)&255]&255)<<8) ^ ((s[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24) ^ KW[r][3];
}
private void decryptBlock(int[][] KW)
@@ -610,9 +621,9 @@ private static final int[] Tinv0 =
// the final round's table is a simple function of Si so we don't use a whole other four tables for it
- this.C0 = (Si[r0&255]&255) ^ ((Si[(r3>>8)&255]&255)<<8) ^ ((Si[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24) ^ KW[0][0];
- this.C1 = (Si[r1&255]&255) ^ ((Si[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (Si[(r2>>24)&255]<<24) ^ KW[0][1];
- this.C2 = (Si[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (Si[(r3>>24)&255]<<24) ^ KW[0][2];
- this.C3 = (Si[r3&255]&255) ^ ((Si[(r2>>8)&255]&255)<<8) ^ ((Si[(r1>>16)&255]&255)<<16) ^ (Si[(r0>>24)&255]<<24) ^ KW[0][3];
+ this.C0 = (Si[r0&255]&255) ^ ((s[(r3>>8)&255]&255)<<8) ^ ((s[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24) ^ KW[0][0];
+ this.C1 = (s[r1&255]&255) ^ ((s[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (s[(r2>>24)&255]<<24) ^ KW[0][1];
+ this.C2 = (s[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (s[(r3>>24)&255]<<24) ^ KW[0][2];
+ this.C3 = (Si[r3&255]&255) ^ ((s[(r2>>8)&255]&255)<<8) ^ ((s[(r1>>16)&255]&255)<<16) ^ (s[(r0>>24)&255]<<24) ^ KW[0][3];
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java
index 11e1bce8..abb8ba8c 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java
@@ -26,9 +26,11 @@ import org.bouncycastle.util.Pack;
* the contents of the first
*
* The slowest version uses no static tables at all and computes the values in each round
+ * </p>
* <p>
- * This file contains the fast version with 8Kbytes of static tables for round precomputation
- *
+ * This file contains the fast version with 8Kbytes of static tables for round precomputation.
+ * </p>
+ * @deprecated unfortunately this class is has a few side channel issues. In an environment where encryption/decryption may be closely observed it should not be used.
*/
public class AESFastEngine
implements BlockCipher
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 ba75c8d7..7274bf94 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeWrapEngine.java
@@ -13,6 +13,9 @@ import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.crypto.params.ParametersWithRandom;
+// BEGIN android-removed
+// import org.bouncycastle.crypto.util.DigestFactory;
+// END android-removed
import org.bouncycastle.util.Arrays;
/**
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 61b4bea9..cec79e03 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAParametersGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAParametersGenerator.java
@@ -4,12 +4,13 @@ import java.math.BigInteger;
import java.security.SecureRandom;
import org.bouncycastle.crypto.Digest;
-// BEGIN android-changed
-import org.bouncycastle.crypto.digests.AndroidDigestFactory;
-// END android-changed
import org.bouncycastle.crypto.params.DSAParameterGenerationParameters;
import org.bouncycastle.crypto.params.DSAParameters;
import org.bouncycastle.crypto.params.DSAValidationParameters;
+// BEGIN android-changed
+// Was: import org.bouncycastle.crypto.util.DigestFactory;
+import org.bouncycastle.crypto.digests.AndroidDigestFactory;
+// END android-added
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.BigIntegers;
import org.bouncycastle.util.encoders.Hex;
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java
index 79ec0f24..e6ec53a0 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/OpenSSLPBEParametersGenerator.java
@@ -5,9 +5,11 @@ import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.PBEParametersGenerator;
// BEGIN android-changed
import org.bouncycastle.crypto.digests.AndroidDigestFactory;
-// END android-changed
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
+// BEGIN android-removed
+// import org.bouncycastle.crypto.util.DigestFactory;
+// END android-removed
/**
* Generator for PBE derived keys and ivs as usd by OpenSSL.
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 9a2239e2..3089f8cc 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,9 @@ import org.bouncycastle.crypto.digests.AndroidDigestFactory;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
+// BEGIN android-removed
+// import org.bouncycastle.crypto.util.DigestFactory;
+// END android-removed
import org.bouncycastle.util.Arrays;
/**
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 ed89ef7d..54e54cec 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/GCMBlockCipher.java
@@ -38,6 +38,7 @@ public class GCMBlockCipher
// These fields are set by init and not modified by processing
private boolean forEncryption;
private int macSize;
+ private byte[] lastKey;
private byte[] nonce;
private byte[] initialAssociatedText;
private byte[] H;
@@ -48,6 +49,7 @@ public class GCMBlockCipher
private byte[] macBlock;
private byte[] S, S_at, S_atPre;
private byte[] counter;
+ private int blocksRemaining;
private int bufOff;
private long totalLength;
private byte[] atBlock;
@@ -99,12 +101,13 @@ public class GCMBlockCipher
this.macBlock = null;
KeyParameter keyParam;
+ byte[] newNonce = null;
if (params instanceof AEADParameters)
{
AEADParameters param = (AEADParameters)params;
- nonce = param.getNonce();
+ newNonce = param.getNonce();
initialAssociatedText = param.getAssociatedText();
int macSizeBits = param.getMacSize();
@@ -120,7 +123,7 @@ public class GCMBlockCipher
{
ParametersWithIV param = (ParametersWithIV)params;
- nonce = param.getIV();
+ newNonce = param.getIV();
initialAssociatedText = null;
macSize = 16;
keyParam = (KeyParameter)param.getParameters();
@@ -133,11 +136,32 @@ public class GCMBlockCipher
int bufLength = forEncryption ? BLOCK_SIZE : (BLOCK_SIZE + macSize);
this.bufBlock = new byte[bufLength];
- if (nonce == null || nonce.length < 1)
+ if (newNonce == null || newNonce.length < 1)
{
throw new IllegalArgumentException("IV must be at least 1 byte");
}
+ if (forEncryption)
+ {
+ if (nonce != null && Arrays.areEqual(nonce, newNonce))
+ {
+ if (keyParam == null)
+ {
+ throw new IllegalArgumentException("cannot reuse nonce for GCM encryption");
+ }
+ if (lastKey != null && Arrays.areEqual(lastKey, keyParam.getKey()))
+ {
+ throw new IllegalArgumentException("cannot reuse nonce for GCM encryption");
+ }
+ }
+ }
+
+ nonce = newNonce;
+ if (keyParam != null)
+ {
+ lastKey = keyParam.getKey();
+ }
+
// TODO Restrict macSize to 16 if nonce length not 12?
// Cipher always used in forward mode
@@ -181,6 +205,7 @@ public class GCMBlockCipher
this.atLength = 0;
this.atLengthPre = 0;
this.counter = Arrays.clone(J0);
+ this.blocksRemaining = -2; // page 8, len(P) <= 2^39 - 256, 1 block used by tag but done on J0
this.bufOff = 0;
this.totalLength = 0;
@@ -192,6 +217,10 @@ public class GCMBlockCipher
public byte[] getMac()
{
+ if (macBlock == null)
+ {
+ return new byte[macSize];
+ }
return Arrays.clone(macBlock);
}
@@ -481,6 +510,8 @@ public class GCMBlockCipher
{
cipher.reset();
+ // note: we do not reset the nonce.
+
S = new byte[BLOCK_SIZE];
S_at = new byte[BLOCK_SIZE];
S_atPre = new byte[BLOCK_SIZE];
@@ -489,6 +520,7 @@ public class GCMBlockCipher
atLength = 0;
atLengthPre = 0;
counter = Arrays.clone(J0);
+ blocksRemaining = -2;
bufOff = 0;
totalLength = 0;
@@ -555,6 +587,12 @@ public class GCMBlockCipher
private byte[] getNextCounterBlock()
{
+ if (blocksRemaining == 0)
+ {
+ throw new IllegalStateException("Attempt to process too many blocks");
+ }
+ blocksRemaining--;
+
int c = 1;
c += counter[15] & 0xFF; counter[15] = (byte)c; c >>>= 8;
c += counter[14] & 0xFF; counter[14] = (byte)c; c >>>= 8;
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/DHPublicKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/DHPublicKeyParameters.java
index ed531603..ba392ab1 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/DHPublicKeyParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/DHPublicKeyParameters.java
@@ -5,6 +5,9 @@ import java.math.BigInteger;
public class DHPublicKeyParameters
extends DHKeyParameters
{
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+ private static final BigInteger TWO = BigInteger.valueOf(2);
+
private BigInteger y;
public DHPublicKeyParameters(
@@ -13,9 +16,37 @@ public class DHPublicKeyParameters
{
super(false, params);
- this.y = y;
+ this.y = validate(y, params);
}
+ private BigInteger validate(BigInteger y, DHParameters dhParams)
+ {
+ if (y == null)
+ {
+ throw new NullPointerException("y value cannot be null");
+ }
+
+ // TLS check
+ if (y.compareTo(TWO) < 0 || y.compareTo(dhParams.getP().subtract(TWO)) > 0)
+ {
+ throw new IllegalArgumentException("invalid DH public key");
+ }
+
+ if (dhParams.getQ() != null)
+ {
+ if (ONE.equals(y.modPow(dhParams.getQ(), dhParams.getP())))
+ {
+ return y;
+ }
+
+ throw new IllegalArgumentException("Y value does not appear to be in correct group");
+ }
+ else
+ {
+ return y; // we can't validate without Q.
+ }
+ }
+
public BigInteger getY()
{
return y;
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/DSAPublicKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/DSAPublicKeyParameters.java
index c0066568..5786ee36 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/DSAPublicKeyParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/DSAPublicKeyParameters.java
@@ -5,6 +5,9 @@ import java.math.BigInteger;
public class DSAPublicKeyParameters
extends DSAKeyParameters
{
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+ private static final BigInteger TWO = BigInteger.valueOf(2);
+
private BigInteger y;
public DSAPublicKeyParameters(
@@ -13,9 +16,27 @@ public class DSAPublicKeyParameters
{
super(false, params);
- this.y = y;
+ this.y = validate(y, params);
}
+ private BigInteger validate(BigInteger y, DSAParameters params)
+ {
+ if (params != null)
+ {
+ if (TWO.compareTo(y) <= 0 && params.getP().subtract(TWO).compareTo(y) >= 0
+ && ONE.equals(y.modPow(params.getQ(), params.getP())))
+ {
+ return y;
+ }
+
+ throw new IllegalArgumentException("y value does not appear to be in correct group");
+ }
+ else
+ {
+ return y; // we can't validate without params, fortunately we can't use the key either...
+ }
+ }
+
public BigInteger getY()
{
return y;
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/ECDomainParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/ECDomainParameters.java
index 9cc6e727..c97f2e76 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/ECDomainParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/ECDomainParameters.java
@@ -71,4 +71,34 @@ public class ECDomainParameters
{
return Arrays.clone(seed);
}
+
+ public boolean equals(
+ Object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+
+ if ((obj instanceof ECDomainParameters))
+ {
+ ECDomainParameters other = (ECDomainParameters)obj;
+
+ return this.curve.equals(other.curve) && this.G.equals(other.G) && this.n.equals(other.n) && this.h.equals(other.h);
+ }
+
+ return false;
+ }
+
+ public int hashCode()
+ {
+ int hc = curve.hashCode();
+ hc *= 37;
+ hc ^= G.hashCode();
+ hc *= 37;
+ hc ^= n.hashCode();
+ hc *= 37;
+ hc ^= h.hashCode();
+ return hc;
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/ECPublicKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/ECPublicKeyParameters.java
index b6b3fb6d..036bf4ae 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/ECPublicKeyParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/ECPublicKeyParameters.java
@@ -5,14 +5,37 @@ import org.bouncycastle.math.ec.ECPoint;
public class ECPublicKeyParameters
extends ECKeyParameters
{
- ECPoint Q;
+ private final ECPoint Q;
public ECPublicKeyParameters(
ECPoint Q,
ECDomainParameters params)
{
super(false, params);
- this.Q = Q.normalize();
+
+ this.Q = validate(Q);
+ }
+
+ private ECPoint validate(ECPoint q)
+ {
+ if (q == null)
+ {
+ throw new IllegalArgumentException("point has null value");
+ }
+
+ if (q.isInfinity())
+ {
+ throw new IllegalArgumentException("point at infinity");
+ }
+
+ q = q.normalize();
+
+ if (!q.isValid())
+ {
+ throw new IllegalArgumentException("point not on curve");
+ }
+
+ return q;
}
public ECPoint getQ()
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/RSAKeyParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/RSAKeyParameters.java
index 4a2d9354..c357843e 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/RSAKeyParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/RSAKeyParameters.java
@@ -5,6 +5,8 @@ import java.math.BigInteger;
public class RSAKeyParameters
extends AsymmetricKeyParameter
{
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+
private BigInteger modulus;
private BigInteger exponent;
@@ -15,10 +17,40 @@ public class RSAKeyParameters
{
super(isPrivate);
- this.modulus = modulus;
+ if (!isPrivate)
+ {
+ if ((exponent.intValue() & 1) == 0)
+ {
+ throw new IllegalArgumentException("RSA publicExponent is even");
+ }
+ }
+
+ this.modulus = validate(modulus);
this.exponent = exponent;
}
+ private BigInteger validate(BigInteger modulus)
+ {
+ if ((modulus.intValue() & 1) == 0)
+ {
+ throw new IllegalArgumentException("RSA modulus is even");
+ }
+
+ // the value is the product of the 132 smallest primes from 3 to 751
+ if (!modulus.gcd(new BigInteger("145188775577763990151158743208307020242261438098488931355057091965" +
+ "931517706595657435907891265414916764399268423699130577757433083166" +
+ "651158914570105971074227669275788291575622090199821297575654322355" +
+ "049043101306108213104080801056529374892690144291505781966373045481" +
+ "8359472391642885328171302299245556663073719855")).equals(ONE))
+ {
+ throw new IllegalArgumentException("RSA modulus has a small prime factor");
+ }
+
+ // TODO: add additional primePower/Composite test - expensive!!
+
+ return modulus;
+ }
+
public BigInteger getModulus()
{
return modulus;
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java
index 44f838b2..920611bc 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/signers/DSASigner.java
@@ -95,7 +95,8 @@ public class DSASigner
BigInteger k = kCalculator.nextK();
- BigInteger r = params.getG().modPow(k, params.getP()).mod(q);
+ // the randomizer is to conceal timing information related to k and x.
+ BigInteger r = params.getG().modPow(k.add(getRandomizer(q, random)), params.getP()).mod(q);
k = k.modInverse(q).multiply(m.add(x.multiply(r)));
@@ -163,4 +164,12 @@ public class DSASigner
{
return !needed ? null : (provided != null) ? provided : new SecureRandom();
}
+
+ private BigInteger getRandomizer(BigInteger q, SecureRandom provided)
+ {
+ // Calculate a random multiple of q to add to k. Note that g^q = 1 (mod p), so adding multiple of q to k does not change r.
+ int randomBits = 7;
+
+ return new BigInteger(randomBits, provided != null ? provided : new SecureRandom()).add(BigInteger.valueOf(128)).multiply(q);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/tls/CertificateType.java b/bcprov/src/main/java/org/bouncycastle/crypto/tls/CertificateType.java
new file mode 100644
index 00000000..5dc503eb
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/tls/CertificateType.java
@@ -0,0 +1,15 @@
+package org.bouncycastle.crypto.tls;
+
+/**
+ * RFC 6091
+ */
+public class CertificateType
+{
+ public static final short X509 = 0;
+ public static final short OpenPGP = 1;
+
+ /*
+ * RFC 7250
+ */
+ public static final short RawPublicKey = 2;
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/iana/AEADAlgorithm.java b/bcprov/src/main/java/org/bouncycastle/iana/AEADAlgorithm.java
new file mode 100644
index 00000000..c289b6a3
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/iana/AEADAlgorithm.java
@@ -0,0 +1,57 @@
+package org.bouncycastle.iana;
+
+/**
+ * RFC 5116
+ */
+public class AEADAlgorithm
+{
+ public static final int AEAD_AES_128_GCM = 1;
+ public static final int AEAD_AES_256_GCM = 2;
+ public static final int AEAD_AES_128_CCM = 3;
+ public static final int AEAD_AES_256_CCM = 4;
+
+ /*
+ * RFC 5282
+ */
+ public static final int AEAD_AES_128_GCM_8 = 5;
+ public static final int AEAD_AES_256_GCM_8 = 6;
+ public static final int AEAD_AES_128_GCM_12 = 7;
+ public static final int AEAD_AES_256_GCM_12 = 8;
+ public static final int AEAD_AES_128_CCM_SHORT = 9;
+ public static final int AEAD_AES_256_CCM_SHORT = 10;
+ public static final int AEAD_AES_128_CCM_SHORT_8 = 11;
+ public static final int AEAD_AES_256_CCM_SHORT_8 = 12;
+ public static final int AEAD_AES_128_CCM_SHORT_12 = 13;
+ public static final int AEAD_AES_256_CCM_SHORT_12 = 14;
+
+ /*
+ * RFC 5297
+ */
+ public static final int AEAD_AES_SIV_CMAC_256 = 15;
+ public static final int AEAD_AES_SIV_CMAC_384 = 16;
+ public static final int AEAD_AES_SIV_CMAC_512 = 17;
+
+ /*
+ * RFC 6655
+ */
+ public static final int AEAD_AES_128_CCM_8 = 18;
+ public static final int AEAD_AES_256_CCM_8 = 19;
+
+ /*
+ * RFC 7253
+ */
+ public static final int AEAD_AES_128_OCB_TAGLEN128 = 20;
+ public static final int AEAD_AES_128_OCB_TAGLEN96 = 21;
+ public static final int AEAD_AES_128_OCB_TAGLEN64 = 22;
+ public static final int AEAD_AES_192_OCB_TAGLEN128 = 23;
+ public static final int AEAD_AES_192_OCB_TAGLEN96 = 24;
+ public static final int AEAD_AES_192_OCB_TAGLEN64 = 25;
+ public static final int AEAD_AES_256_OCB_TAGLEN128 = 26;
+ public static final int AEAD_AES_256_OCB_TAGLEN96 = 27;
+ public static final int AEAD_AES_256_OCB_TAGLEN64 = 28;
+
+ /*
+ * RFC 7539
+ */
+ public static final int AEAD_CHACHA20_POLY1305 = 29;
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/PKCS12Key.java b/bcprov/src/main/java/org/bouncycastle/jcajce/PKCS12Key.java
index db63ecdb..856b3e5b 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/PKCS12Key.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/PKCS12Key.java
@@ -29,6 +29,11 @@ public class PKCS12Key
*/
public PKCS12Key(char[] password, boolean useWrongZeroLengthConversion)
{
+ if (password == null)
+ {
+ password = new char[0];
+ }
+
this.password = new char[password.length];
this.useWrongZeroLengthConversion = useWrongZeroLengthConversion;
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 889d957d..da326f47 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
@@ -41,14 +41,14 @@ public class DH
// 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.IESwithAES-CBC", PREFIX + "IESCipher$IESwithAES");
+ // provider.addAlgorithm("Cipher.IESWITHAES-CBC", PREFIX + "IESCipher$IESwithAES");
+ // provider.addAlgorithm("Cipher.IESWITHDESEDE-CBC", 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.DHIESwithAES-CBC", PREFIX + "IESCipher$IESwithAES");
+ // provider.addAlgorithm("Cipher.DHIESWITHAES-CBC", PREFIX + "IESCipher$IESwithAES");
+ // provider.addAlgorithm("Cipher.DHIESWITHDESEDE-CBC", PREFIX + "IESCipher$IESwithDESede");
//
// provider.addAlgorithm("Cipher.OLDDHIES", PREFIX + "IESCipher$OldIES");
// provider.addAlgorithm("Cipher.OLDDHIESwithAES", PREFIX + "IESCipher$OldIESwithAES");
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DSA.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DSA.java
index 7c402f3d..92581f47 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DSA.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DSA.java
@@ -41,6 +41,17 @@ public class DSA
// provider.addAlgorithm("Signature.SHA256WITHDETDSA", PREFIX + "DSASigner$detDSA256");
// provider.addAlgorithm("Signature.SHA384WITHDETDSA", PREFIX + "DSASigner$detDSA384");
// provider.addAlgorithm("Signature.SHA512WITHDETDSA", PREFIX + "DSASigner$detDSA512");
+
+ // provider.addAlgorithm("Signature.DDSA", PREFIX + "DSASigner$detDSA");
+ // provider.addAlgorithm("Signature.SHA1WITHDDSA", PREFIX + "DSASigner$detDSA");
+ // provider.addAlgorithm("Signature.SHA224WITHDDSA", PREFIX + "DSASigner$detDSA224");
+ // provider.addAlgorithm("Signature.SHA256WITHDDSA", PREFIX + "DSASigner$detDSA256");
+ // provider.addAlgorithm("Signature.SHA384WITHDDSA", PREFIX + "DSASigner$detDSA384");
+ // provider.addAlgorithm("Signature.SHA512WITHDDSA", PREFIX + "DSASigner$detDSA512");
+ // provider.addAlgorithm("Signature.SHA3-224WITHDDSA", PREFIX + "DSASigner$detDSASha3_224");
+ // provider.addAlgorithm("Signature.SHA3-256WITHDDSA", PREFIX + "DSASigner$detDSASha3_256");
+ // provider.addAlgorithm("Signature.SHA3-384WITHDDSA", PREFIX + "DSASigner$detDSASha3_384");
+ // provider.addAlgorithm("Signature.SHA3-512WITHDDSA", PREFIX + "DSASigner$detDSASha3_512");
// END android-removed
addSignatureAlgorithm(provider, "SHA224", "DSA", PREFIX + "DSASigner$dsa224", NISTObjectIdentifiers.dsa_with_sha224);
@@ -53,6 +64,14 @@ public class DSA
// BEGIN android-added
provider.addAlgorithm("Alg.Alias.Signature.DSA", "SHA1withDSA");
// END android-added
+
+ // BEGIN android-removed
+ // addSignatureAlgorithm(provider, "SHA3-224", "DSA", PREFIX + "DSASigner$dsaSha3_224", NISTObjectIdentifiers.id_dsa_with_sha3_224);
+ // addSignatureAlgorithm(provider, "SHA3-256", "DSA", PREFIX + "DSASigner$dsaSha3_256", NISTObjectIdentifiers.id_dsa_with_sha3_256);
+ // addSignatureAlgorithm(provider, "SHA3-384", "DSA", PREFIX + "DSASigner$dsaSha3_384", NISTObjectIdentifiers.id_dsa_with_sha3_384);
+ // addSignatureAlgorithm(provider, "SHA3-512", "DSA", PREFIX + "DSASigner$dsaSha3_512", NISTObjectIdentifiers.id_dsa_with_sha3_512);
+ // END android-removed
+
// BEGIN android-changed
provider.addAlgorithm("Alg.Alias.Signature.SHA/DSA", "SHA1withDSA");
provider.addAlgorithm("Alg.Alias.Signature.SHA1withDSA", "SHA1withDSA");
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 99a27bf8..17e805be 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,6 +3,7 @@ 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.nist.NISTObjectIdentifiers;
// import org.bouncycastle.asn1.sec.SECObjectIdentifiers;
// import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
// END android-removed
@@ -160,24 +161,13 @@ public class EC
// provider.addAlgorithm("KeyPairGenerator.ECIES", PREFIX + "KeyPairGeneratorSpi$ECDH");
//
// provider.addAlgorithm("Cipher.ECIES", PREFIX + "IESCipher$ECIES");
- // provider.addAlgorithm("Cipher.ECIESwithAES", PREFIX + "IESCipher$ECIESwithAES");
- // provider.addAlgorithm("Cipher.ECIESWITHAES", PREFIX + "IESCipher$ECIESwithAES");
- // provider.addAlgorithm("Cipher.ECIESwithDESEDE", PREFIX + "IESCipher$ECIESwithDESede");
- // provider.addAlgorithm("Cipher.ECIESWITHDESEDE", PREFIX + "IESCipher$ECIESwithDESede");
+ //
// provider.addAlgorithm("Cipher.ECIESwithAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC");
// provider.addAlgorithm("Cipher.ECIESWITHAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC");
// provider.addAlgorithm("Cipher.ECIESwithDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC");
// provider.addAlgorithm("Cipher.ECIESWITHDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC");
//
- // provider.addAlgorithm("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");
+ // provider.addAlgorithm("Signature.ECDSA", PREFIX + "SignatureSpi$ecDSA");
// END android-removed
// BEGIN android-changed
@@ -201,7 +191,11 @@ public class EC
// provider.addAlgorithm("Signature.SHA256WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA256");
// provider.addAlgorithm("Signature.SHA384WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA384");
// provider.addAlgorithm("Signature.SHA512WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSA512");
- //
+ // provider.addAlgorithm("Signature.SHA3-224WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_224");
+ // provider.addAlgorithm("Signature.SHA3-256WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_256");
+ // provider.addAlgorithm("Signature.SHA3-384WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_384");
+ // provider.addAlgorithm("Signature.SHA3-512WITHECDDSA", PREFIX + "SignatureSpi$ecDetDSASha3_512");
+
// provider.addAlgorithm("Alg.Alias.Signature.DETECDSA", "ECDDSA");
// provider.addAlgorithm("Alg.Alias.Signature.SHA1WITHDETECDSA", "SHA1WITHECDDSA");
// provider.addAlgorithm("Alg.Alias.Signature.SHA224WITHDETECDSA", "SHA224WITHECDDSA");
@@ -215,6 +209,11 @@ public class EC
addSignatureAlgorithm(provider, "SHA384", "ECDSA", PREFIX + "SignatureSpi$ecDSA384", X9ObjectIdentifiers.ecdsa_with_SHA384);
addSignatureAlgorithm(provider, "SHA512", "ECDSA", PREFIX + "SignatureSpi$ecDSA512", X9ObjectIdentifiers.ecdsa_with_SHA512);
// BEGIN android-removed
+ // addSignatureAlgorithm(provider, "SHA3-224", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_224", NISTObjectIdentifiers.id_ecdsa_with_sha3_224);
+ // addSignatureAlgorithm(provider, "SHA3-256", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_256", NISTObjectIdentifiers.id_ecdsa_with_sha3_256);
+ // addSignatureAlgorithm(provider, "SHA3-384", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_384", NISTObjectIdentifiers.id_ecdsa_with_sha3_384);
+ // addSignatureAlgorithm(provider, "SHA3-512", "ECDSA", PREFIX + "SignatureSpi$ecDSASha3_512", NISTObjectIdentifiers.id_ecdsa_with_sha3_512);
+ //
// addSignatureAlgorithm(provider, "RIPEMD160", "ECDSA", PREFIX + "SignatureSpi$ecDSARipeMD160",TeleTrusTObjectIdentifiers.ecSignWithRipemd160);
//
// provider.addAlgorithm("Signature.SHA1WITHECNR", PREFIX + "SignatureSpi$ecNR");
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 5098c33d..20899c91 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
@@ -1,6 +1,7 @@
package org.bouncycastle.jcajce.provider.asymmetric;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
// BEGIN android-removed
@@ -108,6 +109,11 @@ public class RSA
// addPSSSignature(provider, "SHA512(224)", PREFIX + "PSSSignatureSpi$SHA512_224withRSA");
// addPSSSignature(provider, "SHA512(256)", PREFIX + "PSSSignatureSpi$SHA512_256withRSA");
//
+ // addPSSSignature(provider, "SHA3-224", PREFIX + "PSSSignatureSpi$SHA3_224withRSA");
+ // addPSSSignature(provider, "SHA3-256", PREFIX + "PSSSignatureSpi$SHA3_256withRSA");
+ // addPSSSignature(provider, "SHA3-384", PREFIX + "PSSSignatureSpi$SHA3_384withRSA");
+ // addPSSSignature(provider, "SHA3-512", PREFIX + "PSSSignatureSpi$SHA3_512withRSA");
+ //
// if (provider.hasAlgorithm("MessageDigest", "MD2"))
// {
// addDigestSignature(provider, "MD2", PREFIX + "DigestSignatureSpi$MD2", PKCSObjectIdentifiers.md2WithRSAEncryption);
@@ -152,11 +158,15 @@ public class RSA
addDigestSignature(provider, "SHA256", PREFIX + "DigestSignatureSpi$SHA256", PKCSObjectIdentifiers.sha256WithRSAEncryption);
addDigestSignature(provider, "SHA384", PREFIX + "DigestSignatureSpi$SHA384", PKCSObjectIdentifiers.sha384WithRSAEncryption);
addDigestSignature(provider, "SHA512", PREFIX + "DigestSignatureSpi$SHA512", PKCSObjectIdentifiers.sha512WithRSAEncryption);
-
// BEGIN android-removed
- // addDigestSignature(provider, "SHA512(224)", PREFIX + "DigestSignatureSpi$SHA512_224", null);
- // addDigestSignature(provider, "SHA512(256)", PREFIX + "DigestSignatureSpi$SHA512_256", null);
-
+ // addDigestSignature(provider, "SHA512(224)", PREFIX + "DigestSignatureSpi$SHA512_224", PKCSObjectIdentifiers.sha512_224WithRSAEncryption);
+ // addDigestSignature(provider, "SHA512(256)", PREFIX + "DigestSignatureSpi$SHA512_256", PKCSObjectIdentifiers.sha512_256WithRSAEncryption);
+ //
+ // addDigestSignature(provider, "SHA3-224", PREFIX + "DigestSignatureSpi$SHA3_224", NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224);
+ // addDigestSignature(provider, "SHA3-256", PREFIX + "DigestSignatureSpi$SHA3_256", NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_256);
+ // addDigestSignature(provider, "SHA3-384", PREFIX + "DigestSignatureSpi$SHA3_384", NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_384);
+ // addDigestSignature(provider, "SHA3-512", PREFIX + "DigestSignatureSpi$SHA3_512", NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512);
+ //
// addISO9796Signature(provider, "SHA224", PREFIX + "ISOSignatureSpi$SHA224WithRSAEncryption");
// addISO9796Signature(provider, "SHA256", PREFIX + "ISOSignatureSpi$SHA256WithRSAEncryption");
// addISO9796Signature(provider, "SHA384", PREFIX + "ISOSignatureSpi$SHA384WithRSAEncryption");
@@ -173,38 +183,24 @@ public class RSA
//
// if (provider.hasAlgorithm("MessageDigest", "RIPEMD128"))
// {
- // addDigestSignature(provider, "RIPEMD128", PREFIX + "DigestSignatureSpi$RIPEMD128", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
- // addDigestSignature(provider, "RMD128", PREFIX + "DigestSignatureSpi$RIPEMD128", null);
- // provider.addAlgorithm("Alg.Alias.Signature.RIPEMD128withRSA/X9.31", "RIPEMD128WITHRSA/X9.31");
- // provider.addAlgorithm("Alg.Alias.Signature.RIPEMD128WithRSA/X9.31", "RIPEMD128WITHRSA/X9.31");
- // provider.addAlgorithm("Signature.RIPEMD128WITHRSA/X9.31", PREFIX + "X931SignatureSpi$RIPEMD128WithRSAEncryption");
+ // addDigestSignature(provider, "RIPEMD128", PREFIX + "DigestSignatureSpi$RIPEMD128", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
+ // addDigestSignature(provider, "RMD128", PREFIX + "DigestSignatureSpi$RIPEMD128", null);
+ //
+ // addX931Signature(provider, "RMD128", PREFIX + "X931SignatureSpi$RIPEMD128WithRSAEncryption");
+ // addX931Signature(provider, "RIPEMD128", PREFIX + "X931SignatureSpi$RIPEMD128WithRSAEncryption");
// }
- //
+ //
// if (provider.hasAlgorithm("MessageDigest", "RIPEMD160"))
// {
- // addDigestSignature(provider, "RIPEMD160", PREFIX + "DigestSignatureSpi$RIPEMD160", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
- // addDigestSignature(provider, "RMD160", PREFIX + "DigestSignatureSpi$RIPEMD160", null);
- // provider.addAlgorithm("Alg.Alias.Signature.RIPEMD160WithRSA/ISO9796-2", "RIPEMD160withRSA/ISO9796-2");
- // provider.addAlgorithm("Signature.RIPEMD160withRSA/ISO9796-2", PREFIX + "ISOSignatureSpi$RIPEMD160WithRSAEncryption");
- // provider.addAlgorithm("Alg.Alias.Signature.RIPEMD160withRSA/X9.31", "RIPEMD160WITHRSA/X9.31");
- // provider.addAlgorithm("Alg.Alias.Signature.RIPEMD160WithRSA/X9.31", "RIPEMD160WITHRSA/X9.31");
- // provider.addAlgorithm("Signature.RIPEMD160WITHRSA/X9.31", PREFIX + "X931SignatureSpi$RIPEMD160WithRSAEncryption");
- // }
- //
- // if (provider.hasAlgorithm("MessageDigest", "RIPEMD256"))
- // {
- // addDigestSignature(provider, "RIPEMD256", PREFIX + "DigestSignatureSpi$RIPEMD256", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
- // addDigestSignature(provider, "RMD256", PREFIX + "DigestSignatureSpi$RIPEMD256", null);
- // }
- //
- // if (provider.hasAlgorithm("MessageDigest", "WHIRLPOOL"))
- // {
- // provider.addAlgorithm("Alg.Alias.Signature.WhirlpoolWithRSA/X9.31", "WHIRLPOOLWITHRSA/X9.31");
- // provider.addAlgorithm("Alg.Alias.Signature.WHIRLPOOLwithRSA/X9.31", "WHIRLPOOLWITHRSA/X9.31");
- // provider.addAlgorithm("Alg.Alias.Signature.WHIRLPOOLWithRSA/X9.31", "WHIRLPOOLWITHRSA/X9.31");
- // provider.addAlgorithm("Signature.WHIRLPOOLWITHRSA/X9.31", PREFIX + "X931SignatureSpi$WhirlpoolWithRSAEncryption");
+ // addDigestSignature(provider, "RIPEMD160", PREFIX + "DigestSignatureSpi$RIPEMD160", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
+ // addDigestSignature(provider, "RMD160", PREFIX + "DigestSignatureSpi$RIPEMD160", null);
+ // provider.addAlgorithm("Alg.Alias.Signature.RIPEMD160WithRSA/ISO9796-2", "RIPEMD160withRSA/ISO9796-2");
+ // provider.addAlgorithm("Signature.RIPEMD160withRSA/ISO9796-2", PREFIX + "ISOSignatureSpi$RIPEMD160WithRSAEncryption");
+ //
+ // addX931Signature(provider, "RMD160", PREFIX + "X931SignatureSpi$RIPEMD160WithRSAEncryption");
+ // addX931Signature(provider, "RIPEMD160", PREFIX + "X931SignatureSpi$RIPEMD160WithRSAEncryption");
// }
- // END android-removed
+ // END android-removed
}
private void addDigestSignature(
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 ef743095..1462a38b 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
@@ -16,10 +16,12 @@ import org.bouncycastle.asn1.pkcs.DHParameter;
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.ValidationParams;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import org.bouncycastle.crypto.params.DHParameters;
import org.bouncycastle.crypto.params.DHPublicKeyParameters;
+import org.bouncycastle.crypto.params.DHValidationParameters;
import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
public class BCDHPublicKey
@@ -29,6 +31,7 @@ public class BCDHPublicKey
private BigInteger y;
+ private transient DHPublicKeyParameters dhPublicKey;
private transient DHParameterSpec dhSpec;
private transient SubjectPublicKeyInfo info;
@@ -37,6 +40,7 @@ public class BCDHPublicKey
{
this.y = spec.getY();
this.dhSpec = new DHParameterSpec(spec.getP(), spec.getG());
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(spec.getP(), spec.getG()));
}
BCDHPublicKey(
@@ -44,6 +48,7 @@ public class BCDHPublicKey
{
this.y = key.getY();
this.dhSpec = key.getParams();
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(dhSpec.getP(), dhSpec.getG()));
}
BCDHPublicKey(
@@ -51,6 +56,7 @@ public class BCDHPublicKey
{
this.y = params.getY();
this.dhSpec = new DHParameterSpec(params.getParameters().getP(), params.getParameters().getG(), params.getParameters().getL());
+ this.dhPublicKey = params;
}
BCDHPublicKey(
@@ -59,6 +65,7 @@ public class BCDHPublicKey
{
this.y = y;
this.dhSpec = dhSpec;
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(dhSpec.getP(), dhSpec.getG()));
}
public BCDHPublicKey(
@@ -94,12 +101,23 @@ public class BCDHPublicKey
{
this.dhSpec = new DHParameterSpec(params.getP(), params.getG());
}
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(dhSpec.getP(), dhSpec.getG()));
}
else if (id.equals(X9ObjectIdentifiers.dhpublicnumber))
{
DomainParameters params = DomainParameters.getInstance(seq);
this.dhSpec = new DHParameterSpec(params.getP(), params.getG());
+ ValidationParams validationParams = params.getValidationParams();
+ if (validationParams != null)
+ {
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(params.getP(), params.getG(), params.getQ(), params.getJ(),
+ new DHValidationParameters(validationParams.getSeed(), validationParams.getPgenCounter().intValue())));
+ }
+ else
+ {
+ this.dhPublicKey = new DHPublicKeyParameters(y, new DHParameters(params.getP(), params.getG(), params.getQ(), params.getJ(), null));
+ }
}
else
{
@@ -137,6 +155,11 @@ public class BCDHPublicKey
return y;
}
+ public DHPublicKeyParameters engineGetKeyParameters()
+ {
+ return dhPublicKey;
+ }
+
private boolean isPKCSParam(ASN1Sequence seq)
{
if (seq.size() == 2)
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 3de8ffe5..f5e8d0ef 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
@@ -18,8 +18,8 @@ import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.crypto.DerivationFunction;
// BEGIN android-removed
// import org.bouncycastle.crypto.agreement.kdf.DHKEKGenerator;
+// import org.bouncycastle.crypto.util.DigestFactory;
// END android-removed
-import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.jcajce.provider.asymmetric.util.BaseAgreementSpi;
import org.bouncycastle.jcajce.spec.UserKeyingMaterialSpec;
@@ -31,10 +31,15 @@ import org.bouncycastle.jcajce.spec.UserKeyingMaterialSpec;
public class KeyAgreementSpi
extends BaseAgreementSpi
{
+ private static final BigInteger ONE = BigInteger.valueOf(1);
+ private static final BigInteger TWO = BigInteger.valueOf(2);
+
private BigInteger x;
private BigInteger p;
private BigInteger g;
+ private BigInteger result;
+
public KeyAgreementSpi()
{
super("Diffie-Hellman", null);
@@ -101,14 +106,22 @@ public class KeyAgreementSpi
throw new InvalidKeyException("DHPublicKey not for this KeyAgreement!");
}
- if (lastPhase)
+ BigInteger peerY = ((DHPublicKey)key).getY();
+ if (peerY == null || peerY.compareTo(TWO) < 0
+ || peerY.compareTo(p.subtract(ONE)) >= 0)
{
- result = ((DHPublicKey)key).getY().modPow(x, p);
- return null;
+ throw new InvalidKeyException("Invalid DH PublicKey");
}
- else
+
+ result = peerY.modPow(x, p);
+ if (result.compareTo(ONE) == 0)
+ {
+ throw new InvalidKeyException("Shared key can't be 1");
+ }
+
+ if (lastPhase)
{
- result = ((DHPublicKey)key).getY().modPow(x, p);
+ return null;
}
return new BCDHPublicKey(result, pubKey.getParams());
@@ -216,13 +229,18 @@ public class KeyAgreementSpi
this.x = this.result = privKey.getX();
}
+ protected byte[] calcSecret()
+ {
+ return bigIntToBytes(result);
+ }
+
// BEGIN android-removed
// public static class DHwithRFC2631KDF
- // extends KeyAgreementSpi
+ // extends KeyAgreementSpi
// {
- // public DHwithRFC2631KDF()
+ // public DHwithRFC2631KDF()
// {
- // super("DHwithRFC2631KDF", new DHKEKGenerator(new SHA1Digest()));
+ // super("DHwithRFC2631KDF", new DHKEKGenerator(DigestFactory.createSHA1()));
// }
// }
// END android-removed
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyFactorySpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyFactorySpi.java
index 9565bd2d..32e9b496 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyFactorySpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyFactorySpi.java
@@ -19,6 +19,7 @@ import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi;
+import org.bouncycastle.jcajce.provider.asymmetric.util.ExtendedInvalidKeySpecException;
public class KeyFactorySpi
extends BaseKeyFactorySpi
@@ -82,7 +83,14 @@ public class KeyFactorySpi
{
if (keySpec instanceof DHPublicKeySpec)
{
- return new BCDHPublicKey((DHPublicKeySpec)keySpec);
+ try
+ {
+ return new BCDHPublicKey((DHPublicKeySpec)keySpec);
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ExtendedInvalidKeySpecException(e.getMessage(), e);
+ }
}
return super.engineGeneratePublic(keySpec);
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyPairGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyPairGeneratorSpi.java
index 48da0203..793f7299 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyPairGeneratorSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/KeyPairGeneratorSpi.java
@@ -42,6 +42,7 @@ public class KeyPairGeneratorSpi
{
this.strength = strength;
this.random = random;
+ this.initialised = false;
}
public void initialize(
@@ -113,7 +114,6 @@ public class KeyPairGeneratorSpi
DHPublicKeyParameters pub = (DHPublicKeyParameters)pair.getPublic();
DHPrivateKeyParameters priv = (DHPrivateKeyParameters)pair.getPrivate();
- return new KeyPair(new BCDHPublicKey(pub),
- new BCDHPrivateKey(priv));
+ return new KeyPair(new BCDHPublicKey(pub), new BCDHPrivateKey(priv));
}
}
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 3a7b3121..13223cb6 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
@@ -24,15 +24,19 @@ public class BCDSAPublicKey
implements DSAPublicKey
{
private static final long serialVersionUID = 1752452449903495175L;
+ private static BigInteger ZERO = BigInteger.valueOf(0);
private BigInteger y;
- private transient DSAParams dsaSpec;
+
+ private transient DSAPublicKeyParameters lwKeyParams;
+ private transient DSAParams dsaSpec;
BCDSAPublicKey(
DSAPublicKeySpec spec)
{
this.y = spec.getY();
this.dsaSpec = new DSAParameterSpec(spec.getP(), spec.getQ(), spec.getG());
+ this.lwKeyParams = new DSAPublicKeyParameters(y, DSAUtil.toDSAParameters(dsaSpec));
}
BCDSAPublicKey(
@@ -40,27 +44,27 @@ public class BCDSAPublicKey
{
this.y = key.getY();
this.dsaSpec = key.getParams();
+ this.lwKeyParams = new DSAPublicKeyParameters(y, DSAUtil.toDSAParameters(dsaSpec));
}
BCDSAPublicKey(
DSAPublicKeyParameters params)
{
this.y = params.getY();
- this.dsaSpec = new DSAParameterSpec(params.getParameters().getP(), params.getParameters().getQ(), params.getParameters().getG());
- }
-
- BCDSAPublicKey(
- BigInteger y,
- DSAParameterSpec dsaSpec)
- {
- this.y = y;
- this.dsaSpec = dsaSpec;
+ if (params != null)
+ {
+ this.dsaSpec = new DSAParameterSpec(params.getParameters().getP(), params.getParameters().getQ(), params.getParameters().getG());
+ }
+ else
+ {
+ this.dsaSpec = null;
+ }
+ this.lwKeyParams = params;
}
public BCDSAPublicKey(
SubjectPublicKeyInfo info)
{
-
ASN1Integer derY;
try
@@ -80,6 +84,12 @@ public class BCDSAPublicKey
this.dsaSpec = new DSAParameterSpec(params.getP(), params.getQ(), params.getG());
}
+ else
+ {
+ this.dsaSpec = null;
+ }
+
+ this.lwKeyParams = new DSAPublicKeyParameters(y, DSAUtil.toDSAParameters(dsaSpec));
}
private boolean isNotNull(ASN1Encodable parameters)
@@ -97,6 +107,11 @@ public class BCDSAPublicKey
return "X.509";
}
+ DSAPublicKeyParameters engineGetKeyParameters()
+ {
+ return lwKeyParams;
+ }
+
public byte[] getEncoded()
{
if (dsaSpec == null)
@@ -130,8 +145,15 @@ public class BCDSAPublicKey
public int hashCode()
{
- return this.getY().hashCode() ^ this.getParams().getG().hashCode()
+ if (dsaSpec != null)
+ {
+ return this.getY().hashCode() ^ this.getParams().getG().hashCode()
^ this.getParams().getP().hashCode() ^ this.getParams().getQ().hashCode();
+ }
+ else
+ {
+ return this.getY().hashCode();
+ }
}
public boolean equals(
@@ -143,11 +165,19 @@ public class BCDSAPublicKey
}
DSAPublicKey other = (DSAPublicKey)o;
-
- return this.getY().equals(other.getY())
- && this.getParams().getG().equals(other.getParams().getG())
- && this.getParams().getP().equals(other.getParams().getP())
- && this.getParams().getQ().equals(other.getParams().getQ());
+
+ if (this.dsaSpec != null)
+ {
+ return this.getY().equals(other.getY())
+ && other.getParams() != null
+ && this.getParams().getG().equals(other.getParams().getG())
+ && this.getParams().getP().equals(other.getParams().getP())
+ && this.getParams().getQ().equals(other.getParams().getQ());
+ }
+ else
+ {
+ return this.getY().equals(other.getY()) && other.getParams() == null;
+ }
}
private void readObject(
@@ -156,7 +186,16 @@ public class BCDSAPublicKey
{
in.defaultReadObject();
- this.dsaSpec = new DSAParameterSpec((BigInteger)in.readObject(), (BigInteger)in.readObject(), (BigInteger)in.readObject());
+ BigInteger p = (BigInteger)in.readObject();
+ if (p.equals(ZERO))
+ {
+ this.dsaSpec = null;
+ }
+ else
+ {
+ this.dsaSpec = new DSAParameterSpec(p, (BigInteger)in.readObject(), (BigInteger)in.readObject());
+ }
+ this.lwKeyParams = new DSAPublicKeyParameters(y, DSAUtil.toDSAParameters(dsaSpec));
}
private void writeObject(
@@ -165,8 +204,15 @@ public class BCDSAPublicKey
{
out.defaultWriteObject();
- out.writeObject(dsaSpec.getP());
- out.writeObject(dsaSpec.getQ());
- out.writeObject(dsaSpec.getG());
+ if (dsaSpec == null)
+ {
+ out.writeObject(ZERO);
+ }
+ else
+ {
+ out.writeObject(dsaSpec.getP());
+ out.writeObject(dsaSpec.getQ());
+ out.writeObject(dsaSpec.getG());
+ }
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
index fead55dd..6374419f 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java
@@ -8,7 +8,6 @@ import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.SignatureException;
import java.security.SignatureSpi;
-import java.security.interfaces.DSAKey;
import java.security.spec.AlgorithmParameterSpec;
import org.bouncycastle.asn1.ASN1Encoding;
@@ -17,7 +16,6 @@ import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
-import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DSA;
@@ -39,8 +37,12 @@ import org.bouncycastle.crypto.params.DSAParameters;
// END android-added
import org.bouncycastle.crypto.params.ParametersWithRandom;
// BEGIN android-removed
+// import org.bouncycastle.crypto.digests.SHA1Digest;
+// import org.bouncycastle.crypto.params.ParametersWithRandom;
// import org.bouncycastle.crypto.signers.HMacDSAKCalculator;
+// import org.bouncycastle.crypto.util.DigestFactory;
// END android-removed
+import org.bouncycastle.util.Arrays;
public class DSASigner
extends SignatureSpi
@@ -62,34 +64,7 @@ public class DSASigner
PublicKey publicKey)
throws InvalidKeyException
{
- CipherParameters param;
-
- if (publicKey instanceof DSAKey)
- {
- param = DSAUtil.generatePublicKeyParameter(publicKey);
- }
- else
- {
- try
- {
- byte[] bytes = publicKey.getEncoded();
-
- publicKey = new BCDSAPublicKey(SubjectPublicKeyInfo.getInstance(bytes));
-
- if (publicKey instanceof DSAKey)
- {
- param = DSAUtil.generatePublicKeyParameter(publicKey);
- }
- else
- {
- throw new InvalidKeyException("can't recognise key type in DSA based signer");
- }
- }
- catch (Exception e)
- {
- throw new InvalidKeyException("can't recognise key type in DSA based signer");
- }
- }
+ CipherParameters param = DSAUtil.generatePublicKeyParameter(publicKey);
digest.reset();
signer.init(false, param);
@@ -243,6 +218,15 @@ public class DSASigner
throws IOException
{
ASN1Sequence s = (ASN1Sequence)ASN1Primitive.fromByteArray(encoding);
+ if (s.size() != 2)
+ {
+ throw new IOException("malformed signature");
+ }
+ if (!Arrays.areEqual(encoding, s.getEncoded(ASN1Encoding.DER)))
+ {
+ throw new IOException("malformed signature");
+ }
+
return new BigInteger[]{
((ASN1Integer)s.getObjectAt(0)).getValue(),
((ASN1Integer)s.getObjectAt(1)).getValue()
@@ -266,10 +250,9 @@ public class DSASigner
// {
// public detDSA()
// {
- // super(new SHA1Digest(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(new SHA1Digest())));
+ // super(DigestFactory.createSHA1(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA1())));
// }
// }
- // END android-removed
static public class dsa224
extends DSASigner
@@ -288,10 +271,9 @@ public class DSASigner
// {
// public detDSA224()
// {
- // super(new SHA224Digest(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(new SHA224Digest())));
+ // super(DigestFactory.createSHA224(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA224())));
// }
// }
- // END android-removed
static public class dsa256
extends DSASigner
@@ -303,14 +285,13 @@ public class DSASigner
// END android-changed
}
}
-
// BEGIN android-removed
// static public class detDSA256
// extends DSASigner
// {
// public detDSA256()
// {
- // super(new SHA256Digest(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(new SHA256Digest())));
+ // super(DigestFactory.createSHA256(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA256())));
// }
// }
//
@@ -319,7 +300,7 @@ public class DSASigner
// {
// public dsa384()
// {
- // super(new SHA384Digest(), new org.bouncycastle.crypto.signers.DSASigner());
+ // super(DigestFactory.createSHA384(), new org.bouncycastle.crypto.signers.DSASigner());
// }
// }
//
@@ -328,7 +309,7 @@ public class DSASigner
// {
// public detDSA384()
// {
- // super(new SHA384Digest(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(new SHA384Digest())));
+ // super(DigestFactory.createSHA384(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA384())));
// }
// }
//
@@ -337,7 +318,7 @@ public class DSASigner
// {
// public dsa512()
// {
- // super(new SHA512Digest(), new org.bouncycastle.crypto.signers.DSASigner());
+ // super(DigestFactory.createSHA512(), new org.bouncycastle.crypto.signers.DSASigner());
// }
// }
//
@@ -346,7 +327,79 @@ public class DSASigner
// {
// public detDSA512()
// {
- // super(new SHA512Digest(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(new SHA512Digest())));
+ // super(DigestFactory.createSHA512(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA512())));
+ // }
+ // }
+ //
+ // static public class dsaSha3_224
+ // extends DSASigner
+ // {
+ // public dsaSha3_224()
+ // {
+ // super(DigestFactory.createSHA3_224(), new org.bouncycastle.crypto.signers.DSASigner());
+ // }
+ // }
+ //
+ // static public class detDSASha3_224
+ // extends DSASigner
+ // {
+ // public detDSASha3_224()
+ // {
+ // super(DigestFactory.createSHA3_224(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_224())));
+ // }
+ // }
+ //
+ // static public class dsaSha3_256
+ // extends DSASigner
+ // {
+ // public dsaSha3_256()
+ // {
+ // super(DigestFactory.createSHA3_256(), new org.bouncycastle.crypto.signers.DSASigner());
+ // }
+ // }
+ //
+ // static public class detDSASha3_256
+ // extends DSASigner
+ // {
+ // public detDSASha3_256()
+ // {
+ // super(DigestFactory.createSHA3_256(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_256())));
+ // }
+ // }
+ //
+ // static public class dsaSha3_384
+ // extends DSASigner
+ // {
+ // public dsaSha3_384()
+ // {
+ // super(DigestFactory.createSHA3_384(), new org.bouncycastle.crypto.signers.DSASigner());
+ // }
+ // }
+ //
+ // static public class detDSASha3_384
+ // extends DSASigner
+ // {
+ // public detDSASha3_384()
+ // {
+ // super(DigestFactory.createSHA3_384(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_384())));
+ // }
+ // }
+ //
+ // static public class dsaSha3_512
+ // extends DSASigner
+ // {
+ // public dsaSha3_512()
+ // {
+ // super(DigestFactory.createSHA3_512(), new org.bouncycastle.crypto.signers.DSASigner());
+ // }
+ // }
+ //
+ // static public class detDSASha3_512
+ // extends DSASigner
+ // {
+ // public detDSASha3_512()
+ // {
+ // super(DigestFactory.createSHA3_512(), new org.bouncycastle.crypto.signers.DSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_512())));
// }
// }
// END android-removed
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSAUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSAUtil.java
index c7e2aa91..10bac464 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSAUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSAUtil.java
@@ -3,11 +3,14 @@ package org.bouncycastle.jcajce.provider.asymmetric.dsa;
import java.security.InvalidKeyException;
import java.security.PrivateKey;
import java.security.PublicKey;
+import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.DSAPublicKey;
+import java.security.spec.DSAParameterSpec;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.DSAParameters;
@@ -43,19 +46,42 @@ public class DSAUtil
return false;
}
+ static DSAParameters toDSAParameters(DSAParams spec)
+ {
+ if (spec != null)
+ {
+ return new DSAParameters(spec.getP(), spec.getQ(), spec.getG());
+ }
+
+ return null;
+ }
+
static public AsymmetricKeyParameter generatePublicKeyParameter(
PublicKey key)
throws InvalidKeyException
{
- if (key instanceof DSAPublicKey)
+ if (key instanceof BCDSAPublicKey)
{
- DSAPublicKey k = (DSAPublicKey)key;
+ return ((BCDSAPublicKey)key).engineGetKeyParameters();
+ }
- return new DSAPublicKeyParameters(k.getY(),
- new DSAParameters(k.getParams().getP(), k.getParams().getQ(), k.getParams().getG()));
+ if (key instanceof DSAPublicKey)
+ {
+ return new BCDSAPublicKey((DSAPublicKey)key).engineGetKeyParameters();
}
- throw new InvalidKeyException("can't identify DSA public key: " + key.getClass().getName());
+ try
+ {
+ byte[] bytes = key.getEncoded();
+
+ BCDSAPublicKey bckey = new BCDSAPublicKey(SubjectPublicKeyInfo.getInstance(bytes));
+
+ return bckey.engineGetKeyParameters();
+ }
+ catch (Exception e)
+ {
+ throw new InvalidKeyException("can't identify DSA public key: " + key.getClass().getName());
+ }
}
static public AsymmetricKeyParameter generatePrivateKeyParameter(
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java
index a36f3dd7..7816320d 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyFactorySpi.java
@@ -109,7 +109,20 @@ public class KeyFactorySpi
{
if (keySpec instanceof DSAPublicKeySpec)
{
- return new BCDSAPublicKey((DSAPublicKeySpec)keySpec);
+ try
+ {
+ return new BCDSAPublicKey((DSAPublicKeySpec)keySpec);
+ }
+ catch (final Exception e)
+ {
+ throw new InvalidKeySpecException("invalid KeySpec: " + e.getMessage())
+ {
+ public Throwable getCause()
+ {
+ return e;
+ }
+ };
+ }
}
return super.engineGeneratePublic(keySpec);
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java
index d2c2c712..bacbb6c2 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java
@@ -6,18 +6,26 @@ import java.security.KeyPair;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.DSAParameterSpec;
+import java.util.Hashtable;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
+import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.generators.DSAKeyPairGenerator;
import org.bouncycastle.crypto.generators.DSAParametersGenerator;
import org.bouncycastle.crypto.params.DSAKeyGenerationParameters;
+import org.bouncycastle.crypto.params.DSAParameterGenerationParameters;
import org.bouncycastle.crypto.params.DSAParameters;
import org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
import org.bouncycastle.crypto.params.DSAPublicKeyParameters;
+import org.bouncycastle.util.Integers;
+import org.bouncycastle.util.Properties;
public class KeyPairGeneratorSpi
extends java.security.KeyPairGenerator
{
+ private static Hashtable params = new Hashtable();
+ private static Object lock = new Object();
+
DSAKeyGenerationParameters param;
DSAKeyPairGenerator engine = new DSAKeyPairGenerator();
int strength = 1024;
@@ -41,6 +49,7 @@ public class KeyPairGeneratorSpi
this.strength = strength;
this.random = random;
+ this.initialised = false;
}
public void initialize(
@@ -64,10 +73,65 @@ public class KeyPairGeneratorSpi
{
if (!initialised)
{
- DSAParametersGenerator pGen = new DSAParametersGenerator();
+ Integer paramStrength = Integers.valueOf(strength);
+
+ if (params.containsKey(paramStrength))
+ {
+ param = (DSAKeyGenerationParameters)params.get(paramStrength);
+ }
+ else
+ {
+ synchronized (lock)
+ {
+ // we do the check again in case we were blocked by a generator for
+ // our key size.
+ if (params.containsKey(paramStrength))
+ {
+ param = (DSAKeyGenerationParameters)params.get(paramStrength);
+ }
+ else
+ {
+ DSAParametersGenerator pGen;
+ DSAParameterGenerationParameters dsaParams;
+
+ // Typical combination of keysize and size of q.
+ // keysize = 1024, q's size = 160
+ // keysize = 2048, q's size = 224
+ // keysize = 2048, q's size = 256
+ // keysize = 3072, q's size = 256
+ // For simplicity if keysize is greater than 1024 then we choose q's size to be 256.
+ // For legacy keysize that is less than 1024-bit, we just use the 186-2 style parameters
+ if (strength == 1024)
+ {
+ pGen = new DSAParametersGenerator();
+ if (Properties.isOverrideSet("org.bouncycastle.dsa.FIPS186-2for1024bits"))
+ {
+ pGen.init(strength, certainty, random);
+ }
+ else
+ {
+ dsaParams = new DSAParameterGenerationParameters(1024, 160, certainty, random);
+ pGen.init(dsaParams);
+ }
+ }
+ else if (strength > 1024)
+ {
+ dsaParams = new DSAParameterGenerationParameters(strength, 256, certainty, random);
+ pGen = new DSAParametersGenerator(new SHA256Digest());
+ pGen.init(dsaParams);
+ }
+ else
+ {
+ pGen = new DSAParametersGenerator();
+ pGen.init(strength, certainty, random);
+ }
+ param = new DSAKeyGenerationParameters(random, pGen.generateParameters());
+
+ params.put(paramStrength, param);
+ }
+ }
+ }
- pGen.init(strength, certainty, random);
- param = new DSAKeyGenerationParameters(random, pGen.generateParameters());
engine.init(param);
initialised = true;
}
@@ -76,7 +140,6 @@ public class KeyPairGeneratorSpi
DSAPublicKeyParameters pub = (DSAPublicKeyParameters)pair.getPublic();
DSAPrivateKeyParameters priv = (DSAPrivateKeyParameters)pair.getPrivate();
- return new KeyPair(new BCDSAPublicKey(pub),
- new BCDSAPrivateKey(priv));
+ return new KeyPair(new BCDSAPublicKey(pub), new BCDSAPrivateKey(priv));
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
index 6af71e80..9f56a55a 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/AlgorithmParametersSpi.java
@@ -14,6 +14,7 @@ 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.jce.spec.ECNamedCurveSpec;
import org.bouncycastle.math.ec.ECCurve;
public class AlgorithmParametersSpi
@@ -45,7 +46,14 @@ public class AlgorithmParametersSpi
}
else if (algorithmParameterSpec instanceof ECParameterSpec)
{
- curveName = null;
+ if (algorithmParameterSpec instanceof ECNamedCurveSpec)
+ {
+ curveName = ((ECNamedCurveSpec)algorithmParameterSpec).getName();
+ }
+ else
+ {
+ curveName = null;
+ }
ecParameterSpec = (ECParameterSpec)algorithmParameterSpec;
}
else
@@ -73,7 +81,13 @@ public class AlgorithmParametersSpi
if (params.isNamedCurve())
{
- curveName = ECNamedCurveTable.getName(ASN1ObjectIdentifier.getInstance(params.getParameters()));
+ ASN1ObjectIdentifier curveId = ASN1ObjectIdentifier.getInstance(params.getParameters());
+
+ curveName = ECNamedCurveTable.getName(curveId);
+ if (curveName == null)
+ {
+ curveName = curveId.getId();
+ }
}
ecParameterSpec = EC5Util.convertToSpec(params, curve);
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 e69942a2..815bcac0 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
@@ -17,12 +17,10 @@ import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.DERBitString;
-import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x9.X962Parameters;
-import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
@@ -33,7 +31,6 @@ import org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
import org.bouncycastle.jce.interfaces.ECPointEncoder;
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;
@@ -181,7 +178,14 @@ public class BCECPrivateKey
this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec);
}
- publicKey = getPublicKeyDetails(pubKey);
+ try
+ {
+ publicKey = getPublicKeyDetails(pubKey);
+ }
+ catch (Exception e)
+ {
+ publicKey = null; // not all curves are encodable
+ }
}
public BCECPrivateKey(
@@ -253,38 +257,16 @@ public class BCECPrivateKey
*/
public byte[] getEncoded()
{
- X962Parameters params;
- int orderBitLength;
+ X962Parameters params = ECUtils.getDomainParametersFromName(ecSpec, withCompression);
- if (ecSpec instanceof ECNamedCurveSpec)
- {
- ASN1ObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec)ecSpec).getName());
- if (curveOid == null) // guess it's the OID
- {
- curveOid = new ASN1ObjectIdentifier(((ECNamedCurveSpec)ecSpec).getName());
- }
-
- params = new X962Parameters(curveOid);
- orderBitLength = ECUtil.getOrderBitLength(ecSpec.getOrder(), this.getS());
- }
- else if (ecSpec == null)
+ int orderBitLength;
+ if (ecSpec == null)
{
- params = new X962Parameters(DERNull.INSTANCE);
- orderBitLength = ECUtil.getOrderBitLength(null, this.getS());
+ orderBitLength = ECUtil.getOrderBitLength(configuration, null, this.getS());
}
else
{
- ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve());
-
- X9ECParameters ecP = new X9ECParameters(
- curve,
- EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression),
- ecSpec.getOrder(),
- BigInteger.valueOf(ecSpec.getCofactor()),
- ecSpec.getCurve().getSeed());
-
- params = new X962Parameters(ecP);
- orderBitLength = ECUtil.getOrderBitLength(ecSpec.getOrder(), this.getS());
+ orderBitLength = ECUtil.getOrderBitLength(configuration, ecSpec.getOrder(), this.getS());
}
PrivateKeyInfo info;
@@ -420,9 +402,10 @@ public class BCECPrivateKey
byte[] enc = (byte[])in.readObject();
+ this.configuration = BouncyCastleProvider.CONFIGURATION;
+
populateFromPrivKeyInfo(PrivateKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc)));
- this.configuration = BouncyCastleProvider.CONFIGURATION;
this.attrCarrier = new PKCS12BagAttributeCarrierImpl();
}
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 c3f0dd02..443c5f63 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
@@ -3,7 +3,6 @@ package org.bouncycastle.jcajce.provider.asymmetric.ec;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
-import java.math.BigInteger;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPoint;
@@ -11,16 +10,13 @@ import java.security.spec.ECPublicKeySpec;
import java.security.spec.EllipticCurve;
import org.bouncycastle.asn1.ASN1Encodable;
-import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.DERBitString;
-import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x9.X962Parameters;
-import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.asn1.x9.X9ECPoint;
import org.bouncycastle.asn1.x9.X9IntegerConverter;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
@@ -32,7 +28,6 @@ import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
import org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
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.util.Strings;
@@ -44,7 +39,7 @@ public class BCECPublicKey
private String algorithm = "EC";
private boolean withCompression;
- private transient org.bouncycastle.math.ec.ECPoint q;
+ private transient ECPublicKeyParameters ecPublicKey;
private transient ECParameterSpec ecSpec;
private transient ProviderConfiguration configuration;
@@ -53,7 +48,7 @@ public class BCECPublicKey
BCECPublicKey key)
{
this.algorithm = algorithm;
- this.q = key.q;
+ this.ecPublicKey = key.ecPublicKey;
this.ecSpec = key.ecSpec;
this.withCompression = key.withCompression;
this.configuration = key.configuration;
@@ -66,7 +61,7 @@ public class BCECPublicKey
{
this.algorithm = algorithm;
this.ecSpec = spec.getParams();
- this.q = EC5Util.convertPoint(ecSpec, spec.getW(), false);
+ this.ecPublicKey = new ECPublicKeyParameters(EC5Util.convertPoint(ecSpec, spec.getW(), false), EC5Util.getDomainParameters(configuration, spec.getParams()));
this.configuration = configuration;
}
@@ -76,7 +71,6 @@ public class BCECPublicKey
ProviderConfiguration configuration)
{
this.algorithm = algorithm;
- this.q = spec.getQ();
if (spec.getParams() != null) // can be null if implictlyCa
{
@@ -84,17 +78,15 @@ public class BCECPublicKey
EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, spec.getParams().getSeed());
// this may seem a little long-winded but it's how we pick up the custom curve.
- this.q = EC5Util.convertCurve(ellipticCurve).createPoint(spec.getQ().getAffineXCoord().toBigInteger(), spec.getQ().getAffineYCoord().toBigInteger());
+ this.ecPublicKey = new ECPublicKeyParameters(
+ spec.getQ(), ECUtil.getDomainParameters(configuration, spec.getParams()));
this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec.getParams());
}
else
{
- if (q.getCurve() == null)
- {
- org.bouncycastle.jce.spec.ECParameterSpec s = configuration.getEcImplicitlyCa();
+ org.bouncycastle.jce.spec.ECParameterSpec s = configuration.getEcImplicitlyCa();
- q = s.getCurve().createPoint(q.getXCoord().toBigInteger(), q.getYCoord().toBigInteger(), false);
- }
+ this.ecPublicKey = new ECPublicKeyParameters(s.getCurve().createPoint(spec.getQ().getAffineXCoord().toBigInteger(), spec.getQ().getAffineYCoord().toBigInteger()), EC5Util.getDomainParameters(configuration, (ECParameterSpec)null));
this.ecSpec = null;
}
@@ -110,7 +102,7 @@ public class BCECPublicKey
ECDomainParameters dp = params.getParameters();
this.algorithm = algorithm;
- this.q = params.getQ();
+ this.ecPublicKey = params;
if (spec == null)
{
@@ -149,8 +141,7 @@ public class BCECPublicKey
this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec);
}
- this.q = EC5Util.convertCurve(ecSpec.getCurve()).createPoint(params.getQ().getAffineXCoord().toBigInteger(), params.getQ().getAffineYCoord().toBigInteger());
-
+ this.ecPublicKey = params;
this.configuration = configuration;
}
@@ -163,7 +154,7 @@ public class BCECPublicKey
ProviderConfiguration configuration)
{
this.algorithm = algorithm;
- this.q = params.getQ();
+ this.ecPublicKey = params;
this.ecSpec = null;
this.configuration = configuration;
}
@@ -174,7 +165,7 @@ public class BCECPublicKey
{
this.algorithm = key.getAlgorithm();
this.ecSpec = key.getParams();
- this.q = EC5Util.convertPoint(this.ecSpec, key.getW(), false);
+ this.ecPublicKey = new ECPublicKeyParameters(EC5Util.convertPoint(this.ecSpec, key.getW(), false), EC5Util.getDomainParameters(configuration, key.getParams()));
}
BCECPublicKey(
@@ -200,7 +191,7 @@ public class BCECPublicKey
private void populateFromPubKeyInfo(SubjectPublicKeyInfo info)
{
- X962Parameters params = new X962Parameters((ASN1Primitive)info.getAlgorithm().getParameters());
+ X962Parameters params = X962Parameters.getInstance(info.getAlgorithm().getParameters());
ECCurve curve = EC5Util.getCurve(configuration, params);
ecSpec = EC5Util.convertToSpec(params, curve);
@@ -231,7 +222,7 @@ public class BCECPublicKey
X9ECPoint derQ = new X9ECPoint(curve, key);
- this.q = derQ.getPoint();
+ this.ecPublicKey = new ECPublicKeyParameters(derQ.getPoint(), ECUtil.getDomainParameters(configuration, params));
}
public String getAlgorithm()
@@ -246,72 +237,15 @@ public class BCECPublicKey
public byte[] getEncoded()
{
- ASN1Encodable params;
- SubjectPublicKeyInfo info;
-
- if (ecSpec instanceof ECNamedCurveSpec)
- {
- ASN1ObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec)ecSpec).getName());
- if (curveOid == null)
- {
- curveOid = new ASN1ObjectIdentifier(((ECNamedCurveSpec)ecSpec).getName());
- }
- params = new X962Parameters(curveOid);
- }
- else if (ecSpec == null)
- {
- params = new X962Parameters(DERNull.INSTANCE);
- }
- else
- {
- ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve());
-
- X9ECParameters ecP = new X9ECParameters(
- curve,
- EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression),
- ecSpec.getOrder(),
- BigInteger.valueOf(ecSpec.getCofactor()),
- ecSpec.getCurve().getSeed());
-
- params = new X962Parameters(ecP);
- }
-
- ECCurve curve = this.engineGetQ().getCurve();
- ASN1OctetString p;
+ ASN1Encodable params = ECUtils.getDomainParametersFromName(ecSpec, withCompression);
+ ASN1OctetString p = ASN1OctetString.getInstance(new X9ECPoint(ecPublicKey.getQ(), withCompression).toASN1Primitive());
// stored curve is null if ImplicitlyCa
- if (ecSpec == null)
- {
- p = (ASN1OctetString)
- new X9ECPoint(curve.createPoint(this.getQ().getXCoord().toBigInteger(), this.getQ().getYCoord().toBigInteger(), withCompression)).toASN1Primitive();
- }
- else
- {
- p = (ASN1OctetString)
- new X9ECPoint(curve.createPoint(this.getQ().getAffineXCoord().toBigInteger(), this.getQ().getAffineYCoord().toBigInteger(), withCompression)).toASN1Primitive();
- }
-
- info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), p.getOctets());
+ SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), p.getOctets());
return KeyUtil.getEncodedSubjectPublicKeyInfo(info);
}
- private void extractBytes(byte[] encKey, int offSet, BigInteger bI)
- {
- byte[] val = bI.toByteArray();
- if (val.length < 32)
- {
- byte[] tmp = new byte[32];
- System.arraycopy(val, 0, tmp, tmp.length - val.length, val.length);
- val = tmp;
- }
-
- for (int i = 0; i != 32; i++)
- {
- encKey[offSet + i] = val[val.length - 1 - i];
- }
- }
-
public ECParameterSpec getParams()
{
return ecSpec;
@@ -329,11 +263,15 @@ public class BCECPublicKey
public ECPoint getW()
{
+ org.bouncycastle.math.ec.ECPoint q = ecPublicKey.getQ();
+
return new ECPoint(q.getAffineXCoord().toBigInteger(), q.getAffineYCoord().toBigInteger());
}
public org.bouncycastle.math.ec.ECPoint getQ()
{
+ org.bouncycastle.math.ec.ECPoint q = ecPublicKey.getQ();
+
if (ecSpec == null)
{
return q.getDetachedPoint();
@@ -342,9 +280,9 @@ public class BCECPublicKey
return q;
}
- public org.bouncycastle.math.ec.ECPoint engineGetQ()
+ ECPublicKeyParameters engineGetKeyParameters()
{
- return q;
+ return ecPublicKey;
}
org.bouncycastle.jce.spec.ECParameterSpec engineGetSpec()
@@ -361,10 +299,11 @@ public class BCECPublicKey
{
StringBuffer buf = new StringBuffer();
String nl = Strings.lineSeparator();
+ org.bouncycastle.math.ec.ECPoint q = ecPublicKey.getQ();
buf.append("EC Public Key").append(nl);
- buf.append(" X: ").append(this.q.getAffineXCoord().toBigInteger().toString(16)).append(nl);
- buf.append(" Y: ").append(this.q.getAffineYCoord().toBigInteger().toString(16)).append(nl);
+ buf.append(" X: ").append(q.getAffineXCoord().toBigInteger().toString(16)).append(nl);
+ buf.append(" Y: ").append(q.getAffineYCoord().toBigInteger().toString(16)).append(nl);
return buf.toString();
@@ -384,12 +323,12 @@ public class BCECPublicKey
BCECPublicKey other = (BCECPublicKey)o;
- return engineGetQ().equals(other.engineGetQ()) && (engineGetSpec().equals(other.engineGetSpec()));
+ return ecPublicKey.getQ().equals(other.ecPublicKey.getQ()) && (engineGetSpec().equals(other.engineGetSpec()));
}
public int hashCode()
{
- return engineGetQ().hashCode() ^ engineGetSpec().hashCode();
+ return ecPublicKey.getQ().hashCode() ^ engineGetSpec().hashCode();
}
private void readObject(
@@ -400,9 +339,9 @@ public class BCECPublicKey
byte[] enc = (byte[])in.readObject();
- populateFromPubKeyInfo(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc)));
-
this.configuration = BouncyCastleProvider.CONFIGURATION;
+
+ populateFromPubKeyInfo(SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(enc)));
}
private void writeObject(
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
index dc92e0e4..8a5c834c 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/ECUtils.java
@@ -1,13 +1,30 @@
package org.bouncycastle.jcajce.provider.asymmetric.ec;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.PublicKey;
import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECParameterSpec;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.DERNull;
+import org.bouncycastle.asn1.x9.X962Parameters;
import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
+import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+import org.bouncycastle.jce.spec.ECNamedCurveSpec;
+import org.bouncycastle.math.ec.ECCurve;
class ECUtils
{
+ static AsymmetricKeyParameter generatePublicKeyParameter(
+ PublicKey key)
+ throws InvalidKeyException
+ {
+ return (key instanceof BCECPublicKey) ? ((BCECPublicKey)key).engineGetKeyParameters() : ECUtil.generatePublicKeyParameter(key);
+ }
+
static X9ECParameters getDomainParametersFromGenSpec(ECGenParameterSpec genSpec)
{
return getDomainParametersFromName(genSpec.getName());
@@ -42,4 +59,38 @@ class ECUtils
}
return domainParameters;
}
+
+ static X962Parameters getDomainParametersFromName(ECParameterSpec ecSpec, boolean withCompression)
+ {
+ X962Parameters params;
+
+ if (ecSpec instanceof ECNamedCurveSpec)
+ {
+ ASN1ObjectIdentifier curveOid = ECUtil.getNamedCurveOid(((ECNamedCurveSpec)ecSpec).getName());
+ if (curveOid == null)
+ {
+ curveOid = new ASN1ObjectIdentifier(((ECNamedCurveSpec)ecSpec).getName());
+ }
+ params = new X962Parameters(curveOid);
+ }
+ else if (ecSpec == null)
+ {
+ params = new X962Parameters(DERNull.INSTANCE);
+ }
+ else
+ {
+ ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve());
+
+ X9ECParameters ecP = new X9ECParameters(
+ curve,
+ EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression),
+ ecSpec.getOrder(),
+ BigInteger.valueOf(ecSpec.getCofactor()),
+ ecSpec.getCurve().getSeed());
+
+ params = new X962Parameters(ecP);
+ }
+
+ return params;
+ }
}
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 004e2873..5d8e6b18 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
@@ -18,13 +18,6 @@ import org.bouncycastle.crypto.agreement.ECDHBasicAgreement;
// import org.bouncycastle.crypto.agreement.ECDHCBasicAgreement;
// import org.bouncycastle.crypto.agreement.ECMQVBasicAgreement;
// import org.bouncycastle.crypto.agreement.kdf.ConcatenationKDFGenerator;
-// END android-removed
-import org.bouncycastle.crypto.digests.SHA1Digest;
-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;
@@ -33,6 +26,7 @@ import org.bouncycastle.crypto.params.ECPublicKeyParameters;
// BEGIN android-removed
// import org.bouncycastle.crypto.params.MQVPrivateParameters;
// import org.bouncycastle.crypto.params.MQVPublicParameters;
+// import org.bouncycastle.crypto.util.DigestFactory;
// END android-removed
import org.bouncycastle.jcajce.provider.asymmetric.util.BaseAgreementSpi;
import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
@@ -66,6 +60,7 @@ public class KeyAgreementSpi
// BEGIN android-removed
// private MQVParameterSpec mqvParameters;
// END android-removed
+ private BigInteger result;
protected KeyAgreementSpi(
String kaAlgorithm,
@@ -106,9 +101,9 @@ public class KeyAgreementSpi
// if (!(key instanceof MQVPublicKey))
// {
// ECPublicKeyParameters staticKey = (ECPublicKeyParameters)
- // ECUtil.generatePublicKeyParameter((PublicKey)key);
+ // ECUtils.generatePublicKeyParameter((PublicKey)key);
// ECPublicKeyParameters ephemKey = (ECPublicKeyParameters)
- // ECUtil.generatePublicKeyParameter(mqvParameters.getOtherPartyEphemeralKey());
+ // ECUtils.generatePublicKeyParameter(mqvParameters.getOtherPartyEphemeralKey());
//
// pubKey = new MQVPublicParameters(staticKey, ephemKey);
// }
@@ -116,13 +111,11 @@ public class KeyAgreementSpi
// {
// MQVPublicKey mqvPubKey = (MQVPublicKey)key;
// ECPublicKeyParameters staticKey = (ECPublicKeyParameters)
- // ECUtil.generatePublicKeyParameter(mqvPubKey.getStaticKey());
+ // ECUtils.generatePublicKeyParameter(mqvPubKey.getStaticKey());
// ECPublicKeyParameters ephemKey = (ECPublicKeyParameters)
- // ECUtil.generatePublicKeyParameter(mqvPubKey.getEphemeralKey());
+ // ECUtils.generatePublicKeyParameter(mqvPubKey.getEphemeralKey());
//
// pubKey = new MQVPublicParameters(staticKey, ephemKey);
- //
- // // TODO Validate that all the keys are using the same parameters?
// }
// }
// else
@@ -134,21 +127,27 @@ public class KeyAgreementSpi
+ getSimpleName(ECPublicKey.class) + " for doPhase");
}
- pubKey = ECUtil.generatePublicKeyParameter((PublicKey)key);
-
- // TODO Validate that all the keys are using the same parameters?
+ pubKey = ECUtils.generatePublicKeyParameter((PublicKey)key);
}
- // BEGIN android-added
- try {
- // END android-added
- result = agreement.calculateAgreement(pubKey);
- // BEGIN android-added
+ try
+ {
+ result = agreement.calculateAgreement(pubKey);
+ // BEGIN android-changed
+ // Was:
+ // } catch (final Exception e) {
+ // throw new InvalidKeyException("calculation failed: " + e.getMessage())
+ // {
+ // public Throwable getCause()
+ // {
+ // return e;
+ // }
+ // };
+ // }
+ // END android-changed
} catch (IllegalStateException e) {
- throw new InvalidKeyException("Invalid public key");
+ throw new InvalidKeyException("Invalid public key");
}
- // END android-added
-
return null;
}
@@ -170,7 +169,7 @@ public class KeyAgreementSpi
protected void engineInit(
Key key,
- SecureRandom random)
+ SecureRandom random)
throws InvalidKeyException
{
initFromKey(key, null);
@@ -204,7 +203,7 @@ public class KeyAgreementSpi
// if (mqvPrivKey.getEphemeralPublicKey() != null)
// {
// ephemPubKey = (ECPublicKeyParameters)
- // ECUtil.generatePublicKeyParameter(mqvPrivKey.getEphemeralPublicKey());
+ // ECUtils.generatePublicKeyParameter(mqvPrivKey.getEphemeralPublicKey());
// }
// }
// else
@@ -220,7 +219,7 @@ public class KeyAgreementSpi
// if (mqvParameterSpec.getEphemeralPublicKey() != null)
// {
// ephemPubKey = (ECPublicKeyParameters)
- // ECUtil.generatePublicKeyParameter(mqvParameterSpec.getEphemeralPublicKey());
+ // ECUtils.generatePublicKeyParameter(mqvParameterSpec.getEphemeralPublicKey());
// }
// mqvParameters = mqvParameterSpec;
// ukmParameters = mqvParameterSpec.getUserKeyingMaterial();
@@ -256,6 +255,12 @@ public class KeyAgreementSpi
return fullName.substring(fullName.lastIndexOf('.') + 1);
}
+
+ protected byte[] calcSecret()
+ {
+ return bigIntToBytes(result);
+ }
+
public static class DH
extends KeyAgreementSpi
{
@@ -274,7 +279,7 @@ public class KeyAgreementSpi
// super("ECDHC", new ECDHCBasicAgreement(), null);
// }
// }
- //
+
// public static class MQV
// extends KeyAgreementSpi
// {
@@ -283,229 +288,230 @@ public class KeyAgreementSpi
// super("ECMQV", new ECMQVBasicAgreement(), null);
// }
// }
- //
+
// public static class DHwithSHA1KDF
// extends KeyAgreementSpi
// {
// public DHwithSHA1KDF()
// {
- // super("ECDHwithSHA1KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()));
+ // super("ECDHwithSHA1KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA1()));
// }
// }
- //
+
// public static class DHwithSHA1KDFAndSharedInfo
// extends KeyAgreementSpi
// {
// public DHwithSHA1KDFAndSharedInfo()
// {
- // super("ECDHwithSHA1KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()));
+ // super("ECDHwithSHA1KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA1()));
// }
// }
- //
+
// public static class CDHwithSHA1KDFAndSharedInfo
// extends KeyAgreementSpi
// {
// public CDHwithSHA1KDFAndSharedInfo()
// {
- // super("ECCDHwithSHA1KDF", new ECDHCBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()));
+ // super("ECCDHwithSHA1KDF", new ECDHCBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA1()));
// }
// }
- //
+
// public static class DHwithSHA224KDFAndSharedInfo
// extends KeyAgreementSpi
// {
// public DHwithSHA224KDFAndSharedInfo()
// {
- // super("ECDHwithSHA224KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA224Digest()));
+ // super("ECDHwithSHA224KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA224()));
// }
// }
- //
+
// public static class CDHwithSHA224KDFAndSharedInfo
// extends KeyAgreementSpi
// {
// public CDHwithSHA224KDFAndSharedInfo()
// {
- // super("ECCDHwithSHA224KDF", new ECDHCBasicAgreement(), new KDF2BytesGenerator(new SHA224Digest()));
+ // super("ECCDHwithSHA224KDF", new ECDHCBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA224()));
// }
// }
- //
+
// public static class DHwithSHA256KDFAndSharedInfo
// extends KeyAgreementSpi
// {
// public DHwithSHA256KDFAndSharedInfo()
// {
- // super("ECDHwithSHA256KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA256Digest()));
+ // super("ECDHwithSHA256KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA256()));
// }
// }
- //
+
// public static class CDHwithSHA256KDFAndSharedInfo
// extends KeyAgreementSpi
// {
// public CDHwithSHA256KDFAndSharedInfo()
// {
- // super("ECCDHwithSHA256KDF", new ECDHCBasicAgreement(), new KDF2BytesGenerator(new SHA256Digest()));
+ // super("ECCDHwithSHA256KDF", new ECDHCBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA256()));
// }
// }
- //
+
// public static class DHwithSHA384KDFAndSharedInfo
// extends KeyAgreementSpi
// {
// public DHwithSHA384KDFAndSharedInfo()
// {
- // super("ECDHwithSHA384KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA384Digest()));
+ // super("ECDHwithSHA384KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA384()));
// }
// }
- //
+
// public static class CDHwithSHA384KDFAndSharedInfo
// extends KeyAgreementSpi
// {
// public CDHwithSHA384KDFAndSharedInfo()
// {
- // super("ECCDHwithSHA384KDF", new ECDHCBasicAgreement(), new KDF2BytesGenerator(new SHA384Digest()));
+ // super("ECCDHwithSHA384KDF", new ECDHCBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA384()));
// }
// }
- //
+
// public static class DHwithSHA512KDFAndSharedInfo
// extends KeyAgreementSpi
// {
// public DHwithSHA512KDFAndSharedInfo()
// {
- // super("ECDHwithSHA512KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(new SHA512Digest()));
+ // super("ECDHwithSHA512KDF", new ECDHBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA512()));
// }
// }
- //
+
// public static class CDHwithSHA512KDFAndSharedInfo
// extends KeyAgreementSpi
// {
// public CDHwithSHA512KDFAndSharedInfo()
// {
- // super("ECCDHwithSHA512KDF", new ECDHCBasicAgreement(), new KDF2BytesGenerator(new SHA512Digest()));
+ // super("ECCDHwithSHA512KDF", new ECDHCBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA512()));
// }
// }
- //
+
// public static class MQVwithSHA1KDFAndSharedInfo
// extends KeyAgreementSpi
// {
// public MQVwithSHA1KDFAndSharedInfo()
// {
- // super("ECMQVwithSHA1KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()));
+ // super("ECMQVwithSHA1KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA1()));
// }
// }
- //
+
// public static class MQVwithSHA224KDFAndSharedInfo
// extends KeyAgreementSpi
// {
// public MQVwithSHA224KDFAndSharedInfo()
// {
- // super("ECMQVwithSHA224KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(new SHA224Digest()));
+ // super("ECMQVwithSHA224KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA224()));
// }
// }
- //
+
// public static class MQVwithSHA256KDFAndSharedInfo
// extends KeyAgreementSpi
// {
// public MQVwithSHA256KDFAndSharedInfo()
// {
- // super("ECMQVwithSHA256KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(new SHA256Digest()));
+ // super("ECMQVwithSHA256KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA256()));
// }
// }
- //
+
// public static class MQVwithSHA384KDFAndSharedInfo
// extends KeyAgreementSpi
// {
// public MQVwithSHA384KDFAndSharedInfo()
// {
- // super("ECMQVwithSHA384KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(new SHA384Digest()));
+ // super("ECMQVwithSHA384KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA384()));
// }
// }
- //
+
// public static class MQVwithSHA512KDFAndSharedInfo
// extends KeyAgreementSpi
// {
// public MQVwithSHA512KDFAndSharedInfo()
// {
- // super("ECMQVwithSHA512KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(new SHA512Digest()));
+ // super("ECMQVwithSHA512KDF", new ECMQVBasicAgreement(), new KDF2BytesGenerator(DigestFactory.createSHA512()));
// }
// }
- //
+
// public static class DHwithSHA1CKDF
// extends KeyAgreementSpi
// {
// public DHwithSHA1CKDF()
// {
- // super("ECDHwithSHA1CKDF", new ECDHCBasicAgreement(), new ConcatenationKDFGenerator(new SHA1Digest()));
+ // super("ECDHwithSHA1CKDF", new ECDHCBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA1()));
// }
// }
- //
+
// public static class DHwithSHA256CKDF
// extends KeyAgreementSpi
// {
// public DHwithSHA256CKDF()
// {
- // super("ECDHwithSHA256CKDF", new ECDHCBasicAgreement(), new ConcatenationKDFGenerator(new SHA256Digest()));
+ // super("ECDHwithSHA256CKDF", new ECDHCBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA256()));
// }
// }
- //
+
// public static class DHwithSHA384CKDF
// extends KeyAgreementSpi
// {
// public DHwithSHA384CKDF()
// {
- // super("ECDHwithSHA384CKDF", new ECDHCBasicAgreement(), new ConcatenationKDFGenerator(new SHA384Digest()));
+ // super("ECDHwithSHA384CKDF", new ECDHCBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA384()));
// }
// }
- //
+
// public static class DHwithSHA512CKDF
// extends KeyAgreementSpi
// {
// public DHwithSHA512CKDF()
// {
- // super("ECDHwithSHA512CKDF", new ECDHCBasicAgreement(), new ConcatenationKDFGenerator(new SHA512Digest()));
+ // super("ECDHwithSHA512CKDF", new ECDHCBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA512()));
// }
// }
- //
+
// public static class MQVwithSHA1CKDF
// extends KeyAgreementSpi
// {
// public MQVwithSHA1CKDF()
// {
- // super("ECMQVwithSHA1CKDF", new ECMQVBasicAgreement(), new ConcatenationKDFGenerator(new SHA1Digest()));
+ // super("ECMQVwithSHA1CKDF", new ECMQVBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA1()));
// }
// }
- //
+
// public static class MQVwithSHA224CKDF
// extends KeyAgreementSpi
// {
// public MQVwithSHA224CKDF()
// {
- // super("ECMQVwithSHA224CKDF", new ECMQVBasicAgreement(), new ConcatenationKDFGenerator(new SHA224Digest()));
+ // super("ECMQVwithSHA224CKDF", new ECMQVBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA224()));
// }
// }
- //
+
// public static class MQVwithSHA256CKDF
// extends KeyAgreementSpi
// {
// public MQVwithSHA256CKDF()
// {
- // super("ECMQVwithSHA256CKDF", new ECMQVBasicAgreement(), new ConcatenationKDFGenerator(new SHA256Digest()));
+ // super("ECMQVwithSHA256CKDF", new ECMQVBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA256()));
// }
// }
- //
+
// public static class MQVwithSHA384CKDF
// extends KeyAgreementSpi
// {
// public MQVwithSHA384CKDF()
// {
- // super("ECMQVwithSHA384CKDF", new ECMQVBasicAgreement(), new ConcatenationKDFGenerator(new SHA384Digest()));
+ // super("ECMQVwithSHA384CKDF", new ECMQVBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA384()));
// }
// }
- //
+
// public static class MQVwithSHA512CKDF
// extends KeyAgreementSpi
// {
// public MQVwithSHA512CKDF()
// {
- // super("ECMQVwithSHA512CKDF", new ECMQVBasicAgreement(), new ConcatenationKDFGenerator(new SHA512Digest()));
+ // super("ECMQVwithSHA512CKDF", new ECMQVBasicAgreement(), new ConcatenationKDFGenerator(DigestFactory.createSHA512()));
// }
// }
+ // END android-removed
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
index 5769bacc..a749f114 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/KeyFactorySpi.java
@@ -141,13 +141,20 @@ public class KeyFactorySpi
KeySpec keySpec)
throws InvalidKeySpecException
{
- if (keySpec instanceof ECPublicKeySpec)
+ try
{
- return new BCECPublicKey(algorithm, (ECPublicKeySpec)keySpec, configuration);
+ if (keySpec instanceof ECPublicKeySpec)
+ {
+ return new BCECPublicKey(algorithm, (ECPublicKeySpec)keySpec, configuration);
+ }
+ else if (keySpec instanceof java.security.spec.ECPublicKeySpec)
+ {
+ return new BCECPublicKey(algorithm, (java.security.spec.ECPublicKeySpec)keySpec, configuration);
+ }
}
- else if (keySpec instanceof java.security.spec.ECPublicKeySpec)
+ catch (Exception e)
{
- return new BCECPublicKey(algorithm, (java.security.spec.ECPublicKeySpec)keySpec, configuration);
+ throw new InvalidKeySpecException("invalid KeySpec: " + e.getMessage(), e);
}
return super.engineGeneratePublic(keySpec);
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 9a9c46be..5f8a901e 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
@@ -8,6 +8,7 @@ import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.ECGenParameterSpec;
import java.util.Hashtable;
+import java.util.Map;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
@@ -194,7 +195,7 @@ public abstract class KeyPairGeneratorSpi
protected ECKeyGenerationParameters createKeyGenParamsBC(ECParameterSpec p, SecureRandom r)
{
- return new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN()), r);
+ return new ECKeyGenerationParameters(new ECDomainParameters(p.getCurve(), p.getG(), p.getN(), p.getH()), r);
}
protected ECKeyGenerationParameters createKeyGenParamsJCE(java.security.spec.ECParameterSpec p, SecureRandom r)
@@ -221,7 +222,14 @@ public abstract class KeyPairGeneratorSpi
p = ECNamedCurveTable.getByOID(new ASN1ObjectIdentifier(curveName));
if (p == null)
{
- throw new InvalidAlgorithmParameterException("unknown curve OID: " + curveName);
+ Map extraCurves = configuration.getAdditionalECParameters();
+
+ p = (X9ECParameters)extraCurves.get(new ASN1ObjectIdentifier(curveName));
+
+ if (p == null)
+ {
+ throw new InvalidAlgorithmParameterException("unknown curve OID: " + curveName);
+ }
}
}
catch (IllegalArgumentException ex)
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
index 26811d18..46aeec7e 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java
@@ -21,21 +21,18 @@ import org.bouncycastle.crypto.digests.AndroidDigestFactory;
// END android-added
// BEGIN android-removed
// import org.bouncycastle.crypto.digests.RIPEMD160Digest;
-// import org.bouncycastle.crypto.digests.SHA1Digest;
-// import org.bouncycastle.crypto.digests.SHA224Digest;
-// import org.bouncycastle.crypto.digests.SHA256Digest;
-// import org.bouncycastle.crypto.digests.SHA384Digest;
-// import org.bouncycastle.crypto.digests.SHA512Digest;
// END android-removed
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.crypto.signers.ECDSASigner;
// BEGIN android-removed
// import org.bouncycastle.crypto.signers.ECNRSigner;
// import org.bouncycastle.crypto.signers.HMacDSAKCalculator;
+// import org.bouncycastle.crypto.util.DigestFactory;
// END android-removed
import org.bouncycastle.jcajce.provider.asymmetric.util.DSABase;
import org.bouncycastle.jcajce.provider.asymmetric.util.DSAEncoder;
import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+import org.bouncycastle.util.Arrays;
public class SignatureSpi
extends DSABase
@@ -48,7 +45,7 @@ public class SignatureSpi
protected void engineInitVerify(PublicKey publicKey)
throws InvalidKeyException
{
- CipherParameters param = ECUtil.generatePublicKeyParameter(publicKey);
+ CipherParameters param = ECUtils.generatePublicKeyParameter(publicKey);
digest.reset();
signer.init(false, param);
@@ -89,7 +86,7 @@ public class SignatureSpi
// {
// public ecDetDSA()
// {
- // super(new SHA1Digest(), new ECDSASigner(new HMacDSAKCalculator(new SHA1Digest())), new StdDSAEncoder());
+ // super(DigestFactory.createSHA1(), new ECDSASigner(new HMacDSAKCalculator(DigestFactory.createSHA1())), new StdDSAEncoder());
// }
// }
// END android-removed
@@ -120,7 +117,7 @@ public class SignatureSpi
// {
// public ecDetDSA224()
// {
- // super(new SHA224Digest(), new ECDSASigner(new HMacDSAKCalculator(new SHA224Digest())), new StdDSAEncoder());
+ // super(DigestFactory.createSHA224(), new ECDSASigner(new HMacDSAKCalculator(DigestFactory.createSHA224())), new StdDSAEncoder());
// }
// }
// END android-removed
@@ -142,7 +139,7 @@ public class SignatureSpi
// {
// public ecDetDSA256()
// {
- // super(new SHA256Digest(), new ECDSASigner(new HMacDSAKCalculator(new SHA256Digest())), new StdDSAEncoder());
+ // super(DigestFactory.createSHA256(), new ECDSASigner(new HMacDSAKCalculator(DigestFactory.createSHA256())), new StdDSAEncoder());
// }
// }
// END android-removed
@@ -164,11 +161,10 @@ public class SignatureSpi
// {
// public ecDetDSA384()
// {
- // super(new SHA384Digest(), new ECDSASigner(new HMacDSAKCalculator(new SHA384Digest())), new StdDSAEncoder());
+ // super(DigestFactory.createSHA384(), new ECDSASigner(new HMacDSAKCalculator(DigestFactory.createSHA384())), new StdDSAEncoder());
// }
// }
// END android-removed
-
static public class ecDSA512
extends SignatureSpi
{
@@ -186,10 +182,82 @@ public class SignatureSpi
// {
// public ecDetDSA512()
// {
- // super(new SHA512Digest(), new ECDSASigner(new HMacDSAKCalculator(new SHA512Digest())), new StdDSAEncoder());
+ // super(DigestFactory.createSHA512(), new ECDSASigner(new HMacDSAKCalculator(DigestFactory.createSHA512())), new StdDSAEncoder());
// }
// }
- //
+
+ // static public class ecDSASha3_224
+ // extends SignatureSpi
+ // {
+ // public ecDSASha3_224()
+ // {
+ // super(DigestFactory.createSHA3_224(), new ECDSASigner(), new StdDSAEncoder());
+ // }
+ // }
+
+ // static public class ecDetDSASha3_224
+ // extends SignatureSpi
+ // {
+ // public ecDetDSASha3_224()
+ // {
+ // super(DigestFactory.createSHA3_224(), new ECDSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_224())), new StdDSAEncoder());
+ // }
+ // }
+
+ // static public class ecDSASha3_256
+ // extends SignatureSpi
+ // {
+ // public ecDSASha3_256()
+ // {
+ // super(DigestFactory.createSHA3_256(), new ECDSASigner(), new StdDSAEncoder());
+ // }
+ // }
+
+ // static public class ecDetDSASha3_256
+ // extends SignatureSpi
+ // {
+ // public ecDetDSASha3_256()
+ // {
+ // super(DigestFactory.createSHA3_256(), new ECDSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_256())), new StdDSAEncoder());
+ // }
+ // }
+
+ // static public class ecDSASha3_384
+ // extends SignatureSpi
+ // {
+ // public ecDSASha3_384()
+ // {
+ // super(DigestFactory.createSHA3_384(), new ECDSASigner(), new StdDSAEncoder());
+ // }
+ // }
+
+ // static public class ecDetDSASha3_384
+ // extends SignatureSpi
+ // {
+ // public ecDetDSASha3_384()
+ // {
+ // super(DigestFactory.createSHA3_384(), new ECDSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_384())), new StdDSAEncoder());
+ // }
+ // }
+
+ // static public class ecDSASha3_512
+ // extends SignatureSpi
+ // {
+ // public ecDSASha3_512()
+ // {
+ // super(DigestFactory.createSHA3_512(), new ECDSASigner(), new StdDSAEncoder());
+ // }
+ // }
+
+ // static public class ecDetDSASha3_512
+ // extends SignatureSpi
+ // {
+ // public ecDetDSASha3_512()
+ // {
+ // super(DigestFactory.createSHA3_512(), new ECDSASigner(new HMacDSAKCalculator(DigestFactory.createSHA3_512())), new StdDSAEncoder());
+ // }
+ // }
+
// static public class ecDSARipeMD160
// extends SignatureSpi
// {
@@ -198,97 +266,97 @@ public class SignatureSpi
// super(new RIPEMD160Digest(), new ECDSASigner(), new StdDSAEncoder());
// }
// }
- //
+
// static public class ecNR
// extends SignatureSpi
// {
// public ecNR()
// {
- // super(new SHA1Digest(), new ECNRSigner(), new StdDSAEncoder());
+ // super(DigestFactory.createSHA1(), new ECNRSigner(), new StdDSAEncoder());
// }
// }
- //
+
// static public class ecNR224
// extends SignatureSpi
// {
// public ecNR224()
// {
- // super(new SHA224Digest(), new ECNRSigner(), new StdDSAEncoder());
+ // super(DigestFactory.createSHA224(), new ECNRSigner(), new StdDSAEncoder());
// }
// }
- //
+
// static public class ecNR256
// extends SignatureSpi
// {
// public ecNR256()
// {
- // super(new SHA256Digest(), new ECNRSigner(), new StdDSAEncoder());
+ // super(DigestFactory.createSHA256(), new ECNRSigner(), new StdDSAEncoder());
// }
// }
- //
+
// static public class ecNR384
// extends SignatureSpi
// {
// public ecNR384()
// {
- // super(new SHA384Digest(), new ECNRSigner(), new StdDSAEncoder());
+ // super(DigestFactory.createSHA384(), new ECNRSigner(), new StdDSAEncoder());
// }
// }
- //
+
// static public class ecNR512
// extends SignatureSpi
// {
// public ecNR512()
// {
- // super(new SHA512Digest(), new ECNRSigner(), new StdDSAEncoder());
+ // super(DigestFactory.createSHA512(), new ECNRSigner(), new StdDSAEncoder());
// }
// }
- //
+
// static public class ecCVCDSA
// extends SignatureSpi
// {
// public ecCVCDSA()
// {
- // super(new SHA1Digest(), new ECDSASigner(), new PlainDSAEncoder());
+ // super(DigestFactory.createSHA1(), new ECDSASigner(), new PlainDSAEncoder());
// }
// }
- //
+
// static public class ecCVCDSA224
// extends SignatureSpi
// {
// public ecCVCDSA224()
// {
- // super(new SHA224Digest(), new ECDSASigner(), new PlainDSAEncoder());
+ // super(DigestFactory.createSHA224(), new ECDSASigner(), new PlainDSAEncoder());
// }
// }
- //
+
// static public class ecCVCDSA256
// extends SignatureSpi
// {
// public ecCVCDSA256()
// {
- // super(new SHA256Digest(), new ECDSASigner(), new PlainDSAEncoder());
+ // super(DigestFactory.createSHA256(), new ECDSASigner(), new PlainDSAEncoder());
// }
// }
- //
+
// static public class ecCVCDSA384
// extends SignatureSpi
// {
// public ecCVCDSA384()
// {
- // super(new SHA384Digest(), new ECDSASigner(), new PlainDSAEncoder());
+ // super(DigestFactory.createSHA384(), new ECDSASigner(), new PlainDSAEncoder());
// }
// }
- //
+
// static public class ecCVCDSA512
// extends SignatureSpi
// {
// public ecCVCDSA512()
// {
- // super(new SHA512Digest(), new ECDSASigner(), new PlainDSAEncoder());
+ // super(DigestFactory.createSHA512(), new ECDSASigner(), new PlainDSAEncoder());
// }
// }
- //
+
// static public class ecPlainDSARP160
// extends SignatureSpi
// {
@@ -320,6 +388,15 @@ public class SignatureSpi
throws IOException
{
ASN1Sequence s = (ASN1Sequence)ASN1Primitive.fromByteArray(encoding);
+ if (s.size() != 2)
+ {
+ throw new IOException("malformed signature");
+ }
+ if (!Arrays.areEqual(encoding, s.getEncoded(ASN1Encoding.DER)))
+ {
+ throw new IOException("malformed signature");
+ }
+
BigInteger[] sig = new BigInteger[2];
sig[0] = ASN1Integer.getInstance(s.getObjectAt(0)).getValue();
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 de5a9aa5..e60c36ae 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
@@ -19,6 +19,7 @@ import org.bouncycastle.asn1.pkcs.RSAESOAEPparams;
import org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.jcajce.provider.util.DigestFactory;
+import org.bouncycastle.jcajce.util.MessageDigestUtils;
public abstract class AlgorithmParametersSpi
extends java.security.AlgorithmParametersSpi
@@ -118,10 +119,15 @@ public abstract class AlgorithmParametersSpi
{
RSAESOAEPparams oaepP = RSAESOAEPparams.getInstance(params);
+ if (!oaepP.getMaskGenAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.id_mgf1))
+ {
+ throw new IOException("unknown mask generation function: " + oaepP.getMaskGenAlgorithm().getAlgorithm());
+ }
+
currentSpec = new OAEPParameterSpec(
- oaepP.getHashAlgorithm().getAlgorithm().getId(),
- oaepP.getMaskGenAlgorithm().getAlgorithm().getId(),
- new MGF1ParameterSpec(AlgorithmIdentifier.getInstance(oaepP.getMaskGenAlgorithm().getParameters()).getAlgorithm().getId()),
+ MessageDigestUtils.getDigestName(oaepP.getHashAlgorithm().getAlgorithm()),
+ OAEPParameterSpec.DEFAULT.getMGFAlgorithm(),
+ new MGF1ParameterSpec(MessageDigestUtils.getDigestName(AlgorithmIdentifier.getInstance(oaepP.getMaskGenAlgorithm().getParameters()).getAlgorithm())),
new PSource.PSpecified(ASN1OctetString.getInstance(oaepP.getPSourceAlgorithm().getParameters()).getOctets()));
}
catch (ClassCastException e)
@@ -133,7 +139,7 @@ public abstract class AlgorithmParametersSpi
throw new IOException("Not a valid OAEP Parameter encoding.");
}
}
-
+
protected void engineInit(
byte[] params,
String format)
@@ -225,10 +231,15 @@ public abstract class AlgorithmParametersSpi
{
RSASSAPSSparams pssP = RSASSAPSSparams.getInstance(params);
+ if (!pssP.getMaskGenAlgorithm().getAlgorithm().equals(PKCSObjectIdentifiers.id_mgf1))
+ {
+ throw new IOException("unknown mask generation function: " + pssP.getMaskGenAlgorithm().getAlgorithm());
+ }
+
currentSpec = new PSSParameterSpec(
- pssP.getHashAlgorithm().getAlgorithm().getId(),
- pssP.getMaskGenAlgorithm().getAlgorithm().getId(),
- new MGF1ParameterSpec(AlgorithmIdentifier.getInstance(pssP.getMaskGenAlgorithm().getParameters()).getAlgorithm().getId()),
+ MessageDigestUtils.getDigestName(pssP.getHashAlgorithm().getAlgorithm()),
+ PSSParameterSpec.DEFAULT.getMGFAlgorithm(),
+ new MGF1ParameterSpec(MessageDigestUtils.getDigestName(AlgorithmIdentifier.getInstance(pssP.getMaskGenAlgorithm().getParameters()).getAlgorithm())),
pssP.getSaltLength().intValue(),
pssP.getTrailerField().intValue());
}
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 81e50132..c98b764c 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
@@ -34,6 +34,7 @@ import org.bouncycastle.crypto.encodings.PKCS1Encoding;
import org.bouncycastle.crypto.engines.RSABlindedEngine;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.jcajce.provider.asymmetric.util.BaseCipherSpi;
+import org.bouncycastle.jcajce.provider.util.BadBlockException;
import org.bouncycastle.jcajce.provider.util.DigestFactory;
import org.bouncycastle.jcajce.util.BCJcaJceHelper;
import org.bouncycastle.jcajce.util.JcaJceHelper;
@@ -236,9 +237,27 @@ public class CipherSpi
{
initFromSpec(new OAEPParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512, PSource.PSpecified.DEFAULT));
}
+ // BEGIN android-removed
+ // else if (pad.equals("OAEPWITHSHA3-224ANDMGF1PADDING"))
+ // {
+ // initFromSpec(new OAEPParameterSpec("SHA3-224", "MGF1", new MGF1ParameterSpec("SHA3-224"), PSource.PSpecified.DEFAULT));
+ // }
+ // else if (pad.equals("OAEPWITHSHA3-256ANDMGF1PADDING"))
+ // {
+ // initFromSpec(new OAEPParameterSpec("SHA3-256", "MGF1", new MGF1ParameterSpec("SHA3-256"), PSource.PSpecified.DEFAULT));
+ // }
+ // else if (pad.equals("OAEPWITHSHA3-384ANDMGF1PADDING"))
+ // {
+ // initFromSpec(new OAEPParameterSpec("SHA3-384", "MGF1", new MGF1ParameterSpec("SHA3-384"), PSource.PSpecified.DEFAULT));
+ // }
+ // else if (pad.equals("OAEPWITHSHA3-512ANDMGF1PADDING"))
+ // {
+ // initFromSpec(new OAEPParameterSpec("SHA3-512", "MGF1", new MGF1ParameterSpec("SHA3-512"), PSource.PSpecified.DEFAULT));
+ // }
+ // END android-removed
else
{
- throw new NoSuchPaddingException(padding + " unavailable with RSA.");
+ throw new NoSuchPaddingException(padding + " unavailable with RSA.");
}
}
@@ -308,7 +327,7 @@ public class CipherSpi
{
throw new InvalidAlgorithmParameterException("no match on MGF digest algorithm: "+ mgfParams.getDigestAlgorithm());
}
-
+
cipher = new OAEPEncoding(new RSABlindedEngine(), digest, mgfDigest, ((PSource.PSpecified)spec.getPSource()).getValue());
}
}
@@ -466,18 +485,7 @@ public class CipherSpi
}
}
- try
- {
- byte[] bytes = bOut.toByteArray();
-
- bOut.reset();
-
- return cipher.processBlock(bytes, 0, bytes.length);
- }
- catch (InvalidCipherTextException e)
- {
- throw new BadPaddingException(e.getMessage());
- }
+ return getOutput();
}
protected int engineDoFinal(
@@ -508,29 +516,37 @@ public class CipherSpi
}
}
- byte[] out;
+ byte[] out = getOutput();
+ for (int i = 0; i != out.length; i++)
+ {
+ output[outputOffset + i] = out[i];
+ }
+
+ return out.length;
+ }
+
+ private byte[] getOutput()
+ throws BadPaddingException
+ {
try
{
byte[] bytes = bOut.toByteArray();
- out = cipher.processBlock(bytes, 0, bytes.length);
+ return cipher.processBlock(bytes, 0, bytes.length);
}
catch (InvalidCipherTextException e)
{
- throw new BadPaddingException(e.getMessage());
+ throw new BadBlockException("unable to decrypt block", e);
}
- finally
+ catch (ArrayIndexOutOfBoundsException e)
{
- bOut.reset();
+ throw new BadBlockException("unable to decrypt block", e);
}
-
- for (int i = 0; i != out.length; i++)
+ finally
{
- output[outputOffset + i] = out[i];
+ bOut.reset();
}
-
- return out.length;
}
/**
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 9616a99b..1e4d854b 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
@@ -31,20 +31,16 @@ import org.bouncycastle.crypto.digests.AndroidDigestFactory;
// BEGIN android-removed
// import org.bouncycastle.crypto.digests.MD2Digest;
// import org.bouncycastle.crypto.digests.MD4Digest;
-// import org.bouncycastle.crypto.digests.MD5Digest;
// import org.bouncycastle.crypto.digests.NullDigest;
// import org.bouncycastle.crypto.digests.RIPEMD128Digest;
// import org.bouncycastle.crypto.digests.RIPEMD160Digest;
// import org.bouncycastle.crypto.digests.RIPEMD256Digest;
-// import org.bouncycastle.crypto.digests.SHA1Digest;
-// import org.bouncycastle.crypto.digests.SHA224Digest;
-// 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
import org.bouncycastle.crypto.encodings.PKCS1Encoding;
import org.bouncycastle.crypto.engines.RSABlindedEngine;
+// BEGIN android-removed
+// import org.bouncycastle.crypto.util.DigestFactory;
+// END android-removed
import org.bouncycastle.util.Arrays;
public class DigestSignatureSpi
@@ -318,7 +314,7 @@ public class DigestSignatureSpi
// {
// public SHA512_224()
// {
- // super(NISTObjectIdentifiers.id_sha512_224, new SHA512tDigest(224), new PKCS1Encoding(new RSABlindedEngine()));
+ // super(NISTObjectIdentifiers.id_sha512_224, DigestFactory.createSHA512_224(), new PKCS1Encoding(new RSABlindedEngine()));
// }
// }
@@ -327,7 +323,43 @@ public class DigestSignatureSpi
// {
// public SHA512_256()
// {
- // super(NISTObjectIdentifiers.id_sha512_256, new SHA512tDigest(256), new PKCS1Encoding(new RSABlindedEngine()));
+ // super(NISTObjectIdentifiers.id_sha512_256, DigestFactory.createSHA512_256(), new PKCS1Encoding(new RSABlindedEngine()));
+ // }
+ // }
+
+ // static public class SHA3_224
+ // extends DigestSignatureSpi
+ // {
+ // public SHA3_224()
+ // {
+ // super(NISTObjectIdentifiers.id_sha3_224, DigestFactory.createSHA3_224(), new PKCS1Encoding(new RSABlindedEngine()));
+ // }
+ // }
+
+ // static public class SHA3_256
+ // extends DigestSignatureSpi
+ // {
+ // public SHA3_256()
+ // {
+ // super(NISTObjectIdentifiers.id_sha3_256, DigestFactory.createSHA3_256(), new PKCS1Encoding(new RSABlindedEngine()));
+ // }
+ // }
+
+ // static public class SHA3_384
+ // extends DigestSignatureSpi
+ // {
+ // public SHA3_384()
+ // {
+ // super(NISTObjectIdentifiers.id_sha3_384, DigestFactory.createSHA3_384(), new PKCS1Encoding(new RSABlindedEngine()));
+ // }
+ // }
+
+ // static public class SHA3_512
+ // extends DigestSignatureSpi
+ // {
+ // public SHA3_512()
+ // {
+ // super(NISTObjectIdentifiers.id_sha3_512, DigestFactory.createSHA3_512(), new PKCS1Encoding(new RSABlindedEngine()));
// }
// }
@@ -339,7 +371,7 @@ public class DigestSignatureSpi
// super(PKCSObjectIdentifiers.md2, new MD2Digest(), new PKCS1Encoding(new RSABlindedEngine()));
// }
// }
- //
+
// static public class MD4
// extends DigestSignatureSpi
// {
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
index 16e73481..2994e739 100644
--- 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
@@ -1,6 +1,5 @@
package org.bouncycastle.jcajce.provider.asymmetric.util;
-import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Hashtable;
@@ -145,7 +144,6 @@ public abstract class BaseAgreementSpi
private final String kaAlgorithm;
private final DerivationFunction kdf;
- protected BigInteger result;
protected byte[] ukmParameters;
public BaseAgreementSpi(String kaAlgorithm, DerivationFunction kdf)
@@ -186,7 +184,7 @@ public abstract class BaseAgreementSpi
{
if (algDetails.indexOf('[') > 0)
{
- return (Integer.parseInt(algDetails.substring(algDetails.indexOf('[') + 1, algDetails.indexOf(']'))) + 7) / 8;
+ return Integer.parseInt(algDetails.substring(algDetails.indexOf('[') + 1, algDetails.indexOf(']')));
}
String algKey = Strings.toUpperCase(algDetails);
@@ -229,7 +227,7 @@ public abstract class BaseAgreementSpi
"KDF can only be used when algorithm is known");
}
- return bigIntToBytes(result);
+ return calcSecret();
}
protected int engineGenerateSecret(
@@ -253,7 +251,7 @@ public abstract class BaseAgreementSpi
String algorithm)
throws NoSuchAlgorithmException
{
- byte[] secret = bigIntToBytes(result);
+ byte[] secret = calcSecret();
String algKey = Strings.toUpperCase(algorithm);
String oidAlgorithm = algorithm;
@@ -311,13 +309,15 @@ public abstract class BaseAgreementSpi
}
}
- if (des.containsKey(oidAlgorithm))
+ String algName = getAlgorithm(algorithm);
+
+ if (des.containsKey(algName))
{
DESParameters.setOddParity(secret);
}
- return new SecretKeySpec(secret, getAlgorithm(algorithm));
+ return new SecretKeySpec(secret, algName);
}
- protected abstract byte[] bigIntToBytes(BigInteger result);
+ protected abstract byte[] calcSecret();
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java
index 5842b9e1..602ca74c 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseCipherSpi.java
@@ -156,9 +156,15 @@ public abstract class BaseCipherSpi
{
throw new InvalidKeyException(e.getMessage());
}
- catch (BadPaddingException e)
+ catch (final BadPaddingException e)
{
- throw new InvalidKeyException(e.getMessage());
+ throw new InvalidKeyException("unable to unwrap")
+ {
+ public synchronized Throwable getCause()
+ {
+ return e;
+ }
+ };
}
catch (IllegalBlockSizeException e2)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java
index cb34f447..17c4d3fb 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/BaseKeyFactorySpi.java
@@ -28,12 +28,12 @@ public abstract class BaseKeyFactorySpi
}
catch (Exception e)
{
- throw new InvalidKeySpecException("encoded key spec not recognised");
+ throw new InvalidKeySpecException("encoded key spec not recognized: " + e.getMessage());
}
}
else
{
- throw new InvalidKeySpecException("key spec not recognised");
+ throw new InvalidKeySpecException("key spec not recognized");
}
}
@@ -49,12 +49,12 @@ public abstract class BaseKeyFactorySpi
}
catch (Exception e)
{
- throw new InvalidKeySpecException("encoded key spec not recognised");
+ throw new InvalidKeySpecException("encoded key spec not recognized: " + e.getMessage());
}
}
else
{
- throw new InvalidKeySpecException("key spec not recognised");
+ throw new InvalidKeySpecException("key spec not recognized");
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/DHUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/DHUtil.java
index 52c84ec0..07f8cfd2 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/DHUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/DHUtil.java
@@ -11,6 +11,7 @@ import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.DHParameters;
import org.bouncycastle.crypto.params.DHPrivateKeyParameters;
import org.bouncycastle.crypto.params.DHPublicKeyParameters;
+import org.bouncycastle.jcajce.provider.asymmetric.dh.BCDHPublicKey;
/**
* utility class for converting jce/jca DH objects
@@ -22,6 +23,10 @@ public class DHUtil
PublicKey key)
throws InvalidKeyException
{
+ if (key instanceof BCDHPublicKey)
+ {
+ return ((BCDHPublicKey)key).engineGetKeyParameters();
+ }
if (key instanceof DHPublicKey)
{
DHPublicKey k = (DHPublicKey)key;
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
index 0f25888a..3b8a0a6a 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
@@ -10,13 +10,16 @@ import java.security.spec.EllipticCurve;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
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.crypto.params.ECDomainParameters;
import org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import org.bouncycastle.jce.spec.ECNamedCurveSpec;
import org.bouncycastle.math.ec.ECAlgorithms;
@@ -43,6 +46,15 @@ public class EC5Util
customCurves.put(curveParams.getCurve(), CustomNamedCurves.getByName(name).getCurve());
}
}
+
+ // BEGIN android-removed
+ // X9ECParameters c25519 = CustomNamedCurves.getByName("Curve25519");
+
+ // customCurves.put(new ECCurve.Fp(
+ // c25519.getCurve().getField().getCharacteristic(),
+ // c25519.getCurve().getA().toBigInteger(),
+ // c25519.getCurve().getB().toBigInteger()), c25519.getCurve());
+ // END android-removed
}
public static ECCurve getCurve(
@@ -50,28 +62,66 @@ public class EC5Util
X962Parameters params)
{
ECCurve curve;
+ Set acceptableCurves = configuration.getAcceptableNamedCurves();
if (params.isNamedCurve())
{
ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters());
- X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid);
- curve = ecP.getCurve();
+ if (acceptableCurves.isEmpty() || acceptableCurves.contains(oid))
+ {
+ X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid);
+
+ if (ecP == null)
+ {
+ ecP = (X9ECParameters)configuration.getAdditionalECParameters().get(oid);
+ }
+
+ curve = ecP.getCurve();
+ }
+ else
+ {
+ throw new IllegalStateException("named curve not acceptable");
+ }
}
else if (params.isImplicitlyCA())
{
curve = configuration.getEcImplicitlyCa().getCurve();
}
- else
+ else if (acceptableCurves.isEmpty())
{
X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
curve = ecP.getCurve();
}
+ else
+ {
+ throw new IllegalStateException("encoded parameters not acceptable");
+ }
return curve;
}
+ public static ECDomainParameters getDomainParameters(
+ ProviderConfiguration configuration,
+ java.security.spec.ECParameterSpec params)
+ {
+ ECDomainParameters domainParameters;
+
+ if (params == null)
+ {
+ org.bouncycastle.jce.spec.ECParameterSpec iSpec = configuration.getEcImplicitlyCa();
+
+ domainParameters = new ECDomainParameters(iSpec.getCurve(), iSpec.getG(), iSpec.getN(), iSpec.getH(), iSpec.getSeed());
+ }
+ else
+ {
+ domainParameters = ECUtil.getDomainParameters(configuration, convertSpec(params, false));
+ }
+
+ return domainParameters;
+ }
+
public static ECParameterSpec convertToSpec(
X962Parameters params, ECCurve curve)
{
@@ -82,6 +132,14 @@ public class EC5Util
{
ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid);
+ if (ecP == null)
+ {
+ Map additionalECParameters = BouncyCastleProvider.CONFIGURATION.getAdditionalECParameters();
+ if (!additionalECParameters.isEmpty())
+ {
+ ecP = (X9ECParameters)additionalECParameters.get(oid);
+ }
+ }
ellipticCurve = EC5Util.convertCurve(curve, ecP.getSeed());
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 561259ad..6fd4a0dd 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
@@ -5,6 +5,7 @@ import java.security.InvalidKeyException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Enumeration;
+import java.util.Map;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
// BEGIN android-removed
@@ -20,16 +21,19 @@ import org.bouncycastle.asn1.sec.SECNamedCurves;
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;
import org.bouncycastle.crypto.params.ECDomainParameters;
+import org.bouncycastle.crypto.params.ECNamedDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
-import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
+import org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
import org.bouncycastle.jce.interfaces.ECPrivateKey;
import org.bouncycastle.jce.interfaces.ECPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import org.bouncycastle.jce.spec.ECParameterSpec;
/**
@@ -108,6 +112,67 @@ public class ECUtil
return res;
}
+ public static ECDomainParameters getDomainParameters(
+ ProviderConfiguration configuration,
+ org.bouncycastle.jce.spec.ECParameterSpec params)
+ {
+ ECDomainParameters domainParameters;
+
+ if (params instanceof ECNamedCurveParameterSpec)
+ {
+ ECNamedCurveParameterSpec nParams = (ECNamedCurveParameterSpec)params;
+ ASN1ObjectIdentifier nameOid = ECUtil.getNamedCurveOid(nParams.getName());
+
+ domainParameters = new ECNamedDomainParameters(nameOid, nParams.getCurve(), nParams.getG(), nParams.getN(), nParams.getH(), nParams.getSeed());
+ }
+ else if (params == null)
+ {
+ org.bouncycastle.jce.spec.ECParameterSpec iSpec = configuration.getEcImplicitlyCa();
+
+ domainParameters = new ECDomainParameters(iSpec.getCurve(), iSpec.getG(), iSpec.getN(), iSpec.getH(), iSpec.getSeed());
+ }
+ else
+ {
+ domainParameters = new ECDomainParameters(params.getCurve(), params.getG(), params.getN(), params.getH(), params.getSeed());
+ }
+
+ return domainParameters;
+ }
+
+ public static ECDomainParameters getDomainParameters(
+ ProviderConfiguration configuration,
+ X962Parameters params)
+ {
+ ECDomainParameters domainParameters;
+
+ if (params.isNamedCurve())
+ {
+ ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(params.getParameters());
+ X9ECParameters ecP = ECUtil.getNamedCurveByOid(oid);
+ if (ecP == null)
+ {
+ Map extraCurves = configuration.getAdditionalECParameters();
+
+ ecP = (X9ECParameters)extraCurves.get(oid);
+ }
+ domainParameters = new ECNamedDomainParameters(oid, ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed());
+ }
+ else if (params.isImplicitlyCA())
+ {
+ org.bouncycastle.jce.spec.ECParameterSpec iSpec = configuration.getEcImplicitlyCa();
+
+ domainParameters = new ECDomainParameters(iSpec.getCurve(), iSpec.getG(), iSpec.getN(), iSpec.getH(), iSpec.getSeed());
+ }
+ else
+ {
+ X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters());
+
+ domainParameters = new ECDomainParameters(ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed());
+ }
+
+ return domainParameters;
+ }
+
public static AsymmetricKeyParameter generatePublicKeyParameter(
PublicKey key)
throws InvalidKeyException
@@ -117,20 +182,9 @@ public class ECUtil
ECPublicKey k = (ECPublicKey)key;
ECParameterSpec s = k.getParameters();
- if (s == null)
- {
- s = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
-
- return new ECPublicKeyParameters(
- ((BCECPublicKey)k).engineGetQ(),
- new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
- }
- else
- {
- return new ECPublicKeyParameters(
+ return new ECPublicKeyParameters(
k.getQ(),
new ECDomainParameters(s.getCurve(), s.getG(), s.getN(), s.getH(), s.getSeed()));
- }
}
else if (key instanceof java.security.interfaces.ECPublicKey)
{
@@ -222,11 +276,11 @@ public class ECUtil
throw new InvalidKeyException("can't identify EC private key.");
}
- public static int getOrderBitLength(BigInteger order, BigInteger privateValue)
+ public static int getOrderBitLength(ProviderConfiguration configuration, BigInteger order, BigInteger privateValue)
{
if (order == null) // implicitly CA
{
- ECParameterSpec implicitCA = BouncyCastleProvider.CONFIGURATION.getEcImplicitlyCa();
+ ECParameterSpec implicitCA = configuration.getEcImplicitlyCa();
if (implicitCA == null)
{
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 2203ce79..f00ee7bd 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
@@ -1,5 +1,7 @@
package org.bouncycastle.jcajce.provider.asymmetric.x509;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
@@ -26,6 +28,7 @@ import org.bouncycastle.asn1.x509.Certificate;
import org.bouncycastle.asn1.x509.CertificateList;
import org.bouncycastle.jcajce.util.BCJcaJceHelper;
import org.bouncycastle.jcajce.util.JcaJceHelper;
+import org.bouncycastle.util.io.Streams;
/**
* class for dealing with X509 certificates.
@@ -200,7 +203,31 @@ public class CertificateFactory
}
}
- PushbackInputStream pis = new PushbackInputStream(in);
+ InputStream pis;
+
+ if (in.markSupported())
+ {
+ pis = in;
+ }
+ else
+ {
+ // BEGIN android-changed
+ // Was: pis = new ByteArrayInputStream(Streams.readAll(in));
+ // Reason: we want {@code in.available()} to return the number of available bytes if
+ // there is trailing data (otherwise it breaks
+ // libcore.java.security.cert.X509CertificateTest#test_Provider
+ // ). Which is not possible if we read the whole stream at this point.
+ pis = new PushbackInputStream(in);
+ // END android-changed
+ }
+
+ // BEGIN android-changed
+ // Was: pis.mark(1);
+ if (in.markSupported()) {
+ pis.mark(1);
+ }
+ // END android-changed
+
int tag = pis.read();
if (tag == -1)
@@ -208,7 +235,16 @@ public class CertificateFactory
return null;
}
- pis.unread(tag);
+ // BEGIN android-changdd
+ // Was: pis.reset
+ if (in.markSupported()) {
+ pis.reset();
+ }
+ else
+ {
+ ((PushbackInputStream) pis).unread(tag);
+ }
+ // END android-changed
if (tag != 0x30) // assume ascii PEM encoded.
{
@@ -234,9 +270,19 @@ public class CertificateFactory
throws CertificateException
{
java.security.cert.Certificate cert;
+ // BEGIN android-removed
+ // BufferedInputStream in = new BufferedInputStream(inStream);
+ // Reason: we want {@code in.available()} to return the number of available bytes if
+ // there is trailing data (otherwise it breaks
+ // libcore.java.security.cert.X509CertificateTest#test_Provider
+ // ). Which is not possible if we read the whole stream at this point.
+ // END android-removed
List certs = new ArrayList();
+ // BEGIN android-changed
+ // Was: while ((cert = engineGenerateCertificate(in)) != null)
while ((cert = engineGenerateCertificate(inStream)) != null)
+ // END android-changed
{
certs.add(cert);
}
@@ -249,18 +295,18 @@ public class CertificateFactory
* it with the data read from the input stream inStream.
*/
public CRL engineGenerateCRL(
- InputStream inStream)
+ InputStream in)
throws CRLException
{
if (currentCrlStream == null)
{
- currentCrlStream = inStream;
+ currentCrlStream = in;
sCrlData = null;
sCrlDataObjectCount = 0;
}
- else if (currentCrlStream != inStream) // reset if input stream has changed
+ else if (currentCrlStream != in) // reset if input stream has changed
{
- currentCrlStream = inStream;
+ currentCrlStream = in;
sCrlData = null;
sCrlDataObjectCount = 0;
}
@@ -281,7 +327,18 @@ public class CertificateFactory
}
}
- PushbackInputStream pis = new PushbackInputStream(inStream);
+ InputStream pis;
+
+ if (in.markSupported())
+ {
+ pis = in;
+ }
+ else
+ {
+ pis = new ByteArrayInputStream(Streams.readAll(in));
+ }
+
+ pis.mark(1);
int tag = pis.read();
if (tag == -1)
@@ -289,8 +346,7 @@ public class CertificateFactory
return null;
}
- pis.unread(tag);
-
+ pis.reset();
if (tag != 0x30) // assume ascii PEM encoded.
{
return readPEMCRL(pis);
@@ -325,8 +381,9 @@ public class CertificateFactory
{
CRL crl;
List crls = new ArrayList();
+ BufferedInputStream in = new BufferedInputStream(inStream);
- while ((crl = engineGenerateCRL(inStream)) != null)
+ while ((crl = engineGenerateCRL(in)) != null)
{
crls.add(crl);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
index 8116f294..3efd2d69 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/PEMUtil.java
@@ -43,6 +43,22 @@ class PEMUtil
return null;
}
+ // make sure we parse to end of line.
+ if (c == '\r')
+ {
+ // a '\n' may follow
+ in.mark(1);
+ if (((c = in.read()) == '\n'))
+ {
+ in.mark(1);
+ }
+
+ if (c > 0)
+ {
+ in.reset();
+ }
+ }
+
return l.toString();
}
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 8242b117..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
@@ -68,11 +68,7 @@ import org.bouncycastle.util.Integers;
import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
-// BEGIN ANDROID-CHANGED
-// Was: class X509CertificateObject
-// Changed to public so that it can be accessed from X509V3CertificateGenerator
-public class X509CertificateObject
-// END ANDROID-CHANGED
+class X509CertificateObject
extends X509Certificate
implements PKCS12BagAttributeCarrier
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
index 61b05452..d94dd16f 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/x509/X509SignatureUtil.java
@@ -16,24 +16,17 @@ import org.bouncycastle.asn1.ASN1Null;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERNull;
-// BEGIN android-removed
-// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
-// END android-removed
-import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
-import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
-// BEGIN android-removed
-// import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
-// END android-removed
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import org.bouncycastle.jcajce.util.MessageDigestUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
class X509SignatureUtil
{
private static final ASN1Null derNull = DERNull.INSTANCE;
-
+
static void setSignatureParameters(
Signature signature,
ASN1Encodable params)
@@ -123,51 +116,14 @@ class X509SignatureUtil
private static String getDigestAlgName(
ASN1ObjectIdentifier digestAlgOID)
{
- if (PKCSObjectIdentifiers.md5.equals(digestAlgOID))
- {
- return "MD5";
- }
- else if (OIWObjectIdentifiers.idSHA1.equals(digestAlgOID))
- {
- return "SHA1";
- }
- else if (NISTObjectIdentifiers.id_sha224.equals(digestAlgOID))
- {
- return "SHA224";
- }
- else if (NISTObjectIdentifiers.id_sha256.equals(digestAlgOID))
- {
- return "SHA256";
- }
- else if (NISTObjectIdentifiers.id_sha384.equals(digestAlgOID))
- {
- return "SHA384";
- }
- else if (NISTObjectIdentifiers.id_sha512.equals(digestAlgOID))
- {
- return "SHA512";
- }
- // BEGIN android-removed
- // else if (TeleTrusTObjectIdentifiers.ripemd128.equals(digestAlgOID))
- // {
- // return "RIPEMD128";
- // }
- // else if (TeleTrusTObjectIdentifiers.ripemd160.equals(digestAlgOID))
- // {
- // return "RIPEMD160";
- // }
- // else if (TeleTrusTObjectIdentifiers.ripemd256.equals(digestAlgOID))
- // {
- // return "RIPEMD256";
- // }
- // else if (CryptoProObjectIdentifiers.gostR3411.equals(digestAlgOID))
- // {
- // return "GOST3411";
- // }
- // END android-removed
- else
+ String name = MessageDigestUtils.getDigestName(digestAlgOID);
+
+ int dIndex = name.indexOf('-');
+ if (dIndex > 0 && !name.startsWith("SHA3"))
{
- return digestAlgOID.getId();
+ return name.substring(0, dIndex) + name.substring(dIndex + 1);
}
+
+ return MessageDigestUtils.getDigestName(digestAlgOID);
}
}
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 5fb3ffc9..0865b576 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
@@ -29,6 +29,16 @@ public interface ConfigurableProvider
*/
static final String DH_DEFAULT_PARAMS = "DhDefaultParams";
+ /**
+ * A set of OBJECT IDENTIFIERs representing acceptable named curves for imported keys.
+ */
+ static final String ACCEPTABLE_EC_CURVES = "acceptableEcCurves";
+
+ /**
+ * A set of OBJECT IDENTIFIERs to EC Curves providing local curve name mapping.
+ */
+ static final String ADDITIONAL_EC_PARAMETERS = "additionalEcParameters";
+
void setParameter(String parameterName, Object parameter);
void addAlgorithm(String key, String value);
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ProviderConfiguration.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ProviderConfiguration.java
index 2d99ed9b..e293d9f7 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ProviderConfiguration.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ProviderConfiguration.java
@@ -1,5 +1,8 @@
package org.bouncycastle.jcajce.provider.config;
+import java.util.Map;
+import java.util.Set;
+
import javax.crypto.spec.DHParameterSpec;
import org.bouncycastle.jce.spec.ECParameterSpec;
@@ -9,4 +12,8 @@ public interface ProviderConfiguration
ECParameterSpec getEcImplicitlyCa();
DHParameterSpec getDHDefaultParameters(int keySize);
+
+ Set getAcceptableNamedCurves();
+
+ Map getAdditionalECParameters();
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ProviderConfigurationPermission.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ProviderConfigurationPermission.java
index b21afc54..8d937877 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ProviderConfigurationPermission.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/config/ProviderConfigurationPermission.java
@@ -27,18 +27,23 @@ import org.bouncycastle.util.Strings;
public class ProviderConfigurationPermission
extends BasicPermission
{
- private static final int THREAD_LOCAL_EC_IMPLICITLY_CA = 0x01;
- private static final int EC_IMPLICITLY_CA = 0x02;
- private static final int THREAD_LOCAL_DH_DEFAULT_PARAMS = 0x04;
- private static final int DH_DEFAULT_PARAMS = 0x08;
+ private static final int THREAD_LOCAL_EC_IMPLICITLY_CA = 0x01;
+ private static final int EC_IMPLICITLY_CA = 0x02;
+ private static final int THREAD_LOCAL_DH_DEFAULT_PARAMS = 0x04;
+ private static final int DH_DEFAULT_PARAMS = 0x08;
+ private static final int ACCEPTABLE_EC_CURVES = 0x10;
+ private static final int ADDITIONAL_EC_PARAMETERS = 0x20;
- private static final int ALL = THREAD_LOCAL_EC_IMPLICITLY_CA | EC_IMPLICITLY_CA | THREAD_LOCAL_DH_DEFAULT_PARAMS | DH_DEFAULT_PARAMS;
+ private static final int ALL =
+ THREAD_LOCAL_EC_IMPLICITLY_CA | EC_IMPLICITLY_CA | THREAD_LOCAL_DH_DEFAULT_PARAMS | DH_DEFAULT_PARAMS |
+ ACCEPTABLE_EC_CURVES | ADDITIONAL_EC_PARAMETERS;
private static final String THREAD_LOCAL_EC_IMPLICITLY_CA_STR = "threadlocalecimplicitlyca";
private static final String EC_IMPLICITLY_CA_STR = "ecimplicitlyca";
private static final String THREAD_LOCAL_DH_DEFAULT_PARAMS_STR = "threadlocaldhdefaultparams";
private static final String DH_DEFAULT_PARAMS_STR = "dhdefaultparams";
-
+ private static final String ACCEPTABLE_EC_CURVES_STR = "acceptableeccurves";
+ private static final String ADDITIONAL_EC_PARAMETERS_STR = "additionalecparameters";
private static final String ALL_STR = "all";
private final String actions;
@@ -84,6 +89,14 @@ public class ProviderConfigurationPermission
{
mask |= DH_DEFAULT_PARAMS;
}
+ else if (s.equals(ACCEPTABLE_EC_CURVES_STR))
+ {
+ mask |= ACCEPTABLE_EC_CURVES;
+ }
+ else if (s.equals(ADDITIONAL_EC_PARAMETERS_STR))
+ {
+ mask |= ADDITIONAL_EC_PARAMETERS;
+ }
else if (s.equals(ALL_STR))
{
mask |= ALL;
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 9c99e0b5..35e03189 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
@@ -1,16 +1,9 @@
package org.bouncycastle.jcajce.provider.digest;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.KeySpec;
-
-import javax.crypto.SecretKey;
-import javax.crypto.spec.PBEKeySpec;
-
import org.bouncycastle.asn1.iana.IANAObjectIdentifiers;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.crypto.CipherKeyGenerator;
-import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.digests.SHA1Digest;
// BEGIN ANDROID-ADDED
import org.bouncycastle.crypto.digests.SHA224Digest;
@@ -20,11 +13,8 @@ import org.bouncycastle.crypto.digests.SHA512Digest;
// END ANDROID-ADDED
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
-import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey;
import org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator;
import org.bouncycastle.jcajce.provider.symmetric.util.BaseMac;
-import org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory;
-import org.bouncycastle.jcajce.provider.symmetric.util.PBE;
import org.bouncycastle.jcajce.provider.symmetric.util.PBESecretKeyFactory;
public class SHA1
@@ -86,44 +76,6 @@ public class SHA1
}
}
- // BEGIN ANDROID-ADDED
- public static class SHA224Mac
- extends BaseMac
- {
- public SHA224Mac()
- {
- super(new HMac(new SHA224Digest()));
- }
- }
-
- public static class SHA256Mac
- extends BaseMac
- {
- public SHA256Mac()
- {
- super(new HMac(new SHA256Digest()));
- }
- }
-
- public static class SHA384Mac
- extends BaseMac
- {
- public SHA384Mac()
- {
- super(new HMac(new SHA384Digest()));
- }
- }
-
- public static class SHA512Mac
- extends BaseMac
- {
- public SHA512Mac()
- {
- super(new HMac(new SHA512Digest()));
- }
- }
- // END ANDROID-ADDED
-
/**
* PBEWithHmacSHA
*/
@@ -136,267 +88,6 @@ public class SHA1
}
}
- // BEGIN ANDROID-CHANGED
- // Was: public static class BasePBKDF2WithHmacSHA1
- private static class BasePBKDF2WithHmacSHA_Variant
- // END ANDROID-CHANGED
- extends BaseSecretKeyFactory
- {
- private int scheme;
- // BEGIN ANDROID-ADDED
- private int digest;
- private int keySizeInBits;
- private int ivSizeInBits;
- // END ANDROID-ADDED
-
- // BEGIN ANDROID-CHANGED
- // Was: public BasePBKDF2WithHmacSHA1(String name, int scheme)
- private BasePBKDF2WithHmacSHA_Variant(
- String name, int scheme, int digest, int keySizeInBits, int ivSizeInBits)
- // END ANDROID-CHANGED
- {
- super(name, PKCSObjectIdentifiers.id_PBKDF2);
-
- this.scheme = scheme;
- // BEGIN ANDROID-ADDED
- this.digest = digest;
- this.keySizeInBits = keySizeInBits;
- this.ivSizeInBits = ivSizeInBits;
- // END ANDROID-ADDED
- }
-
- // BEGIN android-added
- private BasePBKDF2WithHmacSHA_Variant(String name, int scheme, int digest) {
- this(name, scheme, digest, 0, 0);
- }
- // END android-added
-
- protected SecretKey engineGenerateSecret(
- KeySpec keySpec)
- throws InvalidKeySpecException
- {
- if (keySpec instanceof PBEKeySpec)
- {
- PBEKeySpec pbeSpec = (PBEKeySpec)keySpec;
-
- // BEGIN ANDROID-ADDED
- // Allow to specify a key using only the password. The key will be generated later
- // when other parameters are known.
- if (pbeSpec.getSalt() == null
- && pbeSpec.getIterationCount() == 0
- && pbeSpec.getKeyLength() == 0
- && pbeSpec.getPassword().length > 0
- && keySizeInBits != 0) {
- return new BCPBEKey(
- this.algName, this.algOid, scheme, digest, keySizeInBits, ivSizeInBits,
- pbeSpec,
- // cipherParameters, to be generated when the PBE parameters are known.
- null);
- }
- // END ANDROID-ADDED
-
- if (pbeSpec.getSalt() == null)
- {
- throw new InvalidKeySpecException("missing required salt");
- }
-
- if (pbeSpec.getIterationCount() <= 0)
- {
- throw new InvalidKeySpecException("positive iteration count required: "
- + pbeSpec.getIterationCount());
- }
-
- if (pbeSpec.getKeyLength() <= 0)
- {
- throw new InvalidKeySpecException("positive key length required: "
- + pbeSpec.getKeyLength());
- }
-
- if (pbeSpec.getPassword().length == 0)
- {
- throw new IllegalArgumentException("password empty");
- }
-
- // BEGIN android-removed
- // int digest = SHA1;
- // END android-removed
- int keySize = pbeSpec.getKeyLength();
- int ivSize = -1; // JDK 1,2 and earlier does not understand simplified version.
- CipherParameters param = PBE.Util.makePBEMacParameters(pbeSpec, scheme, digest, keySize);
-
- return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, param);
- }
-
- throw new InvalidKeySpecException("Invalid KeySpec");
- }
- }
-
- // BEGIN android-added
- public static class BasePBKDF2WithHmacSHA1 extends BasePBKDF2WithHmacSHA_Variant {
- public BasePBKDF2WithHmacSHA1(String name, int scheme)
- {
- super(name, scheme, SHA1);
- }
- }
- // END android-added
-
- public static class PBKDF2WithHmacSHA1UTF8
- extends BasePBKDF2WithHmacSHA1
- {
- public PBKDF2WithHmacSHA1UTF8()
- {
- super("PBKDF2WithHmacSHA1", PKCS5S2_UTF8);
- }
- }
-
- public static class PBKDF2WithHmacSHA18BIT
- extends BasePBKDF2WithHmacSHA1
- {
- public PBKDF2WithHmacSHA18BIT()
- {
- super("PBKDF2WithHmacSHA1And8bit", PKCS5S2);
- }
- }
-
- // BEGIN ANDROID-ADDED
- public static class BasePBKDF2WithHmacSHA224 extends BasePBKDF2WithHmacSHA_Variant {
- public BasePBKDF2WithHmacSHA224(String name, int scheme)
- {
- super(name, scheme, SHA224);
- }
- }
-
- public static class PBKDF2WithHmacSHA224UTF8
- extends BasePBKDF2WithHmacSHA224
- {
- public PBKDF2WithHmacSHA224UTF8()
- {
- super("PBKDF2WithHmacSHA224", PKCS5S2_UTF8);
- }
- }
-
- public static class BasePBKDF2WithHmacSHA256 extends BasePBKDF2WithHmacSHA_Variant {
- public BasePBKDF2WithHmacSHA256(String name, int scheme)
- {
- super(name, scheme, SHA256);
- }
- }
-
- public static class PBKDF2WithHmacSHA256UTF8
- extends BasePBKDF2WithHmacSHA256
- {
- public PBKDF2WithHmacSHA256UTF8()
- {
- super("PBKDF2WithHmacSHA256", PKCS5S2_UTF8);
- }
- }
-
-
- public static class BasePBKDF2WithHmacSHA384 extends BasePBKDF2WithHmacSHA_Variant {
- public BasePBKDF2WithHmacSHA384(String name, int scheme)
- {
- super(name, scheme, SHA384);
- }
- }
-
- public static class PBKDF2WithHmacSHA384UTF8
- extends BasePBKDF2WithHmacSHA384
- {
- public PBKDF2WithHmacSHA384UTF8()
- {
- super("PBKDF2WithHmacSHA384", PKCS5S2_UTF8);
- }
- }
-
- public static class BasePBKDF2WithHmacSHA512 extends BasePBKDF2WithHmacSHA_Variant {
- public BasePBKDF2WithHmacSHA512(String name, int scheme)
- {
- super(name, scheme, SHA512);
- }
- }
-
- public static class PBKDF2WithHmacSHA512UTF8
- extends BasePBKDF2WithHmacSHA512
- {
- public PBKDF2WithHmacSHA512UTF8()
- {
- super("PBKDF2WithHmacSHA512", PKCS5S2_UTF8);
- }
- }
-
- public static class PBEWithHmacSHA1AndAES_128
- extends BasePBKDF2WithHmacSHA_Variant {
- public PBEWithHmacSHA1AndAES_128() {
- super("PBEWithHmacSHA1AndAES_128", PKCS5S2_UTF8, SHA1, 128, 128);
- }
- }
-
- public static class PBEWithHmacSHA224AndAES_128
- extends BasePBKDF2WithHmacSHA_Variant {
- public PBEWithHmacSHA224AndAES_128() {
- super("PBEWithHmacSHA224AndAES_128", PKCS5S2_UTF8, SHA224, 128, 128);
- }
- }
-
- public static class PBEWithHmacSHA256AndAES_128
- extends BasePBKDF2WithHmacSHA_Variant {
- public PBEWithHmacSHA256AndAES_128() {
- super("PBEWithHmacSHA256AndAES_128", PKCS5S2_UTF8, SHA256, 128, 128);
- }
- }
-
- public static class PBEWithHmacSHA384AndAES_128
- extends BasePBKDF2WithHmacSHA_Variant {
- public PBEWithHmacSHA384AndAES_128() {
- super("PBEWithHmacSHA384AndAES_128", PKCS5S2_UTF8, SHA384, 128, 128);
- }
- }
-
- public static class PBEWithHmacSHA512AndAES_128
- extends BasePBKDF2WithHmacSHA_Variant {
- public PBEWithHmacSHA512AndAES_128() {
- super("PBEWithHmacSHA512AndAES_128", PKCS5S2_UTF8, SHA512, 128, 128);
- }
- }
-
-
- public static class PBEWithHmacSHA1AndAES_256
- extends BasePBKDF2WithHmacSHA_Variant {
- public PBEWithHmacSHA1AndAES_256() {
- super("PBEWithHmacSHA1AndAES_256", PKCS5S2_UTF8, SHA1, 256, 128);
- }
- }
-
- public static class PBEWithHmacSHA224AndAES_256
- extends BasePBKDF2WithHmacSHA_Variant {
- public PBEWithHmacSHA224AndAES_256() {
- super("PBEWithHmacSHA224AndAES_256", PKCS5S2_UTF8, SHA224, 256, 128);
- }
- }
-
- public static class PBEWithHmacSHA256AndAES_256
- extends BasePBKDF2WithHmacSHA_Variant {
- public PBEWithHmacSHA256AndAES_256() {
- super("PBEWithHmacSHA256AndAES_256", PKCS5S2_UTF8, SHA256, 256, 128);
- }
- }
-
- public static class PBEWithHmacSHA384AndAES_256
- extends BasePBKDF2WithHmacSHA_Variant {
- public PBEWithHmacSHA384AndAES_256() {
- super("PBEWithHmacSHA384AndAES_256", PKCS5S2_UTF8, SHA384, 256, 128);
- }
- }
-
- public static class PBEWithHmacSHA512AndAES_256
- extends BasePBKDF2WithHmacSHA_Variant {
- public PBEWithHmacSHA512AndAES_256() {
- super("PBEWithHmacSHA512AndAES_256", PKCS5S2_UTF8, SHA512, 256, 128);
- }
- }
- // END ANDROID-ADDED
-
-
public static class Mappings
extends DigestAlgorithmProvider
{
@@ -419,38 +110,11 @@ public class SHA1
provider.addAlgorithm("Mac.PBEWITHHMACSHA", PREFIX + "$SHA1Mac");
provider.addAlgorithm("Mac.PBEWITHHMACSHA1", PREFIX + "$SHA1Mac");
- // BEGIN android-added
- provider.addAlgorithm("Mac.PBEWITHHMACSHA224", PREFIX + "$SHA224Mac");
- provider.addAlgorithm("Mac.PBEWITHHMACSHA256", PREFIX + "$SHA256Mac");
- provider.addAlgorithm("Mac.PBEWITHHMACSHA384", PREFIX + "$SHA384Mac");
- provider.addAlgorithm("Mac.PBEWITHHMACSHA512", PREFIX + "$SHA512Mac");
- // END android-added
provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBEWITHHMACSHA", "PBEWITHHMACSHA1");
provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + OIWObjectIdentifiers.idSHA1, "PBEWITHHMACSHA1");
provider.addAlgorithm("Alg.Alias.Mac." + OIWObjectIdentifiers.idSHA1, "PBEWITHHMACSHA");
provider.addAlgorithm("SecretKeyFactory.PBEWITHHMACSHA1", PREFIX + "$PBEWithMacKeyFactory");
- provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA1", PREFIX + "$PBKDF2WithHmacSHA1UTF8");
- // BEGIN android-added
- provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA224", PREFIX + "$PBKDF2WithHmacSHA224UTF8");
- provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA256", PREFIX + "$PBKDF2WithHmacSHA256UTF8");
- provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA384", PREFIX + "$PBKDF2WithHmacSHA384UTF8");
- provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA512", PREFIX + "$PBKDF2WithHmacSHA512UTF8");
- provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA1AndAES_128", PREFIX + "$PBEWithHmacSHA1AndAES_128");
- provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA224AndAES_128", PREFIX + "$PBEWithHmacSHA224AndAES_128");
- provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA256AndAES_128", PREFIX + "$PBEWithHmacSHA256AndAES_128");
- provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA384AndAES_128", PREFIX + "$PBEWithHmacSHA384AndAES_128");
- provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA512AndAES_128", PREFIX + "$PBEWithHmacSHA512AndAES_128");
- provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA1AndAES_256", PREFIX + "$PBEWithHmacSHA1AndAES_256");
- provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA224AndAES_256", PREFIX + "$PBEWithHmacSHA224AndAES_256");
- provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA256AndAES_256", PREFIX + "$PBEWithHmacSHA256AndAES_256");
- provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA384AndAES_256", PREFIX + "$PBEWithHmacSHA384AndAES_256");
- provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA512AndAES_256", PREFIX + "$PBEWithHmacSHA512AndAES_256");
- // END android-added
- 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/digest/SHA224.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA224.java
index ba06a0fb..ac83fc23 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA224.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA224.java
@@ -68,6 +68,8 @@ public class SHA224
provider.addAlgorithm("Alg.Alias.MessageDigest.SHA224", "SHA-224");
provider.addAlgorithm("Alg.Alias.MessageDigest." + NISTObjectIdentifiers.id_sha224, "SHA-224");
+ provider.addAlgorithm("Mac.PBEWITHHMACSHA224", PREFIX + "$HashMac");
+
addHMACAlgorithm(provider, "SHA224", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
addHMACAlias(provider, "SHA224", PKCSObjectIdentifiers.id_hmacWithSHA224);
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA256.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA256.java
index 4504f306..e129db4d 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA256.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA256.java
@@ -92,6 +92,8 @@ public class SHA256
// provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + NISTObjectIdentifiers.id_sha256, "PBEWITHHMACSHA256");
// END android-removed
+ provider.addAlgorithm("Mac.PBEWITHHMACSHA256", PREFIX + "$HashMac");
+
addHMACAlgorithm(provider, "SHA256", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
addHMACAlias(provider, "SHA256", PKCSObjectIdentifiers.id_hmacWithSHA256);
addHMACAlias(provider, "SHA256", NISTObjectIdentifiers.id_sha256);
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA384.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA384.java
index e5635798..f2fb6d32 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA384.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA384.java
@@ -88,6 +88,8 @@ public class SHA384
// provider.addAlgorithm("Mac.OLDHMACSHA384", PREFIX + "$OldSHA384");
// END android-removed
+ provider.addAlgorithm("Mac.PBEWITHHMACSHA384", PREFIX + "$HashMac");
+
addHMACAlgorithm(provider, "SHA384", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
addHMACAlias(provider, "SHA384", PKCSObjectIdentifiers.id_hmacWithSHA384);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA512.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA512.java
index 903eec1b..9433a817 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA512.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/digest/SHA512.java
@@ -180,6 +180,8 @@ public class SHA512
// provider.addAlgorithm("Mac.OLDHMACSHA512", PREFIX + "$OldSHA512");
// END android-removed
+ provider.addAlgorithm("Mac.PBEWITHHMACSHA512", PREFIX + "$HashMac");
+
addHMACAlgorithm(provider, "SHA512", PREFIX + "$HashMac", PREFIX + "$KeyGenerator");
addHMACAlias(provider, "SHA512", PKCSObjectIdentifiers.id_hmacWithSHA512);
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 ed0fadce..106f75b2 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
@@ -90,7 +90,10 @@ import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.crypto.digests.SHA1Digest;
+// BEGIN android-changed
+// Was: import org.bouncycastle.crypto.digests.SHA1Digest
+import org.bouncycastle.crypto.digests.AndroidDigestFactory;
+// END android-changed
import org.bouncycastle.jcajce.PKCS12Key;
import org.bouncycastle.jcajce.PKCS12StoreParameter;
// BEGIN android-removed
@@ -230,7 +233,7 @@ public class PKCS12KeyStoreSpi
private static byte[] getDigest(SubjectPublicKeyInfo spki)
{
- Digest digest = new SHA1Digest();
+ Digest digest = AndroidDigestFactory.getSHA1();
byte[] resBuf = new byte[digest.getDigestSize()];
byte[] bytes = spki.getPublicKeyData().getBytes();
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 0328ac8b..ed7342d8 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/AES.java
@@ -26,7 +26,11 @@ import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.CipherKeyGenerator;
-import org.bouncycastle.crypto.engines.AESFastEngine;
+import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.InvalidCipherTextException;
+import org.bouncycastle.crypto.Mac;
+import org.bouncycastle.crypto.engines.AESEngine;
import org.bouncycastle.crypto.engines.AESWrapEngine;
// BEGIN android-removed
// import org.bouncycastle.crypto.engines.RFC3211WrapEngine;
@@ -51,11 +55,13 @@ 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;
+// import org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory;
// END android-removed
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.jcajce.spec.AEADParameterSpec;
public final class AES
{
@@ -74,7 +80,7 @@ public final class AES
{
public BlockCipher get()
{
- return new AESFastEngine();
+ return new AESEngine();
}
});
}
@@ -85,7 +91,7 @@ public final class AES
{
public CBC()
{
- super(new CBCBlockCipher(new AESFastEngine()), 128);
+ super(new CBCBlockCipher(new AESEngine()), 128);
}
}
@@ -94,7 +100,7 @@ public final class AES
{
public CFB()
{
- super(new BufferedBlockCipher(new CFBBlockCipher(new AESFastEngine(), 128)), 128);
+ super(new BufferedBlockCipher(new CFBBlockCipher(new AESEngine(), 128)), 128);
}
}
@@ -103,7 +109,7 @@ public final class AES
{
public OFB()
{
- super(new BufferedBlockCipher(new OFBBlockCipher(new AESFastEngine(), 128)), 128);
+ super(new BufferedBlockCipher(new OFBBlockCipher(new AESEngine(), 128)), 128);
}
}
@@ -112,7 +118,7 @@ public final class AES
{
public GCM()
{
- super(new GCMBlockCipher(new AESFastEngine()));
+ super(new GCMBlockCipher(new AESEngine()));
// BEGIN android-added
try {
engineSetMode("GCM");
@@ -131,37 +137,111 @@ public final class AES
// {
// public CCM()
// {
- // super(new CCMBlockCipher(new AESFastEngine()), false, 16);
+ // super(new CCMBlockCipher(new AESEngine()), false, 16);
// }
// }
- //
+
// public static class AESCMAC
// extends BaseMac
// {
// public AESCMAC()
// {
- // super(new CMac(new AESFastEngine()));
+ // super(new CMac(new AESEngine()));
// }
// }
- //
+
// public static class AESGMAC
// extends BaseMac
// {
// public AESGMAC()
// {
- // super(new GMac(new GCMBlockCipher(new AESFastEngine())));
+ // super(new GMac(new GCMBlockCipher(new AESEngine())));
// }
// }
- //
+
+ // public static class AESCCMMAC
+ // extends BaseMac
+ // {
+ // public AESCCMMAC()
+ // {
+ // super(new CCMMac());
+ // }
+
+ // private static class CCMMac
+ // implements Mac
+ // {
+ // private final CCMBlockCipher ccm = new CCMBlockCipher(new AESEngine());
+
+ // private int macLength = 8;
+
+ // public void init(CipherParameters params)
+ // throws IllegalArgumentException
+ // {
+ // ccm.init(true, params);
+
+ // this.macLength = ccm.getMac().length;
+ // }
+
+ // public String getAlgorithmName()
+ // {
+ // return ccm.getAlgorithmName() + "Mac";
+ // }
+
+ // public int getMacSize()
+ // {
+ // return macLength;
+ // }
+
+ // public void update(byte in)
+ // throws IllegalStateException
+ // {
+ // ccm.processAADByte(in);
+ // }
+
+ // public void update(byte[] in, int inOff, int len)
+ // throws DataLengthException, IllegalStateException
+ // {
+ // ccm.processAADBytes(in, inOff, len);
+ // }
+
+ // public int doFinal(byte[] out, int outOff)
+ // throws DataLengthException, IllegalStateException
+ // {
+ // try
+ // {
+ // return ccm.doFinal(out, 0);
+ // }
+ // catch (InvalidCipherTextException e)
+ // {
+ // throw new IllegalStateException("exception on doFinal(): " + e.toString());
+ // }
+ // }
+
+ // public void reset()
+ // {
+ // ccm.reset();
+ // }
+ // }
+ // }
+
+ // static public class KeyFactory
+ // extends BaseSecretKeyFactory
+ // {
+ // public KeyFactory()
+ // {
+ // super("AES", null);
+ // }
+ // }
+
// public static class Poly1305
// extends BaseMac
// {
// public Poly1305()
// {
- // super(new org.bouncycastle.crypto.macs.Poly1305(new AESFastEngine()));
+ // super(new org.bouncycastle.crypto.macs.Poly1305(new AESEngine()));
// }
// }
- //
+
// public static class Poly1305KeyGen
// extends BaseKeyGenerator
// {
@@ -187,16 +267,16 @@ public final class AES
// {
// public RFC3211Wrap()
// {
- // super(new RFC3211WrapEngine(new AESFastEngine()), 16);
+ // super(new RFC3211WrapEngine(new AESEngine()), 16);
// }
// }
- //
+
// public static class RFC5649Wrap
// extends BaseWrapCipher
// {
// public RFC5649Wrap()
// {
- // super(new RFC5649WrapEngine(new AESFastEngine()));
+ // super(new RFC5649WrapEngine(new AESEngine()));
// }
// }
// END android-removed
@@ -209,7 +289,7 @@ public final class AES
{
public PBEWithAESCBC()
{
- super(new CBCBlockCipher(new AESFastEngine()));
+ super(new CBCBlockCipher(new AESEngine()));
}
}
@@ -221,7 +301,7 @@ public final class AES
{
public PBEWithSHA1AESCBC128()
{
- super(new CBCBlockCipher(new AESFastEngine()), PKCS12, SHA1, 128, 16);
+ super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA1, 128, 16);
}
}
@@ -230,7 +310,7 @@ public final class AES
{
public PBEWithSHA1AESCBC192()
{
- super(new CBCBlockCipher(new AESFastEngine()), PKCS12, SHA1, 192, 16);
+ super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA1, 192, 16);
}
}
@@ -239,7 +319,7 @@ public final class AES
{
public PBEWithSHA1AESCBC256()
{
- super(new CBCBlockCipher(new AESFastEngine()), PKCS12, SHA1, 256, 16);
+ super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA1, 256, 16);
}
}
@@ -251,7 +331,7 @@ public final class AES
{
public PBEWithSHA256AESCBC128()
{
- super(new CBCBlockCipher(new AESFastEngine()), PKCS12, SHA256, 128, 16);
+ super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA256, 128, 16);
}
}
@@ -260,7 +340,7 @@ public final class AES
{
public PBEWithSHA256AESCBC192()
{
- super(new CBCBlockCipher(new AESFastEngine()), PKCS12, SHA256, 192, 16);
+ super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA256, 192, 16);
}
}
@@ -269,7 +349,7 @@ public final class AES
{
public PBEWithSHA256AESCBC256()
{
- super(new CBCBlockCipher(new AESFastEngine()), PKCS12, SHA256, 256, 16);
+ super(new CBCBlockCipher(new AESEngine()), PKCS12, SHA256, 256, 16);
}
}
@@ -425,7 +505,7 @@ public final class AES
super("PBEWithMD5And256BitAES-CBC-OpenSSL", null, true, OPENSSL, MD5, 256, 128);
}
}
-
+
// BEGIN android-removed
// public static class AlgParamGen
// extends BaseAlgorithmParameterGenerator
@@ -437,20 +517,20 @@ public final class AES
// {
// throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for AES parameter generation.");
// }
- //
+
// protected AlgorithmParameters engineGenerateParameters()
// {
// byte[] iv = new byte[16];
- //
+
// if (random == null)
// {
// random = new SecureRandom();
// }
- //
+
// random.nextBytes(iv);
- //
+
// AlgorithmParameters params;
- //
+
// try
// {
// params = createParametersInstance("AES");
@@ -460,11 +540,11 @@ public final class AES
// {
// throw new RuntimeException(e.getMessage());
// }
- //
+
// return params;
// }
// }
- //
+
// public static class AlgParamGenCCM
// extends BaseAlgorithmParameterGenerator
// {
@@ -473,22 +553,23 @@ public final class AES
// SecureRandom random)
// throws InvalidAlgorithmParameterException
// {
+ // // TODO: add support for GCMParameterSpec as a template.
// throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for AES parameter generation.");
// }
- //
+
// protected AlgorithmParameters engineGenerateParameters()
// {
// byte[] iv = new byte[12];
- //
+
// if (random == null)
// {
// random = new SecureRandom();
// }
- //
+
// random.nextBytes(iv);
- //
+
// AlgorithmParameters params;
- //
+
// try
// {
// params = createParametersInstance("CCM");
@@ -498,11 +579,11 @@ public final class AES
// {
// throw new RuntimeException(e.getMessage());
// }
- //
+
// return params;
// }
// }
- //
+
// public static class AlgParamGenGCM
// extends BaseAlgorithmParameterGenerator
// {
@@ -511,32 +592,33 @@ public final class AES
// SecureRandom random)
// throws InvalidAlgorithmParameterException
// {
+ // // TODO: add support for GCMParameterSpec as a template.
// throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for AES parameter generation.");
// }
- //
+
// protected AlgorithmParameters engineGenerateParameters()
// {
// byte[] nonce = new byte[12];
- //
+
// if (random == null)
// {
// random = new SecureRandom();
// }
- //
+
// random.nextBytes(nonce);
- //
+
// AlgorithmParameters params;
- //
+
// try
// {
// params = createParametersInstance("GCM");
- // params.init(new GCMParameters(nonce, 12).getEncoded());
+ // params.init(new GCMParameters(nonce, 16).getEncoded());
// }
// catch (Exception e)
// {
// throw new RuntimeException(e.getMessage());
// }
- //
+
// return params;
// }
// }
@@ -563,6 +645,10 @@ public final class AES
{
gcmParams = GcmSpecUtil.extractGcmParameters(paramSpec);
}
+ else if (paramSpec instanceof AEADParameterSpec)
+ {
+ gcmParams = new GCMParameters(((AEADParameterSpec)paramSpec).getNonce(), ((AEADParameterSpec)paramSpec).getMacSizeInBits() / 8);
+ }
else
{
throw new InvalidParameterSpecException("AlgorithmParameterSpec class not recognized: " + paramSpec.getClass().getName());
@@ -617,7 +703,11 @@ public final class AES
{
return GcmSpecUtil.extractGcmSpec(gcmParams.toASN1Primitive());
}
- return new IvParameterSpec(gcmParams.getNonce());
+ return new AEADParameterSpec(gcmParams.getNonce(), gcmParams.getIcvLen() * 8);
+ }
+ if (paramSpec == AEADParameterSpec.class)
+ {
+ return new AEADParameterSpec(gcmParams.getNonce(), gcmParams.getIcvLen() * 8);
}
if (paramSpec == IvParameterSpec.class)
{
@@ -633,7 +723,7 @@ public final class AES
// extends BaseAlgorithmParameters
// {
// private CCMParameters ccmParams;
- //
+
// protected void engineInit(AlgorithmParameterSpec paramSpec)
// throws InvalidParameterSpecException
// {
@@ -641,18 +731,22 @@ public final class AES
// {
// ccmParams = CCMParameters.getInstance(GcmSpecUtil.extractGcmParameters(paramSpec));
// }
+ // else if (paramSpec instanceof AEADParameterSpec)
+ // {
+ // ccmParams = new CCMParameters(((AEADParameterSpec)paramSpec).getNonce(), ((AEADParameterSpec)paramSpec).getMacSizeInBits() / 8);
+ // }
// else
// {
// throw new InvalidParameterSpecException("AlgorithmParameterSpec class not recognized: " + paramSpec.getClass().getName());
// }
// }
- //
+
// protected void engineInit(byte[] params)
// throws IOException
// {
// ccmParams = CCMParameters.getInstance(params);
// }
- //
+
// protected void engineInit(byte[] params, String format)
// throws IOException
// {
@@ -660,16 +754,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
// {
@@ -677,15 +771,15 @@ 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
// {
@@ -695,13 +789,17 @@ public final class AES
// {
// return GcmSpecUtil.extractGcmSpec(ccmParams.toASN1Primitive());
// }
- // return new IvParameterSpec(ccmParams.getNonce());
+ // return new AEADParameterSpec(ccmParams.getNonce(), ccmParams.getIcvLen() * 8);
+ // }
+ // if (paramSpec == AEADParameterSpec.class)
+ // {
+ // return new AEADParameterSpec(ccmParams.getNonce(), ccmParams.getIcvLen() * 8);
// }
// if (paramSpec == IvParameterSpec.class)
// {
// return new IvParameterSpec(ccmParams.getNonce());
// }
- //
+
// throw new InvalidParameterSpecException("AlgorithmParameterSpec not recognized: " + paramSpec.getName());
// }
// }
@@ -832,10 +930,15 @@ public final class AES
// 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");
+
+ // provider.addAlgorithm("Mac.AESCCMMAC", PREFIX + "$AESCCMMAC");
+ // provider.addAlgorithm("Alg.Alias.Mac." + NISTObjectIdentifiers.id_aes128_CCM.getId(), "AESCCMMAC");
+ // provider.addAlgorithm("Alg.Alias.Mac." + NISTObjectIdentifiers.id_aes192_CCM.getId(), "AESCCMMAC");
+ // provider.addAlgorithm("Alg.Alias.Mac." + NISTObjectIdentifiers.id_aes256_CCM.getId(), "AESCCMMAC");
// END android-removed
-
+
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");
@@ -878,7 +981,12 @@ public final class AES
provider.addAlgorithm("Cipher.PBEWITHMD5AND128BITAES-CBC-OPENSSL", PREFIX + "$PBEWithAESCBC");
provider.addAlgorithm("Cipher.PBEWITHMD5AND192BITAES-CBC-OPENSSL", PREFIX + "$PBEWithAESCBC");
provider.addAlgorithm("Cipher.PBEWITHMD5AND256BITAES-CBC-OPENSSL", PREFIX + "$PBEWithAESCBC");
-
+
+ // BEGIN android-removed
+ // provider.addAlgorithm("SecretKeyFactory.AES", PREFIX + "$KeyFactory");
+ // provider.addAlgorithm("SecretKeyFactory", NISTObjectIdentifiers.aes, PREFIX + "$KeyFactory");
+ // END android-removed
+
provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND128BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And128BitAESCBCOpenSSL");
provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND192BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And192BitAESCBCOpenSSL");
provider.addAlgorithm("SecretKeyFactory.PBEWITHMD5AND256BITAES-CBC-OPENSSL", PREFIX + "$PBEWithMD5And256BitAESCBCOpenSSL");
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 64d8972a..c89fe348 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
@@ -18,6 +18,7 @@ import javax.crypto.spec.DESedeKeySpec;
// END android-removed
import javax.crypto.spec.SecretKeySpec;
+import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.crypto.KeyGenerationParameters;
import org.bouncycastle.crypto.engines.DESedeEngine;
@@ -433,16 +434,18 @@ public final class DESede
provider.addAlgorithm("SecretKeyFactory.DESEDE", PREFIX + "$KeyFactory");
// BEGIN android-removed
+ // provider.addAlgorithm("SecretKeyFactory", OIWObjectIdentifiers.desEDE, PREFIX + "$KeyFactory");
+
// provider.addAlgorithm("Mac.DESEDECMAC", PREFIX + "$CMAC");
// provider.addAlgorithm("Mac.DESEDEMAC", PREFIX + "$CBCMAC");
// provider.addAlgorithm("Alg.Alias.Mac.DESEDE", "DESEDEMAC");
- //
+
// provider.addAlgorithm("Mac.DESEDEMAC/CFB8", PREFIX + "$DESedeCFB8");
// provider.addAlgorithm("Alg.Alias.Mac.DESEDE/CFB8", "DESEDEMAC/CFB8");
- //
+
// provider.addAlgorithm("Mac.DESEDEMAC64", PREFIX + "$DESede64");
// provider.addAlgorithm("Alg.Alias.Mac.DESEDE64", "DESEDEMAC64");
- //
+
// provider.addAlgorithm("Mac.DESEDEMAC64WITHISO7816-4PADDING", PREFIX + "$DESede64with7816d4");
// provider.addAlgorithm("Alg.Alias.Mac.DESEDE64WITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING");
// provider.addAlgorithm("Alg.Alias.Mac.DESEDEISO9797ALG1MACWITHISO7816-4PADDING", "DESEDEMAC64WITHISO7816-4PADDING");
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java
new file mode 100644
index 00000000..b19a4d43
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/PBEPBKDF2.java
@@ -0,0 +1,553 @@
+package org.bouncycastle.jcajce.provider.symmetric;
+
+import java.io.IOException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.InvalidParameterSpecException;
+import java.security.spec.KeySpec;
+
+import javax.crypto.SecretKey;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+
+import org.bouncycastle.asn1.ASN1Encoding;
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.ASN1Primitive;
+// BEGIN android-removed
+// import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
+// END android-removed
+import org.bouncycastle.asn1.pkcs.PBKDF2Params;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
+import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey;
+import org.bouncycastle.jcajce.provider.symmetric.util.BaseAlgorithmParameters;
+import org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory;
+import org.bouncycastle.jcajce.provider.symmetric.util.PBE;
+import org.bouncycastle.jcajce.provider.util.AlgorithmProvider;
+import org.bouncycastle.jcajce.spec.PBKDF2KeySpec;
+
+public class PBEPBKDF2
+{
+ private PBEPBKDF2()
+ {
+
+ }
+
+ // BEGIN android-removed
+ // public static class AlgParams
+ // extends BaseAlgorithmParameters
+ // {
+ // PBKDF2Params params;
+ //
+ // protected byte[] engineGetEncoded()
+ // {
+ // try
+ // {
+ // return params.getEncoded(ASN1Encoding.DER);
+ // }
+ // catch (IOException e)
+ // {
+ // throw new RuntimeException("Oooops! " + e.toString());
+ // }
+ // }
+
+ // protected byte[] engineGetEncoded(
+ // String format)
+ // {
+ // if (this.isASN1FormatString(format))
+ // {
+ // return engineGetEncoded();
+ // }
+ //
+ // return null;
+ // }
+ //
+ // protected AlgorithmParameterSpec localEngineGetParameterSpec(
+ // Class paramSpec)
+ // throws InvalidParameterSpecException
+ // {
+ // if (paramSpec == PBEParameterSpec.class)
+ // {
+ // return new PBEParameterSpec(params.getSalt(),
+ // params.getIterationCount().intValue());
+ // }
+ //
+ // throw new InvalidParameterSpecException("unknown parameter spec passed to PBKDF2 PBE parameters object.");
+ // }
+ //
+ // protected void engineInit(
+ // AlgorithmParameterSpec paramSpec)
+ // throws InvalidParameterSpecException
+ // {
+ // if (!(paramSpec instanceof PBEParameterSpec))
+ // {
+ // throw new InvalidParameterSpecException("PBEParameterSpec required to initialise a PBKDF2 PBE parameters algorithm parameters object");
+ // }
+ //
+ // PBEParameterSpec pbeSpec = (PBEParameterSpec)paramSpec;
+ //
+ // this.params = new PBKDF2Params(pbeSpec.getSalt(),
+ // pbeSpec.getIterationCount());
+ // }
+ //
+ // protected void engineInit(
+ // byte[] params)
+ // throws IOException
+ // {
+ // this.params = PBKDF2Params.getInstance(ASN1Primitive.fromByteArray(params));
+ // }
+ //
+ // protected void engineInit(
+ // byte[] params,
+ // String format)
+ // throws IOException
+ // {
+ // if (this.isASN1FormatString(format))
+ // {
+ // engineInit(params);
+ // return;
+ // }
+ //
+ // throw new IOException("Unknown parameters format in PBKDF2 parameters object");
+ // }
+ //
+ // protected String engineToString()
+ // {
+ // return "PBKDF2 Parameters";
+ // }
+ // }
+ // END android-removed
+
+ public static class BasePBKDF2
+ extends BaseSecretKeyFactory
+ {
+ private int scheme;
+ // BEGIN ANDROID-ADDED
+ private int keySizeInBits;
+ private int ivSizeInBits;
+ // END ANDROID-ADDED
+ private int defaultDigest;
+
+ public BasePBKDF2(String name, int scheme)
+ {
+ this(name, scheme, SHA1);
+ }
+
+ // BEGIN ANDROID-CHANGED
+ // Was: public BasePBKDF2(String name, int scheme, int defaultDigest)
+ private BasePBKDF2(
+ String name, int scheme, int digest, int keySizeInBits, int ivSizeInBits)
+ // END ANDROID-CHANGED
+ {
+ super(name, PKCSObjectIdentifiers.id_PBKDF2);
+
+ this.scheme = scheme;
+ // BEGIN ANDROID-ADDED
+ this.keySizeInBits = keySizeInBits;
+ this.ivSizeInBits = ivSizeInBits;
+ // END ANDROID-ADDED
+ this.defaultDigest = digest;
+ }
+
+ // BEGIN android-added
+ private BasePBKDF2(String name, int scheme, int digest) {
+ this(name, scheme, digest, 0, 0);
+ }
+ // END android-added
+
+ protected SecretKey engineGenerateSecret(
+ KeySpec keySpec)
+ throws InvalidKeySpecException
+ {
+ if (keySpec instanceof PBEKeySpec)
+ {
+ PBEKeySpec pbeSpec = (PBEKeySpec)keySpec;
+
+ // BEGIN ANDROID-ADDED
+ // Allow to specify a key using only the password. The key will be generated later
+ // when other parameters are known.
+ if (pbeSpec.getSalt() == null
+ && pbeSpec.getIterationCount() == 0
+ && pbeSpec.getKeyLength() == 0
+ && pbeSpec.getPassword().length > 0
+ && keySizeInBits != 0) {
+ return new BCPBEKey(
+ this.algName, this.algOid, scheme, defaultDigest, keySizeInBits,
+ ivSizeInBits, pbeSpec,
+ // cipherParameters, to be generated when the PBE parameters are known.
+ null);
+ }
+ // END ANDROID-ADDED
+
+ if (pbeSpec.getSalt() == null)
+ {
+ throw new InvalidKeySpecException("missing required salt");
+ }
+
+ if (pbeSpec.getIterationCount() <= 0)
+ {
+ throw new InvalidKeySpecException("positive iteration count required: "
+ + pbeSpec.getIterationCount());
+ }
+
+ if (pbeSpec.getKeyLength() <= 0)
+ {
+ throw new InvalidKeySpecException("positive key length required: "
+ + pbeSpec.getKeyLength());
+ }
+
+ if (pbeSpec.getPassword().length == 0)
+ {
+ throw new IllegalArgumentException("password empty");
+ }
+
+ if (pbeSpec instanceof PBKDF2KeySpec)
+ {
+ PBKDF2KeySpec spec = (PBKDF2KeySpec)pbeSpec;
+
+ int digest = getDigestCode(spec.getPrf().getAlgorithm());
+ int keySize = pbeSpec.getKeyLength();
+ int ivSize = -1; // JDK 1,2 and earlier does not understand simplified version.
+ CipherParameters param = PBE.Util.makePBEMacParameters(pbeSpec, scheme, digest, keySize);
+
+ return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, param);
+ }
+ else
+ {
+ int digest = defaultDigest;
+ int keySize = pbeSpec.getKeyLength();
+ int ivSize = -1; // JDK 1,2 and earlier does not understand simplified version.
+ CipherParameters param = PBE.Util.makePBEMacParameters(pbeSpec, scheme, digest, keySize);
+
+ return new BCPBEKey(this.algName, this.algOid, scheme, digest, keySize, ivSize, pbeSpec, param);
+ }
+ }
+
+ throw new InvalidKeySpecException("Invalid KeySpec");
+ }
+
+
+ private int getDigestCode(ASN1ObjectIdentifier algorithm)
+ throws InvalidKeySpecException
+ {
+ // BEGIN android-removed
+ // if (algorithm.equals(CryptoProObjectIdentifiers.gostR3411Hmac))
+ // {
+ // return GOST3411;
+ // }
+ // else
+ // END android-removed
+ if (algorithm.equals(PKCSObjectIdentifiers.id_hmacWithSHA1))
+ {
+ return SHA1;
+ }
+ else if (algorithm.equals(PKCSObjectIdentifiers.id_hmacWithSHA256))
+ {
+ return SHA256;
+ }
+ else if (algorithm.equals(PKCSObjectIdentifiers.id_hmacWithSHA224))
+ {
+ return SHA224;
+ }
+ else if (algorithm.equals(PKCSObjectIdentifiers.id_hmacWithSHA384))
+ {
+ return SHA384;
+ }
+ else if (algorithm.equals(PKCSObjectIdentifiers.id_hmacWithSHA512))
+ {
+ return SHA512;
+ }
+
+ throw new InvalidKeySpecException("Invalid KeySpec: unknown PRF algorithm " + algorithm);
+ }
+ }
+
+ // BEGIN android-removed
+ // public static class PBKDF2withUTF8
+ // extends BasePBKDF2
+ // {
+ // public PBKDF2withUTF8()
+ // {
+ // super("PBKDF2", PKCS5S2_UTF8);
+ // }
+ // }
+ //
+ // public static class PBKDF2withSHA224
+ // extends BasePBKDF2
+ // {
+ // public PBKDF2withSHA224()
+ // {
+ // super("PBKDF2", PKCS5S2_UTF8, SHA224);
+ // }
+ // }
+ //
+ // public static class PBKDF2withSHA256
+ // extends BasePBKDF2
+ // {
+ // public PBKDF2withSHA256()
+ // {
+ // super("PBKDF2", PKCS5S2_UTF8, SHA256);
+ // }
+ // }
+ //
+ // public static class PBKDF2withSHA384
+ // extends BasePBKDF2
+ // {
+ // public PBKDF2withSHA384()
+ // {
+ // super("PBKDF2", PKCS5S2_UTF8, SHA384);
+ // }
+ // }
+ //
+ // public static class PBKDF2withSHA512
+ // extends BasePBKDF2
+ // {
+ // public PBKDF2withSHA512()
+ // {
+ // super("PBKDF2", PKCS5S2_UTF8, SHA512);
+ // }
+ // }
+ //
+ // public static class PBKDF2with8BIT
+ // extends BasePBKDF2
+ // {
+ // public PBKDF2with8BIT()
+ // {
+ // super("PBKDF2", PKCS5S2);
+ // }
+ // }
+
+ // BEGIN android-added
+ public static class BasePBKDF2WithHmacSHA1 extends BasePBKDF2 {
+ public BasePBKDF2WithHmacSHA1(String name, int scheme)
+ {
+ super(name, scheme, SHA1);
+ }
+ }
+
+ public static class PBKDF2WithHmacSHA1UTF8
+ extends BasePBKDF2WithHmacSHA1
+ {
+ public PBKDF2WithHmacSHA1UTF8()
+ {
+ super("PBKDF2WithHmacSHA1", PKCS5S2_UTF8);
+ }
+ }
+
+ public static class PBKDF2WithHmacSHA18BIT
+ extends BasePBKDF2WithHmacSHA1
+ {
+ public PBKDF2WithHmacSHA18BIT()
+ {
+ super("PBKDF2WithHmacSHA1And8bit", PKCS5S2);
+ }
+ }
+
+ public static class BasePBKDF2WithHmacSHA224 extends BasePBKDF2 {
+ public BasePBKDF2WithHmacSHA224(String name, int scheme)
+ {
+ super(name, scheme, SHA224);
+ }
+ }
+
+ public static class PBKDF2WithHmacSHA224UTF8
+ extends BasePBKDF2WithHmacSHA224
+ {
+ public PBKDF2WithHmacSHA224UTF8()
+ {
+ super("PBKDF2WithHmacSHA224", PKCS5S2_UTF8);
+ }
+ }
+
+ public static class BasePBKDF2WithHmacSHA256 extends BasePBKDF2 {
+ public BasePBKDF2WithHmacSHA256(String name, int scheme)
+ {
+ super(name, scheme, SHA256);
+ }
+ }
+
+ public static class PBKDF2WithHmacSHA256UTF8
+ extends BasePBKDF2WithHmacSHA256
+ {
+ public PBKDF2WithHmacSHA256UTF8()
+ {
+ super("PBKDF2WithHmacSHA256", PKCS5S2_UTF8);
+ }
+ }
+
+
+ public static class BasePBKDF2WithHmacSHA384 extends BasePBKDF2 {
+ public BasePBKDF2WithHmacSHA384(String name, int scheme)
+ {
+ super(name, scheme, SHA384);
+ }
+ }
+
+ public static class PBKDF2WithHmacSHA384UTF8
+ extends BasePBKDF2WithHmacSHA384
+ {
+ public PBKDF2WithHmacSHA384UTF8()
+ {
+ super("PBKDF2WithHmacSHA384", PKCS5S2_UTF8);
+ }
+ }
+
+ public static class BasePBKDF2WithHmacSHA512 extends BasePBKDF2 {
+ public BasePBKDF2WithHmacSHA512(String name, int scheme)
+ {
+ super(name, scheme, SHA512);
+ }
+ }
+
+ public static class PBKDF2WithHmacSHA512UTF8
+ extends BasePBKDF2WithHmacSHA512
+ {
+ public PBKDF2WithHmacSHA512UTF8()
+ {
+ super("PBKDF2WithHmacSHA512", PKCS5S2_UTF8);
+ }
+ }
+
+ public static class PBEWithHmacSHA1AndAES_128
+ extends BasePBKDF2 {
+ public PBEWithHmacSHA1AndAES_128() {
+ super("PBEWithHmacSHA1AndAES_128", PKCS5S2_UTF8, SHA1, 128, 128);
+ }
+ }
+
+ public static class PBEWithHmacSHA224AndAES_128
+ extends BasePBKDF2 {
+ public PBEWithHmacSHA224AndAES_128() {
+ super("PBEWithHmacSHA224AndAES_128", PKCS5S2_UTF8, SHA224, 128, 128);
+ }
+ }
+
+ public static class PBEWithHmacSHA256AndAES_128
+ extends BasePBKDF2 {
+ public PBEWithHmacSHA256AndAES_128() {
+ super("PBEWithHmacSHA256AndAES_128", PKCS5S2_UTF8, SHA256, 128, 128);
+ }
+ }
+
+ public static class PBEWithHmacSHA384AndAES_128
+ extends BasePBKDF2 {
+ public PBEWithHmacSHA384AndAES_128() {
+ super("PBEWithHmacSHA384AndAES_128", PKCS5S2_UTF8, SHA384, 128, 128);
+ }
+ }
+
+ public static class PBEWithHmacSHA512AndAES_128
+ extends BasePBKDF2 {
+ public PBEWithHmacSHA512AndAES_128() {
+ super("PBEWithHmacSHA512AndAES_128", PKCS5S2_UTF8, SHA512, 128, 128);
+ }
+ }
+
+
+ public static class PBEWithHmacSHA1AndAES_256
+ extends BasePBKDF2 {
+ public PBEWithHmacSHA1AndAES_256() {
+ super("PBEWithHmacSHA1AndAES_256", PKCS5S2_UTF8, SHA1, 256, 128);
+ }
+ }
+
+ public static class PBEWithHmacSHA224AndAES_256
+ extends BasePBKDF2 {
+ public PBEWithHmacSHA224AndAES_256() {
+ super("PBEWithHmacSHA224AndAES_256", PKCS5S2_UTF8, SHA224, 256, 128);
+ }
+ }
+
+ public static class PBEWithHmacSHA256AndAES_256
+ extends BasePBKDF2 {
+ public PBEWithHmacSHA256AndAES_256() {
+ super("PBEWithHmacSHA256AndAES_256", PKCS5S2_UTF8, SHA256, 256, 128);
+ }
+ }
+
+ public static class PBEWithHmacSHA384AndAES_256
+ extends BasePBKDF2 {
+ public PBEWithHmacSHA384AndAES_256() {
+ super("PBEWithHmacSHA384AndAES_256", PKCS5S2_UTF8, SHA384, 256, 128);
+ }
+ }
+
+ public static class PBEWithHmacSHA512AndAES_256
+ extends BasePBKDF2 {
+ public PBEWithHmacSHA512AndAES_256() {
+ super("PBEWithHmacSHA512AndAES_256", PKCS5S2_UTF8, SHA512, 256, 128);
+ }
+ }
+ // END android-added
+
+ public static class Mappings
+ extends AlgorithmProvider
+ {
+ private static final String PREFIX = PBEPBKDF2.class.getName();
+
+ public Mappings()
+ {
+ }
+
+ public void configure(ConfigurableProvider provider)
+ {
+ // BEGIN android-comment
+ // Context: many of these services used to be in
+ // com.android.org.bouncycastle.jcajce.provider.digest,SHA1, duplicated with respect to here. This
+ // class (PBEPBKDF2) wasn't present in Android until the upgrade to 1.56. Android added
+ // some other of these services in SHA1 (for fixed key sizes). Then the duplicate
+ // algorithms were removed upstream from SHA1 in
+ // b5634e3155e7fd8688599d3eef8e4f3c8a1db078
+ // . As a result, when adapting BouncyCastle 1.56 from upstream, the Android code that
+ // had been added to SHA1 was moved here, and the rest of the services provided by this
+ // class were commented.
+ // BEGIN android-removed
+ // provider.addAlgorithm("AlgorithmParameters.PBKDF2", PREFIX + "$AlgParams");
+ // provider.addAlgorithm("Alg.Alias.AlgorithmParameters." + PKCSObjectIdentifiers.id_PBKDF2, "PBKDF2");
+ // provider.addAlgorithm("SecretKeyFactory.PBKDF2", PREFIX + "$PBKDF2withUTF8");
+ // provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2WITHHMACSHA1", "PBKDF2");
+ // END android-removed
+ // BEGIN android-changed
+ // Was: provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2WITHHMACSHA1ANDUTF8", "PBKDF2");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2WithHmacSHA1AndUTF8", "PBKDF2WithHmacSHA1");
+ // END android-changed
+ // BEGin android-removed
+ // provider.addAlgorithm("Alg.Alias.SecretKeyFactory." + PKCSObjectIdentifiers.id_PBKDF2, "PBKDF2");
+ // provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHASCII", PREFIX + "$PBKDF2with8BIT");
+ // END android-removed
+ // BEGIN android-changed
+ // Was:
+ // provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2WITH8BIT", "PBKDF2WITHASCII");
+ // provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2WITHHMACSHA1AND8BIT", "PBKDF2WITHASCII");
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2with8BIT", "PBKDF2WithHmacSHA1And8BIT");
+ // END android-changed
+ // BEGIN android-added
+ provider.addAlgorithm("Alg.Alias.SecretKeyFactory.PBKDF2withASCII", "PBKDF2WithHmacSHA1And8BIT");
+ // BEGIN android-removed
+ // provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSHA224", PREFIX + "$PBKDF2withSHA224");
+ // provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSHA256", PREFIX + "$PBKDF2withSHA256");
+ // provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSHA384", PREFIX + "$PBKDF2withSHA384");
+ // provider.addAlgorithm("SecretKeyFactory.PBKDF2WITHHMACSHA512", PREFIX + "$PBKDF2withSHA512");
+ // END android-removed
+ // BEGIN android-added
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA1", PREFIX + "$PBKDF2WithHmacSHA1UTF8");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA224", PREFIX + "$PBKDF2WithHmacSHA224UTF8");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA256", PREFIX + "$PBKDF2WithHmacSHA256UTF8");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA384", PREFIX + "$PBKDF2WithHmacSHA384UTF8");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA512", PREFIX + "$PBKDF2WithHmacSHA512UTF8");
+ provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA1AndAES_128", PREFIX + "$PBEWithHmacSHA1AndAES_128");
+ provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA224AndAES_128", PREFIX + "$PBEWithHmacSHA224AndAES_128");
+ provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA256AndAES_128", PREFIX + "$PBEWithHmacSHA256AndAES_128");
+ provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA384AndAES_128", PREFIX + "$PBEWithHmacSHA384AndAES_128");
+ provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA512AndAES_128", PREFIX + "$PBEWithHmacSHA512AndAES_128");
+ provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA1AndAES_256", PREFIX + "$PBEWithHmacSHA1AndAES_256");
+ provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA224AndAES_256", PREFIX + "$PBEWithHmacSHA224AndAES_256");
+ provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA256AndAES_256", PREFIX + "$PBEWithHmacSHA256AndAES_256");
+ provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA384AndAES_256", PREFIX + "$PBEWithHmacSHA384AndAES_256");
+ provider.addAlgorithm("SecretKeyFactory.PBEWithHmacSHA512AndAES_256", PREFIX + "$PBEWithHmacSHA512AndAES_256");
+ provider.addAlgorithm("SecretKeyFactory.PBKDF2WithHmacSHA1And8BIT", PREFIX + "$PBKDF2WithHmacSHA18BIT");
+ // END android-added
+ }
+ }
+}
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 343fa0c7..7bc1e713 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
@@ -215,7 +215,7 @@ public final class RC2
// extends BaseAlgorithmParameterGenerator
// {
// RC2ParameterSpec spec = null;
- //
+
// protected void engineInit(
// AlgorithmParameterSpec genParamSpec,
// SecureRandom random)
@@ -226,25 +226,25 @@ public final class RC2
// spec = (RC2ParameterSpec)genParamSpec;
// return;
// }
- //
+
// throw new InvalidAlgorithmParameterException("No supported AlgorithmParameterSpec for RC2 parameter generation.");
// }
- //
+
// protected AlgorithmParameters engineGenerateParameters()
// {
// AlgorithmParameters params;
- //
+
// if (spec == null)
// {
// byte[] iv = new byte[8];
- //
+
// if (random == null)
// {
// random = new SecureRandom();
// }
- //
+
// random.nextBytes(iv);
- //
+
// try
// {
// params = createParametersInstance("RC2");
@@ -267,11 +267,11 @@ public final class RC2
// throw new RuntimeException(e.getMessage());
// }
// }
- //
+
// return params;
// }
// }
- //
+
// public static class KeyGenerator
// extends BaseKeyGenerator
// {
@@ -280,7 +280,7 @@ public final class RC2
// super("RC2", 128, new CipherKeyGenerator());
// }
// }
- //
+
// public static class AlgParams
// extends BaseAlgorithmParameters
// {
@@ -302,7 +302,7 @@ public final class RC2
// 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f,
// 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab
// };
- //
+
// private static final short[] ekb = {
// 0x5d, 0xbe, 0x9b, 0x8b, 0x11, 0x99, 0x6e, 0x4d, 0x59, 0xf3, 0x85, 0xa6, 0x3f, 0xb7, 0x83, 0xc5,
// 0xe4, 0x73, 0x6b, 0x3a, 0x68, 0x5a, 0xc0, 0x47, 0xa0, 0x64, 0x34, 0x0c, 0xf1, 0xd0, 0x52, 0xa5,
@@ -321,15 +321,15 @@ public final class RC2
// 0xbd, 0x22, 0xbf, 0x9f, 0x7e, 0xa9, 0x51, 0x4b, 0x4c, 0xfb, 0x02, 0xd3, 0x70, 0x86, 0x31, 0xe7,
// 0x3b, 0x05, 0x03, 0x54, 0x60, 0x48, 0x65, 0x18, 0xd2, 0xcd, 0x5f, 0x32, 0x88, 0x0e, 0x35, 0xfd
// };
- //
+
// private byte[] iv;
// private int parameterVersion = 58;
- //
+
// protected byte[] engineGetEncoded()
// {
// return Arrays.clone(iv);
// }
- //
+
// protected byte[] engineGetEncoded(
// String format)
// throws IOException
@@ -345,20 +345,20 @@ public final class RC2
// return new RC2CBCParameter(parameterVersion, engineGetEncoded()).getEncoded();
// }
// }
- //
+
// if (format.equals("RAW"))
// {
// return engineGetEncoded();
// }
- //
+
// return null;
// }
- //
+
// protected AlgorithmParameterSpec localEngineGetParameterSpec(
// Class paramSpec)
// throws InvalidParameterSpecException
// {
- // if (paramSpec == RC2ParameterSpec.class)
+ // if (paramSpec == RC2ParameterSpec.class || paramSpec == AlgorithmParameterSpec.class)
// {
// if (parameterVersion != -1)
// {
@@ -372,15 +372,15 @@ public final class RC2
// }
// }
// }
- //
- // if (paramSpec == IvParameterSpec.class)
+
+ // if (paramSpec == IvParameterSpec.class || paramSpec == AlgorithmParameterSpec.class)
// {
// return new IvParameterSpec(iv);
// }
- //
+
// throw new InvalidParameterSpecException("unknown parameter spec passed to RC2 parameters object.");
// }
- //
+
// protected void engineInit(
// AlgorithmParameterSpec paramSpec)
// throws InvalidParameterSpecException
@@ -403,7 +403,7 @@ public final class RC2
// parameterVersion = effKeyBits;
// }
// }
- //
+
// this.iv = ((RC2ParameterSpec)paramSpec).getIV();
// }
// else
@@ -411,14 +411,14 @@ public final class RC2
// throw new InvalidParameterSpecException("IvParameterSpec or RC2ParameterSpec required to initialise a RC2 parameters algorithm parameters object");
// }
// }
- //
+
// protected void engineInit(
// byte[] params)
// throws IOException
// {
// this.iv = Arrays.clone(params);
// }
- //
+
// protected void engineInit(
// byte[] params,
// String format)
@@ -427,26 +427,26 @@ public final class RC2
// if (this.isASN1FormatString(format))
// {
// RC2CBCParameter p = RC2CBCParameter.getInstance(ASN1Primitive.fromByteArray(params));
- //
+
// if (p.getRC2ParameterVersion() != null)
// {
// parameterVersion = p.getRC2ParameterVersion().intValue();
// }
- //
+
// iv = p.getIV();
- //
+
// return;
// }
- //
+
// if (format.equals("RAW"))
// {
// engineInit(params);
// return;
// }
- //
+
// throw new IOException("Unknown parameters format in IV parameters object");
// }
- //
+
// protected String engineToString()
// {
// return "RC2 Parameters";
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 fd99c41e..59b715ad 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
@@ -78,6 +78,7 @@ import org.bouncycastle.crypto.params.RC2Parameters;
// END android-removed
import org.bouncycastle.jcajce.PKCS12Key;
import org.bouncycastle.jcajce.PKCS12KeyWithParameters;
+import org.bouncycastle.jcajce.spec.AEADParameterSpec;
// BEGIN android-removed
// import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec;
// import org.bouncycastle.jcajce.spec.RepeatedSecretKeySpec;
@@ -177,9 +178,9 @@ public class BaseBlockCipher
protected BaseBlockCipher(
AEADBlockCipher engine)
{
- baseEngine = engine.getUnderlyingCipher();
- ivLength = baseEngine.getBlockSize();
- cipher = new AEADGenericBlockCipher(engine);
+ this.baseEngine = engine.getUnderlyingCipher();
+ this.ivLength = baseEngine.getBlockSize();
+ this.cipher = new AEADGenericBlockCipher(engine);
}
protected BaseBlockCipher(
@@ -256,6 +257,18 @@ public class BaseBlockCipher
return null;
}
}
+ else if (aeadParams != null)
+ {
+ try
+ {
+ engineParams = createParametersInstance("GCM");
+ engineParams.init(new GCMParameters(aeadParams.getNonce(), aeadParams.getMacSize() / 8).getEncoded());
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e.toString());
+ }
+ }
else if (ivParam != null)
{
String name = cipher.getUnderlyingCipher().getAlgorithmName();
@@ -275,18 +288,6 @@ public class BaseBlockCipher
throw new RuntimeException(e.toString());
}
}
- else if (aeadParams != null)
- {
- try
- {
- engineParams = createParametersInstance("GCM");
- engineParams.init(new GCMParameters(aeadParams.getNonce(), aeadParams.getMacSize() / 8).getEncoded());
- }
- catch (Exception e)
- {
- throw new RuntimeException(e.toString());
- }
- }
}
return engineParams;
@@ -515,7 +516,7 @@ public class BaseBlockCipher
//
if (!(key instanceof SecretKey))
{
- throw new InvalidKeyException("Key for algorithm " + key.getAlgorithm() + " not suitable for symmetric enryption.");
+ throw new InvalidKeyException("Key for algorithm " + ((key != null) ? key.getAlgorithm() : null) + " not suitable for symmetric enryption.");
}
//
@@ -553,34 +554,29 @@ public class BaseBlockCipher
if (k instanceof PBEKey && pbeSpec == null)
{
- // BEGIN android-added
- if (((PBEKey)k).getSalt() == null) {
- throw new InvalidAlgorithmParameterException("Parameters for the algorithm are null "
- + "and the PBEKey has null salt");
+ PBEKey pbeKey = (PBEKey)k;
+ if (pbeKey.getSalt() == null)
+ {
+ throw new InvalidAlgorithmParameterException("PBEKey requires parameters to specify salt");
}
- // END android-added
- pbeSpec = new PBEParameterSpec(((PBEKey)k).getSalt(), ((PBEKey)k).getIterationCount());
+ pbeSpec = new PBEParameterSpec(pbeKey.getSalt(), pbeKey.getIterationCount());
}
if (pbeSpec == null && !(k instanceof PBEKey))
{
throw new InvalidKeyException("Algorithm requires a PBE key");
}
+
if (key instanceof BCPBEKey)
{
- // BEGIN android-changed
- // Was:
- // if (((BCPBEKey)key).getParam() != null)
- // Change taken from:
- // https://github.com/bcgit/bc-java/commit/fcba5c782188d772148ba168beae368d06646ee2
- // PKCS#12 sets an IV, if we get a key that doesn't have ParametersWithIV we need to forget about the fact
- // it's a BCPBEKey
- if (((BCPBEKey)key).getParam() != null && ((BCPBEKey)key).getParam() instanceof ParametersWithIV)
- // END android-changed
+ // PKCS#12 sets an IV, if we get a key that doesn't have ParametersWithIV we need to reject it. If the
+ // key has no parameters it means it's an old-school JCE PBE Key - we use getEncoded() on it.
+ CipherParameters pbeKeyParam = ((BCPBEKey)key).getParam();
+ if (pbeKeyParam instanceof ParametersWithIV)
{
- param = ((BCPBEKey)key).getParam();
+ param = pbeKeyParam;
}
- else
+ else if (pbeKeyParam == null)
{
// BEGIN android-changed
// Was: param = PBE.Util.makePBEParameters(k.getEncoded(), PKCS12, digest, keySizeInBits, ivLength * 8, pbeSpec, cipher.getAlgorithmName());
@@ -590,6 +586,10 @@ public class BaseBlockCipher
// END android-changed
throw new IllegalStateException("Unreachable code");
}
+ else
+ {
+ throw new InvalidKeyException("Algorithm requires a PBE key suitable for PKCS12");
+ }
}
else
{
@@ -696,7 +696,27 @@ public class BaseBlockCipher
// }
// END android-removed
- if (params instanceof IvParameterSpec)
+ if (params instanceof AEADParameterSpec)
+ {
+ if (!isAEADModeName(modeName) && !(cipher instanceof AEADGenericBlockCipher))
+ {
+ throw new InvalidAlgorithmParameterException("AEADParameterSpec can only be used with AEAD modes.");
+ }
+
+ AEADParameterSpec aeadSpec = (AEADParameterSpec)params;
+
+ KeyParameter keyParam;
+ if (param instanceof ParametersWithIV)
+ {
+ keyParam = (KeyParameter)((ParametersWithIV)param).getParameters();
+ }
+ else
+ {
+ keyParam = (KeyParameter)param;
+ }
+ param = aeadParams = new AEADParameters(keyParam, aeadSpec.getMacSizeInBits(), aeadSpec.getNonce(), aeadSpec.getAssociatedData());
+ }
+ else if (params instanceof IvParameterSpec)
{
if (ivLength != 0)
{
@@ -878,6 +898,8 @@ public class BaseBlockCipher
}
}
+
+
if (random != null && padded)
{
param = new ParametersWithRandom(param, random);
@@ -898,16 +920,17 @@ public class BaseBlockCipher
default:
throw new InvalidParameterException("unknown opmode " + opmode + " passed");
}
+
+ if (cipher instanceof AEADGenericBlockCipher && aeadParams == null)
+ {
+ AEADBlockCipher aeadCipher = ((AEADGenericBlockCipher)cipher).cipher;
+
+ aeadParams = new AEADParameters((KeyParameter)ivParam.getParameters(), aeadCipher.getMac().length * 8, ivParam.getIV());
+ }
}
catch (final Exception e)
{
- throw new InvalidKeyException(e.getMessage())
- {
- public Throwable getCause()
- {
- return e;
- }
- };
+ throw new InvalidKeyOrParametersException(e.getMessage(), e);
}
}
@@ -1393,4 +1416,21 @@ public class BaseBlockCipher
}
}
}
+
+ private static class InvalidKeyOrParametersException
+ extends InvalidKeyException
+ {
+ private final Throwable cause;
+
+ InvalidKeyOrParametersException(String msg, Throwable cause)
+ {
+ super(msg);
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+ }
}
diff --git a/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 f6076170..51c29d96 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseMac.java
@@ -1,5 +1,6 @@
package org.bouncycastle.jcajce.provider.symmetric.util;
+import java.lang.reflect.Method;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
@@ -13,15 +14,19 @@ import javax.crypto.SecretKey;
import javax.crypto.interfaces.PBEKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEParameterSpec;
+import javax.crypto.spec.RC2ParameterSpec;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.Mac;
+import org.bouncycastle.crypto.params.AEADParameters;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
// BEGIN android-removed
+// import org.bouncycastle.crypto.params.RC2Parameters;
// import org.bouncycastle.crypto.params.SkeinParameters;
// END android-removed
import org.bouncycastle.jcajce.PKCS12Key;
+import org.bouncycastle.jcajce.spec.AEADParameterSpec;
// BEGIN android-removed
// import org.bouncycastle.jcajce.spec.SkeinParameterSpec;
// END android-removed
@@ -29,6 +34,8 @@ import org.bouncycastle.jcajce.PKCS12Key;
public class BaseMac
extends MacSpi implements PBE
{
+ private static final Class gcmSpecClass = lookup("javax.crypto.spec.GCMParameterSpec");
+
private Mac macEngine;
private int scheme = PKCS12;
@@ -129,26 +136,77 @@ public class BaseMac
throw new InvalidAlgorithmParameterException("PBE requires PBE parameters to be set.");
}
}
+ else
+ {
+ if (params instanceof PBEParameterSpec)
+ {
+ throw new InvalidAlgorithmParameterException("inappropriate parameter type: " + params.getClass().getName());
+ }
+ param = new KeyParameter(key.getEncoded());
+ }
+
+ KeyParameter keyParam;
+ if (param instanceof ParametersWithIV)
+ {
+ keyParam = (KeyParameter)((ParametersWithIV)param).getParameters();
+ }
+ else
+ {
+ keyParam = (KeyParameter)param;
+ }
+
+ if (params instanceof AEADParameterSpec)
+ {
+ AEADParameterSpec aeadSpec = (AEADParameterSpec)params;
+
+ param = new AEADParameters(keyParam, aeadSpec.getMacSizeInBits(), aeadSpec.getNonce(), aeadSpec.getAssociatedData());
+ }
else if (params instanceof IvParameterSpec)
{
- param = new ParametersWithIV(new KeyParameter(key.getEncoded()), ((IvParameterSpec)params).getIV());
+ param = new ParametersWithIV(keyParam, ((IvParameterSpec)params).getIV());
}
// BEGIN android-removed
+ // else if (params instanceof RC2ParameterSpec)
+ // {
+ // param = new ParametersWithIV(new RC2Parameters(keyParam.getKey(), ((RC2ParameterSpec)params).getEffectiveKeyBits()), ((RC2ParameterSpec)params).getIV());
+ // }
+
// else if (params instanceof SkeinParameterSpec)
// {
- // param = new SkeinParameters.Builder(copyMap(((SkeinParameterSpec)params).getParameters())).setKey(key.getEncoded()).build();
+ // param = new SkeinParameters.Builder(copyMap(((SkeinParameterSpec)params).getParameters())).setKey(keyParam.getKey()).build();
// }
// END android-removed
else if (params == null)
{
param = new KeyParameter(key.getEncoded());
}
- else
+ else if (gcmSpecClass != null && gcmSpecClass.isAssignableFrom(params.getClass()))
{
- throw new InvalidAlgorithmParameterException("unknown parameter type.");
+ try
+ {
+ Method tLen = gcmSpecClass.getDeclaredMethod("getTLen", new Class[0]);
+ Method iv= gcmSpecClass.getDeclaredMethod("getIV", new Class[0]);
+
+ param = new AEADParameters(keyParam, ((Integer)tLen.invoke(params, new Object[0])).intValue(), (byte[])iv.invoke(params, new Object[0]));
+ }
+ catch (Exception e)
+ {
+ throw new InvalidAlgorithmParameterException("Cannot process GCMParameterSpec.");
+ }
+ }
+ else if (!(params instanceof PBEParameterSpec))
+ {
+ throw new InvalidAlgorithmParameterException("unknown parameter type: " + params.getClass().getName());
}
- macEngine.init(param);
+ try
+ {
+ macEngine.init(param);
+ }
+ catch (Exception e)
+ {
+ throw new InvalidAlgorithmParameterException("cannot initialize MAC: " + e.getMessage());
+ }
}
protected int engineGetMacLength()
@@ -197,4 +255,18 @@ public class BaseMac
return newTable;
}
+
+ private static Class lookup(String className)
+ {
+ try
+ {
+ Class def = BaseBlockCipher.class.getClassLoader().loadClass(className);
+
+ return def;
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseSecretKeyFactory.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseSecretKeyFactory.java
index 31896cd2..9e798428 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseSecretKeyFactory.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/BaseSecretKeyFactory.java
@@ -32,7 +32,7 @@ public class BaseSecretKeyFactory
{
if (keySpec instanceof SecretKeySpec)
{
- return (SecretKey)keySpec;
+ return new SecretKeySpec(((SecretKeySpec)keySpec).getEncoded(), algName);
}
throw new InvalidKeySpecException("Invalid KeySpec");
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 ece0d146..e2c86766 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
@@ -102,7 +102,7 @@ public abstract class BaseWrapCipher
protected int engineGetKeySize(
Key key)
{
- return key.getEncoded().length;
+ return key.getEncoded().length * 8;
}
protected int engineGetOutputSize(
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/IvAlgorithmParameters.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/IvAlgorithmParameters.java
index b5a95526..84da1003 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/IvAlgorithmParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/symmetric/util/IvAlgorithmParameters.java
@@ -43,7 +43,7 @@ public class IvAlgorithmParameters
Class paramSpec)
throws InvalidParameterSpecException
{
- if (paramSpec == IvParameterSpec.class)
+ if (paramSpec == IvParameterSpec.class || paramSpec == AlgorithmParameterSpec.class)
{
return new IvParameterSpec(iv);
}
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 be131f4e..2e4f96b5 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
@@ -13,18 +13,15 @@ import javax.crypto.spec.PBEParameterSpec;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.PBEParametersGenerator;
+// BEGIN android-added
+import org.bouncycastle.crypto.digests.AndroidDigestFactory;
+// END android-added
// BEGIN android-removed
// import org.bouncycastle.crypto.digests.GOST3411Digest;
// import org.bouncycastle.crypto.digests.MD2Digest;
-// import org.bouncycastle.crypto.digests.MD5Digest;
// import org.bouncycastle.crypto.digests.RIPEMD160Digest;
-// import org.bouncycastle.crypto.digests.SHA1Digest;
-// import org.bouncycastle.crypto.digests.SHA256Digest;
// import org.bouncycastle.crypto.digests.TigerDigest;
// END android-removed
-// BEGIN android-added
-import org.bouncycastle.crypto.digests.AndroidDigestFactory;
-// END android-added
import org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator;
import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator;
import org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator;
@@ -32,6 +29,9 @@ import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
import org.bouncycastle.crypto.params.DESParameters;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
+// BEGIN android-removed
+// import org.bouncycastle.crypto.util.DigestFactory;
+// END android-removed
public interface PBE
{
@@ -49,6 +49,9 @@ public interface PBE
// static final int MD2 = 5;
// static final int GOST3411 = 6;
// END android-removed
+ static final int SHA224 = 7;
+ static final int SHA384 = 8;
+ static final int SHA512 = 9;
static final int PKCS5S1 = 0;
static final int PKCS5S2 = 1;
@@ -56,11 +59,6 @@ public interface PBE
static final int OPENSSL = 3;
static final int PKCS5S1_UTF8 = 4;
static final int PKCS5S2_UTF8 = 5;
- // BEGIN android-added
- static final int SHA224 = 6;
- static final int SHA384 = 7;
- static final int SHA512 = 8;
- // END android-added
/**
@@ -111,6 +109,7 @@ public interface PBE
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getMD5());
// END android-changed
break;
+
case SHA1:
// BEGIN android-changed
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA1());
@@ -142,11 +141,6 @@ public interface PBE
generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA512());
break;
// END android-added
- // BEGIN android-removed
- // case GOST3411:
- // generator = new PKCS5S2ParametersGenerator(new GOST3411Digest());
- // break;
- // END android-removed
default:
throw new IllegalStateException("unknown digest scheme for PBE PKCS5S2 encryption.");
}
@@ -195,12 +189,6 @@ public interface PBE
case SHA512:
generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA512());
break;
- // END android-added
- // BEGIN android-removed
- // case GOST3411:
- // generator = new PKCS12ParametersGenerator(new GOST3411Digest());
- // break;
- // END android-removed
default:
throw new IllegalStateException("unknown digest scheme for PBE encryption.");
}
@@ -284,11 +272,6 @@ public interface PBE
}
}
- for (int i = 0; i != key.length; i++)
- {
- key[i] = 0;
- }
-
return param;
}
@@ -358,11 +341,6 @@ public interface PBE
}
}
- for (int i = 0; i != key.length; i++)
- {
- key[i] = 0;
- }
-
return param;
}
@@ -388,11 +366,6 @@ public interface PBE
generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount());
param = generator.generateDerivedMacParameters(pbeKey.getKeySize());
-
- for (int i = 0; i != key.length; i++)
- {
- key[i] = 0;
- }
return param;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/util/BadBlockException.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/util/BadBlockException.java
new file mode 100644
index 00000000..e2a8d63d
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/util/BadBlockException.java
@@ -0,0 +1,21 @@
+package org.bouncycastle.jcajce.provider.util;
+
+import javax.crypto.BadPaddingException;
+
+public class BadBlockException
+ extends BadPaddingException
+{
+ private final Throwable cause;
+
+ public BadBlockException(String msg, Throwable cause)
+ {
+ super(msg);
+
+ this.cause = cause;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/provider/util/DigestFactory.java b/bcprov/src/main/java/org/bouncycastle/jcajce/provider/util/DigestFactory.java
index ce8bb363..9869b1c6 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
@@ -10,15 +10,6 @@ import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.crypto.Digest;
-// BEGIN android-removed
-// import org.bouncycastle.crypto.digests.MD5Digest;
-// import org.bouncycastle.crypto.digests.SHA1Digest;
-// import org.bouncycastle.crypto.digests.SHA224Digest;
-// 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
@@ -35,6 +26,10 @@ public class DigestFactory
// BEGIN android-removed
// private static Set sha512_224 = new HashSet();
// private static Set sha512_256 = new HashSet();
+ // private static Set sha3_224 = new HashSet();
+ // private static Set sha3_256 = new HashSet();
+ // private static Set sha3_384 = new HashSet();
+ // private static Set sha3_512 = new HashSet();
// END android-removed
private static Map oids = new HashMap();
@@ -72,8 +67,21 @@ public class DigestFactory
// sha512_256.add("SHA512(256)");
// sha512_256.add("SHA-512(256)");
// sha512_256.add(NISTObjectIdentifiers.id_sha512_256.getId());
+
+ // sha3_224.add("SHA3-224");
+ // sha3_224.add(NISTObjectIdentifiers.id_sha3_224.getId());
+
+ // sha3_256.add("SHA3-256");
+ // sha3_256.add(NISTObjectIdentifiers.id_sha3_256.getId());
+
+ // sha3_384.add("SHA3-384");
+ // sha3_384.add(NISTObjectIdentifiers.id_sha3_384.getId());
+
+ // sha3_512.add("SHA3-512");
+ // sha3_512.add(NISTObjectIdentifiers.id_sha3_512.getId());
// END android-removed
+
oids.put("MD5", PKCSObjectIdentifiers.md5);
oids.put(PKCSObjectIdentifiers.md5.getId(), PKCSObjectIdentifiers.md5);
@@ -104,6 +112,18 @@ public class DigestFactory
oids.put("SHA512(256)", NISTObjectIdentifiers.id_sha512_256);
oids.put("SHA-512(256)", NISTObjectIdentifiers.id_sha512_256);
oids.put(NISTObjectIdentifiers.id_sha512_256.getId(), NISTObjectIdentifiers.id_sha512_256);
+
+ oids.put("SHA3-224", NISTObjectIdentifiers.id_sha3_224);
+ oids.put(NISTObjectIdentifiers.id_sha3_224.getId(), NISTObjectIdentifiers.id_sha3_224);
+
+ oids.put("SHA3-256", NISTObjectIdentifiers.id_sha3_256);
+ oids.put(NISTObjectIdentifiers.id_sha3_256.getId(), NISTObjectIdentifiers.id_sha3_256);
+
+ oids.put("SHA3-384", NISTObjectIdentifiers.id_sha3_384);
+ oids.put(NISTObjectIdentifiers.id_sha3_384.getId(), NISTObjectIdentifiers.id_sha3_384);
+
+ oids.put("SHA3-512", NISTObjectIdentifiers.id_sha3_512);
+ oids.put(NISTObjectIdentifiers.id_sha3_512.getId(), NISTObjectIdentifiers.id_sha3_512);
}
public static Digest getDigest(
@@ -141,8 +161,7 @@ public class DigestFactory
return AndroidDigestFactory.getSHA384();
// END android-changed
}
- if (sha512.contains(digestName))
- {
+ if (sha512.contains(digestName)) {
// BEGIN android-changed
return AndroidDigestFactory.getSHA512();
// END android-changed
@@ -150,13 +169,29 @@ public class DigestFactory
// BEGIN android-removed
// if (sha512_224.contains(digestName))
// {
- // return new SHA512tDigest(224);
+ // return org.bouncycastle.crypto.util.DigestFactory.createSHA512_224();
// }
// if (sha512_256.contains(digestName))
// {
- // return new SHA512tDigest(256);
+ // return org.bouncycastle.crypto.util.DigestFactory.createSHA512_256();
+ // }
+ //
+ // if (sha3_224.contains(digestName))
+ // {
+ // return org.bouncycastle.crypto.util.DigestFactory.createSHA3_224();
+ // }
+ // if (sha3_256.contains(digestName))
+ // {
+ // return org.bouncycastle.crypto.util.DigestFactory.createSHA3_256();
+ // }
+ // if (sha3_384.contains(digestName))
+ // {
+ // return org.bouncycastle.crypto.util.DigestFactory.createSHA3_384();
+ // }
+ // if (sha3_512.contains(digestName))
+ // {
+ // return org.bouncycastle.crypto.util.DigestFactory.createSHA3_512();
// }
- // END android-removed
return null;
}
@@ -173,6 +208,10 @@ public class DigestFactory
// BEGIN android-removed
// || (sha512_224.contains(digest1) && sha512_224.contains(digest2))
// || (sha512_256.contains(digest1) && sha512_256.contains(digest2))
+ // || (sha3_224.contains(digest1) && sha3_224.contains(digest2))
+ // || (sha3_256.contains(digest1) && sha3_256.contains(digest2))
+ // || (sha3_384.contains(digest1) && sha3_384.contains(digest2))
+ // || (sha3_512.contains(digest1) && sha3_512.contains(digest2))
// END android-removed
|| (md5.contains(digest1) && md5.contains(digest2));
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/spec/AEADParameterSpec.java b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/AEADParameterSpec.java
new file mode 100644
index 00000000..b5d9657a
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/AEADParameterSpec.java
@@ -0,0 +1,73 @@
+package org.bouncycastle.jcajce.spec;
+
+import javax.crypto.spec.IvParameterSpec;
+
+import org.bouncycastle.util.Arrays;
+
+/**
+ * ParameterSpec for AEAD modes which allows associated data to be added via an algorithm parameter spec.In normal
+ * circumstances you would only want to use this if you had to work with the pre-JDK1.7 Cipher class as associated
+ * data is ignored for the purposes of returning a Cipher's parameters.
+ */
+public class AEADParameterSpec
+ extends IvParameterSpec
+{
+ private final byte[] associatedData;
+ private final int macSizeInBits;
+
+ /**
+ * Base constructor.
+ *
+ * @param nonce nonce/iv to be used
+ * @param macSizeInBits macSize in bits
+ */
+ public AEADParameterSpec(byte[] nonce, int macSizeInBits)
+ {
+ this(nonce, macSizeInBits, null);
+ }
+
+ /**
+ * Base constructor with prepended associated data.
+ *
+ * @param nonce nonce/iv to be used
+ * @param macSizeInBits macSize in bits
+ * @param associatedData associated data to be prepended to the cipher stream.
+ */
+ public AEADParameterSpec(byte[] nonce, int macSizeInBits, byte[] associatedData)
+ {
+ super(nonce);
+
+ this.macSizeInBits = macSizeInBits;
+ this.associatedData = Arrays.clone(associatedData);
+ }
+
+ /**
+ * Return the size of the MAC associated with this parameter spec.
+ *
+ * @return the MAC size in bits.
+ */
+ public int getMacSizeInBits()
+ {
+ return macSizeInBits;
+ }
+
+ /**
+ * Return the associated data associated with this parameter spec.
+ *
+ * @return the associated data, null if there isn't any.
+ */
+ public byte[] getAssociatedData()
+ {
+ return Arrays.clone(associatedData);
+ }
+
+ /**
+ * Return the nonce (same as IV) associated with this parameter spec.
+ *
+ * @return the nonce/IV.
+ */
+ public byte[] getNonce()
+ {
+ return getIV();
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/spec/PBKDF2KeySpec.java b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/PBKDF2KeySpec.java
index df0c1454..e053fb93 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/spec/PBKDF2KeySpec.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/spec/PBKDF2KeySpec.java
@@ -2,6 +2,8 @@ package org.bouncycastle.jcajce.spec;
import javax.crypto.spec.PBEKeySpec;
+import org.bouncycastle.asn1.DERNull;
+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
/**
@@ -10,6 +12,8 @@ import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
public class PBKDF2KeySpec
extends PBEKeySpec
{
+ private static final AlgorithmIdentifier defaultPRF = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_hmacWithSHA1, DERNull.INSTANCE);
+
private AlgorithmIdentifier prf;
/**
@@ -28,6 +32,21 @@ public class PBKDF2KeySpec
this.prf = prf;
}
+ /**
+ * Return true if this spec is for the default PRF (HmacSHA1), false otherwise.
+ *
+ * @return true if this spec uses the default PRF, false otherwise.
+ */
+ public boolean isDefaultPrf()
+ {
+ return defaultPRF.equals(prf);
+ }
+
+ /**
+ * Return an AlgorithmIdentifier representing the PRF.
+ *
+ * @return the PRF's AlgorithmIdentifier.
+ */
public AlgorithmIdentifier getPrf()
{
return prf;
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/AlgorithmParametersUtils.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/AlgorithmParametersUtils.java
index 4a1a92a5..025327f6 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/AlgorithmParametersUtils.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/AlgorithmParametersUtils.java
@@ -1,6 +1,3 @@
-/***************************************************************/
-/****** DO NOT EDIT THIS CLASS bc-java SOURCE FILE ******/
-/***************************************************************/
package org.bouncycastle.jcajce.util;
import java.io.IOException;
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/BCJcaJceHelper.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/BCJcaJceHelper.java
index 40087612..25897cf5 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/BCJcaJceHelper.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/BCJcaJceHelper.java
@@ -11,15 +11,23 @@ import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class BCJcaJceHelper
extends ProviderJcaJceHelper
{
+ private static volatile Provider bcProvider;
+
private static Provider getBouncyCastleProvider()
{
if (Security.getProvider("BC") != null)
{
return Security.getProvider("BC");
}
+ else if (bcProvider != null)
+ {
+ return bcProvider;
+ }
else
{
- return new BouncyCastleProvider();
+ bcProvider = new BouncyCastleProvider();
+
+ return bcProvider;
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java
index 27ca55ae..426efc09 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/DefaultJcaJceHelper.java
@@ -6,6 +6,7 @@ import java.security.KeyFactory;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
import java.security.Signature;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
@@ -96,4 +97,10 @@ public class DefaultJcaJceHelper
{
return CertificateFactory.getInstance(algorithm);
}
+
+ public SecureRandom createSecureRandom(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return SecureRandom.getInstance(algorithm);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/JcaJceHelper.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/JcaJceHelper.java
index 7a78193e..aa151cce 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/JcaJceHelper.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/JcaJceHelper.java
@@ -7,6 +7,7 @@ import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
+import java.security.SecureRandom;
import java.security.Signature;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
@@ -59,4 +60,7 @@ public interface JcaJceHelper
CertificateFactory createCertificateFactory(String algorithm)
throws NoSuchProviderException, CertificateException;
+
+ SecureRandom createSecureRandom(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/MessageDigestUtils.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/MessageDigestUtils.java
index 80ce603f..1125a4ba 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/MessageDigestUtils.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/MessageDigestUtils.java
@@ -41,6 +41,10 @@ public class MessageDigestUtils
// digestOidMap.put(CryptoProObjectIdentifiers.gostR3411, "GOST3411");
// digestOidMap.put(GNUObjectIdentifiers.Tiger_192, "Tiger");
// digestOidMap.put(ISOIECObjectIdentifiers.whirlpool, "Whirlpool");
+ // digestOidMap.put(NISTObjectIdentifiers.id_sha3_224, "SHA3-224");
+ // digestOidMap.put(NISTObjectIdentifiers.id_sha3_256, "SHA3-256");
+ // digestOidMap.put(NISTObjectIdentifiers.id_sha3_384, "SHA3-384");
+ // digestOidMap.put(NISTObjectIdentifiers.id_sha3_512, "SHA3-512");
// END android-removed
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java
index 280539d5..bc5da9a9 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/NamedJcaJceHelper.java
@@ -7,6 +7,7 @@ import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
+import java.security.SecureRandom;
import java.security.Signature;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
@@ -103,4 +104,10 @@ public class NamedJcaJceHelper
{
return CertificateFactory.getInstance(algorithm, providerName);
}
+
+ public SecureRandom createSecureRandom(String algorithm)
+ throws NoSuchAlgorithmException, NoSuchProviderException
+ {
+ return SecureRandom.getInstance(algorithm, providerName);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java b/bcprov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java
index fb4b9a73..f07b0a85 100644
--- a/bcprov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java
+++ b/bcprov/src/main/java/org/bouncycastle/jcajce/util/ProviderJcaJceHelper.java
@@ -7,6 +7,7 @@ import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
+import java.security.SecureRandom;
import java.security.Signature;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
@@ -103,4 +104,10 @@ public class ProviderJcaJceHelper
{
return CertificateFactory.getInstance(algorithm, provider);
}
+
+ public SecureRandom createSecureRandom(String algorithm)
+ throws NoSuchAlgorithmException
+ {
+ return SecureRandom.getInstance(algorithm, provider);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProvider.java
index e5463aa0..6a7c9e62 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.54";
+ private static String info = "BouncyCastle Security Provider v1.56";
public static final String PROVIDER_NAME = "BC";
@@ -60,14 +60,14 @@ public final class BouncyCastleProvider extends Provider
private static final String[] SYMMETRIC_GENERIC =
{
// BEGIN android-changed
- // Was: "PBEPBKDF2", "PBEPKCS12"
+ // Was: "PBEPBKDF2", "TLSKDF"
"PBEPBKDF2", "PBEPKCS12", "PBES2AlgorithmParameters"
};
private static final String[] SYMMETRIC_MACS =
{
// BEGIN android-removed
- // "SipHash"
+ // "SipHash", "Poly1305"
// END android-removed
};
@@ -132,9 +132,19 @@ public final class BouncyCastleProvider extends Provider
private static final String KEYSTORE_PACKAGE = "org.bouncycastle.jcajce.provider.keystore.";
private static final String[] KEYSTORES =
{
- "BC", "PKCS12"
+ "BC", "BCFKS", "PKCS12"
};
+ // BEGIN android-removed
+ // /*
+ // * Configurable secure random
+ // */
+ // private static final String SECURE_RANDOM_PACKAGE = "org.bouncycastle.jcajce.provider.drbg.";
+ // private static final String[] SECURE_RANDOMS =
+ // {
+ // "DRBG"
+ // };
+
/**
* Construct a new provider. This should only be required when
* using runtime registration of the provider using the
@@ -142,7 +152,7 @@ public final class BouncyCastleProvider extends Provider
*/
public BouncyCastleProvider()
{
- super(PROVIDER_NAME, 1.54, info);
+ super(PROVIDER_NAME, 1.56, info);
AccessController.doPrivileged(new PrivilegedAction()
{
@@ -171,6 +181,8 @@ public final class BouncyCastleProvider extends Provider
loadAlgorithms(KEYSTORE_PACKAGE, KEYSTORES);
// BEGIN android-removed
+ // loadAlgorithms(SECURE_RANDOM_PACKAGE, SECURE_RANDOMS);
+ //
// //
// // X509Store
// //
@@ -287,13 +299,24 @@ public final class BouncyCastleProvider extends Provider
public void addKeyInfoConverter(ASN1ObjectIdentifier oid, AsymmetricKeyInfoConverter keyInfoConverter)
{
- keyInfoConverters.put(oid, keyInfoConverter);
+ synchronized (keyInfoConverters)
+ {
+ keyInfoConverters.put(oid, keyInfoConverter);
+ }
+ }
+
+ private static AsymmetricKeyInfoConverter getAsymmetricKeyInfoConverter(ASN1ObjectIdentifier algorithm)
+ {
+ synchronized (keyInfoConverters)
+ {
+ return (AsymmetricKeyInfoConverter)keyInfoConverters.get(algorithm);
+ }
}
public static PublicKey getPublicKey(SubjectPublicKeyInfo publicKeyInfo)
throws IOException
{
- AsymmetricKeyInfoConverter converter = (AsymmetricKeyInfoConverter)keyInfoConverters.get(publicKeyInfo.getAlgorithm().getAlgorithm());
+ AsymmetricKeyInfoConverter converter = getAsymmetricKeyInfoConverter(publicKeyInfo.getAlgorithm().getAlgorithm());
if (converter == null)
{
@@ -306,7 +329,7 @@ public final class BouncyCastleProvider extends Provider
public static PrivateKey getPrivateKey(PrivateKeyInfo privateKeyInfo)
throws IOException
{
- AsymmetricKeyInfoConverter converter = (AsymmetricKeyInfoConverter)keyInfoConverters.get(privateKeyInfo.getPrivateKeyAlgorithm().getAlgorithm());
+ AsymmetricKeyInfoConverter converter = getAsymmetricKeyInfoConverter(privateKeyInfo.getPrivateKeyAlgorithm().getAlgorithm());
if (converter == null)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java
index cda05e83..f89b9fd7 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/BouncyCastleProviderConfiguration.java
@@ -1,6 +1,11 @@
package org.bouncycastle.jce.provider;
import java.security.Permission;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
import javax.crypto.spec.DHParameterSpec;
@@ -21,12 +26,18 @@ class BouncyCastleProviderConfiguration
BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.THREAD_LOCAL_DH_DEFAULT_PARAMS);
private static Permission BC_DH_PERMISSION = new ProviderConfigurationPermission(
BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.DH_DEFAULT_PARAMS);
+ private static Permission BC_EC_CURVE_PERMISSION = new ProviderConfigurationPermission(
+ BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.ACCEPTABLE_EC_CURVES);
+ private static Permission BC_ADDITIONAL_EC_CURVE_PERMISSION = new ProviderConfigurationPermission(
+ BouncyCastleProvider.PROVIDER_NAME, ConfigurableProvider.ADDITIONAL_EC_PARAMETERS);
private ThreadLocal ecThreadSpec = new ThreadLocal();
private ThreadLocal dhThreadSpec = new ThreadLocal();
private volatile ECParameterSpec ecImplicitCaParams;
private volatile Object dhDefaultParams;
+ private volatile Set acceptableNamedCurves = new HashSet();
+ private volatile Map additionalECParameters = new HashMap();
void setParameter(String parameterName, Object parameter)
{
@@ -118,6 +129,24 @@ class BouncyCastleProviderConfiguration
throw new IllegalArgumentException("not a valid DHParameterSpec or DHParameterSpec[]");
}
}
+ else if (parameterName.equals(ConfigurableProvider.ACCEPTABLE_EC_CURVES))
+ {
+ if (securityManager != null)
+ {
+ securityManager.checkPermission(BC_EC_CURVE_PERMISSION);
+ }
+
+ this.acceptableNamedCurves = (Set)parameter;
+ }
+ else if (parameterName.equals(ConfigurableProvider.ADDITIONAL_EC_PARAMETERS))
+ {
+ if (securityManager != null)
+ {
+ securityManager.checkPermission(BC_ADDITIONAL_EC_CURVE_PERMISSION);
+ }
+
+ this.additionalECParameters = (Map)parameter;
+ }
}
public ECParameterSpec getEcImplicitlyCa()
@@ -164,4 +193,14 @@ class BouncyCastleProviderConfiguration
return null;
}
+
+ public Set getAcceptableNamedCurves()
+ {
+ return Collections.unmodifiableSet(acceptableNamedCurves);
+ }
+
+ public Map getAdditionalECParameters()
+ {
+ return Collections.unmodifiableMap(additionalECParameters);
+ }
}
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 b6885ace..b8308207 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CRLObject.java
@@ -53,6 +53,7 @@ import org.bouncycastle.util.encoders.Hex;
* CRL Number
* Delta CRL Indicator (critical)
* Issuing Distribution Point (critical)
+ * @deprecated Do not use this class directly - either use org.bouncycastle.cert (bcpkix) or CertificateFactory.
*/
public class X509CRLObject
extends X509CRL
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 09703f4c..4a0166b2 100644
--- a/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java
+++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/X509CertificateObject.java
@@ -69,6 +69,9 @@ import org.bouncycastle.util.Integers;
import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
+/**
+ * @deprecated Do not use this class directly - either use org.bouncycastle.cert (bcpkix) or CertificateFactory.
+ */
public class X509CertificateObject
extends X509Certificate
implements PKCS12BagAttributeCarrier
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/WNafUtil.java b/bcprov/src/main/java/org/bouncycastle/math/ec/WNafUtil.java
index 339689ea..301b5aee 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/WNafUtil.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/WNafUtil.java
@@ -440,7 +440,7 @@ public abstract class WNafUtil
* 1) additions do not use the curve's A, B coefficients.
* 2) no special cases (i.e. Q +/- Q) when calculating 1P, 3P, 5P, ...
*/
- if (ECAlgorithms.isFpCurve(c) && c.getFieldSize() >= 64)
+ if (!twiceP.isInfinity() && ECAlgorithms.isFpCurve(c) && c.getFieldSize() >= 64)
{
switch (c.getCoordinateSystem())
{
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 5a066d81..1e04f4b9 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
@@ -112,9 +112,10 @@ public class SecP256R1Field
long t4 = xx12 + xx13;
long t5 = xx13 + xx14;
long t6 = xx14 + xx15;
+ long t7 = t5 - t0;
long cc = 0;
- cc += (xx[0] & M) + t0 - t3 - t5;
+ cc += (xx[0] & M) - t3 - t7;
z[0] = (int)cc;
cc >>= 32;
cc += (xx[1] & M) + t1 - t4 - t6;
@@ -123,7 +124,7 @@ public class SecP256R1Field
cc += (xx[2] & M) + t2 - t5;
z[2] = (int)cc;
cc >>= 32;
- cc += (xx[3] & M) + (t3 << 1) + xx13 - xx15 - t0;
+ cc += (xx[3] & M) + (t3 << 1) + t7 - t6;
z[3] = (int)cc;
cc >>= 32;
cc += (xx[4] & M) + (t4 << 1) + xx14 - t1;
@@ -132,7 +133,7 @@ public class SecP256R1Field
cc += (xx[5] & M) + (t5 << 1) - t2;
z[5] = (int)cc;
cc >>= 32;
- cc += (xx[6] & M) + (t6 << 1) + t5 - t0;
+ cc += (xx[6] & M) + (t6 << 1) + t7;
z[6] = (int)cc;
cc >>= 32;
cc += (xx[7] & M) + (xx15 << 1) + xx08 - t2 - t4;
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 fcbb8727..164a7957 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
@@ -107,9 +107,10 @@ public class SecP384R1Field
long t4 = xx17 + xx21;
long t5 = xx21 - xx23;
long t6 = xx22 - xx23;
+ long t7 = t0 + t5;
long cc = 0;
- cc += (xx[0] & M) + t0 + t5;
+ cc += (xx[0] & M) + t7;
z[0] = (int)cc;
cc >>= 32;
cc += (xx[1] & M) + xx23 - t0 + t1;
@@ -118,10 +119,10 @@ public class SecP384R1Field
cc += (xx[2] & M) - xx21 - t1 + t2;
z[2] = (int)cc;
cc >>= 32;
- cc += (xx[3] & M) + t0 - t2 + t3 + t5;
+ cc += (xx[3] & M) - t2 + t3 + t7;
z[3] = (int)cc;
cc >>= 32;
- cc += (xx[4] & M) + xx16 + xx21 + t0 + t1 - t3 + t5;
+ cc += (xx[4] & M) + xx16 + xx21 + t1 - t3 + t7;
z[4] = (int)cc;
cc >>= 32;
cc += (xx[5] & M) - xx16 + t1 + t2 + t4;
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 421883e0..12db01bc 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat192.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat192.java
@@ -715,8 +715,8 @@ public abstract class Nat192
}
long x_3 = x[3] & M;
- long zz_5 = zz[5] & M;
- long zz_6 = zz[6] & M;
+ long zz_5 = (zz[5] & M) + (zz_4 >>> 32); zz_4 &= M;
+ long zz_6 = (zz[6] & M) + (zz_5 >>> 32); zz_5 &= M;
{
zz_3 += x_3 * x_0;
w = (int)zz_3;
@@ -730,8 +730,8 @@ public abstract class Nat192
}
long x_4 = x[4] & M;
- long zz_7 = zz[7] & M;
- long zz_8 = zz[8] & M;
+ long zz_7 = (zz[7] & M) + (zz_6 >>> 32); zz_6 &= M;
+ long zz_8 = (zz[8] & M) + (zz_7 >>> 32); zz_7 &= M;
{
zz_4 += x_4 * x_0;
w = (int)zz_4;
@@ -747,8 +747,8 @@ public abstract class Nat192
}
long x_5 = x[5] & M;
- long zz_9 = zz[9] & M;
- long zz_10 = zz[10] & M;
+ long zz_9 = (zz[9] & M) + (zz_8 >>> 32); zz_8 &= M;
+ long zz_10 = (zz[10] & M) + (zz_9 >>> 32); zz_9 &= M;
{
zz_5 += x_5 * x_0;
w = (int)zz_5;
@@ -776,7 +776,7 @@ public abstract class Nat192
w = (int)zz_10;
zz[10] = (w << 1) | c;
c = w >>> 31;
- w = zz[11] + (int)(zz_10 >> 32);
+ w = zz[11] + (int)(zz_10 >>> 32);
zz[11] = (w << 1) | c;
}
@@ -831,8 +831,8 @@ public abstract class Nat192
}
long x_3 = x[xOff + 3] & M;
- long zz_5 = zz[zzOff + 5] & M;
- long zz_6 = zz[zzOff + 6] & M;
+ long zz_5 = (zz[zzOff + 5] & M) + (zz_4 >>> 32); zz_4 &= M;
+ long zz_6 = (zz[zzOff + 6] & M) + (zz_5 >>> 32); zz_5 &= M;
{
zz_3 += x_3 * x_0;
w = (int)zz_3;
@@ -846,8 +846,8 @@ public abstract class Nat192
}
long x_4 = x[xOff + 4] & M;
- long zz_7 = zz[zzOff + 7] & M;
- long zz_8 = zz[zzOff + 8] & M;
+ long zz_7 = (zz[zzOff + 7] & M) + (zz_6 >>> 32); zz_6 &= M;
+ long zz_8 = (zz[zzOff + 8] & M) + (zz_7 >>> 32); zz_7 &= M;
{
zz_4 += x_4 * x_0;
w = (int)zz_4;
@@ -863,8 +863,8 @@ public abstract class Nat192
}
long x_5 = x[xOff + 5] & M;
- long zz_9 = zz[zzOff + 9] & M;
- long zz_10 = zz[zzOff + 10] & M;
+ long zz_9 = (zz[zzOff + 9] & M) + (zz_8 >>> 32); zz_8 &= M;
+ long zz_10 = (zz[zzOff + 10] & M) + (zz_9 >>> 32); zz_9 &= M;
{
zz_5 += x_5 * x_0;
w = (int)zz_5;
@@ -892,7 +892,7 @@ public abstract class Nat192
w = (int)zz_10;
zz[zzOff + 10] = (w << 1) | c;
c = w >>> 31;
- w = zz[zzOff + 11] + (int)(zz_10 >> 32);
+ w = zz[zzOff + 11] + (int)(zz_10 >>> 32);
zz[zzOff + 11] = (w << 1) | c;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat224.java b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat224.java
index bbe81caa..9ff107c1 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat224.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat224.java
@@ -793,8 +793,8 @@ public abstract class Nat224
}
long x_3 = x[3] & M;
- long zz_5 = zz[5] & M;
- long zz_6 = zz[6] & M;
+ long zz_5 = (zz[5] & M) + (zz_4 >>> 32); zz_4 &= M;
+ long zz_6 = (zz[6] & M) + (zz_5 >>> 32); zz_5 &= M;
{
zz_3 += x_3 * x_0;
w = (int)zz_3;
@@ -808,8 +808,8 @@ public abstract class Nat224
}
long x_4 = x[4] & M;
- long zz_7 = zz[7] & M;
- long zz_8 = zz[8] & M;
+ long zz_7 = (zz[7] & M) + (zz_6 >>> 32); zz_6 &= M;
+ long zz_8 = (zz[8] & M) + (zz_7 >>> 32); zz_7 &= M;
{
zz_4 += x_4 * x_0;
w = (int)zz_4;
@@ -825,8 +825,8 @@ public abstract class Nat224
}
long x_5 = x[5] & M;
- long zz_9 = zz[9] & M;
- long zz_10 = zz[10] & M;
+ long zz_9 = (zz[9] & M) + (zz_8 >>> 32); zz_8 &= M;
+ long zz_10 = (zz[10] & M) + (zz_9 >>> 32); zz_9 &= M;
{
zz_5 += x_5 * x_0;
w = (int)zz_5;
@@ -844,8 +844,8 @@ public abstract class Nat224
}
long x_6 = x[6] & M;
- long zz_11 = zz[11] & M;
- long zz_12 = zz[12] & M;
+ long zz_11 = (zz[11] & M) + (zz_10 >>> 32); zz_10 &= M;
+ long zz_12 = (zz[12] & M) + (zz_11 >>> 32); zz_11 &= M;
{
zz_6 += x_6 * x_0;
w = (int)zz_6;
@@ -877,7 +877,7 @@ public abstract class Nat224
w = (int)zz_12;
zz[12] = (w << 1) | c;
c = w >>> 31;
- w = zz[13] + (int)(zz_12 >> 32);
+ w = zz[13] + (int)(zz_12 >>> 32);
zz[13] = (w << 1) | c;
}
@@ -932,8 +932,8 @@ public abstract class Nat224
}
long x_3 = x[xOff + 3] & M;
- long zz_5 = zz[zzOff + 5] & M;
- long zz_6 = zz[zzOff + 6] & M;
+ long zz_5 = (zz[zzOff + 5] & M) + (zz_4 >>> 32); zz_4 &= M;
+ long zz_6 = (zz[zzOff + 6] & M) + (zz_5 >>> 32); zz_5 &= M;
{
zz_3 += x_3 * x_0;
w = (int)zz_3;
@@ -947,8 +947,8 @@ public abstract class Nat224
}
long x_4 = x[xOff + 4] & M;
- long zz_7 = zz[zzOff + 7] & M;
- long zz_8 = zz[zzOff + 8] & M;
+ long zz_7 = (zz[zzOff + 7] & M) + (zz_6 >>> 32); zz_6 &= M;
+ long zz_8 = (zz[zzOff + 8] & M) + (zz_7 >>> 32); zz_7 &= M;
{
zz_4 += x_4 * x_0;
w = (int)zz_4;
@@ -964,8 +964,8 @@ public abstract class Nat224
}
long x_5 = x[xOff + 5] & M;
- long zz_9 = zz[zzOff + 9] & M;
- long zz_10 = zz[zzOff + 10] & M;
+ long zz_9 = (zz[zzOff + 9] & M) + (zz_8 >>> 32); zz_8 &= M;
+ long zz_10 = (zz[zzOff + 10] & M) + (zz_9 >>> 32); zz_9 &= M;
{
zz_5 += x_5 * x_0;
w = (int)zz_5;
@@ -983,8 +983,8 @@ public abstract class Nat224
}
long x_6 = x[xOff + 6] & M;
- long zz_11 = zz[zzOff + 11] & M;
- long zz_12 = zz[zzOff + 12] & M;
+ long zz_11 = (zz[zzOff + 11] & M) + (zz_10 >>> 32); zz_10 &= M;
+ long zz_12 = (zz[zzOff + 12] & M) + (zz_11 >>> 32); zz_11 &= M;
{
zz_6 += x_6 * x_0;
w = (int)zz_6;
@@ -1016,7 +1016,7 @@ public abstract class Nat224
w = (int)zz_12;
zz[zzOff + 12] = (w << 1) | c;
c = w >>> 31;
- w = zz[zzOff + 13] + (int)(zz_12 >> 32);
+ w = zz[zzOff + 13] + (int)(zz_12 >>> 32);
zz[zzOff + 13] = (w << 1) | c;
}
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 db1daac0..726bae35 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/raw/Nat256.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/raw/Nat256.java
@@ -926,8 +926,8 @@ public abstract class Nat256
}
long x_3 = x[3] & M;
- long zz_5 = zz[5] & M;
- long zz_6 = zz[6] & M;
+ long zz_5 = (zz[5] & M) + (zz_4 >>> 32); zz_4 &= M;
+ long zz_6 = (zz[6] & M) + (zz_5 >>> 32); zz_5 &= M;
{
zz_3 += x_3 * x_0;
w = (int)zz_3;
@@ -941,8 +941,8 @@ public abstract class Nat256
}
long x_4 = x[4] & M;
- long zz_7 = zz[7] & M;
- long zz_8 = zz[8] & M;
+ long zz_7 = (zz[7] & M) + (zz_6 >>> 32); zz_6 &= M;
+ long zz_8 = (zz[8] & M) + (zz_7 >>> 32); zz_7 &= M;
{
zz_4 += x_4 * x_0;
w = (int)zz_4;
@@ -958,8 +958,8 @@ public abstract class Nat256
}
long x_5 = x[5] & M;
- long zz_9 = zz[9] & M;
- long zz_10 = zz[10] & M;
+ long zz_9 = (zz[9] & M) + (zz_8 >>> 32); zz_8 &= M;
+ long zz_10 = (zz[10] & M) + (zz_9 >>> 32); zz_9 &= M;
{
zz_5 += x_5 * x_0;
w = (int)zz_5;
@@ -977,8 +977,8 @@ public abstract class Nat256
}
long x_6 = x[6] & M;
- long zz_11 = zz[11] & M;
- long zz_12 = zz[12] & M;
+ long zz_11 = (zz[11] & M) + (zz_10 >>> 32); zz_10 &= M;
+ long zz_12 = (zz[12] & M) + (zz_11 >>> 32); zz_11 &= M;
{
zz_6 += x_6 * x_0;
w = (int)zz_6;
@@ -998,8 +998,8 @@ public abstract class Nat256
}
long x_7 = x[7] & M;
- long zz_13 = zz[13] & M;
- long zz_14 = zz[14] & M;
+ long zz_13 = (zz[13] & M) + (zz_12 >>> 32); zz_12 &= M;
+ long zz_14 = (zz[14] & M) + (zz_13 >>> 32); zz_13 &= M;
{
zz_7 += x_7 * x_0;
w = (int)zz_7;
@@ -1035,7 +1035,7 @@ public abstract class Nat256
w = (int)zz_14;
zz[14] = (w << 1) | c;
c = w >>> 31;
- w = zz[15] + (int)(zz_14 >> 32);
+ w = zz[15] + (int)(zz_14 >>> 32);
zz[15] = (w << 1) | c;
}
@@ -1090,8 +1090,8 @@ public abstract class Nat256
}
long x_3 = x[xOff + 3] & M;
- long zz_5 = zz[zzOff + 5] & M;
- long zz_6 = zz[zzOff + 6] & M;
+ long zz_5 = (zz[zzOff + 5] & M) + (zz_4 >>> 32); zz_4 &= M;
+ long zz_6 = (zz[zzOff + 6] & M) + (zz_5 >>> 32); zz_5 &= M;
{
zz_3 += x_3 * x_0;
w = (int)zz_3;
@@ -1105,8 +1105,8 @@ public abstract class Nat256
}
long x_4 = x[xOff + 4] & M;
- long zz_7 = zz[zzOff + 7] & M;
- long zz_8 = zz[zzOff + 8] & M;
+ long zz_7 = (zz[zzOff + 7] & M) + (zz_6 >>> 32); zz_6 &= M;
+ long zz_8 = (zz[zzOff + 8] & M) + (zz_7 >>> 32); zz_7 &= M;
{
zz_4 += x_4 * x_0;
w = (int)zz_4;
@@ -1122,8 +1122,8 @@ public abstract class Nat256
}
long x_5 = x[xOff + 5] & M;
- long zz_9 = zz[zzOff + 9] & M;
- long zz_10 = zz[zzOff + 10] & M;
+ long zz_9 = (zz[zzOff + 9] & M) + (zz_8 >>> 32); zz_8 &= M;
+ long zz_10 = (zz[zzOff + 10] & M) + (zz_9 >>> 32); zz_9 &= M;
{
zz_5 += x_5 * x_0;
w = (int)zz_5;
@@ -1141,8 +1141,8 @@ public abstract class Nat256
}
long x_6 = x[xOff + 6] & M;
- long zz_11 = zz[zzOff + 11] & M;
- long zz_12 = zz[zzOff + 12] & M;
+ long zz_11 = (zz[zzOff + 11] & M) + (zz_10 >>> 32); zz_10 &= M;
+ long zz_12 = (zz[zzOff + 12] & M) + (zz_11 >>> 32); zz_11 &= M;
{
zz_6 += x_6 * x_0;
w = (int)zz_6;
@@ -1162,8 +1162,8 @@ public abstract class Nat256
}
long x_7 = x[xOff + 7] & M;
- long zz_13 = zz[zzOff + 13] & M;
- long zz_14 = zz[zzOff + 14] & M;
+ long zz_13 = (zz[zzOff + 13] & M) + (zz_12 >>> 32); zz_12 &= M;
+ long zz_14 = (zz[zzOff + 14] & M) + (zz_13 >>> 32); zz_13 &= M;
{
zz_7 += x_7 * x_0;
w = (int)zz_7;
@@ -1199,7 +1199,7 @@ public abstract class Nat256
w = (int)zz_14;
zz[zzOff + 14] = (w << 1) | c;
c = w >>> 31;
- w = zz[zzOff + 15] + (int)(zz_14 >> 32);
+ w = zz[zzOff + 15] + (int)(zz_14 >>> 32);
zz[zzOff + 15] = (w << 1) | c;
}
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Arrays.java b/bcprov/src/main/java/org/bouncycastle/util/Arrays.java
index 99325a9f..ae609280 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/Arrays.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/Arrays.java
@@ -103,6 +103,36 @@ public final class Arrays
return true;
}
+ public static boolean areEqual(
+ short[] a,
+ short[] b)
+ {
+ if (a == b)
+ {
+ return true;
+ }
+
+ if (a == null || b == null)
+ {
+ return false;
+ }
+
+ if (a.length != b.length)
+ {
+ return false;
+ }
+
+ for (int i = 0; i != a.length; i++)
+ {
+ if (a[i] != b[i])
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
/**
* A constant time equals comparison - does not terminate early if
* test will fail.
@@ -232,6 +262,44 @@ public final class Arrays
return true;
}
+ public static int compareUnsigned(byte[] a, byte[] b)
+ {
+ if (a == b)
+ {
+ return 0;
+ }
+ if (a == null)
+ {
+ return -1;
+ }
+ if (b == null)
+ {
+ return 1;
+ }
+ int minLen = Math.min(a.length, b.length);
+ for (int i = 0; i < minLen; ++i)
+ {
+ int aVal = a[i] & 0xFF, bVal = b[i] & 0xFF;
+ if (aVal < bVal)
+ {
+ return -1;
+ }
+ if (aVal > bVal)
+ {
+ return 1;
+ }
+ }
+ if (a.length < b.length)
+ {
+ return -1;
+ }
+ if (a.length > b.length)
+ {
+ return 1;
+ }
+ return 0;
+ }
+
public static boolean contains(short[] a, short n)
{
for (int i = 0; i < a.length; ++i)
@@ -954,6 +1022,26 @@ public final class Arrays
}
}
+ public static byte[] concatenate(byte[][] arrays)
+ {
+ int size = 0;
+ for (int i = 0; i != arrays.length; i++)
+ {
+ size += arrays[i].length;
+ }
+
+ byte[] rv = new byte[size];
+
+ int offSet = 0;
+ for (int i = 0; i != arrays.length; i++)
+ {
+ System.arraycopy(arrays[i], 0, rv, offSet, arrays[i].length);
+ offSet += arrays[i].length;
+ }
+
+ return rv;
+ }
+
public static int[] concatenate(int[] a, int[] b)
{
if (a == null)
diff --git a/bcprov/src/main/java/org/bouncycastle/util/Pack.java b/bcprov/src/main/java/org/bouncycastle/util/Pack.java
index 94ba17b1..82b02ea5 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/Pack.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/Pack.java
@@ -5,6 +5,13 @@ package org.bouncycastle.util;
*/
public abstract class Pack
{
+ public static short bigEndianToShort(byte[] bs, int off)
+ {
+ int n = (bs[ off] & 0xff) << 8;
+ n |= (bs[++off] & 0xff);
+ return (short)n;
+ }
+
public static int bigEndianToInt(byte[] bs, int off)
{
int n = bs[ off] << 24;
@@ -99,6 +106,13 @@ public abstract class Pack
}
}
+ public static short littleEndianToShort(byte[] bs, int off)
+ {
+ int n = bs[ off] & 0xff;
+ n |= (bs[++off] & 0xff) << 8;
+ return (short)n;
+ }
+
public static int littleEndianToInt(byte[] bs, int off)
{
int n = bs[ off] & 0xff;
@@ -126,6 +140,30 @@ public abstract class Pack
}
}
+ public static int[] littleEndianToInt(byte[] bs, int off, int count)
+ {
+ int[] ns = new int[count];
+ for (int i = 0; i < ns.length; ++i)
+ {
+ ns[i] = littleEndianToInt(bs, off);
+ off += 4;
+ }
+ return ns;
+ }
+
+ public static byte[] shortToLittleEndian(short n)
+ {
+ byte[] bs = new byte[2];
+ shortToLittleEndian(n, bs, 0);
+ return bs;
+ }
+
+ public static void shortToLittleEndian(short n, byte[] bs, int off)
+ {
+ bs[ off] = (byte)(n );
+ bs[++off] = (byte)(n >>> 8);
+ }
+
public static byte[] intToLittleEndian(int n)
{
byte[] bs = new byte[4];
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 f39e026e..adb158f9 100644
--- a/bcprov/src/main/java/org/bouncycastle/util/io/Streams.java
+++ b/bcprov/src/main/java/org/bouncycastle/util/io/Streams.java
@@ -142,4 +142,10 @@ public final class Streams
}
return total;
}
+
+ public static void writeBufTo(ByteArrayOutputStream buf, OutputStream output)
+ throws IOException
+ {
+ buf.writeTo(output);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/x509/X509V1CertificateGenerator.java b/bcprov/src/main/java/org/bouncycastle/x509/X509V1CertificateGenerator.java
index 01f4469f..5833d17e 100644
--- a/bcprov/src/main/java/org/bouncycastle/x509/X509V1CertificateGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/x509/X509V1CertificateGenerator.java
@@ -1,5 +1,6 @@
package org.bouncycastle.x509;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
@@ -11,7 +12,6 @@ import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.SignatureException;
import java.security.cert.CertificateEncodingException;
-import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.Iterator;
@@ -19,19 +19,21 @@ import java.util.Iterator;
import javax.security.auth.x500.X500Principal;
import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.asn1.x509.Certificate;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.TBSCertificate;
import org.bouncycastle.asn1.x509.Time;
import org.bouncycastle.asn1.x509.V1TBSCertificateGenerator;
import org.bouncycastle.asn1.x509.X509Name;
+import org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory;
+import org.bouncycastle.jcajce.util.BCJcaJceHelper;
+import org.bouncycastle.jcajce.util.JcaJceHelper;
import org.bouncycastle.jce.X509Principal;
-import org.bouncycastle.jce.provider.X509CertificateObject;
/**
* class to produce an X.509 Version 1 certificate.
@@ -39,6 +41,9 @@ import org.bouncycastle.jce.provider.X509CertificateObject;
*/
public class X509V1CertificateGenerator
{
+ private final JcaJceHelper bcHelper = new BCJcaJceHelper(); // needed to force provider loading
+ private final CertificateFactory certificateFactory = new CertificateFactory();
+
private V1TBSCertificateGenerator tbsGen;
private ASN1ObjectIdentifier sigOID;
private AlgorithmIdentifier sigAlgId;
@@ -353,9 +358,10 @@ public class X509V1CertificateGenerator
try
{
- return new X509CertificateObject(Certificate.getInstance(new DERSequence(v)));
+ return (X509Certificate)certificateFactory.engineGenerateCertificate(
+ new ByteArrayInputStream(new DERSequence(v).getEncoded(ASN1Encoding.DER)));
}
- catch (CertificateParsingException e)
+ catch (Exception e)
{
throw new ExtCertificateEncodingException("exception producing certificate object", e);
}
diff --git a/bcprov/src/main/java/org/bouncycastle/x509/X509V3CertificateGenerator.java b/bcprov/src/main/java/org/bouncycastle/x509/X509V3CertificateGenerator.java
index 54be0016..28bf5507 100644
--- a/bcprov/src/main/java/org/bouncycastle/x509/X509V3CertificateGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/x509/X509V3CertificateGenerator.java
@@ -1,5 +1,6 @@
package org.bouncycastle.x509;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
@@ -20,26 +21,24 @@ import javax.security.auth.x500.X500Principal;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
-import org.bouncycastle.asn1.x509.Certificate;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.TBSCertificate;
import org.bouncycastle.asn1.x509.Time;
import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator;
import org.bouncycastle.asn1.x509.X509ExtensionsGenerator;
import org.bouncycastle.asn1.x509.X509Name;
-import org.bouncycastle.jce.X509Principal;
-// BEGIN ANDROID-ADDED
-// See the definition of the jcaJceHelper field for details.
-import org.bouncycastle.jcajce.provider.asymmetric.x509.X509CertificateObject;
+import org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory;
import org.bouncycastle.jcajce.util.BCJcaJceHelper;
import org.bouncycastle.jcajce.util.JcaJceHelper;
-// END ANDROID-ADDED
+import org.bouncycastle.jce.X509Principal;
+
import org.bouncycastle.x509.extension.X509ExtensionUtil;
/**
@@ -48,17 +47,14 @@ import org.bouncycastle.x509.extension.X509ExtensionUtil;
*/
public class X509V3CertificateGenerator
{
+ private final JcaJceHelper bcHelper = new BCJcaJceHelper(); // needed to force provider loading
+ private final CertificateFactory certificateFactory = new CertificateFactory();
+
private V3TBSCertificateGenerator tbsGen;
private ASN1ObjectIdentifier sigOID;
private AlgorithmIdentifier sigAlgId;
private String signatureAlgorithm;
private X509ExtensionsGenerator extGenerator;
- // BEGIN ANDROID-ADDED
- // Use org.bouncycastle.jcajce.provider.asymmetric.x509.X509CertificateObject
- // instead of org.bouncycastle.jce.provider.X509CertificateObject.
- // We need to pass one instance of JcaJceHelper in the constructor of the former class.
- private final JcaJceHelper jcaJceHelper = new BCJcaJceHelper();
- // END ANDROID-ADDED
public X509V3CertificateGenerator()
{
@@ -452,7 +448,7 @@ public class X509V3CertificateGenerator
{
return generateJcaObject(tbsCert, signature);
}
- catch (CertificateParsingException e)
+ catch (Exception e)
{
throw new ExtCertificateEncodingException("exception producing certificate object", e);
}
@@ -497,7 +493,7 @@ public class X509V3CertificateGenerator
{
return generateJcaObject(tbsCert, signature);
}
- catch (CertificateParsingException e)
+ catch (Exception e)
{
throw new ExtCertificateEncodingException("exception producing certificate object", e);
}
@@ -514,19 +510,16 @@ public class X509V3CertificateGenerator
}
private X509Certificate generateJcaObject(TBSCertificate tbsCert, byte[] signature)
- throws CertificateParsingException
+ throws Exception
{
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(tbsCert);
v.add(sigAlgId);
v.add(new DERBitString(signature));
- // BEGIN ANDROID-CHANGED
- // Was: return new X509CertificateObject(Certificate.getInstance(new DERSequence(v)));
- // We are using a different X509CertificateObject class than the original, see definition
- // of the jcaJceHelper field for details.
- return new X509CertificateObject(jcaJceHelper, Certificate.getInstance(new DERSequence(v)));
- // END ANDROID-CHANGED
+
+ return (X509Certificate)certificateFactory.engineGenerateCertificate(
+ new ByteArrayInputStream(new DERSequence(v).getEncoded(ASN1Encoding.DER)));
}
/**
diff --git a/bouncycastle.version b/bouncycastle.version
index 00639910..c7e252d8 100644
--- a/bouncycastle.version
+++ b/bouncycastle.version
@@ -1,2 +1,2 @@
BOUNCYCASTLE_JDK=15on
-BOUNCYCASTLE_VERSION=154
+BOUNCYCASTLE_VERSION=156