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.asn1.x509.X509CertificateStructure;
011: import org.bouncycastle.util.StreamParsingException;
012: import org.bouncycastle.x509.X509StreamParserSpi;
013:
014: import java.io.BufferedInputStream;
015: import java.io.IOException;
016: import java.io.InputStream;
017: import java.security.cert.Certificate;
018: import java.security.cert.CertificateParsingException;
019: import java.util.ArrayList;
020: import java.util.Collection;
021: import java.util.List;
022:
023: public class X509CertParser extends X509StreamParserSpi {
024: private static final PEMUtil PEM_PARSER = new PEMUtil("CERTIFICATE");
025:
026: private ASN1Set sData = null;
027: private int sDataObjectCount = 0;
028: private InputStream currentStream = null;
029:
030: private Certificate readDERCertificate(InputStream in)
031: throws IOException, CertificateParsingException {
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 X509CertificateObject(X509CertificateStructure
049: .getInstance(seq));
050: }
051:
052: private Certificate getCertificate()
053: throws CertificateParsingException {
054: if (sData != null) {
055: while (sDataObjectCount < sData.size()) {
056: Object obj = sData.getObjectAt(sDataObjectCount++);
057:
058: if (obj instanceof ASN1Sequence) {
059: return new X509CertificateObject(
060: X509CertificateStructure.getInstance(obj));
061: }
062: }
063: }
064:
065: return null;
066: }
067:
068: private Certificate readPEMCertificate(InputStream in)
069: throws IOException, CertificateParsingException {
070: ASN1Sequence seq = PEM_PARSER.readPEMObject(in);
071:
072: if (seq != null) {
073: return new X509CertificateObject(X509CertificateStructure
074: .getInstance(seq));
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: Certificate cert;
124: List certs = new ArrayList();
125:
126: while ((cert = (Certificate) engineRead()) != null) {
127: certs.add(cert);
128: }
129:
130: return certs;
131: }
132: }
|