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.ASN1GeneralizedTime;
008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Integer;
009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object;
010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1OctetString;
011import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive;
012import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence;
013import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject;
014import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence;
015import org.apache.commons.ssl.org.bouncycastle.asn1.DERTaggedObject;
016import org.apache.commons.ssl.org.bouncycastle.asn1.x500.X500Name;
017import org.apache.commons.ssl.org.bouncycastle.asn1.x509.AlgorithmIdentifier;
018import org.apache.commons.ssl.org.bouncycastle.asn1.x509.GeneralName;
019
020public class PKIHeader
021    extends ASN1Object
022{
023    /**
024     * Value for a "null" recipient or sender.
025     */
026    public static final GeneralName NULL_NAME = new GeneralName(X500Name.getInstance(new DERSequence()));
027
028    public static final int CMP_1999 = 1;
029    public static final int CMP_2000 = 2;
030
031    private ASN1Integer pvno;
032    private GeneralName sender;
033    private GeneralName recipient;
034    private ASN1GeneralizedTime messageTime;
035    private AlgorithmIdentifier protectionAlg;
036    private ASN1OctetString senderKID;       // KeyIdentifier
037    private ASN1OctetString recipKID;        // KeyIdentifier
038    private ASN1OctetString transactionID;
039    private ASN1OctetString senderNonce;
040    private ASN1OctetString recipNonce;
041    private PKIFreeText freeText;
042    private ASN1Sequence generalInfo;
043
044    private PKIHeader(ASN1Sequence seq)
045    {
046        Enumeration en = seq.getObjects();
047
048        pvno = ASN1Integer.getInstance(en.nextElement());
049        sender = GeneralName.getInstance(en.nextElement());
050        recipient = GeneralName.getInstance(en.nextElement());
051
052        while (en.hasMoreElements())
053        {
054            ASN1TaggedObject tObj = (ASN1TaggedObject)en.nextElement();
055
056            switch (tObj.getTagNo())
057            {
058            case 0:
059                messageTime = ASN1GeneralizedTime.getInstance(tObj, true);
060                break;
061            case 1:
062                protectionAlg = AlgorithmIdentifier.getInstance(tObj, true);
063                break;
064            case 2:
065                senderKID = ASN1OctetString.getInstance(tObj, true);
066                break;
067            case 3:
068                recipKID = ASN1OctetString.getInstance(tObj, true);
069                break;
070            case 4:
071                transactionID = ASN1OctetString.getInstance(tObj, true);
072                break;
073            case 5:
074                senderNonce = ASN1OctetString.getInstance(tObj, true);
075                break;
076            case 6:
077                recipNonce = ASN1OctetString.getInstance(tObj, true);
078                break;
079            case 7:
080                freeText = PKIFreeText.getInstance(tObj, true);
081                break;
082            case 8:
083                generalInfo = ASN1Sequence.getInstance(tObj, true);
084                break;
085            default:
086                throw new IllegalArgumentException("unknown tag number: " + tObj.getTagNo());
087            }
088        }
089    }
090
091    public static PKIHeader getInstance(Object o)
092    {
093        if (o instanceof PKIHeader)
094        {
095            return (PKIHeader)o;
096        }
097
098        if (o != null)
099        {
100            return new PKIHeader(ASN1Sequence.getInstance(o));
101        }
102
103        return null;
104    }
105
106    public PKIHeader(
107        int pvno,
108        GeneralName sender,
109        GeneralName recipient)
110    {
111        this(new ASN1Integer(pvno), sender, recipient);
112    }
113
114    private PKIHeader(
115        ASN1Integer pvno,
116        GeneralName sender,
117        GeneralName recipient)
118    {
119        this.pvno = pvno;
120        this.sender = sender;
121        this.recipient = recipient;
122    }
123
124    public ASN1Integer getPvno()
125    {
126        return pvno;
127    }
128
129    public GeneralName getSender()
130    {
131        return sender;
132    }
133
134    public GeneralName getRecipient()
135    {
136        return recipient;
137    }
138
139    public ASN1GeneralizedTime getMessageTime()
140    {
141        return messageTime;
142    }
143
144    public AlgorithmIdentifier getProtectionAlg()
145    {
146        return protectionAlg;
147    }
148
149    public ASN1OctetString getSenderKID()
150    {
151        return senderKID;
152    }
153
154    public ASN1OctetString getRecipKID()
155    {
156        return recipKID;
157    }
158
159    public ASN1OctetString getTransactionID()
160    {
161        return transactionID;
162    }
163
164    public ASN1OctetString getSenderNonce()
165    {
166        return senderNonce;
167    }
168
169    public ASN1OctetString getRecipNonce()
170    {
171        return recipNonce;
172    }
173
174    public PKIFreeText getFreeText()
175    {
176        return freeText;
177    }
178
179    public InfoTypeAndValue[] getGeneralInfo()
180    {
181        if (generalInfo == null)
182        {
183            return null;
184        }
185        InfoTypeAndValue[] results = new InfoTypeAndValue[generalInfo.size()];
186        for (int i = 0; i < results.length; i++)
187        {
188            results[i]
189                = InfoTypeAndValue.getInstance(generalInfo.getObjectAt(i));
190        }
191        return results;
192    }
193
194    /**
195     * <pre>
196     *  PKIHeader ::= SEQUENCE {
197     *            pvno                INTEGER     { cmp1999(1), cmp2000(2) },
198     *            sender              GeneralName,
199     *            -- identifies the sender
200     *            recipient           GeneralName,
201     *            -- identifies the intended recipient
202     *            messageTime     [0] GeneralizedTime         OPTIONAL,
203     *            -- time of production of this message (used when sender
204     *            -- believes that the transport will be "suitable"; i.e.,
205     *            -- that the time will still be meaningful upon receipt)
206     *            protectionAlg   [1] AlgorithmIdentifier     OPTIONAL,
207     *            -- algorithm used for calculation of protection bits
208     *            senderKID       [2] KeyIdentifier           OPTIONAL,
209     *            recipKID        [3] KeyIdentifier           OPTIONAL,
210     *            -- to identify specific keys used for protection
211     *            transactionID   [4] OCTET STRING            OPTIONAL,
212     *            -- identifies the transaction; i.e., this will be the same in
213     *            -- corresponding request, response, certConf, and PKIConf
214     *            -- messages
215     *            senderNonce     [5] OCTET STRING            OPTIONAL,
216     *            recipNonce      [6] OCTET STRING            OPTIONAL,
217     *            -- nonces used to provide replay protection, senderNonce
218     *            -- is inserted by the creator of this message; recipNonce
219     *            -- is a nonce previously inserted in a related message by
220     *            -- the intended recipient of this message
221     *            freeText        [7] PKIFreeText             OPTIONAL,
222     *            -- this may be used to indicate context-specific instructions
223     *            -- (this field is intended for human consumption)
224     *            generalInfo     [8] SEQUENCE SIZE (1..MAX) OF
225     *                                 InfoTypeAndValue     OPTIONAL
226     *            -- this may be used to convey context-specific information
227     *            -- (this field not primarily intended for human consumption)
228     * }
229     * </pre>
230     *
231     * @return a basic ASN.1 object representation.
232     */
233    public ASN1Primitive toASN1Primitive()
234    {
235        ASN1EncodableVector v = new ASN1EncodableVector();
236
237        v.add(pvno);
238        v.add(sender);
239        v.add(recipient);
240        addOptional(v, 0, messageTime);
241        addOptional(v, 1, protectionAlg);
242        addOptional(v, 2, senderKID);
243        addOptional(v, 3, recipKID);
244        addOptional(v, 4, transactionID);
245        addOptional(v, 5, senderNonce);
246        addOptional(v, 6, recipNonce);
247        addOptional(v, 7, freeText);
248        addOptional(v, 8, generalInfo);
249
250        return new DERSequence(v);
251    }
252
253    private void addOptional(ASN1EncodableVector v, int tagNo, ASN1Encodable obj)
254    {
255        if (obj != null)
256        {
257            v.add(new DERTaggedObject(true, tagNo, obj));
258        }
259    }
260}