blob: f9c91e91feac55b50dc3429399202104d4ae862c [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2000-2006 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.IOException;
29import java.io.OutputStream;
30import java.util.Enumeration;
31
32import sun.security.util.Debug;
33import sun.security.util.DerOutputStream;
34import sun.security.util.DerValue;
35import sun.security.util.ObjectIdentifier;
36
37/**
38 * This class represents the Inhibit Any-Policy Extension.
39 *
40 * <p>The inhibit any-policy extension can be used in certificates issued
41 * to CAs. The inhibit any-policy indicates that the special any-policy
42 * OID, with the value {2 5 29 32 0}, is not considered an explicit
43 * match for other certificate policies. The value indicates the number
44 * of additional certificates that may appear in the path before any-
45 * policy is no longer permitted. For example, a value of one indicates
46 * that any-policy may be processed in certificates issued by the sub-
47 * ject of this certificate, but not in additional certificates in the
48 * path.
49 * <p>
50 * This extension MUST be critical.
51 * <p>
52 * The ASN.1 syntax for this extension is:
53 * <code><pre>
54 * id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 }
55 *
56 * InhibitAnyPolicy ::= SkipCerts
57 *
58 * SkipCerts ::= INTEGER (0..MAX)
59 * </pre></code>
60 * @author Anne Anderson
61 * @see CertAttrSet
62 * @see Extension
63 */
64public class InhibitAnyPolicyExtension extends Extension
65implements CertAttrSet<String> {
66
67 private static final Debug debug = Debug.getInstance("certpath");
68
69 /**
70 * Identifier for this attribute, to be used with the
71 * get, set, delete methods of Certificate, x509 type.
72 */
73 public static final String IDENT = "x509.info.extensions.InhibitAnyPolicy";
74
75 /**
76 * Object identifier for "any-policy"
77 */
78 public static ObjectIdentifier AnyPolicy_Id;
79 static {
80 try {
81 AnyPolicy_Id = new ObjectIdentifier("2.5.29.32.0");
82 } catch (IOException ioe) {
83 // Should not happen
84 }
85 }
86
87 /**
88 * Attribute names.
89 */
90 public static final String NAME = "InhibitAnyPolicy";
91 public static final String SKIP_CERTS = "skip_certs";
92
93 // Private data members
94 private int skipCerts = Integer.MAX_VALUE;
95
96 // Encode this extension value
97 private void encodeThis() throws IOException {
98 DerOutputStream out = new DerOutputStream();
99 out.putInteger(skipCerts);
100 this.extensionValue = out.toByteArray();
101 }
102
103 /**
104 * Default constructor for this object.
105 *
106 * @param skipCerts specifies the depth of the certification path.
107 * Use value of -1 to request unlimited depth.
108 */
109 public InhibitAnyPolicyExtension(int skipCerts) throws IOException {
110 if (skipCerts < -1)
111 throw new IOException("Invalid value for skipCerts");
112 if (skipCerts == -1)
113 this.skipCerts = Integer.MAX_VALUE;
114 else
115 this.skipCerts = skipCerts;
116 this.extensionId = PKIXExtensions.InhibitAnyPolicy_Id;
117 critical = true;
118 encodeThis();
119 }
120
121 /**
122 * Create the extension from the passed DER encoded value of the same.
123 *
124 * @param critical criticality flag to use. Must be true for this
125 * extension.
126 * @param value a byte array holding the DER-encoded extension value.
127 * @exception ClassCastException if value is not an array of bytes
128 * @exception IOException on error.
129 */
130 public InhibitAnyPolicyExtension(Boolean critical, Object value)
131 throws IOException {
132
133 this.extensionId = PKIXExtensions.InhibitAnyPolicy_Id;
134
135 if (!critical.booleanValue())
136 throw new IOException("Criticality cannot be false for " +
137 "InhibitAnyPolicy");
138 this.critical = critical.booleanValue();
139
140 this.extensionValue = (byte[]) value;
141 DerValue val = new DerValue(this.extensionValue);
142 if (val.tag != DerValue.tag_Integer)
143 throw new IOException("Invalid encoding of InhibitAnyPolicy: "
144 + "data not integer");
145
146 if (val.data == null)
147 throw new IOException("Invalid encoding of InhibitAnyPolicy: "
148 + "null data");
149 int skipCertsValue = val.getInteger();
150 if (skipCertsValue < -1)
151 throw new IOException("Invalid value for skipCerts");
152 if (skipCertsValue == -1) {
153 this.skipCerts = Integer.MAX_VALUE;
154 } else {
155 this.skipCerts = skipCertsValue;
156 }
157 }
158
159 /**
160 * Return user readable form of extension.
161 */
162 public String toString() {
163 String s = super.toString() + "InhibitAnyPolicy: " + skipCerts + "\n";
164 return s;
165 }
166
167 /**
168 * Encode this extension value to the output stream.
169 *
170 * @param out the DerOutputStream to encode the extension to.
171 */
172 public void encode(OutputStream out) throws IOException {
173 DerOutputStream tmp = new DerOutputStream();
174 if (extensionValue == null) {
175 this.extensionId = PKIXExtensions.InhibitAnyPolicy_Id;
176 critical = true;
177 encodeThis();
178 }
179 super.encode(tmp);
180
181 out.write(tmp.toByteArray());
182 }
183
184 /**
185 * Set the attribute value.
186 *
187 * @param name name of attribute to set. Must be SKIP_CERTS.
188 * @param obj value to which attribute is to be set. Must be Integer
189 * type.
190 * @throws IOException on error
191 */
192 public void set(String name, Object obj) throws IOException {
193 if (name.equalsIgnoreCase(SKIP_CERTS)) {
194 if (!(obj instanceof Integer))
195 throw new IOException("Attribute value should be of type Integer.");
196 int skipCertsValue = ((Integer)obj).intValue();
197 if (skipCertsValue < -1)
198 throw new IOException("Invalid value for skipCerts");
199 if (skipCertsValue == -1) {
200 skipCerts = Integer.MAX_VALUE;
201 } else {
202 skipCerts = skipCertsValue;
203 }
204 } else
205 throw new IOException("Attribute name not recognized by " +
206 "CertAttrSet:InhibitAnyPolicy.");
207 encodeThis();
208 }
209
210 /**
211 * Get the attribute value.
212 *
213 * @param name name of attribute to get. Must be SKIP_CERTS.
214 * @returns value of the attribute. In this case it will be of type
215 * Integer.
216 * @throws IOException on error
217 */
218 public Object get(String name) throws IOException {
219 if (name.equalsIgnoreCase(SKIP_CERTS))
220 return (new Integer(skipCerts));
221 else
222 throw new IOException("Attribute name not recognized by " +
223 "CertAttrSet:InhibitAnyPolicy.");
224 }
225
226 /**
227 * Delete the attribute value.
228 *
229 * @param name name of attribute to delete. Must be SKIP_CERTS.
230 * @throws IOException on error. In this case, IOException will always be
231 * thrown, because the only attribute, SKIP_CERTS, is
232 * required.
233 */
234 public void delete(String name) throws IOException {
235 if (name.equalsIgnoreCase(SKIP_CERTS))
236 throw new IOException("Attribute " + SKIP_CERTS +
237 " may not be deleted.");
238 else
239 throw new IOException("Attribute name not recognized by " +
240 "CertAttrSet:InhibitAnyPolicy.");
241 }
242
243 /**
244 * Return an enumeration of names of attributes existing within this
245 * attribute.
246 *
247 * @returns enumeration of elements
248 */
249 public Enumeration<String> getElements() {
250 AttributeNameEnumeration elements = new AttributeNameEnumeration();
251 elements.addElement(SKIP_CERTS);
252 return (elements.elements());
253 }
254
255 /**
256 * Return the name of this attribute.
257 *
258 * @returns name of attribute.
259 */
260 public String getName() {
261 return (NAME);
262 }
263}