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