Skip to content

Commit c609ec2

Browse files
committed
Rewrite generateCounterSigners
- restore null check in ContentInfo constructor
1 parent 6b80483 commit c609ec2

File tree

2 files changed

+98
-74
lines changed

2 files changed

+98
-74
lines changed

pkix/src/main/java/org/bouncycastle/cms/CMSSignedDataGenerator.java

Lines changed: 93 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
public class CMSSignedDataGenerator
5353
extends CMSSignedGenerator
5454
{
55-
private List signerInfs = new ArrayList();
5655
private boolean isDefiniteLength = false;
5756

5857
/**
@@ -105,12 +104,7 @@ public CMSSignedData generate(
105104
boolean encapsulate)
106105
throws CMSException
107106
{
108-
if (!signerInfs.isEmpty())
109-
{
110-
throw new IllegalStateException("this method can only be used with SignerInfoGenerator");
111-
}
112-
113-
// TODO
107+
// TODO
114108
// if (signerInfs.isEmpty())
115109
// {
116110
// /* RFC 3852 5.2
@@ -141,7 +135,7 @@ public CMSSignedData generate(
141135
// }
142136

143137
Set<AlgorithmIdentifier> digestAlgs = new LinkedHashSet<AlgorithmIdentifier>();
144-
ASN1EncodableVector signerInfos = new ASN1EncodableVector();
138+
ASN1EncodableVector signerInfos = new ASN1EncodableVector();
145139

146140
digests.clear(); // clear the current preserved digest state
147141

@@ -159,92 +153,59 @@ public CMSSignedData generate(
159153
//
160154
// add the SignerInfo objects
161155
//
162-
ASN1ObjectIdentifier contentTypeOID = content.getContentType();
163-
164-
ASN1OctetString octs = null;
156+
ASN1ObjectIdentifier encapContentType = content.getContentType();
157+
ASN1OctetString encapContent = null;
165158

159+
// TODO[cms] Could be unnecessary copy e.g. if content is CMSProcessableByteArray (add hasContent method?)
166160
if (content.getContent() != null)
167161
{
168-
ByteArrayOutputStream bOut = null;
169-
170162
if (encapsulate)
171163
{
172-
bOut = new ByteArrayOutputStream();
173-
}
174-
175-
OutputStream cOut = CMSUtils.attachSignersToOutputStream(signerGens, bOut);
176-
177-
// Just in case it's unencapsulated and there are no signers!
178-
cOut = CMSUtils.getSafeOutputStream(cOut);
179-
180-
try
181-
{
182-
content.write(cOut);
164+
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
183165

184-
cOut.close();
185-
}
186-
catch (IOException e)
187-
{
188-
throw new CMSException("data processing exception: " + e.getMessage(), e);
189-
}
166+
writeContentViaSignerGens(content, bOut);
190167

191-
if (encapsulate)
192-
{
193168
if (isDefiniteLength)
194169
{
195-
octs = new DEROctetString(bOut.toByteArray());
170+
encapContent = new DEROctetString(bOut.toByteArray());
196171
}
197172
else
198173
{
199-
octs = new BEROctetString(bOut.toByteArray());
174+
encapContent = new BEROctetString(bOut.toByteArray());
200175
}
201176
}
177+
else
178+
{
179+
writeContentViaSignerGens(content, null);
180+
}
202181
}
203182

204183
for (Iterator it = signerGens.iterator(); it.hasNext();)
205184
{
206-
SignerInfoGenerator sGen = (SignerInfoGenerator)it.next();
207-
SignerInfo inf = sGen.generate(contentTypeOID);
208-
209-
digestAlgs.add(inf.getDigestAlgorithm());
210-
signerInfos.add(inf);
211-
212-
byte[] calcDigest = sGen.getCalculatedDigest();
213-
214-
if (calcDigest != null)
215-
{
216-
digests.put(inf.getDigestAlgorithm().getAlgorithm().getId(), calcDigest);
217-
}
185+
SignerInfoGenerator signerGen = (SignerInfoGenerator)it.next();
186+
SignerInfo signerInfo = generateSignerInfo(signerGen, encapContentType);
187+
digestAlgs.add(signerInfo.getDigestAlgorithm());
188+
signerInfos.add(signerInfo);
218189
}
219190

220-
ASN1Set certificates = createSetFromList(certs, isDefiniteLength);
191+
ASN1Set certificates = createSetFromList(this.certs, isDefiniteLength);
221192

222-
ASN1Set certrevlist = createSetFromList(crls, isDefiniteLength);
193+
ASN1Set crls = createSetFromList(this.crls, isDefiniteLength);
223194

224-
ContentInfo encInfo = new ContentInfo(contentTypeOID, octs);
195+
ContentInfo encapContentInfo = new ContentInfo(encapContentType, encapContent);
225196

226-
SignedData sd = new SignedData(
227-
CMSUtils.convertToDlSet(digestAlgs),
228-
encInfo,
229-
certificates,
230-
certrevlist,
231-
new DERSet(signerInfos));
197+
SignedData signedData = new SignedData(
198+
CMSUtils.convertToDlSet(digestAlgs),
199+
encapContentInfo,
200+
certificates,
201+
crls,
202+
new DERSet(signerInfos));
232203

233-
ContentInfo contentInfo = new ContentInfo(
234-
CMSObjectIdentifiers.signedData, sd);
204+
ContentInfo contentInfo = new ContentInfo(CMSObjectIdentifiers.signedData, signedData);
235205

236206
return new CMSSignedData(content, contentInfo);
237207
}
238208

239-
private static ASN1Set createSetFromList(List list, boolean isDefiniteLength)
240-
{
241-
if(list.size()!=0)
242-
{
243-
return isDefiniteLength ? CMSUtils.createDlSetFromList(list) : CMSUtils.createBerSetFromList(list);
244-
}
245-
return null;
246-
}
247-
248209
/**
249210
* generate a set of one or more SignerInformation objects representing counter signatures on
250211
* the passed in SignerInformation object.
@@ -255,7 +216,71 @@ private static ASN1Set createSetFromList(List list, boolean isDefiniteLength)
255216
public SignerInformationStore generateCounterSigners(SignerInformation signer)
256217
throws CMSException
257218
{
258-
return this.generate(new CMSProcessableByteArray(null, signer.getSignature()), false).getSignerInfos();
219+
digests.clear();
220+
221+
CMSTypedData content = new CMSProcessableByteArray(null, signer.getSignature());
222+
223+
ArrayList signerInformations = new ArrayList();
224+
225+
for (Iterator it = _signers.iterator(); it.hasNext();)
226+
{
227+
SignerInformation _signer = (SignerInformation)it.next();
228+
SignerInfo signerInfo = _signer.toASN1Structure();
229+
signerInformations.add(new SignerInformation(signerInfo, null, content, null));
230+
}
231+
232+
writeContentViaSignerGens(content, null);
233+
234+
for (Iterator it = signerGens.iterator(); it.hasNext();)
235+
{
236+
SignerInfoGenerator signerGen = (SignerInfoGenerator)it.next();
237+
SignerInfo signerInfo = generateSignerInfo(signerGen, null);
238+
signerInformations.add(new SignerInformation(signerInfo, null, content, null));
239+
}
240+
241+
return new SignerInformationStore(signerInformations);
242+
}
243+
244+
private SignerInfo generateSignerInfo(SignerInfoGenerator signerGen, ASN1ObjectIdentifier contentType)
245+
throws CMSException
246+
{
247+
SignerInfo signerInfo = signerGen.generate(contentType);
248+
249+
byte[] calcDigest = signerGen.getCalculatedDigest();
250+
if (calcDigest != null)
251+
{
252+
digests.put(signerInfo.getDigestAlgorithm().getAlgorithm().getId(), calcDigest);
253+
}
254+
255+
return signerInfo;
256+
}
257+
258+
private void writeContentViaSignerGens(CMSTypedData content, OutputStream s)
259+
throws CMSException
260+
{
261+
OutputStream cOut = CMSUtils.attachSignersToOutputStream(signerGens, s);
262+
263+
// Just in case it's unencapsulated and there are no signers!
264+
cOut = CMSUtils.getSafeOutputStream(cOut);
265+
266+
try
267+
{
268+
content.write(cOut);
269+
270+
cOut.close();
271+
}
272+
catch (IOException e)
273+
{
274+
throw new CMSException("data processing exception: " + e.getMessage(), e);
275+
}
276+
}
277+
278+
private static ASN1Set createSetFromList(List list, boolean isDefiniteLength)
279+
{
280+
return list.size() < 1
281+
? null
282+
: isDefiniteLength
283+
? CMSUtils.createDlSetFromList(list)
284+
: CMSUtils.createBerSetFromList(list);
259285
}
260286
}
261-

util/src/main/java/org/bouncycastle/asn1/cms/ContentInfo.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public static ContentInfo getInstance(
7171
ASN1TaggedObject obj,
7272
boolean explicit)
7373
{
74-
return getInstance(ASN1Sequence.getInstance(obj, explicit));
74+
return new ContentInfo(ASN1Sequence.getInstance(obj, explicit));
7575
}
7676

7777
private ContentInfo(
@@ -104,11 +104,10 @@ public ContentInfo(
104104
ASN1ObjectIdentifier contentType,
105105
ASN1Encodable content)
106106
{
107-
// TODO[cms] Blocked by CMSSignedDataGenerator.generateCounterSigners transient usage of null here
108-
// if (contentType == null)
109-
// {
110-
// throw new NullPointerException("'contentType' cannot be null");
111-
// }
107+
if (contentType == null)
108+
{
109+
throw new NullPointerException("'contentType' cannot be null");
110+
}
112111

113112
this.contentType = contentType;
114113
this.content = content;

0 commit comments

Comments
 (0)