1 /*
   2  * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.security.cert;
  27 
  28 import java.security.NoSuchAlgorithmException;
  29 import java.security.NoSuchProviderException;
  30 import java.security.InvalidKeyException;
  31 import java.security.SignatureException;
  32 import java.security.Principal;
  33 import java.security.Provider;
  34 import java.security.PublicKey;
  35 import java.security.Signature;
  36 import javax.security.auth.x500.X500Principal;
  37 
  38 import java.math.BigInteger;
  39 import java.util.Date;
  40 import java.util.Set;
  41 import java.util.Arrays;
  42 
  43 import sun.security.x509.X509CRLImpl;
  44 
  45 /**
  46  * <p>
  47  * Abstract class for an X.509 Certificate Revocation List (CRL).
  48  * A CRL is a time-stamped list identifying revoked certificates.
  49  * It is signed by a Certificate Authority (CA) and made freely
  50  * available in a public repository.
  51  *
  52  * <p>Each revoked certificate is
  53  * identified in a CRL by its certificate serial number. When a
  54  * certificate-using system uses a certificate (e.g., for verifying a
  55  * remote user's digital signature), that system not only checks the
  56  * certificate signature and validity but also acquires a suitably-
  57  * recent CRL and checks that the certificate serial number is not on
  58  * that CRL.  The meaning of "suitably-recent" may vary with local
  59  * policy, but it usually means the most recently-issued CRL.  A CA
  60  * issues a new CRL on a regular periodic basis (e.g., hourly, daily, or
  61  * weekly).  Entries are added to CRLs as revocations occur, and an
  62  * entry may be removed when the certificate expiration date is reached.
  63  * <p>
  64  * The X.509 v2 CRL format is described below in ASN.1:
  65  * <pre>
  66  * CertificateList  ::=  SEQUENCE  {
  67  *     tbsCertList          TBSCertList,
  68  *     signatureAlgorithm   AlgorithmIdentifier,
  69  *     signature            BIT STRING  }
  70  * </pre>
  71  * <p>
  72  * More information can be found in
  73  * <a href="http://tools.ietf.org/html/rfc5280">RFC 5280: Internet X.509
  74  * Public Key Infrastructure Certificate and CRL Profile</a>.
  75  * <p>
  76  * The ASN.1 definition of {@code tbsCertList} is:
  77  * <pre>
  78  * TBSCertList  ::=  SEQUENCE  {
  79  *     version                 Version OPTIONAL,
  80  *                             -- if present, must be v2
  81  *     signature               AlgorithmIdentifier,
  82  *     issuer                  Name,
  83  *     thisUpdate              ChoiceOfTime,
  84  *     nextUpdate              ChoiceOfTime OPTIONAL,
  85  *     revokedCertificates     SEQUENCE OF SEQUENCE  {
  86  *         userCertificate         CertificateSerialNumber,
  87  *         revocationDate          ChoiceOfTime,
  88  *         crlEntryExtensions      Extensions OPTIONAL
  89  *                                 -- if present, must be v2
  90  *         }  OPTIONAL,
  91  *     crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
  92  *                                  -- if present, must be v2
  93  *     }
  94  * </pre>
  95  * <p>
  96  * CRLs are instantiated using a certificate factory. The following is an
  97  * example of how to instantiate an X.509 CRL:
  98  * <pre>{@code
  99  * try (InputStream inStream = new FileInputStream("fileName-of-crl")) {
 100  *     CertificateFactory cf = CertificateFactory.getInstance("X.509");
 101  *     X509CRL crl = (X509CRL)cf.generateCRL(inStream);
 102  * }
 103  * }</pre>
 104  *
 105  * @author Hemma Prafullchandra
 106  * @since 1.2
 107  *
 108  *
 109  * @see CRL
 110  * @see CertificateFactory
 111  * @see X509Extension
 112  */
 113 
 114 public abstract class X509CRL extends CRL implements X509Extension {
 115 
 116     private transient X500Principal issuerPrincipal;
 117 
 118     /**
 119      * Constructor for X.509 CRLs.
 120      */
 121     protected X509CRL() {
 122         super("X.509");
 123     }
 124 
 125     /**
 126      * Compares this CRL for equality with the given
 127      * object. If the {@code other} object is an
 128      * {@code instanceof} {@code X509CRL}, then
 129      * its encoded form is retrieved and compared with the
 130      * encoded form of this CRL.
 131      *
 132      * @param other the object to test for equality with this CRL.
 133      *
 134      * @return true iff the encoded forms of the two CRLs
 135      * match, false otherwise.
 136      */
 137     public boolean equals(Object other) {
 138         if (this == other) {
 139             return true;
 140         }
 141         if (!(other instanceof X509CRL)) {
 142             return false;
 143         }
 144         try {
 145             byte[] thisCRL = X509CRLImpl.getEncodedInternal(this);
 146             byte[] otherCRL = X509CRLImpl.getEncodedInternal((X509CRL)other);
 147 
 148             return Arrays.equals(thisCRL, otherCRL);
 149         } catch (CRLException e) {
 150             return false;
 151         }
 152     }
 153 
 154     /**
 155      * Returns a hashcode value for this CRL from its
 156      * encoded form.
 157      *
 158      * @return the hashcode value.
 159      */
 160     public int hashCode() {
 161         int retval = 0;
 162         try {
 163             byte[] crlData = X509CRLImpl.getEncodedInternal(this);
 164             for (int i = 1; i < crlData.length; i++) {
 165                  retval += crlData[i] * i;
 166             }
 167             return retval;
 168         } catch (CRLException e) {
 169             return retval;
 170         }
 171     }
 172 
 173     /**
 174      * Returns the ASN.1 DER-encoded form of this CRL.
 175      *
 176      * @return the encoded form of this certificate
 177      * @exception CRLException if an encoding error occurs.
 178      */
 179     public abstract byte[] getEncoded()
 180         throws CRLException;
 181 
 182     /**
 183      * Verifies that this CRL was signed using the
 184      * private key that corresponds to the given public key.
 185      *
 186      * @param key the PublicKey used to carry out the verification.
 187      *
 188      * @exception NoSuchAlgorithmException on unsupported signature
 189      * algorithms.
 190      * @exception InvalidKeyException on incorrect key.
 191      * @exception NoSuchProviderException if there's no default provider.
 192      * @exception SignatureException on signature errors.
 193      * @exception CRLException on encoding errors.
 194      */
 195     public abstract void verify(PublicKey key)
 196         throws CRLException,  NoSuchAlgorithmException,
 197         InvalidKeyException, NoSuchProviderException,
 198         SignatureException;
 199 
 200     /**
 201      * Verifies that this CRL was signed using the
 202      * private key that corresponds to the given public key.
 203      * This method uses the signature verification engine
 204      * supplied by the given provider.
 205      *
 206      * @param key the PublicKey used to carry out the verification.
 207      * @param sigProvider the name of the signature provider.
 208      *
 209      * @exception NoSuchAlgorithmException on unsupported signature
 210      * algorithms.
 211      * @exception InvalidKeyException on incorrect key.
 212      * @exception NoSuchProviderException on incorrect provider.
 213      * @exception SignatureException on signature errors.
 214      * @exception CRLException on encoding errors.
 215      */
 216     public abstract void verify(PublicKey key, String sigProvider)
 217         throws CRLException, NoSuchAlgorithmException,
 218         InvalidKeyException, NoSuchProviderException,
 219         SignatureException;
 220 
 221     /**
 222      * Verifies that this CRL was signed using the
 223      * private key that corresponds to the given public key.
 224      * This method uses the signature verification engine
 225      * supplied by the given provider. Note that the specified Provider object
 226      * does not have to be registered in the provider list.
 227      *
 228      * This method was added to version 1.8 of the Java Platform Standard
 229      * Edition. In order to maintain backwards compatibility with existing
 230      * service providers, this method is not {@code abstract}
 231      * and it provides a default implementation.
 232      *
 233      * @param key the PublicKey used to carry out the verification.
 234      * @param sigProvider the signature provider.
 235      *
 236      * @exception NoSuchAlgorithmException on unsupported signature
 237      * algorithms.
 238      * @exception InvalidKeyException on incorrect key.
 239      * @exception SignatureException on signature errors.
 240      * @exception CRLException on encoding errors.
 241      * @since 1.8
 242      */
 243     public void verify(PublicKey key, Provider sigProvider)
 244         throws CRLException, NoSuchAlgorithmException,
 245         InvalidKeyException, SignatureException {
 246         Signature sig = (sigProvider == null)
 247             ? Signature.getInstance(getSigAlgName())
 248             : Signature.getInstance(getSigAlgName(), sigProvider);
 249         sig.initVerify(key);
 250 
 251         byte[] tbsCRL = getTBSCertList();
 252         sig.update(tbsCRL, 0, tbsCRL.length);
 253 
 254         if (sig.verify(getSignature()) == false) {
 255             throw new SignatureException("Signature does not match.");
 256         }
 257     }
 258 
 259     /**
 260      * Gets the {@code version} (version number) value from the CRL.
 261      * The ASN.1 definition for this is:
 262      * <pre>
 263      * version    Version OPTIONAL,
 264      *             -- if present, must be v2
 265      *
 266      * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
 267      *             -- v3 does not apply to CRLs but appears for consistency
 268      *             -- with definition of Version for certs
 269      * </pre>
 270      *
 271      * @return the version number, i.e. 1 or 2.
 272      */
 273     public abstract int getVersion();
 274 
 275     /**
 276      * <strong>Denigrated</strong>, replaced by {@linkplain
 277      * #getIssuerX500Principal()}. This method returns the {@code issuer}
 278      * as an implementation specific Principal object, which should not be
 279      * relied upon by portable code.
 280      *
 281      * <p>
 282      * Gets the {@code issuer} (issuer distinguished name) value from
 283      * the CRL. The issuer name identifies the entity that signed (and
 284      * issued) the CRL.
 285      *
 286      * <p>The issuer name field contains an
 287      * X.500 distinguished name (DN).
 288      * The ASN.1 definition for this is:
 289      * <pre>
 290      * issuer    Name
 291      *
 292      * Name ::= CHOICE { RDNSequence }
 293      * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
 294      * RelativeDistinguishedName ::=
 295      *     SET OF AttributeValueAssertion
 296      *
 297      * AttributeValueAssertion ::= SEQUENCE {
 298      *                               AttributeType,
 299      *                               AttributeValue }
 300      * AttributeType ::= OBJECT IDENTIFIER
 301      * AttributeValue ::= ANY
 302      * </pre>
 303      * The {@code Name} describes a hierarchical name composed of
 304      * attributes,
 305      * such as country name, and corresponding values, such as US.
 306      * The type of the {@code AttributeValue} component is determined by
 307      * the {@code AttributeType}; in general it will be a
 308      * {@code directoryString}. A {@code directoryString} is usually
 309      * one of {@code PrintableString},
 310      * {@code TeletexString} or {@code UniversalString}.
 311      *
 312      * @return a Principal whose name is the issuer distinguished name.
 313      */
 314     public abstract Principal getIssuerDN();
 315 
 316     /**
 317      * Returns the issuer (issuer distinguished name) value from the
 318      * CRL as an {@code X500Principal}.
 319      * <p>
 320      * It is recommended that subclasses override this method.
 321      *
 322      * @return an {@code X500Principal} representing the issuer
 323      *          distinguished name
 324      * @since 1.4
 325      */
 326     public X500Principal getIssuerX500Principal() {
 327         if (issuerPrincipal == null) {
 328             issuerPrincipal = X509CRLImpl.getIssuerX500Principal(this);
 329         }
 330         return issuerPrincipal;
 331     }
 332 
 333     /**
 334      * Gets the {@code thisUpdate} date from the CRL.
 335      * The ASN.1 definition for this is:
 336      * <pre>
 337      * thisUpdate   ChoiceOfTime
 338      * ChoiceOfTime ::= CHOICE {
 339      *     utcTime        UTCTime,
 340      *     generalTime    GeneralizedTime }
 341      * </pre>
 342      *
 343      * @return the {@code thisUpdate} date from the CRL.
 344      */
 345     public abstract Date getThisUpdate();
 346 
 347     /**
 348      * Gets the {@code nextUpdate} date from the CRL.
 349      *
 350      * @return the {@code nextUpdate} date from the CRL, or null if
 351      * not present.
 352      */
 353     public abstract Date getNextUpdate();
 354 
 355     /**
 356      * Gets the CRL entry, if any, with the given certificate serialNumber.
 357      *
 358      * @param serialNumber the serial number of the certificate for which a CRL entry
 359      * is to be looked up
 360      * @return the entry with the given serial number, or null if no such entry
 361      * exists in this CRL.
 362      * @see X509CRLEntry
 363      */
 364     public abstract X509CRLEntry
 365         getRevokedCertificate(BigInteger serialNumber);
 366 
 367     /**
 368      * Get the CRL entry, if any, for the given certificate.
 369      *
 370      * <p>This method can be used to lookup CRL entries in indirect CRLs,
 371      * that means CRLs that contain entries from issuers other than the CRL
 372      * issuer. The default implementation will only return entries for
 373      * certificates issued by the CRL issuer. Subclasses that wish to
 374      * support indirect CRLs should override this method.
 375      *
 376      * @param certificate the certificate for which a CRL entry is to be looked
 377      *   up
 378      * @return the entry for the given certificate, or null if no such entry
 379      *   exists in this CRL.
 380      * @exception NullPointerException if certificate is null
 381      *
 382      * @since 1.5
 383      */
 384     public X509CRLEntry getRevokedCertificate(X509Certificate certificate) {
 385         X500Principal certIssuer = certificate.getIssuerX500Principal();
 386         X500Principal crlIssuer = getIssuerX500Principal();
 387         if (certIssuer.equals(crlIssuer) == false) {
 388             return null;
 389         }
 390         return getRevokedCertificate(certificate.getSerialNumber());
 391     }
 392 
 393     /**
 394      * Gets all the entries from this CRL.
 395      * This returns a Set of X509CRLEntry objects.
 396      *
 397      * @return all the entries or null if there are none present.
 398      * @see X509CRLEntry
 399      */
 400     public abstract Set<? extends X509CRLEntry> getRevokedCertificates();
 401 
 402     /**
 403      * Gets the DER-encoded CRL information, the
 404      * {@code tbsCertList} from this CRL.
 405      * This can be used to verify the signature independently.
 406      *
 407      * @return the DER-encoded CRL information.
 408      * @exception CRLException if an encoding error occurs.
 409      */
 410     public abstract byte[] getTBSCertList() throws CRLException;
 411 
 412     /**
 413      * Gets the {@code signature} value (the raw signature bits) from
 414      * the CRL.
 415      * The ASN.1 definition for this is:
 416      * <pre>
 417      * signature     BIT STRING
 418      * </pre>
 419      *
 420      * @return the signature.
 421      */
 422     public abstract byte[] getSignature();
 423 
 424     /**
 425      * Gets the signature algorithm name for the CRL
 426      * signature algorithm. An example is the string "SHA256withRSA".
 427      * The ASN.1 definition for this is:
 428      * <pre>
 429      * signatureAlgorithm   AlgorithmIdentifier
 430      *
 431      * AlgorithmIdentifier  ::=  SEQUENCE  {
 432      *     algorithm               OBJECT IDENTIFIER,
 433      *     parameters              ANY DEFINED BY algorithm OPTIONAL  }
 434      *                             -- contains a value of the type
 435      *                             -- registered for use with the
 436      *                             -- algorithm object identifier value
 437      * </pre>
 438      *
 439      * <p>The algorithm name is determined from the {@code algorithm}
 440      * OID string.
 441      *
 442      * @return the signature algorithm name.
 443      */
 444     public abstract String getSigAlgName();
 445 
 446     /**
 447      * Gets the signature algorithm OID string from the CRL.
 448      * An OID is represented by a set of nonnegative whole numbers separated
 449      * by periods.
 450      * For example, the string "1.2.840.10040.4.3" identifies the SHA-1
 451      * with DSA signature algorithm defined in
 452      * <a href="http://www.ietf.org/rfc/rfc3279.txt">RFC 3279: Algorithms and
 453      * Identifiers for the Internet X.509 Public Key Infrastructure Certificate
 454      * and CRL Profile</a>.
 455      *
 456      * <p>See {@link #getSigAlgName() getSigAlgName} for
 457      * relevant ASN.1 definitions.
 458      *
 459      * @return the signature algorithm OID string.
 460      */
 461     public abstract String getSigAlgOID();
 462 
 463     /**
 464      * Gets the DER-encoded signature algorithm parameters from this
 465      * CRL's signature algorithm. In most cases, the signature
 466      * algorithm parameters are null; the parameters are usually
 467      * supplied with the public key.
 468      * If access to individual parameter values is needed then use
 469      * {@link java.security.AlgorithmParameters AlgorithmParameters}
 470      * and instantiate with the name returned by
 471      * {@link #getSigAlgName() getSigAlgName}.
 472      *
 473      * <p>See {@link #getSigAlgName() getSigAlgName} for
 474      * relevant ASN.1 definitions.
 475      *
 476      * @return the DER-encoded signature algorithm parameters, or
 477      *         null if no parameters are present.
 478      */
 479     public abstract byte[] getSigAlgParams();
 480 }