1 /* X509CertificateFactory.java -- generates X.509 certificates.
2 Copyright (C) 2003 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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)
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.
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
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
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. */
39 package gnu.java.security.provider;
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;
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;
63 public class X509CertificateFactory
64 extends CertificateFactorySpi
66 public static final String BEGIN_CERTIFICATE = "-----BEGIN CERTIFICATE-----";
68 public static final String END_CERTIFICATE = "-----END CERTIFICATE-----";
70 public static final String BEGIN_X509_CRL = "-----BEGIN X509 CRL-----";
72 public static final String END_X509_CRL = "-----END X509 CRL-----";
74 public X509CertificateFactory()
79 public Certificate engineGenerateCertificate(InputStream inStream)
80 throws CertificateException
84 return generateCert(inStream);
86 catch (IOException ioe)
88 CertificateException ce = new CertificateException(ioe.getMessage());
94 public Collection engineGenerateCertificates(InputStream inStream)
95 throws CertificateException
97 LinkedList certs = new LinkedList();
102 certs.add(generateCert(inStream));
104 catch (EOFException eof)
108 catch (IOException ioe)
110 CertificateException ce = new CertificateException(ioe.getMessage());
118 public CRL engineGenerateCRL(InputStream inStream) throws CRLException
122 return generateCRL(inStream);
124 catch (IOException ioe)
126 CRLException crle = new CRLException(ioe.getMessage());
132 public Collection engineGenerateCRLs(InputStream inStream)
135 LinkedList crls = new LinkedList();
140 crls.add(generateCRL(inStream));
142 catch (EOFException eof)
146 catch (IOException ioe)
148 CRLException crle = new CRLException(ioe.getMessage());
156 public CertPath engineGenerateCertPath(List certs)
158 return new X509CertPath(certs);
161 public CertPath engineGenerateCertPath(InputStream in)
162 throws CertificateEncodingException
164 return new X509CertPath(in);
167 public CertPath engineGenerateCertPath(InputStream in, String encoding)
168 throws CertificateEncodingException
170 return new X509CertPath(in, encoding);
173 public Iterator engineGetCertPathEncodings()
175 return X509CertPath.ENCODINGS.iterator();
178 private X509Certificate generateCert(InputStream inStream)
179 throws IOException, CertificateException
181 if (inStream == null)
182 throw new CertificateException("missing input stream");
183 if (! inStream.markSupported())
184 inStream = new BufferedInputStream(inStream, 8192);
186 int i = inStream.read();
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.
193 // So if we do not see 0x30 here we will assume it is in Base-64.
197 CPStringBuilder line = new CPStringBuilder(80);
205 throw new EOFException();
206 if (i != '\n' && i != '\r')
207 line.append((char) i);
209 while (i != '\n' && i != '\r');
211 while (! line.toString().equals(BEGIN_CERTIFICATE));
212 X509Certificate ret = new X509Certificate(
213 new BufferedInputStream(new Base64InputStream(inStream), 8192));
215 line.append('-'); // Base64InputStream will eat this.
220 throw new EOFException();
221 if (i != '\n' && i != '\r')
222 line.append((char) i);
224 while (i != '\n' && i != '\r');
226 if (! line.toString().equals(END_CERTIFICATE))
227 throw new CertificateException("no end-of-certificate marker");
233 return new X509Certificate(inStream);
237 private X509CRL generateCRL(InputStream inStream) throws IOException,
240 if (inStream == null)
241 throw new CRLException("missing input stream");
242 if (! inStream.markSupported())
243 inStream = new BufferedInputStream(inStream, 8192);
245 int i = inStream.read();
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.
252 // So if we do not see 0x30 here we will assume it is in Base-64.
256 CPStringBuilder line = new CPStringBuilder(80);
264 throw new EOFException();
265 if (i != '\n' && i != '\r')
266 line.append((char) i);
268 while (i != '\n' && i != '\r');
270 while (! line.toString().startsWith(BEGIN_X509_CRL));
271 X509CRL ret = new X509CRL(
272 new BufferedInputStream(new Base64InputStream(inStream), 8192));
274 line.append('-'); // Base64InputStream will eat this.
279 throw new EOFException();
280 if (i != '\n' && i != '\r')
281 line.append((char) i);
283 while (i != '\n' && i != '\r');
285 if (! line.toString().startsWith(END_X509_CRL))
286 throw new CRLException("no end-of-CRL marker");
292 return new X509CRL(inStream);