1e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrompackage org.bouncycastle.cms; 2e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 3e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.io.ByteArrayOutputStream; 4e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.io.IOException; 5e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.io.OutputStream; 6e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.util.ArrayList; 7e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.util.Iterator; 8e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport java.util.List; 9e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 10e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.ASN1EncodableVector; 11e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.ASN1ObjectIdentifier; 12e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.ASN1OctetString; 13e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.ASN1Set; 14e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.BEROctetString; 15e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.DERSet; 16e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.cms.CMSObjectIdentifiers; 17e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.cms.ContentInfo; 18e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.cms.SignedData; 19e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstromimport org.bouncycastle.asn1.cms.SignerInfo; 20e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 21e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom/** 22e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * general class for generating a pkcs7-signature message. 23e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * <p> 24e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * A simple example of usage, generating a detached signature. 25e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * 26e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * <pre> 27e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * List certList = new ArrayList(); 28e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes()); 29e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * 30e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * certList.add(signCert); 31e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * 32e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * Store certs = new JcaCertStore(certList); 33e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * 34e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); 35e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(signKP.getPrivate()); 36e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * 37e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * gen.addSignerInfoGenerator( 38e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * new JcaSignerInfoGeneratorBuilder( 39e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()) 40e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * .build(sha1Signer, signCert)); 41e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * 42e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * gen.addCertificates(certs); 43e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * 44e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * CMSSignedData sigData = gen.generate(msg, false); 45e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * </pre> 46e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 47e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrompublic class CMSSignedDataGenerator 48e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom extends CMSSignedGenerator 49e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom{ 50e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom private List signerInfs = new ArrayList(); 51e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 52e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 53e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * base constructor 54e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 55e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public CMSSignedDataGenerator() 56e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 57e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 58e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 59e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 605db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root * Generate a CMS Signed Data object carrying a detached CMS signature. 61e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * 625db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root * @param content the content to be signed. 63e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 64e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public CMSSignedData generate( 65e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom CMSTypedData content) 66e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throws CMSException 67e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 68e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return generate(content, false); 69e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 70e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 715db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root /** 725db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root * Generate a CMS Signed Data object which can be carrying a detached CMS signature, or have encapsulated data, depending on the value 735db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root * of the encapsulated parameter. 745db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root * 755db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root * @param content the content to be signed. 765db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root * @param encapsulate true if the content should be encapsulated in the signature, false otherwise. 775db505e1f6a68c8d5dfdb0fed0b8607dea7bed96Kenny Root */ 78e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public CMSSignedData generate( 79e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom // FIXME Avoid accessing more than once to support CMSProcessableInputStream 80e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom CMSTypedData content, 81e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom boolean encapsulate) 82e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throws CMSException 83e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 84e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (!signerInfs.isEmpty()) 85e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 86e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new IllegalStateException("this method can only be used with SignerInfoGenerator"); 87e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 88e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 89e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom // TODO 90e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// if (signerInfs.isEmpty()) 91e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// { 92e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// /* RFC 3852 5.2 93e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// * "In the degenerate case where there are no signers, the 94e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// * EncapsulatedContentInfo value being "signed" is irrelevant. In this 95e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// * case, the content type within the EncapsulatedContentInfo value being 96e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// * "signed" MUST be id-data (as defined in section 4), and the content 97e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// * field of the EncapsulatedContentInfo value MUST be omitted." 98e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// */ 99e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// if (encapsulate) 100e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// { 101e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// throw new IllegalArgumentException("no signers, encapsulate must be false"); 102e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// } 103e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// if (!DATA.equals(eContentType)) 104e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// { 105e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// throw new IllegalArgumentException("no signers, eContentType must be id-data"); 106e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// } 107e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// } 108e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// 109e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// if (!DATA.equals(eContentType)) 110e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// { 111e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// /* RFC 3852 5.3 112e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// * [The 'signedAttrs']... 113e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// * field is optional, but it MUST be present if the content type of 114e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// * the EncapsulatedContentInfo value being signed is not id-data. 115e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// */ 116e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// // TODO signedAttrs must be present for all signers 117e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom// } 118e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 119e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1EncodableVector digestAlgs = new ASN1EncodableVector(); 120e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1EncodableVector signerInfos = new ASN1EncodableVector(); 121e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 122e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom digests.clear(); // clear the current preserved digest state 123e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 124e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom // 125e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom // add the precalculated SignerInfo objects. 126e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom // 127e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom for (Iterator it = _signers.iterator(); it.hasNext();) 128e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 129e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom SignerInformation signer = (SignerInformation)it.next(); 130e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom digestAlgs.add(CMSSignedHelper.INSTANCE.fixAlgID(signer.getDigestAlgorithmID())); 131e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 132e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom // TODO Verify the content type and calculated digest match the precalculated SignerInfo 133e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom signerInfos.add(signer.toASN1Structure()); 134e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 135e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 136e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom // 137e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom // add the SignerInfo objects 138e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom // 139e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1ObjectIdentifier contentTypeOID = content.getContentType(); 140e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 141e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1OctetString octs = null; 142e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 143e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (content != null) 144e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 145e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ByteArrayOutputStream bOut = null; 146e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 147e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (encapsulate) 148e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 149e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom bOut = new ByteArrayOutputStream(); 150e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 151e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 152e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom OutputStream cOut = CMSUtils.attachSignersToOutputStream(signerGens, bOut); 153e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 154e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom // Just in case it's unencapsulated and there are no signers! 155e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom cOut = CMSUtils.getSafeOutputStream(cOut); 156e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 157e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom try 158e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 159e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom content.write(cOut); 160e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 161e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom cOut.close(); 162e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 163e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom catch (IOException e) 164e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 165e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throw new CMSException("data processing exception: " + e.getMessage(), e); 166e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 167e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 168e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (encapsulate) 169e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 170e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom octs = new BEROctetString(bOut.toByteArray()); 171e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 172e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 173e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 174e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom for (Iterator it = signerGens.iterator(); it.hasNext();) 175e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 176e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom SignerInfoGenerator sGen = (SignerInfoGenerator)it.next(); 177e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom SignerInfo inf = sGen.generate(contentTypeOID); 178e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 179e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom digestAlgs.add(inf.getDigestAlgorithm()); 180e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom signerInfos.add(inf); 181e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 182e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom byte[] calcDigest = sGen.getCalculatedDigest(); 183e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 184e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (calcDigest != null) 185e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 186e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom digests.put(inf.getDigestAlgorithm().getAlgorithm().getId(), calcDigest); 187e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 188e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 189e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 190e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1Set certificates = null; 191e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 192e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (certs.size() != 0) 193e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 194e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom certificates = CMSUtils.createBerSetFromList(certs); 195e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 196e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 197e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ASN1Set certrevlist = null; 198e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 199e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom if (crls.size() != 0) 200e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 201e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom certrevlist = CMSUtils.createBerSetFromList(crls); 202e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 203e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 204e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ContentInfo encInfo = new ContentInfo(contentTypeOID, octs); 205e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 206e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom SignedData sd = new SignedData( 207e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom new DERSet(digestAlgs), 208e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom encInfo, 209e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom certificates, 210e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom certrevlist, 211e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom new DERSet(signerInfos)); 212e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 213e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom ContentInfo contentInfo = new ContentInfo( 214e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom CMSObjectIdentifiers.signedData, sd); 215e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 216e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return new CMSSignedData(content, contentInfo); 217e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 218e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 219e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom /** 220e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * generate a set of one or more SignerInformation objects representing counter signatures on 221e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * the passed in SignerInformation object. 222e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * 223e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @param signer the signer to be countersigned 224e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom * @return a store containing the signers. 225e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom */ 226e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom public SignerInformationStore generateCounterSigners(SignerInformation signer) 227e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom throws CMSException 228e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom { 229e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom return this.generate(new CMSProcessableByteArray(null, signer.getSignature()), false).getSignerInfos(); 230e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom } 231e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom} 232e6bf3e8dfa2804891a82075cb469b736321b4827Brian Carlstrom 233