001package org.apache.commons.ssl.org.bouncycastle.asn1.cms;
002
003import java.io.IOException;
004
005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Encodable;
006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Integer;
007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1OctetString;
008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1SequenceParser;
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 * Parse {@link AuthEnvelopedData} input stream.
015 * 
016 * <pre>
017 * AuthEnvelopedData ::= SEQUENCE {
018 *   version CMSVersion,
019 *   originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
020 *   recipientInfos RecipientInfos,
021 *   authEncryptedContentInfo EncryptedContentInfo,
022 *   authAttrs [1] IMPLICIT AuthAttributes OPTIONAL,
023 *   mac MessageAuthenticationCode,
024 *   unauthAttrs [2] IMPLICIT UnauthAttributes OPTIONAL }
025 * </pre>
026 */
027public class AuthEnvelopedDataParser
028{
029    private ASN1SequenceParser seq;
030    private ASN1Integer version;
031    private ASN1Encodable nextObject;
032    private boolean originatorInfoCalled;
033
034    public AuthEnvelopedDataParser(ASN1SequenceParser seq) throws IOException
035    {
036        this.seq = seq;
037
038        // TODO
039        // "It MUST be set to 0."
040        this.version = ASN1Integer.getInstance(seq.readObject());
041    }
042
043    public ASN1Integer getVersion()
044    {
045        return version;
046    }
047
048    public OriginatorInfo getOriginatorInfo()
049        throws IOException
050    {
051        originatorInfoCalled = true;
052
053        if (nextObject == null)
054        {
055            nextObject = seq.readObject();
056        }
057
058        if (nextObject instanceof ASN1TaggedObjectParser && ((ASN1TaggedObjectParser)nextObject).getTagNo() == 0)
059        {
060            ASN1SequenceParser originatorInfo = (ASN1SequenceParser) ((ASN1TaggedObjectParser)nextObject).getObjectParser(BERTags.SEQUENCE, false);
061            nextObject = null;
062            return OriginatorInfo.getInstance(originatorInfo.toASN1Primitive());
063        }
064
065        return null;
066    }
067
068    public ASN1SetParser getRecipientInfos()
069        throws IOException
070    {
071        if (!originatorInfoCalled)
072        {
073            getOriginatorInfo();
074        }
075
076        if (nextObject == null)
077        {
078            nextObject = seq.readObject();
079        }
080
081        ASN1SetParser recipientInfos = (ASN1SetParser)nextObject;
082        nextObject = null;
083        return recipientInfos;
084    }
085
086    public EncryptedContentInfoParser getAuthEncryptedContentInfo() 
087        throws IOException
088    {
089        if (nextObject == null)
090        {
091            nextObject = seq.readObject();
092        }
093
094        if (nextObject != null)
095        {
096            ASN1SequenceParser o = (ASN1SequenceParser) nextObject;
097            nextObject = null;
098            return new EncryptedContentInfoParser(o);
099        }
100
101        return null;
102    }
103
104    public ASN1SetParser getAuthAttrs()
105        throws IOException
106    {
107        if (nextObject == null)
108        {
109            nextObject = seq.readObject();
110        }
111
112        if (nextObject instanceof ASN1TaggedObjectParser)
113        {
114            ASN1Encodable o = nextObject;
115            nextObject = null;
116            return (ASN1SetParser)((ASN1TaggedObjectParser)o).getObjectParser(BERTags.SET, false);
117        }
118
119        // TODO
120        // "The authAttrs MUST be present if the content type carried in
121        // EncryptedContentInfo is not id-data."
122
123        return null;
124    }
125
126    public ASN1OctetString getMac()
127        throws IOException
128    {
129        if (nextObject == null)
130        {
131            nextObject = seq.readObject();
132        }
133
134        ASN1Encodable o = nextObject;
135        nextObject = null;
136
137        return ASN1OctetString.getInstance(o.toASN1Primitive());
138    }
139
140    public ASN1SetParser getUnauthAttrs()
141        throws IOException
142    {
143        if (nextObject == null)
144        {
145            nextObject = seq.readObject();
146        }
147
148        if (nextObject != null)
149        {
150            ASN1Encodable o = nextObject;
151            nextObject = null;
152            return (ASN1SetParser)((ASN1TaggedObjectParser)o).getObjectParser(BERTags.SET, false);
153        }
154
155        return null;
156    }
157}