1 47 package com.lowagie.text.pdf; 48 49 import java.io.ByteArrayInputStream ; 50 import java.io.ByteArrayOutputStream ; 51 import java.io.File ; 52 import java.io.FileInputStream ; 53 import java.io.IOException ; 54 import java.security.InvalidKeyException ; 55 import java.security.KeyStore ; 56 import java.security.MessageDigest ; 57 import java.security.NoSuchAlgorithmException ; 58 import java.security.NoSuchProviderException ; 59 import java.security.PrivateKey ; 60 import java.security.Signature ; 61 import java.security.SignatureException ; 62 import java.security.cert.CRL ; 63 import java.security.cert.CRLException ; 64 import java.security.cert.Certificate ; 65 import java.security.cert.CertificateException ; 66 import java.security.cert.X509CRL ; 67 import java.security.cert.X509Certificate ; 68 import java.util.ArrayList ; 69 import java.util.Arrays ; 70 import java.util.Calendar ; 71 import java.util.Collection ; 72 import java.util.Enumeration ; 73 import java.util.GregorianCalendar ; 74 import java.util.HashMap ; 75 import java.util.HashSet ; 76 import java.util.Iterator ; 77 import java.util.Set ; 78 79 import com.lowagie.text.ExceptionConverter; 80 import java.math.BigInteger ; 81 import org.bouncycastle.asn1.ASN1EncodableVector; 82 import org.bouncycastle.asn1.ASN1InputStream; 83 import org.bouncycastle.asn1.ASN1OutputStream; 84 import org.bouncycastle.asn1.ASN1Sequence; 85 import org.bouncycastle.asn1.ASN1Set; 86 import org.bouncycastle.asn1.ASN1TaggedObject; 87 import org.bouncycastle.asn1.DERConstructedSet; 88 import org.bouncycastle.asn1.DERInteger; 89 import org.bouncycastle.asn1.DERNull; 90 import org.bouncycastle.asn1.DERObject; 91 import org.bouncycastle.asn1.DERObjectIdentifier; 92 import org.bouncycastle.asn1.DEROctetString; 93 import org.bouncycastle.asn1.DERSequence; 94 import org.bouncycastle.asn1.DERSet; 95 import org.bouncycastle.asn1.DERString; 96 import org.bouncycastle.asn1.DERTaggedObject; 97 import org.bouncycastle.asn1.DERUTCTime; 98 import org.bouncycastle.jce.provider.X509CRLParser; 99 import org.bouncycastle.jce.provider.X509CertParser; 100 import org.bouncycastle.util.StreamParsingException; 101 102 108 public class PdfPKCS7 { 109 110 private byte sigAttr[]; 111 private byte digestAttr[]; 112 private int version, signerversion; 113 private Set digestalgos; 114 private Collection certs, crls; 115 private X509Certificate signCert; 116 private byte[] digest; 117 private MessageDigest messageDigest; 118 private String digestAlgorithm, digestEncryptionAlgorithm; 119 private Signature sig; 120 private transient PrivateKey privKey; 121 private byte RSAdata[]; 122 private boolean verified; 123 private boolean verifyResult; 124 private byte externalDigest[]; 125 private byte externalRSAdata[]; 126 127 private static final String ID_PKCS7_DATA = "1.2.840.113549.1.7.1"; 128 private static final String ID_PKCS7_SIGNED_DATA = "1.2.840.113549.1.7.2"; 129 private static final String ID_MD5 = "1.2.840.113549.2.5"; 130 private static final String ID_MD2 = "1.2.840.113549.2.2"; 131 private static final String ID_SHA1 = "1.3.14.3.2.26"; 132 private static final String ID_RSA = "1.2.840.113549.1.1.1"; 133 private static final String ID_DSA = "1.2.840.10040.4.1"; 134 private static final String ID_CONTENT_TYPE = "1.2.840.113549.1.9.3"; 135 private static final String ID_MESSAGE_DIGEST = "1.2.840.113549.1.9.4"; 136 private static final String ID_SIGNING_TIME = "1.2.840.113549.1.9.5"; 137 private static final String ID_MD2RSA = "1.2.840.113549.1.1.2"; 138 private static final String ID_MD5RSA = "1.2.840.113549.1.1.4"; 139 private static final String ID_SHA1RSA = "1.2.840.113549.1.1.5"; 140 private static final String ID_ADBE_REVOCATION = "1.2.840.113583.1.1.8"; 141 144 private String reason; 145 146 149 private String location; 150 151 154 private Calendar signDate; 155 156 159 private String signName; 160 161 173 public PdfPKCS7(byte[] contentsKey, byte[] certsKey, String provider) throws SecurityException , InvalidKeyException , CertificateException , NoSuchProviderException , NoSuchAlgorithmException , IOException , StreamParsingException { 174 X509CertParser cr = new X509CertParser(); 175 cr.engineInit(new ByteArrayInputStream (certsKey)); 176 certs = cr.engineReadAll(); 177 signCert = (X509Certificate )certs.iterator().next(); 178 crls = new ArrayList (); 179 ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream (contentsKey)); 180 digest = ((DEROctetString)in.readObject()).getOctets(); 181 if (provider == null) 182 sig = Signature.getInstance("SHA1withRSA"); 183 else 184 sig = Signature.getInstance("SHA1withRSA", provider); 185 sig.initVerify(signCert.getPublicKey()); 186 } 187 188 200 public PdfPKCS7(byte[] contentsKey, String provider) throws SecurityException , CRLException , InvalidKeyException , CertificateException , NoSuchProviderException , NoSuchAlgorithmException , StreamParsingException { 201 ASN1InputStream din = new ASN1InputStream(new ByteArrayInputStream (contentsKey)); 202 203 DERObject pkcs; 207 208 try { 209 pkcs = din.readObject(); 210 } 211 catch (IOException e) { 212 throw new SecurityException ("can't decode PKCS7SignedData object"); 213 } 214 if (!(pkcs instanceof ASN1Sequence)) { 215 throw new SecurityException ("Not a valid PKCS#7 object - not a sequence"); 216 } 217 ASN1Sequence signedData = (ASN1Sequence)pkcs; 218 DERObjectIdentifier objId = (DERObjectIdentifier)signedData.getObjectAt(0); 219 if (!objId.getId().equals(ID_PKCS7_SIGNED_DATA)) 220 throw new SecurityException ("Not a valid PKCS#7 object - not signed data"); 221 ASN1Sequence content = (ASN1Sequence)((DERTaggedObject)signedData.getObjectAt(1)).getObject(); 222 229 version = ((DERInteger)content.getObjectAt(0)).getValue().intValue(); 231 232 digestalgos = new HashSet (); 234 Enumeration e = ((ASN1Set)content.getObjectAt(1)).getObjects(); 235 while (e.hasMoreElements()) 236 { 237 ASN1Sequence s = (ASN1Sequence)e.nextElement(); 238 DERObjectIdentifier o = (DERObjectIdentifier)s.getObjectAt(0); 239 digestalgos.add(o.getId()); 240 } 241 242 X509CertParser cr = new X509CertParser(); 244 cr.engineInit(new ByteArrayInputStream (contentsKey)); 245 certs = cr.engineReadAll(); 246 X509CRLParser cl = new X509CRLParser(); 247 cl.engineInit(new ByteArrayInputStream (contentsKey)); 248 crls = cl.engineReadAll(); 249 250 ASN1Sequence rsaData = (ASN1Sequence)content.getObjectAt(2); 252 if (rsaData.size() > 1) { 253 DEROctetString rsaDataContent = (DEROctetString)((DERTaggedObject)rsaData.getObjectAt(1)).getObject(); 254 RSAdata = rsaDataContent.getOctets(); 255 } 256 257 int next = 3; 259 while (content.getObjectAt(next) instanceof DERTaggedObject) 260 ++next; 261 ASN1Set signerInfos = (ASN1Set)content.getObjectAt(next); 262 if (signerInfos.size() != 1) 263 throw new SecurityException ("This PKCS#7 object has multiple SignerInfos - only one is supported at this time"); 264 ASN1Sequence signerInfo = (ASN1Sequence)signerInfos.getObjectAt(0); 265 signerversion = ((DERInteger)signerInfo.getObjectAt(0)).getValue().intValue(); 272 ASN1Sequence issuerAndSerialNumber = (ASN1Sequence)signerInfo.getObjectAt(1); 274 BigInteger serialNumber = ((DERInteger)issuerAndSerialNumber.getObjectAt(1)).getValue(); 275 for (Iterator i = certs.iterator(); i.hasNext();) { 276 X509Certificate cert = (X509Certificate )i.next(); 277 if (serialNumber.equals(cert.getSerialNumber())) { 278 signCert = cert; 279 break; 280 } 281 } 282 if (signCert == null) { 283 throw new SecurityException ("Can't find signing certificate with serial " + serialNumber.toString(16)); 284 } 285 digestAlgorithm = ((DERObjectIdentifier)((ASN1Sequence)signerInfo.getObjectAt(2)).getObjectAt(0)).getId(); 286 next = 3; 287 if (signerInfo.getObjectAt(next) instanceof ASN1TaggedObject) { 288 ASN1TaggedObject tagsig = (ASN1TaggedObject)signerInfo.getObjectAt(next); 289 ASN1Sequence sseq = (ASN1Sequence)tagsig.getObject(); 290 ByteArrayOutputStream bOut = new ByteArrayOutputStream (); 291 ASN1OutputStream dout = new ASN1OutputStream(bOut); 292 try { 293 ASN1EncodableVector attribute = new ASN1EncodableVector(); 294 for (int k = 0; k < sseq.size(); ++k) { 295 attribute.add(sseq.getObjectAt(k)); 296 } 297 dout.writeObject(new DERSet(attribute)); 298 dout.close(); 299 } 300 catch (IOException ioe){} 301 sigAttr = bOut.toByteArray(); 302 303 for (int k = 0; k < sseq.size(); ++k) { 304 ASN1Sequence seq2 = (ASN1Sequence)sseq.getObjectAt(k); 305 if (((DERObjectIdentifier)seq2.getObjectAt(0)).getId().equals(ID_MESSAGE_DIGEST)) { 306 ASN1Set set = (ASN1Set)seq2.getObjectAt(1); 307 digestAttr = ((DEROctetString)set.getObjectAt(0)).getOctets(); 308 break; 309 } 310 } 311 if (digestAttr == null) 312 throw new SecurityException ("Authenticated attribute is missing the digest."); 313 ++next; 314 } 315 digestEncryptionAlgorithm = ((DERObjectIdentifier)((ASN1Sequence)signerInfo.getObjectAt(next++)).getObjectAt(0)).getId(); 316 digest = ((DEROctetString)signerInfo.getObjectAt(next)).getOctets(); 317 if (RSAdata != null || digestAttr != null) { 318 if (provider == null || provider.startsWith("SunPKCS11")) 319 messageDigest = MessageDigest.getInstance(getHashAlgorithm()); 320 else 321 messageDigest = MessageDigest.getInstance(getHashAlgorithm(), provider); 322 } 323 if (provider == null) 324 sig = Signature.getInstance(getDigestAlgorithm()); 325 else 326 sig = Signature.getInstance(getDigestAlgorithm(), provider); 327 sig.initVerify(signCert.getPublicKey()); 328 } 329 330 343 public PdfPKCS7(PrivateKey privKey, Certificate [] certChain, CRL [] crlList, 344 String hashAlgorithm, String provider, boolean hasRSAdata) 345 throws SecurityException , InvalidKeyException , NoSuchProviderException , 346 NoSuchAlgorithmException 347 { 348 this.privKey = privKey; 349 350 if (hashAlgorithm.equals("MD5")) { 351 digestAlgorithm = ID_MD5; 352 } 353 else if (hashAlgorithm.equals("MD2")) { 354 digestAlgorithm = ID_MD2; 355 } 356 else if (hashAlgorithm.equals("SHA")) { 357 digestAlgorithm = ID_SHA1; 358 } 359 else if (hashAlgorithm.equals("SHA1")) { 360 digestAlgorithm = ID_SHA1; 361 } 362 else { 363 throw new NoSuchAlgorithmException ("Unknown Hash Algorithm "+hashAlgorithm); 364 } 365 366 version = signerversion = 1; 367 certs = new ArrayList (); 368 crls = new ArrayList (); 369 digestalgos = new HashSet (); 370 digestalgos.add(digestAlgorithm); 371 372 signCert = (X509Certificate )certChain[0]; 376 for (int i = 0;i < certChain.length;i++) { 377 certs.add(certChain[i]); 378 } 379 380 if (crlList != null) { 381 for (int i = 0;i < crlList.length;i++) { 382 crls.add(crlList[i]); 383 } 384 } 385 386 if (privKey != null) { 387 digestEncryptionAlgorithm = privKey.getAlgorithm(); 391 if (digestEncryptionAlgorithm.equals("RSA")) { 392 digestEncryptionAlgorithm = ID_RSA; 393 } 394 else if (digestEncryptionAlgorithm.equals("DSA")) { 395 digestEncryptionAlgorithm = ID_DSA; 396 } 397 else { 398 throw new NoSuchAlgorithmException ("Unknown Key Algorithm "+digestEncryptionAlgorithm); 399 } 400 } 401 if (hasRSAdata) { 402 RSAdata = new byte[0]; 403 if (provider == null || provider.startsWith("SunPKCS11")) 404 messageDigest = MessageDigest.getInstance(getHashAlgorithm()); 405 else 406 messageDigest = MessageDigest.getInstance(getHashAlgorithm(), provider); 407 } 408 409 if (privKey != null) { 410 if (provider == null) 411 sig = Signature.getInstance(getDigestAlgorithm()); 412 else 413 sig = Signature.getInstance(getDigestAlgorithm(), provider); 414 415 sig.initSign(privKey); 416 } 417 } 418 419 426 public void update(byte[] buf, int off, int len) throws SignatureException { 427 if (RSAdata != null || digestAttr != null) 428 messageDigest.update(buf, off, len); 429 else 430 sig.update(buf, off, len); 431 } 432 433 438 public boolean verify() throws SignatureException { 439 if (verified) 440 return verifyResult; 441 if (sigAttr != null) { 442 sig.update(sigAttr); 443 if (RSAdata != null) { 444 byte msd[] = messageDigest.digest(); 445 messageDigest.update(msd); 446 } 447 verifyResult = (Arrays.equals(messageDigest.digest(), digestAttr) && sig.verify(digest)); 448 } 449 else { 450 if (RSAdata != null) 451 sig.update(messageDigest.digest()); 452 verifyResult = sig.verify(digest); 453 } 454 verified = true; 455 return verifyResult; 456 } 457 458 462 public Certificate [] getCertificates() { 463 return (X509Certificate [])certs.toArray(new X509Certificate [certs.size()]); 464 } 465 466 470 public Collection getCRLs() { 471 return crls; 472 } 473 474 478 public X509Certificate getSigningCertificate() { 479 return signCert; 480 } 481 482 486 public int getVersion() { 487 return version; 488 } 489 490 494 public int getSigningInfoVersion() { 495 return signerversion; 496 } 497 498 502 public String getDigestAlgorithm() { 503 String dea = digestEncryptionAlgorithm; 504 505 if (digestEncryptionAlgorithm.equals(ID_RSA) || digestEncryptionAlgorithm.equals(ID_MD5RSA) 506 || digestEncryptionAlgorithm.equals(ID_MD2RSA) || digestEncryptionAlgorithm.equals(ID_SHA1RSA)) { 507 dea = "RSA"; 508 } 509 else if (digestEncryptionAlgorithm.equals(ID_DSA)) { 510 dea = "DSA"; 511 } 512 513 return getHashAlgorithm() + "with" + dea; 514 } 515 516 520 public String getHashAlgorithm() { 521 String da = digestAlgorithm; 522 523 if (digestAlgorithm.equals(ID_MD5) || digestAlgorithm.equals(ID_MD5RSA)) { 524 da = "MD5"; 525 } 526 else if (digestAlgorithm.equals(ID_MD2) || digestAlgorithm.equals(ID_MD2RSA)) { 527 da = "MD2"; 528 } 529 else if (digestAlgorithm.equals(ID_SHA1) || digestAlgorithm.equals(ID_SHA1RSA)) { 530 da = "SHA1"; 531 } 532 return da; 533 } 534 535 540 public static KeyStore loadCacertsKeyStore() { 541 return loadCacertsKeyStore(null); 542 } 543 544 549 public static KeyStore loadCacertsKeyStore(String provider) { 550 File file = new File (System.getProperty("java.home"), "lib"); 551 file = new File (file, "security"); 552 file = new File (file, "cacerts"); 553 FileInputStream fin = null; 554 try { 555 fin = new FileInputStream (file); 556 KeyStore k; 557 if (provider == null) 558 k = KeyStore.getInstance("JKS"); 559 else 560 k = KeyStore.getInstance("JKS", provider); 561 k.load(fin, null); 562 return k; 563 } 564 catch (Exception e) { 565 throw new ExceptionConverter(e); 566 } 567 finally { 568 try{if (fin != null) {fin.close();}}catch(Exception ex){} 569 } 570 } 571 572 580 public static String verifyCertificate(X509Certificate cert, Collection crls, Calendar calendar) { 581 if (calendar == null) 582 calendar = new GregorianCalendar (); 583 if (cert.hasUnsupportedCriticalExtension()) 584 return "Has unsupported critical extension"; 585 try { 586 cert.checkValidity(calendar.getTime()); 587 } 588 catch (Exception e) { 589 return e.getMessage(); 590 } 591 if (crls != null) { 592 for (Iterator it = crls.iterator(); it.hasNext();) { 593 if (((CRL )it.next()).isRevoked(cert)) 594 return "Certificate revoked"; 595 } 596 } 597 return null; 598 } 599 600 610 public static Object [] verifyCertificates(Certificate certs[], KeyStore keystore, Collection crls, Calendar calendar) { 611 if (calendar == null) 612 calendar = new GregorianCalendar (); 613 for (int k = 0; k < certs.length; ++k) { 614 X509Certificate cert = (X509Certificate )certs[k]; 615 String err = verifyCertificate(cert, crls, calendar); 616 if (err != null) 617 return new Object []{cert, err}; 618 try { 619 for (Enumeration aliases = keystore.aliases(); aliases.hasMoreElements();) { 620 try { 621 String alias = (String )aliases.nextElement(); 622 if (!keystore.isCertificateEntry(alias)) 623 continue; 624 X509Certificate certStoreX509 = (X509Certificate )keystore.getCertificate(alias); 625 if (verifyCertificate(certStoreX509, crls, calendar) != null) 626 continue; 627 try { 628 cert.verify(certStoreX509.getPublicKey()); 629 return null; 630 } 631 catch (Exception e) { 632 continue; 633 } 634 } 635 catch (Exception ex) { 636 } 637 } 638 } 639 catch (Exception e) { 640 } 641 int j; 642 for (j = 0; j < certs.length; ++j) { 643 if (j == k) 644 continue; 645 X509Certificate certNext = (X509Certificate )certs[j]; 646 try { 647 cert.verify(certNext.getPublicKey()); 648 break; 649 } 650 catch (Exception e) { 651 } 652 } 653 if (j == certs.length) 654 return new Object []{cert, "Cannot be verified against the KeyStore or the certificate chain"}; 655 } 656 return new Object []{null, "Invalid state. Possible circular certificate chain"}; 657 } 658 659 664 private static DERObject getIssuer(byte[] enc) { 665 try { 666 ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream (enc)); 667 ASN1Sequence seq = (ASN1Sequence)in.readObject(); 668 return (DERObject)seq.getObjectAt(seq.getObjectAt(0) instanceof DERTaggedObject ? 3 : 2); 669 } 670 catch (IOException e) { 671 throw new ExceptionConverter(e); 672 } 673 } 674 675 680 private static DERObject getSubject(byte[] enc) { 681 try { 682 ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream (enc)); 683 ASN1Sequence seq = (ASN1Sequence)in.readObject(); 684 return (DERObject)seq.getObjectAt(seq.getObjectAt(0) instanceof DERTaggedObject ? 5 : 4); 685 } 686 catch (IOException e) { 687 throw new ExceptionConverter(e); 688 } 689 } 690 691 696 public static X509Name getIssuerFields(X509Certificate cert) { 697 try { 698 return new X509Name((ASN1Sequence)getIssuer(cert.getTBSCertificate())); 699 } 700 catch (Exception e) { 701 throw new ExceptionConverter(e); 702 } 703 } 704 705 710 public static X509Name getSubjectFields(X509Certificate cert) { 711 try { 712 return new X509Name((ASN1Sequence)getSubject(cert.getTBSCertificate())); 713 } 714 catch (Exception e) { 715 throw new ExceptionConverter(e); 716 } 717 } 718 719 723 public byte[] getEncodedPKCS1() { 724 try { 725 if (externalDigest != null) 726 digest = externalDigest; 727 else 728 digest = sig.sign(); 729 ByteArrayOutputStream bOut = new ByteArrayOutputStream (); 730 731 ASN1OutputStream dout = new ASN1OutputStream(bOut); 732 dout.writeObject(new DEROctetString(digest)); 733 dout.close(); 734 735 return bOut.toByteArray(); 736 } 737 catch (Exception e) { 738 throw new ExceptionConverter(e); 739 } 740 } 741 742 750 public void setExternalDigest(byte digest[], byte RSAdata[], String digestEncryptionAlgorithm) { 751 externalDigest = digest; 752 externalRSAdata = RSAdata; 753 if (digestEncryptionAlgorithm != null) { 754 if (digestEncryptionAlgorithm.equals("RSA")) { 755 this.digestEncryptionAlgorithm = ID_RSA; 756 } 757 else if (digestEncryptionAlgorithm.equals("DSA")) { 758 this.digestEncryptionAlgorithm = ID_DSA; 759 } 760 else 761 throw new ExceptionConverter(new NoSuchAlgorithmException ("Unknown Key Algorithm "+digestEncryptionAlgorithm)); 762 } 763 } 764 765 769 public byte[] getEncodedPKCS7() { 770 return getEncodedPKCS7(null, null); 771 } 772 773 780 public byte[] getEncodedPKCS7(byte secondDigest[], Calendar signingTime) { 781 try { 782 if (externalDigest != null) { 783 digest = externalDigest; 784 if (RSAdata != null) 785 RSAdata = externalRSAdata; 786 } 787 else if (externalRSAdata != null && RSAdata != null) { 788 RSAdata = externalRSAdata; 789 sig.update(RSAdata); 790 digest = sig.sign(); 791 } 792 else { 793 if (RSAdata != null) { 794 RSAdata = messageDigest.digest(); 795 sig.update(RSAdata); 796 } 797 digest = sig.sign(); 798 } 799 800 DERConstructedSet digestAlgorithms = new DERConstructedSet(); 802 for(Iterator it = digestalgos.iterator(); it.hasNext();) { 803 ASN1EncodableVector algos = new ASN1EncodableVector(); 804 algos.add(new DERObjectIdentifier((String )it.next())); 805 algos.add(new DERNull()); 806 digestAlgorithms.addObject(new DERSequence(algos)); 807 } 808 809 ASN1EncodableVector v = new ASN1EncodableVector(); 811 v.add(new DERObjectIdentifier(ID_PKCS7_DATA)); 812 if (RSAdata != null) 813 v.add(new DERTaggedObject(0, new DEROctetString(RSAdata))); 814 DERSequence contentinfo = new DERSequence(v); 815 816 v = new ASN1EncodableVector(); 819 for (Iterator i = certs.iterator(); i.hasNext();) { 820 ASN1InputStream tempstream = new ASN1InputStream(new ByteArrayInputStream (((X509Certificate )i.next()).getEncoded())); 821 v.add(tempstream.readObject()); 822 } 823 824 DERSet dercertificates = new DERSet(v); 825 826 ASN1EncodableVector signerinfo = new ASN1EncodableVector(); 829 830 signerinfo.add(new DERInteger(signerversion)); 833 834 v = new ASN1EncodableVector(); 835 v.add(getIssuer(signCert.getTBSCertificate())); 836 v.add(new DERInteger(signCert.getSerialNumber())); 837 signerinfo.add(new DERSequence(v)); 838 839 v = new ASN1EncodableVector(); 841 v.add(new DERObjectIdentifier(digestAlgorithm)); 842 v.add(new DERNull()); 843 signerinfo.add(new DERSequence(v)); 844 845 if (secondDigest != null && signingTime != null) { 847 ASN1EncodableVector attribute = new ASN1EncodableVector(); 848 v = new ASN1EncodableVector(); 849 v.add(new DERObjectIdentifier(ID_CONTENT_TYPE)); 850 v.add(new DERSet(new DERObjectIdentifier(ID_PKCS7_DATA))); 851 attribute.add(new DERSequence(v)); 852 v = new ASN1EncodableVector(); 853 v.add(new DERObjectIdentifier(ID_SIGNING_TIME)); 854 v.add(new DERSet(new DERUTCTime(signingTime.getTime()))); 855 attribute.add(new DERSequence(v)); 856 v = new ASN1EncodableVector(); 857 v.add(new DERObjectIdentifier(ID_MESSAGE_DIGEST)); 858 v.add(new DERSet(new DEROctetString(secondDigest))); 859 attribute.add(new DERSequence(v)); 860 if (!crls.isEmpty()) { 861 v = new ASN1EncodableVector(); 862 v.add(new DERObjectIdentifier(ID_ADBE_REVOCATION)); 863 ASN1EncodableVector v2 = new ASN1EncodableVector(); 864 for (Iterator i = crls.iterator();i.hasNext();) { 865 ASN1InputStream t = new ASN1InputStream(new ByteArrayInputStream ((((X509CRL )i.next()).getEncoded()))); 866 v2.add(t.readObject()); 867 } 868 v.add(new DERSet(new DERSequence(new DERTaggedObject(true, 0, new DERSequence(v2))))); 869 attribute.add(new DERSequence(v)); 870 } 871 signerinfo.add(new DERTaggedObject(false, 0, new DERSet(attribute))); 872 } 873 v = new ASN1EncodableVector(); 875 v.add(new DERObjectIdentifier(digestEncryptionAlgorithm)); 876 v.add(new DERNull()); 877 signerinfo.add(new DERSequence(v)); 878 879 signerinfo.add(new DEROctetString(digest)); 881 882 883 ASN1EncodableVector body = new ASN1EncodableVector(); 885 body.add(new DERInteger(version)); 886 body.add(digestAlgorithms); 887 body.add(contentinfo); 888 body.add(new DERTaggedObject(false, 0, dercertificates)); 889 890 if (!crls.isEmpty()) { 891 v = new ASN1EncodableVector(); 892 for (Iterator i = crls.iterator();i.hasNext();) { 893 ASN1InputStream t = new ASN1InputStream(new ByteArrayInputStream ((((X509CRL )i.next()).getEncoded()))); 894 v.add(t.readObject()); 895 } 896 DERSet dercrls = new DERSet(v); 897 body.add(new DERTaggedObject(false, 1, dercrls)); 898 } 899 900 body.add(new DERSet(new DERSequence(signerinfo))); 902 903 ASN1EncodableVector whole = new ASN1EncodableVector(); 907 whole.add(new DERObjectIdentifier(ID_PKCS7_SIGNED_DATA)); 908 whole.add(new DERTaggedObject(0, new DERSequence(body))); 909 910 ByteArrayOutputStream bOut = new ByteArrayOutputStream (); 911 912 ASN1OutputStream dout = new ASN1OutputStream(bOut); 913 dout.writeObject(new DERSequence(whole)); 914 dout.close(); 915 916 return bOut.toByteArray(); 917 } 918 catch (Exception e) { 919 throw new ExceptionConverter(e); 920 } 921 } 922 923 924 951 public byte[] getAuthenticatedAttributeBytes(byte secondDigest[], Calendar signingTime) { 952 try { 953 ASN1EncodableVector attribute = new ASN1EncodableVector(); 954 ASN1EncodableVector v = new ASN1EncodableVector(); 955 v.add(new DERObjectIdentifier(ID_CONTENT_TYPE)); 956 v.add(new DERSet(new DERObjectIdentifier(ID_PKCS7_DATA))); 957 attribute.add(new DERSequence(v)); 958 v = new ASN1EncodableVector(); 959 v.add(new DERObjectIdentifier(ID_SIGNING_TIME)); 960 v.add(new DERSet(new DERUTCTime(signingTime.getTime()))); 961 attribute.add(new DERSequence(v)); 962 v = new ASN1EncodableVector(); 963 v.add(new DERObjectIdentifier(ID_MESSAGE_DIGEST)); 964 v.add(new DERSet(new DEROctetString(secondDigest))); 965 attribute.add(new DERSequence(v)); 966 if (!crls.isEmpty()) { 967 v = new ASN1EncodableVector(); 968 v.add(new DERObjectIdentifier(ID_ADBE_REVOCATION)); 969 ASN1EncodableVector v2 = new ASN1EncodableVector(); 970 for (Iterator i = crls.iterator();i.hasNext();) { 971 ASN1InputStream t = new ASN1InputStream(new ByteArrayInputStream ((((X509CRL )i.next()).getEncoded()))); 972 v2.add(t.readObject()); 973 } 974 v.add(new DERSet(new DERSequence(new DERTaggedObject(true, 0, new DERSequence(v2))))); 975 attribute.add(new DERSequence(v)); 976 } 977 ByteArrayOutputStream bOut = new ByteArrayOutputStream (); 978 979 ASN1OutputStream dout = new ASN1OutputStream(bOut); 980 dout.writeObject(new DERSet(attribute)); 981 dout.close(); 982 983 return bOut.toByteArray(); 984 } 985 catch (Exception e) { 986 throw new ExceptionConverter(e); 987 } 988 } 989 993 public String getReason() { 994 return this.reason; 995 } 996 997 1001 public void setReason(String reason) { 1002 this.reason = reason; 1003 } 1004 1005 1009 public String getLocation() { 1010 return this.location; 1011 } 1012 1013 1017 public void setLocation(String location) { 1018 this.location = location; 1019 } 1020 1021 1025 public Calendar getSignDate() { 1026 return this.signDate; 1027 } 1028 1029 1033 public void setSignDate(Calendar signDate) { 1034 this.signDate = signDate; 1035 } 1036 1037 1041 public String getSignName() { 1042 return this.signName; 1043 } 1044 1045 1049 public void setSignName(String signName) { 1050 this.signName = signName; 1051 } 1052 1053 1056 public static class X509Name { 1057 1060 public static final DERObjectIdentifier C = new DERObjectIdentifier("2.5.4.6"); 1061 1062 1065 public static final DERObjectIdentifier O = new DERObjectIdentifier("2.5.4.10"); 1066 1067 1070 public static final DERObjectIdentifier OU = new DERObjectIdentifier("2.5.4.11"); 1071 1072 1075 public static final DERObjectIdentifier T = new DERObjectIdentifier("2.5.4.12"); 1076 1077 1080 public static final DERObjectIdentifier CN = new DERObjectIdentifier("2.5.4.3"); 1081 1082 1085 public static final DERObjectIdentifier SN = new DERObjectIdentifier("2.5.4.5"); 1086 1087 1090 public static final DERObjectIdentifier L = new DERObjectIdentifier("2.5.4.7"); 1091 1092 1095 public static final DERObjectIdentifier ST = new DERObjectIdentifier("2.5.4.8"); 1096 1097 1098 public static final DERObjectIdentifier SURNAME = new DERObjectIdentifier("2.5.4.4"); 1099 1100 public static final DERObjectIdentifier GIVENNAME = new DERObjectIdentifier("2.5.4.42"); 1101 1102 public static final DERObjectIdentifier INITIALS = new DERObjectIdentifier("2.5.4.43"); 1103 1104 public static final DERObjectIdentifier GENERATION = new DERObjectIdentifier("2.5.4.44"); 1105 1106 public static final DERObjectIdentifier UNIQUE_IDENTIFIER = new DERObjectIdentifier("2.5.4.45"); 1107 1108 1112 public static final DERObjectIdentifier EmailAddress = new DERObjectIdentifier("1.2.840.113549.1.9.1"); 1113 1114 1117 public static final DERObjectIdentifier E = EmailAddress; 1118 1119 1120 public static final DERObjectIdentifier DC = new DERObjectIdentifier("0.9.2342.19200300.100.1.25"); 1121 1122 1123 public static final DERObjectIdentifier UID = new DERObjectIdentifier("0.9.2342.19200300.100.1.1"); 1124 1125 1126 public static HashMap DefaultSymbols = new HashMap (); 1127 1128 static { 1129 DefaultSymbols.put(C, "C"); 1130 DefaultSymbols.put(O, "O"); 1131 DefaultSymbols.put(T, "T"); 1132 DefaultSymbols.put(OU, "OU"); 1133 DefaultSymbols.put(CN, "CN"); 1134 DefaultSymbols.put(L, "L"); 1135 DefaultSymbols.put(ST, "ST"); 1136 DefaultSymbols.put(SN, "SN"); 1137 DefaultSymbols.put(EmailAddress, "E"); 1138 DefaultSymbols.put(DC, "DC"); 1139 DefaultSymbols.put(UID, "UID"); 1140 DefaultSymbols.put(SURNAME, "SURNAME"); 1141 DefaultSymbols.put(GIVENNAME, "GIVENNAME"); 1142 DefaultSymbols.put(INITIALS, "INITIALS"); 1143 DefaultSymbols.put(GENERATION, "GENERATION"); 1144 } 1145 1146 public HashMap values = new HashMap (); 1147 1148 1152 public X509Name(ASN1Sequence seq) { 1153 Enumeration e = seq.getObjects(); 1154 1155 while (e.hasMoreElements()) { 1156 ASN1Set set = (ASN1Set)e.nextElement(); 1157 1158 for (int i = 0; i < set.size(); i++) { 1159 ASN1Sequence s = (ASN1Sequence)set.getObjectAt(i); 1160 String id = (String )DefaultSymbols.get(s.getObjectAt(0)); 1161 if (id == null) 1162 continue; 1163 ArrayList vs = (ArrayList )values.get(id); 1164 if (vs == null) { 1165 vs = new ArrayList (); 1166 values.put(id, vs); 1167 } 1168 vs.add(((DERString)s.getObjectAt(1)).getString()); 1169 } 1170 } 1171 } 1172 1176 public X509Name(String dirName) { 1177 X509NameTokenizer nTok = new X509NameTokenizer(dirName); 1178 1179 while (nTok.hasMoreTokens()) { 1180 String token = nTok.nextToken(); 1181 int index = token.indexOf('='); 1182 1183 if (index == -1) { 1184 throw new IllegalArgumentException ("badly formated directory string"); 1185 } 1186 1187 String id = token.substring(0, index).toUpperCase(); 1188 String value = token.substring(index + 1); 1189 ArrayList vs = (ArrayList )values.get(id); 1190 if (vs == null) { 1191 vs = new ArrayList (); 1192 values.put(id, vs); 1193 } 1194 vs.add(value); 1195 } 1196 1197 } 1198 1199 public String getField(String name) { 1200 ArrayList vs = (ArrayList )values.get(name); 1201 return vs == null ? null : (String )vs.get(0); 1202 } 1203 1204 1209 public ArrayList getFieldArray(String name) { 1210 ArrayList vs = (ArrayList )values.get(name); 1211 return vs == null ? null : vs; 1212 } 1213 1214 1218 public HashMap getFields() { 1219 return values; 1220 } 1221 1222 1225 public String toString() { 1226 return values.toString(); 1227 } 1228 } 1229 1230 1236 public static class X509NameTokenizer { 1237 private String oid; 1238 private int index; 1239 private StringBuffer buf = new StringBuffer (); 1240 1241 public X509NameTokenizer( 1242 String oid) { 1243 this.oid = oid; 1244 this.index = -1; 1245 } 1246 1247 public boolean hasMoreTokens() { 1248 return (index != oid.length()); 1249 } 1250 1251 public String nextToken() { 1252 if (index == oid.length()) { 1253 return null; 1254 } 1255 1256 int end = index + 1; 1257 boolean quoted = false; 1258 boolean escaped = false; 1259 1260 buf.setLength(0); 1261 1262 while (end != oid.length()) { 1263 char c = oid.charAt(end); 1264 1265 if (c == '"') { 1266 if (!escaped) { 1267 quoted = !quoted; 1268 } 1269 else { 1270 buf.append(c); 1271 } 1272 escaped = false; 1273 } 1274 else { 1275 if (escaped || quoted) { 1276 buf.append(c); 1277 escaped = false; 1278 } 1279 else if (c == '\\') { 1280 escaped = true; 1281 } 1282 else if (c == ',') { 1283 break; 1284 } 1285 else { 1286 buf.append(c); 1287 } 1288 } 1289 end++; 1290 } 1291 1292 index = end; 1293 return buf.toString().trim(); 1294 } 1295 } 1296} 1297 | Popular Tags |