| package org.bouncycastle.cms; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.bouncycastle.asn1.ASN1Encodable; |
| import org.bouncycastle.asn1.ASN1EncodableVector; |
| import org.bouncycastle.asn1.ASN1InputStream; |
| import org.bouncycastle.asn1.ASN1ObjectIdentifier; |
| import org.bouncycastle.asn1.ASN1Set; |
| import org.bouncycastle.asn1.BEROctetStringGenerator; |
| import org.bouncycastle.asn1.BERSet; |
| import org.bouncycastle.asn1.DERSet; |
| import org.bouncycastle.asn1.DERTaggedObject; |
| import org.bouncycastle.asn1.cms.CMSObjectIdentifiers; |
| import org.bouncycastle.asn1.cms.ContentInfo; |
| import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat; |
| import org.bouncycastle.asn1.ocsp.OCSPResponse; |
| import org.bouncycastle.asn1.ocsp.OCSPResponseStatus; |
| import org.bouncycastle.cert.X509AttributeCertificateHolder; |
| import org.bouncycastle.cert.X509CRLHolder; |
| import org.bouncycastle.cert.X509CertificateHolder; |
| import org.bouncycastle.operator.DigestCalculator; |
| import org.bouncycastle.util.Store; |
| import org.bouncycastle.util.io.Streams; |
| import org.bouncycastle.util.io.TeeInputStream; |
| import org.bouncycastle.util.io.TeeOutputStream; |
| |
| class CMSUtils |
| { |
| static ContentInfo readContentInfo( |
| byte[] input) |
| throws CMSException |
| { |
| // enforce limit checking as from a byte array |
| return readContentInfo(new ASN1InputStream(input)); |
| } |
| |
| static ContentInfo readContentInfo( |
| InputStream input) |
| throws CMSException |
| { |
| // enforce some limit checking |
| return readContentInfo(new ASN1InputStream(input)); |
| } |
| |
| static List getCertificatesFromStore(Store certStore) |
| throws CMSException |
| { |
| List certs = new ArrayList(); |
| |
| try |
| { |
| for (Iterator it = certStore.getMatches(null).iterator(); it.hasNext();) |
| { |
| X509CertificateHolder c = (X509CertificateHolder)it.next(); |
| |
| certs.add(c.toASN1Structure()); |
| } |
| |
| return certs; |
| } |
| catch (ClassCastException e) |
| { |
| throw new CMSException("error processing certs", e); |
| } |
| } |
| |
| static List getAttributeCertificatesFromStore(Store attrStore) |
| throws CMSException |
| { |
| List certs = new ArrayList(); |
| |
| try |
| { |
| for (Iterator it = attrStore.getMatches(null).iterator(); it.hasNext();) |
| { |
| X509AttributeCertificateHolder attrCert = (X509AttributeCertificateHolder)it.next(); |
| |
| certs.add(new DERTaggedObject(false, 2, attrCert.toASN1Structure())); |
| } |
| |
| return certs; |
| } |
| catch (ClassCastException e) |
| { |
| throw new CMSException("error processing certs", e); |
| } |
| } |
| |
| |
| static List getCRLsFromStore(Store crlStore) |
| throws CMSException |
| { |
| List certs = new ArrayList(); |
| |
| try |
| { |
| for (Iterator it = crlStore.getMatches(null).iterator(); it.hasNext();) |
| { |
| X509CRLHolder c = (X509CRLHolder)it.next(); |
| |
| certs.add(c.toASN1Structure()); |
| } |
| |
| return certs; |
| } |
| catch (ClassCastException e) |
| { |
| throw new CMSException("error processing certs", e); |
| } |
| } |
| |
| static Collection getOthersFromStore(ASN1ObjectIdentifier otherRevocationInfoFormat, Store otherRevocationInfos) |
| { |
| List others = new ArrayList(); |
| |
| for (Iterator it = otherRevocationInfos.getMatches(null).iterator(); it.hasNext();) |
| { |
| ASN1Encodable info = (ASN1Encodable)it.next(); |
| |
| if (CMSObjectIdentifiers.id_ri_ocsp_response.equals(otherRevocationInfoFormat)) |
| { |
| OCSPResponse resp = OCSPResponse.getInstance(info); |
| |
| if (resp.getResponseStatus().getValue().intValue() != OCSPResponseStatus.SUCCESSFUL) |
| { |
| throw new IllegalArgumentException("cannot add unsuccessful OCSP response to CMS SignedData"); |
| } |
| } |
| |
| others.add(new DERTaggedObject(false, 1, new OtherRevocationInfoFormat(otherRevocationInfoFormat, info))); |
| } |
| |
| return others; |
| } |
| |
| static ASN1Set createBerSetFromList(List derObjects) |
| { |
| ASN1EncodableVector v = new ASN1EncodableVector(); |
| |
| for (Iterator it = derObjects.iterator(); it.hasNext();) |
| { |
| v.add((ASN1Encodable)it.next()); |
| } |
| |
| return new BERSet(v); |
| } |
| |
| static ASN1Set createDerSetFromList(List derObjects) |
| { |
| ASN1EncodableVector v = new ASN1EncodableVector(); |
| |
| for (Iterator it = derObjects.iterator(); it.hasNext();) |
| { |
| v.add((ASN1Encodable)it.next()); |
| } |
| |
| return new DERSet(v); |
| } |
| |
| static OutputStream createBEROctetOutputStream(OutputStream s, |
| int tagNo, boolean isExplicit, int bufferSize) throws IOException |
| { |
| BEROctetStringGenerator octGen = new BEROctetStringGenerator(s, tagNo, isExplicit); |
| |
| if (bufferSize != 0) |
| { |
| return octGen.getOctetOutputStream(new byte[bufferSize]); |
| } |
| |
| return octGen.getOctetOutputStream(); |
| } |
| |
| private static ContentInfo readContentInfo( |
| ASN1InputStream in) |
| throws CMSException |
| { |
| try |
| { |
| return ContentInfo.getInstance(in.readObject()); |
| } |
| catch (IOException e) |
| { |
| throw new CMSException("IOException reading content.", e); |
| } |
| catch (ClassCastException e) |
| { |
| throw new CMSException("Malformed content.", e); |
| } |
| catch (IllegalArgumentException e) |
| { |
| throw new CMSException("Malformed content.", e); |
| } |
| } |
| |
| public static byte[] streamToByteArray( |
| InputStream in) |
| throws IOException |
| { |
| return Streams.readAll(in); |
| } |
| |
| public static byte[] streamToByteArray( |
| InputStream in, |
| int limit) |
| throws IOException |
| { |
| return Streams.readAllLimited(in, limit); |
| } |
| |
| static InputStream attachDigestsToInputStream(Collection digests, InputStream s) |
| { |
| InputStream result = s; |
| Iterator it = digests.iterator(); |
| while (it.hasNext()) |
| { |
| DigestCalculator digest = (DigestCalculator)it.next(); |
| result = new TeeInputStream(result, digest.getOutputStream()); |
| } |
| return result; |
| } |
| |
| static OutputStream attachSignersToOutputStream(Collection signers, OutputStream s) |
| { |
| OutputStream result = s; |
| Iterator it = signers.iterator(); |
| while (it.hasNext()) |
| { |
| SignerInfoGenerator signerGen = (SignerInfoGenerator)it.next(); |
| result = getSafeTeeOutputStream(result, signerGen.getCalculatingOutputStream()); |
| } |
| return result; |
| } |
| |
| static OutputStream getSafeOutputStream(OutputStream s) |
| { |
| return s == null ? new NullOutputStream() : s; |
| } |
| |
| static OutputStream getSafeTeeOutputStream(OutputStream s1, |
| OutputStream s2) |
| { |
| return s1 == null ? getSafeOutputStream(s2) |
| : s2 == null ? getSafeOutputStream(s1) : new TeeOutputStream( |
| s1, s2); |
| } |
| } |