1 50 51 59 60 90 91 package com.lowagie.text.pdf; 92 93 import java.io.ByteArrayInputStream ; 94 import java.io.ByteArrayOutputStream ; 95 import java.io.IOException ; 96 97 import java.security.AlgorithmParameterGenerator ; 98 import java.security.AlgorithmParameters ; 99 import java.security.GeneralSecurityException ; 100 import java.security.NoSuchAlgorithmException ; 101 import java.security.SecureRandom ; 102 import java.security.cert.Certificate ; 103 import java.security.cert.X509Certificate ; 104 105 import java.util.ArrayList ; 106 107 import javax.crypto.Cipher; 108 import javax.crypto.KeyGenerator; 109 import javax.crypto.SecretKey; 110 111 import org.bouncycastle.asn1.ASN1InputStream; 112 import org.bouncycastle.asn1.DERObject; 113 import org.bouncycastle.asn1.DERObjectIdentifier; 114 import org.bouncycastle.asn1.DEROctetString; 115 import org.bouncycastle.asn1.DEROutputStream; 116 import org.bouncycastle.asn1.DERSet; 117 import org.bouncycastle.asn1.cms.ContentInfo; 118 import org.bouncycastle.asn1.cms.EncryptedContentInfo; 119 import org.bouncycastle.asn1.cms.EnvelopedData; 120 import org.bouncycastle.asn1.cms.IssuerAndSerialNumber; 121 import org.bouncycastle.asn1.cms.KeyTransRecipientInfo; 122 import org.bouncycastle.asn1.cms.RecipientIdentifier; 123 import org.bouncycastle.asn1.cms.RecipientInfo; 124 import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 125 import org.bouncycastle.asn1.x509.AlgorithmIdentifier; 126 import org.bouncycastle.asn1.x509.TBSCertificateStructure; 127 128 131 public class PdfPublicKeySecurityHandler { 132 133 static final int SEED_LENGTH = 20; 134 135 private ArrayList recipients = null; 136 137 private byte[] seed = new byte[SEED_LENGTH]; 138 139 public PdfPublicKeySecurityHandler() { 140 KeyGenerator key; 141 try { 142 key = KeyGenerator.getInstance("AES"); 143 key.init(192, new SecureRandom ()); 144 SecretKey sk = key.generateKey(); 145 System.arraycopy(sk.getEncoded(), 0, seed, 0, SEED_LENGTH); } catch (NoSuchAlgorithmException e) { 147 seed = SecureRandom.getSeed(SEED_LENGTH); 148 } 149 150 recipients = new ArrayList (); 151 } 152 153 154 158 159 static public byte[] unescapedString(byte[] bytes) throws BadPdfFormatException { 160 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 161 162 int index = 0; 163 164 if (bytes[0] != '(' && bytes[bytes.length-1] != ')') throw new BadPdfFormatException("Expect '(' and ')' at begin and end of the string."); 165 166 while (index < bytes.length) { 167 if (bytes[index] == '\\') { 168 index++; 169 switch (bytes[index]) { 170 case 'b': 171 baos.write('\b'); 172 break; 173 case 'f': 174 baos.write('\f'); 175 break; 176 case 't': 177 baos.write('\t'); 178 break; 179 case 'n': 180 baos.write('\n'); 181 break; 182 case 'r': 183 baos.write('\r'); 184 break; 185 case '(': 186 baos.write('('); 187 break; 188 case ')': 189 baos.write(')'); 190 break; 191 case '\\': 192 baos.write('\\'); 193 break; 194 } 195 } else 196 baos.write(bytes[index]); 197 index++; 198 } 199 return baos.toByteArray(); 200 } 201 202 public void addRecipient(PdfPublicKeyRecipient recipient) { 203 recipients.add(recipient); 204 } 205 206 protected byte[] getSeed() { 207 return (byte[])seed.clone(); 208 } 209 214 215 public int getRecipientsSize() { 216 return recipients.size(); 217 } 218 219 public byte[] getEncodedRecipient(int index) throws IOException , GeneralSecurityException { 220 PdfPublicKeyRecipient recipient = (PdfPublicKeyRecipient)recipients.get(index); 222 byte[] cms = recipient.getCms(); 223 224 if (cms != null) return cms; 225 226 Certificate certificate = recipient.getCertificate(); 227 int permission = recipient.getPermission(); int revision = 3; 229 230 permission |= revision==3 ? 0xfffff0c0 : 0xffffffc0; 231 permission &= 0xfffffffc; 232 permission += 1; 233 234 byte[] pkcs7input = new byte[24]; 235 236 byte one = (byte)(permission); 237 byte two = (byte)(permission >> 8); 238 byte three = (byte)(permission >> 16); 239 byte four = (byte)(permission >> 24); 240 241 System.arraycopy(seed, 0, pkcs7input, 0, 20); 243 pkcs7input[20] = four; 244 pkcs7input[21] = three; 245 pkcs7input[22] = two; 246 pkcs7input[23] = one; 247 248 DERObject obj = createDERForRecipient(pkcs7input, (X509Certificate )certificate); 249 250 ByteArrayOutputStream baos = new ByteArrayOutputStream (); 251 252 DEROutputStream k = new DEROutputStream(baos); 253 254 k.writeObject(obj); 255 256 cms = baos.toByteArray(); 257 258 recipient.setCms(cms); 259 260 return cms; 261 } 262 263 public PdfArray getEncodedRecipients() throws IOException , 264 GeneralSecurityException { 265 PdfArray EncodedRecipients = new PdfArray(); 266 byte[] cms = null; 267 for (int i=0; i<recipients.size(); i++) 268 try { 269 cms = getEncodedRecipient(i); 270 EncodedRecipients.add(new PdfLiteral(PdfContentByte.escapeString(cms))); 271 } catch (GeneralSecurityException e) { 272 EncodedRecipients = null; 273 } catch (IOException e) { 274 EncodedRecipients = null; 275 } 276 277 return EncodedRecipients; 278 } 279 280 private DERObject createDERForRecipient(byte[] in, X509Certificate cert) 281 throws IOException , 282 GeneralSecurityException 283 { 284 285 String s = "1.2.840.113549.3.2"; 286 287 AlgorithmParameterGenerator algorithmparametergenerator = AlgorithmParameterGenerator.getInstance(s); 288 AlgorithmParameters algorithmparameters = algorithmparametergenerator.generateParameters(); 289 ByteArrayInputStream bytearrayinputstream = new ByteArrayInputStream (algorithmparameters.getEncoded("ASN.1")); 290 ASN1InputStream asn1inputstream = new ASN1InputStream(bytearrayinputstream); 291 DERObject derobject = asn1inputstream.readObject(); 292 KeyGenerator keygenerator = KeyGenerator.getInstance(s); 293 keygenerator.init(128); 294 SecretKey secretkey = keygenerator.generateKey(); 295 Cipher cipher = Cipher.getInstance(s); 296 cipher.init(1, secretkey, algorithmparameters); 297 byte[] abyte1 = cipher.doFinal(in); 298 DEROctetString deroctetstring = new DEROctetString(abyte1); 299 KeyTransRecipientInfo keytransrecipientinfo = computeRecipientInfo(cert, secretkey.getEncoded()); 300 DERSet derset = new DERSet(new RecipientInfo(keytransrecipientinfo)); 301 AlgorithmIdentifier algorithmidentifier = new AlgorithmIdentifier(new DERObjectIdentifier(s), derobject); 302 EncryptedContentInfo encryptedcontentinfo = 303 new EncryptedContentInfo(PKCSObjectIdentifiers.data, algorithmidentifier, deroctetstring); 304 EnvelopedData env = new EnvelopedData(null, derset, encryptedcontentinfo, null); 305 ContentInfo contentinfo = 306 new ContentInfo(PKCSObjectIdentifiers.envelopedData, env); 307 return contentinfo.getDERObject(); 308 } 309 310 private KeyTransRecipientInfo computeRecipientInfo(X509Certificate x509certificate, byte[] abyte0) 311 throws GeneralSecurityException , IOException 312 { 313 ASN1InputStream asn1inputstream = 314 new ASN1InputStream(new ByteArrayInputStream (x509certificate.getTBSCertificate())); 315 TBSCertificateStructure tbscertificatestructure = 316 TBSCertificateStructure.getInstance(asn1inputstream.readObject()); 317 AlgorithmIdentifier algorithmidentifier = tbscertificatestructure.getSubjectPublicKeyInfo().getAlgorithmId(); 318 IssuerAndSerialNumber issuerandserialnumber = 319 new IssuerAndSerialNumber( 320 tbscertificatestructure.getIssuer(), 321 tbscertificatestructure.getSerialNumber().getValue()); 322 Cipher cipher = Cipher.getInstance(algorithmidentifier.getObjectId().getId()); 323 cipher.init(1, x509certificate); 324 DEROctetString deroctetstring = new DEROctetString(cipher.doFinal(abyte0)); 325 RecipientIdentifier recipId = new RecipientIdentifier(issuerandserialnumber); 326 return new KeyTransRecipientInfo( recipId, algorithmidentifier, deroctetstring); 327 } 328 } 329 | Popular Tags |