certid.java
来自「This is a resource based on j2me embedde」· Java 代码 · 共 340 行
JAVA
340 行
/* * * * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */package com.sun.midp.pki.ocsp;import java.io.IOException;import java.util.Hashtable;import com.sun.midp.pki.DerInputStream;import com.sun.midp.pki.DerOutputStream;import com.sun.midp.pki.DerValue;import com.sun.midp.pki.X509Certificate;import com.sun.midp.pki.Utils;import com.sun.midp.pki.AlgorithmId;import com.sun.midp.pki.SerialNumber;import com.sun.midp.pki.BigInteger;import com.sun.midp.crypto.MessageDigest;import com.sun.midp.log.Logging;import com.sun.midp.log.LogChannels;/** * This class corresponds to the CertId field in OCSP Request * and the OCSP Response. The ASN.1 definition for CertID is defined * in RFC 2560 as: * <pre> * * CertID ::= SEQUENCE { * hashAlgorithm AlgorithmIdentifier, * issuerNameHash OCTET STRING, -- Hash of Issuer's DN * issuerKeyHash OCTET STRING, -- Hash of Issuers public key * serialNumber CertificateSerialNumber * } * * </pre> */public class CertId { private AlgorithmId hashAlgId; private byte[] issuerNameHash; private byte[] issuerKeyHash; private SerialNumber certSerialNumber; private int myhash = -1; // hashcode for this CertId /** * Creates a CertId. The hash algorithm used is SHA-1. */ public CertId(X509Certificate issuerCert, SerialNumber serialNumber) throws Exception { // compute issuerNameHash MessageDigest md = MessageDigest.getInstance("SHA-1"); hashAlgId = AlgorithmId.get("SHA-1"); byte[] data = getNameEncoded(issuerCert.getSubject()); md.update(data, 0, data.length); issuerNameHash = new byte[md.getDigestLength()]; md.digest(issuerNameHash, 0, issuerNameHash.length); // compute issuerKeyHash (remove the tag and length) byte[] pubKey = issuerCert.getPublicKey().getEncoded(); DerValue val = new DerValue(pubKey); DerValue[] seq = new DerValue[2]; seq[0] = val.data.getDerValue(); // AlgorithmID seq[1] = val.data.getDerValue(); // Key byte[] keyBytes = seq[1].getBitString(); md.update(keyBytes, 0, keyBytes.length); issuerKeyHash = new byte[md.getDigestLength()]; md.digest(issuerKeyHash, 0, issuerKeyHash.length); certSerialNumber = serialNumber; if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_SECURITY, "Issuer Certificate is " + issuerCert); Logging.report(Logging.INFORMATION, LogChannels.LC_SECURITY, "issuerNameHash is " + Utils.hexEncode(issuerNameHash)); Logging.report(Logging.INFORMATION, LogChannels.LC_SECURITY, "issuerKeyHash is " + Utils.hexEncode(issuerKeyHash)); } } /** * Creates a CertId from its ASN.1 DER encoding. */ public CertId(DerInputStream derIn) throws IOException { hashAlgId = AlgorithmId.parse(derIn.getDerValue()); issuerNameHash = derIn.getOctetString(); issuerKeyHash = derIn.getOctetString(); certSerialNumber = new SerialNumber(derIn); } /** * Return the hash algorithm identifier. */ public AlgorithmId getHashAlgorithm() { return hashAlgId; } /** * Return the hash value for the issuer name. */ public byte[] getIssuerNameHash() { return issuerNameHash; } /** * Return the hash value for the issuer key. */ public byte[] getIssuerKeyHash() { return issuerKeyHash; } /** * Return the serial number. */ public BigInteger getSerialNumber() { return certSerialNumber.getNumber(); } /** * Encode the CertId using ASN.1 DER. * The hash algorithm used is SHA-1. */ public void encode(DerOutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); hashAlgId.encode(tmp); tmp.putOctetString(issuerNameHash); tmp.putOctetString(issuerKeyHash); certSerialNumber.encode(tmp); out.write(DerValue.tag_Sequence, tmp); if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_SECURITY, "Encoded certId is " + Utils.hexEncode(out.toByteArray())); } } /** * Returns a hashcode value for this CertId. * * @return the hashcode value. */ public int hashCode() { if (myhash == -1) { myhash = hashAlgId.hashCode(); for (int i = 0; i < issuerNameHash.length; i++) { myhash += issuerNameHash[i] * i; } for (int i = 0; i < issuerKeyHash.length; i++) { myhash += issuerKeyHash[i] * i; } myhash += certSerialNumber.getNumber().hashCode(); } return myhash; } /** * Compares this CertId for equality with the specified * object. Two CertId objects are considered equal if their hash algorithms, * their issuer name and issuer key hash values and their serial numbers * are equal. * * @param other the object to test for equality with this object. * @return true if the objects are considered equal, false otherwise. */ public boolean equals(Object other) { if (this == other) { return true; } if (other == null || (!(other instanceof CertId))) { return false; } CertId that = (CertId) other; if (hashAlgId.equals(that.getHashAlgorithm()) && arraysEqual(issuerNameHash, that.getIssuerNameHash()) && arraysEqual(issuerKeyHash, that.getIssuerKeyHash()) && certSerialNumber.getNumber().equals(that.getSerialNumber())) { return true; } else { return false; } } /** * Returns DER-encoded form of the given name. * * @param name name to encode * @return array of bytes containing DER-encoded name * @throws IOException if error occured when encoding the subject name */ private byte[] getNameEncoded(String name) throws IOException { Hashtable nameTagToCode = new Hashtable(20); nameTagToCode.put("CN", new Integer(3)); // Common name: id-at 3 nameTagToCode.put("SN", new Integer(4)); // Surname: id-at 4 nameTagToCode.put("C", new Integer(6)); // Country: id-at 6 nameTagToCode.put("L", new Integer(7)); // Locality: id-at 7 nameTagToCode.put("ST", new Integer(8)); // State or province: id-at 8 nameTagToCode.put("STREET", new Integer(9)); // Street address: id-at 9 nameTagToCode.put("O", new Integer(10)); // Organization: id-at 10 nameTagToCode.put("OU", new Integer(11)); // Organization unit: id-at 11 // "EmailAddress" //String issuer = cert.getIssuer(); StringBuffer currTag = new StringBuffer(); int i = 0; DerOutputStream tmpStream = new DerOutputStream(); while (i < name.length()) { DerOutputStream out = new DerOutputStream(); char c = name.charAt(i); i++; if (c == '=') { Integer code = (Integer)nameTagToCode.get(currTag.toString()); if (code != null) { DerValue v = new DerValue(DerValue.tag_ObjectId, new byte[] {0x55, 0x04, code.byteValue()}); out.putDerValue(v); } else { // IMPL_NOTE: handle e-mail and unknown names throw new IOException("Can't encode: " + currTag); } String restOfName = name.substring(i); int idx = restOfName.indexOf(";"); if (idx < 0) { idx = restOfName.length(); } String attrValue = name.substring(i, i + idx); out.putPrintableString(attrValue); DerOutputStream tmpStream2 = new DerOutputStream(); tmpStream2.write(DerValue.tag_Sequence, out); tmpStream.write(DerValue.tag_Set, tmpStream2); i += idx + 1; currTag = new StringBuffer(); continue; } currTag.append(c); } DerOutputStream finalOut = new DerOutputStream(); finalOut.write(DerValue.tag_Sequence, tmpStream); return finalOut.toByteArray(); } /** * Returns <tt>true</tt> if the two specified arrays of bytes are * <i>equal</i> to one another. Two arrays are considered equal if both * arrays contain the same number of elements, and all corresponding pairs * of elements in the two arrays are equal. In other words, two arrays * are equal if they contain the same elements in the same order. Also, * two array references are considered equal if both are <tt>null</tt>.<p> * * @param a one array to be tested for equality. * @param a2 the other array to be tested for equality. * @return <tt>true</tt> if the two arrays are equal. */ private static boolean arraysEqual(byte[] a, byte[] a2) { if (a==a2) { return true; } if (a==null || a2==null) { return false; } int length = a.length; if (a2.length != length) { return false; } for (int i=0; i<length; i++) { if (a[i] != a2[i]) { return false; } } return true; } /** * Create a string representation of the CertId. */ public String toString() { StringBuffer sb = new StringBuffer(); sb.append("-- CertId ---\n"); sb.append("Algorithm: "); sb.append(hashAlgId.toString()); sb.append("\n"); sb.append("issuerNameHash: \n"); sb.append(Utils.hexEncode(issuerNameHash)); sb.append("\nissuerKeyHash: \n"); sb.append(Utils.hexEncode(issuerKeyHash)); sb.append("\n"); sb.append(certSerialNumber.toString()); return sb.toString(); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?