History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/security/x509/KeyUsageExtension.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/security/x509/KeyUsageExtension.java+363−0
@@ -0,0 +1,363 @@
1+/*
2+ * Copyright (c) 1997, 2006, Oracle and/or its affiliates. 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. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package sun.security.x509;
27+
28+import java.io.IOException;
29+import java.io.OutputStream;
30+import java.util.Enumeration;
31+
32+import sun.security.util.*;
33+
34+/**
35+ * Represent the Key Usage Extension.
36+ *
37+ * <p>This extension, if present, defines the purpose (e.g., encipherment,
38+ * signature, certificate signing) of the key contained in the certificate.
39+ * The usage restriction might be employed when a multipurpose key is to be
40+ * restricted (e.g., when an RSA key should be used only for signing or only
41+ * for key encipherment).
42+ *
43+ * @author Amit Kapoor
44+ * @author Hemma Prafullchandra
45+ * @see Extension
46+ * @see CertAttrSet
47+ */
48+public class KeyUsageExtension extends Extension
49+implements CertAttrSet<String> {
50+
51+ /**
52+ * Identifier for this attribute, to be used with the
53+ * get, set, delete methods of Certificate, x509 type.
54+ */
55+ public static final String IDENT = "x509.info.extensions.KeyUsage";
56+ /**
57+ * Attribute names.
58+ */
59+ public static final String NAME = "KeyUsage";
60+ public static final String DIGITAL_SIGNATURE = "digital_signature";
61+ public static final String NON_REPUDIATION = "non_repudiation";
62+ public static final String KEY_ENCIPHERMENT = "key_encipherment";
63+ public static final String DATA_ENCIPHERMENT = "data_encipherment";
64+ public static final String KEY_AGREEMENT = "key_agreement";
65+ public static final String KEY_CERTSIGN = "key_certsign";
66+ public static final String CRL_SIGN = "crl_sign";
67+ public static final String ENCIPHER_ONLY = "encipher_only";
68+ public static final String DECIPHER_ONLY = "decipher_only";
69+
70+ // Private data members
71+ private boolean[] bitString;
72+
73+ // Encode this extension value
74+ private void encodeThis() throws IOException {
75+ DerOutputStream os = new DerOutputStream();
76+ os.putTruncatedUnalignedBitString(new BitArray(this.bitString));
77+ this.extensionValue = os.toByteArray();
78+ }
79+
80+ /**
81+ * Check if bit is set.
82+ *
83+ * @param position the position in the bit string to check.
84+ */
85+ private boolean isSet(int position) {
86+ return bitString[position];
87+ }
88+
89+ /**
90+ * Set the bit at the specified position.
91+ */
92+ private void set(int position, boolean val) {
93+ // enlarge bitString if necessary
94+ if (position >= bitString.length) {
95+ boolean[] tmp = new boolean[position+1];
96+ System.arraycopy(bitString, 0, tmp, 0, bitString.length);
97+ bitString = tmp;
98+ }
99+ bitString[position] = val;
100+ }
101+
102+ /**
103+ * Create a KeyUsageExtension with the passed bit settings. The criticality
104+ * is set to true.
105+ *
106+ * @param bitString the bits to be set for the extension.
107+ */
108+ public KeyUsageExtension(byte[] bitString) throws IOException {
109+ this.bitString =
110+ new BitArray(bitString.length*8,bitString).toBooleanArray();
111+ this.extensionId = PKIXExtensions.KeyUsage_Id;
112+ this.critical = true;
113+ encodeThis();
114+ }
115+
116+ /**
117+ * Create a KeyUsageExtension with the passed bit settings. The criticality
118+ * is set to true.
119+ *
120+ * @param bitString the bits to be set for the extension.
121+ */
122+ public KeyUsageExtension(boolean[] bitString) throws IOException {
123+ this.bitString = bitString;
124+ this.extensionId = PKIXExtensions.KeyUsage_Id;
125+ this.critical = true;
126+ encodeThis();
127+ }
128+
129+ /**
130+ * Create a KeyUsageExtension with the passed bit settings. The criticality
131+ * is set to true.
132+ *
133+ * @param bitString the bits to be set for the extension.
134+ */
135+ public KeyUsageExtension(BitArray bitString) throws IOException {
136+ this.bitString = bitString.toBooleanArray();
137+ this.extensionId = PKIXExtensions.KeyUsage_Id;
138+ this.critical = true;
139+ encodeThis();
140+ }
141+
142+ /**
143+ * Create the extension from the passed DER encoded value of the same.
144+ * The DER encoded value may be wrapped in an OCTET STRING.
145+ *
146+ * @param critical true if the extension is to be treated as critical.
147+ * @param value an array of DER encoded bytes of the actual value (possibly
148+ * wrapped in an OCTET STRING).
149+ * @exception ClassCastException if value is not an array of bytes
150+ * @exception IOException on error.
151+ */
152+ public KeyUsageExtension(Boolean critical, Object value)
153+ throws IOException {
154+ this.extensionId = PKIXExtensions.KeyUsage_Id;
155+ this.critical = critical.booleanValue();
156+ /*
157+ * The following check should be activated again after
158+ * the PKIX profiling work becomes standard and the check
159+ * is not a barrier to interoperability !
160+ * if (!this.critical) {
161+ * throw new IOException("KeyUsageExtension not marked critical,"
162+ * + " invalid profile.");
163+ * }
164+ */
165+ byte[] extValue = (byte[]) value;
166+ if (extValue[0] == DerValue.tag_OctetString) {
167+ this.extensionValue = new DerValue(extValue).getOctetString();
168+ } else {
169+ this.extensionValue = extValue;
170+ }
171+ DerValue val = new DerValue(this.extensionValue);
172+ this.bitString = val.getUnalignedBitString().toBooleanArray();
173+ }
174+
175+ /**
176+ * Create a default key usage.
177+ */
178+ public KeyUsageExtension() {
179+ extensionId = PKIXExtensions.KeyUsage_Id;
180+ critical = true;
181+ bitString = new boolean[0];
182+ }
183+
184+ /**
185+ * Set the attribute value.
186+ */
187+ public void set(String name, Object obj) throws IOException {
188+ if (!(obj instanceof Boolean)) {
189+ throw new IOException("Attribute must be of type Boolean.");
190+ }
191+ boolean val = ((Boolean)obj).booleanValue();
192+ if (name.equalsIgnoreCase(DIGITAL_SIGNATURE)) {
193+ set(0,val);
194+ } else if (name.equalsIgnoreCase(NON_REPUDIATION)) {
195+ set(1,val);
196+ } else if (name.equalsIgnoreCase(KEY_ENCIPHERMENT)) {
197+ set(2,val);
198+ } else if (name.equalsIgnoreCase(DATA_ENCIPHERMENT)) {
199+ set(3,val);
200+ } else if (name.equalsIgnoreCase(KEY_AGREEMENT)) {
201+ set(4,val);
202+ } else if (name.equalsIgnoreCase(KEY_CERTSIGN)) {
203+ set(5,val);
204+ } else if (name.equalsIgnoreCase(CRL_SIGN)) {
205+ set(6,val);
206+ } else if (name.equalsIgnoreCase(ENCIPHER_ONLY)) {
207+ set(7,val);
208+ } else if (name.equalsIgnoreCase(DECIPHER_ONLY)) {
209+ set(8,val);
210+ } else {
211+ throw new IOException("Attribute name not recognized by"
212+ + " CertAttrSet:KeyUsage.");
213+ }
214+ encodeThis();
215+ }
216+
217+ /**
218+ * Get the attribute value.
219+ */
220+ public Object get(String name) throws IOException {
221+ if (name.equalsIgnoreCase(DIGITAL_SIGNATURE)) {
222+ return Boolean.valueOf(isSet(0));
223+ } else if (name.equalsIgnoreCase(NON_REPUDIATION)) {
224+ return Boolean.valueOf(isSet(1));
225+ } else if (name.equalsIgnoreCase(KEY_ENCIPHERMENT)) {
226+ return Boolean.valueOf(isSet(2));
227+ } else if (name.equalsIgnoreCase(DATA_ENCIPHERMENT)) {
228+ return Boolean.valueOf(isSet(3));
229+ } else if (name.equalsIgnoreCase(KEY_AGREEMENT)) {
230+ return Boolean.valueOf(isSet(4));
231+ } else if (name.equalsIgnoreCase(KEY_CERTSIGN)) {
232+ return Boolean.valueOf(isSet(5));
233+ } else if (name.equalsIgnoreCase(CRL_SIGN)) {
234+ return Boolean.valueOf(isSet(6));
235+ } else if (name.equalsIgnoreCase(ENCIPHER_ONLY)) {
236+ return Boolean.valueOf(isSet(7));
237+ } else if (name.equalsIgnoreCase(DECIPHER_ONLY)) {
238+ return Boolean.valueOf(isSet(8));
239+ } else {
240+ throw new IOException("Attribute name not recognized by"
241+ + " CertAttrSet:KeyUsage.");
242+ }
243+ }
244+
245+ /**
246+ * Delete the attribute value.
247+ */
248+ public void delete(String name) throws IOException {
249+ if (name.equalsIgnoreCase(DIGITAL_SIGNATURE)) {
250+ set(0,false);
251+ } else if (name.equalsIgnoreCase(NON_REPUDIATION)) {
252+ set(1,false);
253+ } else if (name.equalsIgnoreCase(KEY_ENCIPHERMENT)) {
254+ set(2,false);
255+ } else if (name.equalsIgnoreCase(DATA_ENCIPHERMENT)) {
256+ set(3,false);
257+ } else if (name.equalsIgnoreCase(KEY_AGREEMENT)) {
258+ set(4,false);
259+ } else if (name.equalsIgnoreCase(KEY_CERTSIGN)) {
260+ set(5,false);
261+ } else if (name.equalsIgnoreCase(CRL_SIGN)) {
262+ set(6,false);
263+ } else if (name.equalsIgnoreCase(ENCIPHER_ONLY)) {
264+ set(7,false);
265+ } else if (name.equalsIgnoreCase(DECIPHER_ONLY)) {
266+ set(8,false);
267+ } else {
268+ throw new IOException("Attribute name not recognized by"
269+ + " CertAttrSet:KeyUsage.");
270+ }
271+ encodeThis();
272+ }
273+
274+ /**
275+ * Returns a printable representation of the KeyUsage.
276+ */
277+ public String toString() {
278+ String s = super.toString() + "KeyUsage [\n";
279+
280+ try {
281+ if (isSet(0)) {
282+ s += " DigitalSignature\n";
283+ }
284+ if (isSet(1)) {
285+ s += " Non_repudiation\n";
286+ }
287+ if (isSet(2)) {
288+ s += " Key_Encipherment\n";
289+ }
290+ if (isSet(3)) {
291+ s += " Data_Encipherment\n";
292+ }
293+ if (isSet(4)) {
294+ s += " Key_Agreement\n";
295+ }
296+ if (isSet(5)) {
297+ s += " Key_CertSign\n";
298+ }
299+ if (isSet(6)) {
300+ s += " Crl_Sign\n";
301+ }
302+ if (isSet(7)) {
303+ s += " Encipher_Only\n";
304+ }
305+ if (isSet(8)) {
306+ s += " Decipher_Only\n";
307+ }
308+ } catch (ArrayIndexOutOfBoundsException ex) {}
309+
310+ s += "]\n";
311+
312+ return (s);
313+ }
314+
315+ /**
316+ * Write the extension to the DerOutputStream.
317+ *
318+ * @param out the DerOutputStream to write the extension to.
319+ * @exception IOException on encoding errors.
320+ */
321+ public void encode(OutputStream out) throws IOException {
322+ DerOutputStream tmp = new DerOutputStream();
323+
324+ if (this.extensionValue == null) {
325+ this.extensionId = PKIXExtensions.KeyUsage_Id;
326+ this.critical = true;
327+ encodeThis();
328+ }
329+ super.encode(tmp);
330+ out.write(tmp.toByteArray());
331+ }
332+
333+ /**
334+ * Return an enumeration of names of attributes existing within this
335+ * attribute.
336+ */
337+ public Enumeration<String> getElements() {
338+ AttributeNameEnumeration elements = new AttributeNameEnumeration();
339+ elements.addElement(DIGITAL_SIGNATURE);
340+ elements.addElement(NON_REPUDIATION);
341+ elements.addElement(KEY_ENCIPHERMENT);
342+ elements.addElement(DATA_ENCIPHERMENT);
343+ elements.addElement(KEY_AGREEMENT);
344+ elements.addElement(KEY_CERTSIGN);
345+ elements.addElement(CRL_SIGN);
346+ elements.addElement(ENCIPHER_ONLY);
347+ elements.addElement(DECIPHER_ONLY);
348+
349+ return (elements.elements());
350+ }
351+
352+
353+ public boolean[] getBits() {
354+ return bitString.clone();
355+ }
356+
357+ /**
358+ * Return the name of this attribute.
359+ */
360+ public String getName() {
361+ return (NAME);
362+ }
363+}