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

Unified · Split

java/pkg/sun/security/provider/certpath/X509CertPath.java+387−0
@@ -0,0 +1,387 @@
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.provider.certpath;
27+
28+import java.io.BufferedInputStream;
29+import java.io.ByteArrayInputStream;
30+import java.io.ByteArrayOutputStream;
31+import java.io.IOException;
32+import java.io.InputStream;
33+import java.security.cert.CertificateEncodingException;
34+import java.security.cert.Certificate;
35+import java.security.cert.CertificateException;
36+import java.security.cert.CertificateFactory;
37+import java.security.cert.X509Certificate;
38+import java.util.*;
39+import java.security.cert.CertPath;
40+import sun.security.pkcs.ContentInfo;
41+import sun.security.pkcs.PKCS7;
42+import sun.security.pkcs.SignerInfo;
43+import sun.security.x509.AlgorithmId;
44+import sun.security.util.DerValue;
45+import sun.security.util.DerOutputStream;
46+import sun.security.util.DerInputStream;
47+
48+
49+/**
50+ * A {@link java.security.cert.CertPath CertPath} (certification path)
51+ * consisting exclusively of
52+ * {@link java.security.cert.X509Certificate X509Certificate}s.
53+ * <p>
54+ * By convention, X.509 <code>CertPath</code>s are stored from target
55+ * to trust anchor.
56+ * That is, the issuer of one certificate is the subject of the following
57+ * one. However, unvalidated X.509 <code>CertPath</code>s may not follow
58+ * this convention. PKIX <code>CertPathValidator</code>s will detect any
59+ * departure from this convention and throw a
60+ * <code>CertPathValidatorException</code>.
61+ *
62+ * @author Yassir Elley
63+ * @since 1.4
64+ */
65+public class X509CertPath extends CertPath {
66+
67+ private static final long serialVersionUID = 4989800333263052980L;
68+
69+ /**
70+ * List of certificates in this chain
71+ */
72+ private List<X509Certificate> certs;
73+
74+ /**
75+ * The names of our encodings. PkiPath is the default.
76+ */
77+ private static final String COUNT_ENCODING = "count";
78+ private static final String PKCS7_ENCODING = "PKCS7";
79+ private static final String PKIPATH_ENCODING = "PkiPath";
80+
81+ /**
82+ * List of supported encodings
83+ */
84+ private static final Collection<String> encodingList;
85+
86+ static {
87+ List<String> list = new ArrayList<String>(2);
88+ list.add(PKIPATH_ENCODING);
89+ list.add(PKCS7_ENCODING);
90+ encodingList = Collections.unmodifiableCollection(list);
91+ }
92+
93+ /**
94+ * Creates an <code>X509CertPath</code> from a <code>List</code> of
95+ * <code>X509Certificate</code>s.
96+ * <p>
97+ * The certificates are copied out of the supplied <code>List</code>
98+ * object.
99+ *
100+ * @param certs a <code>List</code> of <code>X509Certificate</code>s
101+ * @exception CertificateException if <code>certs</code> contains an element
102+ * that is not an <code>X509Certificate</code>
103+ */
104+ public X509CertPath(List<? extends Certificate> certs) throws CertificateException {
105+ super("X.509");
106+
107+ // Ensure that the List contains only X509Certificates
108+ for (Object obj : (List<?>)certs) {
109+ if (obj instanceof X509Certificate == false) {
110+ throw new CertificateException
111+ ("List is not all X509Certificates: "
112+ + obj.getClass().getName());
113+ }
114+ }
115+
116+ // Assumes that the resulting List is thread-safe. This is true
117+ // because we ensure that it cannot be modified after construction
118+ // and the methods in the Sun JDK 1.4 implementation of ArrayList that
119+ // allow read-only access are thread-safe.
120+ this.certs = Collections.unmodifiableList(
121+ new ArrayList<X509Certificate>((List<X509Certificate>)certs));
122+ }
123+
124+ /**
125+ * Creates an <code>X509CertPath</code>, reading the encoded form
126+ * from an <code>InputStream</code>. The data is assumed to be in
127+ * the default encoding.
128+ *
129+ * @param is the <code>InputStream</code> to read the data from
130+ * @exception CertificateException if an exception occurs while decoding
131+ */
132+ public X509CertPath(InputStream is) throws CertificateException {
133+ this(is, PKIPATH_ENCODING);
134+ }
135+
136+ /**
137+ * Creates an <code>X509CertPath</code>, reading the encoded form
138+ * from an InputStream. The data is assumed to be in the specified
139+ * encoding.
140+ *
141+ * @param is the <code>InputStream</code> to read the data from
142+ * @param encoding the encoding used
143+ * @exception CertificateException if an exception occurs while decoding or
144+ * the encoding requested is not supported
145+ */
146+ public X509CertPath(InputStream is, String encoding)
147+ throws CertificateException {
148+ super("X.509");
149+
150+ if (PKIPATH_ENCODING.equals(encoding)) {
151+ certs = parsePKIPATH(is);
152+ } else if (PKCS7_ENCODING.equals(encoding)) {
153+ certs = parsePKCS7(is);
154+ } else {
155+ throw new CertificateException("unsupported encoding");
156+ }
157+ }
158+
159+ /**
160+ * Parse a PKIPATH format CertPath from an InputStream. Return an
161+ * unmodifiable List of the certificates.
162+ *
163+ * @param is the <code>InputStream</code> to read the data from
164+ * @return an unmodifiable List of the certificates
165+ * @exception CertificateException if an exception occurs
166+ */
167+ private static List<X509Certificate> parsePKIPATH(InputStream is)
168+ throws CertificateException {
169+ List<X509Certificate> certList = null;
170+ CertificateFactory certFac = null;
171+
172+ if (is == null) {
173+ throw new CertificateException("input stream is null");
174+ }
175+
176+ try {
177+ DerInputStream dis = new DerInputStream(readAllBytes(is));
178+ DerValue[] seq = dis.getSequence(3);
179+ if (seq.length == 0) {
180+ return Collections.<X509Certificate>emptyList();
181+ }
182+
183+ certFac = CertificateFactory.getInstance("X.509");
184+ certList = new ArrayList<X509Certificate>(seq.length);
185+
186+ // append certs in reverse order (target to trust anchor)
187+ for (int i = seq.length-1; i >= 0; i--) {
188+ certList.add((X509Certificate)certFac.generateCertificate
189+ (new ByteArrayInputStream(seq[i].toByteArray())));
190+ }
191+
192+ return Collections.unmodifiableList(certList);
193+
194+ } catch (IOException ioe) {
195+ CertificateException ce = new CertificateException("IOException" +
196+ " parsing PkiPath data: " + ioe);
197+ ce.initCause(ioe);
198+ throw ce;
199+ }
200+ }
201+
202+ /**
203+ * Parse a PKCS#7 format CertPath from an InputStream. Return an
204+ * unmodifiable List of the certificates.
205+ *
206+ * @param is the <code>InputStream</code> to read the data from
207+ * @return an unmodifiable List of the certificates
208+ * @exception CertificateException if an exception occurs
209+ */
210+ private static List<X509Certificate> parsePKCS7(InputStream is)
211+ throws CertificateException {
212+ List<X509Certificate> certList;
213+
214+ if (is == null) {
215+ throw new CertificateException("input stream is null");
216+ }
217+
218+ try {
219+ if (is.markSupported() == false) {
220+ // Copy the entire input stream into an InputStream that does
221+ // support mark
222+ is = new ByteArrayInputStream(readAllBytes(is));
223+ };
224+ PKCS7 pkcs7 = new PKCS7(is);
225+
226+ X509Certificate[] certArray = pkcs7.getCertificates();
227+ // certs are optional in PKCS #7
228+ if (certArray != null) {
229+ certList = Arrays.asList(certArray);
230+ } else {
231+ // no certs provided
232+ certList = new ArrayList<X509Certificate>(0);
233+ }
234+ } catch (IOException ioe) {
235+ throw new CertificateException("IOException parsing PKCS7 data: " +
236+ ioe);
237+ }
238+ // Assumes that the resulting List is thread-safe. This is true
239+ // because we ensure that it cannot be modified after construction
240+ // and the methods in the Sun JDK 1.4 implementation of ArrayList that
241+ // allow read-only access are thread-safe.
242+ return Collections.unmodifiableList(certList);
243+ }
244+
245+ /*
246+ * Reads the entire contents of an InputStream into a byte array.
247+ *
248+ * @param is the InputStream to read from
249+ * @return the bytes read from the InputStream
250+ */
251+ private static byte[] readAllBytes(InputStream is) throws IOException {
252+ byte[] buffer = new byte[8192];
253+ ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
254+ int n;
255+ while ((n = is.read(buffer)) != -1) {
256+ baos.write(buffer, 0, n);
257+ }
258+ return baos.toByteArray();
259+ }
260+
261+ /**
262+ * Returns the encoded form of this certification path, using the
263+ * default encoding.
264+ *
265+ * @return the encoded bytes
266+ * @exception CertificateEncodingException if an encoding error occurs
267+ */
268+ public byte[] getEncoded() throws CertificateEncodingException {
269+ // @@@ Should cache the encoded form
270+ return encodePKIPATH();
271+ }
272+
273+ /**
274+ * Encode the CertPath using PKIPATH format.
275+ *
276+ * @return a byte array containing the binary encoding of the PkiPath object
277+ * @exception CertificateEncodingException if an exception occurs
278+ */
279+ private byte[] encodePKIPATH() throws CertificateEncodingException {
280+
281+ ListIterator<X509Certificate> li = certs.listIterator(certs.size());
282+ try {
283+ DerOutputStream bytes = new DerOutputStream();
284+ // encode certs in reverse order (trust anchor to target)
285+ // according to PkiPath format
286+ while (li.hasPrevious()) {
287+ X509Certificate cert = li.previous();
288+ // check for duplicate cert
289+ if (certs.lastIndexOf(cert) != certs.indexOf(cert)) {
290+ throw new CertificateEncodingException
291+ ("Duplicate Certificate");
292+ }
293+ // get encoded certificates
294+ byte[] encoded = cert.getEncoded();
295+ bytes.write(encoded);
296+ }
297+
298+ // Wrap the data in a SEQUENCE
299+ DerOutputStream derout = new DerOutputStream();
300+ derout.write(DerValue.tag_SequenceOf, bytes);
301+ return derout.toByteArray();
302+
303+ } catch (IOException ioe) {
304+ CertificateEncodingException ce = new CertificateEncodingException
305+ ("IOException encoding PkiPath data: " + ioe);
306+ ce.initCause(ioe);
307+ throw ce;
308+ }
309+ }
310+
311+ /**
312+ * Encode the CertPath using PKCS#7 format.
313+ *
314+ * @return a byte array containing the binary encoding of the PKCS#7 object
315+ * @exception CertificateEncodingException if an exception occurs
316+ */
317+ private byte[] encodePKCS7() throws CertificateEncodingException {
318+ PKCS7 p7 = new PKCS7(new AlgorithmId[0],
319+ new ContentInfo(ContentInfo.DATA_OID, null),
320+ certs.toArray(new X509Certificate[certs.size()]),
321+ new SignerInfo[0]);
322+ DerOutputStream derout = new DerOutputStream();
323+ try {
324+ p7.encodeSignedData(derout);
325+ } catch (IOException ioe) {
326+ throw new CertificateEncodingException(ioe.getMessage());
327+ }
328+ return derout.toByteArray();
329+ }
330+
331+ /**
332+ * Returns the encoded form of this certification path, using the
333+ * specified encoding.
334+ *
335+ * @param encoding the name of the encoding to use
336+ * @return the encoded bytes
337+ * @exception CertificateEncodingException if an encoding error occurs or
338+ * the encoding requested is not supported
339+ */
340+ public byte[] getEncoded(String encoding)
341+ throws CertificateEncodingException {
342+ if (PKIPATH_ENCODING.equals(encoding)) {
343+ return encodePKIPATH();
344+ } else if (PKCS7_ENCODING.equals(encoding)) {
345+ return encodePKCS7();
346+ } else {
347+ throw new CertificateEncodingException("unsupported encoding");
348+ }
349+ }
350+
351+ /**
352+ * Returns the encodings supported by this certification path, with the
353+ * default encoding first.
354+ *
355+ * @return an <code>Iterator</code> over the names of the supported
356+ * encodings (as Strings)
357+ */
358+ public static Iterator<String> getEncodingsStatic() {
359+ return encodingList.iterator();
360+ }
361+
362+ /**
363+ * Returns an iteration of the encodings supported by this certification
364+ * path, with the default encoding first.
365+ * <p>
366+ * Attempts to modify the returned <code>Iterator</code> via its
367+ * <code>remove</code> method result in an
368+ * <code>UnsupportedOperationException</code>.
369+ *
370+ * @return an <code>Iterator</code> over the names of the supported
371+ * encodings (as Strings)
372+ */
373+ public Iterator<String> getEncodings() {
374+ return getEncodingsStatic();
375+ }
376+
377+ /**
378+ * Returns the list of certificates in this certification path.
379+ * The <code>List</code> returned must be immutable and thread-safe.
380+ *
381+ * @return an immutable <code>List</code> of <code>X509Certificate</code>s
382+ * (may be empty, but not null)
383+ */
384+ public List<X509Certificate> getCertificates() {
385+ return certs;
386+ }
387+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t