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/ExtendedKeyUsageExtension.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/security/x509/ExtendedKeyUsageExtension.java+312−0
@@ -0,0 +1,312 @@
1+/*
2+ * Copyright (c) 2000, 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.ArrayList;
31+import java.util.Enumeration;
32+import java.util.HashMap;
33+import java.util.List;
34+import java.util.Map;
35+import java.util.Vector;
36+
37+import sun.security.util.DerValue;
38+import sun.security.util.DerOutputStream;
39+import sun.security.util.ObjectIdentifier;
40+
41+/**
42+ * This class defines the Extended Key Usage Extension, which
43+ * indicates one or more purposes for which the certified public key
44+ * may be used, in addition to or in place of the basic purposes
45+ * indicated in the key usage extension field. This field is defined
46+ * as follows:<p>
47+ *
48+ * id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37}<p>
49+ *
50+ * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId<p>
51+ *
52+ * KeyPurposeId ::= OBJECT IDENTIFIER<p>
53+ *
54+ * Key purposes may be defined by any organization with a need. Object
55+ * identifiers used to identify key purposes shall be assigned in
56+ * accordance with IANA or ITU-T Rec. X.660 | ISO/IEC/ITU 9834-1.<p>
57+ *
58+ * This extension may, at the option of the certificate issuer, be
59+ * either critical or non-critical.<p>
60+ *
61+ * If the extension is flagged critical, then the certificate MUST be
62+ * used only for one of the purposes indicated.<p>
63+ *
64+ * If the extension is flagged non-critical, then it indicates the
65+ * intended purpose or purposes of the key, and may be used in finding
66+ * the correct key/certificate of an entity that has multiple
67+ * keys/certificates. It is an advisory field and does not imply that
68+ * usage of the key is restricted by the certification authority to
69+ * the purpose indicated. Certificate using applications may
70+ * nevertheless require that a particular purpose be indicated in
71+ * order for the certificate to be acceptable to that application.<p>
72+
73+ * If a certificate contains both a critical key usage field and a
74+ * critical extended key usage field, then both fields MUST be
75+ * processed independently and the certificate MUST only be used for a
76+ * purpose consistent with both fields. If there is no purpose
77+ * consistent with both fields, then the certificate MUST NOT be used
78+ * for any purpose.<p>
79+ *
80+ * @since 1.4
81+ */
82+public class ExtendedKeyUsageExtension extends Extension
83+implements CertAttrSet<String> {
84+
85+ /**
86+ * Identifier for this attribute, to be used with the
87+ * get, set, delete methods of Certificate, x509 type.
88+ */
89+ public static final String IDENT = "x509.info.extensions.ExtendedKeyUsage";
90+
91+ /**
92+ * Attribute names.
93+ */
94+ public static final String NAME = "ExtendedKeyUsage";
95+ public static final String USAGES = "usages";
96+
97+ // OID defined in RFC 3280 Sections 4.2.1.13
98+ // more from http://www.alvestrand.no/objectid/1.3.6.1.5.5.7.3.html
99+ private static final Map <ObjectIdentifier, String> map =
100+ new HashMap <ObjectIdentifier, String> ();
101+
102+ private static final int[] anyExtendedKeyUsageOidData = {2, 5, 29, 37, 0};
103+ private static final int[] serverAuthOidData = {1, 3, 6, 1, 5, 5, 7, 3, 1};
104+ private static final int[] clientAuthOidData = {1, 3, 6, 1, 5, 5, 7, 3, 2};
105+ private static final int[] codeSigningOidData = {1, 3, 6, 1, 5, 5, 7, 3, 3};
106+ private static final int[] emailProtectionOidData = {1, 3, 6, 1, 5, 5, 7, 3, 4};
107+ private static final int[] ipsecEndSystemOidData = {1, 3, 6, 1, 5, 5, 7, 3, 5};
108+ private static final int[] ipsecTunnelOidData = {1, 3, 6, 1, 5, 5, 7, 3, 6};
109+ private static final int[] ipsecUserOidData = {1, 3, 6, 1, 5, 5, 7, 3, 7};
110+ private static final int[] timeStampingOidData = {1, 3, 6, 1, 5, 5, 7, 3, 8};
111+ private static final int[] OCSPSigningOidData = {1, 3, 6, 1, 5, 5, 7, 3, 9};
112+
113+ static {
114+ map.put(ObjectIdentifier.newInternal(anyExtendedKeyUsageOidData), "anyExtendedKeyUsage");
115+ map.put(ObjectIdentifier.newInternal(serverAuthOidData), "serverAuth");
116+ map.put(ObjectIdentifier.newInternal(clientAuthOidData), "clientAuth");
117+ map.put(ObjectIdentifier.newInternal(codeSigningOidData), "codeSigning");
118+ map.put(ObjectIdentifier.newInternal(emailProtectionOidData), "emailProtection");
119+ map.put(ObjectIdentifier.newInternal(ipsecEndSystemOidData), "ipsecEndSystem");
120+ map.put(ObjectIdentifier.newInternal(ipsecTunnelOidData), "ipsecTunnel");
121+ map.put(ObjectIdentifier.newInternal(ipsecUserOidData), "ipsecUser");
122+ map.put(ObjectIdentifier.newInternal(timeStampingOidData), "timeStamping");
123+ map.put(ObjectIdentifier.newInternal(OCSPSigningOidData), "OCSPSigning");
124+ };
125+
126+ /**
127+ * Vector of KeyUsages for this object.
128+ */
129+ private Vector<ObjectIdentifier> keyUsages;
130+
131+ // Encode this extension value.
132+ private void encodeThis() throws IOException {
133+ if (keyUsages == null || keyUsages.isEmpty()) {
134+ this.extensionValue = null;
135+ return;
136+ }
137+ DerOutputStream os = new DerOutputStream();
138+ DerOutputStream tmp = new DerOutputStream();
139+
140+ for (int i = 0; i < keyUsages.size(); i++) {
141+ tmp.putOID(keyUsages.elementAt(i));
142+ }
143+
144+ os.write(DerValue.tag_Sequence, tmp);
145+ this.extensionValue = os.toByteArray();
146+ }
147+
148+ /**
149+ * Create a ExtendedKeyUsageExtension object from
150+ * a Vector of Key Usages; the criticality is set to false.
151+ *
152+ * @param keyUsages the Vector of KeyUsages (ObjectIdentifiers)
153+ */
154+ public ExtendedKeyUsageExtension(Vector<ObjectIdentifier> keyUsages)
155+ throws IOException {
156+ this(Boolean.FALSE, keyUsages);
157+ }
158+
159+ /**
160+ * Create a ExtendedKeyUsageExtension object from
161+ * a Vector of KeyUsages with specified criticality.
162+ *
163+ * @param critical true if the extension is to be treated as critical.
164+ * @param keyUsages the Vector of KeyUsages (ObjectIdentifiers)
165+ */
166+ public ExtendedKeyUsageExtension(Boolean critical, Vector<ObjectIdentifier> keyUsages)
167+ throws IOException {
168+ this.keyUsages = keyUsages;
169+ this.extensionId = PKIXExtensions.ExtendedKeyUsage_Id;
170+ this.critical = critical.booleanValue();
171+ encodeThis();
172+ }
173+
174+ /**
175+ * Create the extension from its DER encoded value and criticality.
176+ *
177+ * @param critical true if the extension is to be treated as critical.
178+ * @param value an array of DER encoded bytes of the actual value.
179+ * @exception ClassCastException if value is not an array of bytes
180+ * @exception IOException on error.
181+ */
182+ public ExtendedKeyUsageExtension(Boolean critical, Object value)
183+ throws IOException {
184+ this.extensionId = PKIXExtensions.ExtendedKeyUsage_Id;
185+ this.critical = critical.booleanValue();
186+ this.extensionValue = (byte[]) value;
187+ DerValue val = new DerValue(this.extensionValue);
188+ if (val.tag != DerValue.tag_Sequence) {
189+ throw new IOException("Invalid encoding for " +
190+ "ExtendedKeyUsageExtension.");
191+ }
192+ keyUsages = new Vector<ObjectIdentifier>();
193+ while (val.data.available() != 0) {
194+ DerValue seq = val.data.getDerValue();
195+ ObjectIdentifier usage = seq.getOID();
196+ keyUsages.addElement(usage);
197+ }
198+ }
199+
200+ /**
201+ * Return the extension as user readable string.
202+ */
203+ public String toString() {
204+ if (keyUsages == null) return "";
205+ String usage = " ";
206+ boolean first = true;
207+ for (ObjectIdentifier oid: keyUsages) {
208+ if(!first) {
209+ usage += "\n ";
210+ }
211+
212+ String result = map.get(oid);
213+ if (result != null) {
214+ usage += result;
215+ } else {
216+ usage += oid.toString();
217+ }
218+ first = false;
219+ }
220+ return super.toString() + "ExtendedKeyUsages [\n"
221+ + usage + "\n]\n";
222+ }
223+
224+ /**
225+ * Write the extension to the DerOutputStream.
226+ *
227+ * @param out the DerOutputStream to write the extension to.
228+ * @exception IOException on encoding errors.
229+ */
230+ public void encode(OutputStream out) throws IOException {
231+ DerOutputStream tmp = new DerOutputStream();
232+ if (extensionValue == null) {
233+ extensionId = PKIXExtensions.ExtendedKeyUsage_Id;
234+ critical = false;
235+ encodeThis();
236+ }
237+ super.encode(tmp);
238+ out.write(tmp.toByteArray());
239+ }
240+
241+ /**
242+ * Set the attribute value.
243+ */
244+ public void set(String name, Object obj) throws IOException {
245+ if (name.equalsIgnoreCase(USAGES)) {
246+ if (!(obj instanceof Vector)) {
247+ throw new IOException("Attribute value should be of type Vector.");
248+ }
249+ this.keyUsages = (Vector<ObjectIdentifier>)obj;
250+ } else {
251+ throw new IOException("Attribute name [" + name +
252+ "] not recognized by " +
253+ "CertAttrSet:ExtendedKeyUsageExtension.");
254+ }
255+ encodeThis();
256+ }
257+
258+ /**
259+ * Get the attribute value.
260+ */
261+ public Object get(String name) throws IOException {
262+ if (name.equalsIgnoreCase(USAGES)) {
263+ //XXXX May want to consider cloning this
264+ return keyUsages;
265+ } else {
266+ throw new IOException("Attribute name [" + name +
267+ "] not recognized by " +
268+ "CertAttrSet:ExtendedKeyUsageExtension.");
269+ }
270+ }
271+
272+ /**
273+ * Delete the attribute value.
274+ */
275+ public void delete(String name) throws IOException {
276+ if (name.equalsIgnoreCase(USAGES)) {
277+ keyUsages = null;
278+ } else {
279+ throw new IOException("Attribute name [" + name +
280+ "] not recognized by " +
281+ "CertAttrSet:ExtendedKeyUsageExtension.");
282+ }
283+ encodeThis();
284+ }
285+
286+ /**
287+ * Return an enumeration of names of attributes existing within this
288+ * attribute.
289+ */
290+ public Enumeration<String> getElements() {
291+ AttributeNameEnumeration elements = new AttributeNameEnumeration();
292+ elements.addElement(USAGES);
293+
294+ return (elements.elements());
295+ }
296+
297+ /**
298+ * Return the name of this attribute.
299+ */
300+ public String getName() {
301+ return (NAME);
302+ }
303+
304+ public List<String> getExtendedKeyUsage() {
305+ List<String> al = new ArrayList<String>(keyUsages.size());
306+ for (ObjectIdentifier oid : keyUsages) {
307+ al.add(oid.toString());
308+ }
309+ return al;
310+ }
311+
312+}