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