blob: 025ffe8d556d6930c3b383aed25d1c91589b5f8c [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.security.x509;
27
28import java.io.*;
29
30import sun.security.util.*;
31
32/**
33 * Represent the GeneralSubtree ASN.1 object, whose syntax is:
34 * <pre>
35 * GeneralSubtree ::= SEQUENCE {
36 * base GeneralName,
37 * minimum [0] BaseDistance DEFAULT 0,
38 * maximum [1] BaseDistance OPTIONAL
39 * }
40 * BaseDistance ::= INTEGER (0..MAX)
41 * </pre>
42 * @author Amit Kapoor
43 * @author Hemma Prafullchandra
44 */
45public class GeneralSubtree {
46 private static final byte TAG_MIN = 0;
47 private static final byte TAG_MAX = 1;
48 private static final int MIN_DEFAULT = 0;
49
50 private GeneralName name;
51 private int minimum = MIN_DEFAULT;
52 private int maximum = -1;
53
54 private int myhash = -1;
55
56 /**
57 * The default constructor for the class.
58 *
59 * @params name the GeneralName
60 * @params min the minimum BaseDistance
61 * @params max the maximum BaseDistance
62 */
63 public GeneralSubtree(GeneralName name, int min, int max) {
64 this.name = name;
65 this.minimum = min;
66 this.maximum = max;
67 }
68
69 /**
70 * Create the object from its DER encoded form.
71 *
72 * @param val the DER encoded from of the same.
73 */
74 public GeneralSubtree(DerValue val) throws IOException {
75 if (val.tag != DerValue.tag_Sequence) {
76 throw new IOException("Invalid encoding for GeneralSubtree.");
77 }
78 name = new GeneralName(val.data.getDerValue(), true);
79
80 // NB. this is always encoded with the IMPLICIT tag
81 // The checks only make sense if we assume implicit tagging,
82 // with explicit tagging the form is always constructed.
83 while (val.data.available() != 0) {
84 DerValue opt = val.data.getDerValue();
85
86 if (opt.isContextSpecific(TAG_MIN) && !opt.isConstructed()) {
87 opt.resetTag(DerValue.tag_Integer);
88 minimum = opt.getInteger();
89
90 } else if (opt.isContextSpecific(TAG_MAX) && !opt.isConstructed()) {
91 opt.resetTag(DerValue.tag_Integer);
92 maximum = opt.getInteger();
93 } else
94 throw new IOException("Invalid encoding of GeneralSubtree.");
95 }
96 }
97
98 /**
99 * Return the GeneralName.
100 *
101 * @return the GeneralName
102 */
103 public GeneralName getName() {
104 //XXXX May want to consider cloning this
105 return name;
106 }
107
108 /**
109 * Return the minimum BaseDistance.
110 *
111 * @return the minimum BaseDistance. Default is 0 if not set.
112 */
113 public int getMinimum() {
114 return minimum;
115 }
116
117 /**
118 * Return the maximum BaseDistance.
119 *
120 * @return the maximum BaseDistance, or -1 if not set.
121 */
122 public int getMaximum() {
123 return maximum;
124 }
125
126 /**
127 * Return a printable string of the GeneralSubtree.
128 */
129 public String toString() {
130 String s = "\n GeneralSubtree: [\n" +
131 " GeneralName: " + ((name == null) ? "" : name.toString()) +
132 "\n Minimum: " + minimum;
133 if (maximum == -1) {
134 s += "\t Maximum: undefined";
135 } else
136 s += "\t Maximum: " + maximum;
137 s += " ]\n";
138 return (s);
139 }
140
141 /**
142 * Compare this GeneralSubtree with another
143 *
144 * @param other GeneralSubtree to compare to this
145 * @returns true if match
146 */
147 public boolean equals(Object other) {
148 if (!(other instanceof GeneralSubtree))
149 return false;
150 GeneralSubtree otherGS = (GeneralSubtree)other;
151 if (this.name == null) {
152 if (otherGS.name != null) {
153 return false;
154 }
155 } else {
156 if (!((this.name).equals(otherGS.name)))
157 return false;
158 }
159 if (this.minimum != otherGS.minimum)
160 return false;
161 if (this.maximum != otherGS.maximum)
162 return false;
163 return true;
164 }
165
166 /**
167 * Returns the hash code for this GeneralSubtree.
168 *
169 * @return a hash code value.
170 */
171 public int hashCode() {
172 if (myhash == -1) {
173 myhash = 17;
174 if (name != null) {
175 myhash = 37 * myhash + name.hashCode();
176 }
177 if (minimum != MIN_DEFAULT) {
178 myhash = 37 * myhash + minimum;
179 }
180 if (maximum != -1) {
181 myhash = 37 * myhash + maximum;
182 }
183 }
184 return myhash;
185 }
186
187 /**
188 * Encode the GeneralSubtree.
189 *
190 * @params out the DerOutputStream to encode this object to.
191 */
192 public void encode(DerOutputStream out) throws IOException {
193 DerOutputStream seq = new DerOutputStream();
194
195 name.encode(seq);
196
197 if (minimum != MIN_DEFAULT) {
198 DerOutputStream tmp = new DerOutputStream();
199 tmp.putInteger(minimum);
200 seq.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
201 false, TAG_MIN), tmp);
202 }
203 if (maximum != -1) {
204 DerOutputStream tmp = new DerOutputStream();
205 tmp.putInteger(maximum);
206 seq.writeImplicit(DerValue.createTag(DerValue.TAG_CONTEXT,
207 false, TAG_MAX), tmp);
208 }
209 out.write(DerValue.tag_Sequence, seq);
210 }
211}