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)
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
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
.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
;
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
;
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
;
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
;
107 private byte[] sigAlgParams
;
108 private byte[] rawSig
;
109 private byte[] signature
;
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
124 revokedCerts
= new HashMap();
125 extensions
= new HashMap();
126 critOids
= new HashSet();
127 nonCritOids
= new HashSet();
132 catch (IOException ioe
)
134 ioe
.printStackTrace();
140 throw new CRLException(x
.toString());
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());
170 public void verify(PublicKey key
, String provider
)
171 throws CRLException
, NoSuchAlgorithmException
, InvalidKeyException
,
172 NoSuchProviderException
, SignatureException
174 Signature sig
= Signature
.getInstance(sigAlg
.toString(), provider
);
178 public int getVersion()
183 public Principal
getIssuerDN()
188 public X500Principal
getIssuerX500Principal()
193 public Date
getThisUpdate()
195 return (Date
) thisUpdate
.clone();
198 public Date
getNextUpdate()
200 if (nextUpdate
!= null)
201 return (Date
) nextUpdate
.clone();
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
))
231 if (sigAlg
.equals(ID_RSA_WITH_MD5
))
233 if (sigAlg
.equals(ID_RSA_WITH_SHA1
))
234 return "SHA1withRSA";
238 public String
getSigAlgOID()
240 return sigAlg
.toString();
243 public byte[] getSigAlgParams()
245 if (sigAlgParams
!= null)
246 return (byte[]) sigAlgParams
.clone();
250 // X509Extension methods.
251 // ------------------------------------------------------------------------
253 public boolean hasUnsupportedCriticalExtension()
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
);
272 return (byte[]) ext
.clone();
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
);
293 return ent
.getRevocationDate().compareTo(new Date()) < 0;
297 // ------------------------------------------------------------------------
299 private void doVerify(Signature sig
, PublicKey key
)
300 throws CRLException
, InvalidKeyException
, SignatureException
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();
317 if (!val
.isConstructed())
318 throw new ASN1ParsingException("malformed TBSCertList");
319 tbsCRLBytes
= val
.getEncoded();
322 if (val
.getValue() instanceof BigInteger
)
324 version
= ((BigInteger
) val
.getValue()).intValue() + 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())
337 algParams
= val
.getEncoded();
338 if (val
.isConstructed())
339 in
.skip(val
.getLength());
342 issuerDN
= new X500Principal(in
);
344 thisUpdate
= (Date
) der
.read().getValue();
347 if (val
.getValue() instanceof Date
)
349 nextUpdate
= (Date
) val
.getValue();
352 if (val
.getTag() != 0)
355 while (len
< val
.getLength())
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)
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();
378 byte[] extVal
= (byte[]) val2
.getValue();
379 extensions
.put(extId
.toString(), extVal
);
380 if (crit
.booleanValue())
381 critOids
.add(extId
.toString());
383 nonCritOids
.add(extId
.toString());
384 len
+= ext
.getEncodedLength();
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())
396 sigAlgParams
= (byte[]) val
.getEncoded();
397 if (val
.isConstructed())
398 in
.skip(val
.getLength());
401 rawSig
= val
.getEncoded();
402 signature
= ((BitString
) val
.getValue()).toByteArray();