diff --git a/.github/workflows/pki-nss-aes-test.yml b/.github/workflows/pki-nss-aes-test.yml index c129a7e5004..8a289040a6b 100644 --- a/.github/workflows/pki-nss-aes-test.yml +++ b/.github/workflows/pki-nss-aes-test.yml @@ -35,6 +35,8 @@ jobs: run: | docker exec pki pki nss-key-create --key-type AES test | tee output + docker exec pki pki nss-key-show --key-nickname test + # verify with tkstool docker exec pki tkstool -L -d /root/.dogtag/nssdb | tee output echo "test" > expected diff --git a/.github/workflows/pki-nss-ecc-test.yml b/.github/workflows/pki-nss-ecc-test.yml index f1417e67871..99464a245c7 100644 --- a/.github/workflows/pki-nss-ecc-test.yml +++ b/.github/workflows/pki-nss-ecc-test.yml @@ -36,7 +36,10 @@ jobs: docker exec pki pki nss-key-create --key-type EC | tee output # get key ID - sed -n 's/^\s*Key ID:\s*\(\S\+\)\s*$/\1/p' output > ca_signing_key_id + KEY_ID=$(sed -n 's/^\s*Key ID:\s*\(\S\+\)\s*$/\1/p' output) + echo $KEY_ID > ca_signing_key_id + + docker exec pki pki nss-key-show --key-id $KEY_ID - name: Verify key type run: | diff --git a/.github/workflows/pki-nss-hsm-test.yml b/.github/workflows/pki-nss-hsm-test.yml index 191f022df22..ffd7d3f2e85 100644 --- a/.github/workflows/pki-nss-hsm-test.yml +++ b/.github/workflows/pki-nss-hsm-test.yml @@ -53,7 +53,14 @@ jobs: nss-key-create | tee output # get key ID - sed -n 's/^\s*Key ID:\s*\(\S\+\)\s*$/\1/p' output > ca_signing_key_id + KEY_ID=$(sed -n 's/^\s*Key ID:\s*\(\S\+\)\s*$/\1/p' output) + echo $KEY_ID > ca_signing_key_id + + docker exec pki pki \ + --token HSM \ + -f $SHARED/password.conf \ + nss-key-show \ + --key-id $KEY_ID - name: Verify key in HSM run: | diff --git a/.github/workflows/pki-nss-rsa-test.yml b/.github/workflows/pki-nss-rsa-test.yml index c205eb8da40..a5a88dba426 100644 --- a/.github/workflows/pki-nss-rsa-test.yml +++ b/.github/workflows/pki-nss-rsa-test.yml @@ -36,7 +36,10 @@ jobs: docker exec pki pki nss-key-create --key-type RSA | tee output # get key ID - sed -n 's/^\s*Key ID:\s*\(\S\+\)\s*$/\1/p' output > ca_signing_key_id + KEY_ID=$(sed -n 's/^\s*Key ID:\s*\(\S\+\)\s*$/\1/p' output) + echo $KEY_ID > ca_signing_key_id + + docker exec pki pki nss-key-show --key-id $KEY_ID - name: Verify key type run: | diff --git a/base/tools/src/main/java/com/netscape/cmstools/nss/NSSKeyCLI.java b/base/tools/src/main/java/com/netscape/cmstools/nss/NSSKeyCLI.java index d18428f05de..414b75ce561 100644 --- a/base/tools/src/main/java/com/netscape/cmstools/nss/NSSKeyCLI.java +++ b/base/tools/src/main/java/com/netscape/cmstools/nss/NSSKeyCLI.java @@ -18,6 +18,7 @@ public NSSKeyCLI(NSSCLI nssCLI) { addModule(new NSSKeyCreateCLI(this)); addModule(new NSSKeyExportCLI(this)); addModule(new NSSKeyFindCLI(this)); + addModule(new NSSKeyShowCLI(this)); addModule(new NSSKeyImportCLI(this)); } diff --git a/base/tools/src/main/java/com/netscape/cmstools/nss/NSSKeyShowCLI.java b/base/tools/src/main/java/com/netscape/cmstools/nss/NSSKeyShowCLI.java new file mode 100644 index 00000000000..3995ba352db --- /dev/null +++ b/base/tools/src/main/java/com/netscape/cmstools/nss/NSSKeyShowCLI.java @@ -0,0 +1,137 @@ +// +// Copyright Red Hat, Inc. +// +// SPDX-License-Identifier: GPL-2.0-or-later +// +package com.netscape.cmstools.nss; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Option; +import org.apache.commons.lang3.StringUtils; +import org.dogtagpki.cli.CLIException; +import org.dogtagpki.cli.CommandCLI; +import org.dogtagpki.util.logging.PKILogger; +import org.dogtagpki.util.logging.PKILogger.LogLevel; +import org.mozilla.jss.crypto.CryptoStore; +import org.mozilla.jss.crypto.CryptoToken; +import org.mozilla.jss.crypto.PrivateKey; +import org.mozilla.jss.netscape.security.util.Utils; +import org.mozilla.jss.pkcs11.PK11SymKey; +import org.mozilla.jss.symkey.SessionKey; + +import com.netscape.certsrv.dbs.keydb.KeyId; +import com.netscape.certsrv.key.KeyInfo; +import com.netscape.cmstools.cli.MainCLI; +import com.netscape.cmsutil.crypto.CryptoUtil; + +/** + * @author Endi S. Dewata + */ +public class NSSKeyShowCLI extends CommandCLI { + + public NSSKeyCLI keyCLI; + + public NSSKeyShowCLI(NSSKeyCLI keyCLI) { + super("show", "Show key in NSS database", keyCLI); + this.keyCLI = keyCLI; + } + + @Override + public void printHelp() { + formatter.printHelp(getFullName() + " [OPTIONS...]", options); + } + + @Override + public void createOptions() { + Option option = new Option(null, "key-id", true, "Key ID"); + option.setArgName("ID"); + options.addOption(option); + + option = new Option(null, "key-nickname", true, "Key nickname"); + option.setArgName("nickname"); + options.addOption(option); + + option = new Option(null, "output-format", true, "Output format: text (default), json"); + option.setArgName("format"); + options.addOption(option); + } + + public void printKeyInfo(KeyInfo keyInfo, String outputFormat) throws Exception { + if (outputFormat.equalsIgnoreCase("json")) { + System.out.println(keyInfo.toJSON()); + + } else if (outputFormat.equalsIgnoreCase("text")) { + NSSKeyCLI.printKeyInfo(keyInfo); + + } else { + throw new Exception("Unsupported output format: " + outputFormat); + } + } + + @Override + public void execute(CommandLine cmd) throws Exception { + + if (cmd.hasOption("debug")) { + PKILogger.setLevel(PKILogger.LogLevel.DEBUG); + + } else if (cmd.hasOption("verbose")) { + PKILogger.setLevel(LogLevel.INFO); + } + + MainCLI mainCLI = (MainCLI) getRoot(); + mainCLI.init(); + + String keyID = cmd.getOptionValue("key-id"); + String keyNickname = cmd.getOptionValue("key-nickname"); + String outputFormat = cmd.getOptionValue("output-format", "text"); + + String tokenName = getConfig().getTokenName(); + CryptoToken token = CryptoUtil.getKeyStorageToken(tokenName); + CryptoStore cryptoStore = token.getCryptoStore(); + + if (keyID != null) { + + // TODO: implement cryptoStore.getPrivateKey(keyID) + PrivateKey[] privateKeys = cryptoStore.getPrivateKeys(); + logger.info("Private keys: " + privateKeys); + + for (PrivateKey privateKey : privateKeys) { + + String hexKeyID = "0x" + Utils.HexEncode(privateKey.getUniqueID()); + if (!keyID.equals(hexKeyID)) continue; + + KeyInfo keyInfo = new KeyInfo(); + keyInfo.setKeyId(new KeyId(hexKeyID)); + keyInfo.setType(privateKey.getType().toString()); + keyInfo.setAlgorithm(privateKey.getAlgorithm()); + + printKeyInfo(keyInfo, outputFormat); + break; + } + + } else if (keyNickname != null) { + + // TODO: implement cryptoStore.getSymmetricKey(keyNickname) + String nicknames = SessionKey.ListSymmetricKeys(tokenName); + logger.info("Symmetric keys: " + nicknames); + + for (String nickname : nicknames.split(",")) { + if (StringUtils.isEmpty(nickname)) continue; + if (!keyNickname.equals(nickname)) continue; + + PK11SymKey symmetricKey = SessionKey.GetSymKeyByName(tokenName, nickname); + + KeyInfo keyInfo = new KeyInfo(); + keyInfo.setNickname(symmetricKey.getNickName()); + keyInfo.setType(symmetricKey.getType().toString()); + keyInfo.setAlgorithm(symmetricKey.getAlgorithm()); + + printKeyInfo(keyInfo, outputFormat); + break; + } + + } else { + throw new CLIException("Missing key ID or key nickname"); + } + } +}