2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libjava / gnu / java / security / x509 / X509CRL.java
blob6205c0f89558a5067af8ebdd7319048549d4ffc1
1 /* X509CRL.java -- X.509 certificate revocation list.
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)
9 any later version.
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., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
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.
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.x509;
41 import java.io.InputStream;
42 import java.io.IOException;
44 import java.math.BigInteger;
46 import java.util.Calendar;
47 import java.util.Collections;
48 import java.util.Date;
49 import java.util.HashSet;
50 import java.util.HashMap;
51 import java.util.Set;
53 import java.security.InvalidKeyException;
54 import java.security.NoSuchAlgorithmException;
55 import java.security.NoSuchProviderException;
56 import java.security.PublicKey;
57 import java.security.Principal;
58 import java.security.Signature;
59 import java.security.SignatureException;
60 import java.security.cert.Certificate;
61 import java.security.cert.CRLException;
62 import java.security.cert.X509CRLEntry;
64 import javax.security.auth.x500.X500Principal;
66 import gnu.java.io.ASN1ParsingException;
67 import gnu.java.security.OID;
68 import gnu.java.security.der.BitString;
69 import gnu.java.security.der.DER;
70 import gnu.java.security.der.DERReader;
71 import gnu.java.security.der.DERValue;
72 import gnu.java.security.der.DERWriter;
74 /**
75 * X.509 certificate revocation lists.
77 * @author Casey Marshall (rsdio@metastatic.org)
79 public class X509CRL extends java.security.cert.X509CRL
82 // Constants and fields.
83 // ------------------------------------------------------------------------
85 private static final OID ID_DSA = new OID("1.2.840.10040.4.1");
86 private static final OID ID_DSA_WITH_SHA1 = new OID("1.2.840.10040.4.3");
87 private static final OID ID_RSA = new OID("1.2.840.113549.1.1.1");
88 private static final OID ID_RSA_WITH_MD2 = new OID("1.2.840.113549.1.1.2");
89 private static final OID ID_RSA_WITH_MD5 = new OID("1.2.840.113549.1.1.4");
90 private static final OID ID_RSA_WITH_SHA1 = new OID("1.2.840.113549.1.1.5");
92 private byte[] encoded;
94 private byte[] tbsCRLBytes;
95 private int version;
96 private OID algId;
97 private byte[] algParams;
98 private Date thisUpdate;
99 private Date nextUpdate;
100 private X500Principal issuerDN;
101 private HashMap revokedCerts;
102 private HashMap extensions;
103 private HashSet critOids;
104 private HashSet nonCritOids;
106 private OID sigAlg;
107 private byte[] sigAlgParams;
108 private byte[] rawSig;
109 private byte[] signature;
111 // Constructors.
112 // ------------------------------------------------------------------------
115 * Create a new X.509 CRL.
117 * @param encoded The DER encoded CRL.
118 * @throws CRLException If the input bytes are incorrect.
119 * @throws IOException If the input bytes cannot be read.
121 public X509CRL(InputStream encoded) throws CRLException, IOException
123 super();
124 revokedCerts = new HashMap();
125 extensions = new HashMap();
126 critOids = new HashSet();
127 nonCritOids = new HashSet();
130 parse(encoded);
132 catch (IOException ioe)
134 ioe.printStackTrace();
135 throw ioe;
137 catch (Exception x)
139 x.printStackTrace();
140 throw new CRLException(x.toString());
144 // X509CRL methods.
145 // ------------------------------------------------------------------------
147 public boolean equals(Object o)
149 return ((X509CRL) o).revokedCerts.equals(revokedCerts);
152 public int hashCode()
154 return revokedCerts.hashCode();
157 public byte[] getEncoded() throws CRLException
159 return (byte[]) encoded.clone();
162 public void verify(PublicKey key)
163 throws CRLException, NoSuchAlgorithmException, InvalidKeyException,
164 NoSuchProviderException, SignatureException
166 Signature sig = Signature.getInstance(sigAlg.toString());
167 doVerify(sig, key);
170 public void verify(PublicKey key, String provider)
171 throws CRLException, NoSuchAlgorithmException, InvalidKeyException,
172 NoSuchProviderException, SignatureException
174 Signature sig = Signature.getInstance(sigAlg.toString(), provider);
175 doVerify(sig, key);
178 public int getVersion()
180 return version;
183 public Principal getIssuerDN()
185 return issuerDN;
188 public X500Principal getIssuerX500Principal()
190 return issuerDN;
193 public Date getThisUpdate()
195 return (Date) thisUpdate.clone();
198 public Date getNextUpdate()
200 if (nextUpdate != null)
201 return (Date) nextUpdate.clone();
202 return null;
205 public X509CRLEntry getRevokedCertificate(BigInteger serialNo)
207 return (X509CRLEntry) revokedCerts.get(serialNo);
210 public Set getRevokedCertificates()
212 return Collections.unmodifiableSet(new HashSet(revokedCerts.values()));
215 public byte[] getTBSCertList() throws CRLException
217 return (byte[]) tbsCRLBytes.clone();
220 public byte[] getSignature()
222 return (byte[]) rawSig.clone();
225 public String getSigAlgName()
227 if (sigAlg.equals(ID_DSA_WITH_SHA1))
228 return "SHA1withDSA";
229 if (sigAlg.equals(ID_RSA_WITH_MD2))
230 return "MD2withRSA";
231 if (sigAlg.equals(ID_RSA_WITH_MD5))
232 return "MD5withRSA";
233 if (sigAlg.equals(ID_RSA_WITH_SHA1))
234 return "SHA1withRSA";
235 return "unknown";
238 public String getSigAlgOID()
240 return sigAlg.toString();
243 public byte[] getSigAlgParams()
245 if (sigAlgParams != null)
246 return (byte[]) sigAlgParams.clone();
247 return null;
250 // X509Extension methods.
251 // ------------------------------------------------------------------------
253 public boolean hasUnsupportedCriticalExtension()
255 return false; // XXX
258 public Set getCriticalExtensionOIDs()
260 return Collections.unmodifiableSet(critOids);
263 public Set getNonCriticalExtensionOIDs()
265 return Collections.unmodifiableSet(nonCritOids);
268 public byte[] getExtensionValue(String oid)
270 byte[] ext = (byte[]) extensions.get(oid);
271 if (ext != null)
272 return (byte[]) ext.clone();
273 return null;
276 // CRL methods.
277 // ------------------------------------------------------------------------
279 public String toString()
281 return gnu.java.security.x509.X509CRL.class.getName();
284 public boolean isRevoked(Certificate cert)
286 if (!(cert instanceof java.security.cert.X509Certificate))
287 throw new IllegalArgumentException("not a X.509 certificate");
288 BigInteger certSerial =
289 ((java.security.cert.X509Certificate) cert).getSerialNumber();
290 X509CRLEntry ent = (X509CRLEntry) revokedCerts.get(certSerial);
291 if (ent == null)
292 return false;
293 return ent.getRevocationDate().compareTo(new Date()) < 0;
296 // Own methods.
297 // ------------------------------------------------------------------------
299 private void doVerify(Signature sig, PublicKey key)
300 throws CRLException, InvalidKeyException, SignatureException
302 sig.initVerify(key);
303 sig.update(tbsCRLBytes);
304 if (!sig.verify(signature))
305 throw new CRLException("signature not verified");
308 private void parse(InputStream in) throws Exception
310 DERReader der = new DERReader(in);
311 DERValue val = der.read();
312 if (!val.isConstructed())
313 throw new ASN1ParsingException("malformed CertificateList");
314 encoded = val.getEncoded();
316 val = der.read();
317 if (!val.isConstructed())
318 throw new ASN1ParsingException("malformed TBSCertList");
319 tbsCRLBytes = val.getEncoded();
321 val = der.read();
322 if (val.getValue() instanceof BigInteger)
324 version = ((BigInteger) val.getValue()).intValue() + 1;
325 val = der.read();
327 else
328 version = 1;
330 if (!val.isConstructed())
331 throw new ASN1ParsingException("malformed AlgorithmIdentifier");
332 DERValue algIdVal = der.read();
333 algId = (OID) algIdVal.getValue();
334 if (val.getLength() > algIdVal.getEncodedLength())
336 val = der.read();
337 algParams = val.getEncoded();
338 if (val.isConstructed())
339 in.skip(val.getLength());
342 issuerDN = new X500Principal(in);
344 thisUpdate = (Date) der.read().getValue();
346 val = der.read();
347 if (val.getValue() instanceof Date)
349 nextUpdate = (Date) val.getValue();
350 val = der.read();
352 if (val.getTag() != 0)
354 int len = 0;
355 while (len < val.getLength())
357 X509CRLEntry entry =
358 new gnu.java.security.x509.X509CRLEntry(version, in);
359 revokedCerts.put(entry.getSerialNumber(), entry);
360 len += entry.getEncoded().length;
363 if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 0)
365 val = der.read();
366 int len = 0;
367 while (len < val.getLength())
369 DERValue ext = der.read();
370 OID extId = (OID) der.read().getValue();
371 DERValue val2 = der.read();
372 Boolean crit = Boolean.valueOf(false);
373 if (val2.getValue() instanceof Boolean)
375 crit = (Boolean) val2.getValue();
376 val2 = der.read();
378 byte[] extVal = (byte[]) val2.getValue();
379 extensions.put(extId.toString(), extVal);
380 if (crit.booleanValue())
381 critOids.add(extId.toString());
382 else
383 nonCritOids.add(extId.toString());
384 len += ext.getEncodedLength();
388 val = der.read();
389 if (!val.isConstructed())
390 throw new ASN1ParsingException("malformed AlgorithmIdentifier");
391 DERValue sigAlgVal = der.read();
392 sigAlg = (OID) sigAlgVal.getValue();
393 if (val.getLength() > sigAlgVal.getEncodedLength())
395 val = der.read();
396 sigAlgParams = (byte[]) val.getEncoded();
397 if (val.isConstructed())
398 in.skip(val.getLength());
400 val = der.read();
401 rawSig = val.getEncoded();
402 signature = ((BitString) val.getValue()).toByteArray();