Java tutorial
/************************************************************************* * * * EJBCA: The OpenSource Certificate Authority * * * * This software is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or any later version. * * * * See terms of license at gnu.org. * * * *************************************************************************/ package org.ejbca.core.protocol.certificatestore; import java.io.IOException; import java.math.BigInteger; import java.security.cert.X509Certificate; import javax.security.auth.x500.X500Principal; import org.apache.log4j.Logger; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.util.encoders.Base64; import org.ejbca.util.CertTools; import org.ejbca.util.keystore.KeyTools; /** * An object of this class is identifying one or several certificates or a CRL. * @author Lars Silven PrimeKey * @version $Id: HashID.java 15003 2012-06-17 23:55:15Z primelars $ */ public class HashID { /** Log4j instance for Base */ private static final Logger log = Logger.getLogger(HashID.class); /** * True if the ID confirms to a RFC4387 ID. */ public final boolean isOK; /* * The RFC4387 identification string. This is a base64 encoding of the hash. */ public final String b64; /** * The b64 with \ substituted with %2B to be used for URLs */ public final String b64url; /** * Key to be used for hash tables. */ public final Integer key; private HashID(byte hash[]) { final String b64padded = new String(Base64.encode(hash)); if (b64padded.length() != 28 || b64padded.charAt(27) != '=') { this.isOK = false; this.b64 = b64padded; } else { this.isOK = true; this.b64 = b64padded.substring(0, 27); } this.b64url = this.b64.replaceAll("\\+", "%2B"); this.key = new Integer(new BigInteger(hash).hashCode()); } private static byte[] hashFromPrincipalDN(X500Principal principal) { return CertTools.generateSHA1Fingerprint(principal.getEncoded()); } private static HashID getFromDN(X500Principal principal) { final HashID id = new HashID(hashFromPrincipalDN(principal)); if (id.isOK) { if (log.isDebugEnabled()) { log.debug("The DN '" + principal.getName() + "' is identified by the Hash string '" + id.b64 + "' when accessing the VA."); } } else { log.error("The DN '" + principal.getName() + "' has a non valid Hash identification string: " + id.b64); } return id; } /** * @param cert The subject DN of the certificate should be the identifier. * @return the ID */ public static HashID getFromSubjectDN(X509Certificate cert) { return getFromDN(cert.getSubjectX500Principal()); } /** * @param cert The issuer DN of the certificate should be the identifier. * @return the ID */ public static HashID getFromIssuerDN(X509Certificate cert) { return getFromDN(cert.getIssuerX500Principal()); } /** * @param sDN A string representation of a DN to be as ID. * @return the ID. */ public static HashID getFromDN(String sDN) { final String ejbcaDN = CertTools.stringToBCDNString(sDN); // Note that the DN string has to be encoded to an ASN1 with the BC lib. BC endcoding is EJBCA standard. return getFromDN(new X500Principal(new X509Principal(ejbcaDN).getEncoded())); } /** * @param s The hash base64 encoded. See RFC4387 * @return the ID. */ public static HashID getFromB64(String s) { return new HashID(Base64.decode(s.length() == 27 ? s + '=' : s)); } /** * @param cert The public key of the certificate will be used as ID. * @return the ID. */ public static HashID getFromKeyID(X509Certificate cert) { final HashID id = new HashID(KeyTools.createSubjectKeyId(cert.getPublicKey()).getKeyIdentifier()); if (id.isOK) { if (log.isDebugEnabled()) { log.debug("The certificate with subject DN '" + cert.getSubjectX500Principal().getName() + "' can be fetched with 'search.cgi?sKIDHash=" + id.b64 + "' from the VA."); } } else { log.error("The certificate with subject DN '" + cert.getSubjectX500Principal().getName() + "' gives a sKIDHash with a not valid format: " + id.b64); } return id; } public static HashID getFromAuthorityKeyId(X509Certificate cert) throws IOException { final byte hash[] = CertTools.getAuthorityKeyId(cert); if (hash == null) { return null; } final HashID id = new HashID(CertTools.getAuthorityKeyId(cert)); if (!id.isOK) { log.error("The certificate with subject DN '" + cert.getSubjectX500Principal().getName() + "' don't have a valid AuthorityKeyId: " + id.b64); } return id; } }