Java tutorial
/************************************************************************* * * * EJBCA Community: 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.cesecore.certificates.certificate; import java.io.IOException; import java.math.BigInteger; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.security.auth.x500.X500Principal; import org.apache.log4j.Logger; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.util.encoders.Base64; import org.cesecore.keys.util.KeyTools; import org.cesecore.util.CertTools; /** * An object of this class is identifying one or several certificates or a CRL. * * @version $Id: HashID.java 19902 2014-09-30 14:32:24Z anatom $ */ 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. */ private final boolean isOK; /* * The RFC4387 identification string. This is a base64 encoding of the hash. */ private final String b64; /** * The b64 with \ substituted with %2B to be used for URLs */ private final String b64url; /** * Key to be used for hash tables. */ private 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 = Integer.valueOf(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 cert The issuer DN of the certificate should be the identifier. * @return the ID * @throws CertificateException */ public static HashID getFromIssuerDN(X509CertificateHolder certificateHolder) throws CertificateException { return getFromIssuerDN(new JcaX509CertificateConverter().getCertificate(certificateHolder)); } /** * @param sDN A string representation of a DN to be as ID. The DN will not be transformed in any way. * @return the ID. */ public static HashID getFromDNString(String 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(CertTools.isDNReversed(sDN) ? CertTools.reverseDN(sDN) : sDN).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; } public String getB64url() { return b64url; } public Integer getKey() { return key; } public String getB64() { return b64; } }