• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.bouncycastle.cms;
2 
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.io.OutputStream;
6 import java.util.ArrayList;
7 import java.util.Collection;
8 import java.util.HashSet;
9 import java.util.Iterator;
10 import java.util.List;
11 import java.util.Set;
12 
13 import org.bouncycastle.asn1.ASN1Encodable;
14 import org.bouncycastle.asn1.ASN1EncodableVector;
15 import org.bouncycastle.asn1.ASN1InputStream;
16 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
17 import org.bouncycastle.asn1.ASN1Set;
18 import org.bouncycastle.asn1.ASN1TaggedObject;
19 import org.bouncycastle.asn1.BEROctetStringGenerator;
20 import org.bouncycastle.asn1.BERSet;
21 import org.bouncycastle.asn1.DERNull;
22 import org.bouncycastle.asn1.DERSet;
23 import org.bouncycastle.asn1.DERTaggedObject;
24 import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
25 import org.bouncycastle.asn1.cms.ContentInfo;
26 // BEGIN android-removed
27 // import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat;
28 // import org.bouncycastle.asn1.ocsp.OCSPResponse;
29 // import org.bouncycastle.asn1.ocsp.OCSPResponseStatus;
30 // import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
31 // import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
32 // END android-removed
33 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
34 import org.bouncycastle.cert.X509AttributeCertificateHolder;
35 import org.bouncycastle.cert.X509CRLHolder;
36 import org.bouncycastle.cert.X509CertificateHolder;
37 import org.bouncycastle.operator.DigestCalculator;
38 import org.bouncycastle.util.Store;
39 import org.bouncycastle.util.Strings;
40 import org.bouncycastle.util.io.Streams;
41 import org.bouncycastle.util.io.TeeInputStream;
42 import org.bouncycastle.util.io.TeeOutputStream;
43 
44 class CMSUtils
45 {
46     private static final Set<String> des = new HashSet<String>();
47 
48     static
49     {
50         des.add("DES");
51         des.add("DESEDE");
52         // BEGIN android-removed
53         // des.add(OIWObjectIdentifiers.desCBC.getId());
54         // des.add(PKCSObjectIdentifiers.des_EDE3_CBC.getId());
55         // des.add(PKCSObjectIdentifiers.des_EDE3_CBC.getId());
56         // des.add(PKCSObjectIdentifiers.id_alg_CMS3DESwrap.getId());
57         // END android-removed
58     }
59 
isDES(String algorithmID)60     static boolean isDES(String algorithmID)
61     {
62         String name = Strings.toUpperCase(algorithmID);
63 
64         return des.contains(name);
65     }
66 
isEquivalent(AlgorithmIdentifier algId1, AlgorithmIdentifier algId2)67     static boolean isEquivalent(AlgorithmIdentifier algId1, AlgorithmIdentifier algId2)
68     {
69         if (algId1 == null || algId2 == null)
70         {
71             return false;
72         }
73 
74         if (!algId1.getAlgorithm().equals(algId2.getAlgorithm()))
75         {
76             return false;
77         }
78 
79         ASN1Encodable params1 = algId1.getParameters();
80         ASN1Encodable params2 = algId2.getParameters();
81         if (params1 != null)
82         {
83             return params1.equals(params2) || (params1.equals(DERNull.INSTANCE) && params2 == null);
84         }
85 
86         return params2 == null || params2.equals(DERNull.INSTANCE);
87     }
88 
readContentInfo( byte[] input)89     static ContentInfo readContentInfo(
90         byte[] input)
91         throws CMSException
92     {
93         // enforce limit checking as from a byte array
94         return readContentInfo(new ASN1InputStream(input));
95     }
96 
readContentInfo( InputStream input)97     static ContentInfo readContentInfo(
98         InputStream input)
99         throws CMSException
100     {
101         // enforce some limit checking
102         return readContentInfo(new ASN1InputStream(input));
103     }
104 
getCertificatesFromStore(Store certStore)105     static List getCertificatesFromStore(Store certStore)
106         throws CMSException
107     {
108         List certs = new ArrayList();
109 
110         try
111         {
112             for (Iterator it = certStore.getMatches(null).iterator(); it.hasNext();)
113             {
114                 X509CertificateHolder c = (X509CertificateHolder)it.next();
115 
116                 certs.add(c.toASN1Structure());
117             }
118 
119             return certs;
120         }
121         catch (ClassCastException e)
122         {
123             throw new CMSException("error processing certs", e);
124         }
125     }
126 
getAttributeCertificatesFromStore(Store attrStore)127     static List getAttributeCertificatesFromStore(Store attrStore)
128         throws CMSException
129     {
130         List certs = new ArrayList();
131 
132         try
133         {
134             for (Iterator it = attrStore.getMatches(null).iterator(); it.hasNext();)
135             {
136                 X509AttributeCertificateHolder attrCert = (X509AttributeCertificateHolder)it.next();
137 
138                 certs.add(new DERTaggedObject(false, 2, attrCert.toASN1Structure()));
139             }
140 
141             return certs;
142         }
143         catch (ClassCastException e)
144         {
145             throw new CMSException("error processing certs", e);
146         }
147     }
148 
149 
getCRLsFromStore(Store crlStore)150     static List getCRLsFromStore(Store crlStore)
151         throws CMSException
152     {
153         List crls = new ArrayList();
154 
155         try
156         {
157             for (Iterator it = crlStore.getMatches(null).iterator(); it.hasNext();)
158             {
159                 Object rev = it.next();
160 
161                 if (rev instanceof X509CRLHolder)
162                 {
163                     X509CRLHolder c = (X509CRLHolder)rev;
164 
165                     crls.add(c.toASN1Structure());
166                 }
167                 // BEGIN android-removed
168                 // else if (rev instanceof OtherRevocationInfoFormat)
169                 // {
170                 //     OtherRevocationInfoFormat infoFormat = OtherRevocationInfoFormat.getInstance(rev);
171                 //
172                 //     validateInfoFormat(infoFormat);
173                 //
174                 //     crls.add(new DERTaggedObject(false, 1, infoFormat));
175                 // }
176                 // END android-removed
177                 else if (rev instanceof ASN1TaggedObject)
178                 {
179                     crls.add(rev);
180                 }
181             }
182 
183             return crls;
184         }
185         catch (ClassCastException e)
186         {
187             throw new CMSException("error processing certs", e);
188         }
189     }
190 
191     // BEGIN android-removed
192     // private static void validateInfoFormat(OtherRevocationInfoFormat infoFormat)
193     // {
194     //     if (CMSObjectIdentifiers.id_ri_ocsp_response.equals(infoFormat.getInfoFormat()))
195     //     {
196     //         OCSPResponse resp = OCSPResponse.getInstance(infoFormat.getInfo());
197     //
198     //         if (resp.getResponseStatus().getValue().intValue() != OCSPResponseStatus.SUCCESSFUL)
199     //         {
200     //             throw new IllegalArgumentException("cannot add unsuccessful OCSP response to CMS SignedData");
201     //         }
202     //     }
203     // }
204     //
205     // static Collection getOthersFromStore(ASN1ObjectIdentifier otherRevocationInfoFormat, Store otherRevocationInfos)
206     // {
207     //     List others = new ArrayList();
208     //
209     //     for (Iterator it = otherRevocationInfos.getMatches(null).iterator(); it.hasNext();)
210     //     {
211     //         ASN1Encodable info = (ASN1Encodable)it.next();
212     //         OtherRevocationInfoFormat infoFormat = new OtherRevocationInfoFormat(otherRevocationInfoFormat, info);
213     //         validateInfoFormat(infoFormat);
214     //
215     //         others.add(new DERTaggedObject(false, 1, infoFormat));
216     //     }
217     //
218     //     return others;
219     // }
220     // END android-removed
221 
createBerSetFromList(List derObjects)222     static ASN1Set createBerSetFromList(List derObjects)
223     {
224         ASN1EncodableVector v = new ASN1EncodableVector();
225 
226         for (Iterator it = derObjects.iterator(); it.hasNext();)
227         {
228             v.add((ASN1Encodable)it.next());
229         }
230 
231         return new BERSet(v);
232     }
233 
createDerSetFromList(List derObjects)234     static ASN1Set createDerSetFromList(List derObjects)
235     {
236         ASN1EncodableVector v = new ASN1EncodableVector();
237 
238         for (Iterator it = derObjects.iterator(); it.hasNext();)
239         {
240             v.add((ASN1Encodable)it.next());
241         }
242 
243         return new DERSet(v);
244     }
245 
createBEROctetOutputStream(OutputStream s, int tagNo, boolean isExplicit, int bufferSize)246     static OutputStream createBEROctetOutputStream(OutputStream s,
247             int tagNo, boolean isExplicit, int bufferSize) throws IOException
248     {
249         BEROctetStringGenerator octGen = new BEROctetStringGenerator(s, tagNo, isExplicit);
250 
251         if (bufferSize != 0)
252         {
253             return octGen.getOctetOutputStream(new byte[bufferSize]);
254         }
255 
256         return octGen.getOctetOutputStream();
257     }
258 
readContentInfo( ASN1InputStream in)259     private static ContentInfo readContentInfo(
260         ASN1InputStream in)
261         throws CMSException
262     {
263         try
264         {
265             return ContentInfo.getInstance(in.readObject());
266         }
267         catch (IOException e)
268         {
269             throw new CMSException("IOException reading content.", e);
270         }
271         catch (ClassCastException e)
272         {
273             throw new CMSException("Malformed content.", e);
274         }
275         catch (IllegalArgumentException e)
276         {
277             throw new CMSException("Malformed content.", e);
278         }
279     }
280 
streamToByteArray( InputStream in)281     public static byte[] streamToByteArray(
282         InputStream in)
283         throws IOException
284     {
285         return Streams.readAll(in);
286     }
287 
streamToByteArray( InputStream in, int limit)288     public static byte[] streamToByteArray(
289         InputStream in,
290         int         limit)
291         throws IOException
292     {
293         return Streams.readAllLimited(in, limit);
294     }
295 
attachDigestsToInputStream(Collection digests, InputStream s)296     static InputStream attachDigestsToInputStream(Collection digests, InputStream s)
297     {
298         InputStream result = s;
299         Iterator it = digests.iterator();
300         while (it.hasNext())
301         {
302             DigestCalculator digest = (DigestCalculator)it.next();
303             result = new TeeInputStream(result, digest.getOutputStream());
304         }
305         return result;
306     }
307 
attachSignersToOutputStream(Collection signers, OutputStream s)308     static OutputStream attachSignersToOutputStream(Collection signers, OutputStream s)
309     {
310         OutputStream result = s;
311         Iterator it = signers.iterator();
312         while (it.hasNext())
313         {
314             SignerInfoGenerator signerGen = (SignerInfoGenerator)it.next();
315             result = getSafeTeeOutputStream(result, signerGen.getCalculatingOutputStream());
316         }
317         return result;
318     }
319 
getSafeOutputStream(OutputStream s)320     static OutputStream getSafeOutputStream(OutputStream s)
321     {
322         return s == null ? new NullOutputStream() : s;
323     }
324 
getSafeTeeOutputStream(OutputStream s1, OutputStream s2)325     static OutputStream getSafeTeeOutputStream(OutputStream s1,
326             OutputStream s2)
327     {
328         return s1 == null ? getSafeOutputStream(s2)
329                 : s2 == null ? getSafeOutputStream(s1) : new TeeOutputStream(
330                         s1, s2);
331     }
332 }
333