1package org.bouncycastle.asn1.x509;
2
3import java.math.BigInteger;
4
5import org.bouncycastle.asn1.ASN1EncodableVector;
6import org.bouncycastle.asn1.ASN1Sequence;
7import org.bouncycastle.asn1.ASN1TaggedObject;
8import org.bouncycastle.asn1.DERBoolean;
9import org.bouncycastle.asn1.ASN1Encodable;
10import org.bouncycastle.asn1.DERInteger;
11import org.bouncycastle.asn1.DERObject;
12import org.bouncycastle.asn1.DERSequence;
13
14public class BasicConstraints
15    extends ASN1Encodable
16{
17    // BEGIN android-changed
18    DERBoolean  cA = DERBoolean.FALSE;
19    // END android-changed
20    DERInteger  pathLenConstraint = null;
21
22    public static BasicConstraints getInstance(
23        ASN1TaggedObject obj,
24        boolean          explicit)
25    {
26        return getInstance(ASN1Sequence.getInstance(obj, explicit));
27    }
28
29    public static BasicConstraints getInstance(
30        Object  obj)
31    {
32        if (obj == null || obj instanceof BasicConstraints)
33        {
34            return (BasicConstraints)obj;
35        }
36        else if (obj instanceof ASN1Sequence)
37        {
38            return new BasicConstraints((ASN1Sequence)obj);
39        }
40
41        throw new IllegalArgumentException("unknown object in factory");
42    }
43
44    public BasicConstraints(
45        ASN1Sequence   seq)
46    {
47        if (seq.size() == 0)
48        {
49            this.cA = null;
50            this.pathLenConstraint = null;
51        }
52        else
53        {
54            this.cA = DERBoolean.getInstance(seq.getObjectAt(0));
55            if (seq.size() > 1)
56            {
57                this.pathLenConstraint = DERInteger.getInstance(seq.getObjectAt(1));
58            }
59        }
60    }
61
62    /**
63     * @deprecated use one of the other two unambigous constructors.
64     * @param cA
65     * @param pathLenConstraint
66     */
67    public BasicConstraints(
68        boolean cA,
69        int     pathLenConstraint)
70    {
71        if (cA)
72        {
73            // BEGIN android-changed
74            this.cA = DERBoolean.getInstance(cA);
75            // END android-changed
76            this.pathLenConstraint = new DERInteger(pathLenConstraint);
77        }
78        else
79        {
80            this.cA = null;
81            this.pathLenConstraint = null;
82        }
83    }
84
85    public BasicConstraints(
86        boolean cA)
87    {
88        if (cA)
89        {
90            // BEGIN android-changed
91            this.cA = DERBoolean.TRUE;
92            // END android-changed
93        }
94        else
95        {
96            this.cA = null;
97        }
98        this.pathLenConstraint = null;
99    }
100
101    /**
102     * create a cA=true object for the given path length constraint.
103     *
104     * @param pathLenConstraint
105     */
106    public BasicConstraints(
107        int     pathLenConstraint)
108    {
109        // BEGIN android-changed
110        this.cA = DERBoolean.TRUE;
111        // END android-changed
112        this.pathLenConstraint = new DERInteger(pathLenConstraint);
113    }
114
115    public boolean isCA()
116    {
117        return (cA != null) && cA.isTrue();
118    }
119
120    public BigInteger getPathLenConstraint()
121    {
122        if (pathLenConstraint != null)
123        {
124            return pathLenConstraint.getValue();
125        }
126
127        return null;
128    }
129
130    /**
131     * Produce an object suitable for an ASN1OutputStream.
132     * <pre>
133     * BasicConstraints := SEQUENCE {
134     *    cA                  BOOLEAN DEFAULT FALSE,
135     *    pathLenConstraint   INTEGER (0..MAX) OPTIONAL
136     * }
137     * </pre>
138     */
139    public DERObject toASN1Object()
140    {
141        ASN1EncodableVector  v = new ASN1EncodableVector();
142
143        if (cA != null)
144        {
145            v.add(cA);
146
147            if (pathLenConstraint != null)
148            {
149                v.add(pathLenConstraint);
150            }
151        }
152
153        return new DERSequence(v);
154    }
155
156    public String toString()
157    {
158        if (pathLenConstraint == null)
159        {
160            if (cA == null)
161            {
162                return "BasicConstraints: isCa(false)";
163            }
164            return "BasicConstraints: isCa(" + this.isCA() + ")";
165        }
166        return "BasicConstraints: isCa(" + this.isCA() + "), pathLenConstraint = " + pathLenConstraint.getValue();
167    }
168}
169