diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-07-22 16:14:31 +0400 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-07-22 16:14:31 +0400 |
commit | 8bfd438251442bfe6e0cdaabe054a3ffc88d794e (patch) | |
tree | 4eaf2c68587914926be1550cc7efefd2f818a575 | |
parent | 57c97c2341af7f73da4ab59c76d4c4a928fa338a (diff) | |
parent | 67e19ce65628c0a3e37bf04e36826ab747deca62 (diff) |
Merge branch 'master' of git.bouncycastle.org:bc-java
-rw-r--r-- | ant/jdk14.xml | 2 | ||||
-rw-r--r-- | buildj2me | 222 | ||||
-rw-r--r-- | core/src/main/j2me/org/bouncycastle/asn1/ASN1GeneralizedTime.java | 251 | ||||
-rw-r--r-- | core/src/main/j2me/org/bouncycastle/asn1/ASN1UTCTime.java | 251 | ||||
-rw-r--r-- | core/src/main/j2me/org/bouncycastle/asn1/DERGeneralizedTime.java | 251 | ||||
-rw-r--r-- | core/src/main/j2me/org/bouncycastle/asn1/DERUTCTime.java | 251 | ||||
-rw-r--r-- | core/src/main/j2me/org/bouncycastle/crypto/encodings/PKCS1Encoding.java | 184 | ||||
-rw-r--r-- | core/src/main/j2me/org/bouncycastle/math/ec/LongArray.java | 320 | ||||
-rw-r--r-- | core/src/main/java/org/bouncycastle/math/raw/Mod.java | 7 | ||||
-rw-r--r-- | core/src/test/java/org/bouncycastle/crypto/test/AESWrapPadTest.java | 2 | ||||
-rw-r--r-- | core/src/test/java/org/bouncycastle/crypto/test/DigestTest.java | 2 | ||||
-rw-r--r-- | docs/releasenotes.html | 1 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/attachonly.eml (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/attachonly.eml) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/basicAS2.message (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/basicAS2.message) | bin | 3599 -> 3599 bytes | |||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/brokenEnv.message (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/brokenEnv.message) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/cert.pem (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/cert.pem) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/certpath_end1.crt (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/certpath_end1.crt) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/certpath_end2.crt (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/certpath_end2.crt) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/certpath_inter1.crt (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/certpath_inter1.crt) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/certpath_inter2.crt (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/certpath_inter2.crt) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/certpath_root.crt (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/certpath_root.crt) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/circular.eml (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/circular.eml) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/dotnet_enc_cert.pem (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/dotnet_enc_cert.pem) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/dotnet_encrypted_mail.eml (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/dotnet_encrypted_mail.eml) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/embeddedmulti.message (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/embeddedmulti.message) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/extra-nl.eml (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/extra-nl.eml) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/johndoe.p12 (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/johndoe.p12) | bin | 2390 -> 2390 bytes | |||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/key.pem (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/key.pem) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/multi-alternative.eml (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/multi-alternative.eml) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/outlook_2010_beta_sime_msg.eml (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/outlook_2010_beta_sime_msg.eml) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/qp-soft-break.eml (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/qp-soft-break.eml) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/quotable.message (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/quotable.message) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/rawAS2.message (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/rawAS2.message) | bin | 3082 -> 3082 bytes | |||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/test128.message (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/test128.message) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/test192.message (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/test192.message) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/test256.message (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/test256.message) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.expired.eml (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/validator.expired.eml) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.extKeyUsage.eml (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/validator.extKeyUsage.eml) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.fakeRoot.crt (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/validator.fakeRoot.crt) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.keyUsage.eml (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/validator.keyUsage.eml) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.longValidity.eml (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/validator.longValidity.eml) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.noEmail.eml (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/validator.noEmail.eml) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.notYetValid.eml (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/validator.notYetValid.eml) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.revoked.crl (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/validator.revoked.crl) | bin | 276 -> 276 bytes | |||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.revoked.eml (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/validator.revoked.eml) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.root.crt (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/validator.root.crt) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.shortKey.eml (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/validator.shortKey.eml) | 0 | ||||
-rw-r--r-- | mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.validMail.eml (renamed from core/src/test/data/org/bouncycastle/mail/smime/test/validator.validMail.eml) | 0 | ||||
-rw-r--r-- | pkix/src/main/j2me/org/bouncycastle/cert/CertUtils.java | 2 | ||||
-rw-r--r-- | pkix/src/main/j2me/org/bouncycastle/cert/X509v1CertificateBuilder.java | 83 | ||||
-rw-r--r-- | pkix/src/main/j2me/org/bouncycastle/cert/X509v2AttributeCertificateBuilder.java | 138 | ||||
-rw-r--r-- | pkix/src/main/j2me/org/bouncycastle/cert/X509v2CRLBuilder.java | 231 | ||||
-rw-r--r-- | pkix/src/main/j2me/org/bouncycastle/cert/X509v3CertificateBuilder.java | 177 | ||||
-rw-r--r-- | pkix/src/main/java/org/bouncycastle/cert/X509v1CertificateBuilder.java | 67 | ||||
-rw-r--r-- | pkix/src/main/java/org/bouncycastle/cms/DefaultAuthenticatedAttributeTableGenerator.java | 10 |
55 files changed, 1861 insertions, 591 deletions
diff --git a/ant/jdk14.xml b/ant/jdk14.xml index 33bc182b..0bdeb592 100644 --- a/ant/jdk14.xml +++ b/ant/jdk14.xml @@ -84,8 +84,10 @@ <fileset dir="core/src/test/" includes="**/*.properties" /> <fileset dir="prov/src/main/" includes="**/*.properties" /> <fileset dir="pkix/src/test/resources" includes="**/*.*" /> + <fileset dir="prov/src/test/resources" includes="**/*.*" /> <fileset dir="core/src/test/resources" includes="**/*.*" /> <fileset dir="pg/src/test/resources" includes="**/*.*" /> + <fileset dir="mail/src/test/resources" includes="**/*.*" /> <fileset dir="core/src/test/data" includes="**/*.pem" /> <fileset dir="core/src/test/data" includes="**/*.properties" /> <fileset dir="core/src/test/data" includes="**/*.eml" /> diff --git a/buildj2me b/buildj2me new file mode 100644 index 00000000..1ed8ce2a --- /dev/null +++ b/buildj2me @@ -0,0 +1,222 @@ +#!/bin/sh - +# +# build script for J2ME - this only includes the lightweight API +# if a distribution name is given as an argument the build is placed +# in a subdirectory - nothing gets compiled as we expect the classes +# to be in ./palm +# +# Note: this script expects javadoc for jdk 1.3 to be in your path. +# + +base=$1 +version=`echo $base | sed -e "s/\([0-9]\)\([0-9a-z]*\)/\1.\2/"` + +WINDOWTITLE="Bouncy Castle Cryptography $version API Specification" +HEADER="<b>Bouncy Castle Cryptography $version</b>" +DOCTITLE="Bouncy Castle $version API Specification" + +echo "making j2me lightweight release" + +if test "$base" != "" +then + target=build/artifacts/j2me/lcrypto-j2me-$base + + mkdir -p $target + mkdir $target/javadoc + mkdir $target/src + tar cf - common.xml midp.xml crypto_env.properties index.html LICENSE.html CONTRIBUTORS.html docs zips | (cd $target && tar xf -) + ((cd core/src/main/java; tar cf - * ) | (cd $target/src && tar xf -)) + ((cd core/src/main/javadoc; tar cf - * ) | (cd $target/src && tar xf -)) + ((cd core/src/main/j2me; tar cf - * ) | (cd $target/src && tar xf -)) + ((cd core/src/test/java; tar cf - * ) | (cd $target/src && tar xf -)) + ((cd core/src/test/j2me; tar cf - * ) | (cd $target/src && tar xf -)) + ((cd pkix/src/main/java; tar cf - * ) | (cd $target/src && tar xf -)) + ((cd pkix/src/main/javadoc; tar cf - * ) | (cd $target/src && tar xf -)) + ((cd pkix/src/main/j2me; tar cf - * ) | (cd $target/src && tar xf -)) + ((cd pkix/src/test/java; tar cf - org/bouncycastle/cert/test ) | (cd $target/src && tar xf - ) ) + ((cd pkix/src/test/j2me; tar cf - * ) | (cd $target/src && tar xf -)) + ((cd pg/src/main/java; tar cf - * ) | (cd $target/src && tar xf -)) + ((cd pg/src/main/javadoc; tar cf - * ) | (cd $target/src && tar xf -)) + ((cd pg/src/main/j2me; tar cf - * ) | (cd $target/src && tar xf -)) + + (cd $target; + rm src/org/bouncycastle/crypto/test/AllTests.java + rm src/org/bouncycastle/util/StreamParser.java + rm src/org/bouncycastle/util/StreamParsingException.java + rm src/org/bouncycastle/asn1/util/Dump.java + rm src/org/bouncycastle/asn1/test/AllTests.java + rm src/org/bouncycastle/asn1/test/ASN1SequenceParserTest.java + rm src/org/bouncycastle/asn1/test/AttributeTableUnitTest.java + rm src/org/bouncycastle/asn1/test/BiometricDataUnitTest.java + rm src/org/bouncycastle/asn1/test/BitStringConstantTester.java + rm src/org/bouncycastle/asn1/test/CommitmentTypeIndicationUnitTest.java + rm src/org/bouncycastle/asn1/test/CommitmentTypeQualifierUnitTest.java + rm src/org/bouncycastle/asn1/test/DataGroupHashUnitTest.java + rm src/org/bouncycastle/asn1/test/DERUTF8StringTest.java + rm src/org/bouncycastle/asn1/test/EqualsAndHashCodeTest.java + rm src/org/bouncycastle/asn1/test/GeneralizedTimeTest.java + rm src/org/bouncycastle/asn1/test/GenerationTest.java + rm src/org/bouncycastle/asn1/test/InputStreamTest.java + rm src/org/bouncycastle/asn1/test/Iso4217CurrencyCodeUnitTest.java + rm src/org/bouncycastle/asn1/test/KeyUsageTest.java + rm src/org/bouncycastle/asn1/test/LDSSecurityObjectUnitTest.java + rm -rf src/org/bouncycastle/pqc/math/ntru + rm -rf src/org/bouncycastle/pqc/crypto/test/ntru + rm -rf src/org/bouncycastle/pqc/crypto/*/NTRU* + rm -rf src/org/bouncycastle/pqc/crypto/*/BitStringTest* + rm -rf src/org/bouncycastle/pqc/crypto/*/IndexGenerator* + rm src/org/bouncycastle/asn1/test/MonetaryValueUnitTest.java + rm src/org/bouncycastle/asn1/test/NameOrPseudonymUnitTest.java + rm src/org/bouncycastle/asn1/test/NetscapeCertTypeTest.java + rm src/org/bouncycastle/asn1/test/OctetStringTest.java + rm src/org/bouncycastle/asn1/test/ParseTest.java + rm src/org/bouncycastle/asn1/test/PersonalDataUnitTest.java + rm src/org/bouncycastle/asn1/test/PKIFailureInfoTest.java + rm src/org/bouncycastle/asn1/test/QCStatementUnitTest.java + rm src/org/bouncycastle/asn1/test/ReasonFlagsTest.java + rm src/org/bouncycastle/asn1/test/SemanticsInformationUnitTest.java + rm src/org/bouncycastle/asn1/test/SetTest.java + rm src/org/bouncycastle/asn1/test/SignerLocationUnitTest.java + rm src/org/bouncycastle/asn1/test/SMIMETest.java + rm src/org/bouncycastle/asn1/test/TagTest.java + rm src/org/bouncycastle/asn1/test/TypeOfBiometricDataUnitTest.java + rm src/org/bouncycastle/asn1/test/UTCTimeTest.java + rm src/org/bouncycastle/crypto/test/AESVectorFileTest.java + rm src/org/bouncycastle/crypto/test/GCMReorderTest.java + rm src/org/bouncycastle/crypto/test/HCFamilyVecTest.java + rm src/org/bouncycastle/crypto/test/RSABlindedTest.java + find src -name AllTests.java -exec rm {} \; + find src -name jcajce -exec rm -r {} \; + rm src/org/bouncycastle/asn1/test/GetInstanceTest.java + rm src/org/bouncycastle/asn1/test/ASN1SequenceParserTest.java + rm src/org/bouncycastle/asn1/test/OctetStringTest.java + rm src/org/bouncycastle/asn1/test/ParseTest.java + rm src/org/bouncycastle/crypto/test/GCMReorderTest.java + rm -r src/org/bouncycastle/pqc/crypto/test + rm src/org/bouncycastle/cert/test/BcCertTest.java + rm src/org/bouncycastle/crypto/test/SCryptTest.java + rm src/org/bouncycastle/crypto/examples/DESExample.java + rm src/org/bouncycastle/pqc/crypto/test/EncryptionKeyTest.java + rm -r src/org/bouncycastle/util/io/pem + rm -r src/org/bouncycastle/crypto/test/cavp + rm -r src/org/bouncycastle/crypto/test/speedy + rm -r src/org/bouncycastle/asn1/test/EnumeratedTest.java + rm -r src/org/bouncycastle/crypto/test/KDFFeedbackGeneratorTest.java + rm -r src/org/bouncycastle/crypto/test/KDFDoublePipelineIteratorGeneratorTest.java + rm -r src/org/bouncycastle/crypto/test/KDFCounterGeneratorTest.java + rm src/org/bouncycastle/cert/test/ConverterTest.java + rm src/org/bouncycastle/cert/test/BcPKCS10Test.java + rm src/org/bouncycastle/cert/test/BcAttrCertTest.java + rm src/org/bouncycastle/cert/test/BcAttrCertSelectorTest.java + rm -r src/org/bouncycastle/util/utiltest + rm -r src/org/bouncycastle/openpgp/examples + rm src/org/bouncycastle/openpgp/PGPCompressed* + rm -r src/org/bouncycastle/util/encoders/test + rm -r src/org/bouncycastle/util/io/test + rm src/org/bouncycastle/cms/CMSProcessableFile.java + rm -r src/org/bouncycastle/math/ec/test + rm -r src/org/bouncycastle/crypto/agreement/test + rm -r src/org/bouncycastle/crypto/tls/test + rm -r src/org/bouncycastle/i18n + rm -r src/org/bouncycastle/openssl + rm -r src/org/bouncycastle/apache + rm -r src/org/bouncycastle/voms + rm src/org/bouncycastle/mozilla/SignedPublicKeyAndChallenge.java + ) + + + (2>&1 find $target -name CVS -exec rm -rf \{\} \; ) > /dev/null + + ( + cd $target; + javadoc -windowtitle "$WINDOWTITLE" -doctitle "$DOCTITLE" \ + -header "$HEADER" \ + -group "Lightweight Crypto Packages" "org.bouncycastle.crypto*" \ + -group "ASN.1 Support Packages" "org.bouncycastle.asn1*" \ + -group "OpenPGP Support Packages" "org.bouncycastle.bcpg*:org.bouncycastle.openpgp*" \ + -group "Basic Signing And Encryption" "org.bouncycastle.operator*" \ + -group "Certificate Generation And Handling Support Packages" "org.bouncycastle.cert*" \ + -group "CMS Support Packages" "org.bouncycastle.cms*" \ + -group "EAC Support Packages" "org.bouncycastle.eac*" \ + -group "TSP Support Packages" "org.bouncycastle.tsp*" \ + -group "PKCS Support Packages" "org.bouncycastle.pkcs*" \ + -group "Post-Quantum Crypto Packages" "org.bouncycastle.pqc*" \ + -group "Utility Packages" "org.bouncycastle.util*:org.bouncycastle.math*" \ + -classpath classes \ + -d javadoc -sourcepath src -breakiterator \ + org.bouncycastle.asn1 \ + org.bouncycastle.asn1.cmp \ + org.bouncycastle.asn1.cms \ + org.bouncycastle.asn1.cryptopro \ + org.bouncycastle.asn1.esf \ + org.bouncycastle.asn1.ess \ + org.bouncycastle.asn1.gnu \ + org.bouncycastle.asn1.iana \ + org.bouncycastle.asn1.icao \ + org.bouncycastle.asn1.misc \ + org.bouncycastle.asn1.mozilla \ + org.bouncycastle.asn1.nist \ + org.bouncycastle.asn1.ocsp \ + org.bouncycastle.asn1.oiw \ + org.bouncycastle.asn1.pkcs \ + org.bouncycastle.asn1.sec \ + org.bouncycastle.asn1.smime \ + org.bouncycastle.asn1.teletrust \ + org.bouncycastle.asn1.test \ + org.bouncycastle.asn1.tsp \ + org.bouncycastle.asn1.util \ + org.bouncycastle.asn1.x500 \ + org.bouncycastle.asn1.x500.style \ + org.bouncycastle.asn1.x509 \ + org.bouncycastle.asn1.x9 \ + org.bouncycastle.bcpg \ + org.bouncycastle.bcpg.sig \ + org.bouncycastle.openpgp \ + org.bouncycastle.openpgp.bc \ + org.bouncycastle.openpgp.operator \ + org.bouncycastle.openpgp.operator.bc \ + org.bouncycastle.operator \ + org.bouncycastle.operator.bc \ + org.bouncycastle.cert \ + org.bouncycastle.cert.crmf \ + org.bouncycastle.cert.crmf.bc \ + org.bouncycastle.cert.cmp \ + org.bouncycastle.pkcs \ + org.bouncycastle.pkcs.bc \ + org.bouncycastle.tsp \ + org.bouncycastle.cms \ + org.bouncycastle.cms.bc \ + org.bouncycastle.math.ec \ + org.bouncycastle.crypto \ + org.bouncycastle.crypto.agreement \ + org.bouncycastle.crypto.commitments \ + org.bouncycastle.crypto.digests \ + org.bouncycastle.crypto.encodings \ + org.bouncycastle.crypto.engines \ + org.bouncycastle.crypto.generators \ + org.bouncycastle.crypto.io \ + org.bouncycastle.crypto.kems \ + org.bouncycastle.crypto.macs \ + org.bouncycastle.crypto.modes \ + org.bouncycastle.crypto.params \ + org.bouncycastle.crypto.parsers \ + org.bouncycastle.crypto.paddings \ + org.bouncycastle.crypto.signers \ + org.bouncycastle.crypto.prng \ + org.bouncycastle.crypto.tls \ + org.bouncycastle.crypto.test \ + org.bouncycastle.crypto.util \ + org.bouncycastle.crypto.examples \ + org.bouncycastle.pqc.asn1 \ + org.bouncycastle.pqc.crypto \ + org.bouncycastle.pqc.crypto.rainbow \ + org.bouncycastle.pqc.crypto.mceliece \ + org.bouncycastle.pqc.crypto.gmss \ + org.bouncycastle.pqc.math.linearalgebra \ + org.bouncycastle.util \ + org.bouncycastle.util.encoders \ + org.bouncycastle.util.test > /dev/null \ + + ) +fi + diff --git a/core/src/main/j2me/org/bouncycastle/asn1/ASN1GeneralizedTime.java b/core/src/main/j2me/org/bouncycastle/asn1/ASN1GeneralizedTime.java index ea2cb3f2..87058121 100644 --- a/core/src/main/j2me/org/bouncycastle/asn1/ASN1GeneralizedTime.java +++ b/core/src/main/j2me/org/bouncycastle/asn1/ASN1GeneralizedTime.java @@ -1,27 +1,260 @@ package org.bouncycastle.asn1; +import java.io.IOException; import java.util.Date; +import java.util.TimeZone; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; + +/** + * Generalized time object. + */ public class ASN1GeneralizedTime - extends DERGeneralizedTime + extends ASN1Primitive { - ASN1GeneralizedTime(byte[] bytes) + private byte[] time; + + /** + * return a generalized time from the passed in object + * + * @exception IllegalArgumentException if the object cannot be converted. + */ + public static ASN1GeneralizedTime getInstance( + Object obj) + { + if (obj == null || obj instanceof ASN1GeneralizedTime) + { + return (ASN1GeneralizedTime)obj; + } + + if (obj instanceof ASN1GeneralizedTime) + { + return new ASN1GeneralizedTime(((ASN1GeneralizedTime)obj).time); + } + + throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); + } + + /** + * return a Generalized Time object from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicit true if the object is meant to be explicitly + * tagged false otherwise. + * @exception IllegalArgumentException if the tagged object cannot + * be converted. + */ + public static ASN1GeneralizedTime getInstance( + ASN1TaggedObject obj, + boolean explicit) + { + ASN1Primitive o = obj.getObject(); + + if (explicit || o instanceof ASN1GeneralizedTime) + { + return getInstance(o); + } + else + { + return new ASN1GeneralizedTime(((ASN1OctetString)o).getOctets()); + } + } + + /** + * The correct format for this is YYYYMMDDHHMMSS[.f]Z, or without the Z + * for local time, or Z|[+|-]HHMM on the end, for difference between local + * time and UTC time. The fractional second amount f must consist of at + * least one number with trailing zeroes removed. + * + * @param time the time string. + * @exception IllegalArgumentException if String is an illegal format. + */ + public ASN1GeneralizedTime( + String time) + { + char last = time.charAt(time.length() - 1); + if (last != 'Z' && !(last >= 0 && last <= '9')) + { + if (time.indexOf('-') < 0 && time.indexOf('+') < 0) + { + throw new IllegalArgumentException("time needs to be in format YYYYMMDDHHMMSS[.f]Z or YYYYMMDDHHMMSS[.f][+-]HHMM"); + } + } + + this.time = Strings.toByteArray(time); + } + + /** + * base constructer from a java.util.date object + */ + public ASN1GeneralizedTime( + Date time) + { + this.time = Strings.toByteArray(DateFormatter.getGeneralizedTimeDateString(time, false)); + } + + protected ASN1GeneralizedTime(Date date, boolean includeMillis) { - super(bytes); + this.time = Strings.toByteArray(DateFormatter.getGeneralizedTimeDateString(date, true)); } - public ASN1GeneralizedTime(Date date) + ASN1GeneralizedTime( + byte[] bytes) { - super(date); + this.time = bytes; } - public ASN1GeneralizedTime(Date date, boolean includeMillis) + /** + * Return the time. + * @return The time string as it appeared in the encoded object. + */ + public String getTimeString() + { + return Strings.fromByteArray(time); + } + + /** + * return the time - always in the form of + * YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm). + * <p> + * Normally in a certificate we would expect "Z" rather than "GMT", + * however adding the "GMT" means we can just use: + * <pre> + * dateF = new SimpleDateFormat("yyyyMMddHHmmssz"); + * </pre> + * To read in the time and get a date which is compatible with our local + * time zone. + */ + public String getTime() { - super(date, includeMillis); + String stime = Strings.fromByteArray(time); + + // + // standardise the format. + // + if (stime.charAt(stime.length() - 1) == 'Z') + { + return stime.substring(0, stime.length() - 1) + "GMT+00:00"; + } + else + { + int signPos = stime.length() - 5; + char sign = stime.charAt(signPos); + if (sign == '-' || sign == '+') + { + return stime.substring(0, signPos) + + "GMT" + + stime.substring(signPos, signPos + 3) + + ":" + + stime.substring(signPos + 3); + } + else + { + signPos = stime.length() - 3; + sign = stime.charAt(signPos); + if (sign == '-' || sign == '+') + { + return stime.substring(0, signPos) + + "GMT" + + stime.substring(signPos) + + ":00"; + } + } + } + return stime + calculateGMTOffset(); } - public ASN1GeneralizedTime(String time) + private String calculateGMTOffset() + { + String sign = "+"; + TimeZone timeZone = TimeZone.getDefault(); + int offset = timeZone.getRawOffset(); + if (offset < 0) + { + sign = "-"; + offset = -offset; + } + int hours = offset / (60 * 60 * 1000); + int minutes = (offset - (hours * 60 * 60 * 1000)) / (60 * 1000); + +// try +// { +// if (timeZone.useDaylightTime() && timeZone.inDaylightTime(this.getDate())) +// { +// hours += sign.equals("+") ? 1 : -1; +// } +// } +// catch (ParseException e) +// { +// // we'll do our best and ignore daylight savings +// } + + return "GMT" + sign + convert(hours) + ":" + convert(minutes); + } + + private String convert(int time) + { + if (time < 10) + { + return "0" + time; + } + + return Integer.toString(time); + } + + public Date getDate() + { + return DateFormatter.fromGeneralizedTimeString(time); + } + + private boolean hasFractionalSeconds() + { + for (int i = 0; i != time.length; i++) + { + if (time[i] == '.') + { + if (i == 14) + { + return true; + } + } + } + return false; + } + + boolean isConstructed() + { + return false; + } + + int encodedLength() + { + int length = time.length; + + return 1 + StreamUtil.calculateBodyLength(length) + length; + } + + void encode( + ASN1OutputStream out) + throws IOException + { + out.writeEncoded(BERTags.GENERALIZED_TIME, time); + } + + boolean asn1Equals( + ASN1Primitive o) + { + if (!(o instanceof ASN1GeneralizedTime)) + { + return false; + } + + return Arrays.areEqual(time, ((ASN1GeneralizedTime)o).time); + } + + public int hashCode() { - super(time); + return Arrays.hashCode(time); } } diff --git a/core/src/main/j2me/org/bouncycastle/asn1/ASN1UTCTime.java b/core/src/main/j2me/org/bouncycastle/asn1/ASN1UTCTime.java index aac76e10..0d18c6af 100644 --- a/core/src/main/j2me/org/bouncycastle/asn1/ASN1UTCTime.java +++ b/core/src/main/j2me/org/bouncycastle/asn1/ASN1UTCTime.java @@ -1,22 +1,259 @@ package org.bouncycastle.asn1; +import java.io.IOException; import java.util.Date; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Strings; + +/** + * UTC time object. + */ public class ASN1UTCTime - extends DERUTCTime + extends ASN1Primitive { - ASN1UTCTime(byte[] bytes) + private byte[] time; + + /** + * return an UTC Time from the passed in object. + * + * @exception IllegalArgumentException if the object cannot be converted. + */ + public static ASN1UTCTime getInstance( + Object obj) + { + if (obj == null || obj instanceof ASN1UTCTime) + { + return (ASN1UTCTime)obj; + } + + if (obj instanceof ASN1UTCTime) + { + return new ASN1UTCTime(((ASN1UTCTime)obj).time); + } + + throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); + } + + /** + * return an UTC Time from a tagged object. + * + * @param obj the tagged object holding the object we want + * @param explicit true if the object is meant to be explicitly + * tagged false otherwise. + * @exception IllegalArgumentException if the tagged object cannot + * be converted. + */ + public static ASN1UTCTime getInstance( + ASN1TaggedObject obj, + boolean explicit) + { + ASN1Object o = obj.getObject(); + + if (explicit || o instanceof ASN1UTCTime) + { + return getInstance(o); + } + else + { + return new ASN1UTCTime(((ASN1OctetString)o).getOctets()); + } + } + + /** + * The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were + * never encoded. When you're creating one of these objects from scratch, that's + * what you want to use, otherwise we'll try to deal with whatever gets read from + * the input stream... (this is why the input format is different from the getTime() + * method output). + * <p> + * + * @param time the time string. + */ + public ASN1UTCTime( + String time) + { + if (time.charAt(time.length() - 1) != 'Z') + { + // we accept this as a variation + if (time.indexOf('-') < 0 && time.indexOf('+') < 0) + { + throw new IllegalArgumentException("time needs to be in format YYMMDDHHMMSSZ"); + } + } + + this.time = Strings.toByteArray(time); + } + + /** + * base constructor from a java.util.date object + */ + public ASN1UTCTime( + Date time) + { + this.time = Strings.toByteArray(DateFormatter.toUTCDateString(time)); + } + + ASN1UTCTime( + byte[] time) + { + this.time = time; + } + + /** + * return the time as a date based on whatever a 2 digit year will return. For + * standardised processing use getAdjustedDate(). + * + * @return the resulting date + */ + public Date getDate() { - super(bytes); + return DateFormatter.adjustedFromUTCDateString(time); } - public ASN1UTCTime(Date date) + /** + * return the time as an adjusted date + * in the range of 1950 - 2049. + * + * @return a date in the range of 1950 to 2049. + */ + public Date getAdjustedDate() + { + return DateFormatter.adjustedFromUTCDateString(time); + } + + /** + * return the time - always in the form of + * YYMMDDhhmmssGMT(+hh:mm|-hh:mm). + * <p> + * Normally in a certificate we would expect "Z" rather than "GMT", + * however adding the "GMT" means we can just use: + * <pre> + * dateF = new SimpleDateFormat("yyMMddHHmmssz"); + * </pre> + * To read in the time and get a date which is compatible with our local + * time zone. + * <p> + * <b>Note:</b> In some cases, due to the local date processing, this + * may lead to unexpected results. If you want to stick the normal + * convention of 1950 to 2049 use the getAdjustedTime() method. + */ + public String getTime() + { + String stime = Strings.fromByteArray(time); + + // + // standardise the format. + // + if (stime.indexOf('-') < 0 && stime.indexOf('+') < 0) + { + if (stime.length() == 11) + { + return stime.substring(0, 10) + "00GMT+00:00"; + } + else + { + return stime.substring(0, 12) + "GMT+00:00"; + } + } + else + { + int index = stime.indexOf('-'); + if (index < 0) + { + index = stime.indexOf('+'); + } + String d = stime; + + if (index == stime.length() - 3) + { + d += "00"; + } + + if (index == 10) + { + return d.substring(0, 10) + "00GMT" + d.substring(10, 13) + ":" + d.substring(13, 15); + } + else + { + return d.substring(0, 12) + "GMT" + d.substring(12, 15) + ":" + d.substring(15, 17); + } + } + } + + /** + * return a time string as an adjusted date with a 4 digit year. This goes + * in the range of 1950 - 2049. + */ + public String getAdjustedTime() + { + String d = this.getTime(); + + if (d.charAt(0) < '5') + { + return "20" + d; + } + else + { + return "19" + d; + } + } + + /** + * Return the time. + * @return The time string as it appeared in the encoded object. + */ + public String getTimeString() + { + return Strings.fromByteArray(time); + } + + boolean isConstructed() + { + return false; + } + + int encodedLength() + { + int length = time.length; + + return 1 + StreamUtil.calculateBodyLength(length) + length; + } + + void encode( + ASN1OutputStream out) + throws IOException + { + out.write(BERTags.UTC_TIME); + + int length = time.length; + + out.writeLength(length); + + for (int i = 0; i != length; i++) + { + out.write((byte)time[i]); + } + } + + boolean asn1Equals( + ASN1Primitive o) + { + if (!(o instanceof ASN1UTCTime)) + { + return false; + } + + return Arrays.areEqual(time, ((ASN1UTCTime)o).time); + } + + public int hashCode() { - super(date); + return Arrays.hashCode(time); } - public ASN1UTCTime(String time) + public String toString() { - super(time); + return Strings.fromByteArray(time); } } diff --git a/core/src/main/j2me/org/bouncycastle/asn1/DERGeneralizedTime.java b/core/src/main/j2me/org/bouncycastle/asn1/DERGeneralizedTime.java index 2cb95b60..6162da40 100644 --- a/core/src/main/j2me/org/bouncycastle/asn1/DERGeneralizedTime.java +++ b/core/src/main/j2me/org/bouncycastle/asn1/DERGeneralizedTime.java @@ -1,260 +1,27 @@ package org.bouncycastle.asn1; -import java.io.IOException; import java.util.Date; -import java.util.TimeZone; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.Strings; - -/** - * Generalized time object. - */ public class DERGeneralizedTime - extends ASN1Primitive + extends ASN1GeneralizedTime { - private byte[] time; - - /** - * return a generalized time from the passed in object - * - * @exception IllegalArgumentException if the object cannot be converted. - */ - public static ASN1GeneralizedTime getInstance( - Object obj) - { - if (obj == null || obj instanceof ASN1GeneralizedTime) - { - return (ASN1GeneralizedTime)obj; - } - - if (obj instanceof DERGeneralizedTime) - { - return new ASN1GeneralizedTime(((DERGeneralizedTime)obj).time); - } - - throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); - } - - /** - * return a Generalized Time object from a tagged object. - * - * @param obj the tagged object holding the object we want - * @param explicit true if the object is meant to be explicitly - * tagged false otherwise. - * @exception IllegalArgumentException if the tagged object cannot - * be converted. - */ - public static ASN1GeneralizedTime getInstance( - ASN1TaggedObject obj, - boolean explicit) - { - ASN1Primitive o = obj.getObject(); - - if (explicit || o instanceof DERGeneralizedTime) - { - return getInstance(o); - } - else - { - return new ASN1GeneralizedTime(((ASN1OctetString)o).getOctets()); - } - } - - /** - * The correct format for this is YYYYMMDDHHMMSS[.f]Z, or without the Z - * for local time, or Z|[+|-]HHMM on the end, for difference between local - * time and UTC time. The fractional second amount f must consist of at - * least one number with trailing zeroes removed. - * - * @param time the time string. - * @exception IllegalArgumentException if String is an illegal format. - */ - public DERGeneralizedTime( - String time) - { - char last = time.charAt(time.length() - 1); - if (last != 'Z' && !(last >= 0 && last <= '9')) - { - if (time.indexOf('-') < 0 && time.indexOf('+') < 0) - { - throw new IllegalArgumentException("time needs to be in format YYYYMMDDHHMMSS[.f]Z or YYYYMMDDHHMMSS[.f][+-]HHMM"); - } - } - - this.time = Strings.toByteArray(time); - } - - /** - * base constructer from a java.util.date object - */ - public DERGeneralizedTime( - Date time) - { - this.time = Strings.toByteArray(DateFormatter.getGeneralizedTimeDateString(time, false)); - } - - protected DERGeneralizedTime(Date date, boolean includeMillis) + DERGeneralizedTime(byte[] bytes) { - this.time = Strings.toByteArray(DateFormatter.getGeneralizedTimeDateString(date, true)); + super(bytes); } - DERGeneralizedTime( - byte[] bytes) + public DERGeneralizedTime(Date date) { - this.time = bytes; + super(date); } - /** - * Return the time. - * @return The time string as it appeared in the encoded object. - */ - public String getTimeString() - { - return Strings.fromByteArray(time); - } - - /** - * return the time - always in the form of - * YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm). - * <p> - * Normally in a certificate we would expect "Z" rather than "GMT", - * however adding the "GMT" means we can just use: - * <pre> - * dateF = new SimpleDateFormat("yyyyMMddHHmmssz"); - * </pre> - * To read in the time and get a date which is compatible with our local - * time zone. - */ - public String getTime() + public DERGeneralizedTime(Date date, boolean includeMillis) { - String stime = Strings.fromByteArray(time); - - // - // standardise the format. - // - if (stime.charAt(stime.length() - 1) == 'Z') - { - return stime.substring(0, stime.length() - 1) + "GMT+00:00"; - } - else - { - int signPos = stime.length() - 5; - char sign = stime.charAt(signPos); - if (sign == '-' || sign == '+') - { - return stime.substring(0, signPos) - + "GMT" - + stime.substring(signPos, signPos + 3) - + ":" - + stime.substring(signPos + 3); - } - else - { - signPos = stime.length() - 3; - sign = stime.charAt(signPos); - if (sign == '-' || sign == '+') - { - return stime.substring(0, signPos) - + "GMT" - + stime.substring(signPos) - + ":00"; - } - } - } - return stime + calculateGMTOffset(); + super(date, includeMillis); } - private String calculateGMTOffset() - { - String sign = "+"; - TimeZone timeZone = TimeZone.getDefault(); - int offset = timeZone.getRawOffset(); - if (offset < 0) - { - sign = "-"; - offset = -offset; - } - int hours = offset / (60 * 60 * 1000); - int minutes = (offset - (hours * 60 * 60 * 1000)) / (60 * 1000); - -// try -// { -// if (timeZone.useDaylightTime() && timeZone.inDaylightTime(this.getDate())) -// { -// hours += sign.equals("+") ? 1 : -1; -// } -// } -// catch (ParseException e) -// { -// // we'll do our best and ignore daylight savings -// } - - return "GMT" + sign + convert(hours) + ":" + convert(minutes); - } - - private String convert(int time) - { - if (time < 10) - { - return "0" + time; - } - - return Integer.toString(time); - } - - public Date getDate() - { - return DateFormatter.fromGeneralizedTimeString(time); - } - - private boolean hasFractionalSeconds() - { - for (int i = 0; i != time.length; i++) - { - if (time[i] == '.') - { - if (i == 14) - { - return true; - } - } - } - return false; - } - - boolean isConstructed() - { - return false; - } - - int encodedLength() - { - int length = time.length; - - return 1 + StreamUtil.calculateBodyLength(length) + length; - } - - void encode( - ASN1OutputStream out) - throws IOException - { - out.writeEncoded(BERTags.GENERALIZED_TIME, time); - } - - boolean asn1Equals( - ASN1Primitive o) - { - if (!(o instanceof DERGeneralizedTime)) - { - return false; - } - - return Arrays.areEqual(time, ((DERGeneralizedTime)o).time); - } - - public int hashCode() + public DERGeneralizedTime(String time) { - return Arrays.hashCode(time); + super(time); } } diff --git a/core/src/main/j2me/org/bouncycastle/asn1/DERUTCTime.java b/core/src/main/j2me/org/bouncycastle/asn1/DERUTCTime.java index 3e8010b4..621febff 100644 --- a/core/src/main/j2me/org/bouncycastle/asn1/DERUTCTime.java +++ b/core/src/main/j2me/org/bouncycastle/asn1/DERUTCTime.java @@ -1,259 +1,22 @@ package org.bouncycastle.asn1; -import java.io.IOException; import java.util.Date; -import org.bouncycastle.util.Arrays; -import org.bouncycastle.util.Strings; - -/** - * UTC time object. - */ public class DERUTCTime - extends ASN1Primitive + extends ASN1UTCTime { - private byte[] time; - - /** - * return an UTC Time from the passed in object. - * - * @exception IllegalArgumentException if the object cannot be converted. - */ - public static ASN1UTCTime getInstance( - Object obj) - { - if (obj == null || obj instanceof ASN1UTCTime) - { - return (ASN1UTCTime)obj; - } - - if (obj instanceof DERUTCTime) - { - return new ASN1UTCTime(((DERUTCTime)obj).time); - } - - throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); - } - - /** - * return an UTC Time from a tagged object. - * - * @param obj the tagged object holding the object we want - * @param explicit true if the object is meant to be explicitly - * tagged false otherwise. - * @exception IllegalArgumentException if the tagged object cannot - * be converted. - */ - public static ASN1UTCTime getInstance( - ASN1TaggedObject obj, - boolean explicit) - { - ASN1Object o = obj.getObject(); - - if (explicit || o instanceof ASN1UTCTime) - { - return getInstance(o); - } - else - { - return new ASN1UTCTime(((ASN1OctetString)o).getOctets()); - } - } - - /** - * The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were - * never encoded. When you're creating one of these objects from scratch, that's - * what you want to use, otherwise we'll try to deal with whatever gets read from - * the input stream... (this is why the input format is different from the getTime() - * method output). - * <p> - * - * @param time the time string. - */ - public DERUTCTime( - String time) - { - if (time.charAt(time.length() - 1) != 'Z') - { - // we accept this as a variation - if (time.indexOf('-') < 0 && time.indexOf('+') < 0) - { - throw new IllegalArgumentException("time needs to be in format YYMMDDHHMMSSZ"); - } - } - - this.time = Strings.toByteArray(time); - } - - /** - * base constructor from a java.util.date object - */ - public DERUTCTime( - Date time) - { - this.time = Strings.toByteArray(DateFormatter.toUTCDateString(time)); - } - - DERUTCTime( - byte[] time) - { - this.time = time; - } - - /** - * return the time as a date based on whatever a 2 digit year will return. For - * standardised processing use getAdjustedDate(). - * - * @return the resulting date - */ - public Date getDate() + DERUTCTime(byte[] bytes) { - return DateFormatter.adjustedFromUTCDateString(time); + super(bytes); } - /** - * return the time as an adjusted date - * in the range of 1950 - 2049. - * - * @return a date in the range of 1950 to 2049. - */ - public Date getAdjustedDate() - { - return DateFormatter.adjustedFromUTCDateString(time); - } - - /** - * return the time - always in the form of - * YYMMDDhhmmssGMT(+hh:mm|-hh:mm). - * <p> - * Normally in a certificate we would expect "Z" rather than "GMT", - * however adding the "GMT" means we can just use: - * <pre> - * dateF = new SimpleDateFormat("yyMMddHHmmssz"); - * </pre> - * To read in the time and get a date which is compatible with our local - * time zone. - * <p> - * <b>Note:</b> In some cases, due to the local date processing, this - * may lead to unexpected results. If you want to stick the normal - * convention of 1950 to 2049 use the getAdjustedTime() method. - */ - public String getTime() - { - String stime = Strings.fromByteArray(time); - - // - // standardise the format. - // - if (stime.indexOf('-') < 0 && stime.indexOf('+') < 0) - { - if (stime.length() == 11) - { - return stime.substring(0, 10) + "00GMT+00:00"; - } - else - { - return stime.substring(0, 12) + "GMT+00:00"; - } - } - else - { - int index = stime.indexOf('-'); - if (index < 0) - { - index = stime.indexOf('+'); - } - String d = stime; - - if (index == stime.length() - 3) - { - d += "00"; - } - - if (index == 10) - { - return d.substring(0, 10) + "00GMT" + d.substring(10, 13) + ":" + d.substring(13, 15); - } - else - { - return d.substring(0, 12) + "GMT" + d.substring(12, 15) + ":" + d.substring(15, 17); - } - } - } - - /** - * return a time string as an adjusted date with a 4 digit year. This goes - * in the range of 1950 - 2049. - */ - public String getAdjustedTime() - { - String d = this.getTime(); - - if (d.charAt(0) < '5') - { - return "20" + d; - } - else - { - return "19" + d; - } - } - - /** - * Return the time. - * @return The time string as it appeared in the encoded object. - */ - public String getTimeString() - { - return Strings.fromByteArray(time); - } - - boolean isConstructed() - { - return false; - } - - int encodedLength() - { - int length = time.length; - - return 1 + StreamUtil.calculateBodyLength(length) + length; - } - - void encode( - ASN1OutputStream out) - throws IOException - { - out.write(BERTags.UTC_TIME); - - int length = time.length; - - out.writeLength(length); - - for (int i = 0; i != length; i++) - { - out.write((byte)time[i]); - } - } - - boolean asn1Equals( - ASN1Primitive o) - { - if (!(o instanceof DERUTCTime)) - { - return false; - } - - return Arrays.areEqual(time, ((DERUTCTime)o).time); - } - - public int hashCode() + public DERUTCTime(Date date) { - return Arrays.hashCode(time); + super(date); } - public String toString() + public DERUTCTime(String time) { - return Strings.fromByteArray(time); + super(time); } } diff --git a/core/src/main/j2me/org/bouncycastle/crypto/encodings/PKCS1Encoding.java b/core/src/main/j2me/org/bouncycastle/crypto/encodings/PKCS1Encoding.java index e4a8750f..76051c3f 100644 --- a/core/src/main/j2me/org/bouncycastle/crypto/encodings/PKCS1Encoding.java +++ b/core/src/main/j2me/org/bouncycastle/crypto/encodings/PKCS1Encoding.java @@ -1,13 +1,13 @@ package org.bouncycastle.crypto.encodings; +import java.security.SecureRandom; + import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.ParametersWithRandom; -import java.security.SecureRandom; - /** * this does your basic PKCS 1 v1.5 padding - whether or not you should be using this * depends on your application - see PKCS1 Version 2 for details. @@ -32,6 +32,8 @@ public class PKCS1Encoding private boolean forEncryption; private boolean forPrivateKey; private boolean useStrictLength; + private int pLen = -1; + private byte[] fallback = null; /** * Basic constructor. @@ -44,11 +46,48 @@ public class PKCS1Encoding this.useStrictLength = useStrict(); } + /** + * Constructor for decryption with a fixed plaintext length. + * + * @param cipher The cipher to use for cryptographic operation. + * @param pLen Length of the expected plaintext. + */ + public PKCS1Encoding( + AsymmetricBlockCipher cipher, + int pLen) + { + this.engine = cipher; + this.useStrictLength = useStrict(); + this.pLen = pLen; + } + + /** + * Constructor for decryption with a fixed plaintext length and a fallback + * value that is returned, if the padding is incorrect. + * + * @param cipher + * The cipher to use for cryptographic operation. + * @param fallback + * The fallback value, we don't to a arraycopy here. + */ + public PKCS1Encoding( + AsymmetricBlockCipher cipher, + byte[] fallback) + { + this.engine = cipher; + this.useStrictLength = useStrict(); + this.fallback = fallback; + this.pLen = fallback.length; + } + + + // // for J2ME compatibility // private boolean useStrict() { + // required if security manager has been installed. String strict = System.getProperty(STRICT_LENGTH_ENABLED_PROPERTY); return strict == null || strict.equals("true"); @@ -174,6 +213,121 @@ 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. + * @return Either 0, if the encoding is correct, or -1, if it is incorrect. + */ + private static int checkPkcs1Encoding(byte[] encoded, int pLen) { + int correct = 0; + /* + * Check if the first two bytes are 0 2 + */ + correct |= (encoded[0] ^ 2); + + /* + * Now the padding check, check for no 0 byte in the padding + */ + int plen = encoded.length - ( + pLen /* 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)]; + + /* + * Return 0 or 1, depending on the result. + */ + correct |= correct >> 1; + correct |= correct >> 2; + correct |= correct >> 4; + return ~((correct & 1) - 1); + } + + + /** + * Decode PKCS#1.5 encoding, and return a random value if the padding is not correct. + * + * @param in The encrypted block. + * @param inOff Offset in the encrypted block. + * @param inLen Length of the encrypted block. + * //@param pLen Length of the desired output. + * @return The plaintext without padding, or a random value if the padding was incorrect. + * + * @throws InvalidCipherTextException + */ + private byte[] decodeBlockOrRandom(byte[] in, int inOff, int inLen) + throws InvalidCipherTextException + { + if (!forPrivateKey) + { + throw new InvalidCipherTextException("sorry, this method is only for decryption, not for signing"); + } + + byte[] block = engine.processBlock(in, inOff, inLen); + byte[] random = null; + if (this.fallback == null) + { + random = new byte[this.pLen]; + this.random.nextBytes(random); + } + else + { + 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"); + } + + /* + * Check the padding. + */ + int correct = PKCS1Encoding.checkPkcs1Encoding(block, this.pLen); + + /* + * Now, to a constant time constant memory copy of the decrypted value + * or the random value, depending on the validity of the padding. + */ + byte[] result = new byte[this.pLen]; + for (int i = 0; i < this.pLen; i++) + { + result[i] = (byte)((block[i + (block.length - pLen)] & (~correct)) | (random[i] & correct)); + } + + return result; + } /** * @exception InvalidCipherTextException if the decrypted block is not in PKCS1 format. @@ -184,7 +338,15 @@ public class PKCS1Encoding int inLen) throws InvalidCipherTextException { - byte[] block = engine.processBlock(in, inOff, inLen); + /* + * If the length of the expected plaintext is known, we use a constant-time decryption. + * If the decryption fails, we return a random value. + */ + if (this.pLen != -1) { + return this.decodeBlockOrRandom(in, inOff, inLen); + } + + byte[] block = engine.processBlock(in, inOff, inLen); if (block.length < getOutputBlockSize()) { @@ -192,10 +354,20 @@ public class PKCS1Encoding } byte type = block[0]; - - if (type != 1 && type != 2) + + if (forPrivateKey) { - throw new InvalidCipherTextException("unknown block type"); + if (type != 2) + { + throw new InvalidCipherTextException("unknown block type"); + } + } + else + { + if (type != 1) + { + throw new InvalidCipherTextException("unknown block type"); + } } if (useStrictLength && block.length != engine.getOutputBlockSize()) diff --git a/core/src/main/j2me/org/bouncycastle/math/ec/LongArray.java b/core/src/main/j2me/org/bouncycastle/math/ec/LongArray.java index 4ed4ef4d..b8522c16 100644 --- a/core/src/main/j2me/org/bouncycastle/math/ec/LongArray.java +++ b/core/src/main/j2me/org/bouncycastle/math/ec/LongArray.java @@ -371,6 +371,23 @@ class LongArray } } + public boolean isOne() + { + long[] a = m_ints; + if (a[0] != 1L) + { + return false; + } + for (int i = 1; i < a.length; ++i) + { + if (a[i] != 0L) + { + return false; + } + } + return true; + } + public boolean isZero() { long[] a = m_ints; @@ -822,12 +839,12 @@ class LongArray add(c, cOff, b, 0, bLen); } int k = 1; - while ((a >>>= 1) != 0) + while ((a >>>= 1) != 0L) { if ((a & 1L) != 0L) { long carry = addShiftedUp(c, cOff, b, 0, bLen, k); - if (carry != 0) + if (carry != 0L) { c[cOff + bLen] ^= carry; } @@ -871,8 +888,8 @@ class LongArray if (aLen == 1) { - long a = A.m_ints[0]; - if (a == 1L) + long a0 = A.m_ints[0]; + if (a0 == 1L) { return B; } @@ -880,13 +897,13 @@ class LongArray /* * Fast path for small A, with performance dependent only on the number of set bits */ - long[] c = new long[cLen]; - multiplyWord(a, B.m_ints, bLen, c, 0); + long[] c0 = new long[cLen]; + multiplyWord(a0, B.m_ints, bLen, c0, 0); /* * Reduce the raw answer against the reduction coefficients */ - return reduceResult(c, 0, cLen, m, ks); + return reduceResult(c0, 0, cLen, m, ks); } /* @@ -1003,8 +1020,8 @@ class LongArray if (aLen == 1) { - long a = A.m_ints[0]; - if (a == 1L) + long a0 = A.m_ints[0]; + if (a0 == 1L) { return B; } @@ -1012,13 +1029,13 @@ class LongArray /* * Fast path for small A, with performance dependent only on the number of set bits */ - long[] c = new long[cLen]; - multiplyWord(a, B.m_ints, bLen, c, 0); + long[] c0 = new long[cLen]; + multiplyWord(a0, B.m_ints, bLen, c0, 0); /* * Reduce the raw answer against the reduction coefficients */ - return reduceResult(c, 0, cLen, m, ks); + return reduceResult(c0, 0, cLen, m, ks); } /* @@ -1077,7 +1094,8 @@ class LongArray aVal >>>= 4; int v = (int)aVal & MASK; addBoth(c, cOff, T0, ti[u], T1, ti[v], bMax); - if ((aVal >>>= 4) == 0L) + aVal >>>= 4; + if (aVal == 0L) { break; } @@ -1085,10 +1103,12 @@ class LongArray } } - int cOff = c.length; - while ((cOff -= cLen) != 0) { - addShiftedUp(c, cOff - cLen, c, cOff, cLen, 8); + int cOff = c.length; + while ((cOff -= cLen) != 0) + { + addShiftedUp(c, cOff - cLen, c, cOff, cLen, 8); + } } /* @@ -1132,8 +1152,8 @@ class LongArray if (aLen == 1) { - long a = A.m_ints[0]; - if (a == 1L) + long a0 = A.m_ints[0]; + if (a0 == 1L) { return B; } @@ -1141,13 +1161,13 @@ class LongArray /* * Fast path for small A, with performance dependent only on the number of set bits */ - long[] c = new long[cLen]; - multiplyWord(a, B.m_ints, bLen, c, 0); + long[] c0 = new long[cLen]; + multiplyWord(a0, B.m_ints, bLen, c0, 0); /* * Reduce the raw answer against the reduction coefficients */ - return reduceResult(c, 0, cLen, m, ks); + return reduceResult(c0, 0, cLen, m, ks); } // NOTE: This works, but is slower than width 4 processing @@ -1314,6 +1334,158 @@ class LongArray return reduceResult(c, ci[1], cLen, m, ks); } + public LongArray modReduce(int m, int[] ks) + { + long[] buf = Arrays.clone(m_ints); + int rLen = reduceInPlace(buf, 0, buf.length, m, ks); + return new LongArray(buf, 0, rLen); + } + + public LongArray multiply(LongArray other, int m, int[] ks) + { + /* + * Find out the degree of each argument and handle the zero cases + */ + int aDeg = degree(); + if (aDeg == 0) + { + return this; + } + int bDeg = other.degree(); + if (bDeg == 0) + { + return other; + } + + /* + * Swap if necessary so that A is the smaller argument + */ + LongArray A = this, B = other; + if (aDeg > bDeg) + { + A = other; B = this; + int tmp = aDeg; aDeg = bDeg; bDeg = tmp; + } + + /* + * Establish the word lengths of the arguments and result + */ + int aLen = (aDeg + 63) >>> 6; + int bLen = (bDeg + 63) >>> 6; + int cLen = (aDeg + bDeg + 62) >>> 6; + + if (aLen == 1) + { + long a0 = A.m_ints[0]; + if (a0 == 1L) + { + return B; + } + + /* + * Fast path for small A, with performance dependent only on the number of set bits + */ + long[] c0 = new long[cLen]; + multiplyWord(a0, B.m_ints, bLen, c0, 0); + + /* + * Reduce the raw answer against the reduction coefficients + */ +// return reduceResult(c0, 0, cLen, m, ks); + return new LongArray(c0, 0, cLen); + } + + /* + * Determine if B will get bigger during shifting + */ + int bMax = (bDeg + 7 + 63) >>> 6; + + /* + * Lookup table for the offset of each B in the tables + */ + int[] ti = new int[16]; + + /* + * Precompute table of all 4-bit products of B + */ + long[] T0 = new long[bMax << 4]; + int tOff = bMax; + ti[1] = tOff; + System.arraycopy(B.m_ints, 0, T0, tOff, bLen); + for (int i = 2; i < 16; ++i) + { + ti[i] = (tOff += bMax); + if ((i & 1) == 0) + { + shiftUp(T0, tOff >>> 1, T0, tOff, bMax, 1); + } + else + { + add(T0, bMax, T0, tOff - bMax, T0, tOff, bMax); + } + } + + /* + * Second table with all 4-bit products of B shifted 4 bits + */ + long[] T1 = new long[T0.length]; + shiftUp(T0, 0, T1, 0, T0.length, 4); +// shiftUp(T0, bMax, T1, bMax, tOff, 4); + + long[] a = A.m_ints; + long[] c = new long[cLen << 3]; + + int MASK = 0xF; + + /* + * Lopez-Dahab (Modified) algorithm + */ + + for (int aPos = 0; aPos < aLen; ++aPos) + { + long aVal = a[aPos]; + int cOff = aPos; + for (;;) + { + int u = (int)aVal & MASK; + aVal >>>= 4; + int v = (int)aVal & MASK; + addBoth(c, cOff, T0, ti[u], T1, ti[v], bMax); + aVal >>>= 4; + if (aVal == 0L) + { + break; + } + cOff += cLen; + } + } + + { + int cOff = c.length; + while ((cOff -= cLen) != 0) + { + addShiftedUp(c, cOff - cLen, c, cOff, cLen, 8); + } + } + + /* + * Finally the raw answer is collected, reduce it against the reduction coefficients + */ +// return reduceResult(c, 0, cLen, m, ks); + return new LongArray(c, 0, cLen); + } + + public void reduce(int m, int[] ks) + { + long[] buf = m_ints; + int rLen = reduceInPlace(buf, 0, buf.length, m, ks); + if (rLen < buf.length) + { + m_ints = new long[rLen]; + System.arraycopy(buf, 0, m_ints, 0, rLen); + } + } + private static LongArray reduceResult(long[] buf, int off, int len, int m, int[] ks) { int rLen = reduceInPlace(buf, off, len, m, ks); @@ -1405,13 +1577,13 @@ class LongArray private static void reduceBit(long[] buf, int off, int bit, int m, int[] ks) { flipBit(buf, off, bit); - int base = bit - m; + int n = bit - m; int j = ks.length; while (--j >= 0) { - flipBit(buf, off, ks[j] + base); + flipBit(buf, off, ks[j] + n); } - flipBit(buf, off, base); + flipBit(buf, off, n); } private static void reduceWordWise(long[] buf, int off, int len, int toBit, int m, int[] ks) @@ -1428,12 +1600,14 @@ class LongArray } } - int partial = toBit & 0x3F; - long word = buf[off + toPos] >>> partial; - if (word != 0) { - buf[off + toPos] ^= word << partial; - reduceWord(buf, off, toBit, word, m, ks); + int partial = toBit & 0x3F; + long word = buf[off + toPos] >>> partial; + if (word != 0) + { + buf[off + toPos] ^= word << partial; + reduceWord(buf, off, toBit, word, m, ks); + } } } @@ -1502,37 +1676,59 @@ class LongArray return new LongArray(r, 0, reduceInPlace(r, 0, r.length, m, ks)); } -// private LongArray modSquareN(int n, int m, int[] ks) -// { -// int len = getUsedLength(); -// if (len == 0) -// { -// return this; -// } -// -// int mLen = (m + 63) >>> 6; -// long[] r = new long[mLen << 1]; -// System.arraycopy(m_ints, 0, r, 0, len); -// -// while (--n >= 0) -// { -// squareInPlace(r, len, m, ks); -// len = reduceInPlace(r, 0, r.length, m, ks); -// } -// -// return new LongArray(r, 0, len); -// } -// -// private static void squareInPlace(long[] x, int xLen, int m, int[] ks) -// { -// int pos = xLen << 1; -// while (--xLen >= 0) -// { -// long xVal = x[xLen]; -// x[--pos] = interleave2_32to64((int)(xVal >>> 32)); -// x[--pos] = interleave2_32to64((int)xVal); -// } -// } + public LongArray modSquareN(int n, int m, int[] ks) + { + int len = getUsedLength(); + if (len == 0) + { + return this; + } + + int mLen = (m + 63) >>> 6; + long[] r = new long[mLen << 1]; + System.arraycopy(m_ints, 0, r, 0, len); + + while (--n >= 0) + { + squareInPlace(r, len, m, ks); + len = reduceInPlace(r, 0, r.length, m, ks); + } + + return new LongArray(r, 0, len); + } + + public LongArray square(int m, int[] ks) + { + int len = getUsedLength(); + if (len == 0) + { + return this; + } + + int _2len = len << 1; + long[] r = new long[_2len]; + + int pos = 0; + while (pos < _2len) + { + long mi = m_ints[pos >>> 1]; + r[pos++] = interleave2_32to64((int)mi); + r[pos++] = interleave2_32to64((int)(mi >>> 32)); + } + + return new LongArray(r, 0, r.length); + } + + private static void squareInPlace(long[] x, int xLen, int m, int[] ks) + { + int pos = xLen << 1; + while (--xLen >= 0) + { + long xVal = x[xLen]; + x[--pos] = interleave2_32to64((int)(xVal >>> 32)); + x[--pos] = interleave2_32to64((int)xVal); + } + } private static void interleave(long[] x, int xOff, long[] z, int zOff, int count, int width) { @@ -1856,6 +2052,10 @@ class LongArray * Output: a(z)^(-1) mod f(z) */ int uzDegree = degree(); + if (uzDegree == 0) + { + throw new IllegalStateException(); + } if (uzDegree == 1) { return this; diff --git a/core/src/main/java/org/bouncycastle/math/raw/Mod.java b/core/src/main/java/org/bouncycastle/math/raw/Mod.java index 1bc7d3f7..47e6d8c6 100644 --- a/core/src/main/java/org/bouncycastle/math/raw/Mod.java +++ b/core/src/main/java/org/bouncycastle/math/raw/Mod.java @@ -101,9 +101,10 @@ public abstract class Mod do { - byte[] bytes = new byte[len << 2]; - rand.nextBytes(bytes); - Pack.bigEndianToInt(bytes, 0, s); + for (int i = 0; i != len; i++) + { + s[i] = rand.nextInt(); + } s[len - 1] &= m; } while (Nat.gte(len, s, p)); diff --git a/core/src/test/java/org/bouncycastle/crypto/test/AESWrapPadTest.java b/core/src/test/java/org/bouncycastle/crypto/test/AESWrapPadTest.java index 3b02f4aa..fcf5979f 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/AESWrapPadTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/AESWrapPadTest.java @@ -123,7 +123,7 @@ public class AESWrapPadTest for (int i = 0; i < numOfRandomIterations; i++) { int kekLength = 128; - boolean shouldIncrease = rnd.nextBoolean(); + boolean shouldIncrease = (rnd.nextInt() & 0x01) != 0; if (shouldIncrease) { kekLength = 256; diff --git a/core/src/test/java/org/bouncycastle/crypto/test/DigestTest.java b/core/src/test/java/org/bouncycastle/crypto/test/DigestTest.java index b25e2d82..db9b490e 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/DigestTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/DigestTest.java @@ -182,7 +182,7 @@ public abstract class DigestTest protected Digest cloneDigest(byte[] encodedState) { - throw new UnsupportedOperationException(); + throw new IllegalStateException("Unsupported"); } // diff --git a/docs/releasenotes.html b/docs/releasenotes.html index 40a928c7..58ee3900 100644 --- a/docs/releasenotes.html +++ b/docs/releasenotes.html @@ -32,6 +32,7 @@ Release 1.51 <li>The JCE provider will now produce simple RSAPrivateKey objects where CRT coefficients are not provided.</li> <li>PGP key signature certifications did not support DIRECT KEY signatures. This has been fixed.</li> <li>User Attribute subpackets in PGP with long length encodings could result in certification verification failing. This has been fixed.</li> +<li>Calls to CommandMap.setDefaultCommandMap() in the SMIME API are now wrapped in doPrivileged() blocks to allow them to work with a security manager.</li> <li>The encoding of the certificate_authorities field of a TLS CertificateRequest has been fixed.</li> </ul> <h3>2.1.3 Additional Features and Functionality</h3> diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/attachonly.eml b/mail/src/test/resources/org/bouncycastle/mail/smime/test/attachonly.eml index 9ce23f79..9ce23f79 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/attachonly.eml +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/attachonly.eml diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/basicAS2.message b/mail/src/test/resources/org/bouncycastle/mail/smime/test/basicAS2.message Binary files differindex b4e52c84..b4e52c84 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/basicAS2.message +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/basicAS2.message diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/brokenEnv.message b/mail/src/test/resources/org/bouncycastle/mail/smime/test/brokenEnv.message index ccf73068..ccf73068 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/brokenEnv.message +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/brokenEnv.message diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/cert.pem b/mail/src/test/resources/org/bouncycastle/mail/smime/test/cert.pem index 13d908ba..13d908ba 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/cert.pem +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/cert.pem diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/certpath_end1.crt b/mail/src/test/resources/org/bouncycastle/mail/smime/test/certpath_end1.crt index ffa77bc6..ffa77bc6 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/certpath_end1.crt +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/certpath_end1.crt diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/certpath_end2.crt b/mail/src/test/resources/org/bouncycastle/mail/smime/test/certpath_end2.crt index 2689c937..2689c937 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/certpath_end2.crt +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/certpath_end2.crt diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/certpath_inter1.crt b/mail/src/test/resources/org/bouncycastle/mail/smime/test/certpath_inter1.crt index a17b2fc3..a17b2fc3 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/certpath_inter1.crt +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/certpath_inter1.crt diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/certpath_inter2.crt b/mail/src/test/resources/org/bouncycastle/mail/smime/test/certpath_inter2.crt index 3ed78e1b..3ed78e1b 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/certpath_inter2.crt +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/certpath_inter2.crt diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/certpath_root.crt b/mail/src/test/resources/org/bouncycastle/mail/smime/test/certpath_root.crt index 7b70b1a5..7b70b1a5 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/certpath_root.crt +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/certpath_root.crt diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/circular.eml b/mail/src/test/resources/org/bouncycastle/mail/smime/test/circular.eml index 4820fbe1..4820fbe1 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/circular.eml +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/circular.eml diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/dotnet_enc_cert.pem b/mail/src/test/resources/org/bouncycastle/mail/smime/test/dotnet_enc_cert.pem index c84b1926..c84b1926 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/dotnet_enc_cert.pem +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/dotnet_enc_cert.pem diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/dotnet_encrypted_mail.eml b/mail/src/test/resources/org/bouncycastle/mail/smime/test/dotnet_encrypted_mail.eml index 085e9d14..085e9d14 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/dotnet_encrypted_mail.eml +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/dotnet_encrypted_mail.eml diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/embeddedmulti.message b/mail/src/test/resources/org/bouncycastle/mail/smime/test/embeddedmulti.message index d5513a6f..d5513a6f 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/embeddedmulti.message +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/embeddedmulti.message diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/extra-nl.eml b/mail/src/test/resources/org/bouncycastle/mail/smime/test/extra-nl.eml index 69c92df4..69c92df4 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/extra-nl.eml +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/extra-nl.eml diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/johndoe.p12 b/mail/src/test/resources/org/bouncycastle/mail/smime/test/johndoe.p12 Binary files differindex ae23f92e..ae23f92e 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/johndoe.p12 +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/johndoe.p12 diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/key.pem b/mail/src/test/resources/org/bouncycastle/mail/smime/test/key.pem index 274f4c55..274f4c55 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/key.pem +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/key.pem diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/multi-alternative.eml b/mail/src/test/resources/org/bouncycastle/mail/smime/test/multi-alternative.eml index b60a7aba..b60a7aba 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/multi-alternative.eml +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/multi-alternative.eml diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/outlook_2010_beta_sime_msg.eml b/mail/src/test/resources/org/bouncycastle/mail/smime/test/outlook_2010_beta_sime_msg.eml index 3de619b7..3de619b7 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/outlook_2010_beta_sime_msg.eml +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/outlook_2010_beta_sime_msg.eml diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/qp-soft-break.eml b/mail/src/test/resources/org/bouncycastle/mail/smime/test/qp-soft-break.eml index d0e0a939..d0e0a939 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/qp-soft-break.eml +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/qp-soft-break.eml diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/quotable.message b/mail/src/test/resources/org/bouncycastle/mail/smime/test/quotable.message index 6c3d6ac4..6c3d6ac4 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/quotable.message +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/quotable.message diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/rawAS2.message b/mail/src/test/resources/org/bouncycastle/mail/smime/test/rawAS2.message Binary files differindex a7528332..a7528332 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/rawAS2.message +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/rawAS2.message diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/test128.message b/mail/src/test/resources/org/bouncycastle/mail/smime/test/test128.message index b08afe0b..b08afe0b 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/test128.message +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/test128.message diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/test192.message b/mail/src/test/resources/org/bouncycastle/mail/smime/test/test192.message index c2b215f9..c2b215f9 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/test192.message +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/test192.message diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/test256.message b/mail/src/test/resources/org/bouncycastle/mail/smime/test/test256.message index d08295e3..d08295e3 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/test256.message +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/test256.message diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.expired.eml b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.expired.eml index 7e37267b..7e37267b 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.expired.eml +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.expired.eml diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.extKeyUsage.eml b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.extKeyUsage.eml index 9397f928..9397f928 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.extKeyUsage.eml +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.extKeyUsage.eml diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.fakeRoot.crt b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.fakeRoot.crt index 2605b2d2..2605b2d2 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.fakeRoot.crt +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.fakeRoot.crt diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.keyUsage.eml b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.keyUsage.eml index e9a972d4..e9a972d4 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.keyUsage.eml +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.keyUsage.eml diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.longValidity.eml b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.longValidity.eml index 446da89e..446da89e 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.longValidity.eml +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.longValidity.eml diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.noEmail.eml b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.noEmail.eml index 82f50345..82f50345 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.noEmail.eml +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.noEmail.eml diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.notYetValid.eml b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.notYetValid.eml index c4940496..c4940496 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.notYetValid.eml +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.notYetValid.eml diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.revoked.crl b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.revoked.crl Binary files differindex 0640cf74..0640cf74 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.revoked.crl +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.revoked.crl diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.revoked.eml b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.revoked.eml index ad665dbd..ad665dbd 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.revoked.eml +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.revoked.eml diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.root.crt b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.root.crt index 93576842..93576842 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.root.crt +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.root.crt diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.shortKey.eml b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.shortKey.eml index eeae2d0e..eeae2d0e 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.shortKey.eml +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.shortKey.eml diff --git a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.validMail.eml b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.validMail.eml index 6590e0ef..6590e0ef 100644 --- a/core/src/test/data/org/bouncycastle/mail/smime/test/validator.validMail.eml +++ b/mail/src/test/resources/org/bouncycastle/mail/smime/test/validator.validMail.eml diff --git a/pkix/src/main/j2me/org/bouncycastle/cert/CertUtils.java b/pkix/src/main/j2me/org/bouncycastle/cert/CertUtils.java index b263f237..0a4cb7c1 100644 --- a/pkix/src/main/j2me/org/bouncycastle/cert/CertUtils.java +++ b/pkix/src/main/j2me/org/bouncycastle/cert/CertUtils.java @@ -14,7 +14,7 @@ import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERBitString; -import org.bouncycastle.asn1.DERGeneralizedTime; +import org.bouncycastle.asn1.ASN1GeneralizedTime; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.DERSequence; diff --git a/pkix/src/main/j2me/org/bouncycastle/cert/X509v1CertificateBuilder.java b/pkix/src/main/j2me/org/bouncycastle/cert/X509v1CertificateBuilder.java new file mode 100644 index 00000000..3457e0c3 --- /dev/null +++ b/pkix/src/main/j2me/org/bouncycastle/cert/X509v1CertificateBuilder.java @@ -0,0 +1,83 @@ +package org.bouncycastle.cert; + +import java.math.BigInteger; +import java.util.Date; + +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.ExtensionsGenerator; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.asn1.x509.Time; +import org.bouncycastle.asn1.x509.V1TBSCertificateGenerator; +import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator; +import org.bouncycastle.operator.ContentSigner; + + +/** + * class to produce an X.509 Version 1 certificate. + */ +public class X509v1CertificateBuilder +{ + private V1TBSCertificateGenerator tbsGen; + + /** + * Create a builder for a version 1 certificate. + * + * @param issuer the certificate issuer + * @param serial the certificate serial number + * @param notBefore the date before which the certificate is not valid + * @param notAfter the date after which the certificate is not valid + * @param subject the certificate subject + * @param publicKeyInfo the info structure for the public key to be associated with this certificate. + */ + public X509v1CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, SubjectPublicKeyInfo publicKeyInfo) + { + this(issuer, serial, new Time(notBefore), new Time(notAfter), subject, publicKeyInfo); + } + + /** + * Create a builder for a version 1 certificate. + * + * @param issuer the certificate issuer + * @param serial the certificate serial number + * @param notBefore the Time before which the certificate is not valid + * @param notAfter the Time after which the certificate is not valid + * @param subject the certificate subject + * @param publicKeyInfo the info structure for the public key to be associated with this certificate. + */ + public X509v1CertificateBuilder(X500Name issuer, BigInteger serial, Time notBefore, Time notAfter, X500Name subject, SubjectPublicKeyInfo publicKeyInfo) + { + if (issuer == null) + { + throw new IllegalArgumentException("issuer must not be null"); + } + + if (publicKeyInfo == null) + { + throw new IllegalArgumentException("publicKeyInfo must not be null"); + } + + tbsGen = new V1TBSCertificateGenerator(); + tbsGen.setSerialNumber(new ASN1Integer(serial)); + tbsGen.setIssuer(issuer); + tbsGen.setStartDate(notBefore); + tbsGen.setEndDate(notAfter); + tbsGen.setSubject(subject); + tbsGen.setSubjectPublicKeyInfo(publicKeyInfo); + } + + /** + * Generate an X509 certificate, based on the current issuer and subject + * using the passed in signer. + * + * @param signer the content signer to be used to generate the signature validating the certificate. + * @return a holder containing the resulting signed certificate. + */ + public X509CertificateHolder build( + ContentSigner signer) + { + tbsGen.setSignature(signer.getAlgorithmIdentifier()); + + return CertUtils.generateFullCert(signer, tbsGen.generateTBSCertificate()); + } +} diff --git a/pkix/src/main/j2me/org/bouncycastle/cert/X509v2AttributeCertificateBuilder.java b/pkix/src/main/j2me/org/bouncycastle/cert/X509v2AttributeCertificateBuilder.java new file mode 100644 index 00000000..72efae91 --- /dev/null +++ b/pkix/src/main/j2me/org/bouncycastle/cert/X509v2AttributeCertificateBuilder.java @@ -0,0 +1,138 @@ +package org.bouncycastle.cert; + +import java.math.BigInteger; +import java.util.Date; + +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1GeneralizedTime; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.DERSet; +import org.bouncycastle.asn1.x509.AttCertIssuer; +import org.bouncycastle.asn1.x509.Attribute; +import org.bouncycastle.asn1.x509.ExtensionsGenerator; +import org.bouncycastle.asn1.x509.V2AttributeCertificateInfoGenerator; +import org.bouncycastle.operator.ContentSigner; + +/** + * class to produce an X.509 Version 2 AttributeCertificate. + */ +public class X509v2AttributeCertificateBuilder +{ + private V2AttributeCertificateInfoGenerator acInfoGen; + private ExtensionsGenerator extGenerator; + + /** + * Base constructor. + * + * @param holder holder certificate details + * @param issuer issuer of this attribute certificate. + * @param serialNumber serial number of this attribute certificate. + * @param notBefore the date before which the certificate is not valid. + * @param notAfter the date after which the certificate is not valid. + */ + public X509v2AttributeCertificateBuilder(AttributeCertificateHolder holder, AttributeCertificateIssuer issuer, BigInteger serialNumber, Date notBefore, Date notAfter) + { + acInfoGen = new V2AttributeCertificateInfoGenerator(); + extGenerator = new ExtensionsGenerator(); + + acInfoGen.setHolder(holder.holder); + acInfoGen.setIssuer(AttCertIssuer.getInstance(issuer.form)); + acInfoGen.setSerialNumber(new ASN1Integer(serialNumber)); + acInfoGen.setStartDate(new ASN1GeneralizedTime(notBefore)); + acInfoGen.setEndDate(new ASN1GeneralizedTime(notAfter)); + } + + /** + * Add an attribute to the certification request we are building. + * + * @param attrType the OID giving the type of the attribute. + * @param attrValue the ASN.1 structure that forms the value of the attribute. + * @return this builder object. + */ + public X509v2AttributeCertificateBuilder addAttribute(ASN1ObjectIdentifier attrType, ASN1Encodable attrValue) + { + acInfoGen.addAttribute(new Attribute(attrType, new DERSet(attrValue))); + + return this; + } + + /** + * Add an attribute with multiple values to the certification request we are building. + * + * @param attrType the OID giving the type of the attribute. + * @param attrValues an array of ASN.1 structures that form the value of the attribute. + * @return this builder object. + */ + public X509v2AttributeCertificateBuilder addAttribute(ASN1ObjectIdentifier attrType, ASN1Encodable[] attrValues) + { + acInfoGen.addAttribute(new Attribute(attrType, new DERSet(attrValues))); + + return this; + } + + public void setIssuerUniqueId( + boolean[] iui) + { + acInfoGen.setIssuerUniqueID(CertUtils.booleanToBitString(iui)); + } + + /** + * Add a given extension field for the standard extensions tag + * + * @param oid the OID defining the extension type. + * @param isCritical true if the extension is critical, false otherwise. + * @param value the ASN.1 structure that forms the extension's value. + * @return this builder object. + */ + public X509v2AttributeCertificateBuilder addExtension( + ASN1ObjectIdentifier oid, + boolean isCritical, + ASN1Encodable value) + throws CertIOException + { + CertUtils.addExtension(extGenerator, oid, isCritical, value); + + return this; + } + + /** + * Add a given extension field for the standard extensions tag (tag 3) using a byte encoding of the + * extension value. + * + * @param oid the OID defining the extension type. + * @param isCritical true if the extension is critical, false otherwise. + * @param encodedValue a byte array representing the encoding of the extension value. + * @return this builder object. + */ + public X509v2AttributeCertificateBuilder addExtension( + ASN1ObjectIdentifier oid, + boolean isCritical, + byte[] encodedValue) + throws CertIOException + { + extGenerator.addExtension(oid, isCritical, encodedValue); + + return this; + } + + /** + * Generate an X509 certificate, based on the current issuer and subject + * using the passed in signer. + * + * @param signer the content signer to be used to generate the signature validating the certificate. + * @return a holder containing the resulting signed certificate. + */ + public X509AttributeCertificateHolder build( + ContentSigner signer) + { + acInfoGen.setSignature(signer.getAlgorithmIdentifier()); + + if (!extGenerator.isEmpty()) + { + acInfoGen.setExtensions(extGenerator.generate()); + } + + return CertUtils.generateFullAttrCert(signer, acInfoGen.generateAttributeCertificateInfo()); + } +} diff --git a/pkix/src/main/j2me/org/bouncycastle/cert/X509v2CRLBuilder.java b/pkix/src/main/j2me/org/bouncycastle/cert/X509v2CRLBuilder.java new file mode 100644 index 00000000..6d54f0af --- /dev/null +++ b/pkix/src/main/j2me/org/bouncycastle/cert/X509v2CRLBuilder.java @@ -0,0 +1,231 @@ +package org.bouncycastle.cert; + +import java.math.BigInteger; +import java.util.Date; +import java.util.Enumeration; + +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1GeneralizedTime; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.Extensions; +import org.bouncycastle.asn1.x509.ExtensionsGenerator; +import org.bouncycastle.asn1.x509.TBSCertList; +import org.bouncycastle.asn1.x509.Time; +import org.bouncycastle.asn1.x509.V2TBSCertListGenerator; +import org.bouncycastle.asn1.x509.X509Extensions; +import org.bouncycastle.operator.ContentSigner; + +/** + * class to produce an X.509 Version 2 CRL. + */ +public class X509v2CRLBuilder +{ + private V2TBSCertListGenerator tbsGen; + private ExtensionsGenerator extGenerator; + + /** + * Basic constructor. + * + * @param issuer the issuer this CRL is associated with. + * @param thisUpdate the date of this update. + */ + public X509v2CRLBuilder( + X500Name issuer, + Date thisUpdate) + { + tbsGen = new V2TBSCertListGenerator(); + extGenerator = new ExtensionsGenerator(); + + tbsGen.setIssuer(issuer); + tbsGen.setThisUpdate(new Time(thisUpdate)); + } + + /** + * Basic constructor. + * + * @param issuer the issuer this CRL is associated with. + * @param thisUpdate the Time of this update. + */ + public X509v2CRLBuilder( + X500Name issuer, + Time thisUpdate) + { + tbsGen = new V2TBSCertListGenerator(); + extGenerator = new ExtensionsGenerator(); + + tbsGen.setIssuer(issuer); + tbsGen.setThisUpdate(thisUpdate); + } + + /** + * Set the date by which the next CRL will become available. + * + * @param date date of next CRL update. + * @return the current builder. + */ + public X509v2CRLBuilder setNextUpdate( + Date date) + { + return this.setNextUpdate(new Time(date)); + } + + /** + * Set the date by which the next CRL will become available. + * + * @param date date of next CRL update. + * @return the current builder. + */ + public X509v2CRLBuilder setNextUpdate( + Time date) + { + tbsGen.setNextUpdate(date); + + return this; + } + + /** + * Add a CRL entry with the just reasonCode extension. + * + * @param userCertificateSerial serial number of revoked certificate. + * @param revocationDate date of certificate revocation. + * @param reason the reason code, as indicated in CRLReason, i.e CRLReason.keyCompromise, or 0 if not to be used. + * @return the current builder. + */ + public X509v2CRLBuilder addCRLEntry(BigInteger userCertificateSerial, Date revocationDate, int reason) + { + tbsGen.addCRLEntry(new ASN1Integer(userCertificateSerial), new Time(revocationDate), reason); + + return this; + } + + /** + * Add a CRL entry with an invalidityDate extension as well as a reasonCode extension. This is used + * where the date of revocation might be after issues with the certificate may have occurred. + * + * @param userCertificateSerial serial number of revoked certificate. + * @param revocationDate date of certificate revocation. + * @param reason the reason code, as indicated in CRLReason, i.e CRLReason.keyCompromise, or 0 if not to be used. + * @param invalidityDate the date on which the private key for the certificate became compromised or the certificate otherwise became invalid. + * @return the current builder. + */ + public X509v2CRLBuilder addCRLEntry(BigInteger userCertificateSerial, Date revocationDate, int reason, Date invalidityDate) + { + tbsGen.addCRLEntry(new ASN1Integer(userCertificateSerial), new Time(revocationDate), reason, new ASN1GeneralizedTime(invalidityDate)); + + return this; + } + + /** + * Add a CRL entry with extensions. + * + * @param userCertificateSerial serial number of revoked certificate. + * @param revocationDate date of certificate revocation. + * @param extensions extension set to be associated with this CRLEntry. + * @return the current builder. + * @deprecated use method taking Extensions + */ + public X509v2CRLBuilder addCRLEntry(BigInteger userCertificateSerial, Date revocationDate, X509Extensions extensions) + { + tbsGen.addCRLEntry(new ASN1Integer(userCertificateSerial), new Time(revocationDate), Extensions.getInstance(extensions)); + + return this; + } + + /** + * Add a CRL entry with extensions. + * + * @param userCertificateSerial serial number of revoked certificate. + * @param revocationDate date of certificate revocation. + * @param extensions extension set to be associated with this CRLEntry. + * @return the current builder. + */ + public X509v2CRLBuilder addCRLEntry(BigInteger userCertificateSerial, Date revocationDate, Extensions extensions) + { + tbsGen.addCRLEntry(new ASN1Integer(userCertificateSerial), new Time(revocationDate), extensions); + + return this; + } + + /** + * Add the CRLEntry objects contained in a previous CRL. + * + * @param other the X509CRLHolder to source the other entries from. + * @return the current builder. + */ + public X509v2CRLBuilder addCRL(X509CRLHolder other) + { + TBSCertList revocations = other.toASN1Structure().getTBSCertList(); + + if (revocations != null) + { + for (Enumeration en = revocations.getRevokedCertificateEnumeration(); en.hasMoreElements();) + { + tbsGen.addCRLEntry(ASN1Sequence.getInstance(((ASN1Encodable)en.nextElement()).toASN1Primitive())); + } + } + + return this; + } + + /** + * Add a given extension field for the standard extensions tag (tag 3) + * + * @param oid the OID defining the extension type. + * @param isCritical true if the extension is critical, false otherwise. + * @param value the ASN.1 structure that forms the extension's value. + * @return this builder object. + */ + public X509v2CRLBuilder addExtension( + ASN1ObjectIdentifier oid, + boolean isCritical, + ASN1Encodable value) + throws CertIOException + { + CertUtils.addExtension(extGenerator, oid, isCritical, value); + + return this; + } + + /** + * Add a given extension field for the standard extensions tag (tag 3) using a byte encoding of the + * extension value. + * + * @param oid the OID defining the extension type. + * @param isCritical true if the extension is critical, false otherwise. + * @param encodedValue a byte array representing the encoding of the extension value. + * @return this builder object. + */ + public X509v2CRLBuilder addExtension( + ASN1ObjectIdentifier oid, + boolean isCritical, + byte[] encodedValue) + throws CertIOException + { + extGenerator.addExtension(oid, isCritical, encodedValue); + + return this; + } + + /** + * Generate an X.509 CRL, based on the current issuer and subject + * using the passed in signer. + * + * @param signer the content signer to be used to generate the signature validating the certificate. + * @return a holder containing the resulting signed certificate. + */ + public X509CRLHolder build( + ContentSigner signer) + { + tbsGen.setSignature(signer.getAlgorithmIdentifier()); + + if (!extGenerator.isEmpty()) + { + tbsGen.setExtensions(extGenerator.generate()); + } + + return CertUtils.generateFullCRL(signer, tbsGen.generateTBSCertList()); + } +} diff --git a/pkix/src/main/j2me/org/bouncycastle/cert/X509v3CertificateBuilder.java b/pkix/src/main/j2me/org/bouncycastle/cert/X509v3CertificateBuilder.java new file mode 100644 index 00000000..48e08c19 --- /dev/null +++ b/pkix/src/main/j2me/org/bouncycastle/cert/X509v3CertificateBuilder.java @@ -0,0 +1,177 @@ +package org.bouncycastle.cert; + +import java.math.BigInteger; +import java.util.Date; + +import org.bouncycastle.asn1.ASN1Encodable; +import org.bouncycastle.asn1.ASN1Integer; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.Certificate; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.ExtensionsGenerator; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.asn1.x509.Time; +import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator; +import org.bouncycastle.operator.ContentSigner; + + +/** + * class to produce an X.509 Version 3 certificate. + */ +public class X509v3CertificateBuilder +{ + private V3TBSCertificateGenerator tbsGen; + private ExtensionsGenerator extGenerator; + + /** + * Create a builder for a version 3 certificate. + * + * @param issuer the certificate issuer + * @param serial the certificate serial number + * @param notBefore the date before which the certificate is not valid + * @param notAfter the date after which the certificate is not valid + * @param subject the certificate subject + * @param publicKeyInfo the info structure for the public key to be associated with this certificate. + */ + public X509v3CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, SubjectPublicKeyInfo publicKeyInfo) + { + this(issuer, serial, new Time(notBefore), new Time(notAfter), subject, publicKeyInfo); + } + + /** + * Create a builder for a version 3 certificate. + * + * @param issuer the certificate issuer + * @param serial the certificate serial number + * @param notBefore the Time before which the certificate is not valid + * @param notAfter the Time after which the certificate is not valid + * @param subject the certificate subject + * @param publicKeyInfo the info structure for the public key to be associated with this certificate. + */ + public X509v3CertificateBuilder(X500Name issuer, BigInteger serial, Time notBefore, Time notAfter, X500Name subject, SubjectPublicKeyInfo publicKeyInfo) + { + tbsGen = new V3TBSCertificateGenerator(); + tbsGen.setSerialNumber(new ASN1Integer(serial)); + tbsGen.setIssuer(issuer); + tbsGen.setStartDate(notBefore); + tbsGen.setEndDate(notAfter); + tbsGen.setSubject(subject); + tbsGen.setSubjectPublicKeyInfo(publicKeyInfo); + + extGenerator = new ExtensionsGenerator(); + } + + /** + * Set the subjectUniqueID - note: it is very rare that it is correct to do this. + * + * @param uniqueID a boolean array representing the bits making up the subjectUniqueID. + * @return this builder object. + */ + public X509v3CertificateBuilder setSubjectUniqueID(boolean[] uniqueID) + { + tbsGen.setSubjectUniqueID(CertUtils.booleanToBitString(uniqueID)); + + return this; + } + + /** + * Set the issuerUniqueID - note: it is very rare that it is correct to do this. + * + * @param uniqueID a boolean array representing the bits making up the issuerUniqueID. + * @return this builder object. + */ + public X509v3CertificateBuilder setIssuerUniqueID(boolean[] uniqueID) + { + tbsGen.setIssuerUniqueID(CertUtils.booleanToBitString(uniqueID)); + + return this; + } + + /** + * Add a given extension field for the standard extensions tag (tag 3) + * + * @param oid the OID defining the extension type. + * @param isCritical true if the extension is critical, false otherwise. + * @param value the ASN.1 structure that forms the extension's value. + * @return this builder object. + */ + public X509v3CertificateBuilder addExtension( + ASN1ObjectIdentifier oid, + boolean isCritical, + ASN1Encodable value) + throws CertIOException + { + CertUtils.addExtension(extGenerator, oid, isCritical, value); + + return this; + } + + /** + * Add a given extension field for the standard extensions tag (tag 3) using a byte encoding of the + * extension value. + * + * @param oid the OID defining the extension type. + * @param isCritical true if the extension is critical, false otherwise. + * @param encodedValue a byte array representing the encoding of the extension value. + * @return this builder object. + */ + public X509v3CertificateBuilder addExtension( + ASN1ObjectIdentifier oid, + boolean isCritical, + byte[] encodedValue) + throws CertIOException + { + extGenerator.addExtension(oid, isCritical, encodedValue); + + return this; + } + + /** + * Add a given extension field for the standard extensions tag (tag 3) + * copying the extension value from another certificate. + * + * @param oid the OID defining the extension type. + * @param isCritical true if the copied extension is to be marked as critical, false otherwise. + * @param certHolder the holder for the certificate that the extension is to be copied from. + * @return this builder object. + */ + public X509v3CertificateBuilder copyAndAddExtension( + ASN1ObjectIdentifier oid, + boolean isCritical, + X509CertificateHolder certHolder) + { + Certificate cert = certHolder.toASN1Structure(); + + Extension extension = cert.getTBSCertificate().getExtensions().getExtension(oid); + + if (extension == null) + { + throw new NullPointerException("extension " + oid + " not present"); + } + + extGenerator.addExtension(oid, isCritical, extension.getExtnValue().getOctets()); + + return this; + } + + /** + * Generate an X.509 certificate, based on the current issuer and subject + * using the passed in signer. + * + * @param signer the content signer to be used to generate the signature validating the certificate. + * @return a holder containing the resulting signed certificate. + */ + public X509CertificateHolder build( + ContentSigner signer) + { + tbsGen.setSignature(signer.getAlgorithmIdentifier()); + + if (!extGenerator.isEmpty()) + { + tbsGen.setExtensions(extGenerator.generate()); + } + + return CertUtils.generateFullCert(signer, tbsGen.generateTBSCertificate()); + } +} diff --git a/pkix/src/main/java/org/bouncycastle/cert/X509v1CertificateBuilder.java b/pkix/src/main/java/org/bouncycastle/cert/X509v1CertificateBuilder.java index 4a4e150f..3652ba9e 100644 --- a/pkix/src/main/java/org/bouncycastle/cert/X509v1CertificateBuilder.java +++ b/pkix/src/main/java/org/bouncycastle/cert/X509v1CertificateBuilder.java @@ -2,12 +2,15 @@ package org.bouncycastle.cert; import java.math.BigInteger; import java.util.Date; +import java.util.Locale; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.Time; import org.bouncycastle.asn1.x509.V1TBSCertificateGenerator; +import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator; import org.bouncycastle.operator.ContentSigner; @@ -30,24 +33,56 @@ public class X509v1CertificateBuilder */ public X509v1CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, SubjectPublicKeyInfo publicKeyInfo) { - if (issuer == null) - { - throw new IllegalArgumentException("issuer must not be null"); - } + this(issuer, serial, new Time(notBefore), new Time(notAfter), subject, publicKeyInfo); + } - if (publicKeyInfo == null) - { - throw new IllegalArgumentException("publicKeyInfo must not be null"); - } + /** + * Create a builder for a version 1 certificate. You may need to use this constructor if the default locale + * doesn't use a Gregorian calender so that the Time produced is compatible with other ASN.1 implementations. + * + * @param issuer the certificate issuer + * @param serial the certificate serial number + * @param notBefore the date before which the certificate is not valid + * @param notAfter the date after which the certificate is not valid + * @param dateLocale locale to be used for date interpretation. + * @param subject the certificate subject + * @param publicKeyInfo the info structure for the public key to be associated with this certificate. + */ + public X509v1CertificateBuilder(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, Locale dateLocale, X500Name subject, SubjectPublicKeyInfo publicKeyInfo) + { + this(issuer, serial, new Time(notBefore, dateLocale), new Time(notAfter, dateLocale), subject, publicKeyInfo); + } - tbsGen = new V1TBSCertificateGenerator(); - tbsGen.setSerialNumber(new ASN1Integer(serial)); - tbsGen.setIssuer(issuer); - tbsGen.setStartDate(new Time(notBefore)); - tbsGen.setEndDate(new Time(notAfter)); - tbsGen.setSubject(subject); - tbsGen.setSubjectPublicKeyInfo(publicKeyInfo); - } + /** + * Create a builder for a version 1 certificate. + * + * @param issuer the certificate issuer + * @param serial the certificate serial number + * @param notBefore the Time before which the certificate is not valid + * @param notAfter the Time after which the certificate is not valid + * @param subject the certificate subject + * @param publicKeyInfo the info structure for the public key to be associated with this certificate. + */ + public X509v1CertificateBuilder(X500Name issuer, BigInteger serial, Time notBefore, Time notAfter, X500Name subject, SubjectPublicKeyInfo publicKeyInfo) + { + if (issuer == null) + { + throw new IllegalArgumentException("issuer must not be null"); + } + + if (publicKeyInfo == null) + { + throw new IllegalArgumentException("publicKeyInfo must not be null"); + } + + tbsGen = new V1TBSCertificateGenerator(); + tbsGen.setSerialNumber(new ASN1Integer(serial)); + tbsGen.setIssuer(issuer); + tbsGen.setStartDate(notBefore); + tbsGen.setEndDate(notAfter); + tbsGen.setSubject(subject); + tbsGen.setSubjectPublicKeyInfo(publicKeyInfo); + } /** * Generate an X509 certificate, based on the current issuer and subject diff --git a/pkix/src/main/java/org/bouncycastle/cms/DefaultAuthenticatedAttributeTableGenerator.java b/pkix/src/main/java/org/bouncycastle/cms/DefaultAuthenticatedAttributeTableGenerator.java index 66b61d12..fb37b4d8 100644 --- a/pkix/src/main/java/org/bouncycastle/cms/DefaultAuthenticatedAttributeTableGenerator.java +++ b/pkix/src/main/java/org/bouncycastle/cms/DefaultAuthenticatedAttributeTableGenerator.java @@ -1,5 +1,6 @@ package org.bouncycastle.cms; +import java.util.Enumeration; import java.util.Hashtable; import java.util.Map; @@ -57,7 +58,14 @@ public class DefaultAuthenticatedAttributeTableGenerator protected Hashtable createStandardAttributeTable( Map parameters) { - Hashtable std = (Hashtable)table.clone(); + Hashtable std = new Hashtable(); + + for (Enumeration en = table.keys(); en.hasMoreElements();) + { + Object key = en.nextElement(); + + std.put(key, table.get(key)); + } if (!std.containsKey(CMSAttributes.contentType)) { |