diff --git a/.gitignore b/.gitignore index f0ea68e..cdfe663 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ .vs build/ .gradle/ +.idea/ # Binary files *.jar diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..9fd5355 --- /dev/null +++ b/build.gradle @@ -0,0 +1,38 @@ +apply plugin: 'java' +apply plugin: 'groovy' + +repositories { + mavenCentral() +} + +jar { + archiveBaseName = 'itext' + archiveVersion = '2.1.7.1-pf' +} + +// tag::dependencies[] +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +dependencies { + implementation group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.69' + implementation group: 'org.bouncycastle', name: 'bcpkix-jdk15on', version: '1.69' + implementation group: 'org.bouncycastle', name: 'bcmail-jdk15on', version: '1.69' + + testImplementation "org.codehaus.groovy:groovy:3.0.8" + testImplementation platform(group: 'org.spockframework', name: 'spock-bom', version: '2.0-groovy-3.0') + testImplementation group: 'org.spockframework', name: 'spock-core' + testImplementation group: 'org.spockframework', name: 'spock-junit4' + + // optional dependencies for using Spock + testImplementation "org.hamcrest:hamcrest-core:2.2" // only necessary if Hamcrest matchers are used + testRuntimeOnly "net.bytebuddy:byte-buddy:1.11.0" // allows mocking of classes (in addition to interfaces) + testRuntimeOnly "org.objenesis:objenesis:3.2" // allows mocking of classes without default constructor (together with ByteBuddy or CGLIB) +} + +test { + useJUnitPlatform() + testLogging { + events "passed", "skipped", "failed" + } +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..e708b1c Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..4d9ca16 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..4f906e0 --- /dev/null +++ b/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/main/java/com/lowagie/text/pdf/OcspClientBouncyCastle.java b/src/main/java/com/lowagie/text/pdf/OcspClientBouncyCastle.java index 982d708..d844940 100644 --- a/src/main/java/com/lowagie/text/pdf/OcspClientBouncyCastle.java +++ b/src/main/java/com/lowagie/text/pdf/OcspClientBouncyCastle.java @@ -59,20 +59,26 @@ import java.net.HttpURLConnection; import java.net.URL; import java.security.Security; +import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import java.util.Vector; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; +import org.bouncycastle.asn1.x509.Extensions; import org.bouncycastle.asn1.x509.X509Extension; import org.bouncycastle.asn1.x509.X509Extensions; -import org.bouncycastle.ocsp.BasicOCSPResp; -import org.bouncycastle.ocsp.CertificateID; -import org.bouncycastle.ocsp.CertificateStatus; -import org.bouncycastle.ocsp.OCSPException; -import org.bouncycastle.ocsp.OCSPReq; -import org.bouncycastle.ocsp.OCSPReqGenerator; -import org.bouncycastle.ocsp.OCSPResp; -import org.bouncycastle.ocsp.SingleResp; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.ocsp.BasicOCSPResp; +import org.bouncycastle.cert.ocsp.CertificateID; +import org.bouncycastle.cert.ocsp.CertificateStatus; +import org.bouncycastle.cert.ocsp.OCSPException; +import org.bouncycastle.cert.ocsp.OCSPReq; +import org.bouncycastle.cert.ocsp.OCSPReqBuilder; +import org.bouncycastle.cert.ocsp.OCSPResp; +import org.bouncycastle.cert.ocsp.SingleResp; +import org.bouncycastle.operator.DigestCalculatorProvider; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; /** * OcspClient implementation using BouncyCastle. @@ -112,10 +118,21 @@ private static OCSPReq generateOCSPRequest(X509Certificate issuerCert, BigIntege Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); // Generate the id for the certificate we are looking for - CertificateID id = new CertificateID(CertificateID.HASH_SHA1, issuerCert, serialNumber); - + + CertificateID id = null; + try { + DigestCalculatorProvider dcp = new JcaDigestCalculatorProviderBuilder().setProvider("BC").build(); + id = new CertificateID(dcp.get(CertificateID.HASH_SHA1), + new X509CertificateHolder(issuerCert.getEncoded()), + serialNumber); + } catch (CertificateEncodingException e) { + e.printStackTrace(); + } catch (OperatorCreationException e) { + e.printStackTrace(); + } + // basic request generation with nonce - OCSPReqGenerator gen = new OCSPReqGenerator(); + OCSPReqBuilder gen = new OCSPReqBuilder(); gen.addRequest(id); @@ -126,9 +143,9 @@ private static OCSPReq generateOCSPRequest(X509Certificate issuerCert, BigIntege oids.add(OCSPObjectIdentifiers.id_pkix_ocsp_nonce); values.add(new X509Extension(false, new DEROctetString(new DEROctetString(PdfEncryption.createDocumentId()).getEncoded()))); - gen.setRequestExtensions(new X509Extensions(oids, values)); + gen.setRequestExtensions(Extensions.getInstance(new X509Extensions(oids, values))); - return gen.generate(); + return gen.build(); } /** @@ -167,7 +184,7 @@ public byte[] getEncoded() { if (status == CertificateStatus.GOOD) { return basicResponse.getEncoded(); } - else if (status instanceof org.bouncycastle.ocsp.RevokedStatus) { + else if (status instanceof org.bouncycastle.cert.ocsp.RevokedStatus) { throw new IOException("OCSP Status is revoked!"); } else { diff --git a/src/main/java/com/lowagie/text/pdf/PdfPKCS7.java b/src/main/java/com/lowagie/text/pdf/PdfPKCS7.java index 8ccc73e..9ef8d6f 100644 --- a/src/main/java/com/lowagie/text/pdf/PdfPKCS7.java +++ b/src/main/java/com/lowagie/text/pdf/PdfPKCS7.java @@ -75,29 +75,31 @@ import java.util.Iterator; import java.util.Set; -import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1InputStream; import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.ASN1TaggedObject; -import org.bouncycastle.asn1.DEREnumerated; -import org.bouncycastle.asn1.DERInteger; +import org.bouncycastle.asn1.ASN1Enumerated; +import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.DERNull; -import org.bouncycastle.asn1.DERObject; -import org.bouncycastle.asn1.DERObjectIdentifier; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.DEROutputStream; +import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; -import org.bouncycastle.asn1.DERString; +import org.bouncycastle.asn1.ASN1String; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DERUTCTime; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.ocsp.BasicOCSPResponse; import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cms.SignerInformationVerifier; +import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; import org.bouncycastle.jce.provider.X509CRLParser; import org.bouncycastle.jce.provider.X509CertParser; import com.lowagie.text.ExceptionConverter; @@ -108,9 +110,12 @@ import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.tsp.MessageImprint; import org.bouncycastle.asn1.x509.X509Extensions; -import org.bouncycastle.ocsp.BasicOCSPResp; -import org.bouncycastle.ocsp.CertificateID; -import org.bouncycastle.ocsp.SingleResp; +import org.bouncycastle.cert.ocsp.BasicOCSPResp; +import org.bouncycastle.cert.ocsp.CertificateID; +import org.bouncycastle.cert.ocsp.SingleResp; +import org.bouncycastle.operator.DigestCalculatorProvider; +import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder; +import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; import org.bouncycastle.tsp.TimeStampToken; /** @@ -334,8 +339,8 @@ private void findOcsp(ASN1Sequence seq) throws IOException { basicResp = null; boolean ret = false; while (true) { - if ((seq.getObjectAt(0) instanceof DERObjectIdentifier) - && ((DERObjectIdentifier)seq.getObjectAt(0)).getId().equals(OCSPObjectIdentifiers.id_pkix_ocsp_basic.getId())) { + if ((seq.getObjectAt(0) instanceof ASN1ObjectIdentifier) + && ((ASN1ObjectIdentifier)seq.getObjectAt(0)).getId().equals(OCSPObjectIdentifiers.id_pkix_ocsp_basic.getId())) { break; } ret = true; @@ -379,7 +384,7 @@ public PdfPKCS7(byte[] contentsKey, String provider) { // // Basic checks to make sure it's a PKCS#7 SignedData Object // - DERObject pkcs; + ASN1Object pkcs; try { pkcs = din.readObject(); @@ -391,7 +396,7 @@ public PdfPKCS7(byte[] contentsKey, String provider) { throw new IllegalArgumentException("Not a valid PKCS#7 object - not a sequence"); } ASN1Sequence signedData = (ASN1Sequence)pkcs; - DERObjectIdentifier objId = (DERObjectIdentifier)signedData.getObjectAt(0); + ASN1ObjectIdentifier objId = (ASN1ObjectIdentifier)signedData.getObjectAt(0); if (!objId.getId().equals(ID_PKCS7_SIGNED_DATA)) throw new IllegalArgumentException("Not a valid PKCS#7 object - not signed data"); ASN1Sequence content = (ASN1Sequence)((DERTaggedObject)signedData.getObjectAt(1)).getObject(); @@ -403,7 +408,7 @@ public PdfPKCS7(byte[] contentsKey, String provider) { // last - signerInfos // the version - version = ((DERInteger)content.getObjectAt(0)).getValue().intValue(); + version = ((ASN1Integer)content.getObjectAt(0)).getValue().intValue(); // the digestAlgorithms digestalgos = new HashSet(); @@ -411,7 +416,7 @@ public PdfPKCS7(byte[] contentsKey, String provider) { while (e.hasMoreElements()) { ASN1Sequence s = (ASN1Sequence)e.nextElement(); - DERObjectIdentifier o = (DERObjectIdentifier)s.getObjectAt(0); + ASN1ObjectIdentifier o = (ASN1ObjectIdentifier)s.getObjectAt(0); digestalgos.add(o.getId()); } @@ -444,10 +449,10 @@ public PdfPKCS7(byte[] contentsKey, String provider) { // 2 - the digest algorithm // 3 or 4 - digestEncryptionAlgorithm // 4 or 5 - encryptedDigest - signerversion = ((DERInteger)signerInfo.getObjectAt(0)).getValue().intValue(); + signerversion = ((ASN1Integer)signerInfo.getObjectAt(0)).getValue().intValue(); // Get the signing certificate ASN1Sequence issuerAndSerialNumber = (ASN1Sequence)signerInfo.getObjectAt(1); - BigInteger serialNumber = ((DERInteger)issuerAndSerialNumber.getObjectAt(1)).getValue(); + BigInteger serialNumber = ((ASN1Integer)issuerAndSerialNumber.getObjectAt(1)).getValue(); for (Iterator i = certs.iterator(); i.hasNext();) { X509Certificate cert = (X509Certificate)i.next(); if (serialNumber.equals(cert.getSerialNumber())) { @@ -459,20 +464,20 @@ public PdfPKCS7(byte[] contentsKey, String provider) { throw new IllegalArgumentException("Can't find signing certificate with serial " + serialNumber.toString(16)); } signCertificateChain(); - digestAlgorithm = ((DERObjectIdentifier)((ASN1Sequence)signerInfo.getObjectAt(2)).getObjectAt(0)).getId(); + digestAlgorithm = ((ASN1ObjectIdentifier)((ASN1Sequence)signerInfo.getObjectAt(2)).getObjectAt(0)).getId(); next = 3; if (signerInfo.getObjectAt(next) instanceof ASN1TaggedObject) { ASN1TaggedObject tagsig = (ASN1TaggedObject)signerInfo.getObjectAt(next); ASN1Set sseq = ASN1Set.getInstance(tagsig, false); - sigAttr = sseq.getEncoded(ASN1Encodable.DER); + sigAttr = sseq.getEncoded("DER"); for (int k = 0; k < sseq.size(); ++k) { ASN1Sequence seq2 = (ASN1Sequence)sseq.getObjectAt(k); - if (((DERObjectIdentifier)seq2.getObjectAt(0)).getId().equals(ID_MESSAGE_DIGEST)) { + if (((ASN1ObjectIdentifier)seq2.getObjectAt(0)).getId().equals(ID_MESSAGE_DIGEST)) { ASN1Set set = (ASN1Set)seq2.getObjectAt(1); digestAttr = ((DEROctetString)set.getObjectAt(0)).getOctets(); } - else if (((DERObjectIdentifier)seq2.getObjectAt(0)).getId().equals(ID_ADBE_REVOCATION)) { + else if (((ASN1ObjectIdentifier)seq2.getObjectAt(0)).getId().equals(ID_ADBE_REVOCATION)) { ASN1Set setout = (ASN1Set)seq2.getObjectAt(1); ASN1Sequence seqout = (ASN1Sequence)setout.getObjectAt(0); for (int j = 0; j < seqout.size(); ++j) { @@ -488,7 +493,7 @@ else if (((DERObjectIdentifier)seq2.getObjectAt(0)).getId().equals(ID_ADBE_REVOC throw new IllegalArgumentException("Authenticated attribute is missing the digest."); ++next; } - digestEncryptionAlgorithm = ((DERObjectIdentifier)((ASN1Sequence)signerInfo.getObjectAt(next++)).getObjectAt(0)).getId(); + digestEncryptionAlgorithm = ((ASN1ObjectIdentifier)((ASN1Sequence)signerInfo.getObjectAt(next++)).getObjectAt(0)).getId(); digest = ((DEROctetString)signerInfo.getObjectAt(next++)).getOctets(); if (next < signerInfo.size() && (signerInfo.getObjectAt(next) instanceof DERTaggedObject)) { DERTaggedObject taggedObject = (DERTaggedObject) signerInfo.getObjectAt(next); @@ -894,12 +899,14 @@ public static boolean verifyOcspCertificates(BasicOCSPResp ocsp, KeyStore keysto try { for (Enumeration aliases = keystore.aliases(); aliases.hasMoreElements();) { try { - String alias = (String)aliases.nextElement(); + String alias = (String) aliases.nextElement(); if (!keystore.isCertificateEntry(alias)) continue; - X509Certificate certStoreX509 = (X509Certificate)keystore.getCertificate(alias); - if (ocsp.verify(certStoreX509.getPublicKey(), provider)) + X509Certificate certStoreX509 = (X509Certificate) keystore.getCertificate(alias); + if (ocsp.isSignatureValid( + new JcaContentVerifierProviderBuilder().setProvider(provider).build(certStoreX509))) { return true; + } } catch (Exception ex) { } @@ -928,7 +935,9 @@ public static boolean verifyTimestampCertificates(TimeStampToken ts, KeyStore ke if (!keystore.isCertificateEntry(alias)) continue; X509Certificate certStoreX509 = (X509Certificate)keystore.getCertificate(alias); - ts.validate(certStoreX509, provider); + + SignerInformationVerifier verifier = new JcaSimpleSignerInfoVerifierBuilder().setProvider(provider).build(certStoreX509); + ts.validate(verifier); return true; } catch (Exception ex) { @@ -949,7 +958,7 @@ public static boolean verifyTimestampCertificates(TimeStampToken ts, KeyStore ke */ public static String getOCSPURL(X509Certificate certificate) throws CertificateParsingException { try { - DERObject obj = getExtensionValue(certificate, X509Extensions.AuthorityInfoAccess.getId()); + ASN1Object obj = getExtensionValue(certificate, X509Extensions.AuthorityInfoAccess.getId()); if (obj == null) { return null; } @@ -960,8 +969,8 @@ public static String getOCSPURL(X509Certificate certificate) throws CertificateP if ( AccessDescription.size() != 2 ) { continue; } else { - if ((AccessDescription.getObjectAt(0) instanceof DERObjectIdentifier) && ((DERObjectIdentifier)AccessDescription.getObjectAt(0)).getId().equals("1.3.6.1.5.5.7.48.1")) { - String AccessLocation = getStringFromGeneralName((DERObject)AccessDescription.getObjectAt(1)); + if ((AccessDescription.getObjectAt(0) instanceof ASN1ObjectIdentifier) && ((ASN1ObjectIdentifier)AccessDescription.getObjectAt(0)).getId().equals("1.3.6.1.5.5.7.48.1")) { + String AccessLocation = getStringFromGeneralName((ASN1Object)AccessDescription.getObjectAt(1)); if ( AccessLocation == null ) { return "" ; } else { @@ -991,7 +1000,11 @@ public boolean isRevocationValid() { CertificateID cid = sr.getCertID(); X509Certificate sigcer = getSigningCertificate(); X509Certificate isscer = cs[1]; - CertificateID tis = new CertificateID(CertificateID.HASH_SHA1, isscer, sigcer.getSerialNumber()); + + DigestCalculatorProvider dcp = new JcaDigestCalculatorProviderBuilder().setProvider("BC").build(); + CertificateID tis = new CertificateID(dcp.get(CertificateID.HASH_SHA1), + new X509CertificateHolder(isscer.getEncoded()), + sigcer.getSerialNumber()); return tis.equals(cid); } catch (Exception ex) { @@ -999,7 +1012,7 @@ public boolean isRevocationValid() { return false; } - private static DERObject getExtensionValue(X509Certificate cert, String oid) throws IOException { + private static ASN1Object getExtensionValue(X509Certificate cert, String oid) throws IOException { byte[] bytes = cert.getExtensionValue(oid); if (bytes == null) { return null; @@ -1010,7 +1023,7 @@ private static DERObject getExtensionValue(X509Certificate cert, String oid) thr return aIn.readObject(); } - private static String getStringFromGeneralName(DERObject names) throws IOException { + private static String getStringFromGeneralName(ASN1Object names) throws IOException { DERTaggedObject taggedObject = (DERTaggedObject) names ; return new String(ASN1OctetString.getInstance(taggedObject, false).getOctets(), "ISO-8859-1"); } @@ -1020,11 +1033,11 @@ private static String getStringFromGeneralName(DERObject names) throws IOExcepti * @param enc a TBSCertificate in a byte array * @return a DERObject */ - private static DERObject getIssuer(byte[] enc) { + private static ASN1Object getIssuer(byte[] enc) { try { ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream(enc)); ASN1Sequence seq = (ASN1Sequence)in.readObject(); - return (DERObject)seq.getObjectAt(seq.getObjectAt(0) instanceof DERTaggedObject ? 3 : 2); + return (ASN1Object)seq.getObjectAt(seq.getObjectAt(0) instanceof DERTaggedObject ? 3 : 2); } catch (IOException e) { throw new ExceptionConverter(e); @@ -1036,11 +1049,11 @@ private static DERObject getIssuer(byte[] enc) { * @param enc A TBSCertificate in a byte array * @return a DERObject */ - private static DERObject getSubject(byte[] enc) { + private static ASN1Object getSubject(byte[] enc) { try { ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream(enc)); ASN1Sequence seq = (ASN1Sequence)in.readObject(); - return (DERObject)seq.getObjectAt(seq.getObjectAt(0) instanceof DERTaggedObject ? 5 : 4); + return (ASN1Object)seq.getObjectAt(seq.getObjectAt(0) instanceof DERTaggedObject ? 5 : 4); } catch (IOException e) { throw new ExceptionConverter(e); @@ -1174,14 +1187,14 @@ else if (externalRSAdata != null && RSAdata != null) { ASN1EncodableVector digestAlgorithms = new ASN1EncodableVector(); for(Iterator it = digestalgos.iterator(); it.hasNext();) { ASN1EncodableVector algos = new ASN1EncodableVector(); - algos.add(new DERObjectIdentifier((String)it.next())); + algos.add(new ASN1ObjectIdentifier((String)it.next())); algos.add(DERNull.INSTANCE); digestAlgorithms.add(new DERSequence(algos)); } // Create the contentInfo. ASN1EncodableVector v = new ASN1EncodableVector(); - v.add(new DERObjectIdentifier(ID_PKCS7_DATA)); + v.add(new ASN1ObjectIdentifier(ID_PKCS7_DATA)); if (RSAdata != null) v.add(new DERTaggedObject(0, new DEROctetString(RSAdata))); DERSequence contentinfo = new DERSequence(v); @@ -1202,17 +1215,17 @@ else if (externalRSAdata != null && RSAdata != null) { // Add the signerInfo version // - signerinfo.add(new DERInteger(signerversion)); + signerinfo.add(new ASN1Integer(signerversion)); v = new ASN1EncodableVector(); v.add(getIssuer(signCert.getTBSCertificate())); - v.add(new DERInteger(signCert.getSerialNumber())); + v.add(new ASN1Integer(signCert.getSerialNumber())); signerinfo.add(new DERSequence(v)); // Add the digestAlgorithm v = new ASN1EncodableVector(); - v.add(new DERObjectIdentifier(digestAlgorithm)); - v.add(new DERNull()); + v.add(new ASN1ObjectIdentifier(digestAlgorithm)); + v.add(DERNull.INSTANCE); signerinfo.add(new DERSequence(v)); // add the authenticated attribute if present @@ -1221,8 +1234,8 @@ else if (externalRSAdata != null && RSAdata != null) { } // Add the digestEncryptionAlgorithm v = new ASN1EncodableVector(); - v.add(new DERObjectIdentifier(digestEncryptionAlgorithm)); - v.add(new DERNull()); + v.add(new ASN1ObjectIdentifier(digestEncryptionAlgorithm)); + v.add(DERNull.INSTANCE); signerinfo.add(new DERSequence(v)); // Add the digest @@ -1244,7 +1257,7 @@ else if (externalRSAdata != null && RSAdata != null) { // Finally build the body out of all the components above ASN1EncodableVector body = new ASN1EncodableVector(); - body.add(new DERInteger(version)); + body.add(new ASN1Integer(version)); body.add(new DERSet(digestAlgorithms)); body.add(contentinfo); body.add(new DERTaggedObject(false, 0, dercertificates)); @@ -1266,7 +1279,7 @@ else if (externalRSAdata != null && RSAdata != null) { // and return it // ASN1EncodableVector whole = new ASN1EncodableVector(); - whole.add(new DERObjectIdentifier(ID_PKCS7_SIGNED_DATA)); + whole.add(new ASN1ObjectIdentifier(ID_PKCS7_SIGNED_DATA)); whole.add(new DERTaggedObject(0, new DERSequence(body))); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); @@ -1302,7 +1315,7 @@ private ASN1EncodableVector buildUnauthenticatedAttributes(byte[] timeStampToken ASN1EncodableVector unauthAttributes = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(); - v.add(new DERObjectIdentifier(ID_TIME_STAMP_TOKEN)); // id-aa-timeStampToken + v.add(new ASN1ObjectIdentifier(ID_TIME_STAMP_TOKEN)); // id-aa-timeStampToken ASN1Sequence seq = (ASN1Sequence) tempstream.readObject(); v.add(new DERSet(seq)); @@ -1340,7 +1353,7 @@ private ASN1EncodableVector buildUnauthenticatedAttributes(byte[] timeStampToken */ public byte[] getAuthenticatedAttributeBytes(byte secondDigest[], Calendar signingTime, byte[] ocsp) { try { - return getAuthenticatedAttributeSet(secondDigest, signingTime, ocsp).getEncoded(ASN1Encodable.DER); + return getAuthenticatedAttributeSet(secondDigest, signingTime, ocsp).getEncoded("DER"); } catch (Exception e) { throw new ExceptionConverter(e); @@ -1351,26 +1364,26 @@ private DERSet getAuthenticatedAttributeSet(byte secondDigest[], Calendar signin try { ASN1EncodableVector attribute = new ASN1EncodableVector(); ASN1EncodableVector v = new ASN1EncodableVector(); - v.add(new DERObjectIdentifier(ID_CONTENT_TYPE)); - v.add(new DERSet(new DERObjectIdentifier(ID_PKCS7_DATA))); + v.add(new ASN1ObjectIdentifier(ID_CONTENT_TYPE)); + v.add(new DERSet(new ASN1ObjectIdentifier(ID_PKCS7_DATA))); attribute.add(new DERSequence(v)); v = new ASN1EncodableVector(); - v.add(new DERObjectIdentifier(ID_SIGNING_TIME)); + v.add(new ASN1ObjectIdentifier(ID_SIGNING_TIME)); v.add(new DERSet(new DERUTCTime(signingTime.getTime()))); attribute.add(new DERSequence(v)); v = new ASN1EncodableVector(); - v.add(new DERObjectIdentifier(ID_MESSAGE_DIGEST)); + v.add(new ASN1ObjectIdentifier(ID_MESSAGE_DIGEST)); v.add(new DERSet(new DEROctetString(secondDigest))); attribute.add(new DERSequence(v)); if (ocsp != null) { v = new ASN1EncodableVector(); - v.add(new DERObjectIdentifier(ID_ADBE_REVOCATION)); + v.add(new ASN1ObjectIdentifier(ID_ADBE_REVOCATION)); DEROctetString doctet = new DEROctetString(ocsp); ASN1EncodableVector vo1 = new ASN1EncodableVector(); ASN1EncodableVector v2 = new ASN1EncodableVector(); v2.add(OCSPObjectIdentifiers.id_pkix_ocsp_basic); v2.add(doctet); - DEREnumerated den = new DEREnumerated(0); + ASN1Enumerated den = new ASN1Enumerated(0); ASN1EncodableVector v3 = new ASN1EncodableVector(); v3.add(den); v3.add(new DERTaggedObject(true, 0, new DERSequence(v2))); @@ -1380,7 +1393,7 @@ private DERSet getAuthenticatedAttributeSet(byte secondDigest[], Calendar signin } else if (!crls.isEmpty()) { v = new ASN1EncodableVector(); - v.add(new DERObjectIdentifier(ID_ADBE_REVOCATION)); + v.add(new ASN1ObjectIdentifier(ID_ADBE_REVOCATION)); ASN1EncodableVector v2 = new ASN1EncodableVector(); for (Iterator i = crls.iterator();i.hasNext();) { ASN1InputStream t = new ASN1InputStream(new ByteArrayInputStream(((X509CRL)i.next()).getEncoded())); @@ -1467,70 +1480,70 @@ public static class X509Name { /** * country code - StringType(SIZE(2)) */ - public static final DERObjectIdentifier C = new DERObjectIdentifier("2.5.4.6"); + public static final ASN1ObjectIdentifier C = new ASN1ObjectIdentifier("2.5.4.6"); /** * organization - StringType(SIZE(1..64)) */ - public static final DERObjectIdentifier O = new DERObjectIdentifier("2.5.4.10"); + public static final ASN1ObjectIdentifier O = new ASN1ObjectIdentifier("2.5.4.10"); /** * organizational unit name - StringType(SIZE(1..64)) */ - public static final DERObjectIdentifier OU = new DERObjectIdentifier("2.5.4.11"); + public static final ASN1ObjectIdentifier OU = new ASN1ObjectIdentifier("2.5.4.11"); /** * Title */ - public static final DERObjectIdentifier T = new DERObjectIdentifier("2.5.4.12"); + public static final ASN1ObjectIdentifier T = new ASN1ObjectIdentifier("2.5.4.12"); /** * common name - StringType(SIZE(1..64)) */ - public static final DERObjectIdentifier CN = new DERObjectIdentifier("2.5.4.3"); + public static final ASN1ObjectIdentifier CN = new ASN1ObjectIdentifier("2.5.4.3"); /** * device serial number name - StringType(SIZE(1..64)) */ - public static final DERObjectIdentifier SN = new DERObjectIdentifier("2.5.4.5"); + public static final ASN1ObjectIdentifier SN = new ASN1ObjectIdentifier("2.5.4.5"); /** * locality name - StringType(SIZE(1..64)) */ - public static final DERObjectIdentifier L = new DERObjectIdentifier("2.5.4.7"); + public static final ASN1ObjectIdentifier L = new ASN1ObjectIdentifier("2.5.4.7"); /** * state, or province name - StringType(SIZE(1..64)) */ - public static final DERObjectIdentifier ST = new DERObjectIdentifier("2.5.4.8"); + public static final ASN1ObjectIdentifier ST = new ASN1ObjectIdentifier("2.5.4.8"); /** Naming attribute of type X520name */ - public static final DERObjectIdentifier SURNAME = new DERObjectIdentifier("2.5.4.4"); + public static final ASN1ObjectIdentifier SURNAME = new ASN1ObjectIdentifier("2.5.4.4"); /** Naming attribute of type X520name */ - public static final DERObjectIdentifier GIVENNAME = new DERObjectIdentifier("2.5.4.42"); + public static final ASN1ObjectIdentifier GIVENNAME = new ASN1ObjectIdentifier("2.5.4.42"); /** Naming attribute of type X520name */ - public static final DERObjectIdentifier INITIALS = new DERObjectIdentifier("2.5.4.43"); + public static final ASN1ObjectIdentifier INITIALS = new ASN1ObjectIdentifier("2.5.4.43"); /** Naming attribute of type X520name */ - public static final DERObjectIdentifier GENERATION = new DERObjectIdentifier("2.5.4.44"); + public static final ASN1ObjectIdentifier GENERATION = new ASN1ObjectIdentifier("2.5.4.44"); /** Naming attribute of type X520name */ - public static final DERObjectIdentifier UNIQUE_IDENTIFIER = new DERObjectIdentifier("2.5.4.45"); + public static final ASN1ObjectIdentifier UNIQUE_IDENTIFIER = new ASN1ObjectIdentifier("2.5.4.45"); /** * Email address (RSA PKCS#9 extension) - IA5String. *

Note: if you're trying to be ultra orthodox, don't use this! It shouldn't be in here. */ - public static final DERObjectIdentifier EmailAddress = new DERObjectIdentifier("1.2.840.113549.1.9.1"); + public static final ASN1ObjectIdentifier EmailAddress = new ASN1ObjectIdentifier("1.2.840.113549.1.9.1"); /** * email address in Verisign certificates */ - public static final DERObjectIdentifier E = EmailAddress; + public static final ASN1ObjectIdentifier E = EmailAddress; /** object identifier */ - public static final DERObjectIdentifier DC = new DERObjectIdentifier("0.9.2342.19200300.100.1.25"); + public static final ASN1ObjectIdentifier DC = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.25"); /** LDAP User id. */ - public static final DERObjectIdentifier UID = new DERObjectIdentifier("0.9.2342.19200300.100.1.1"); + public static final ASN1ObjectIdentifier UID = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.1"); /** A HashMap with default symbols */ public static HashMap DefaultSymbols = new HashMap(); @@ -1575,7 +1588,7 @@ public X509Name(ASN1Sequence seq) { vs = new ArrayList(); values.put(id, vs); } - vs.add(((DERString)s.getObjectAt(1)).getString()); + vs.add(((ASN1String)s.getObjectAt(1)).getString()); } } } diff --git a/src/main/java/com/lowagie/text/pdf/PdfPublicKeySecurityHandler.java b/src/main/java/com/lowagie/text/pdf/PdfPublicKeySecurityHandler.java index ed30814..b76a4e8 100644 --- a/src/main/java/com/lowagie/text/pdf/PdfPublicKeySecurityHandler.java +++ b/src/main/java/com/lowagie/text/pdf/PdfPublicKeySecurityHandler.java @@ -50,7 +50,7 @@ /** * The below 2 methods are from pdfbox. * - * private DERObject createDERForRecipient(byte[] in, X509Certificate cert) ; + * private ASN1Object createDERForRecipient(byte[] in, X509Certificate cert) ; * private KeyTransRecipientInfo computeRecipientInfo(X509Certificate x509certificate, byte[] abyte0); * * 2006-11-22 Aiken Sam. @@ -108,10 +108,11 @@ import javax.crypto.SecretKey; import org.bouncycastle.asn1.ASN1InputStream; -import org.bouncycastle.asn1.DERObject; -import org.bouncycastle.asn1.DERObjectIdentifier; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Set; import org.bouncycastle.asn1.DEROctetString; -import org.bouncycastle.asn1.DEROutputStream; +import org.bouncycastle.asn1.ASN1OutputStream; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.asn1.cms.EncryptedContentInfo; @@ -244,11 +245,11 @@ public byte[] getEncodedRecipient(int index) throws IOException, GeneralSecurity pkcs7input[22] = two; pkcs7input[23] = one; - DERObject obj = createDERForRecipient(pkcs7input, (X509Certificate)certificate); + ASN1Object obj = createDERForRecipient(pkcs7input, (X509Certificate)certificate); ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DEROutputStream k = new DEROutputStream(baos); + ASN1OutputStream k = new ASN1OutputStream(baos); k.writeObject(obj); @@ -276,7 +277,7 @@ public PdfArray getEncodedRecipients() throws IOException, return EncodedRecipients; } - private DERObject createDERForRecipient(byte[] in, X509Certificate cert) + private ASN1Object createDERForRecipient(byte[] in, X509Certificate cert) throws IOException, GeneralSecurityException { @@ -287,7 +288,7 @@ private DERObject createDERForRecipient(byte[] in, X509Certificate cert) AlgorithmParameters algorithmparameters = algorithmparametergenerator.generateParameters(); ByteArrayInputStream bytearrayinputstream = new ByteArrayInputStream(algorithmparameters.getEncoded("ASN.1")); ASN1InputStream asn1inputstream = new ASN1InputStream(bytearrayinputstream); - DERObject derobject = asn1inputstream.readObject(); + ASN1Object derobject = asn1inputstream.readObject(); KeyGenerator keygenerator = KeyGenerator.getInstance(s); keygenerator.init(128); SecretKey secretkey = keygenerator.generateKey(); @@ -297,13 +298,13 @@ private DERObject createDERForRecipient(byte[] in, X509Certificate cert) DEROctetString deroctetstring = new DEROctetString(abyte1); KeyTransRecipientInfo keytransrecipientinfo = computeRecipientInfo(cert, secretkey.getEncoded()); DERSet derset = new DERSet(new RecipientInfo(keytransrecipientinfo)); - AlgorithmIdentifier algorithmidentifier = new AlgorithmIdentifier(new DERObjectIdentifier(s), derobject); + AlgorithmIdentifier algorithmidentifier = new AlgorithmIdentifier(new ASN1ObjectIdentifier(s), derobject); EncryptedContentInfo encryptedcontentinfo = new EncryptedContentInfo(PKCSObjectIdentifiers.data, algorithmidentifier, deroctetstring); - EnvelopedData env = new EnvelopedData(null, derset, encryptedcontentinfo, null); + EnvelopedData env = new EnvelopedData(null, derset, encryptedcontentinfo, (ASN1Set) null); ContentInfo contentinfo = new ContentInfo(PKCSObjectIdentifiers.envelopedData, env); - return contentinfo.getDERObject(); + return contentinfo.toASN1Primitive(); } private KeyTransRecipientInfo computeRecipientInfo(X509Certificate x509certificate, byte[] abyte0) @@ -318,7 +319,7 @@ private KeyTransRecipientInfo computeRecipientInfo(X509Certificate x509certifica new IssuerAndSerialNumber( tbscertificatestructure.getIssuer(), tbscertificatestructure.getSerialNumber().getValue()); - Cipher cipher = Cipher.getInstance(algorithmidentifier.getObjectId().getId()); + Cipher cipher = Cipher.getInstance(algorithmidentifier.getAlgorithm().getId()); cipher.init(1, x509certificate); DEROctetString deroctetstring = new DEROctetString(cipher.doFinal(abyte0)); RecipientIdentifier recipId = new RecipientIdentifier(issuerandserialnumber); diff --git a/src/main/java/com/lowagie/text/pdf/PdfReader.java b/src/main/java/com/lowagie/text/pdf/PdfReader.java index 8699f22..ce8f8b1 100644 --- a/src/main/java/com/lowagie/text/pdf/PdfReader.java +++ b/src/main/java/com/lowagie/text/pdf/PdfReader.java @@ -55,6 +55,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.security.PrivateKey; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -79,7 +80,9 @@ import com.lowagie.text.pdf.internal.PdfViewerPreferencesImp; import org.bouncycastle.cms.CMSEnvelopedData; -import org.bouncycastle.cms.RecipientInformation; +import org.bouncycastle.cms.KeyTransRecipientInformation; +import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; +import org.bouncycastle.cms.jcajce.JceKeyTransRecipient; /** Reads a PDF document. * @author Paulo Soares (psoares@consiste.pt) @@ -714,13 +717,12 @@ else if (PdfName.AESV2.equals(dic.get(PdfName.CFM))) { data = new CMSEnvelopedData(recipient.getBytes()); Iterator recipientCertificatesIt = data.getRecipientInfos().getRecipients().iterator(); - while (recipientCertificatesIt.hasNext()) { - RecipientInformation recipientInfo = (RecipientInformation)recipientCertificatesIt.next(); - + KeyTransRecipientInformation recipientInfo = (KeyTransRecipientInformation)recipientCertificatesIt.next(); if (recipientInfo.getRID().match(certificate) && !foundRecipient) { - envelopedData = recipientInfo.getContent(certificateKey, certificateKeyProvider); - foundRecipient = true; + JceKeyTransRecipient recipient1 = new JceKeyTransEnvelopedRecipient((PrivateKey) certificateKey); + envelopedData = recipientInfo.getContent(recipient1); + foundRecipient = true; } } } diff --git a/src/test/groovy/com/lowagie/text/pdf/PdfWriterSpec.groovy b/src/test/groovy/com/lowagie/text/pdf/PdfWriterSpec.groovy new file mode 100644 index 0000000..76ebd5d --- /dev/null +++ b/src/test/groovy/com/lowagie/text/pdf/PdfWriterSpec.groovy @@ -0,0 +1,47 @@ +package com.lowagie.text.pdf + +import com.lowagie.text.Document +import com.lowagie.text.Element +import com.lowagie.text.Paragraph +import spock.lang.Specification + +class PdfWriterSpec extends Specification { + private static String OUTPUT_FOLDER = 'build/test-output' + private static String FILE = "${OUTPUT_FOLDER}/PositionPdf.pdf"; + + def setup() { + (new File(OUTPUT_FOLDER)).mkdirs() + } + + def "Create a PDF"() throws Exception { + when: + Document document = new Document(); + PdfWriter.getInstance(document, new FileOutputStream(FILE)); + document.open(); + // Left + Paragraph paragraph = new Paragraph("This is right aligned text"); + paragraph.setAlignment(Element.ALIGN_RIGHT); + document.add(paragraph); + // Centered + paragraph = new Paragraph("This is centered text"); + paragraph.setAlignment(Element.ALIGN_CENTER); + document.add(paragraph); + // Left + paragraph = new Paragraph("This is left aligned text"); + paragraph.setAlignment(Element.ALIGN_LEFT); + document.add(paragraph); + // Left with indentation + paragraph = new Paragraph( + "This is left aligned text with indentation"); + paragraph.setAlignment(Element.ALIGN_LEFT); + paragraph.setIndentationLeft(50); + document.add(paragraph); + + document.close(); + File createdPDF = new File(FILE) + + then: + createdPDF.exists() + createdPDF.size() > 0 + } +}