1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1.x509;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
34c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport java.math.BigInteger;
44c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
570c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstromimport org.bouncycastle.asn1.ASN1Boolean;
6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1EncodableVector;
74c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Integer;
84c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Object;
94c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.asn1.ASN1Primitive;
10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1Sequence;
11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1TaggedObject;
12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERBoolean;
13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERSequence;
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class BasicConstraints
164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    extends ASN1Object
17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
1870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom    ASN1Boolean  cA = ASN1Boolean.getInstance(false);
194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    ASN1Integer  pathLenConstraint = null;
20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static BasicConstraints getInstance(
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1TaggedObject obj,
23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean          explicit)
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return getInstance(ASN1Sequence.getInstance(obj, explicit));
26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static BasicConstraints getInstance(
29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Object  obj)
30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (obj instanceof BasicConstraints)
32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return (BasicConstraints)obj;
34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
35c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (obj instanceof X509Extension)
36c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
37c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return getInstance(X509Extension.convertValueToObject((X509Extension)obj));
38c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (obj != null)
404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return new BasicConstraints(ASN1Sequence.getInstance(obj));
424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
43c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return null;
45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
4670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom
4770c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom    public static BasicConstraints fromExtensions(Extensions extensions)
4870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom    {
4970c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom        return BasicConstraints.getInstance(extensions.getExtensionParsedValue(Extension.basicConstraints));
5070c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom    }
5170c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom
524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private BasicConstraints(
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1Sequence   seq)
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (seq.size() == 0)
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            this.cA = null;
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            this.pathLenConstraint = null;
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
62c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (seq.getObjectAt(0) instanceof DERBoolean)
63c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
64c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                this.cA = DERBoolean.getInstance(seq.getObjectAt(0));
65c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
66c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            else
67c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
68c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                this.cA = null;
694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                this.pathLenConstraint = ASN1Integer.getInstance(seq.getObjectAt(0));
70c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (seq.size() > 1)
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
73c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (this.cA != null)
74c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    this.pathLenConstraint = ASN1Integer.getInstance(seq.getObjectAt(1));
76c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
77c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                else
78c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
79c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    throw new IllegalArgumentException("wrong sequence in constructor");
80c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public BasicConstraints(
86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean cA)
87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (cA)
89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
9070c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom            this.cA = ASN1Boolean.getInstance(true);
91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else
93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            this.cA = null;
95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.pathLenConstraint = null;
97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * create a cA=true object for the given path length constraint.
101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param pathLenConstraint
103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public BasicConstraints(
105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int     pathLenConstraint)
106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
10770c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom        this.cA = ASN1Boolean.getInstance(true);
1084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.pathLenConstraint = new ASN1Integer(pathLenConstraint);
109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public boolean isCA()
112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return (cA != null) && cA.isTrue();
114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public BigInteger getPathLenConstraint()
117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (pathLenConstraint != null)
119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return pathLenConstraint.getValue();
121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return null;
124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Produce an object suitable for an ASN1OutputStream.
128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * <pre>
129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * BasicConstraints := SEQUENCE {
130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *    cA                  BOOLEAN DEFAULT FALSE,
131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *    pathLenConstraint   INTEGER (0..MAX) OPTIONAL
132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * }
133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * </pre>
134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
1354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public ASN1Primitive toASN1Primitive()
136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1EncodableVector  v = new ASN1EncodableVector();
138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (cA != null)
140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            v.add(cA);
142c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
143c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
144c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (pathLenConstraint != null)  // yes some people actually do this when cA is false...
145c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
146c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            v.add(pathLenConstraint);
147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return new DERSequence(v);
150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public String toString()
153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (pathLenConstraint == null)
155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (cA == null)
157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                return "BasicConstraints: isCa(false)";
159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return "BasicConstraints: isCa(" + this.isCA() + ")";
161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return "BasicConstraints: isCa(" + this.isCA() + "), pathLenConstraint = " + pathLenConstraint.getValue();
163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
165