001package org.apache.commons.ssl.org.bouncycastle.asn1.cmp;
002
003import java.util.Enumeration;
004
005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Encodable;
006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector;
007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object;
008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive;
009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence;
010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject;
011import org.apache.commons.ssl.org.bouncycastle.asn1.DERBitString;
012import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence;
013import org.apache.commons.ssl.org.bouncycastle.asn1.DERTaggedObject;
014
015public class PKIMessage
016    extends ASN1Object
017{
018    private PKIHeader header;
019    private PKIBody body;
020    private DERBitString protection;
021    private ASN1Sequence extraCerts;
022
023    private PKIMessage(ASN1Sequence seq)
024    {
025        Enumeration en = seq.getObjects();
026
027        header = PKIHeader.getInstance(en.nextElement());
028        body = PKIBody.getInstance(en.nextElement());
029
030        while (en.hasMoreElements())
031        {
032            ASN1TaggedObject tObj = (ASN1TaggedObject)en.nextElement();
033
034            if (tObj.getTagNo() == 0)
035            {
036                protection = DERBitString.getInstance(tObj, true);
037            }
038            else
039            {
040                extraCerts = ASN1Sequence.getInstance(tObj, true);
041            }
042        }
043    }
044
045    public static PKIMessage getInstance(Object o)
046    {
047        if (o instanceof PKIMessage)
048        {
049            return (PKIMessage)o;
050        }
051        else if (o != null)
052        {
053            return new PKIMessage(ASN1Sequence.getInstance(o));
054        }
055
056        return null;
057    }
058
059    /**
060     * Creates a new PKIMessage.
061     *
062     * @param header     message header
063     * @param body       message body
064     * @param protection message protection (may be null)
065     * @param extraCerts extra certificates (may be null)
066     */
067    public PKIMessage(
068        PKIHeader header,
069        PKIBody body,
070        DERBitString protection,
071        CMPCertificate[] extraCerts)
072    {
073        this.header = header;
074        this.body = body;
075        this.protection = protection;
076        if (extraCerts != null)
077        {
078            ASN1EncodableVector v = new ASN1EncodableVector();
079            for (int i = 0; i < extraCerts.length; i++)
080            {
081                v.add(extraCerts[i]);
082            }
083            this.extraCerts = new DERSequence(v);
084        }
085    }
086
087    public PKIMessage(
088        PKIHeader header,
089        PKIBody body,
090        DERBitString protection)
091    {
092        this(header, body, protection, null);
093    }
094
095    public PKIMessage(
096        PKIHeader header,
097        PKIBody body)
098    {
099        this(header, body, null, null);
100    }
101
102    public PKIHeader getHeader()
103    {
104        return header;
105    }
106
107    public PKIBody getBody()
108    {
109        return body;
110    }
111
112    public DERBitString getProtection()
113    {
114        return protection;
115    }
116
117    public CMPCertificate[] getExtraCerts()
118    {
119        if (extraCerts == null)
120        {
121            return null;
122        }
123
124        CMPCertificate[] results = new CMPCertificate[extraCerts.size()];
125
126        for (int i = 0; i < results.length; i++)
127        {
128            results[i] = CMPCertificate.getInstance(extraCerts.getObjectAt(i));
129        }
130        return results;
131    }
132
133    /**
134     * <pre>
135     * PKIMessage ::= SEQUENCE {
136     *                  header           PKIHeader,
137     *                  body             PKIBody,
138     *                  protection   [0] PKIProtection OPTIONAL,
139     *                  extraCerts   [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
140     *                                                                     OPTIONAL
141     * }
142     * </pre>
143     *
144     * @return a basic ASN.1 object representation.
145     */
146    public ASN1Primitive toASN1Primitive()
147    {
148        ASN1EncodableVector v = new ASN1EncodableVector();
149
150        v.add(header);
151        v.add(body);
152
153        addOptional(v, 0, protection);
154        addOptional(v, 1, extraCerts);
155
156        return new DERSequence(v);
157    }
158
159    private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj)
160    {
161        if (obj != null)
162        {
163            v.add(new DERTaggedObject(true, tagNo, obj));
164        }
165    }
166}