      1 /*
      2  * Copyright (c) 1997, 2019, 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.util.Arrays;
     29
     30 import java.security.Provider;
     31 import java.security.PublicKey;
     32 import java.security.NoSuchAlgorithmException;
     33 import java.security.NoSuchProviderException;
     34 import java.security.InvalidKeyException;
     35 import java.security.SignatureException;
     36
     37 import sun.security.x509.X509CertImpl;
     38
     39 /**
     40  * <p>Abstract class for managing a variety of identity certificates.
     41  * An identity certificate is a binding of a principal to a public key which
     42  * is vouched for by another principal.  (A principal represents
     43  * an entity such as an individual user, a group, or a corporation.)
     44  * <p>
     45  * This class is an abstraction for certificates that have different
     46  * formats but important common uses.  For example, different types of
     47  * certificates, such as X.509 and PGP, share general certificate
     48  * functionality (like encoding and verifying) and
     49  * some types of information (like a public key).
     50  * <p>
     51  * X.509, PGP, and SDSI certificates can all be implemented by
     52  * subclassing the Certificate class, even though they contain different
     53  * sets of information, and they store and retrieve the information in
     54  * different ways.
     55  *
     56  * @see X509Certificate
     57  * @see CertificateFactory
     58  *
     59  * @author Hemma Prafullchandra
     60  * @since 1.2
     61  */
     62
     63 public abstract class Certificate implements java.io.Serializable {
     64
     65     @java.io.Serial
     66     private static final long serialVersionUID = -3585440601605666277L;
     67
     68     // the certificate type
     69     private final String type;
     70
     71     /** Cache the hash code for the certiticate */
     72     private int hash = -1; // Default to -1
     73
     74     /**
     75      * Creates a certificate of the specified type.
     76      *
     77      * @param type the standard name of the certificate type.
     78      * See the CertificateFactory section in the <a href=
     79      * "{@docRoot}/../specs/security/standard-names.html#certificatefactory-types">
     80      * Java Security Standard Algorithm Names Specification</a>
     81      * for information about standard certificate types.
     82      */
     83     protected Certificate(String type) {
     84         this.type = type;
     85     }
     86
     87     /**
     88      * Returns the type of this certificate.
     89      *
     90      * @return the type of this certificate.
     91      */
     92     public final String getType() {
     93         return this.type;
     94     }
     95
     96     /**
     97      * Compares this certificate for equality with the specified
     98      * object. If the {@code other} object is an
     99      * {@code instanceof} {@code Certificate}, then
    100      * its encoded form is retrieved and compared with the
    101      * encoded form of this certificate.
    102      *
    103      * @param other the object to test for equality with this certificate.
    104      * @return true iff the encoded forms of the two certificates
    105      * match, false otherwise.
    106      */
    107     public boolean equals(Object other) {
    108         if (this == other) {
    109             return true;
    110         }
    111         if (!(other instanceof Certificate)) {
    112             return false;
    113         }
    114         try {
    115             byte[] thisCert = X509CertImpl.getEncodedInternal(this);
    116             byte[] otherCert = X509CertImpl.getEncodedInternal((Certificate)other);
    117
    118             return Arrays.equals(thisCert, otherCert);
    119         } catch (CertificateException e) {
    120             return false;
    121         }
    122     }
    123
    124     /**
    125      * Returns a hashcode value for this certificate from its
    126      * encoded form.
    127      *
    128      * @return the hashcode value.
    129      */
    130     public int hashCode() {
    131         int h = hash;
    132         if (h == -1) {
    133             try {
    134                 h = Arrays.hashCode(X509CertImpl.getEncodedInternal(this));
    135             } catch (CertificateException e) {
    136                 h = 0;
    137             }
    138             hash = h;
    139         }
    140         return h;
    141     }
    142
    143     /**
    144      * Returns the encoded form of this certificate. It is
    145      * assumed that each certificate type would have only a single
    146      * form of encoding; for example, X.509 certificates would
    147      * be encoded as ASN.1 DER.
    148      *
    149      * @return the encoded form of this certificate
    150      *
    151      * @throws    CertificateEncodingException if an encoding error occurs.
    152      */
    153     public abstract byte[] getEncoded()
    154         throws CertificateEncodingException;
    155
    156     /**
    157      * Verifies that this certificate was signed using the
    158      * private key that corresponds to the specified public key.
    159      *
    160      * @param key the PublicKey used to carry out the verification.
    161      *
    162      * @throws    NoSuchAlgorithmException on unsupported signature
    163      * algorithms.
    164      * @throws    InvalidKeyException on incorrect key.
    165      * @throws    NoSuchProviderException if there's no default provider.
    166      * @throws    SignatureException on signature errors.
    167      * @throws    CertificateException on encoding errors.
    168      */
    169     public abstract void verify(PublicKey key)
    170         throws CertificateException, NoSuchAlgorithmException,
    171         InvalidKeyException, NoSuchProviderException,
    172         SignatureException;
    173
    174     /**
    175      * Verifies that this certificate was signed using the
    176      * private key that corresponds to the specified public key.
    177      * This method uses the signature verification engine
    178      * supplied by the specified provider.
    179      *
    180      * @param key the PublicKey used to carry out the verification.
    181      * @param sigProvider the name of the signature provider.
    182      *
    183      * @throws    NoSuchAlgorithmException on unsupported signature
    184      * algorithms.
    185      * @throws    InvalidKeyException on incorrect key.
    186      * @throws    NoSuchProviderException on incorrect provider.
    187      * @throws    SignatureException on signature errors.
    188      * @throws    CertificateException on encoding errors.
    189      */
    190     public abstract void verify(PublicKey key, String sigProvider)
    191         throws CertificateException, NoSuchAlgorithmException,
    192         InvalidKeyException, NoSuchProviderException,
    193         SignatureException;
    194
    195     /**
    196      * Verifies that this certificate was signed using the
    197      * private key that corresponds to the specified public key.
    198      * This method uses the signature verification engine
    199      * supplied by the specified provider. Note that the specified
    200      * Provider object does not have to be registered in the provider list.
    201      *
    202      * <p> This method was added to version 1.8 of the Java Platform
    203      * Standard Edition. In order to maintain backwards compatibility with
    204      * existing service providers, this method cannot be {@code abstract}
    205      * and by default throws an {@code UnsupportedOperationException}.
    206      *
    207      * @param key the PublicKey used to carry out the verification.
    208      * @param sigProvider the signature provider.
    209      *
    210      * @throws    NoSuchAlgorithmException on unsupported signature
    211      * algorithms.
    212      * @throws    InvalidKeyException on incorrect key.
    213      * @throws    SignatureException on signature errors.
    214      * @throws    CertificateException on encoding errors.
    215      * @throws    UnsupportedOperationException if the method is not supported
    216      * @since 1.8
    217      */
    218     public void verify(PublicKey key, Provider sigProvider)
    219         throws CertificateException, NoSuchAlgorithmException,
    220         InvalidKeyException, SignatureException {
    221         throw new UnsupportedOperationException();
    222     }
    223
    224     /**
    225      * Returns a string representation of this certificate.
    226      *
    227      * @return a string representation of this certificate.
    228      */
    229     public abstract String toString();
    230
    231     /**
    232      * Gets the public key from this certificate.
    233      *
    234      * @return the public key.
    235      */
    236     public abstract PublicKey getPublicKey();
    237
    238     /**
    239      * Alternate Certificate class for serialization.
    240      * @since 1.3
    241      */
    242     protected static class CertificateRep implements java.io.Serializable {
    243
    244         @java.io.Serial
    245         private static final long serialVersionUID = -8563758940495660020L;
    246

    247         private String type;

    248         private byte[] data;
    249
    250         /**
    251          * Construct the alternate Certificate class with the Certificate
    252          * type and Certificate encoding bytes.
    253          *
    254          * @param type the standard name of the Certificate type.
    255          *
    256          * @param data the Certificate data.
    257          */
    258         protected CertificateRep(String type, byte[] data) {
    259             this.type = type;
    260             this.data = data;
    261         }
    262
    263         /**
    264          * Resolve the Certificate Object.
    265          *
    266          * @return the resolved Certificate Object
    267          *
    268          * @throws java.io.ObjectStreamException if the Certificate
    269          *      could not be resolved
    270          */
    271         @java.io.Serial
    272         protected Object readResolve() throws java.io.ObjectStreamException {
    273             try {
    274                 CertificateFactory cf = CertificateFactory.getInstance(type);
    275                 return cf.generateCertificate
    276                         (new java.io.ByteArrayInputStream(data));
    277             } catch (CertificateException e) {
    278                 throw new java.io.NotSerializableException
    279                                 ("java.security.cert.Certificate: " +
    280                                 type +
    281                                 ": " +
    282                                 e.getMessage());
    283             }
    284         }
    285     }
    286
    287     /**
    288      * Replace the Certificate to be serialized.
    289      *
    290      * @return the alternate Certificate object to be serialized
    291      *
    292      * @throws java.io.ObjectStreamException if a new object representing
    293      * this Certificate could not be created
    294      * @since 1.3
    295      */
    296     @java.io.Serial
    297     protected Object writeReplace() throws java.io.ObjectStreamException {
    298         try {
    299             return new CertificateRep(type, getEncoded());
    300         } catch (CertificateException e) {
    301             throw new java.io.NotSerializableException
    302                                 ("java.security.cert.Certificate: " +
    303                                 type +
    304                                 ": " +
    305                                 e.getMessage());
    306         }
    307     }
    308 }
    --- EOF ---