From ec1f1b4bfb3b221cadcfd49f83c311746865541a Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Thu, 10 Aug 2023 18:16:20 -0500 Subject: [PATCH] Add pki nss-cert-find --cert option The pki nss-cert-find has been updated to provide an option to search for a cert in NSS database based on an existing cert file. This can be used to check whether the cert has been imported into the NSS database and to get the nickname and trust flags assigned to the cert. --- .../netscape/cmstools/nss/NSSCertFindCLI.java | 104 +++++++++++++++++- 1 file changed, 100 insertions(+), 4 deletions(-) diff --git a/base/tools/src/main/java/com/netscape/cmstools/nss/NSSCertFindCLI.java b/base/tools/src/main/java/com/netscape/cmstools/nss/NSSCertFindCLI.java index 56a30dc757f..881f38f8e63 100644 --- a/base/tools/src/main/java/com/netscape/cmstools/nss/NSSCertFindCLI.java +++ b/base/tools/src/main/java/com/netscape/cmstools/nss/NSSCertFindCLI.java @@ -5,12 +5,29 @@ // package com.netscape.cmstools.nss; +import java.io.ByteArrayInputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Option; import org.dogtagpki.cli.CommandCLI; +import org.mozilla.jss.CryptoManager; +import org.mozilla.jss.asn1.ASN1Util; +import org.mozilla.jss.asn1.INTEGER; import org.mozilla.jss.crypto.CryptoStore; import org.mozilla.jss.crypto.CryptoToken; +import org.mozilla.jss.crypto.ObjectNotFoundException; import org.mozilla.jss.crypto.X509Certificate; +import org.mozilla.jss.netscape.security.util.Cert; +import org.mozilla.jss.pkix.cert.Certificate; +import org.mozilla.jss.pkix.cert.CertificateInfo; +import org.mozilla.jss.pkix.primitive.Name; +import com.netscape.certsrv.dbs.certdb.CertId; import com.netscape.cmstools.cli.MainCLI; import com.netscape.cmsutil.crypto.CryptoUtil; @@ -29,15 +46,94 @@ public void printHelp() { } @Override - public void execute(CommandLine cmd) throws Exception { + public void createOptions() { + Option option = new Option(null, "cert", true, "Certificate to find"); + option.setArgName("path"); + options.addOption(option); - MainCLI mainCLI = (MainCLI) getRoot(); - mainCLI.init(); + option = new Option(null, "format", true, "Certificate format: PEM (default), DER"); + option.setArgName("format"); + options.addOption(option); + } + + public Collection findCertByDERCert(byte[] derCert) throws Exception { + + ArrayList certs = new ArrayList<>(); + + Certificate pkixCert; + try (ByteArrayInputStream is = new ByteArrayInputStream(derCert)) { + pkixCert = (Certificate) Certificate.getTemplate().decode(is); + } + + CertificateInfo certInfo = pkixCert.getInfo(); + Name issuer = certInfo.getIssuer(); + INTEGER serialNumber = certInfo.getSerialNumber(); + logger.info("Searching for cert with:"); + logger.info("- issuer: " + issuer.getRFC1485()); + logger.info("- serial number: " + new CertId(serialNumber).toHexString()); + + try { + CryptoManager cm = CryptoManager.getInstance(); + + // CryptoManager doesn't have a method that calls CERT_FindCertByDERCert() + // in NSS so for now just use findCertByIssuerAndSerialNumber(). + // TODO: Add CryptoManager.findCertByDERCert() to call CERT_FindCertByDERCert(). + X509Certificate x509cert = cm.findCertByIssuerAndSerialNumber( + ASN1Util.encode(issuer), + serialNumber); + + certs.add(x509cert); + + } catch (ObjectNotFoundException e) { + logger.info("Cert not found"); + } + + return certs; + } + + public Collection findAllCerts() throws Exception { + + logger.info("Searching for all certs"); String tokenName = getConfig().getTokenName(); CryptoToken token = CryptoUtil.getKeyStorageToken(tokenName); CryptoStore store = token.getCryptoStore(); - X509Certificate[] certs = store.getCertificates(); + + return Arrays.asList(store.getCertificates()); + } + + @Override + public void execute(CommandLine cmd) throws Exception { + + String filename = cmd.getOptionValue("cert"); + String format = cmd.getOptionValue("format"); + + MainCLI mainCLI = (MainCLI) getRoot(); + mainCLI.init(); + + Collection certs; + + if (filename != null) { + + // load cert from file + byte[] bytes = Files.readAllBytes(Paths.get(filename)); + + if (format == null || "PEM".equalsIgnoreCase(format)) { + bytes = Cert.parseCertificate(new String(bytes)); + + } else if ("DER".equalsIgnoreCase(format)) { + // nothing to do + + } else { + throw new Exception("Unsupported format: " + format); + } + + certs = findCertByDERCert(bytes); + + } else { + certs = findAllCerts(); + } + boolean first = true; for (X509Certificate cert : certs) {