Path: blob/master/src/java.base/share/classes/sun/security/provider/certpath/CertId.java
41161 views
/*1* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.provider.certpath;2627import java.io.IOException;28import java.math.BigInteger;29import java.security.MessageDigest;30import java.security.NoSuchAlgorithmException;31import java.security.PublicKey;32import java.security.cert.X509Certificate;33import java.util.Arrays;34import javax.security.auth.x500.X500Principal;35import sun.security.util.HexDumpEncoder;36import sun.security.x509.*;37import sun.security.util.*;3839/**40* This class corresponds to the CertId field in OCSP Request41* and the OCSP Response. The ASN.1 definition for CertID is defined42* in RFC 2560 as:43* <pre>44*45* CertID ::= SEQUENCE {46* hashAlgorithm AlgorithmIdentifier,47* issuerNameHash OCTET STRING, -- Hash of Issuer's DN48* issuerKeyHash OCTET STRING, -- Hash of Issuers public key49* serialNumber CertificateSerialNumber50* }51*52* </pre>53*54* @author Ram Marti55*/5657public class CertId {5859private static final boolean debug = false;60private static final AlgorithmId SHA1_ALGID61= new AlgorithmId(AlgorithmId.SHA_oid);62private final AlgorithmId hashAlgId;63private final byte[] issuerNameHash;64private final byte[] issuerKeyHash;65private final SerialNumber certSerialNumber;66private int myhash = -1; // hashcode for this CertId6768/**69* Creates a CertId. The hash algorithm used is SHA-1.70*/71public CertId(X509Certificate issuerCert, SerialNumber serialNumber)72throws IOException {7374this(issuerCert.getSubjectX500Principal(),75issuerCert.getPublicKey(), serialNumber);76}7778public CertId(X500Principal issuerName, PublicKey issuerKey,79SerialNumber serialNumber) throws IOException {8081// compute issuerNameHash82MessageDigest md = null;83try {84md = MessageDigest.getInstance("SHA1");85} catch (NoSuchAlgorithmException nsae) {86throw new IOException("Unable to create CertId", nsae);87}88hashAlgId = SHA1_ALGID;89md.update(issuerName.getEncoded());90issuerNameHash = md.digest();9192// compute issuerKeyHash (remove the tag and length)93byte[] pubKey = issuerKey.getEncoded();94DerValue val = new DerValue(pubKey);95DerValue[] seq = new DerValue[2];96seq[0] = val.data.getDerValue(); // AlgorithmID97seq[1] = val.data.getDerValue(); // Key98byte[] keyBytes = seq[1].getBitString();99md.update(keyBytes);100issuerKeyHash = md.digest();101certSerialNumber = serialNumber;102103if (debug) {104HexDumpEncoder encoder = new HexDumpEncoder();105System.out.println("Issuer Name is " + issuerName);106System.out.println("issuerNameHash is " +107encoder.encodeBuffer(issuerNameHash));108System.out.println("issuerKeyHash is " +109encoder.encodeBuffer(issuerKeyHash));110System.out.println("SerialNumber is " + serialNumber.getNumber());111}112}113114/**115* Creates a CertId from its ASN.1 DER encoding.116*/117public CertId(DerInputStream derIn) throws IOException {118hashAlgId = AlgorithmId.parse(derIn.getDerValue());119issuerNameHash = derIn.getOctetString();120issuerKeyHash = derIn.getOctetString();121certSerialNumber = new SerialNumber(derIn);122}123124/**125* Return the hash algorithm identifier.126*/127public AlgorithmId getHashAlgorithm() {128return hashAlgId;129}130131/**132* Return the hash value for the issuer name.133*/134public byte[] getIssuerNameHash() {135return issuerNameHash;136}137138/**139* Return the hash value for the issuer key.140*/141public byte[] getIssuerKeyHash() {142return issuerKeyHash;143}144145/**146* Return the serial number.147*/148public BigInteger getSerialNumber() {149return certSerialNumber.getNumber();150}151152/**153* Encode the CertId using ASN.1 DER.154* The hash algorithm used is SHA-1.155*/156public void encode(DerOutputStream out) throws IOException {157158DerOutputStream tmp = new DerOutputStream();159hashAlgId.encode(tmp);160tmp.putOctetString(issuerNameHash);161tmp.putOctetString(issuerKeyHash);162certSerialNumber.encode(tmp);163out.write(DerValue.tag_Sequence, tmp);164165if (debug) {166HexDumpEncoder encoder = new HexDumpEncoder();167System.out.println("Encoded certId is " +168encoder.encode(out.toByteArray()));169}170}171172/**173* Returns a hashcode value for this CertId.174*175* @return the hashcode value.176*/177@Override public int hashCode() {178if (myhash == -1) {179myhash = hashAlgId.hashCode();180for (int i = 0; i < issuerNameHash.length; i++) {181myhash += issuerNameHash[i] * i;182}183for (int i = 0; i < issuerKeyHash.length; i++) {184myhash += issuerKeyHash[i] * i;185}186myhash += certSerialNumber.getNumber().hashCode();187}188return myhash;189}190191/**192* Compares this CertId for equality with the specified193* object. Two CertId objects are considered equal if their hash algorithms,194* their issuer name and issuer key hash values and their serial numbers195* are equal.196*197* @param other the object to test for equality with this object.198* @return true if the objects are considered equal, false otherwise.199*/200@Override public boolean equals(Object other) {201if (this == other) {202return true;203}204if (other == null || (!(other instanceof CertId))) {205return false;206}207208CertId that = (CertId) other;209if (hashAlgId.equals(that.getHashAlgorithm()) &&210Arrays.equals(issuerNameHash, that.getIssuerNameHash()) &&211Arrays.equals(issuerKeyHash, that.getIssuerKeyHash()) &&212certSerialNumber.getNumber().equals(that.getSerialNumber())) {213return true;214} else {215return false;216}217}218219/**220* Create a string representation of the CertId.221*/222@Override public String toString() {223StringBuilder sb = new StringBuilder();224sb.append("CertId \n");225sb.append("Algorithm: " + hashAlgId.toString() +"\n");226sb.append("issuerNameHash \n");227HexDumpEncoder encoder = new HexDumpEncoder();228sb.append(encoder.encode(issuerNameHash));229sb.append("\nissuerKeyHash: \n");230sb.append(encoder.encode(issuerKeyHash));231sb.append("\n" + certSerialNumber.toString());232return sb.toString();233}234}235236237