blob: 1ee63949964452c1217897df50d2d8beaed8b2f9 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2003-2005 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.security.provider.certpath;
27
28import java.io.*;
29import java.math.BigInteger;
30import java.security.MessageDigest;
31import java.util.Arrays;
32import sun.misc.HexDumpEncoder;
33import sun.security.x509.*;
34import sun.security.util.*;
35
36/**
37 * This class corresponds to the CertId field in OCSP Request
38 * and the OCSP Response. The ASN.1 definition for CertID is defined
39 * in RFC 2560 as:
40 * <pre>
41 *
42 * CertID ::= SEQUENCE {
43 * hashAlgorithm AlgorithmIdentifier,
44 * issuerNameHash OCTET STRING, -- Hash of Issuer's DN
45 * issuerKeyHash OCTET STRING, -- Hash of Issuers public key
46 * serialNumber CertificateSerialNumber
47 * }
48 *
49 * </pre>
50 *
51 * @author Ram Marti
52 */
53
54public class CertId {
55
56 private static final boolean debug = false;
57 private AlgorithmId hashAlgId;
58 private byte[] issuerNameHash;
59 private byte[] issuerKeyHash;
60 private SerialNumber certSerialNumber;
61 private int myhash = -1; // hashcode for this CertId
62
63 /**
64 * Creates a CertId. The hash algorithm used is SHA-1.
65 */
66 public CertId(X509CertImpl issuerCert, SerialNumber serialNumber)
67 throws Exception {
68
69 // compute issuerNameHash
70 MessageDigest md = MessageDigest.getInstance("SHA1");
71 hashAlgId = AlgorithmId.get("SHA1");
72 md.update(issuerCert.getSubjectX500Principal().getEncoded());
73 issuerNameHash = md.digest();
74
75 // compute issuerKeyHash (remove the tag and length)
76 byte[] pubKey = issuerCert.getPublicKey().getEncoded();
77 DerValue val = new DerValue(pubKey);
78 DerValue[] seq = new DerValue[2];
79 seq[0] = val.data.getDerValue(); // AlgorithmID
80 seq[1] = val.data.getDerValue(); // Key
81 byte[] keyBytes = seq[1].getBitString();
82 md.update(keyBytes);
83 issuerKeyHash = md.digest();
84 certSerialNumber = serialNumber;
85
86 if (debug) {
87 HexDumpEncoder encoder = new HexDumpEncoder();
88 System.out.println("Issuer Certificate is " + issuerCert);
89 System.out.println("issuerNameHash is " +
90 encoder.encode(issuerNameHash));
91 System.out.println("issuerKeyHash is " +
92 encoder.encode(issuerKeyHash));
93 }
94 }
95
96 /**
97 * Creates a CertId from its ASN.1 DER encoding.
98 */
99 public CertId(DerInputStream derIn) throws IOException {
100
101 hashAlgId = AlgorithmId.parse(derIn.getDerValue());
102 issuerNameHash = derIn.getOctetString();
103 issuerKeyHash = derIn.getOctetString();
104 certSerialNumber = new SerialNumber(derIn);
105 }
106
107 /**
108 * Return the hash algorithm identifier.
109 */
110 public AlgorithmId getHashAlgorithm() {
111 return hashAlgId;
112 }
113
114 /**
115 * Return the hash value for the issuer name.
116 */
117 public byte[] getIssuerNameHash() {
118 return issuerNameHash;
119 }
120
121 /**
122 * Return the hash value for the issuer key.
123 */
124 public byte[] getIssuerKeyHash() {
125 return issuerKeyHash;
126 }
127
128 /**
129 * Return the serial number.
130 */
131 public BigInteger getSerialNumber() {
132 return certSerialNumber.getNumber();
133 }
134
135 /**
136 * Encode the CertId using ASN.1 DER.
137 * The hash algorithm used is SHA-1.
138 */
139 public void encode(DerOutputStream out) throws IOException {
140
141 DerOutputStream tmp = new DerOutputStream();
142 hashAlgId.encode(tmp);
143 tmp.putOctetString(issuerNameHash);
144 tmp.putOctetString(issuerKeyHash);
145 certSerialNumber.encode(tmp);
146 out.write(DerValue.tag_Sequence, tmp);
147
148 if (debug) {
149 HexDumpEncoder encoder = new HexDumpEncoder();
150 System.out.println("Encoded certId is " +
151 encoder.encode(out.toByteArray()));
152 }
153 }
154
155 /**
156 * Returns a hashcode value for this CertId.
157 *
158 * @return the hashcode value.
159 */
160 public int hashCode() {
161 if (myhash == -1) {
162 myhash = hashAlgId.hashCode();
163 for (int i = 0; i < issuerNameHash.length; i++) {
164 myhash += issuerNameHash[i] * i;
165 }
166 for (int i = 0; i < issuerKeyHash.length; i++) {
167 myhash += issuerKeyHash[i] * i;
168 }
169 myhash += certSerialNumber.getNumber().hashCode();
170 }
171 return myhash;
172 }
173
174 /**
175 * Compares this CertId for equality with the specified
176 * object. Two CertId objects are considered equal if their hash algorithms,
177 * their issuer name and issuer key hash values and their serial numbers
178 * are equal.
179 *
180 * @param other the object to test for equality with this object.
181 * @return true if the objects are considered equal, false otherwise.
182 */
183 public boolean equals(Object other) {
184
185 if (this == other) {
186 return true;
187 }
188 if (other == null || (!(other instanceof CertId))) {
189 return false;
190 }
191
192 CertId that = (CertId) other;
193 if (hashAlgId.equals(that.getHashAlgorithm()) &&
194 Arrays.equals(issuerNameHash, that.getIssuerNameHash()) &&
195 Arrays.equals(issuerKeyHash, that.getIssuerKeyHash()) &&
196 certSerialNumber.getNumber().equals(that.getSerialNumber())) {
197 return true;
198 } else {
199 return false;
200 }
201 }
202
203 /**
204 * Create a string representation of the CertId.
205 */
206 public String toString() {
207 StringBuilder sb = new StringBuilder();
208 sb.append("CertId \n");
209 sb.append("Algorithm: " + hashAlgId.toString() +"\n");
210 sb.append("issuerNameHash \n");
211 HexDumpEncoder encoder = new HexDumpEncoder();
212 sb.append(encoder.encode(issuerNameHash));
213 sb.append("\nissuerKeyHash: \n");
214 sb.append(encoder.encode(issuerKeyHash));
215 sb.append("\n" + certSerialNumber.toString());
216 return sb.toString();
217 }
218}