/* * DSS - Digital Signature Services * * Copyright (C) 2013 European Commission, Directorate-General Internal Market and Services (DG MARKT), B-1049 Bruxelles/Brussel * * Developed by: 2013 ARHS Developments S.A. (rue Nicolas Bové 2B, L-1253 Luxembourg) http://www.arhs-developments.com * * This file is part of the "DSS - Digital Signature Services" project. * * "DSS - Digital Signature Services" 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 (at your option) any later version. * * DSS 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with * "DSS - Digital Signature Services". If not, see <http://www.gnu.org/licenses/>. */ package eu.europa.ec.markt.dss; import java.security.cert.X509Certificate; import java.util.LinkedHashMap; import java.util.Map.Entry; import javax.security.auth.x500.X500Principal; import eu.europa.ec.markt.dss.exception.DSSException; /** * This class is used to obtain a unique DSS certificate's id. It is very helpful to follow the relationships between * certificates, CRLs, OCSPs and signatures. This DSS unique id is a simple integer number. * <p/> * DISCLAIMER: Project owner DG-MARKT. * * @author <a href="mailto:dgmarkt.Project-DSS@arhs-developments.com">ARHS Developments</a> * @version $Revision: 672 $ - $Date: 2011-05-12 11:59:21 +0200 (Thu, 12 May 2011) $ */ public final class CertificateIdentifier { /** * This is the id which is given to a new certificate. */ private static int nextCertificateIdentifier = 1; /** * This boolean is used in testing context, to keep consistent ids for certificates between various test launches */ private static boolean UNIQUE_IDENTIFIER = false; /** * This {@link LinkedHashMap} represents the association between the certificate unique identifier (certificate's * issuer distinguished name + "|" + certificate's serial number) and the DSS certificate's id. */ private static LinkedHashMap<String, Integer> ids = new LinkedHashMap<String, Integer>(); private CertificateIdentifier() { } public static boolean isUniqueIdentifier() { return UNIQUE_IDENTIFIER; } /** * This method is used to keep consistent ids for certificates between various test launches * * @param uniqueIdentifier */ public static void setUniqueIdentifier(boolean uniqueIdentifier) { UNIQUE_IDENTIFIER = uniqueIdentifier; } /** * Returns the DSS certificate's unique id for a given {@link X509Certificate}. If the certificate is unknown then its identifier is created. * * @param x509Certificate {@code X509Certificate} for which the dss id is looking for * @return dss unique certificate identifier */ public static int getId(final X509Certificate x509Certificate) { if (x509Certificate == null) { throw new DSSException("The certificate cannot be null!"); } synchronized (ids) { final String certKey = getKey(x509Certificate); Integer id = ids.get(certKey); if (id == null) { id = add(certKey); } return id; } } /** * This method returns the DSS certificate's id based on the certificate's key: ( issuer distinguished name + "|" + * serial number). If the certificate is not yet stored it is added to the {@code ids}. * * @param key the key is composed of issuer distinguished name + "|" + serial number * @return DSS certificate's id */ private static int add(final String key) { Integer id = ids.get(key); if (id == null) { if (UNIQUE_IDENTIFIER) { id = key.hashCode(); ids.put(key, id); } else { id = nextCertificateIdentifier; ids.put(key, id); nextCertificateIdentifier++; } } return id; } /** * This method returns the unique identifier of a given {@link X509Certificate}. This identifier is used to obtain * the DSS certificate's unique id. The CANONICAL form of the {@code X500Principal} is used. * * @param cert * @return */ private static String getKey(final X509Certificate cert) { final String canonicalIssuerX500Principal = cert.getIssuerX500Principal().getName(X500Principal.CANONICAL); final String serialNumber = cert.getSerialNumber().toString(); return canonicalIssuerX500Principal + "|" + serialNumber; } /** * This method resets the list of certificates. */ public static void clear() { ids.clear(); nextCertificateIdentifier = 1; } /** * Returns the text representation of all certificates and their internal DSS number. The text is indented with the * given {@code indentStr} string. * * @param indentStr * @return */ public static String toString(String indentStr) { StringBuilder sb = new StringBuilder(); sb.append(indentStr).append("List of certificates:\n"); for (Entry<String, Integer> entry : ids.entrySet()) { Integer id = entry.getValue(); String key = entry.getKey(); sb.append(indentStr).append(String.format("[%s] : %s\n", id, key)); } return sb.toString(); } }