/* * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.security.x509; import java.io.InputStream;import java.io.OutputStream;import java.io.IOException;import java.math.BigInteger;import java.security.Principal;import java.security.PublicKey;import java.security.PrivateKey;import java.security.Security;import java.security.Signature;import java.security.NoSuchAlgorithmException;import java.security.InvalidKeyException;import java.security.NoSuchProviderException;import java.security.SignatureException;import java.security.cert.Certificate;import java.security.cert.X509CRL;import java.security.cert.X509Certificate;import java.security.cert.X509CRLEntry;import java.security.cert.CRLException;import java.util.*; import javax.security.auth.x500.X500Principal; import sun.security.provider.X509Factory;import sun.security.util.*;import sun.misc.HexDumpEncoder; /** * <p> * An implmentation for X509 CRL (Certificate Revocation List). * <p> * The X.509 v2 CRL format is described below in ASN.1: * <pre> * CertificateList ::= SEQUENCE { * tbsCertList TBSCertList, * signatureAlgorithm AlgorithmIdentifier, * signature BIT STRING } * </pre> * More information can be found in * <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509 * Public Key Infrastructure Certificate and CRL Profile</a>. * <p> * The ASN.1 definition of <code>tbsCertList</code> is: * <pre> * TBSCertList ::= SEQUENCE { * version Version OPTIONAL, * -- if present, must be v2 * signature AlgorithmIdentifier, * issuer Name, * thisUpdate ChoiceOfTime, * nextUpdate ChoiceOfTime OPTIONAL, * revokedCertificates SEQUENCE OF SEQUENCE { * userCertificate CertificateSerialNumber, * revocationDate ChoiceOfTime, * crlEntryExtensions Extensions OPTIONAL * -- if present, must be v2 * } OPTIONAL, * crlExtensions [0] EXPLICIT Extensions OPTIONAL * -- if present, must be v2 * } * </pre> * * @author Hemma Prafullchandra * @see X509CRL */public class X509CRLImpl extends X509CRL implements DerEncoder { // CRL data, and its envelope private byte[] signedCRL = null; // DER encoded crl private byte[] signature = null; // raw signature bits private byte[] tbsCertList = null; // DER encoded "to-be-signed" CRL private AlgorithmId sigAlgId = null; // sig alg in CRL // crl information private int version; private AlgorithmId infoSigAlgId; // sig alg in "to-be-signed" crl private X500Name issuer = null; private X500Principal issuerPrincipal = null; private Date thisUpdate = null; private Date nextUpdate = null; private Map<X509IssuerSerial,X509CRLEntry> revokedCerts = new LinkedHashMap<X509IssuerSerial,X509CRLEntry>(); private CRLExtensions extensions = null; private final static boolean isExplicit = true; private static final long YR_2050 = 2524636800000L; private boolean readOnly = false; /** * PublicKey that has previously been used to successfully verify * the signature of this CRL. Null if the CRL has not * yet been verified (successfully). */ private PublicKey verifiedPublicKey; /** * If verifiedPublicKey is not null, name of the provider used to * successfully verify the signature of this CRL, or the * empty String if no provider was explicitly specified. */ private String verifiedProvider; /** * Not to be used. As it would lead to cases of uninitialized * CRL objects. */ private X509CRLImpl() { } /** * Unmarshals an X.509 CRL from its encoded form, parsing the encoded * bytes. This form of constructor is used by agents which * need to examine and use CRL contents. Note that the buffer * must include only one CRL, and no "garbage" may be left at * the end. * * @param crlData the encoded bytes, with no trailing padding. * @exception CRLException on parsing errors. */ public X509CRLImpl(byte[] crlData) throws CRLException { try { parse(new DerValue(crlData)); } catch (IOException e) { signedCRL = null; throw new CRLException("Parsing error: " + e.getMessage()); } } /** * Unmarshals an X.509 CRL from an DER value. * * @param val a DER value holding at least one CRL * @exception CRLException on parsing errors. */ public X509CRLImpl(DerValue val) throws CRLException { try { parse(val); } catch (IOException e) { signedCRL = null; throw new CRLException("Parsing error: " + e.getMessage()); } } /** * Unmarshals an X.509 CRL from an input stream. Only one CRL * is expected at the end of the input stream. * * @param inStrm an input stream holding at least one CRL * @exception CRLException on parsing errors. */ public X509CRLImpl(InputStream inStrm) throws CRLException { try { parse(new DerValue(inStrm)); } catch (IOException e) { signedCRL = null; throw new CRLException("Parsing error: " + e.getMessage()); } } /** * Initial CRL constructor, no revoked certs, and no extensions. * * @param issuer the name of the CA issuing this CRL. * @param thisUpdate the Date of this issue. * @param nextUpdate the Date of the next CRL. */ public X509CRLImpl(X500Name issuer, Date thisDate, Date nextDate) { this.issuer = issuer; this.thisUpdate = thisDate; this.nextUpdate = nextDate; } /** * CRL constructor, revoked certs, no extensions. * * @param issuer the name of the CA issuing this CRL. * @param thisUpdate the Date of this issue. * @param nextUpdate the Date of the next CRL. * @param badCerts the array of CRL entries. * * @exception CRLException on parsing/construction errors. */ public X509CRLImpl(X500Name issuer, Date thisDate, Date nextDate, X509CRLEntry[] badCerts) throws CRLException { this.issuer = issuer; this.thisUpdate = thisDate; this.nextUpdate = nextDate; if (badCerts != null) { X500Principal crlIssuer = getIssuerX500Principal(); X500Principal badCertIssuer = crlIssuer; for (int i = 0; i < badCerts.length; i++) { X509CRLEntryImpl badCert = (X509CRLEntryImpl)badCerts[i]; try { badCertIssuer = getCertIssuer(badCert, badCertIssuer); } catch (IOException ioe) { throw new CRLException(ioe); } badCert.setCertificateIssuer(crlIssuer, badCertIssuer); X509IssuerSerial issuerSerial = new X509IssuerSerial (badCertIssuer, badCert.getSerialNumber()); this.revokedCerts.put(issuerSerial, badCert); if (badCert.hasExtensions()) { this.version = 1; } } } } /** * CRL constructor, revoked certs and extensions. * * @param issuer the name of the CA issuing this CRL. * @param thisUpdate the Date of this issue. * @param nextUpdate the Date of the next CRL. * @param badCerts the array of CRL entries. * @param crlExts the CRL extensions. * * @exception CRLException on parsing/construction errors. */ public X509CRLImpl(X500Name issuer, Date thisDate, Date nextDate, X509CRLEntry[] badCerts, CRLExtensions crlExts) throws CRLException { this(issuer, thisDate, nextDate, badCerts); if (crlExts != null) { this.extensions = crlExts; this.version = 1; } } /** * Returned the encoding as an uncloned byte array. Callers must * guarantee that they neither modify it nor expose it to untrusted * code. */ public byte[] getEncodedInternal() throws CRLException { if (signedCRL == null) { throw new CRLException("Null CRL to encode"); } return signedCRL; } /** * Returns the ASN.1 DER encoded form of this CRL. * * @exception CRLException if an encoding error occurs. */ public byte[] getEncoded() throws CRLException { return getEncodedInternal().clone(); } /** * Encodes the "to-be-signed" CRL to the OutputStream. * * @param out the OutputStream to write to. * @exception CRLException on encoding errors. */ public void encodeInfo(OutputStream out) throws CRLException { try { DerOutputStream tmp = new DerOutputStream(); DerOutputStream rCerts = new DerOutputStream(); DerOutputStream seq = new DerOutputStream(); if (version != 0) // v2 crl encode version tmp.putInteger(version); infoSigAlgId.encode(tmp); if ((version == 0) && (issuer.toString() == null)) throw new CRLException("Null Issuer DN not allowed in v1 CRL"); issuer.encode(tmp); if (thisUpdate.getTime() < YR_2050) tmp.putUTCTime(thisUpdate); else tmp.putGeneralizedTime(thisUpdate); if (nextUpdate != null) { if (nextUpdate.getTime() < YR_2050) tmp.putUTCTime(nextUpdate); else tmp.putGeneralizedTime(nextUpdate); } if (!revokedCerts.isEmpty()) { for (X509CRLEntry entry : revokedCerts.values()) { ((X509CRLEntryImpl)entry).encode(rCerts); } tmp.write(DerValue.tag_Sequence, rCerts); } if (extensions != null) extensions.encode(tmp, isExplicit); seq.write(DerValue.tag_Sequence, tmp); tbsCertList = seq.toByteArray(); out.write(tbsCertList); } catch (IOException e) { throw new CRLException("Encoding error: " + e.getMessage()); } } /** * Verifies that this CRL was signed using the * private key that corresponds to the given public key. * * @param key the PublicKey used to carry out the verification. * * @exception NoSuchAlgorithmException on unsupported signature * algorithms. * @exception InvalidKeyException on incorrect key. * @exception NoSuchProviderException if there's no default provider. * @exception SignatureException on signature errors. * @exception CRLException on encoding errors. */ public void verify(PublicKey key) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { verify(key, ""); } /** * Verifies that this CRL was signed using the * private key that corresponds to the given public key, * and that the signature verification was computed by * the given provider. * * @param key the PublicKey used to carry out the verification. * @param sigProvider the name of the signature provider. * * @exception NoSuchAlgorithmException on unsupported signature * algorithms. * @exception InvalidKeyException on incorrect key. * @exception NoSuchProviderException on incorrect provider. * @exception SignatureException on signature errors. * @exception CRLException on encoding errors. */ public synchronized void verify(PublicKey key, String sigProvider) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { if (sigProvider == null) { sigProvider = ""; } if ((verifiedPublicKey != null) && verifiedPublicKey.equals(key)) { // this CRL has already been successfully verified using // this public key. Make sure providers match, too. if (sigProvider.equals(verifiedProvider)) { return; } } if (signedCRL == null) { throw new CRLException("Uninitialized CRL"); } Signature sigVerf = null; if (sigProvider.length() == 0) { sigVerf = Signature.getInstance(sigAlgId.getName()); } else { sigVerf = Signature.getInstance(sigAlgId.getName(), sigProvider); } sigVerf.initVerify(key); if (tbsCertList == null) { throw new CRLException("Uninitialized CRL"); } sigVerf.update(tbsCertList, 0, tbsCertList.length); if (!sigVerf.verify(signature)) { throw new SignatureException("Signature does not match."); } verifiedPublicKey = key; verifiedProvider = sigProvider; } /** * Encodes an X.509 CRL, and signs it using the given key. * * @param key the private key used for signing. * @param algorithm the name of the signature algorithm used. * * @exception NoSuchAlgorithmException on unsupported signature * algorithms. * @exception InvalidKeyException on incorrect key. * @exception NoSuchProviderException on incorrect provider. * @exception SignatureException on signature errors. * @exception CRLException if any mandatory data was omitted. */ public void sign(PrivateKey key, String algorithm) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { sign(key, algorithm, null); } /** * Encodes an X.509 CRL, and signs it using the given key. * * @param key the private key used for signing. * @param algorithm the name of the signature algorithm used. * @param provider the name of the provider. * * @exception NoSuchAlgorithmException on unsupported signature * algorithms. * @exception InvalidKeyException on incorrect key. * @exception NoSuchProviderException on incorrect provider. * @exception SignatureException on signature errors. * @exception CRLException if any mandatory data was omitted. */ public void sign(PrivateKey key, String algorithm, String provider) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { try { if (readOnly) throw new CRLException("cannot over-write existing CRL"); Signature sigEngine = null; if ((provider == null) || (provider.length() == 0)) sigEngine = Signature.getInstance(algorithm); else sigEngine = Signature.getInstance(algorithm, provider); sigEngine.initSign(key); // in case the name is reset sigAlgId = AlgorithmId.get(sigEngine.getAlgorithm()); infoSigAlgId = sigAlgId; DerOutputStream out = new DerOutputStream(); DerOutputStream tmp = new DerOutputStream(); // encode crl info encodeInfo(tmp); // encode algorithm identifier sigAlgId.encode(tmp); // Create and encode the signature itself. sigEngine.update(tbsCertList, 0, tbsCertList.length); signature = sigEngine.sign(); tmp.putBitString(signature); // Wrap the signed data in a SEQUENCE { data, algorithm, sig } out.write(DerValue.tag_Sequence, tmp); signedCRL = out.toByteArray(); readOnly = true; } catch (IOException e) { throw new CRLException("Error while encoding data: " + e.getMessage()); } } /** * Returns a printable string of this CRL. * * @return value of this CRL in a printable form. */ public String toString() { StringBuffer sb = new StringBuffer(); sb.append("X.509 CRL v" + (version+1) + "\n"); if (sigAlgId != null) sb.append("Signature Algorithm: " + sigAlgId.toString() + ", OID=" + (sigAlgId.getOID()).toString() + "\n"); if (issuer != null) sb.append("Issuer: " + issuer.toString() + "\n"); if (thisUpdate != null) sb.append("\nThis Update: " + thisUpdate.toString() + "\n"); if (nextUpdate != null) sb.append("Next Update: " + nextUpdate.toString() + "\n"); if (revokedCerts.isEmpty()) sb.append("\nNO certificates have been revoked\n"); else { sb.append("\nRevoked Certificates: " + revokedCerts.size()); int i = 1; for (Iterator<X509CRLEntry> iter = revokedCerts.values().iterator(); iter.hasNext(); i++) sb.append("\n[" + i + "] " + iter.next().toString());Lines 1–500 of 1291. Load more
/* * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.security.x509; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.Principal; import java.security.PublicKey; import java.security.PrivateKey; import java.security.Security; import java.security.Signature; import java.security.NoSuchAlgorithmException; import java.security.InvalidKeyException; import java.security.NoSuchProviderException; import java.security.SignatureException; import java.security.cert.Certificate; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.security.cert.X509CRLEntry; import java.security.cert.CRLException; import java.util.*; import javax.security.auth.x500.X500Principal; import sun.security.provider.X509Factory; import sun.security.util.*; import sun.misc.HexDumpEncoder; /** * <p> * An implmentation for X509 CRL (Certificate Revocation List). * <p> * The X.509 v2 CRL format is described below in ASN.1: * <pre> * CertificateList ::= SEQUENCE { * tbsCertList TBSCertList, * signatureAlgorithm AlgorithmIdentifier, * signature BIT STRING } * </pre> * More information can be found in * <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509 * Public Key Infrastructure Certificate and CRL Profile</a>. * <p> * The ASN.1 definition of <code>tbsCertList</code> is: * <pre> * TBSCertList ::= SEQUENCE { * version Version OPTIONAL, * -- if present, must be v2 * signature AlgorithmIdentifier, * issuer Name, * thisUpdate ChoiceOfTime, * nextUpdate ChoiceOfTime OPTIONAL, * revokedCertificates SEQUENCE OF SEQUENCE { * userCertificate CertificateSerialNumber, * revocationDate ChoiceOfTime, * crlEntryExtensions Extensions OPTIONAL * -- if present, must be v2 * } OPTIONAL, * crlExtensions [0] EXPLICIT Extensions OPTIONAL * -- if present, must be v2 * } * </pre> * * @author Hemma Prafullchandra * @see X509CRL */ public class X509CRLImpl extends X509CRL implements DerEncoder { // CRL data, and its envelope private byte[] signedCRL = null; // DER encoded crl private byte[] signature = null; // raw signature bits private byte[] tbsCertList = null; // DER encoded "to-be-signed" CRL private AlgorithmId sigAlgId = null; // sig alg in CRL // crl information private int version; private AlgorithmId infoSigAlgId; // sig alg in "to-be-signed" crl private X500Name issuer = null; private X500Principal issuerPrincipal = null; private Date thisUpdate = null; private Date nextUpdate = null; private Map<X509IssuerSerial,X509CRLEntry> revokedCerts = new LinkedHashMap<X509IssuerSerial,X509CRLEntry>(); private CRLExtensions extensions = null; private final static boolean isExplicit = true; private static final long YR_2050 = 2524636800000L; private boolean readOnly = false; /** * PublicKey that has previously been used to successfully verify * the signature of this CRL. Null if the CRL has not * yet been verified (successfully). */ private PublicKey verifiedPublicKey; /** * If verifiedPublicKey is not null, name of the provider used to * successfully verify the signature of this CRL, or the * empty String if no provider was explicitly specified. */ private String verifiedProvider; /** * Not to be used. As it would lead to cases of uninitialized * CRL objects. */ private X509CRLImpl() { } /** * Unmarshals an X.509 CRL from its encoded form, parsing the encoded * bytes. This form of constructor is used by agents which * need to examine and use CRL contents. Note that the buffer * must include only one CRL, and no "garbage" may be left at * the end. * * @param crlData the encoded bytes, with no trailing padding. * @exception CRLException on parsing errors. */ public X509CRLImpl(byte[] crlData) throws CRLException { try { parse(new DerValue(crlData)); } catch (IOException e) { signedCRL = null; throw new CRLException("Parsing error: " + e.getMessage()); } } /** * Unmarshals an X.509 CRL from an DER value. * * @param val a DER value holding at least one CRL * @exception CRLException on parsing errors. */ public X509CRLImpl(DerValue val) throws CRLException { try { parse(val); } catch (IOException e) { signedCRL = null; throw new CRLException("Parsing error: " + e.getMessage()); } } /** * Unmarshals an X.509 CRL from an input stream. Only one CRL * is expected at the end of the input stream. * * @param inStrm an input stream holding at least one CRL * @exception CRLException on parsing errors. */ public X509CRLImpl(InputStream inStrm) throws CRLException { try { parse(new DerValue(inStrm)); } catch (IOException e) { signedCRL = null; throw new CRLException("Parsing error: " + e.getMessage()); } } /** * Initial CRL constructor, no revoked certs, and no extensions. * * @param issuer the name of the CA issuing this CRL. * @param thisUpdate the Date of this issue. * @param nextUpdate the Date of the next CRL. */ public X509CRLImpl(X500Name issuer, Date thisDate, Date nextDate) { this.issuer = issuer; this.thisUpdate = thisDate; this.nextUpdate = nextDate; } /** * CRL constructor, revoked certs, no extensions. * * @param issuer the name of the CA issuing this CRL. * @param thisUpdate the Date of this issue. * @param nextUpdate the Date of the next CRL. * @param badCerts the array of CRL entries. * * @exception CRLException on parsing/construction errors. */ public X509CRLImpl(X500Name issuer, Date thisDate, Date nextDate, X509CRLEntry[] badCerts) throws CRLException { this.issuer = issuer; this.thisUpdate = thisDate; this.nextUpdate = nextDate; if (badCerts != null) { X500Principal crlIssuer = getIssuerX500Principal(); X500Principal badCertIssuer = crlIssuer; for (int i = 0; i < badCerts.length; i++) { X509CRLEntryImpl badCert = (X509CRLEntryImpl)badCerts[i]; try { badCertIssuer = getCertIssuer(badCert, badCertIssuer); } catch (IOException ioe) { throw new CRLException(ioe); } badCert.setCertificateIssuer(crlIssuer, badCertIssuer); X509IssuerSerial issuerSerial = new X509IssuerSerial (badCertIssuer, badCert.getSerialNumber()); this.revokedCerts.put(issuerSerial, badCert); if (badCert.hasExtensions()) { this.version = 1; } } } } /** * CRL constructor, revoked certs and extensions. * * @param issuer the name of the CA issuing this CRL. * @param thisUpdate the Date of this issue. * @param nextUpdate the Date of the next CRL. * @param badCerts the array of CRL entries. * @param crlExts the CRL extensions. * * @exception CRLException on parsing/construction errors. */ public X509CRLImpl(X500Name issuer, Date thisDate, Date nextDate, X509CRLEntry[] badCerts, CRLExtensions crlExts) throws CRLException { this(issuer, thisDate, nextDate, badCerts); if (crlExts != null) { this.extensions = crlExts; this.version = 1; } } /** * Returned the encoding as an uncloned byte array. Callers must * guarantee that they neither modify it nor expose it to untrusted * code. */ public byte[] getEncodedInternal() throws CRLException { if (signedCRL == null) { throw new CRLException("Null CRL to encode"); } return signedCRL; } /** * Returns the ASN.1 DER encoded form of this CRL. * * @exception CRLException if an encoding error occurs. */ public byte[] getEncoded() throws CRLException { return getEncodedInternal().clone(); } /** * Encodes the "to-be-signed" CRL to the OutputStream. * * @param out the OutputStream to write to. * @exception CRLException on encoding errors. */ public void encodeInfo(OutputStream out) throws CRLException { try { DerOutputStream tmp = new DerOutputStream(); DerOutputStream rCerts = new DerOutputStream(); DerOutputStream seq = new DerOutputStream(); if (version != 0) // v2 crl encode version tmp.putInteger(version); infoSigAlgId.encode(tmp); if ((version == 0) && (issuer.toString() == null)) throw new CRLException("Null Issuer DN not allowed in v1 CRL"); issuer.encode(tmp); if (thisUpdate.getTime() < YR_2050) tmp.putUTCTime(thisUpdate); else tmp.putGeneralizedTime(thisUpdate); if (nextUpdate != null) { if (nextUpdate.getTime() < YR_2050) tmp.putUTCTime(nextUpdate); else tmp.putGeneralizedTime(nextUpdate); } if (!revokedCerts.isEmpty()) { for (X509CRLEntry entry : revokedCerts.values()) { ((X509CRLEntryImpl)entry).encode(rCerts); } tmp.write(DerValue.tag_Sequence, rCerts); } if (extensions != null) extensions.encode(tmp, isExplicit); seq.write(DerValue.tag_Sequence, tmp); tbsCertList = seq.toByteArray(); out.write(tbsCertList); } catch (IOException e) { throw new CRLException("Encoding error: " + e.getMessage()); } } /** * Verifies that this CRL was signed using the * private key that corresponds to the given public key. * * @param key the PublicKey used to carry out the verification. * * @exception NoSuchAlgorithmException on unsupported signature * algorithms. * @exception InvalidKeyException on incorrect key. * @exception NoSuchProviderException if there's no default provider. * @exception SignatureException on signature errors. * @exception CRLException on encoding errors. */ public void verify(PublicKey key) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { verify(key, ""); } /** * Verifies that this CRL was signed using the * private key that corresponds to the given public key, * and that the signature verification was computed by * the given provider. * * @param key the PublicKey used to carry out the verification. * @param sigProvider the name of the signature provider. * * @exception NoSuchAlgorithmException on unsupported signature * algorithms. * @exception InvalidKeyException on incorrect key. * @exception NoSuchProviderException on incorrect provider. * @exception SignatureException on signature errors. * @exception CRLException on encoding errors. */ public synchronized void verify(PublicKey key, String sigProvider) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { if (sigProvider == null) { sigProvider = ""; } if ((verifiedPublicKey != null) && verifiedPublicKey.equals(key)) { // this CRL has already been successfully verified using // this public key. Make sure providers match, too. if (sigProvider.equals(verifiedProvider)) { return; } } if (signedCRL == null) { throw new CRLException("Uninitialized CRL"); } Signature sigVerf = null; if (sigProvider.length() == 0) { sigVerf = Signature.getInstance(sigAlgId.getName()); } else { sigVerf = Signature.getInstance(sigAlgId.getName(), sigProvider); } sigVerf.initVerify(key); if (tbsCertList == null) { throw new CRLException("Uninitialized CRL"); } sigVerf.update(tbsCertList, 0, tbsCertList.length); if (!sigVerf.verify(signature)) { throw new SignatureException("Signature does not match."); } verifiedPublicKey = key; verifiedProvider = sigProvider; } /** * Encodes an X.509 CRL, and signs it using the given key. * * @param key the private key used for signing. * @param algorithm the name of the signature algorithm used. * * @exception NoSuchAlgorithmException on unsupported signature * algorithms. * @exception InvalidKeyException on incorrect key. * @exception NoSuchProviderException on incorrect provider. * @exception SignatureException on signature errors. * @exception CRLException if any mandatory data was omitted. */ public void sign(PrivateKey key, String algorithm) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { sign(key, algorithm, null); } /** * Encodes an X.509 CRL, and signs it using the given key. * * @param key the private key used for signing. * @param algorithm the name of the signature algorithm used. * @param provider the name of the provider. * * @exception NoSuchAlgorithmException on unsupported signature * algorithms. * @exception InvalidKeyException on incorrect key. * @exception NoSuchProviderException on incorrect provider. * @exception SignatureException on signature errors. * @exception CRLException if any mandatory data was omitted. */ public void sign(PrivateKey key, String algorithm, String provider) throws CRLException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, SignatureException { try { if (readOnly) throw new CRLException("cannot over-write existing CRL"); Signature sigEngine = null; if ((provider == null) || (provider.length() == 0)) sigEngine = Signature.getInstance(algorithm); else sigEngine = Signature.getInstance(algorithm, provider); sigEngine.initSign(key); // in case the name is reset sigAlgId = AlgorithmId.get(sigEngine.getAlgorithm()); infoSigAlgId = sigAlgId; DerOutputStream out = new DerOutputStream(); DerOutputStream tmp = new DerOutputStream(); // encode crl info encodeInfo(tmp); // encode algorithm identifier sigAlgId.encode(tmp); // Create and encode the signature itself. sigEngine.update(tbsCertList, 0, tbsCertList.length); signature = sigEngine.sign(); tmp.putBitString(signature); // Wrap the signed data in a SEQUENCE { data, algorithm, sig } out.write(DerValue.tag_Sequence, tmp); signedCRL = out.toByteArray(); readOnly = true; } catch (IOException e) { throw new CRLException("Error while encoding data: " + e.getMessage()); } } /** * Returns a printable string of this CRL. * * @return value of this CRL in a printable form. */ public String toString() { StringBuffer sb = new StringBuffer(); sb.append("X.509 CRL v" + (version+1) + "\n"); if (sigAlgId != null) sb.append("Signature Algorithm: " + sigAlgId.toString() + ", OID=" + (sigAlgId.getOID()).toString() + "\n"); if (issuer != null) sb.append("Issuer: " + issuer.toString() + "\n"); if (thisUpdate != null) sb.append("\nThis Update: " + thisUpdate.toString() + "\n"); if (nextUpdate != null) sb.append("Next Update: " + nextUpdate.toString() + "\n"); if (revokedCerts.isEmpty()) sb.append("\nNO certificates have been revoked\n"); else { sb.append("\nRevoked Certificates: " + revokedCerts.size()); int i = 1; for (Iterator<X509CRLEntry> iter = revokedCerts.values().iterator(); iter.hasNext(); i++) sb.append("\n[" + i + "] " + iter.next().toString());