001: package org.bouncycastle.jce.provider;
002:
003: import org.bouncycastle.asn1.ASN1InputStream;
004: import org.bouncycastle.asn1.ASN1Sequence;
005: import org.bouncycastle.asn1.ASN1Set;
006: import org.bouncycastle.asn1.ASN1TaggedObject;
007: import org.bouncycastle.asn1.DERObjectIdentifier;
008: import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
009: import org.bouncycastle.asn1.pkcs.SignedData;
010: import org.bouncycastle.util.StreamParsingException;
011: import org.bouncycastle.x509.X509AttributeCertificate;
012: import org.bouncycastle.x509.X509StreamParserSpi;
013: import org.bouncycastle.x509.X509V2AttributeCertificate;
014:
015: import java.io.BufferedInputStream;
016: import java.io.IOException;
017: import java.io.InputStream;
018: import java.util.ArrayList;
019: import java.util.Collection;
020: import java.util.List;
021:
022: public class X509AttrCertParser extends X509StreamParserSpi {
023: private static final PEMUtil PEM_PARSER = new PEMUtil(
024: "ATTRIBUTE CERTIFICATE");
025:
026: private ASN1Set sData = null;
027: private int sDataObjectCount = 0;
028: private InputStream currentStream = null;
029:
030: private X509AttributeCertificate readDERCertificate(InputStream in)
031: throws IOException {
032: ASN1InputStream dIn = new ASN1InputStream(in, ProviderUtil
033: .getReadLimit(in));
034: ASN1Sequence seq = (ASN1Sequence) dIn.readObject();
035:
036: if (seq.size() > 1
037: && seq.getObjectAt(0) instanceof DERObjectIdentifier) {
038: if (seq.getObjectAt(0).equals(
039: PKCSObjectIdentifiers.signedData)) {
040: sData = new SignedData(ASN1Sequence.getInstance(
041: (ASN1TaggedObject) seq.getObjectAt(1), true))
042: .getCertificates();
043:
044: return getCertificate();
045: }
046: }
047:
048: return new X509V2AttributeCertificate(seq.getEncoded());
049: }
050:
051: private X509AttributeCertificate getCertificate()
052: throws IOException {
053: if (sData != null) {
054: while (sDataObjectCount < sData.size()) {
055: Object obj = sData.getObjectAt(sDataObjectCount++);
056:
057: if (obj instanceof ASN1TaggedObject
058: && ((ASN1TaggedObject) obj).getTagNo() == 2) {
059: return new X509V2AttributeCertificate(ASN1Sequence
060: .getInstance((ASN1TaggedObject) obj, false)
061: .getEncoded());
062: }
063: }
064: }
065:
066: return null;
067: }
068:
069: private X509AttributeCertificate readPEMCertificate(InputStream in)
070: throws IOException {
071: ASN1Sequence seq = PEM_PARSER.readPEMObject(in);
072:
073: if (seq != null) {
074: return new X509V2AttributeCertificate(seq.getEncoded());
075: }
076:
077: return null;
078: }
079:
080: public void engineInit(InputStream in) {
081: currentStream = in;
082: sData = null;
083: sDataObjectCount = 0;
084:
085: if (!currentStream.markSupported()) {
086: currentStream = new BufferedInputStream(currentStream);
087: }
088: }
089:
090: public Object engineRead() throws StreamParsingException {
091: try {
092: if (sData != null) {
093: if (sDataObjectCount != sData.size()) {
094: return getCertificate();
095: } else {
096: sData = null;
097: sDataObjectCount = 0;
098: return null;
099: }
100: }
101:
102: currentStream.mark(10);
103: int tag = currentStream.read();
104:
105: if (tag == -1) {
106: return null;
107: }
108:
109: if (tag != 0x30) // assume ascii PEM encoded.
110: {
111: currentStream.reset();
112: return readPEMCertificate(currentStream);
113: } else {
114: currentStream.reset();
115: return readDERCertificate(currentStream);
116: }
117: } catch (Exception e) {
118: throw new StreamParsingException(e.toString(), e);
119: }
120: }
121:
122: public Collection engineReadAll() throws StreamParsingException {
123: X509AttributeCertificate cert;
124: List certs = new ArrayList();
125:
126: while ((cert = (X509AttributeCertificate) engineRead()) != null) {
127: certs.add(cert);
128: }
129:
130: return certs;
131: }
132: }
|