001/* 002 * $Id: PdfSigGenericPKCS.java 4790 2011-04-01 20:49:40Z psoares33 $ 003 * 004 * This file is part of the iText (R) project. 005 * Copyright (c) 1998-2011 1T3XT BVBA 006 * Authors: Bruno Lowagie, Paulo Soares, et al. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU Affero General Public License version 3 010 * as published by the Free Software Foundation with the addition of the 011 * following permission added to Section 15 as permitted in Section 7(a): 012 * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY 1T3XT, 013 * 1T3XT DISCLAIMS THE WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. 014 * 015 * This program is distributed in the hope that it will be useful, but 016 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 017 * or FITNESS FOR A PARTICULAR PURPOSE. 018 * See the GNU Affero General Public License for more details. 019 * You should have received a copy of the GNU Affero General Public License 020 * along with this program; if not, see http://www.gnu.org/licenses or write to 021 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 022 * Boston, MA, 02110-1301 USA, or download the license from the following URL: 023 * http://itextpdf.com/terms-of-use/ 024 * 025 * The interactive user interfaces in modified source and object code versions 026 * of this program must display Appropriate Legal Notices, as required under 027 * Section 5 of the GNU Affero General Public License. 028 * 029 * In accordance with Section 7(b) of the GNU Affero General Public License, 030 * a covered work must retain the producer line in every PDF that is created 031 * or manipulated using iText. 032 * 033 * You can be released from the requirements of the license by purchasing 034 * a commercial license. Buying such a license is mandatory as soon as you 035 * develop commercial activities involving the iText software without 036 * disclosing the source code of your own applications. 037 * These activities include: offering paid services to customers as an ASP, 038 * serving PDFs on the fly in a web application, shipping iText with a closed 039 * source product. 040 * 041 * For more information, please contact iText Software Corp. at this 042 * address: sales@itextpdf.com 043 */ 044package com.itextpdf.text.pdf; 045 046import java.io.ByteArrayOutputStream; 047import java.security.PrivateKey; 048import java.security.cert.CRL; 049import java.security.cert.Certificate; 050 051import com.itextpdf.text.ExceptionConverter; 052 053/** 054 * A signature dictionary representation for the standard filters. 055 */ 056public abstract class PdfSigGenericPKCS extends PdfSignature { 057 /** 058 * The hash algorithm, for example "SHA1" 059 */ 060 protected String hashAlgorithm; 061 /** 062 * The crypto provider 063 */ 064 protected String provider = null; 065 /** 066 * The class instance that calculates the PKCS#1 and PKCS#7 067 */ 068 protected PdfPKCS7 pkcs; 069 /** 070 * The subject name in the signing certificate (the element "CN") 071 */ 072 protected String name; 073 074 private byte externalDigest[]; 075 private byte externalRSAdata[]; 076 private String digestEncryptionAlgorithm; 077 078 /** 079 * Creates a generic standard filter. 080 * @param filter the filter name 081 * @param subFilter the sub-filter name 082 */ 083 public PdfSigGenericPKCS(PdfName filter, PdfName subFilter) { 084 super(filter, subFilter); 085 } 086 087 /** 088 * Sets the crypto information to sign. 089 * @param privKey the private key 090 * @param certChain the certificate chain 091 * @param crlList the certificate revocation list. It can be <CODE>null</CODE> 092 */ 093 public void setSignInfo(PrivateKey privKey, Certificate[] certChain, CRL[] crlList) { 094 try { 095 pkcs = new PdfPKCS7(privKey, certChain, crlList, hashAlgorithm, provider, PdfName.ADBE_PKCS7_SHA1.equals(get(PdfName.SUBFILTER))); 096 pkcs.setExternalDigest(externalDigest, externalRSAdata, digestEncryptionAlgorithm); 097 if (PdfName.ADBE_X509_RSA_SHA1.equals(get(PdfName.SUBFILTER))) { 098 if (certChain.length > 1) { 099 PdfArray arr = new PdfArray(); 100 for (int ii = 0; ii < certChain.length; ii++) { 101 arr.add(new PdfString(certChain[ii].getEncoded())); 102 } 103 put(PdfName.CERT, arr); 104 } 105 else { 106 ByteArrayOutputStream bout = new ByteArrayOutputStream(); 107 for (int k = 0; k < certChain.length; ++k) { 108 bout.write(certChain[k].getEncoded()); 109 } 110 bout.close(); 111 setCert(bout.toByteArray()); 112 } 113 setContents(pkcs.getEncodedPKCS1()); 114 } 115 else 116 setContents(pkcs.getEncodedPKCS7()); 117 name = PdfPKCS7.getSubjectFields(pkcs.getSigningCertificate()).getField("CN"); 118 if (name != null) 119 put(PdfName.NAME, new PdfString(name, PdfObject.TEXT_UNICODE)); 120 pkcs = new PdfPKCS7(privKey, certChain, crlList, hashAlgorithm, provider, PdfName.ADBE_PKCS7_SHA1.equals(get(PdfName.SUBFILTER))); 121 pkcs.setExternalDigest(externalDigest, externalRSAdata, digestEncryptionAlgorithm); 122 } 123 catch (Exception e) { 124 throw new ExceptionConverter(e); 125 } 126 } 127 128 /** 129 * Sets the digest/signature to an external calculated value. 130 * @param digest the digest. This is the actual signature 131 * @param RSAdata the extra data that goes into the data tag in PKCS#7 132 * @param digestEncryptionAlgorithm the encryption algorithm. It may must be <CODE>null</CODE> if the <CODE>digest</CODE> 133 * is also <CODE>null</CODE>. If the <CODE>digest</CODE> is not <CODE>null</CODE> 134 * then it may be "RSA" or "DSA" 135 */ 136 public void setExternalDigest(byte digest[], byte RSAdata[], String digestEncryptionAlgorithm) { 137 externalDigest = digest; 138 externalRSAdata = RSAdata; 139 this.digestEncryptionAlgorithm = digestEncryptionAlgorithm; 140 } 141 142 /** 143 * Gets the subject name in the signing certificate (the element "CN") 144 * @return the subject name in the signing certificate (the element "CN") 145 */ 146 public String getName() { 147 return name; 148 } 149 150 /** 151 * Gets the class instance that does the actual signing. 152 * @return the class instance that does the actual signing 153 */ 154 public PdfPKCS7 getSigner() { 155 return pkcs; 156 } 157 158 /** 159 * Gets the signature content. This can be a PKCS#1 or a PKCS#7. It corresponds to 160 * the /Contents key. 161 * @return the signature content 162 */ 163 public byte[] getSignerContents() { 164 if (PdfName.ADBE_X509_RSA_SHA1.equals(get(PdfName.SUBFILTER))) 165 return pkcs.getEncodedPKCS1(); 166 else 167 return pkcs.getEncodedPKCS7(); 168 } 169 170 /** 171 * Creates a standard filter of the type VeriSign. 172 */ 173 public static class VeriSign extends PdfSigGenericPKCS { 174 /** 175 * The constructor for the default provider. 176 */ 177 public VeriSign() { 178 super(PdfName.VERISIGN_PPKVS, PdfName.ADBE_PKCS7_DETACHED); 179 hashAlgorithm = "MD5"; 180 put(PdfName.R, new PdfNumber(65537)); 181 } 182 183 /** 184 * The constructor for an explicit provider. 185 * @param provider the crypto provider 186 */ 187 public VeriSign(String provider) { 188 this(); 189 this.provider = provider; 190 } 191 } 192 193 /** 194 * Creates a standard filter of the type self signed. 195 */ 196 public static class PPKLite extends PdfSigGenericPKCS { 197 /** 198 * The constructor for the default provider. 199 */ 200 public PPKLite() { 201 super(PdfName.ADOBE_PPKLITE, PdfName.ADBE_X509_RSA_SHA1); 202 hashAlgorithm = "SHA1"; 203 put(PdfName.R, new PdfNumber(65541)); 204 } 205 206 /** 207 * The constructor for an explicit provider. 208 * @param provider the crypto provider 209 */ 210 public PPKLite(String provider) { 211 this(); 212 this.provider = provider; 213 } 214 } 215 216 /** 217 * Creates a standard filter of the type Windows Certificate. 218 */ 219 public static class PPKMS extends PdfSigGenericPKCS { 220 /** 221 * The constructor for the default provider. 222 */ 223 public PPKMS() { 224 super(PdfName.ADOBE_PPKMS, PdfName.ADBE_PKCS7_SHA1); 225 hashAlgorithm = "SHA1"; 226 } 227 228 /** 229 * The constructor for an explicit provider. 230 * @param provider the crypto provider 231 */ 232 public PPKMS(String provider) { 233 this(); 234 this.provider = provider; 235 } 236 } 237}