1package org.bouncycastle.cms; 2 3import java.io.IOException; 4import java.io.InputStream; 5import java.io.OutputStream; 6import java.security.NoSuchAlgorithmException; 7import java.security.NoSuchProviderException; 8import java.security.Provider; 9import java.security.cert.CertStore; 10import java.security.cert.CertStoreException; 11import java.util.ArrayList; 12import java.util.Collection; 13import java.util.Iterator; 14import java.util.List; 15import java.util.Map; 16 17import org.bouncycastle.asn1.ASN1EncodableVector; 18import org.bouncycastle.asn1.ASN1InputStream; 19import org.bouncycastle.asn1.ASN1ObjectIdentifier; 20import org.bouncycastle.asn1.ASN1OctetString; 21import org.bouncycastle.asn1.ASN1Sequence; 22import org.bouncycastle.asn1.ASN1Set; 23import org.bouncycastle.asn1.BERSequence; 24import org.bouncycastle.asn1.DERSet; 25import org.bouncycastle.asn1.cms.ContentInfo; 26import org.bouncycastle.asn1.cms.SignedData; 27import org.bouncycastle.asn1.cms.SignerInfo; 28// BEGIN android-removed 29// import org.bouncycastle.cert.jcajce.JcaCertStoreBuilder; 30// END android-removed 31import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder; 32import org.bouncycastle.operator.OperatorCreationException; 33import org.bouncycastle.operator.SignatureAlgorithmIdentifierFinder; 34import org.bouncycastle.util.Store; 35import org.bouncycastle.x509.NoSuchStoreException; 36import org.bouncycastle.x509.X509Store; 37 38/** 39 * general class for handling a pkcs7-signature message. 40 * 41 * A simple example of usage - note, in the example below the validity of 42 * the certificate isn't verified, just the fact that one of the certs 43 * matches the given signer... 44 * 45 * <pre> 46 * Store certStore = s.getCertificates(); 47 * SignerInformationStore signers = s.getSignerInfos(); 48 * Collection c = signers.getSigners(); 49 * Iterator it = c.iterator(); 50 * 51 * while (it.hasNext()) 52 * { 53 * SignerInformation signer = (SignerInformation)it.next(); 54 * Collection certCollection = certStore.getMatches(signer.getSID()); 55 * 56 * Iterator certIt = certCollection.iterator(); 57 * X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); 58 * 59 * if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert))) 60 * { 61 * verified++; 62 * } 63 * } 64 * </pre> 65 */ 66public class CMSSignedData 67{ 68 private static final CMSSignedHelper HELPER = CMSSignedHelper.INSTANCE; 69 70 SignedData signedData; 71 ContentInfo contentInfo; 72 CMSTypedData signedContent; 73 SignerInformationStore signerInfoStore; 74 X509Store attributeStore; 75 X509Store certificateStore; 76 X509Store crlStore; 77 private Map hashes; 78 79 private CMSSignedData( 80 CMSSignedData c) 81 { 82 this.signedData = c.signedData; 83 this.contentInfo = c.contentInfo; 84 this.signedContent = c.signedContent; 85 this.signerInfoStore = c.signerInfoStore; 86 } 87 88 public CMSSignedData( 89 byte[] sigBlock) 90 throws CMSException 91 { 92 this(CMSUtils.readContentInfo(sigBlock)); 93 } 94 95 public CMSSignedData( 96 CMSProcessable signedContent, 97 byte[] sigBlock) 98 throws CMSException 99 { 100 this(signedContent, CMSUtils.readContentInfo(sigBlock)); 101 } 102 103 /** 104 * Content with detached signature, digests precomputed 105 * 106 * @param hashes a map of precomputed digests for content indexed by name of hash. 107 * @param sigBlock the signature object. 108 */ 109 public CMSSignedData( 110 Map hashes, 111 byte[] sigBlock) 112 throws CMSException 113 { 114 this(hashes, CMSUtils.readContentInfo(sigBlock)); 115 } 116 117 /** 118 * base constructor - content with detached signature. 119 * 120 * @param signedContent the content that was signed. 121 * @param sigData the signature object. 122 */ 123 public CMSSignedData( 124 CMSProcessable signedContent, 125 InputStream sigData) 126 throws CMSException 127 { 128 this(signedContent, CMSUtils.readContentInfo(new ASN1InputStream(sigData))); 129 } 130 131 /** 132 * base constructor - with encapsulated content 133 */ 134 public CMSSignedData( 135 InputStream sigData) 136 throws CMSException 137 { 138 this(CMSUtils.readContentInfo(sigData)); 139 } 140 141 public CMSSignedData( 142 final CMSProcessable signedContent, 143 ContentInfo sigData) 144 throws CMSException 145 { 146 if (signedContent instanceof CMSTypedData) 147 { 148 this.signedContent = (CMSTypedData)signedContent; 149 } 150 else 151 { 152 this.signedContent = new CMSTypedData() 153 { 154 public ASN1ObjectIdentifier getContentType() 155 { 156 return signedData.getEncapContentInfo().getContentType(); 157 } 158 159 public void write(OutputStream out) 160 throws IOException, CMSException 161 { 162 signedContent.write(out); 163 } 164 165 public Object getContent() 166 { 167 return signedContent.getContent(); 168 } 169 }; 170 } 171 172 this.contentInfo = sigData; 173 this.signedData = getSignedData(); 174 } 175 176 public CMSSignedData( 177 Map hashes, 178 ContentInfo sigData) 179 throws CMSException 180 { 181 this.hashes = hashes; 182 this.contentInfo = sigData; 183 this.signedData = getSignedData(); 184 } 185 186 public CMSSignedData( 187 ContentInfo sigData) 188 throws CMSException 189 { 190 this.contentInfo = sigData; 191 this.signedData = getSignedData(); 192 193 // 194 // this can happen if the signed message is sent simply to send a 195 // certificate chain. 196 // 197 if (signedData.getEncapContentInfo().getContent() != null) 198 { 199 this.signedContent = new CMSProcessableByteArray(signedData.getEncapContentInfo().getContentType(), 200 ((ASN1OctetString)(signedData.getEncapContentInfo() 201 .getContent())).getOctets()); 202 } 203 else 204 { 205 this.signedContent = null; 206 } 207 } 208 209 private SignedData getSignedData() 210 throws CMSException 211 { 212 try 213 { 214 return SignedData.getInstance(contentInfo.getContent()); 215 } 216 catch (ClassCastException e) 217 { 218 throw new CMSException("Malformed content.", e); 219 } 220 catch (IllegalArgumentException e) 221 { 222 throw new CMSException("Malformed content.", e); 223 } 224 } 225 226 /** 227 * Return the version number for this object 228 */ 229 public int getVersion() 230 { 231 return signedData.getVersion().getValue().intValue(); 232 } 233 234 /** 235 * return the collection of signers that are associated with the 236 * signatures for the message. 237 */ 238 public SignerInformationStore getSignerInfos() 239 { 240 if (signerInfoStore == null) 241 { 242 ASN1Set s = signedData.getSignerInfos(); 243 List signerInfos = new ArrayList(); 244 SignatureAlgorithmIdentifierFinder sigAlgFinder = new DefaultSignatureAlgorithmIdentifierFinder(); 245 246 for (int i = 0; i != s.size(); i++) 247 { 248 SignerInfo info = SignerInfo.getInstance(s.getObjectAt(i)); 249 ASN1ObjectIdentifier contentType = signedData.getEncapContentInfo().getContentType(); 250 251 if (hashes == null) 252 { 253 signerInfos.add(new SignerInformation(info, contentType, signedContent, null)); 254 } 255 else 256 { 257 Object obj = hashes.keySet().iterator().next(); 258 byte[] hash = (obj instanceof String) ? (byte[])hashes.get(info.getDigestAlgorithm().getAlgorithm().getId()) : (byte[])hashes.get(info.getDigestAlgorithm().getAlgorithm()); 259 260 signerInfos.add(new SignerInformation(info, contentType, null, hash)); 261 } 262 } 263 264 signerInfoStore = new SignerInformationStore(signerInfos); 265 } 266 267 return signerInfoStore; 268 } 269 270 /** 271 * return a X509Store containing the attribute certificates, if any, contained 272 * in this message. 273 * 274 * @param type type of store to create 275 * @param provider name of provider to use 276 * @return a store of attribute certificates 277 * @exception NoSuchProviderException if the provider requested isn't available. 278 * @exception NoSuchStoreException if the store type isn't available. 279 * @exception CMSException if a general exception prevents creation of the X509Store 280 * @deprecated use base Store returning method 281 */ 282 public X509Store getAttributeCertificates( 283 String type, 284 String provider) 285 throws NoSuchStoreException, NoSuchProviderException, CMSException 286 { 287 return getAttributeCertificates(type, CMSUtils.getProvider(provider)); 288 } 289 290 /** 291 * return a X509Store containing the attribute certificates, if any, contained 292 * in this message. 293 * 294 * @param type type of store to create 295 * @param provider provider to use 296 * @return a store of attribute certificates 297 * @exception NoSuchStoreException if the store type isn't available. 298 * @exception CMSException if a general exception prevents creation of the X509Store 299 * @deprecated use base Store returning method 300 */ 301 public X509Store getAttributeCertificates( 302 String type, 303 Provider provider) 304 throws NoSuchStoreException, CMSException 305 { 306 if (attributeStore == null) 307 { 308 attributeStore = HELPER.createAttributeStore(type, provider, this.getAttributeCertificates()); 309 } 310 311 return attributeStore; 312 } 313 314 // BEGIN android-removed 315 // /** 316 // * return a X509Store containing the public key certificates, if any, contained 317 // * in this message. 318 // * 319 // * @param type type of store to create 320 // * @param provider name of provider to use 321 // * @return a store of public key certificates 322 // * @exception NoSuchProviderException if the provider requested isn't available. 323 // * @exception NoSuchStoreException if the store type isn't available. 324 // * @exception CMSException if a general exception prevents creation of the X509Store 325 // * @deprecated use base Store returning method 326 // */ 327 // public X509Store getCertificates( 328 // String type, 329 // String provider) 330 // throws NoSuchStoreException, NoSuchProviderException, CMSException 331 // { 332 // return getCertificates(type, CMSUtils.getProvider(provider)); 333 // } 334 // 335 // /** 336 // * return a X509Store containing the public key certificates, if any, contained 337 // * in this message. 338 // * 339 // * @param type type of store to create 340 // * @param provider provider to use 341 // * @return a store of public key certificates 342 // * @exception NoSuchStoreException if the store type isn't available. 343 // * @exception CMSException if a general exception prevents creation of the X509Store 344 // * @deprecated use base Store returning method 345 // */ 346 // public X509Store getCertificates( 347 // String type, 348 // Provider provider) 349 // throws NoSuchStoreException, CMSException 350 // { 351 // if (certificateStore == null) 352 // { 353 // certificateStore = HELPER.createCertificateStore(type, provider, this.getCertificates()); 354 // } 355 // 356 // return certificateStore; 357 // } 358 // 359 // /** 360 // * return a X509Store containing CRLs, if any, contained 361 // * in this message. 362 // * 363 // * @param type type of store to create 364 // * @param provider name of provider to use 365 // * @return a store of CRLs 366 // * @exception NoSuchProviderException if the provider requested isn't available. 367 // * @exception NoSuchStoreException if the store type isn't available. 368 // * @exception CMSException if a general exception prevents creation of the X509Store 369 // * @deprecated use base Store returning method 370 // */ 371 // public X509Store getCRLs( 372 // String type, 373 // String provider) 374 // throws NoSuchStoreException, NoSuchProviderException, CMSException 375 // { 376 // return getCRLs(type, CMSUtils.getProvider(provider)); 377 // } 378 // 379 // /** 380 // * return a X509Store containing CRLs, if any, contained 381 // * in this message. 382 // * 383 // * @param type type of store to create 384 // * @param provider provider to use 385 // * @return a store of CRLs 386 // * @exception NoSuchStoreException if the store type isn't available. 387 // * @exception CMSException if a general exception prevents creation of the X509Store 388 // * @deprecated use base Store returning method 389 // */ 390 // public X509Store getCRLs( 391 // String type, 392 // Provider provider) 393 // throws NoSuchStoreException, CMSException 394 // { 395 // if (crlStore == null) 396 // { 397 // crlStore = HELPER.createCRLsStore(type, provider, getCRLs()); 398 // } 399 // 400 // return crlStore; 401 // } 402 // 403 // /** 404 // * return a CertStore containing the certificates and CRLs associated with 405 // * this message. 406 // * 407 // * @exception NoSuchProviderException if the provider requested isn't available. 408 // * @exception NoSuchAlgorithmException if the cert store isn't available. 409 // * @exception CMSException if a general exception prevents creation of the CertStore 410 // * @deprecated use base Store returning method and org.bouncycastle.cert.jcajce.JcaCertStoreBuilder 411 // */ 412 // public CertStore getCertificatesAndCRLs( 413 // String type, 414 // String provider) 415 // throws NoSuchAlgorithmException, NoSuchProviderException, CMSException 416 // { 417 // return getCertificatesAndCRLs(type, CMSUtils.getProvider(provider)); 418 // } 419 // 420 // /** 421 // * return a CertStore containing the certificates and CRLs associated with 422 // * this message. 423 // * 424 // * @exception NoSuchAlgorithmException if the cert store isn't available. 425 // * @exception CMSException if a general exception prevents creation of the CertStore 426 // * @deprecated use base Store returning method and org.bouncycastle.cert.jcajce.JcaCertStoreBuilder 427 // */ 428 // public CertStore getCertificatesAndCRLs( 429 // String type, 430 // Provider provider) 431 // throws NoSuchAlgorithmException, CMSException 432 // { 433 // try 434 // { 435 // JcaCertStoreBuilder certStoreBuilder = new JcaCertStoreBuilder().setType(type); 436 // 437 // if (provider != null) 438 // { 439 // certStoreBuilder.setProvider(provider); 440 // } 441 // 442 // certStoreBuilder.addCertificates(this.getCertificates()); 443 // certStoreBuilder.addCRLs(this.getCRLs()); 444 // 445 // return certStoreBuilder.build(); 446 // } 447 // catch (NoSuchAlgorithmException e) 448 // { 449 // throw e; 450 // } 451 // catch (Exception e) 452 // { 453 // throw new CMSException("exception creating CertStore: " + e.getMessage(), e); 454 // } 455 // } 456 // END android-removed 457 458 /** 459 * Return any X.509 certificate objects in this SignedData structure as a Store of X509CertificateHolder objects. 460 * 461 * @return a Store of X509CertificateHolder objects. 462 */ 463 public Store getCertificates() 464 { 465 return HELPER.getCertificates(signedData.getCertificates()); 466 } 467 468 /** 469 * Return any X.509 CRL objects in this SignedData structure as a Store of X509CRLHolder objects. 470 * 471 * @return a Store of X509CRLHolder objects. 472 */ 473 public Store getCRLs() 474 { 475 return HELPER.getCRLs(signedData.getCRLs()); 476 } 477 478 /** 479 * Return any X.509 attribute certificate objects in this SignedData structure as a Store of X509AttributeCertificateHolder objects. 480 * 481 * @return a Store of X509AttributeCertificateHolder objects. 482 */ 483 public Store getAttributeCertificates() 484 { 485 return HELPER.getAttributeCertificates(signedData.getCertificates()); 486 } 487 488 // BEGIN android-removed 489 // /** 490 // * Return any OtherRevocationInfo OtherRevInfo objects of the type indicated by otherRevocationInfoFormat in 491 // * this SignedData structure. 492 // * 493 // * @param otherRevocationInfoFormat OID of the format type been looked for. 494 // * 495 // * @return a Store of ASN1Encodable objects representing any objects of otherRevocationInfoFormat found. 496 // */ 497 // public Store getOtherRevocationInfo(ASN1ObjectIdentifier otherRevocationInfoFormat) 498 // { 499 // return HELPER.getOtherRevocationInfo(otherRevocationInfoFormat, signedData.getCRLs()); 500 // } 501 // END android-removed 502 503 /** 504 * Return the a string representation of the OID associated with the 505 * encapsulated content info structure carried in the signed data. 506 * 507 * @return the OID for the content type. 508 */ 509 public String getSignedContentTypeOID() 510 { 511 return signedData.getEncapContentInfo().getContentType().getId(); 512 } 513 514 public CMSTypedData getSignedContent() 515 { 516 return signedContent; 517 } 518 519 /** 520 * return the ContentInfo 521 * @deprecated use toASN1Structure() 522 */ 523 public ContentInfo getContentInfo() 524 { 525 return contentInfo; 526 } 527 528 /** 529 * return the ContentInfo 530 */ 531 public ContentInfo toASN1Structure() 532 { 533 return contentInfo; 534 } 535 536 /** 537 * return the ASN.1 encoded representation of this object. 538 */ 539 public byte[] getEncoded() 540 throws IOException 541 { 542 return contentInfo.getEncoded(); 543 } 544 545 // BEGIN android-removed 546 // /** 547 // * Verify all the SignerInformation objects and their associated counter signatures attached 548 // * to this CMS SignedData object. 549 // * 550 // * @param verifierProvider a provider of SignerInformationVerifier objects. 551 // * @return true if all verify, false otherwise. 552 // * @throws CMSException if an exception occurs during the verification process. 553 // */ 554 // public boolean verifySignatures(SignerInformationVerifierProvider verifierProvider) 555 // throws CMSException 556 // { 557 // return verifySignatures(verifierProvider, false); 558 // } 559 // 560 // /** 561 // * Verify all the SignerInformation objects and optionally their associated counter signatures attached 562 // * to this CMS SignedData object. 563 // * 564 // * @param verifierProvider a provider of SignerInformationVerifier objects. 565 // * @param ignoreCounterSignatures if true don't check counter signatures. If false check counter signatures as well. 566 // * @return true if all verify, false otherwise. 567 // * @throws CMSException if an exception occurs during the verification process. 568 // */ 569 // public boolean verifySignatures(SignerInformationVerifierProvider verifierProvider, boolean ignoreCounterSignatures) 570 // throws CMSException 571 // { 572 // Collection signers = this.getSignerInfos().getSigners(); 573 // 574 // for (Iterator it = signers.iterator(); it.hasNext();) 575 // { 576 // SignerInformation signer = (SignerInformation)it.next(); 577 // 578 // try 579 // { 580 // SignerInformationVerifier verifier = verifierProvider.get(signer.getSID()); 581 // 582 // if (!signer.verify(verifier)) 583 // { 584 // return false; 585 // } 586 // 587 // if (!ignoreCounterSignatures) 588 // { 589 // Collection counterSigners = signer.getCounterSignatures().getSigners(); 590 // 591 // for (Iterator cIt = counterSigners.iterator(); cIt.hasNext();) 592 // { 593 // SignerInformation counterSigner = (SignerInformation)cIt.next(); 594 // SignerInformationVerifier counterVerifier = verifierProvider.get(signer.getSID()); 595 // 596 // if (!counterSigner.verify(counterVerifier)) 597 // { 598 // return false; 599 // } 600 // } 601 // } 602 // } 603 // catch (OperatorCreationException e) 604 // { 605 // throw new CMSException("failure in verifier provider: " + e.getMessage(), e); 606 // } 607 // } 608 // 609 // return true; 610 // } 611 // END android-removed 612 613 /** 614 * Replace the SignerInformation store associated with this 615 * CMSSignedData object with the new one passed in. You would 616 * probably only want to do this if you wanted to change the unsigned 617 * attributes associated with a signer, or perhaps delete one. 618 * 619 * @param signedData the signed data object to be used as a base. 620 * @param signerInformationStore the new signer information store to use. 621 * @return a new signed data object. 622 */ 623 public static CMSSignedData replaceSigners( 624 CMSSignedData signedData, 625 SignerInformationStore signerInformationStore) 626 { 627 // 628 // copy 629 // 630 CMSSignedData cms = new CMSSignedData(signedData); 631 632 // 633 // replace the store 634 // 635 cms.signerInfoStore = signerInformationStore; 636 637 // 638 // replace the signers in the SignedData object 639 // 640 ASN1EncodableVector digestAlgs = new ASN1EncodableVector(); 641 ASN1EncodableVector vec = new ASN1EncodableVector(); 642 643 Iterator it = signerInformationStore.getSigners().iterator(); 644 while (it.hasNext()) 645 { 646 SignerInformation signer = (SignerInformation)it.next(); 647 digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID())); 648 vec.add(signer.toASN1Structure()); 649 } 650 651 ASN1Set digests = new DERSet(digestAlgs); 652 ASN1Set signers = new DERSet(vec); 653 ASN1Sequence sD = (ASN1Sequence)signedData.signedData.toASN1Primitive(); 654 655 vec = new ASN1EncodableVector(); 656 657 // 658 // signers are the last item in the sequence. 659 // 660 vec.add(sD.getObjectAt(0)); // version 661 vec.add(digests); 662 663 for (int i = 2; i != sD.size() - 1; i++) 664 { 665 vec.add(sD.getObjectAt(i)); 666 } 667 668 vec.add(signers); 669 670 cms.signedData = SignedData.getInstance(new BERSequence(vec)); 671 672 // 673 // replace the contentInfo with the new one 674 // 675 cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData); 676 677 return cms; 678 } 679 680 /** 681 * Replace the certificate and CRL information associated with this 682 * CMSSignedData object with the new one passed in. 683 * 684 * @param signedData the signed data object to be used as a base. 685 * @param certsAndCrls the new certificates and CRLs to be used. 686 * @return a new signed data object. 687 * @exception CMSException if there is an error processing the CertStore 688 * @deprecated use method taking Store arguments. 689 */ 690 public static CMSSignedData replaceCertificatesAndCRLs( 691 CMSSignedData signedData, 692 CertStore certsAndCrls) 693 throws CMSException 694 { 695 // 696 // copy 697 // 698 CMSSignedData cms = new CMSSignedData(signedData); 699 700 // 701 // replace the certs and crls in the SignedData object 702 // 703 ASN1Set certs = null; 704 ASN1Set crls = null; 705 706 try 707 { 708 ASN1Set set = CMSUtils.createBerSetFromList(CMSUtils.getCertificatesFromStore(certsAndCrls)); 709 710 if (set.size() != 0) 711 { 712 certs = set; 713 } 714 } 715 catch (CertStoreException e) 716 { 717 throw new CMSException("error getting certs from certStore", e); 718 } 719 720 try 721 { 722 ASN1Set set = CMSUtils.createBerSetFromList(CMSUtils.getCRLsFromStore(certsAndCrls)); 723 724 if (set.size() != 0) 725 { 726 crls = set; 727 } 728 } 729 catch (CertStoreException e) 730 { 731 throw new CMSException("error getting crls from certStore", e); 732 } 733 734 // 735 // replace the CMS structure. 736 // 737 cms.signedData = new SignedData(signedData.signedData.getDigestAlgorithms(), 738 signedData.signedData.getEncapContentInfo(), 739 certs, 740 crls, 741 signedData.signedData.getSignerInfos()); 742 743 // 744 // replace the contentInfo with the new one 745 // 746 cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData); 747 748 return cms; 749 } 750 751 /** 752 * Replace the certificate and CRL information associated with this 753 * CMSSignedData object with the new one passed in. 754 * 755 * @param signedData the signed data object to be used as a base. 756 * @param certificates the new certificates to be used. 757 * @param attrCerts the new attribute certificates to be used. 758 * @param crls the new CRLs to be used. 759 * @return a new signed data object. 760 * @exception CMSException if there is an error processing the CertStore 761 */ 762 public static CMSSignedData replaceCertificatesAndCRLs( 763 CMSSignedData signedData, 764 Store certificates, 765 Store attrCerts, 766 Store crls) 767 throws CMSException 768 { 769 // 770 // copy 771 // 772 CMSSignedData cms = new CMSSignedData(signedData); 773 774 // 775 // replace the certs and crls in the SignedData object 776 // 777 ASN1Set certSet = null; 778 ASN1Set crlSet = null; 779 780 if (certificates != null || attrCerts != null) 781 { 782 List certs = new ArrayList(); 783 784 if (certificates != null) 785 { 786 certs.addAll(CMSUtils.getCertificatesFromStore(certificates)); 787 } 788 if (attrCerts != null) 789 { 790 certs.addAll(CMSUtils.getAttributeCertificatesFromStore(attrCerts)); 791 } 792 793 ASN1Set set = CMSUtils.createBerSetFromList(certs); 794 795 if (set.size() != 0) 796 { 797 certSet = set; 798 } 799 } 800 801 if (crls != null) 802 { 803 ASN1Set set = CMSUtils.createBerSetFromList(CMSUtils.getCRLsFromStore(crls)); 804 805 if (set.size() != 0) 806 { 807 crlSet = set; 808 } 809 } 810 811 // 812 // replace the CMS structure. 813 // 814 cms.signedData = new SignedData(signedData.signedData.getDigestAlgorithms(), 815 signedData.signedData.getEncapContentInfo(), 816 certSet, 817 crlSet, 818 signedData.signedData.getSignerInfos()); 819 820 // 821 // replace the contentInfo with the new one 822 // 823 cms.contentInfo = new ContentInfo(cms.contentInfo.getContentType(), cms.signedData); 824 825 return cms; 826 } 827} 828