diff --git a/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/pdf/PdfPKCS7.java b/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/pdf/PdfPKCS7.java index 409dca2d4..23bbccc72 100644 --- a/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/pdf/PdfPKCS7.java +++ b/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/pdf/PdfPKCS7.java @@ -46,8 +46,11 @@ */ package com.fr.third.com.lowagie.text.pdf; +import com.fr.third.org.bouncycastle.asn1.ASN1Integer; import com.fr.third.org.bouncycastle.asn1.ASN1Object; +import com.fr.third.org.bouncycastle.asn1.ASN1ObjectIdentifier; import com.fr.third.org.bouncycastle.asn1.ASN1String; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; @@ -77,19 +80,15 @@ import java.util.HashSet; import java.util.Iterator; import java.util.Set; -import com.fr.third.org.bouncycastle.asn1.ASN1Encodable; import com.fr.third.org.bouncycastle.asn1.ASN1EncodableVector; import com.fr.third.org.bouncycastle.asn1.ASN1InputStream; import com.fr.third.org.bouncycastle.asn1.ASN1OutputStream; import com.fr.third.org.bouncycastle.asn1.ASN1Sequence; import com.fr.third.org.bouncycastle.asn1.ASN1Set; import com.fr.third.org.bouncycastle.asn1.ASN1TaggedObject; -import com.fr.third.org.bouncycastle.asn1.DEREnumerated; -import com.fr.third.org.bouncycastle.asn1.DERInteger; +import com.fr.third.org.bouncycastle.asn1.ASN1Enumerated; import com.fr.third.org.bouncycastle.asn1.DERNull; -import com.fr.third.org.bouncycastle.asn1.DERObjectIdentifier; import com.fr.third.org.bouncycastle.asn1.DEROctetString; -import com.fr.third.org.bouncycastle.asn1.DEROutputStream; import com.fr.third.org.bouncycastle.asn1.DERSequence; import com.fr.third.org.bouncycastle.asn1.DERSet; import com.fr.third.org.bouncycastle.asn1.DERTaggedObject; @@ -101,12 +100,12 @@ import com.fr.third.org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; import com.fr.third.org.bouncycastle.jce.provider.X509CRLParser; import com.fr.third.org.bouncycastle.jce.provider.X509CertParser; import com.fr.third.com.lowagie.text.ExceptionConverter; + import java.security.cert.CertificateParsingException; -import java.util.Date; + import com.fr.third.org.bouncycastle.asn1.ASN1OctetString; import com.fr.third.org.bouncycastle.asn1.cms.ContentInfo; import com.fr.third.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; -import com.fr.third.org.bouncycastle.asn1.tsp.MessageImprint; import com.fr.third.org.bouncycastle.asn1.x509.X509Extensions; //import org.bouncycastle.ocsp.BasicOCSPResp; //import org.bouncycastle.ocsp.CertificateID; @@ -138,7 +137,7 @@ public class PdfPKCS7 { private byte externalDigest[]; private byte externalRSAdata[]; private String provider; - + private static final String ID_PKCS7_DATA = "1.2.840.113549.1.7.1"; private static final String ID_PKCS7_SIGNED_DATA = "1.2.840.113549.1.7.2"; private static final String ID_RSA = "1.2.840.113549.1.1.1"; @@ -151,28 +150,28 @@ public class PdfPKCS7 { * Holds value of property reason. */ private String reason; - + /** * Holds value of property location. */ private String location; - + /** * Holds value of property signDate. */ private Calendar signDate; - + /** * Holds value of property signName. */ private String signName; - + // private TimeStampToken timeStampToken; - + private static final HashMap digestNames = new HashMap(); private static final HashMap algorithmNames = new HashMap(); private static final HashMap allowedDigests = new HashMap(); - + static { digestNames.put("1.2.840.113549.2.5", "MD5"); digestNames.put("1.2.840.113549.2.2", "MD2"); @@ -201,7 +200,7 @@ public class PdfPKCS7 { digestNames.put("1.3.36.3.3.1.3", "RIPEMD128"); digestNames.put("1.3.36.3.3.1.2", "RIPEMD160"); digestNames.put("1.3.36.3.3.1.4", "RIPEMD256"); - + algorithmNames.put("1.2.840.113549.1.1.1", "RSA"); algorithmNames.put("1.2.840.10040.4.1", "DSA"); algorithmNames.put("1.2.840.113549.1.1.2", "RSA"); @@ -217,7 +216,7 @@ public class PdfPKCS7 { algorithmNames.put("1.3.36.3.3.1.3", "RSA"); algorithmNames.put("1.3.36.3.3.1.2", "RSA"); algorithmNames.put("1.3.36.3.3.1.4", "RSA"); - + allowedDigests.put("MD5", "1.2.840.113549.2.5"); allowedDigests.put("MD2", "1.2.840.113549.2.2"); allowedDigests.put("SHA1", "1.3.14.3.2.26"); @@ -239,48 +238,50 @@ public class PdfPKCS7 { allowedDigests.put("RIPEMD256", "1.3.36.3.2.3"); allowedDigests.put("RIPEMD-256", "1.3.36.3.2.3"); } - + /** * Gets the digest name for a certain id - * @param oid an id (for instance "1.2.840.113549.2.5") - * @return a digest name (for instance "MD5") - * @since 2.1.6 + * + * @param oid an id (for instance "1.2.840.113549.2.5") + * @return a digest name (for instance "MD5") + * @since 2.1.6 */ public static String getDigest(String oid) { - String ret = (String)digestNames.get(oid); + String ret = (String) digestNames.get(oid); if (ret == null) return oid; else return ret; } - + /** * Gets the algorithm name for a certain id. - * @param oid an id (for instance "1.2.840.113549.1.1.1") - * @return an algorithm name (for instance "RSA") - * @since 2.1.6 + * + * @param oid an id (for instance "1.2.840.113549.1.1.1") + * @return an algorithm name (for instance "RSA") + * @since 2.1.6 */ public static String getAlgorithm(String oid) { - String ret = (String)algorithmNames.get(oid); + String ret = (String) algorithmNames.get(oid); if (ret == null) return oid; else return ret; } - + /** * Gets the timestamp token if there is one. * @return the timestamp token or null - * @since 2.1.6 + * @since 2.1.6 */ // public TimeStampToken getTimeStampToken() { // return timeStampToken; // } - + /** * Gets the timestamp date - * @return a date - * @since 2.1.6 + * @return a date + * @since 2.1.6 */ // public Calendar getTimeStampDate() { // if (timeStampToken == null) @@ -290,13 +291,14 @@ public class PdfPKCS7 { // cal.setTime(date); // return cal; // } - + /** * Verifies a signature using the sub-filter adbe.x509.rsa_sha1. + * * @param contentsKey the /Contents key - * @param certsKey the /Cert key - * @param provider the provider or null for the default provider - */ + * @param certsKey the /Cert key + * @param provider the provider or null for the default provider + */ public PdfPKCS7(byte[] contentsKey, byte[] certsKey, String provider) { try { this.provider = provider; @@ -304,73 +306,72 @@ public class PdfPKCS7 { cr.engineInit(new ByteArrayInputStream(certsKey)); certs = cr.engineReadAll(); signCerts = certs; - signCert = (X509Certificate)certs.iterator().next(); + signCert = (X509Certificate) certs.iterator().next(); crls = new ArrayList(); ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream(contentsKey)); - digest = ((DEROctetString)in.readObject()).getOctets(); + digest = ((DEROctetString) in.readObject()).getOctets(); if (provider == null) sig = Signature.getInstance("SHA1withRSA"); else sig = Signature.getInstance("SHA1withRSA", provider); sig.initVerify(signCert.getPublicKey()); - } - catch (Exception e) { + } catch (Exception e) { throw new ExceptionConverter(e); } } - + // private BasicOCSPResp basicResp; - + /** * Gets the OCSP basic response if there is one. + * * @return the OCSP basic response or null - * @since 2.1.6 + * @since 2.1.6 */ // public BasicOCSPResp getOcsp() { // return basicResp; // } - 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; for (int k = 0; k < seq.size(); ++k) { if (seq.getObjectAt(k) instanceof ASN1Sequence) { - seq = (ASN1Sequence)seq.getObjectAt(0); + seq = (ASN1Sequence) seq.getObjectAt(0); ret = false; break; } if (seq.getObjectAt(k) instanceof ASN1TaggedObject) { - ASN1TaggedObject tag = (ASN1TaggedObject)seq.getObjectAt(k); + ASN1TaggedObject tag = (ASN1TaggedObject) seq.getObjectAt(k); if (tag.getObject() instanceof ASN1Sequence) { - seq = (ASN1Sequence)tag.getObject(); + seq = (ASN1Sequence) tag.getObject(); ret = false; break; - } - else + } else return; } } if (ret) return; } - DEROctetString os = (DEROctetString)seq.getObjectAt(1); + DEROctetString os = (DEROctetString) seq.getObjectAt(1); ASN1InputStream inp = new ASN1InputStream(os.getOctets()); BasicOCSPResponse resp = BasicOCSPResponse.getInstance(inp.readObject()); // basicResp = new BasicOCSPResp(resp); } - + /** * Verifies a signature using the sub-filter adbe.pkcs7.detached or * adbe.pkcs7.sha1. + * * @param contentsKey the /Contents key - * @param provider the provider or null for the default provider - */ + * @param provider the provider or null for the default provider + */ public PdfPKCS7(byte[] contentsKey, String provider) { try { this.provider = provider; @@ -383,18 +384,17 @@ public class PdfPKCS7 { try { pkcs = din.readObject(); - } - catch (IOException e) { + } catch (IOException e) { throw new IllegalArgumentException("can't decode PKCS7SignedData object"); } if (!(pkcs instanceof ASN1Sequence)) { throw new IllegalArgumentException("Not a valid PKCS#7 object - not a sequence"); } - ASN1Sequence signedData = (ASN1Sequence)pkcs; - DERObjectIdentifier objId = (DERObjectIdentifier)signedData.getObjectAt(0); + ASN1Sequence signedData = (ASN1Sequence) pkcs; + 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(); + ASN1Sequence content = (ASN1Sequence) ((DERTaggedObject) signedData.getObjectAt(1)).getObject(); // the positions that we care are: // 0 - version // 1 - digestAlgorithms @@ -403,15 +403,14 @@ public class PdfPKCS7 { // last - signerInfos // the version - version = ((DERInteger)content.getObjectAt(0)).getValue().intValue(); + version = ((ASN1Integer) content.getObjectAt(0)).getValue().intValue(); // the digestAlgorithms digestalgos = new HashSet(); - Enumeration e = ((ASN1Set)content.getObjectAt(1)).getObjects(); - while (e.hasMoreElements()) - { - ASN1Sequence s = (ASN1Sequence)e.nextElement(); - DERObjectIdentifier o = (DERObjectIdentifier)s.getObjectAt(0); + Enumeration e = ((ASN1Set) content.getObjectAt(1)).getObjects(); + while (e.hasMoreElements()) { + ASN1Sequence s = (ASN1Sequence) e.nextElement(); + ASN1ObjectIdentifier o = (ASN1ObjectIdentifier) s.getObjectAt(0); digestalgos.add(o.getId()); } @@ -424,9 +423,9 @@ public class PdfPKCS7 { crls = cl.engineReadAll(); // the possible ID_PKCS7_DATA - ASN1Sequence rsaData = (ASN1Sequence)content.getObjectAt(2); + ASN1Sequence rsaData = (ASN1Sequence) content.getObjectAt(2); if (rsaData.size() > 1) { - DEROctetString rsaDataContent = (DEROctetString)((DERTaggedObject)rsaData.getObjectAt(1)).getObject(); + DEROctetString rsaDataContent = (DEROctetString) ((DERTaggedObject) rsaData.getObjectAt(1)).getObject(); RSAdata = rsaDataContent.getOctets(); } @@ -434,22 +433,22 @@ public class PdfPKCS7 { int next = 3; while (content.getObjectAt(next) instanceof DERTaggedObject) ++next; - ASN1Set signerInfos = (ASN1Set)content.getObjectAt(next); + ASN1Set signerInfos = (ASN1Set) content.getObjectAt(next); if (signerInfos.size() != 1) throw new IllegalArgumentException("This PKCS#7 object has multiple SignerInfos - only one is supported at this time"); - ASN1Sequence signerInfo = (ASN1Sequence)signerInfos.getObjectAt(0); + ASN1Sequence signerInfo = (ASN1Sequence) signerInfos.getObjectAt(0); // the positions that we care are // 0 - version // 1 - the signing certificate serial number // 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(); - for (Iterator i = certs.iterator(); i.hasNext();) { - X509Certificate cert = (X509Certificate)i.next(); + ASN1Sequence issuerAndSerialNumber = (ASN1Sequence) signerInfo.getObjectAt(1); + BigInteger serialNumber = ((ASN1Integer) issuerAndSerialNumber.getObjectAt(1)).getValue(); + for (Iterator i = certs.iterator(); i.hasNext(); ) { + X509Certificate cert = (X509Certificate) i.next(); if (serialNumber.equals(cert.getSerialNumber())) { signCert = cert; break; @@ -459,27 +458,26 @@ public class PdfPKCS7 { 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); + ASN1TaggedObject tagsig = (ASN1TaggedObject) signerInfo.getObjectAt(next); ASN1Set sseq = ASN1Set.getInstance(tagsig, false); 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)) { - ASN1Set set = (ASN1Set)seq2.getObjectAt(1); - digestAttr = ((DEROctetString)set.getObjectAt(0)).getOctets(); - } - else if (((DERObjectIdentifier)seq2.getObjectAt(0)).getId().equals(ID_ADBE_REVOCATION)) { - ASN1Set setout = (ASN1Set)seq2.getObjectAt(1); - ASN1Sequence seqout = (ASN1Sequence)setout.getObjectAt(0); + ASN1Sequence seq2 = (ASN1Sequence) sseq.getObjectAt(k); + if (((ASN1ObjectIdentifier) seq2.getObjectAt(0)).getId().equals(ID_MESSAGE_DIGEST)) { + ASN1Set set = (ASN1Set) seq2.getObjectAt(1); + digestAttr = ((DEROctetString) set.getObjectAt(0)).getOctets(); + } 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) { - ASN1TaggedObject tg = (ASN1TaggedObject)seqout.getObjectAt(j); + ASN1TaggedObject tg = (ASN1TaggedObject) seqout.getObjectAt(j); if (tg.getTagNo() != 1) continue; - ASN1Sequence seqin = (ASN1Sequence)tg.getObject(); + ASN1Sequence seqin = (ASN1Sequence) tg.getObject(); findOcsp(seqin); } } @@ -488,8 +486,8 @@ public class PdfPKCS7 { throw new IllegalArgumentException("Authenticated attribute is missing the digest."); ++next; } - digestEncryptionAlgorithm = ((DERObjectIdentifier)((ASN1Sequence)signerInfo.getObjectAt(next++)).getObjectAt(0)).getId(); - digest = ((DEROctetString)signerInfo.getObjectAt(next++)).getOctets(); + 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); ASN1Set unat = ASN1Set.getInstance(taggedObject, false); @@ -513,56 +511,55 @@ public class PdfPKCS7 { else sig = Signature.getInstance(getDigestAlgorithm(), provider); sig.initVerify(signCert.getPublicKey()); - } - catch (Exception e) { + } catch (Exception e) { throw new ExceptionConverter(e); } } /** * Generates a signature. - * @param privKey the private key - * @param certChain the certificate chain - * @param crlList the certificate revocation list + * + * @param privKey the private key + * @param certChain the certificate chain + * @param crlList the certificate revocation list * @param hashAlgorithm the hash algorithm - * @param provider the provider or null for the default provider - * @param hasRSAdata true if the sub-filter is adbe.pkcs7.sha1 - * @throws InvalidKeyException on error - * @throws NoSuchProviderException on error + * @param provider the provider or null for the default provider + * @param hasRSAdata true if the sub-filter is adbe.pkcs7.sha1 + * @throws InvalidKeyException on error + * @throws NoSuchProviderException on error * @throws NoSuchAlgorithmException on error - */ + */ public PdfPKCS7(PrivateKey privKey, Certificate[] certChain, CRL[] crlList, String hashAlgorithm, String provider, boolean hasRSAdata) - throws InvalidKeyException, NoSuchProviderException, - NoSuchAlgorithmException - { + throws InvalidKeyException, NoSuchProviderException, + NoSuchAlgorithmException { this.privKey = privKey; this.provider = provider; - - digestAlgorithm = (String)allowedDigests.get(hashAlgorithm.toUpperCase()); + + digestAlgorithm = (String) allowedDigests.get(hashAlgorithm.toUpperCase()); if (digestAlgorithm == null) - throw new NoSuchAlgorithmException("Unknown Hash Algorithm "+hashAlgorithm); - + throw new NoSuchAlgorithmException("Unknown Hash Algorithm " + hashAlgorithm); + version = signerversion = 1; certs = new ArrayList(); crls = new ArrayList(); digestalgos = new HashSet(); digestalgos.add(digestAlgorithm); - + // // Copy in the certificates and crls used to sign the private key. // - signCert = (X509Certificate)certChain[0]; - for (int i = 0;i < certChain.length;i++) { + signCert = (X509Certificate) certChain[0]; + for (int i = 0; i < certChain.length; i++) { certs.add(certChain[i]); } - + if (crlList != null) { - for (int i = 0;i < crlList.length;i++) { + for (int i = 0; i < crlList.length; i++) { crls.add(crlList[i]); } } - + if (privKey != null) { // // Now we have private key, find out what the digestEncryptionAlgorithm is. @@ -570,12 +567,10 @@ public class PdfPKCS7 { digestEncryptionAlgorithm = privKey.getAlgorithm(); if (digestEncryptionAlgorithm.equals("RSA")) { digestEncryptionAlgorithm = ID_RSA; - } - else if (digestEncryptionAlgorithm.equals("DSA")) { + } else if (digestEncryptionAlgorithm.equals("DSA")) { digestEncryptionAlgorithm = ID_DSA; - } - else { - throw new NoSuchAlgorithmException("Unknown Key Algorithm "+digestEncryptionAlgorithm); + } else { + throw new NoSuchAlgorithmException("Unknown Key Algorithm " + digestEncryptionAlgorithm); } } if (hasRSAdata) { @@ -598,6 +593,7 @@ public class PdfPKCS7 { /** * Update the digest with the specified bytes. This method is used both for signing and verifying + * * @param buf the data buffer * @param off the offset in the data buffer * @param len the data length @@ -609,11 +605,12 @@ public class PdfPKCS7 { else sig.update(buf, off, len); } - + /** * Verify the digest. - * @throws SignatureException on error + * * @return true if the signature checks out, false otherwise + * @throws SignatureException on error */ public boolean verify() throws SignatureException { if (verified) @@ -625,8 +622,7 @@ public class PdfPKCS7 { messageDigest.update(msd); } verifyResult = (Arrays.equals(messageDigest.digest(), digestAttr) && sig.verify(digest)); - } - else { + } else { if (RSAdata != null) sig.update(messageDigest.digest()); verifyResult = sig.verify(digest); @@ -634,12 +630,12 @@ public class PdfPKCS7 { verified = true; return verifyResult; } - + /** * Checks if the timestamp refers to this document. * @throws java.security.NoSuchAlgorithmException on error * @return true if it checks false otherwise - * @since 2.1.6 + * @since 2.1.6 */ // public boolean verifyTimestampImprint() throws NoSuchAlgorithmException { // if (timeStampToken == null) @@ -650,33 +646,35 @@ public class PdfPKCS7 { // boolean res = Arrays.equals(md, imphashed); // return res; // } - + /** * Get all the X.509 certificates associated with this PKCS#7 object in no particular order. * Other certificates, from OCSP for example, will also be included. + * * @return the X.509 certificates associated with this PKCS#7 object */ public Certificate[] getCertificates() { - return (X509Certificate[])certs.toArray(new X509Certificate[certs.size()]); + return (X509Certificate[]) certs.toArray(new X509Certificate[certs.size()]); } - + /** * Get the X.509 sign certificate chain associated with this PKCS#7 object. * Only the certificates used for the main signature will be returned, with * the signing certificate first. + * * @return the X.509 certificates associated with this PKCS#7 object - * @since 2.1.6 + * @since 2.1.6 */ public Certificate[] getSignCertificateChain() { - return (X509Certificate[])signCerts.toArray(new X509Certificate[signCerts.size()]); + return (X509Certificate[]) signCerts.toArray(new X509Certificate[signCerts.size()]); } - + private void signCertificateChain() { ArrayList cc = new ArrayList(); cc.add(signCert); ArrayList oc = new ArrayList(certs); for (int k = 0; k < oc.size(); ++k) { - if (signCert.getSerialNumber().equals(((X509Certificate)oc.get(k)).getSerialNumber())) { + if (signCert.getSerialNumber().equals(((X509Certificate) oc.get(k)).getSerialNumber())) { oc.remove(k); --k; continue; @@ -684,72 +682,77 @@ public class PdfPKCS7 { } boolean found = true; while (found) { - X509Certificate v = (X509Certificate)cc.get(cc.size() - 1); + X509Certificate v = (X509Certificate) cc.get(cc.size() - 1); found = false; for (int k = 0; k < oc.size(); ++k) { try { if (provider == null) - v.verify(((X509Certificate)oc.get(k)).getPublicKey()); + v.verify(((X509Certificate) oc.get(k)).getPublicKey()); else - v.verify(((X509Certificate)oc.get(k)).getPublicKey(), provider); + v.verify(((X509Certificate) oc.get(k)).getPublicKey(), provider); found = true; cc.add(oc.get(k)); oc.remove(k); break; - } - catch (Exception e) { + } catch (Exception e) { } } } signCerts = cc; } - + /** * Get the X.509 certificate revocation lists associated with this PKCS#7 object + * * @return the X.509 certificate revocation lists associated with this PKCS#7 object */ public Collection getCRLs() { return crls; } - + /** * Get the X.509 certificate actually used to sign the digest. + * * @return the X.509 certificate actually used to sign the digest */ public X509Certificate getSigningCertificate() { return signCert; } - + /** * Get the version of the PKCS#7 object. Always 1 + * * @return the version of the PKCS#7 object. Always 1 */ public int getVersion() { return version; } - + /** * Get the version of the PKCS#7 "SignerInfo" object. Always 1 + * * @return the version of the PKCS#7 "SignerInfo" object. Always 1 */ public int getSigningInfoVersion() { return signerversion; } - + /** * Get the algorithm used to calculate the message digest + * * @return the algorithm used to calculate the message digest */ public String getDigestAlgorithm() { String dea = getAlgorithm(digestEncryptionAlgorithm); if (dea == null) dea = digestEncryptionAlgorithm; - + return getHashAlgorithm() + "with" + dea; } /** * Returns the algorithm. + * * @return the digest algorithm */ public String getHashAlgorithm() { @@ -759,17 +762,19 @@ public class PdfPKCS7 { /** * Loads the default root certificates at <java.home>/lib/security/cacerts * with the default provider. + * * @return a KeyStore - */ + */ public static KeyStore loadCacertsKeyStore() { return loadCacertsKeyStore(null); } /** * Loads the default root certificates at <java.home>/lib/security/cacerts. + * * @param provider the provider or null for the default provider * @return a KeyStore - */ + */ public static KeyStore loadCacertsKeyStore(String provider) { File file = new File(System.getProperty("java.home"), "lib"); file = new File(file, "security"); @@ -784,23 +789,27 @@ public class PdfPKCS7 { k = KeyStore.getInstance("JKS", provider); k.load(fin, null); return k; - } - catch (Exception e) { + } catch (Exception e) { throw new ExceptionConverter(e); - } - finally { - try{if (fin != null) {fin.close();}}catch(Exception ex){} + } finally { + try { + if (fin != null) { + fin.close(); + } + } catch (Exception ex) { + } } } - + /** * Verifies a single certificate. - * @param cert the certificate to verify - * @param crls the certificate revocation list or null + * + * @param cert the certificate to verify + * @param crls the certificate revocation list or null * @param calendar the date or null for the current date * @return a String with the error description or null * if no error - */ + */ public static String verifyCertificate(X509Certificate cert, Collection crls, Calendar calendar) { if (calendar == null) calendar = new GregorianCalendar(); @@ -808,70 +817,66 @@ public class PdfPKCS7 { return "Has unsupported critical extension"; try { cert.checkValidity(calendar.getTime()); - } - catch (Exception e) { + } catch (Exception e) { return e.getMessage(); } if (crls != null) { - for (Iterator it = crls.iterator(); it.hasNext();) { - if (((CRL)it.next()).isRevoked(cert)) + for (Iterator it = crls.iterator(); it.hasNext(); ) { + if (((CRL) it.next()).isRevoked(cert)) return "Certificate revoked"; } } return null; } - + /** * Verifies a certificate chain against a KeyStore. - * @param certs the certificate chain + * + * @param certs the certificate chain * @param keystore the KeyStore - * @param crls the certificate revocation list or null + * @param crls the certificate revocation list or null * @param calendar the date or null for the current date * @return null if the certificate chain could be validated or a * Object[]{cert,error} where cert is the * failed certificate and error is the error message - */ + */ public static Object[] verifyCertificates(Certificate certs[], KeyStore keystore, Collection crls, Calendar calendar) { if (calendar == null) calendar = new GregorianCalendar(); for (int k = 0; k < certs.length; ++k) { - X509Certificate cert = (X509Certificate)certs[k]; + X509Certificate cert = (X509Certificate) certs[k]; String err = verifyCertificate(cert, crls, calendar); if (err != null) return new Object[]{cert, err}; try { - for (Enumeration aliases = keystore.aliases(); aliases.hasMoreElements();) { + 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); + X509Certificate certStoreX509 = (X509Certificate) keystore.getCertificate(alias); if (verifyCertificate(certStoreX509, crls, calendar) != null) continue; try { cert.verify(certStoreX509.getPublicKey()); return null; - } - catch (Exception e) { + } catch (Exception e) { continue; } - } - catch (Exception ex) { + } catch (Exception ex) { } } - } - catch (Exception e) { + } catch (Exception e) { } int j; for (j = 0; j < certs.length; ++j) { if (j == k) continue; - X509Certificate certNext = (X509Certificate)certs[j]; + X509Certificate certNext = (X509Certificate) certs[j]; try { cert.verify(certNext.getPublicKey()); break; - } - catch (Exception e) { + } catch (Exception e) { } } if (j == certs.length) @@ -886,8 +891,8 @@ public class PdfPKCS7 { * @param keystore the KeyStore * @param provider the provider or null to use the BouncyCastle provider * @return true is a certificate was found - * @since 2.1.6 - */ + * @since 2.1.6 + */ // public static boolean verifyOcspCertificates(BasicOCSPResp ocsp, KeyStore keystore, String provider) { // if (provider == null) // provider = "BC"; @@ -909,15 +914,15 @@ public class PdfPKCS7 { // } // return false; // } - + /** * Verifies a timestamp against a KeyStore. * @param ts the timestamp * @param keystore the KeyStore * @param provider the provider or null to use the BouncyCastle provider * @return true is a certificate was found - * @since 2.1.6 - */ + * @since 2.1.6 + */ // public static boolean verifyTimestampCertificates(TimeStampToken ts, KeyStore keystore, String provider) { // if (provider == null) // provider = "BC"; @@ -939,13 +944,14 @@ public class PdfPKCS7 { // } // return false; // } - + /** * Retrieves the OCSP URL from the given certificate. + * * @param certificate the certificate * @return the URL or null * @throws CertificateParsingException on error - * @since 2.1.6 + * @since 2.1.6 */ public static String getOCSPURL(X509Certificate certificate) throws CertificateParsingException { try { @@ -953,32 +959,33 @@ public class PdfPKCS7 { if (obj == null) { return null; } - + ASN1Sequence AccessDescriptions = (ASN1Sequence) obj; for (int i = 0; i < AccessDescriptions.size(); i++) { ASN1Sequence AccessDescription = (ASN1Sequence) AccessDescriptions.getObjectAt(i); - if ( AccessDescription.size() != 2 ) { + 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((ASN1Object)AccessDescription.getObjectAt(1)); - if ( AccessLocation == null ) { - return "" ; + 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 { - return AccessLocation ; + return AccessLocation; } } } } - } catch (Exception e) { + } catch (Exception e) { } return null; } - + /** * Checks if OCSP revocation refers to the document signing certificate. + * * @return true if it checks false otherwise - * @since 2.1.6 + * @since 2.1.6 */ // public boolean isRevocationValid() { // if (basicResp == null) @@ -998,7 +1005,6 @@ public class PdfPKCS7 { // } // return false; // } - private static ASN1Object getExtensionValue(X509Certificate cert, String oid) throws IOException { byte[] bytes = cert.getExtensionValue(oid); if (bytes == null) { @@ -1009,74 +1015,75 @@ public class PdfPKCS7 { aIn = new ASN1InputStream(new ByteArrayInputStream(octs.getOctets())); return aIn.readObject(); } - + private static String getStringFromGeneralName(ASN1Object names) throws IOException { - DERTaggedObject taggedObject = (DERTaggedObject) names ; + DERTaggedObject taggedObject = (DERTaggedObject) names; return new String(ASN1OctetString.getInstance(taggedObject, false).getOctets(), "ISO-8859-1"); } /** * Get the "issuer" from the TBSCertificate bytes that are passed in + * * @param enc a TBSCertificate in a byte array * @return a DERObject */ private static ASN1Object getIssuer(byte[] enc) { try { ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream(enc)); - ASN1Sequence seq = (ASN1Sequence)in.readObject(); - return (ASN1Object)seq.getObjectAt(seq.getObjectAt(0) instanceof DERTaggedObject ? 3 : 2); - } - catch (IOException e) { + ASN1Sequence seq = (ASN1Sequence) in.readObject(); + return (ASN1Object) seq.getObjectAt(seq.getObjectAt(0) instanceof DERTaggedObject ? 3 : 2); + } catch (IOException e) { throw new ExceptionConverter(e); } } /** * Get the "subject" from the TBSCertificate bytes that are passed in + * * @param enc A TBSCertificate in a byte array * @return a DERObject */ private static ASN1Object getSubject(byte[] enc) { try { ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream(enc)); - ASN1Sequence seq = (ASN1Sequence)in.readObject(); - return (ASN1Object)seq.getObjectAt(seq.getObjectAt(0) instanceof DERTaggedObject ? 5 : 4); - } - catch (IOException e) { + ASN1Sequence seq = (ASN1Sequence) in.readObject(); + return (ASN1Object) seq.getObjectAt(seq.getObjectAt(0) instanceof DERTaggedObject ? 5 : 4); + } catch (IOException e) { throw new ExceptionConverter(e); } } /** * Get the issuer fields from an X509 Certificate + * * @param cert an X509Certificate * @return an X509Name */ public static X509Name getIssuerFields(X509Certificate cert) { try { - return new X509Name((ASN1Sequence)getIssuer(cert.getTBSCertificate())); - } - catch (Exception e) { + return new X509Name((ASN1Sequence) getIssuer(cert.getTBSCertificate())); + } catch (Exception e) { throw new ExceptionConverter(e); } } /** * Get the subject fields from an X509 Certificate + * * @param cert an X509Certificate * @return an X509Name */ public static X509Name getSubjectFields(X509Certificate cert) { try { - return new X509Name((ASN1Sequence)getSubject(cert.getTBSCertificate())); - } - catch (Exception e) { + return new X509Name((ASN1Sequence) getSubject(cert.getTBSCertificate())); + } catch (Exception e) { throw new ExceptionConverter(e); } } - + /** * Gets the bytes for the PKCS#1 object. + * * @return a byte array */ public byte[] getEncodedPKCS1() { @@ -1085,55 +1092,55 @@ public class PdfPKCS7 { digest = externalDigest; else digest = sig.sign(); - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ASN1OutputStream dout = new ASN1OutputStream(bOut); dout.writeObject(new DEROctetString(digest)); dout.close(); - + return bOut.toByteArray(); - } - catch (Exception e) { + } catch (Exception e) { throw new ExceptionConverter(e); } } - + /** * Sets the digest/signature to an external calculated value. - * @param digest the digest. This is the actual signature - * @param RSAdata the extra data that goes into the data tag in PKCS#7 + * + * @param digest the digest. This is the actual signature + * @param RSAdata the extra data that goes into the data tag in PKCS#7 * @param digestEncryptionAlgorithm the encryption algorithm. It may must be null if the digest - * is also null. If the digest is not null - * then it may be "RSA" or "DSA" - */ + * is also null. If the digest is not null + * then it may be "RSA" or "DSA" + */ public void setExternalDigest(byte digest[], byte RSAdata[], String digestEncryptionAlgorithm) { externalDigest = digest; externalRSAdata = RSAdata; if (digestEncryptionAlgorithm != null) { if (digestEncryptionAlgorithm.equals("RSA")) { this.digestEncryptionAlgorithm = ID_RSA; - } - else if (digestEncryptionAlgorithm.equals("DSA")) { + } else if (digestEncryptionAlgorithm.equals("DSA")) { this.digestEncryptionAlgorithm = ID_DSA; - } - else - throw new ExceptionConverter(new NoSuchAlgorithmException("Unknown Key Algorithm "+digestEncryptionAlgorithm)); + } else + throw new ExceptionConverter(new NoSuchAlgorithmException("Unknown Key Algorithm " + digestEncryptionAlgorithm)); } } - + /** * Gets the bytes for the PKCS7SignedData object. + * * @return the bytes for the PKCS7SignedData object */ public byte[] getEncodedPKCS7() { return getEncodedPKCS7(null, null, null, null); } - + /** * Gets the bytes for the PKCS7SignedData object. Optionally the authenticatedAttributes * in the signerInfo can also be set. If either of the parameters is null, none will be used. + * * @param secondDigest the digest in the authenticatedAttributes - * @param signingTime the signing time in the authenticatedAttributes + * @param signingTime the signing time in the authenticatedAttributes * @return the bytes for the PKCS7SignedData object */ public byte[] getEncodedPKCS7(byte secondDigest[], Calendar signingTime) { @@ -1144,11 +1151,12 @@ public class PdfPKCS7 { * Gets the bytes for the PKCS7SignedData object. Optionally the authenticatedAttributes * in the signerInfo can also be set, OR a time-stamp-authority client * may be provided. + * * @param secondDigest the digest in the authenticatedAttributes - * @param signingTime the signing time in the authenticatedAttributes - * @param tsaClient TSAClient - null or an optional time stamp authority client + * @param signingTime the signing time in the authenticatedAttributes + * @param tsaClient TSAClient - null or an optional time stamp authority client * @return byte[] the bytes for the PKCS7SignedData object - * @since 2.1.6 + * @since 2.1.6 */ public byte[] getEncodedPKCS7(byte secondDigest[], Calendar signingTime, TSAClient tsaClient, byte[] ocsp) { try { @@ -1156,78 +1164,76 @@ public class PdfPKCS7 { digest = externalDigest; if (RSAdata != null) RSAdata = externalRSAdata; - } - else if (externalRSAdata != null && RSAdata != null) { + } else if (externalRSAdata != null && RSAdata != null) { RSAdata = externalRSAdata; sig.update(RSAdata); digest = sig.sign(); - } - else { + } else { if (RSAdata != null) { RSAdata = messageDigest.digest(); sig.update(RSAdata); } digest = sig.sign(); } - + // Create the set of Hash algorithms ASN1EncodableVector digestAlgorithms = new ASN1EncodableVector(); - for(Iterator it = digestalgos.iterator(); it.hasNext();) { + 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); - + // Get all the certificates // v = new ASN1EncodableVector(); - for (Iterator i = certs.iterator(); i.hasNext();) { - ASN1InputStream tempstream = new ASN1InputStream(new ByteArrayInputStream(((X509Certificate)i.next()).getEncoded())); + for (Iterator i = certs.iterator(); i.hasNext(); ) { + ASN1InputStream tempstream = new ASN1InputStream(new ByteArrayInputStream(((X509Certificate) i.next()).getEncoded())); v.add(tempstream.readObject()); } - + DERSet dercertificates = new DERSet(v); - + // Create signerinfo structure. // ASN1EncodableVector signerinfo = new ASN1EncodableVector(); - + // 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 if (secondDigest != null && signingTime != null) { signerinfo.add(new DERTaggedObject(false, 0, getAuthenticatedAttributeSet(secondDigest, signingTime, ocsp))); } // 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 signerinfo.add(new DEROctetString(digest)); - + // When requested, go get and add the timestamp. May throw an exception. // Added by Martin Brunecky, 07/12/2007 folowing Aiken Sam, 2006-11-15 // Sam found Adobe expects time-stamped SHA1-1 of the encrypted digest @@ -1241,57 +1247,57 @@ public class PdfPKCS7 { } } } - + // 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)); - - if (!crls.isEmpty()) { + + if (!crls.isEmpty()) { v = new ASN1EncodableVector(); - for (Iterator i = crls.iterator();i.hasNext();) { - ASN1InputStream t = new ASN1InputStream(new ByteArrayInputStream(((X509CRL)i.next()).getEncoded())); + for (Iterator i = crls.iterator(); i.hasNext(); ) { + ASN1InputStream t = new ASN1InputStream(new ByteArrayInputStream(((X509CRL) i.next()).getEncoded())); v.add(t.readObject()); } DERSet dercrls = new DERSet(v); body.add(new DERTaggedObject(false, 1, dercrls)); } - + // Only allow one signerInfo body.add(new DERSet(new DERSequence(signerinfo))); - + // Now we have the body, wrap it in it's PKCS7Signed shell // 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(); - + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ASN1OutputStream dout = new ASN1OutputStream(bOut); dout.writeObject(new DERSequence(whole)); dout.close(); - + return bOut.toByteArray(); - } - catch (Exception e) { + } catch (Exception e) { throw new ExceptionConverter(e); } } - + /** * Added by Aiken Sam, 2006-11-15, modifed by Martin Brunecky 07/12/2007 * to start with the timeStampToken (signedData 1.2.840.113549.1.7.2). * Token is the TSA response without response status, which is usually * handled by the (vendor supplied) TSA request/response interface). + * * @param timeStampToken byte[] - time stamp token, DER encoded signedData * @return ASN1EncodableVector * @throws IOException */ - private ASN1EncodableVector buildUnauthenticatedAttributes(byte[] timeStampToken) throws IOException { + private ASN1EncodableVector buildUnauthenticatedAttributes(byte[] timeStampToken) throws IOException { if (timeStampToken == null) return null; @@ -1302,20 +1308,20 @@ public class PdfPKCS7 { 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)); unauthAttributes.add(new DERSequence(v)); return unauthAttributes; - } + } + - /** * When using authenticatedAttributes the authentication process is different. * The document digest is generated and put inside the attribute. The signing is done over the DER encoded * authenticatedAttributes. This method provides that encoding and the parameters must be - * exactly the same as in {@link #getEncodedPKCS7(byte[],Calendar)}. + * exactly the same as in {@link #getEncodedPKCS7(byte[], Calendar)}. *

* A simple example: *

@@ -1334,132 +1340,138 @@ public class PdfPKCS7 { * pk7.update(sh, 0, sh.length); * byte sg[] = pk7.getEncodedPKCS7(hash, cal); * + * * @param secondDigest the content digest - * @param signingTime the signing time + * @param signingTime the signing time * @return the byte array representation of the authenticatedAttributes ready to be signed - */ + */ public byte[] getAuthenticatedAttributeBytes(byte secondDigest[], Calendar signingTime, byte[] ocsp) { try { return getAuthenticatedAttributeSet(secondDigest, signingTime, ocsp).getEncoded("DER"); - } - catch (Exception e) { + } catch (Exception e) { throw new ExceptionConverter(e); } } - + private DERSet getAuthenticatedAttributeSet(byte secondDigest[], Calendar signingTime, byte[] ocsp) { 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))); vo1.add(new DERSequence(v3)); v.add(new DERSet(new DERSequence(new DERTaggedObject(true, 1, new DERSequence(vo1))))); attribute.add(new DERSequence(v)); - } - else if (!crls.isEmpty()) { + } 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())); + for (Iterator i = crls.iterator(); i.hasNext(); ) { + ASN1InputStream t = new ASN1InputStream(new ByteArrayInputStream(((X509CRL) i.next()).getEncoded())); v2.add(t.readObject()); } v.add(new DERSet(new DERSequence(new DERTaggedObject(true, 0, new DERSequence(v2))))); attribute.add(new DERSequence(v)); } return new DERSet(attribute); - } - catch (Exception e) { + } catch (Exception e) { throw new ExceptionConverter(e); } } - + /** * Getter for property reason. + * * @return Value of property reason. */ public String getReason() { return this.reason; } - + /** * Setter for property reason. + * * @param reason New value of property reason. */ public void setReason(String reason) { this.reason = reason; } - + /** * Getter for property location. + * * @return Value of property location. */ public String getLocation() { return this.location; } - + /** * Setter for property location. + * * @param location New value of property location. */ public void setLocation(String location) { this.location = location; } - + /** * Getter for property signDate. + * * @return Value of property signDate. */ public Calendar getSignDate() { return this.signDate; } - + /** * Setter for property signDate. + * * @param signDate New value of property signDate. */ public void setSignDate(Calendar signDate) { this.signDate = signDate; } - + /** * Getter for property sigName. + * * @return Value of property sigName. */ public String getSignName() { return this.signName; } - + /** * Setter for property sigName. + * * @param signName New value of property sigName. */ public void setSignName(String signName) { this.signName = signName; } - + /** * a class that holds an X509 name */ @@ -1467,74 +1479,90 @@ public class PdfPKCS7 { /** * 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"); - - /** Naming attribute of type X520name */ - public static final DERObjectIdentifier SURNAME = new DERObjectIdentifier("2.5.4.4"); - /** Naming attribute of type X520name */ - public static final DERObjectIdentifier GIVENNAME = new DERObjectIdentifier("2.5.4.42"); - /** Naming attribute of type X520name */ - public static final DERObjectIdentifier INITIALS = new DERObjectIdentifier("2.5.4.43"); - /** Naming attribute of type X520name */ - public static final DERObjectIdentifier GENERATION = new DERObjectIdentifier("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 ST = new ASN1ObjectIdentifier("2.5.4.8"); + + /** + * Naming attribute of type X520name + */ + public static final ASN1ObjectIdentifier SURNAME = new ASN1ObjectIdentifier("2.5.4.4"); + /** + * Naming attribute of type X520name + */ + public static final ASN1ObjectIdentifier GIVENNAME = new ASN1ObjectIdentifier("2.5.4.42"); + /** + * Naming attribute of type X520name + */ + public static final ASN1ObjectIdentifier INITIALS = new ASN1ObjectIdentifier("2.5.4.43"); + /** + * Naming attribute of type X520name + */ + public static final ASN1ObjectIdentifier GENERATION = new ASN1ObjectIdentifier("2.5.4.44"); + /** + * Naming attribute of type X520name + */ + 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"); + /** + * object identifier + */ + 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"); + /** + * LDAP User id. + */ + public static final ASN1ObjectIdentifier UID = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.1"); - /** A HashMap with default symbols */ + /** + * A HashMap with default symbols + */ public static HashMap DefaultSymbols = new HashMap(); - + static { DefaultSymbols.put(C, "C"); DefaultSymbols.put(O, "O"); @@ -1552,83 +1580,91 @@ public class PdfPKCS7 { DefaultSymbols.put(INITIALS, "INITIALS"); DefaultSymbols.put(GENERATION, "GENERATION"); } - /** A HashMap with values */ + + /** + * A HashMap with values + */ public HashMap values = new HashMap(); /** * Constructs an X509 name + * * @param seq an ASN1 Sequence */ public X509Name(ASN1Sequence seq) { Enumeration e = seq.getObjects(); - + while (e.hasMoreElements()) { - ASN1Set set = (ASN1Set)e.nextElement(); - + ASN1Set set = (ASN1Set) e.nextElement(); + for (int i = 0; i < set.size(); i++) { - ASN1Sequence s = (ASN1Sequence)set.getObjectAt(i); - String id = (String)DefaultSymbols.get(s.getObjectAt(0)); + ASN1Sequence s = (ASN1Sequence) set.getObjectAt(i); + String id = (String) DefaultSymbols.get(s.getObjectAt(0)); if (id == null) continue; - ArrayList vs = (ArrayList)values.get(id); + ArrayList vs = (ArrayList) values.get(id); if (vs == null) { vs = new ArrayList(); values.put(id, vs); } - vs.add(((ASN1String)s.getObjectAt(1)).getString()); + vs.add(((ASN1String) s.getObjectAt(1)).getString()); } } } + /** * Constructs an X509 name + * * @param dirName a directory name */ public X509Name(String dirName) { - X509NameTokenizer nTok = new X509NameTokenizer(dirName); - + X509NameTokenizer nTok = new X509NameTokenizer(dirName); + while (nTok.hasMoreTokens()) { - String token = nTok.nextToken(); + String token = nTok.nextToken(); int index = token.indexOf('='); - + if (index == -1) { throw new IllegalArgumentException("badly formated directory string"); } - + String id = token.substring(0, index).toUpperCase(); String value = token.substring(index + 1); - ArrayList vs = (ArrayList)values.get(id); + ArrayList vs = (ArrayList) values.get(id); if (vs == null) { vs = new ArrayList(); values.put(id, vs); } vs.add(value); } - + } - + public String getField(String name) { - ArrayList vs = (ArrayList)values.get(name); - return vs == null ? null : (String)vs.get(0); + ArrayList vs = (ArrayList) values.get(name); + return vs == null ? null : (String) vs.get(0); } /** * gets a field array from the values Hashmap + * * @param name * @return an ArrayList */ public ArrayList getFieldArray(String name) { - ArrayList vs = (ArrayList)values.get(name); + ArrayList vs = (ArrayList) values.get(name); return vs == null ? null : vs; } - + /** * getter for values + * * @return a HashMap with the fields of the X509 name */ public HashMap getFields() { return values; } - + /** * @see java.lang.Object#toString() */ @@ -1636,7 +1672,7 @@ public class PdfPKCS7 { return values.toString(); } } - + /** * class for breaking up an X500 Name into it's component tokens, ala * java.util.StringTokenizer. We need this class as some of the @@ -1644,61 +1680,56 @@ public class PdfPKCS7 { * StringTokenizer. */ public static class X509NameTokenizer { - private String oid; - private int index; - private StringBuffer buf = new StringBuffer(); - + private String oid; + private int index; + private StringBuffer buf = new StringBuffer(); + public X509NameTokenizer( - String oid) { + String oid) { this.oid = oid; this.index = -1; } - + public boolean hasMoreTokens() { return (index != oid.length()); } - + public String nextToken() { if (index == oid.length()) { return null; } - - int end = index + 1; + + int end = index + 1; boolean quoted = false; boolean escaped = false; - + buf.setLength(0); - + while (end != oid.length()) { - char c = oid.charAt(end); - + char c = oid.charAt(end); + if (c == '"') { if (!escaped) { quoted = !quoted; - } - else { + } else { buf.append(c); } escaped = false; - } - else { + } else { if (escaped || quoted) { buf.append(c); escaped = false; - } - else if (c == '\\') { + } else if (c == '\\') { escaped = true; - } - else if (c == ',') { + } else if (c == ',') { break; - } - else { + } else { buf.append(c); } } end++; } - + index = end; return buf.toString().trim(); } diff --git a/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/pdf/PdfPublicKeySecurityHandler.java b/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/pdf/PdfPublicKeySecurityHandler.java index 1bd9ee366..6c483824e 100644 --- a/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/pdf/PdfPublicKeySecurityHandler.java +++ b/fine-itext-old/src/main/java/com/fr/third/com/lowagie/text/pdf/PdfPublicKeySecurityHandler.java @@ -48,12 +48,40 @@ */ /** - * The below 2 methods are from pdfbox. - * - * private DERObject createDERForRecipient(byte[] in, X509Certificate cert) ; - * private KeyTransRecipientInfo computeRecipientInfo(X509Certificate x509certificate, byte[] abyte0); - * - * 2006-11-22 Aiken Sam. + * The below 2 methods are from pdfbox. + *

+ * private DERObject createDERForRecipient(byte[] in, X509Certificate cert) ; + * private KeyTransRecipientInfo computeRecipientInfo(X509Certificate x509certificate, byte[] abyte0); + *

+ * 2006-11-22 Aiken Sam. + *

+ * Copyright (c) 2003-2006, www.pdfbox.org + * All rights reserved. + *

+ * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + *

+ * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *

+ * http://www.pdfbox.org */ /** @@ -90,7 +118,9 @@ package com.fr.third.com.lowagie.text.pdf; import com.fr.third.org.bouncycastle.asn1.ASN1Object; +import com.fr.third.org.bouncycastle.asn1.ASN1OutputStream; import com.fr.third.org.bouncycastle.asn1.ASN1Set; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -110,9 +140,8 @@ import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import com.fr.third.org.bouncycastle.asn1.ASN1InputStream; -import com.fr.third.org.bouncycastle.asn1.DERObjectIdentifier; +import com.fr.third.org.bouncycastle.asn1.ASN1ObjectIdentifier; import com.fr.third.org.bouncycastle.asn1.DEROctetString; -import com.fr.third.org.bouncycastle.asn1.DEROutputStream; import com.fr.third.org.bouncycastle.asn1.DERSet; import com.fr.third.org.bouncycastle.asn1.cms.ContentInfo; import com.fr.third.org.bouncycastle.asn1.cms.EncryptedContentInfo; @@ -129,11 +158,11 @@ import com.fr.third.org.bouncycastle.asn1.x509.TBSCertificateStructure; * @author Aiken Sam (aikensam@ieee.org) */ public class PdfPublicKeySecurityHandler { - + static final int SEED_LENGTH = 20; - + private ArrayList recipients = null; - + private byte[] seed = new byte[SEED_LENGTH]; public PdfPublicKeySecurityHandler() { @@ -141,56 +170,57 @@ public class PdfPublicKeySecurityHandler { try { key = KeyGenerator.getInstance("AES"); key.init(192, new SecureRandom()); - SecretKey sk = key.generateKey(); + SecretKey sk = key.generateKey(); System.arraycopy(sk.getEncoded(), 0, seed, 0, SEED_LENGTH); // create the 20 bytes seed } catch (NoSuchAlgorithmException e) { - seed = SecureRandom.getSeed(SEED_LENGTH); + seed = SecureRandom.getSeed(SEED_LENGTH); } - + recipients = new ArrayList(); } - /* + /* * Routine for decode output of PdfContentByte.escapeString(byte[] bytes). - * It should be moved to PdfContentByte. + * It should be moved to PdfContentByte. */ - + static public byte[] unescapedString(byte[] bytes) throws BadPdfFormatException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); - + int index = 0; - - if (bytes[0] != '(' && bytes[bytes.length-1] != ')') throw new BadPdfFormatException("Expect '(' and ')' at begin and end of the string."); - + + if (bytes[0] != '(' && bytes[bytes.length - 1] != ')') + throw new BadPdfFormatException("Expect '(' and ')' at begin and end of the string."); + while (index < bytes.length) { if (bytes[index] == '\\') { index++; switch (bytes[index]) { - case 'b': - baos.write('\b'); - break; - case 'f': - baos.write('\f'); - break; - case 't': - baos.write('\t'); - break; - case 'n': - baos.write('\n'); - break; - case 'r': - baos.write('\r'); - break; - case '(': + case 'b': + baos.write('\b'); + break; + case 'f': + baos.write('\f'); + break; + case 't': + baos.write('\t'); + break; + case 'n': + baos.write('\n'); + break; + case 'r': + baos.write('\r'); + break; + case '(': baos.write('('); break; - case ')': + case ')': baos.write(')'); - break; - case '\\': - baos.write('\\'); - break; + break; + case '\\': + baos.write('\\'); + break; } } else baos.write(bytes[index]); @@ -198,92 +228,91 @@ public class PdfPublicKeySecurityHandler { } return baos.toByteArray(); } - + public void addRecipient(PdfPublicKeyRecipient recipient) { recipients.add(recipient); } - + protected byte[] getSeed() { - return (byte[])seed.clone(); + return (byte[]) seed.clone(); } /* public PdfPublicKeyRecipient[] getRecipients() { recipients.toArray(); return (PdfPublicKeyRecipient[])recipients.toArray(); }*/ - + public int getRecipientsSize() { return recipients.size(); } - + public byte[] getEncodedRecipient(int index) throws IOException, GeneralSecurityException { //Certificate certificate = recipient.getX509(); - PdfPublicKeyRecipient recipient = (PdfPublicKeyRecipient)recipients.get(index); + PdfPublicKeyRecipient recipient = (PdfPublicKeyRecipient) recipients.get(index); byte[] cms = recipient.getCms(); - + if (cms != null) return cms; - - Certificate certificate = recipient.getCertificate(); - int permission = recipient.getPermission();//PdfWriter.AllowCopy | PdfWriter.AllowPrinting | PdfWriter.AllowScreenReaders | PdfWriter.AllowAssembly; + + Certificate certificate = recipient.getCertificate(); + int permission = recipient.getPermission();//PdfWriter.AllowCopy | PdfWriter.AllowPrinting | PdfWriter.AllowScreenReaders | PdfWriter.AllowAssembly; int revision = 3; - - permission |= revision==3 ? 0xfffff0c0 : 0xffffffc0; + + permission |= revision == 3 ? 0xfffff0c0 : 0xffffffc0; permission &= 0xfffffffc; permission += 1; - + byte[] pkcs7input = new byte[24]; - - byte one = (byte)(permission); - byte two = (byte)(permission >> 8); - byte three = (byte)(permission >> 16); - byte four = (byte)(permission >> 24); + + byte one = (byte) (permission); + byte two = (byte) (permission >> 8); + byte three = (byte) (permission >> 16); + byte four = (byte) (permission >> 24); System.arraycopy(seed, 0, pkcs7input, 0, 20); // put this seed in the pkcs7 input - + pkcs7input[20] = four; - pkcs7input[21] = three; + pkcs7input[21] = three; pkcs7input[22] = two; pkcs7input[23] = one; - - ASN1Object obj = createDERForRecipient(pkcs7input, (X509Certificate)certificate); - + + ASN1Object obj = createDERForRecipient(pkcs7input, (X509Certificate) certificate); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - DEROutputStream k = new DEROutputStream(baos); - - k.writeObject(obj); - + + ASN1OutputStream k = ASN1OutputStream.create(baos); + + k.writeObject(obj); + cms = baos.toByteArray(); recipient.setCms(cms); - - return cms; + + return cms; } - - public PdfArray getEncodedRecipients() throws IOException, - GeneralSecurityException { + + public PdfArray getEncodedRecipients() throws IOException, + GeneralSecurityException { PdfArray EncodedRecipients = new PdfArray(); byte[] cms = null; - for (int i=0; inull for the default provider - */ + * @param certsKey the /Cert key + * @param provider the provider or null for the default provider + */ public PdfPKCS7(byte[] contentsKey, byte[] certsKey, String provider) { try { this.provider = provider; @@ -304,73 +302,72 @@ public class PdfPKCS7 { cr.engineInit(new ByteArrayInputStream(certsKey)); certs = cr.engineReadAll(); signCerts = certs; - signCert = (X509Certificate)certs.iterator().next(); + signCert = (X509Certificate) certs.iterator().next(); crls = new ArrayList(); ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream(contentsKey)); - digest = ((DEROctetString)in.readObject()).getOctets(); + digest = ((DEROctetString) in.readObject()).getOctets(); if (provider == null) sig = Signature.getInstance("SHA1withRSA"); else sig = Signature.getInstance("SHA1withRSA", provider); sig.initVerify(signCert.getPublicKey()); - } - catch (Exception e) { + } catch (Exception e) { throw new ExceptionConverter(e); } } - + // private BasicOCSPResp basicResp; - + /** * Gets the OCSP basic response if there is one. + * * @return the OCSP basic response or null - * @since 2.1.6 + * @since 2.1.6 */ // public BasicOCSPResp getOcsp() { // return basicResp; // } - 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; for (int k = 0; k < seq.size(); ++k) { if (seq.getObjectAt(k) instanceof ASN1Sequence) { - seq = (ASN1Sequence)seq.getObjectAt(0); + seq = (ASN1Sequence) seq.getObjectAt(0); ret = false; break; } if (seq.getObjectAt(k) instanceof ASN1TaggedObject) { - ASN1TaggedObject tag = (ASN1TaggedObject)seq.getObjectAt(k); + ASN1TaggedObject tag = (ASN1TaggedObject) seq.getObjectAt(k); if (tag.getObject() instanceof ASN1Sequence) { - seq = (ASN1Sequence)tag.getObject(); + seq = (ASN1Sequence) tag.getObject(); ret = false; break; - } - else + } else return; } } if (ret) return; } - DEROctetString os = (DEROctetString)seq.getObjectAt(1); + DEROctetString os = (DEROctetString) seq.getObjectAt(1); ASN1InputStream inp = new ASN1InputStream(os.getOctets()); BasicOCSPResponse resp = BasicOCSPResponse.getInstance(inp.readObject()); // basicResp = new BasicOCSPResp(resp); } - + /** * Verifies a signature using the sub-filter adbe.pkcs7.detached or * adbe.pkcs7.sha1. + * * @param contentsKey the /Contents key - * @param provider the provider or null for the default provider - */ + * @param provider the provider or null for the default provider + */ public PdfPKCS7(byte[] contentsKey, String provider) { try { this.provider = provider; @@ -383,18 +380,17 @@ public class PdfPKCS7 { try { pkcs = din.readObject(); - } - catch (IOException e) { + } catch (IOException e) { throw new IllegalArgumentException("can't decode PKCS7SignedData object"); } if (!(pkcs instanceof ASN1Sequence)) { throw new IllegalArgumentException("Not a valid PKCS#7 object - not a sequence"); } - ASN1Sequence signedData = (ASN1Sequence)pkcs; - DERObjectIdentifier objId = (DERObjectIdentifier)signedData.getObjectAt(0); + ASN1Sequence signedData = (ASN1Sequence) pkcs; + 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(); + ASN1Sequence content = (ASN1Sequence) ((DERTaggedObject) signedData.getObjectAt(1)).getObject(); // the positions that we care are: // 0 - version // 1 - digestAlgorithms @@ -403,15 +399,14 @@ public class PdfPKCS7 { // last - signerInfos // the version - version = ((DERInteger)content.getObjectAt(0)).getValue().intValue(); + version = ((ASN1Integer) content.getObjectAt(0)).getValue().intValue(); // the digestAlgorithms digestalgos = new HashSet(); - Enumeration e = ((ASN1Set)content.getObjectAt(1)).getObjects(); - while (e.hasMoreElements()) - { - ASN1Sequence s = (ASN1Sequence)e.nextElement(); - DERObjectIdentifier o = (DERObjectIdentifier)s.getObjectAt(0); + Enumeration e = ((ASN1Set) content.getObjectAt(1)).getObjects(); + while (e.hasMoreElements()) { + ASN1Sequence s = (ASN1Sequence) e.nextElement(); + ASN1ObjectIdentifier o = (ASN1ObjectIdentifier) s.getObjectAt(0); digestalgos.add(o.getId()); } @@ -424,9 +419,9 @@ public class PdfPKCS7 { crls = cl.engineReadAll(); // the possible ID_PKCS7_DATA - ASN1Sequence rsaData = (ASN1Sequence)content.getObjectAt(2); + ASN1Sequence rsaData = (ASN1Sequence) content.getObjectAt(2); if (rsaData.size() > 1) { - DEROctetString rsaDataContent = (DEROctetString)((DERTaggedObject)rsaData.getObjectAt(1)).getObject(); + DEROctetString rsaDataContent = (DEROctetString) ((DERTaggedObject) rsaData.getObjectAt(1)).getObject(); RSAdata = rsaDataContent.getOctets(); } @@ -434,22 +429,22 @@ public class PdfPKCS7 { int next = 3; while (content.getObjectAt(next) instanceof DERTaggedObject) ++next; - ASN1Set signerInfos = (ASN1Set)content.getObjectAt(next); + ASN1Set signerInfos = (ASN1Set) content.getObjectAt(next); if (signerInfos.size() != 1) throw new IllegalArgumentException("This PKCS#7 object has multiple SignerInfos - only one is supported at this time"); - ASN1Sequence signerInfo = (ASN1Sequence)signerInfos.getObjectAt(0); + ASN1Sequence signerInfo = (ASN1Sequence) signerInfos.getObjectAt(0); // the positions that we care are // 0 - version // 1 - the signing certificate serial number // 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(); - for (Iterator i = certs.iterator(); i.hasNext();) { - X509Certificate cert = (X509Certificate)i.next(); + ASN1Sequence issuerAndSerialNumber = (ASN1Sequence) signerInfo.getObjectAt(1); + BigInteger serialNumber = ((ASN1Integer) issuerAndSerialNumber.getObjectAt(1)).getValue(); + for (Iterator i = certs.iterator(); i.hasNext(); ) { + X509Certificate cert = (X509Certificate) i.next(); if (serialNumber.equals(cert.getSerialNumber())) { signCert = cert; break; @@ -459,27 +454,26 @@ public class PdfPKCS7 { 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); + ASN1TaggedObject tagsig = (ASN1TaggedObject) signerInfo.getObjectAt(next); ASN1Set sseq = ASN1Set.getInstance(tagsig, false); 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)) { - ASN1Set set = (ASN1Set)seq2.getObjectAt(1); - digestAttr = ((DEROctetString)set.getObjectAt(0)).getOctets(); - } - else if (((DERObjectIdentifier)seq2.getObjectAt(0)).getId().equals(ID_ADBE_REVOCATION)) { - ASN1Set setout = (ASN1Set)seq2.getObjectAt(1); - ASN1Sequence seqout = (ASN1Sequence)setout.getObjectAt(0); + ASN1Sequence seq2 = (ASN1Sequence) sseq.getObjectAt(k); + if (((ASN1ObjectIdentifier) seq2.getObjectAt(0)).getId().equals(ID_MESSAGE_DIGEST)) { + ASN1Set set = (ASN1Set) seq2.getObjectAt(1); + digestAttr = ((DEROctetString) set.getObjectAt(0)).getOctets(); + } 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) { - ASN1TaggedObject tg = (ASN1TaggedObject)seqout.getObjectAt(j); + ASN1TaggedObject tg = (ASN1TaggedObject) seqout.getObjectAt(j); if (tg.getTagNo() != 1) continue; - ASN1Sequence seqin = (ASN1Sequence)tg.getObject(); + ASN1Sequence seqin = (ASN1Sequence) tg.getObject(); findOcsp(seqin); } } @@ -488,8 +482,8 @@ public class PdfPKCS7 { throw new IllegalArgumentException("Authenticated attribute is missing the digest."); ++next; } - digestEncryptionAlgorithm = ((DERObjectIdentifier)((ASN1Sequence)signerInfo.getObjectAt(next++)).getObjectAt(0)).getId(); - digest = ((DEROctetString)signerInfo.getObjectAt(next++)).getOctets(); + 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); ASN1Set unat = ASN1Set.getInstance(taggedObject, false); @@ -513,56 +507,55 @@ public class PdfPKCS7 { else sig = Signature.getInstance(getDigestAlgorithm(), provider); sig.initVerify(signCert.getPublicKey()); - } - catch (Exception e) { + } catch (Exception e) { throw new ExceptionConverter(e); } } /** * Generates a signature. - * @param privKey the private key - * @param certChain the certificate chain - * @param crlList the certificate revocation list + * + * @param privKey the private key + * @param certChain the certificate chain + * @param crlList the certificate revocation list * @param hashAlgorithm the hash algorithm - * @param provider the provider or null for the default provider - * @param hasRSAdata true if the sub-filter is adbe.pkcs7.sha1 - * @throws InvalidKeyException on error - * @throws NoSuchProviderException on error + * @param provider the provider or null for the default provider + * @param hasRSAdata true if the sub-filter is adbe.pkcs7.sha1 + * @throws InvalidKeyException on error + * @throws NoSuchProviderException on error * @throws NoSuchAlgorithmException on error - */ + */ public PdfPKCS7(PrivateKey privKey, Certificate[] certChain, CRL[] crlList, String hashAlgorithm, String provider, boolean hasRSAdata) - throws InvalidKeyException, NoSuchProviderException, - NoSuchAlgorithmException - { + throws InvalidKeyException, NoSuchProviderException, + NoSuchAlgorithmException { this.privKey = privKey; this.provider = provider; - - digestAlgorithm = (String)allowedDigests.get(hashAlgorithm.toUpperCase()); + + digestAlgorithm = (String) allowedDigests.get(hashAlgorithm.toUpperCase()); if (digestAlgorithm == null) - throw new NoSuchAlgorithmException("Unknown Hash Algorithm "+hashAlgorithm); - + throw new NoSuchAlgorithmException("Unknown Hash Algorithm " + hashAlgorithm); + version = signerversion = 1; certs = new ArrayList(); crls = new ArrayList(); digestalgos = new HashSet(); digestalgos.add(digestAlgorithm); - + // // Copy in the certificates and crls used to sign the private key. // - signCert = (X509Certificate)certChain[0]; - for (int i = 0;i < certChain.length;i++) { + signCert = (X509Certificate) certChain[0]; + for (int i = 0; i < certChain.length; i++) { certs.add(certChain[i]); } - + if (crlList != null) { - for (int i = 0;i < crlList.length;i++) { + for (int i = 0; i < crlList.length; i++) { crls.add(crlList[i]); } } - + if (privKey != null) { // // Now we have private key, find out what the digestEncryptionAlgorithm is. @@ -570,12 +563,10 @@ public class PdfPKCS7 { digestEncryptionAlgorithm = privKey.getAlgorithm(); if (digestEncryptionAlgorithm.equals("RSA")) { digestEncryptionAlgorithm = ID_RSA; - } - else if (digestEncryptionAlgorithm.equals("DSA")) { + } else if (digestEncryptionAlgorithm.equals("DSA")) { digestEncryptionAlgorithm = ID_DSA; - } - else { - throw new NoSuchAlgorithmException("Unknown Key Algorithm "+digestEncryptionAlgorithm); + } else { + throw new NoSuchAlgorithmException("Unknown Key Algorithm " + digestEncryptionAlgorithm); } } if (hasRSAdata) { @@ -598,6 +589,7 @@ public class PdfPKCS7 { /** * Update the digest with the specified bytes. This method is used both for signing and verifying + * * @param buf the data buffer * @param off the offset in the data buffer * @param len the data length @@ -609,11 +601,12 @@ public class PdfPKCS7 { else sig.update(buf, off, len); } - + /** * Verify the digest. - * @throws SignatureException on error + * * @return true if the signature checks out, false otherwise + * @throws SignatureException on error */ public boolean verify() throws SignatureException { if (verified) @@ -625,8 +618,7 @@ public class PdfPKCS7 { messageDigest.update(msd); } verifyResult = (Arrays.equals(messageDigest.digest(), digestAttr) && sig.verify(digest)); - } - else { + } else { if (RSAdata != null) sig.update(messageDigest.digest()); verifyResult = sig.verify(digest); @@ -634,12 +626,12 @@ public class PdfPKCS7 { verified = true; return verifyResult; } - + /** * Checks if the timestamp refers to this document. * @throws java.security.NoSuchAlgorithmException on error * @return true if it checks false otherwise - * @since 2.1.6 + * @since 2.1.6 */ // public boolean verifyTimestampImprint() throws NoSuchAlgorithmException { // if (timeStampToken == null) @@ -650,33 +642,35 @@ public class PdfPKCS7 { // boolean res = Arrays.equals(md, imphashed); // return res; // } - + /** * Get all the X.509 certificates associated with this PKCS#7 object in no particular order. * Other certificates, from OCSP for example, will also be included. + * * @return the X.509 certificates associated with this PKCS#7 object */ public Certificate[] getCertificates() { - return (X509Certificate[])certs.toArray(new X509Certificate[certs.size()]); + return (X509Certificate[]) certs.toArray(new X509Certificate[certs.size()]); } - + /** * Get the X.509 sign certificate chain associated with this PKCS#7 object. * Only the certificates used for the main signature will be returned, with * the signing certificate first. + * * @return the X.509 certificates associated with this PKCS#7 object - * @since 2.1.6 + * @since 2.1.6 */ public Certificate[] getSignCertificateChain() { - return (X509Certificate[])signCerts.toArray(new X509Certificate[signCerts.size()]); + return (X509Certificate[]) signCerts.toArray(new X509Certificate[signCerts.size()]); } - + private void signCertificateChain() { ArrayList cc = new ArrayList(); cc.add(signCert); ArrayList oc = new ArrayList(certs); for (int k = 0; k < oc.size(); ++k) { - if (signCert.getSerialNumber().equals(((X509Certificate)oc.get(k)).getSerialNumber())) { + if (signCert.getSerialNumber().equals(((X509Certificate) oc.get(k)).getSerialNumber())) { oc.remove(k); --k; continue; @@ -684,72 +678,77 @@ public class PdfPKCS7 { } boolean found = true; while (found) { - X509Certificate v = (X509Certificate)cc.get(cc.size() - 1); + X509Certificate v = (X509Certificate) cc.get(cc.size() - 1); found = false; for (int k = 0; k < oc.size(); ++k) { try { if (provider == null) - v.verify(((X509Certificate)oc.get(k)).getPublicKey()); + v.verify(((X509Certificate) oc.get(k)).getPublicKey()); else - v.verify(((X509Certificate)oc.get(k)).getPublicKey(), provider); + v.verify(((X509Certificate) oc.get(k)).getPublicKey(), provider); found = true; cc.add(oc.get(k)); oc.remove(k); break; - } - catch (Exception e) { + } catch (Exception e) { } } } signCerts = cc; } - + /** * Get the X.509 certificate revocation lists associated with this PKCS#7 object + * * @return the X.509 certificate revocation lists associated with this PKCS#7 object */ public Collection getCRLs() { return crls; } - + /** * Get the X.509 certificate actually used to sign the digest. + * * @return the X.509 certificate actually used to sign the digest */ public X509Certificate getSigningCertificate() { return signCert; } - + /** * Get the version of the PKCS#7 object. Always 1 + * * @return the version of the PKCS#7 object. Always 1 */ public int getVersion() { return version; } - + /** * Get the version of the PKCS#7 "SignerInfo" object. Always 1 + * * @return the version of the PKCS#7 "SignerInfo" object. Always 1 */ public int getSigningInfoVersion() { return signerversion; } - + /** * Get the algorithm used to calculate the message digest + * * @return the algorithm used to calculate the message digest */ public String getDigestAlgorithm() { String dea = getAlgorithm(digestEncryptionAlgorithm); if (dea == null) dea = digestEncryptionAlgorithm; - + return getHashAlgorithm() + "with" + dea; } /** * Returns the algorithm. + * * @return the digest algorithm */ public String getHashAlgorithm() { @@ -759,17 +758,19 @@ public class PdfPKCS7 { /** * Loads the default root certificates at <java.home>/lib/security/cacerts * with the default provider. + * * @return a KeyStore - */ + */ public static KeyStore loadCacertsKeyStore() { return loadCacertsKeyStore(null); } /** * Loads the default root certificates at <java.home>/lib/security/cacerts. + * * @param provider the provider or null for the default provider * @return a KeyStore - */ + */ public static KeyStore loadCacertsKeyStore(String provider) { File file = new File(System.getProperty("java.home"), "lib"); file = new File(file, "security"); @@ -784,23 +785,27 @@ public class PdfPKCS7 { k = KeyStore.getInstance("JKS", provider); k.load(fin, null); return k; - } - catch (Exception e) { + } catch (Exception e) { throw new ExceptionConverter(e); - } - finally { - try{if (fin != null) {fin.close();}}catch(Exception ex){} + } finally { + try { + if (fin != null) { + fin.close(); + } + } catch (Exception ex) { + } } } - + /** * Verifies a single certificate. - * @param cert the certificate to verify - * @param crls the certificate revocation list or null + * + * @param cert the certificate to verify + * @param crls the certificate revocation list or null * @param calendar the date or null for the current date * @return a String with the error description or null * if no error - */ + */ public static String verifyCertificate(X509Certificate cert, Collection crls, Calendar calendar) { if (calendar == null) calendar = new GregorianCalendar(); @@ -808,70 +813,66 @@ public class PdfPKCS7 { return "Has unsupported critical extension"; try { cert.checkValidity(calendar.getTime()); - } - catch (Exception e) { + } catch (Exception e) { return e.getMessage(); } if (crls != null) { - for (Iterator it = crls.iterator(); it.hasNext();) { - if (((CRL)it.next()).isRevoked(cert)) + for (Iterator it = crls.iterator(); it.hasNext(); ) { + if (((CRL) it.next()).isRevoked(cert)) return "Certificate revoked"; } } return null; } - + /** * Verifies a certificate chain against a KeyStore. - * @param certs the certificate chain + * + * @param certs the certificate chain * @param keystore the KeyStore - * @param crls the certificate revocation list or null + * @param crls the certificate revocation list or null * @param calendar the date or null for the current date * @return null if the certificate chain could be validated or a * Object[]{cert,error} where cert is the * failed certificate and error is the error message - */ + */ public static Object[] verifyCertificates(Certificate certs[], KeyStore keystore, Collection crls, Calendar calendar) { if (calendar == null) calendar = new GregorianCalendar(); for (int k = 0; k < certs.length; ++k) { - X509Certificate cert = (X509Certificate)certs[k]; + X509Certificate cert = (X509Certificate) certs[k]; String err = verifyCertificate(cert, crls, calendar); if (err != null) return new Object[]{cert, err}; try { - for (Enumeration aliases = keystore.aliases(); aliases.hasMoreElements();) { + 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); + X509Certificate certStoreX509 = (X509Certificate) keystore.getCertificate(alias); if (verifyCertificate(certStoreX509, crls, calendar) != null) continue; try { cert.verify(certStoreX509.getPublicKey()); return null; - } - catch (Exception e) { + } catch (Exception e) { continue; } - } - catch (Exception ex) { + } catch (Exception ex) { } } - } - catch (Exception e) { + } catch (Exception e) { } int j; for (j = 0; j < certs.length; ++j) { if (j == k) continue; - X509Certificate certNext = (X509Certificate)certs[j]; + X509Certificate certNext = (X509Certificate) certs[j]; try { cert.verify(certNext.getPublicKey()); break; - } - catch (Exception e) { + } catch (Exception e) { } } if (j == certs.length) @@ -886,8 +887,8 @@ public class PdfPKCS7 { * @param keystore the KeyStore * @param provider the provider or null to use the BouncyCastle provider * @return true is a certificate was found - * @since 2.1.6 - */ + * @since 2.1.6 + */ // public static boolean verifyOcspCertificates(BasicOCSPResp ocsp, KeyStore keystore, String provider) { // if (provider == null) // provider = "BC"; @@ -909,15 +910,15 @@ public class PdfPKCS7 { // } // return false; // } - + /** * Verifies a timestamp against a KeyStore. * @param ts the timestamp * @param keystore the KeyStore * @param provider the provider or null to use the BouncyCastle provider * @return true is a certificate was found - * @since 2.1.6 - */ + * @since 2.1.6 + */ // public static boolean verifyTimestampCertificates(TimeStampToken ts, KeyStore keystore, String provider) { // if (provider == null) // provider = "BC"; @@ -939,13 +940,14 @@ public class PdfPKCS7 { // } // return false; // } - + /** * Retrieves the OCSP URL from the given certificate. + * * @param certificate the certificate * @return the URL or null * @throws CertificateParsingException on error - * @since 2.1.6 + * @since 2.1.6 */ public static String getOCSPURL(X509Certificate certificate) throws CertificateParsingException { try { @@ -953,32 +955,33 @@ public class PdfPKCS7 { if (obj == null) { return null; } - + ASN1Sequence AccessDescriptions = (ASN1Sequence) obj; for (int i = 0; i < AccessDescriptions.size(); i++) { ASN1Sequence AccessDescription = (ASN1Sequence) AccessDescriptions.getObjectAt(i); - if ( AccessDescription.size() != 2 ) { + 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((ASN1Object)AccessDescription.getObjectAt(1)); - if ( AccessLocation == null ) { - return "" ; + 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 { - return AccessLocation ; + return AccessLocation; } } } } - } catch (Exception e) { + } catch (Exception e) { } return null; } - + /** * Checks if OCSP revocation refers to the document signing certificate. + * * @return true if it checks false otherwise - * @since 2.1.6 + * @since 2.1.6 */ // public boolean isRevocationValid() { // if (basicResp == null) @@ -998,7 +1001,6 @@ public class PdfPKCS7 { // } // return false; // } - private static ASN1Object getExtensionValue(X509Certificate cert, String oid) throws IOException { byte[] bytes = cert.getExtensionValue(oid); if (bytes == null) { @@ -1009,74 +1011,75 @@ public class PdfPKCS7 { aIn = new ASN1InputStream(new ByteArrayInputStream(octs.getOctets())); return aIn.readObject(); } - + private static String getStringFromGeneralName(ASN1Object names) throws IOException { - DERTaggedObject taggedObject = (DERTaggedObject) names ; + DERTaggedObject taggedObject = (DERTaggedObject) names; return new String(ASN1OctetString.getInstance(taggedObject, false).getOctets(), "ISO-8859-1"); } /** * Get the "issuer" from the TBSCertificate bytes that are passed in + * * @param enc a TBSCertificate in a byte array * @return a DERObject */ private static ASN1Object getIssuer(byte[] enc) { try { ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream(enc)); - ASN1Sequence seq = (ASN1Sequence)in.readObject(); - return (ASN1Object)seq.getObjectAt(seq.getObjectAt(0) instanceof DERTaggedObject ? 3 : 2); - } - catch (IOException e) { + ASN1Sequence seq = (ASN1Sequence) in.readObject(); + return (ASN1Object) seq.getObjectAt(seq.getObjectAt(0) instanceof DERTaggedObject ? 3 : 2); + } catch (IOException e) { throw new ExceptionConverter(e); } } /** * Get the "subject" from the TBSCertificate bytes that are passed in + * * @param enc A TBSCertificate in a byte array * @return a DERObject */ private static ASN1Object getSubject(byte[] enc) { try { ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream(enc)); - ASN1Sequence seq = (ASN1Sequence)in.readObject(); - return (ASN1Object)seq.getObjectAt(seq.getObjectAt(0) instanceof DERTaggedObject ? 5 : 4); - } - catch (IOException e) { + ASN1Sequence seq = (ASN1Sequence) in.readObject(); + return (ASN1Object) seq.getObjectAt(seq.getObjectAt(0) instanceof DERTaggedObject ? 5 : 4); + } catch (IOException e) { throw new ExceptionConverter(e); } } /** * Get the issuer fields from an X509 Certificate + * * @param cert an X509Certificate * @return an X509Name */ public static X509Name getIssuerFields(X509Certificate cert) { try { - return new X509Name((ASN1Sequence)getIssuer(cert.getTBSCertificate())); - } - catch (Exception e) { + return new X509Name((ASN1Sequence) getIssuer(cert.getTBSCertificate())); + } catch (Exception e) { throw new ExceptionConverter(e); } } /** * Get the subject fields from an X509 Certificate + * * @param cert an X509Certificate * @return an X509Name */ public static X509Name getSubjectFields(X509Certificate cert) { try { - return new X509Name((ASN1Sequence)getSubject(cert.getTBSCertificate())); - } - catch (Exception e) { + return new X509Name((ASN1Sequence) getSubject(cert.getTBSCertificate())); + } catch (Exception e) { throw new ExceptionConverter(e); } } - + /** * Gets the bytes for the PKCS#1 object. + * * @return a byte array */ public byte[] getEncodedPKCS1() { @@ -1085,55 +1088,55 @@ public class PdfPKCS7 { digest = externalDigest; else digest = sig.sign(); - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ASN1OutputStream dout = new ASN1OutputStream(bOut); dout.writeObject(new DEROctetString(digest)); dout.close(); - + return bOut.toByteArray(); - } - catch (Exception e) { + } catch (Exception e) { throw new ExceptionConverter(e); } } - + /** * Sets the digest/signature to an external calculated value. - * @param digest the digest. This is the actual signature - * @param RSAdata the extra data that goes into the data tag in PKCS#7 + * + * @param digest the digest. This is the actual signature + * @param RSAdata the extra data that goes into the data tag in PKCS#7 * @param digestEncryptionAlgorithm the encryption algorithm. It may must be null if the digest - * is also null. If the digest is not null - * then it may be "RSA" or "DSA" - */ + * is also null. If the digest is not null + * then it may be "RSA" or "DSA" + */ public void setExternalDigest(byte digest[], byte RSAdata[], String digestEncryptionAlgorithm) { externalDigest = digest; externalRSAdata = RSAdata; if (digestEncryptionAlgorithm != null) { if (digestEncryptionAlgorithm.equals("RSA")) { this.digestEncryptionAlgorithm = ID_RSA; - } - else if (digestEncryptionAlgorithm.equals("DSA")) { + } else if (digestEncryptionAlgorithm.equals("DSA")) { this.digestEncryptionAlgorithm = ID_DSA; - } - else - throw new ExceptionConverter(new NoSuchAlgorithmException("Unknown Key Algorithm "+digestEncryptionAlgorithm)); + } else + throw new ExceptionConverter(new NoSuchAlgorithmException("Unknown Key Algorithm " + digestEncryptionAlgorithm)); } } - + /** * Gets the bytes for the PKCS7SignedData object. + * * @return the bytes for the PKCS7SignedData object */ public byte[] getEncodedPKCS7() { return getEncodedPKCS7(null, null, null, null); } - + /** * Gets the bytes for the PKCS7SignedData object. Optionally the authenticatedAttributes * in the signerInfo can also be set. If either of the parameters is null, none will be used. + * * @param secondDigest the digest in the authenticatedAttributes - * @param signingTime the signing time in the authenticatedAttributes + * @param signingTime the signing time in the authenticatedAttributes * @return the bytes for the PKCS7SignedData object */ public byte[] getEncodedPKCS7(byte secondDigest[], Calendar signingTime) { @@ -1144,11 +1147,12 @@ public class PdfPKCS7 { * Gets the bytes for the PKCS7SignedData object. Optionally the authenticatedAttributes * in the signerInfo can also be set, OR a time-stamp-authority client * may be provided. + * * @param secondDigest the digest in the authenticatedAttributes - * @param signingTime the signing time in the authenticatedAttributes - * @param tsaClient TSAClient - null or an optional time stamp authority client + * @param signingTime the signing time in the authenticatedAttributes + * @param tsaClient TSAClient - null or an optional time stamp authority client * @return byte[] the bytes for the PKCS7SignedData object - * @since 2.1.6 + * @since 2.1.6 */ public byte[] getEncodedPKCS7(byte secondDigest[], Calendar signingTime, TSAClient tsaClient, byte[] ocsp) { try { @@ -1156,78 +1160,76 @@ public class PdfPKCS7 { digest = externalDigest; if (RSAdata != null) RSAdata = externalRSAdata; - } - else if (externalRSAdata != null && RSAdata != null) { + } else if (externalRSAdata != null && RSAdata != null) { RSAdata = externalRSAdata; sig.update(RSAdata); digest = sig.sign(); - } - else { + } else { if (RSAdata != null) { RSAdata = messageDigest.digest(); sig.update(RSAdata); } digest = sig.sign(); } - + // Create the set of Hash algorithms ASN1EncodableVector digestAlgorithms = new ASN1EncodableVector(); - for(Iterator it = digestalgos.iterator(); it.hasNext();) { + 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); - + // Get all the certificates // v = new ASN1EncodableVector(); - for (Iterator i = certs.iterator(); i.hasNext();) { - ASN1InputStream tempstream = new ASN1InputStream(new ByteArrayInputStream(((X509Certificate)i.next()).getEncoded())); + for (Iterator i = certs.iterator(); i.hasNext(); ) { + ASN1InputStream tempstream = new ASN1InputStream(new ByteArrayInputStream(((X509Certificate) i.next()).getEncoded())); v.add(tempstream.readObject()); } - + DERSet dercertificates = new DERSet(v); - + // Create signerinfo structure. // ASN1EncodableVector signerinfo = new ASN1EncodableVector(); - + // 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 if (secondDigest != null && signingTime != null) { signerinfo.add(new DERTaggedObject(false, 0, getAuthenticatedAttributeSet(secondDigest, signingTime, ocsp))); } // 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 signerinfo.add(new DEROctetString(digest)); - + // When requested, go get and add the timestamp. May throw an exception. // Added by Martin Brunecky, 07/12/2007 folowing Aiken Sam, 2006-11-15 // Sam found Adobe expects time-stamped SHA1-1 of the encrypted digest @@ -1241,57 +1243,57 @@ public class PdfPKCS7 { } } } - + // 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)); - - if (!crls.isEmpty()) { + + if (!crls.isEmpty()) { v = new ASN1EncodableVector(); - for (Iterator i = crls.iterator();i.hasNext();) { - ASN1InputStream t = new ASN1InputStream(new ByteArrayInputStream(((X509CRL)i.next()).getEncoded())); + for (Iterator i = crls.iterator(); i.hasNext(); ) { + ASN1InputStream t = new ASN1InputStream(new ByteArrayInputStream(((X509CRL) i.next()).getEncoded())); v.add(t.readObject()); } DERSet dercrls = new DERSet(v); body.add(new DERTaggedObject(false, 1, dercrls)); } - + // Only allow one signerInfo body.add(new DERSet(new DERSequence(signerinfo))); - + // Now we have the body, wrap it in it's PKCS7Signed shell // 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(); - + + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + ASN1OutputStream dout = new ASN1OutputStream(bOut); dout.writeObject(new DERSequence(whole)); dout.close(); - + return bOut.toByteArray(); - } - catch (Exception e) { + } catch (Exception e) { throw new ExceptionConverter(e); } } - + /** * Added by Aiken Sam, 2006-11-15, modifed by Martin Brunecky 07/12/2007 * to start with the timeStampToken (signedData 1.2.840.113549.1.7.2). * Token is the TSA response without response status, which is usually * handled by the (vendor supplied) TSA request/response interface). + * * @param timeStampToken byte[] - time stamp token, DER encoded signedData * @return ASN1EncodableVector * @throws IOException */ - private ASN1EncodableVector buildUnauthenticatedAttributes(byte[] timeStampToken) throws IOException { + private ASN1EncodableVector buildUnauthenticatedAttributes(byte[] timeStampToken) throws IOException { if (timeStampToken == null) return null; @@ -1302,20 +1304,20 @@ public class PdfPKCS7 { 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)); unauthAttributes.add(new DERSequence(v)); return unauthAttributes; - } + } + - /** * When using authenticatedAttributes the authentication process is different. * The document digest is generated and put inside the attribute. The signing is done over the DER encoded * authenticatedAttributes. This method provides that encoding and the parameters must be - * exactly the same as in {@link #getEncodedPKCS7(byte[],Calendar)}. + * exactly the same as in {@link #getEncodedPKCS7(byte[], Calendar)}. *

* A simple example: *

@@ -1334,132 +1336,138 @@ public class PdfPKCS7 { * pk7.update(sh, 0, sh.length); * byte sg[] = pk7.getEncodedPKCS7(hash, cal); * + * * @param secondDigest the content digest - * @param signingTime the signing time + * @param signingTime the signing time * @return the byte array representation of the authenticatedAttributes ready to be signed - */ + */ public byte[] getAuthenticatedAttributeBytes(byte secondDigest[], Calendar signingTime, byte[] ocsp) { try { return getAuthenticatedAttributeSet(secondDigest, signingTime, ocsp).getEncoded("DER"); - } - catch (Exception e) { + } catch (Exception e) { throw new ExceptionConverter(e); } } - + private DERSet getAuthenticatedAttributeSet(byte secondDigest[], Calendar signingTime, byte[] ocsp) { 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))); vo1.add(new DERSequence(v3)); v.add(new DERSet(new DERSequence(new DERTaggedObject(true, 1, new DERSequence(vo1))))); attribute.add(new DERSequence(v)); - } - else if (!crls.isEmpty()) { + } 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())); + for (Iterator i = crls.iterator(); i.hasNext(); ) { + ASN1InputStream t = new ASN1InputStream(new ByteArrayInputStream(((X509CRL) i.next()).getEncoded())); v2.add(t.readObject()); } v.add(new DERSet(new DERSequence(new DERTaggedObject(true, 0, new DERSequence(v2))))); attribute.add(new DERSequence(v)); } return new DERSet(attribute); - } - catch (Exception e) { + } catch (Exception e) { throw new ExceptionConverter(e); } } - + /** * Getter for property reason. + * * @return Value of property reason. */ public String getReason() { return this.reason; } - + /** * Setter for property reason. + * * @param reason New value of property reason. */ public void setReason(String reason) { this.reason = reason; } - + /** * Getter for property location. + * * @return Value of property location. */ public String getLocation() { return this.location; } - + /** * Setter for property location. + * * @param location New value of property location. */ public void setLocation(String location) { this.location = location; } - + /** * Getter for property signDate. + * * @return Value of property signDate. */ public Calendar getSignDate() { return this.signDate; } - + /** * Setter for property signDate. + * * @param signDate New value of property signDate. */ public void setSignDate(Calendar signDate) { this.signDate = signDate; } - + /** * Getter for property sigName. + * * @return Value of property sigName. */ public String getSignName() { return this.signName; } - + /** * Setter for property sigName. + * * @param signName New value of property sigName. */ public void setSignName(String signName) { this.signName = signName; } - + /** * a class that holds an X509 name */ @@ -1467,74 +1475,90 @@ public class PdfPKCS7 { /** * 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"); - - /** Naming attribute of type X520name */ - public static final DERObjectIdentifier SURNAME = new DERObjectIdentifier("2.5.4.4"); - /** Naming attribute of type X520name */ - public static final DERObjectIdentifier GIVENNAME = new DERObjectIdentifier("2.5.4.42"); - /** Naming attribute of type X520name */ - public static final DERObjectIdentifier INITIALS = new DERObjectIdentifier("2.5.4.43"); - /** Naming attribute of type X520name */ - public static final DERObjectIdentifier GENERATION = new DERObjectIdentifier("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 ST = new ASN1ObjectIdentifier("2.5.4.8"); + + /** + * Naming attribute of type X520name + */ + public static final ASN1ObjectIdentifier SURNAME = new ASN1ObjectIdentifier("2.5.4.4"); + /** + * Naming attribute of type X520name + */ + public static final ASN1ObjectIdentifier GIVENNAME = new ASN1ObjectIdentifier("2.5.4.42"); + /** + * Naming attribute of type X520name + */ + public static final ASN1ObjectIdentifier INITIALS = new ASN1ObjectIdentifier("2.5.4.43"); + /** + * Naming attribute of type X520name + */ + public static final ASN1ObjectIdentifier GENERATION = new ASN1ObjectIdentifier("2.5.4.44"); + /** + * Naming attribute of type X520name + */ + 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"); + /** + * object identifier + */ + 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"); + /** + * LDAP User id. + */ + public static final ASN1ObjectIdentifier UID = new ASN1ObjectIdentifier("0.9.2342.19200300.100.1.1"); - /** A HashMap with default symbols */ + /** + * A HashMap with default symbols + */ public static HashMap DefaultSymbols = new HashMap(); - + static { DefaultSymbols.put(C, "C"); DefaultSymbols.put(O, "O"); @@ -1552,83 +1576,91 @@ public class PdfPKCS7 { DefaultSymbols.put(INITIALS, "INITIALS"); DefaultSymbols.put(GENERATION, "GENERATION"); } - /** A HashMap with values */ + + /** + * A HashMap with values + */ public HashMap values = new HashMap(); /** * Constructs an X509 name + * * @param seq an ASN1 Sequence */ public X509Name(ASN1Sequence seq) { Enumeration e = seq.getObjects(); - + while (e.hasMoreElements()) { - ASN1Set set = (ASN1Set)e.nextElement(); - + ASN1Set set = (ASN1Set) e.nextElement(); + for (int i = 0; i < set.size(); i++) { - ASN1Sequence s = (ASN1Sequence)set.getObjectAt(i); - String id = (String)DefaultSymbols.get(s.getObjectAt(0)); + ASN1Sequence s = (ASN1Sequence) set.getObjectAt(i); + String id = (String) DefaultSymbols.get(s.getObjectAt(0)); if (id == null) continue; - ArrayList vs = (ArrayList)values.get(id); + ArrayList vs = (ArrayList) values.get(id); if (vs == null) { vs = new ArrayList(); values.put(id, vs); } - vs.add(((ASN1String)s.getObjectAt(1)).getString()); + vs.add(((ASN1String) s.getObjectAt(1)).getString()); } } } + /** * Constructs an X509 name + * * @param dirName a directory name */ public X509Name(String dirName) { - X509NameTokenizer nTok = new X509NameTokenizer(dirName); - + X509NameTokenizer nTok = new X509NameTokenizer(dirName); + while (nTok.hasMoreTokens()) { - String token = nTok.nextToken(); + String token = nTok.nextToken(); int index = token.indexOf('='); - + if (index == -1) { throw new IllegalArgumentException("badly formated directory string"); } - + String id = token.substring(0, index).toUpperCase(); String value = token.substring(index + 1); - ArrayList vs = (ArrayList)values.get(id); + ArrayList vs = (ArrayList) values.get(id); if (vs == null) { vs = new ArrayList(); values.put(id, vs); } vs.add(value); } - + } - + public String getField(String name) { - ArrayList vs = (ArrayList)values.get(name); - return vs == null ? null : (String)vs.get(0); + ArrayList vs = (ArrayList) values.get(name); + return vs == null ? null : (String) vs.get(0); } /** * gets a field array from the values Hashmap + * * @param name * @return an ArrayList */ public ArrayList getFieldArray(String name) { - ArrayList vs = (ArrayList)values.get(name); + ArrayList vs = (ArrayList) values.get(name); return vs == null ? null : vs; } - + /** * getter for values + * * @return a HashMap with the fields of the X509 name */ public HashMap getFields() { return values; } - + /** * @see java.lang.Object#toString() */ @@ -1636,7 +1668,7 @@ public class PdfPKCS7 { return values.toString(); } } - + /** * class for breaking up an X500 Name into it's component tokens, ala * java.util.StringTokenizer. We need this class as some of the @@ -1644,61 +1676,56 @@ public class PdfPKCS7 { * StringTokenizer. */ public static class X509NameTokenizer { - private String oid; - private int index; - private StringBuffer buf = new StringBuffer(); - + private String oid; + private int index; + private StringBuffer buf = new StringBuffer(); + public X509NameTokenizer( - String oid) { + String oid) { this.oid = oid; this.index = -1; } - + public boolean hasMoreTokens() { return (index != oid.length()); } - + public String nextToken() { if (index == oid.length()) { return null; } - - int end = index + 1; + + int end = index + 1; boolean quoted = false; boolean escaped = false; - + buf.setLength(0); - + while (end != oid.length()) { - char c = oid.charAt(end); - + char c = oid.charAt(end); + if (c == '"') { if (!escaped) { quoted = !quoted; - } - else { + } else { buf.append(c); } escaped = false; - } - else { + } else { if (escaped || quoted) { buf.append(c); escaped = false; - } - else if (c == '\\') { + } else if (c == '\\') { escaped = true; - } - else if (c == ',') { + } else if (c == ',') { break; - } - else { + } else { buf.append(c); } } end++; } - + index = end; return buf.toString().trim(); } diff --git a/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/pdf/PdfPublicKeySecurityHandler.java b/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/pdf/PdfPublicKeySecurityHandler.java index 1c5fc76f1..99c47bac3 100644 --- a/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/pdf/PdfPublicKeySecurityHandler.java +++ b/fine-itext/src/main/java/com/fr/third/v2/lowagie/text/pdf/PdfPublicKeySecurityHandler.java @@ -48,12 +48,124 @@ */ /** - * The below 2 methods are from pdfbox. - * - * private DERObject createDERForRecipient(byte[] in, X509Certificate cert) ; - * private KeyTransRecipientInfo computeRecipientInfo(X509Certificate x509certificate, byte[] abyte0); - * - * 2006-11-22 Aiken Sam. + * The below 2 methods are from pdfbox. + *

+ * private DERObject createDERForRecipient(byte[] in, X509Certificate cert) ; + * private KeyTransRecipientInfo computeRecipientInfo(X509Certificate x509certificate, byte[] abyte0); + *

+ * 2006-11-22 Aiken Sam. + *

+ * Copyright (c) 2003-2006, www.pdfbox.org + * All rights reserved. + *

+ * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + *

+ * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *

+ * http://www.pdfbox.org + *

+ * Copyright (c) 2003-2006, www.pdfbox.org + * All rights reserved. + *

+ * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + *

+ * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *

+ * http://www.pdfbox.org + *

+ * Copyright (c) 2003-2006, www.pdfbox.org + * All rights reserved. + *

+ * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + *

+ * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *

+ * http://www.pdfbox.org + *

+ * Copyright (c) 2003-2006, www.pdfbox.org + * All rights reserved. + *

+ * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + *

+ * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of pdfbox; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + *

+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *

+ * http://www.pdfbox.org */ /** @@ -90,7 +202,9 @@ package com.fr.third.v2.lowagie.text.pdf; import com.fr.third.org.bouncycastle.asn1.ASN1Object; +import com.fr.third.org.bouncycastle.asn1.ASN1OutputStream; import com.fr.third.org.bouncycastle.asn1.ASN1Set; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -110,9 +224,8 @@ import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import com.fr.third.org.bouncycastle.asn1.ASN1InputStream; -import com.fr.third.org.bouncycastle.asn1.DERObjectIdentifier; +import com.fr.third.org.bouncycastle.asn1.ASN1ObjectIdentifier; import com.fr.third.org.bouncycastle.asn1.DEROctetString; -import com.fr.third.org.bouncycastle.asn1.DEROutputStream; import com.fr.third.org.bouncycastle.asn1.DERSet; import com.fr.third.org.bouncycastle.asn1.cms.ContentInfo; import com.fr.third.org.bouncycastle.asn1.cms.EncryptedContentInfo; @@ -129,11 +242,11 @@ import com.fr.third.org.bouncycastle.asn1.x509.TBSCertificateStructure; * @author Aiken Sam (aikensam@ieee.org) */ public class PdfPublicKeySecurityHandler { - + static final int SEED_LENGTH = 20; - + private ArrayList recipients = null; - + private byte[] seed = new byte[SEED_LENGTH]; public PdfPublicKeySecurityHandler() { @@ -141,56 +254,57 @@ public class PdfPublicKeySecurityHandler { try { key = KeyGenerator.getInstance("AES"); key.init(192, new SecureRandom()); - SecretKey sk = key.generateKey(); + SecretKey sk = key.generateKey(); System.arraycopy(sk.getEncoded(), 0, seed, 0, SEED_LENGTH); // create the 20 bytes seed } catch (NoSuchAlgorithmException e) { - seed = SecureRandom.getSeed(SEED_LENGTH); + seed = SecureRandom.getSeed(SEED_LENGTH); } - + recipients = new ArrayList(); } - /* + /* * Routine for decode output of PdfContentByte.escapeString(byte[] bytes). - * It should be moved to PdfContentByte. + * It should be moved to PdfContentByte. */ - + static public byte[] unescapedString(byte[] bytes) throws BadPdfFormatException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); - + int index = 0; - - if (bytes[0] != '(' && bytes[bytes.length-1] != ')') throw new BadPdfFormatException("Expect '(' and ')' at begin and end of the string."); - + + if (bytes[0] != '(' && bytes[bytes.length - 1] != ')') + throw new BadPdfFormatException("Expect '(' and ')' at begin and end of the string."); + while (index < bytes.length) { if (bytes[index] == '\\') { index++; switch (bytes[index]) { - case 'b': - baos.write('\b'); - break; - case 'f': - baos.write('\f'); - break; - case 't': - baos.write('\t'); - break; - case 'n': - baos.write('\n'); - break; - case 'r': - baos.write('\r'); - break; - case '(': + case 'b': + baos.write('\b'); + break; + case 'f': + baos.write('\f'); + break; + case 't': + baos.write('\t'); + break; + case 'n': + baos.write('\n'); + break; + case 'r': + baos.write('\r'); + break; + case '(': baos.write('('); break; - case ')': + case ')': baos.write(')'); - break; - case '\\': - baos.write('\\'); - break; + break; + case '\\': + baos.write('\\'); + break; } } else baos.write(bytes[index]); @@ -198,92 +312,91 @@ public class PdfPublicKeySecurityHandler { } return baos.toByteArray(); } - + public void addRecipient(PdfPublicKeyRecipient recipient) { recipients.add(recipient); } - + protected byte[] getSeed() { - return (byte[])seed.clone(); + return (byte[]) seed.clone(); } /* public PdfPublicKeyRecipient[] getRecipients() { recipients.toArray(); return (PdfPublicKeyRecipient[])recipients.toArray(); }*/ - + public int getRecipientsSize() { return recipients.size(); } - + public byte[] getEncodedRecipient(int index) throws IOException, GeneralSecurityException { //Certificate certificate = recipient.getX509(); - PdfPublicKeyRecipient recipient = (PdfPublicKeyRecipient)recipients.get(index); + PdfPublicKeyRecipient recipient = (PdfPublicKeyRecipient) recipients.get(index); byte[] cms = recipient.getCms(); - + if (cms != null) return cms; - - Certificate certificate = recipient.getCertificate(); - int permission = recipient.getPermission();//PdfWriter.AllowCopy | PdfWriter.AllowPrinting | PdfWriter.AllowScreenReaders | PdfWriter.AllowAssembly; + + Certificate certificate = recipient.getCertificate(); + int permission = recipient.getPermission();//PdfWriter.AllowCopy | PdfWriter.AllowPrinting | PdfWriter.AllowScreenReaders | PdfWriter.AllowAssembly; int revision = 3; - - permission |= revision==3 ? 0xfffff0c0 : 0xffffffc0; + + permission |= revision == 3 ? 0xfffff0c0 : 0xffffffc0; permission &= 0xfffffffc; permission += 1; - + byte[] pkcs7input = new byte[24]; - - byte one = (byte)(permission); - byte two = (byte)(permission >> 8); - byte three = (byte)(permission >> 16); - byte four = (byte)(permission >> 24); + + byte one = (byte) (permission); + byte two = (byte) (permission >> 8); + byte three = (byte) (permission >> 16); + byte four = (byte) (permission >> 24); System.arraycopy(seed, 0, pkcs7input, 0, 20); // put this seed in the pkcs7 input - + pkcs7input[20] = four; - pkcs7input[21] = three; + pkcs7input[21] = three; pkcs7input[22] = two; pkcs7input[23] = one; - - ASN1Object obj = createDERForRecipient(pkcs7input, (X509Certificate)certificate); - + + ASN1Object obj = createDERForRecipient(pkcs7input, (X509Certificate) certificate); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - DEROutputStream k = new DEROutputStream(baos); - - k.writeObject(obj); - + + ASN1OutputStream k = ASN1OutputStream.create(baos); + + k.writeObject(obj); + cms = baos.toByteArray(); recipient.setCms(cms); - - return cms; + + return cms; } - - public PdfArray getEncodedRecipients() throws IOException, - GeneralSecurityException { + + public PdfArray getEncodedRecipients() throws IOException, + GeneralSecurityException { PdfArray EncodedRecipients = new PdfArray(); byte[] cms = null; - for (int i=0; i