OSDN Git Service

libjava/ChangeLog:
[pf3gnuchains/gcc-fork.git] / libjava / classpath / gnu / java / security / provider / X509CertificateFactory.java
1 /* X509CertificateFactory.java -- generates X.509 certificates.
2    Copyright (C) 2003 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 package gnu.java.security.provider;
40
41 import gnu.java.io.Base64InputStream;
42 import gnu.java.lang.CPStringBuilder;
43 import gnu.java.security.x509.X509CRL;
44 import gnu.java.security.x509.X509CertPath;
45 import gnu.java.security.x509.X509Certificate;
46
47 import java.io.BufferedInputStream;
48 import java.io.EOFException;
49 import java.io.IOException;
50 import java.io.InputStream;
51 import java.security.cert.CRL;
52 import java.security.cert.CRLException;
53 import java.security.cert.CertPath;
54 import java.security.cert.Certificate;
55 import java.security.cert.CertificateEncodingException;
56 import java.security.cert.CertificateException;
57 import java.security.cert.CertificateFactorySpi;
58 import java.util.Collection;
59 import java.util.Iterator;
60 import java.util.LinkedList;
61 import java.util.List;
62
63 public class X509CertificateFactory
64     extends CertificateFactorySpi
65 {
66   public static final String BEGIN_CERTIFICATE = "-----BEGIN CERTIFICATE-----";
67
68   public static final String END_CERTIFICATE = "-----END CERTIFICATE-----";
69
70   public static final String BEGIN_X509_CRL = "-----BEGIN X509 CRL-----";
71
72   public static final String END_X509_CRL = "-----END X509 CRL-----";
73
74   public X509CertificateFactory()
75   {
76     super();
77   }
78
79   public Certificate engineGenerateCertificate(InputStream inStream)
80       throws CertificateException
81   {
82     try
83       {
84         return generateCert(inStream);
85       }
86     catch (IOException ioe)
87       {
88         CertificateException ce = new CertificateException(ioe.getMessage());
89         ce.initCause(ioe);
90         throw ce;
91       }
92   }
93
94   public Collection engineGenerateCertificates(InputStream inStream)
95       throws CertificateException
96   {
97     LinkedList certs = new LinkedList();
98     while (true)
99       {
100         try
101           {
102             certs.add(generateCert(inStream));
103           }
104         catch (EOFException eof)
105           {
106             break;
107           }
108         catch (IOException ioe)
109           {
110             CertificateException ce = new CertificateException(ioe.getMessage());
111             ce.initCause(ioe);
112             throw ce;
113           }
114       }
115     return certs;
116   }
117
118   public CRL engineGenerateCRL(InputStream inStream) throws CRLException
119   {
120     try
121       {
122         return generateCRL(inStream);
123       }
124     catch (IOException ioe)
125       {
126         CRLException crle = new CRLException(ioe.getMessage());
127         crle.initCause(ioe);
128         throw crle;
129       }
130   }
131
132   public Collection engineGenerateCRLs(InputStream inStream)
133       throws CRLException
134   {
135     LinkedList crls = new LinkedList();
136     while (true)
137       {
138         try
139           {
140             crls.add(generateCRL(inStream));
141           }
142         catch (EOFException eof)
143           {
144             break;
145           }
146         catch (IOException ioe)
147           {
148             CRLException crle = new CRLException(ioe.getMessage());
149             crle.initCause(ioe);
150             throw crle;
151           }
152       }
153     return crls;
154   }
155
156   public CertPath engineGenerateCertPath(List certs)
157   {
158     return new X509CertPath(certs);
159   }
160
161   public CertPath engineGenerateCertPath(InputStream in)
162       throws CertificateEncodingException
163   {
164     return new X509CertPath(in);
165   }
166
167   public CertPath engineGenerateCertPath(InputStream in, String encoding)
168       throws CertificateEncodingException
169   {
170     return new X509CertPath(in, encoding);
171   }
172
173   public Iterator engineGetCertPathEncodings()
174   {
175     return X509CertPath.ENCODINGS.iterator();
176   }
177
178   private X509Certificate generateCert(InputStream inStream)
179       throws IOException, CertificateException
180   {
181     if (inStream == null)
182       throw new CertificateException("missing input stream");
183     if (! inStream.markSupported())
184       inStream = new BufferedInputStream(inStream, 8192);
185     inStream.mark(20);
186     int i = inStream.read();
187     if (i == -1)
188       throw new EOFException();
189     // If the input is in binary DER format, the first byte MUST be
190     // 0x30, which stands for the ASN.1 [UNIVERSAL 16], which is the
191     // UNIVERSAL SEQUENCE, with the CONSTRUCTED bit (0x20) set.
192     //
193     // So if we do not see 0x30 here we will assume it is in Base-64.
194     if (i != 0x30)
195       {
196         inStream.reset();
197         CPStringBuilder line = new CPStringBuilder(80);
198         do
199           {
200             line.setLength(0);
201             do
202               {
203                 i = inStream.read();
204                 if (i == -1)
205                   throw new EOFException();
206                 if (i != '\n' && i != '\r')
207                   line.append((char) i);
208               }
209             while (i != '\n' && i != '\r');
210           }
211         while (! line.toString().equals(BEGIN_CERTIFICATE));
212         X509Certificate ret = new X509Certificate(
213             new BufferedInputStream(new Base64InputStream(inStream), 8192));
214         line.setLength(0);
215         line.append('-'); // Base64InputStream will eat this.
216         do
217           {
218             i = inStream.read();
219             if (i == -1)
220               throw new EOFException();
221             if (i != '\n' && i != '\r')
222               line.append((char) i);
223           }
224         while (i != '\n' && i != '\r');
225         // XXX ???
226         if (! line.toString().equals(END_CERTIFICATE))
227           throw new CertificateException("no end-of-certificate marker");
228         return ret;
229       }
230     else
231       {
232         inStream.reset();
233         return new X509Certificate(inStream);
234       }
235   }
236
237   private X509CRL generateCRL(InputStream inStream) throws IOException,
238       CRLException
239   {
240     if (inStream == null)
241       throw new CRLException("missing input stream");
242     if (! inStream.markSupported())
243       inStream = new BufferedInputStream(inStream, 8192);
244     inStream.mark(20);
245     int i = inStream.read();
246     if (i == -1)
247       throw new EOFException();
248     // If the input is in binary DER format, the first byte MUST be
249     // 0x30, which stands for the ASN.1 [UNIVERSAL 16], which is the
250     // UNIVERSAL SEQUENCE, with the CONSTRUCTED bit (0x20) set.
251     //
252     // So if we do not see 0x30 here we will assume it is in Base-64.
253     if (i != 0x30)
254       {
255         inStream.reset();
256         CPStringBuilder line = new CPStringBuilder(80);
257         do
258           {
259             line.setLength(0);
260             do
261               {
262                 i = inStream.read();
263                 if (i == -1)
264                   throw new EOFException();
265                 if (i != '\n' && i != '\r')
266                   line.append((char) i);
267               }
268             while (i != '\n' && i != '\r');
269           }
270         while (! line.toString().startsWith(BEGIN_X509_CRL));
271         X509CRL ret = new X509CRL(
272             new BufferedInputStream(new Base64InputStream(inStream), 8192));
273         line.setLength(0);
274         line.append('-'); // Base64InputStream will eat this.
275         do
276           {
277             i = inStream.read();
278             if (i == -1)
279               throw new EOFException();
280             if (i != '\n' && i != '\r')
281               line.append((char) i);
282           }
283         while (i != '\n' && i != '\r');
284         // XXX ???
285         if (! line.toString().startsWith(END_X509_CRL))
286           throw new CRLException("no end-of-CRL marker");
287         return ret;
288       }
289     else
290       {
291         inStream.reset();
292         return new X509CRL(inStream);
293       }
294   }
295 }