1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1.x509;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
36e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstromimport java.math.BigInteger;
46e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1Encodable;
6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1EncodableVector;
7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1Sequence;
8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.ASN1TaggedObject;
9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERInteger;
10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERObject;
11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERSequence;
12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport org.bouncycastle.asn1.DERTaggedObject;
13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/**
15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * Class for containing a restriction object subtrees in NameConstraints. See
16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * RFC 3280.
17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam *
18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * <pre>
19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam *
20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam *       GeneralSubtree ::= SEQUENCE
21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam *       {
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam *         base                    GeneralName,
23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam *         minimum         [0]     BaseDistance DEFAULT 0,
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam *         maximum         [1]     BaseDistance OPTIONAL
25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam *       }
26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * </pre>
27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam *
28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @see org.bouncycastle.asn1.x509.NameConstraints
29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam *
30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */
31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class GeneralSubtree
32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    extends ASN1Encodable
33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private static final BigInteger ZERO = BigInteger.valueOf(0);
35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private GeneralName base;
37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private DERInteger minimum;
39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private DERInteger maximum;
41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public GeneralSubtree(
43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1Sequence seq)
44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        base = GeneralName.getInstance(seq.getObjectAt(0));
46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        switch (seq.size())
48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        case 1:
50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            break;
51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        case 2:
52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            ASN1TaggedObject o = ASN1TaggedObject.getInstance(seq.getObjectAt(1));
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            switch (o.getTagNo())
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            case 0:
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                minimum = DERInteger.getInstance(o, false);
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                break;
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            case 1:
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                maximum = DERInteger.getInstance(o, false);
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                break;
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            default:
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                throw new IllegalArgumentException("Bad tag number: "
63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                        + o.getTagNo());
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            break;
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        case 3:
676e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        {
686e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            {
696e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom                ASN1TaggedObject oMin = ASN1TaggedObject.getInstance(seq.getObjectAt(1));
706e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom                if (oMin.getTagNo() != 0)
716e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom                {
726e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom                    throw new IllegalArgumentException("Bad tag number for 'minimum': " + oMin.getTagNo());
736e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom                }
746e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom                minimum = DERInteger.getInstance(oMin, false);
756e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            }
766e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
776e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            {
786e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom                ASN1TaggedObject oMax = ASN1TaggedObject.getInstance(seq.getObjectAt(2));
796e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom                if (oMax.getTagNo() != 1)
806e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom                {
816e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom                    throw new IllegalArgumentException("Bad tag number for 'maximum': " + oMax.getTagNo());
826e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom                }
836e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom                maximum = DERInteger.getInstance(oMax, false);
846e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            }
856e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            break;
876e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        }
88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        default:
89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            throw new IllegalArgumentException("Bad sequence size: "
90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    + seq.size());
91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Constructor from a given details.
96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * According RFC 3280, the minimum and maximum fields are not used with any
98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * name forms, thus minimum MUST be zero, and maximum MUST be absent.
99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * <p>
100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * If minimum is <code>null</code>, zero is assumed, if
101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * maximum is <code>null</code>, maximum is absent.
102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param base
104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *            A restriction.
105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param minimum
106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *            Minimum
107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param maximum
109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *            Maximum
110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public GeneralSubtree(
112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        GeneralName base,
113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        BigInteger minimum,
114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        BigInteger maximum)
115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.base = base;
117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (maximum != null)
118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            this.maximum = new DERInteger(maximum);
120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (minimum == null)
122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            this.minimum = null;
124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else
126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            this.minimum = new DERInteger(minimum);
128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
131c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public GeneralSubtree(GeneralName base)
132c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
133c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        this(base, null, null);
134c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
135c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static GeneralSubtree getInstance(
137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1TaggedObject o,
138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean explicit)
139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return new GeneralSubtree(ASN1Sequence.getInstance(o, explicit));
141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static GeneralSubtree getInstance(
144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Object obj)
145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj == null)
147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return null;
149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj instanceof GeneralSubtree)
152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return (GeneralSubtree) obj;
154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return new GeneralSubtree(ASN1Sequence.getInstance(obj));
157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public GeneralName getBase()
160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return base;
162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public BigInteger getMinimum()
165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
166b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (minimum == null)
167b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return ZERO;
169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return minimum.getValue();
172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public BigInteger getMaximum()
175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (maximum == null)
177b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
178b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return null;
179b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
181b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return maximum.getValue();
182b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
185b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Produce an object suitable for an ASN1OutputStream.
186b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
187b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Returns:
188b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
189b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * <pre>
190b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *       GeneralSubtree ::= SEQUENCE
191b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *       {
192b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *         base                    GeneralName,
193b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *         minimum         [0]     BaseDistance DEFAULT 0,
194b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *         maximum         [1]     BaseDistance OPTIONAL
195b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *       }
196b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * </pre>
197b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
198b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return a DERObject
199b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
200b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public DERObject toASN1Object()
201b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
202b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1EncodableVector v = new ASN1EncodableVector();
203b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
204b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        v.add(base);
205b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
206b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (minimum != null && !minimum.getValue().equals(ZERO))
207b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
208b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            v.add(new DERTaggedObject(false, 0, minimum));
209b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
210b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
211b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (maximum != null)
212b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
213b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            v.add(new DERTaggedObject(false, 1, maximum));
214b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
215b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
216b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return new DERSequence(v);
217b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
219