001package org.apache.commons.ssl.org.bouncycastle.asn1.cms;
002
003import java.io.IOException;
004
005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Integer;
006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence;
007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1SequenceParser;
008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Set;
009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1SetParser;
010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObjectParser;
011import org.apache.commons.ssl.org.bouncycastle.asn1.BERTags;
012
013/**
014 * Parser for <a href="http://tools.ietf.org/html/rfc5652#section-5.1">RFC 5652</a>: {@link SignedData} object.
015 * <p>
016 * <pre>
017 * SignedData ::= SEQUENCE {
018 *     version CMSVersion,
019 *     digestAlgorithms DigestAlgorithmIdentifiers,
020 *     encapContentInfo EncapsulatedContentInfo,
021 *     certificates [0] IMPLICIT CertificateSet OPTIONAL,
022 *     crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
023 *     signerInfos SignerInfos
024 *   }
025 * </pre>
026 */
027public class SignedDataParser
028{
029    private ASN1SequenceParser _seq;
030    private ASN1Integer         _version;
031    private Object             _nextObject;
032    private boolean            _certsCalled;
033    private boolean            _crlsCalled;
034
035    public static SignedDataParser getInstance(
036        Object o)
037        throws IOException
038    {
039        if (o instanceof ASN1Sequence)
040        {
041            return new SignedDataParser(((ASN1Sequence)o).parser());
042        }
043        if (o instanceof ASN1SequenceParser)
044        {
045            return new SignedDataParser((ASN1SequenceParser)o);
046        }
047
048        throw new IOException("unknown object encountered: " + o.getClass().getName());
049    }
050
051    private SignedDataParser(
052        ASN1SequenceParser seq)
053        throws IOException
054    {
055        this._seq = seq;
056        this._version = (ASN1Integer)seq.readObject();
057    }
058
059    public ASN1Integer getVersion()
060    {
061        return _version;
062    }
063
064    public ASN1SetParser getDigestAlgorithms()
065        throws IOException
066    {
067        Object o = _seq.readObject();
068
069        if (o instanceof ASN1Set)
070        {
071            return ((ASN1Set)o).parser();
072        }
073
074        return (ASN1SetParser)o;
075    }
076
077    public ContentInfoParser getEncapContentInfo()
078        throws IOException
079    {
080        return new ContentInfoParser((ASN1SequenceParser)_seq.readObject());
081    }
082
083    public ASN1SetParser getCertificates()
084        throws IOException
085    {
086        _certsCalled = true;
087        _nextObject = _seq.readObject();
088
089        if (_nextObject instanceof ASN1TaggedObjectParser && ((ASN1TaggedObjectParser)_nextObject).getTagNo() == 0)
090        {
091            ASN1SetParser certs = (ASN1SetParser)((ASN1TaggedObjectParser)_nextObject).getObjectParser(BERTags.SET, false);
092            _nextObject = null;
093
094            return certs;
095        }
096
097        return null;
098    }
099
100    public ASN1SetParser getCrls()
101        throws IOException
102    {
103        if (!_certsCalled)
104        {
105            throw new IOException("getCerts() has not been called.");
106        }
107
108        _crlsCalled = true;
109
110        if (_nextObject == null)
111        {
112            _nextObject = _seq.readObject();
113        }
114
115        if (_nextObject instanceof ASN1TaggedObjectParser && ((ASN1TaggedObjectParser)_nextObject).getTagNo() == 1)
116        {
117            ASN1SetParser crls = (ASN1SetParser)((ASN1TaggedObjectParser)_nextObject).getObjectParser(BERTags.SET, false);
118            _nextObject = null;
119
120            return crls;
121        }
122
123        return null;
124    }
125
126    public ASN1SetParser getSignerInfos()
127        throws IOException
128    {
129        if (!_certsCalled || !_crlsCalled)
130        {
131            throw new IOException("getCerts() and/or getCrls() has not been called.");
132        }
133
134        if (_nextObject == null)
135        {
136            _nextObject = _seq.readObject();
137        }
138
139        return (ASN1SetParser)_nextObject;
140    }
141}