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