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.DERSequence;
13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class BasicConstraints
154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    extends ASN1Object
16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
1770c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom    ASN1Boolean  cA = ASN1Boolean.getInstance(false);
184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    ASN1Integer  pathLenConstraint = null;
19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static BasicConstraints getInstance(
21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1TaggedObject obj,
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean          explicit)
23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return getInstance(ASN1Sequence.getInstance(obj, explicit));
25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static BasicConstraints getInstance(
28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Object  obj)
29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (obj instanceof BasicConstraints)
31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return (BasicConstraints)obj;
33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
34c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (obj instanceof X509Extension)
35c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
36c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return getInstance(X509Extension.convertValueToObject((X509Extension)obj));
37c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (obj != null)
394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return new BasicConstraints(ASN1Sequence.getInstance(obj));
414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
42c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return null;
44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
4570c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom
4670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom    public static BasicConstraints fromExtensions(Extensions extensions)
4770c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom    {
4870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom        return BasicConstraints.getInstance(extensions.getExtensionParsedValue(Extension.basicConstraints));
4970c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom    }
5070c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom
514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private BasicConstraints(
52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1Sequence   seq)
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (seq.size() == 0)
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            this.cA = null;
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            this.pathLenConstraint = null;
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
61d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root            if (seq.getObjectAt(0) instanceof ASN1Boolean)
62c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
63d001700a15b8bd733ae344c1fc315b97c43c6590Kenny Root                this.cA = ASN1Boolean.getInstance(seq.getObjectAt(0));
64c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
65c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            else
66c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
67c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                this.cA = null;
684c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                this.pathLenConstraint = ASN1Integer.getInstance(seq.getObjectAt(0));
69c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (seq.size() > 1)
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
72c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (this.cA != null)
73c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    this.pathLenConstraint = ASN1Integer.getInstance(seq.getObjectAt(1));
75c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
76c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                else
77c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
78c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    throw new IllegalArgumentException("wrong sequence in constructor");
79c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public BasicConstraints(
85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean cA)
86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (cA)
88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
8970c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom            this.cA = ASN1Boolean.getInstance(true);
90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else
92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            this.cA = null;
94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.pathLenConstraint = null;
96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * create a cA=true object for the given path length constraint.
100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param pathLenConstraint
102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public BasicConstraints(
104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int     pathLenConstraint)
105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
10670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom        this.cA = ASN1Boolean.getInstance(true);
1074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        this.pathLenConstraint = new ASN1Integer(pathLenConstraint);
108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public boolean isCA()
111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return (cA != null) && cA.isTrue();
113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public BigInteger getPathLenConstraint()
116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (pathLenConstraint != null)
118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return pathLenConstraint.getValue();
120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return null;
123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Produce an object suitable for an ASN1OutputStream.
127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * <pre>
128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * BasicConstraints := SEQUENCE {
129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *    cA                  BOOLEAN DEFAULT FALSE,
130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *    pathLenConstraint   INTEGER (0..MAX) OPTIONAL
131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * }
132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * </pre>
133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
1344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public ASN1Primitive toASN1Primitive()
135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1EncodableVector  v = new ASN1EncodableVector();
137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (cA != null)
139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            v.add(cA);
141c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
142c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
143c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (pathLenConstraint != null)  // yes some people actually do this when cA is false...
144c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
145c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            v.add(pathLenConstraint);
146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return new DERSequence(v);
149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public String toString()
152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (pathLenConstraint == null)
154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (cA == null)
156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                return "BasicConstraints: isCa(false)";
158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return "BasicConstraints: isCa(" + this.isCA() + ")";
160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return "BasicConstraints: isCa(" + this.isCA() + "), pathLenConstraint = " + pathLenConstraint.getValue();
162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
164