1:
37:
38: package ;
39:
40: import ;
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46:
47: import ;
48: import ;
49: import ;
50:
51: import ;
52:
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58:
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66:
67:
73: public class PKCS7SignedData
74: {
75:
76: public static final OID PKCS7_DATA = new OID("1.2.840.113549.1.7.1");
77: public static final OID PKCS7_SIGNED_DATA = new OID("1.2.840.113549.1.7.2");
78:
79: private BigInteger version;
80: private Set digestAlgorithms;
81: private OID contentType;
82: private byte[] content;
83: private Certificate[] certificates;
84: private CRL[] crls;
85: private Set signerInfos;
86:
87: private static final boolean DEBUG = false;
88: private static void debug(String msg)
89: {
90: System.err.print("PKCS7SignedData >> ");
91: System.err.println(msg);
92: }
93:
94: public PKCS7SignedData(InputStream in)
95: throws CRLException, CertificateException, IOException
96: {
97: this(new BERReader(in));
98: }
99:
100:
157: public PKCS7SignedData(BERReader ber)
158: throws CRLException, CertificateException, IOException
159: {
160: CertificateFactory x509 = CertificateFactory.getInstance("X509");
161: DERValue val = ber.read();
162: if (!val.isConstructed())
163: throw new BEREncodingException("malformed ContentInfo");
164:
165: val = ber.read();
166: if (val.getTag() != BER.OBJECT_IDENTIFIER)
167: throw new BEREncodingException("malformed ContentType");
168:
169: if (!PKCS7_SIGNED_DATA.equals(val.getValue()))
170: throw new BEREncodingException("content is not SignedData");
171:
172: val = ber.read();
173: if (val.getTag() != 0)
174: throw new BEREncodingException("malformed Content");
175:
176: val = ber.read();
177: if (!val.isConstructed())
178: throw new BEREncodingException("malformed SignedData");
179:
180: if (DEBUG)
181: debug("SignedData: " + val);
182:
183: val = ber.read();
184: if (val.getTag() != BER.INTEGER)
185: throw new BEREncodingException("expecting Version");
186: version = (BigInteger) val.getValue();
187:
188: if (DEBUG)
189: debug(" Version: " + version);
190:
191: digestAlgorithms = new HashSet();
192: val = ber.read();
193: if (!val.isConstructed())
194: throw new BEREncodingException("malformed DigestAlgorithmIdentifiers");
195: if (DEBUG)
196: debug(" DigestAlgorithmIdentifiers: " + val);
197: int count = 0;
198: DERValue val2 = ber.read();
199: while (val2 != BER.END_OF_SEQUENCE &&
200: (val.getLength() > 0 && val.getLength() > count))
201: {
202: if (!val2.isConstructed())
203: throw new BEREncodingException("malformed AlgorithmIdentifier");
204: if (DEBUG)
205: debug(" AlgorithmIdentifier: " + val2);
206: count += val2.getEncodedLength();
207: val2 = ber.read();
208: if (val2.getTag() != BER.OBJECT_IDENTIFIER)
209: throw new BEREncodingException("malformed AlgorithmIdentifier");
210: if (DEBUG)
211: debug(" ID: " + val2.getValue());
212: List algId = new ArrayList(2);
213: algId.add(val2.getValue());
214: val2 = ber.read();
215: if (val2 != BER.END_OF_SEQUENCE)
216: {
217: count += val2.getEncodedLength();
218: if (val2.getTag() == BER.NULL)
219: algId.add(null);
220: else
221: algId.add(val2.getEncoded());
222: if (DEBUG)
223: debug(" params: " + new BigInteger(1, val2.getEncoded()).toString(16));
224: if (val2.isConstructed())
225: ber.skip(val2.getLength());
226: if (BERValue.isIndefinite(val))
227: val2 = ber.read();
228: }
229: else
230: algId.add(null);
231: digestAlgorithms.add(algId);
232: }
233:
234: val = ber.read();
235: if (!val.isConstructed())
236: throw new BEREncodingException("malformed ContentInfo");
237: if (DEBUG)
238: debug(" ContentInfo: " + val);
239: val2 = ber.read();
240: if (val2.getTag() != BER.OBJECT_IDENTIFIER)
241: throw new BEREncodingException("malformed ContentType");
242: contentType = (OID) val2.getValue();
243: if (DEBUG)
244: debug(" ContentType: " + contentType);
245: if (BERValue.isIndefinite(val)
246: || (val.getLength() > 0 && val.getLength() > val2.getEncodedLength()))
247: {
248: val2 = ber.read();
249: if (val2 != BER.END_OF_SEQUENCE)
250: {
251: content = val2.getEncoded();
252: if (BERValue.isIndefinite(val))
253: val2 = ber.read();
254: if (DEBUG)
255: debug(" Content: " + new BigInteger(1, content).toString(16));
256: }
257: }
258:
259: val = ber.read();
260: if (val.getTag() == 0)
261: {
262: if (!val.isConstructed())
263: throw new BEREncodingException("malformed ExtendedCertificatesAndCertificates");
264: if (DEBUG)
265: debug(" ExtendedCertificatesAndCertificates: " + val);
266: count = 0;
267: val2 = ber.read();
268: List certs = new LinkedList();
269: while (val2 != BER.END_OF_SEQUENCE &&
270: (val.getLength() > 0 && val.getLength() > count))
271: {
272: Certificate cert =
273: x509.generateCertificate(new ByteArrayInputStream(val2.getEncoded()));
274: if (DEBUG)
275: debug(" Certificate: " + cert);
276: certs.add(cert);
277: count += val2.getEncodedLength();
278: ber.skip(val2.getLength());
279: if (BERValue.isIndefinite(val) || val.getLength() > count)
280: val2 = ber.read();
281: }
282: certificates = (Certificate[]) certs.toArray(new Certificate[certs.size()]);
283: val = ber.read();
284: }
285:
286: if (val.getTag() == 1)
287: {
288: if (!val.isConstructed())
289: throw new BEREncodingException("malformed CertificateRevocationLists");
290: if (DEBUG)
291: debug(" CertificateRevocationLists: " + val);
292: count = 0;
293: val2 = ber.read();
294: List crls = new LinkedList();
295: while (val2 != BER.END_OF_SEQUENCE &&
296: (val.getLength() > 0 && val.getLength() > count))
297: {
298: CRL crl = x509.generateCRL(new ByteArrayInputStream(val2.getEncoded()));
299: if (DEBUG)
300: debug (" CRL: " + crl);
301: crls.add(crl);
302: count += val2.getEncodedLength();
303: ber.skip(val2.getLength());
304: if (BERValue.isIndefinite(val) || val.getLength() > count)
305: val2 = ber.read();
306: }
307: this.crls = (CRL[]) crls.toArray(new CRL[crls.size()]);
308: val = ber.read();
309: }
310:
311: signerInfos = new HashSet();
312: if (!val.isConstructed())
313: throw new BEREncodingException("malformed SignerInfos");
314:
315: if (DEBUG)
316: debug(" SignerInfos: " + val);
317:
318:
319:
320:
321: while (true)
322: {
323: int i = ber.peek();
324: if (i == 0 || i == -1)
325: break;
326: signerInfos.add(new SignerInfo(ber));
327: }
328: }
329:
330: public BigInteger getVersion()
331: {
332: return version;
333: }
334:
335: public Certificate[] getCertificates()
336: {
337: return (certificates != null ? (Certificate[]) certificates.clone()
338: : null);
339: }
340:
341: public OID getContentType()
342: {
343: return contentType;
344: }
345:
346: public byte[] getContent()
347: {
348: return (content != null ? (byte[]) content.clone() : null);
349: }
350:
351: public Set getDigestAlgorithms()
352: {
353:
354: return Collections.unmodifiableSet(digestAlgorithms);
355: }
356:
357: public Set getSignerInfos()
358: {
359: Set copy = new HashSet();
360: for (Iterator it = signerInfos.iterator(); it.hasNext(); )
361: copy.add(it.next());
362: return Collections.unmodifiableSet(copy);
363: }
364: }