001package org.apache.commons.ssl.org.bouncycastle.asn1.x509;
002
003import java.io.IOException;
004
005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Boolean;
006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Encodable;
007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector;
008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object;
009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1ObjectIdentifier;
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.DEROctetString;
014import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence;
015
016/**
017 * an object for the elements in the X.509 V3 extension block.
018 */
019public class Extension
020    extends ASN1Object
021{
022    /**
023     * Subject Directory Attributes
024     */
025    public static final ASN1ObjectIdentifier subjectDirectoryAttributes = new ASN1ObjectIdentifier("2.5.29.9");
026    
027    /**
028     * Subject Key Identifier 
029     */
030    public static final ASN1ObjectIdentifier subjectKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.14");
031
032    /**
033     * Key Usage 
034     */
035    public static final ASN1ObjectIdentifier keyUsage = new ASN1ObjectIdentifier("2.5.29.15");
036
037    /**
038     * Private Key Usage Period 
039     */
040    public static final ASN1ObjectIdentifier privateKeyUsagePeriod = new ASN1ObjectIdentifier("2.5.29.16");
041
042    /**
043     * Subject Alternative Name 
044     */
045    public static final ASN1ObjectIdentifier subjectAlternativeName = new ASN1ObjectIdentifier("2.5.29.17");
046
047    /**
048     * Issuer Alternative Name 
049     */
050    public static final ASN1ObjectIdentifier issuerAlternativeName = new ASN1ObjectIdentifier("2.5.29.18");
051
052    /**
053     * Basic Constraints 
054     */
055    public static final ASN1ObjectIdentifier basicConstraints = new ASN1ObjectIdentifier("2.5.29.19");
056
057    /**
058     * CRL Number 
059     */
060    public static final ASN1ObjectIdentifier cRLNumber = new ASN1ObjectIdentifier("2.5.29.20");
061
062    /**
063     * Reason code 
064     */
065    public static final ASN1ObjectIdentifier reasonCode = new ASN1ObjectIdentifier("2.5.29.21");
066
067    /**
068     * Hold Instruction Code 
069     */
070    public static final ASN1ObjectIdentifier instructionCode = new ASN1ObjectIdentifier("2.5.29.23");
071
072    /**
073     * Invalidity Date 
074     */
075    public static final ASN1ObjectIdentifier invalidityDate = new ASN1ObjectIdentifier("2.5.29.24");
076
077    /**
078     * Delta CRL indicator 
079     */
080    public static final ASN1ObjectIdentifier deltaCRLIndicator = new ASN1ObjectIdentifier("2.5.29.27");
081
082    /**
083     * Issuing Distribution Point 
084     */
085    public static final ASN1ObjectIdentifier issuingDistributionPoint = new ASN1ObjectIdentifier("2.5.29.28");
086
087    /**
088     * Certificate Issuer 
089     */
090    public static final ASN1ObjectIdentifier certificateIssuer = new ASN1ObjectIdentifier("2.5.29.29");
091
092    /**
093     * Name Constraints 
094     */
095    public static final ASN1ObjectIdentifier nameConstraints = new ASN1ObjectIdentifier("2.5.29.30");
096
097    /**
098     * CRL Distribution Points 
099     */
100    public static final ASN1ObjectIdentifier cRLDistributionPoints = new ASN1ObjectIdentifier("2.5.29.31");
101
102    /**
103     * Certificate Policies 
104     */
105    public static final ASN1ObjectIdentifier certificatePolicies = new ASN1ObjectIdentifier("2.5.29.32");
106
107    /**
108     * Policy Mappings 
109     */
110    public static final ASN1ObjectIdentifier policyMappings = new ASN1ObjectIdentifier("2.5.29.33");
111
112    /**
113     * Authority Key Identifier 
114     */
115    public static final ASN1ObjectIdentifier authorityKeyIdentifier = new ASN1ObjectIdentifier("2.5.29.35");
116
117    /**
118     * Policy Constraints 
119     */
120    public static final ASN1ObjectIdentifier policyConstraints = new ASN1ObjectIdentifier("2.5.29.36");
121
122    /**
123     * Extended Key Usage 
124     */
125    public static final ASN1ObjectIdentifier extendedKeyUsage = new ASN1ObjectIdentifier("2.5.29.37");
126
127    /**
128     * Freshest CRL
129     */
130    public static final ASN1ObjectIdentifier freshestCRL = new ASN1ObjectIdentifier("2.5.29.46");
131     
132    /**
133     * Inhibit Any Policy
134     */
135    public static final ASN1ObjectIdentifier inhibitAnyPolicy = new ASN1ObjectIdentifier("2.5.29.54");
136
137    /**
138     * Authority Info Access
139     */
140    public static final ASN1ObjectIdentifier authorityInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.1");
141
142    /**
143     * Subject Info Access
144     */
145    public static final ASN1ObjectIdentifier subjectInfoAccess = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.11");
146    
147    /**
148     * Logo Type
149     */
150    public static final ASN1ObjectIdentifier logoType = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.12");
151
152    /**
153     * BiometricInfo
154     */
155    public static final ASN1ObjectIdentifier biometricInfo = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.2");
156    
157    /**
158     * QCStatements
159     */
160    public static final ASN1ObjectIdentifier qCStatements = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.3");
161
162    /**
163     * Audit identity extension in attribute certificates.
164     */
165    public static final ASN1ObjectIdentifier auditIdentity = new ASN1ObjectIdentifier("1.3.6.1.5.5.7.1.4");
166    
167    /**
168     * NoRevAvail extension in attribute certificates.
169     */
170    public static final ASN1ObjectIdentifier noRevAvail = new ASN1ObjectIdentifier("2.5.29.56");
171
172    /**
173     * TargetInformation extension in attribute certificates.
174     */
175    public static final ASN1ObjectIdentifier targetInformation = new ASN1ObjectIdentifier("2.5.29.55");
176
177    private ASN1ObjectIdentifier extnId;
178    private boolean             critical;
179    private ASN1OctetString      value;
180
181    public Extension(
182        ASN1ObjectIdentifier extnId,
183        ASN1Boolean critical,
184        ASN1OctetString value)
185    {
186        this(extnId, critical.isTrue(), value);
187    }
188
189    public Extension(
190        ASN1ObjectIdentifier extnId,
191        boolean critical,
192        byte[] value)
193    {
194        this(extnId, critical, new DEROctetString(value));
195    }
196
197    public Extension(
198        ASN1ObjectIdentifier extnId,
199        boolean critical,
200        ASN1OctetString value)
201    {
202        this.extnId = extnId;
203        this.critical = critical;
204        this.value = value;
205    }
206
207    private Extension(ASN1Sequence seq)
208    {
209        if (seq.size() == 2)
210        {
211            this.extnId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
212            this.critical = false;
213            this.value = ASN1OctetString.getInstance(seq.getObjectAt(1));
214        }
215        else if (seq.size() == 3)
216        {
217            this.extnId = ASN1ObjectIdentifier.getInstance(seq.getObjectAt(0));
218            this.critical = ASN1Boolean.getInstance(seq.getObjectAt(1)).isTrue();
219            this.value = ASN1OctetString.getInstance(seq.getObjectAt(2));
220        }
221        else
222        {
223            throw new IllegalArgumentException("Bad sequence size: " + seq.size());
224        }
225    }
226
227    public static Extension getInstance(Object obj)
228    {
229        if (obj instanceof Extension)
230        {
231            return (Extension)obj;
232        }
233        else if (obj != null)
234        {
235            return new Extension(ASN1Sequence.getInstance(obj));
236        }
237
238        return null;
239    }
240
241    public ASN1ObjectIdentifier getExtnId()
242    {
243        return extnId;
244    }
245
246    public boolean isCritical()
247    {
248        return critical;
249    }
250
251    public ASN1OctetString getExtnValue()
252    {
253        return value;
254    }
255
256    public ASN1Encodable getParsedValue()
257    {
258        return convertValueToObject(this);
259    }
260
261    public int hashCode()
262    {
263        if (this.isCritical())
264        {
265            return this.getExtnValue().hashCode() ^ this.getExtnId().hashCode();
266        }
267
268        return ~(this.getExtnValue().hashCode() ^ this.getExtnId().hashCode());
269    }
270
271    public boolean equals(
272        Object  o)
273    {
274        if (!(o instanceof Extension))
275        {
276            return false;
277        }
278
279        Extension other = (Extension)o;
280
281        return other.getExtnId().equals(this.getExtnId())
282            && other.getExtnValue().equals(this.getExtnValue())
283            && (other.isCritical() == this.isCritical());
284    }
285
286    public ASN1Primitive toASN1Primitive()
287    {
288        ASN1EncodableVector v = new ASN1EncodableVector();
289
290        v.add(extnId);
291
292        if (critical)
293        {
294            v.add(ASN1Boolean.getInstance(true));
295        }
296
297        v.add(value);
298
299        return new DERSequence(v);
300    }
301
302    /**
303     * Convert the value of the passed in extension to an object
304     * @param ext the extension to parse
305     * @return the object the value string contains
306     * @exception IllegalArgumentException if conversion is not possible
307     */
308    private static ASN1Primitive convertValueToObject(
309        Extension ext)
310        throws IllegalArgumentException
311    {
312        try
313        {
314            return ASN1Primitive.fromByteArray(ext.getExtnValue().getOctets());
315        }
316        catch (IOException e)
317        {
318            throw new IllegalArgumentException("can't convert extension: " +  e);
319        }
320    }
321}