From b080d962581a3f9294e182e4f24945e5e201bba2 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sun, 26 May 2024 00:31:13 +0800 Subject: [PATCH] feat: save key and cert for client ca --- .../tools/yubikeyca/YubikeyCaConstant.java | 2 +- .../hatter/tools/yubikeyca/YubikeyCaMain.java | 46 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/yubikey-ca-java/src/main/java/me/hatter/tools/yubikeyca/YubikeyCaConstant.java b/yubikey-ca-java/src/main/java/me/hatter/tools/yubikeyca/YubikeyCaConstant.java index 8f36c57..6ecb559 100644 --- a/yubikey-ca-java/src/main/java/me/hatter/tools/yubikeyca/YubikeyCaConstant.java +++ b/yubikey-ca-java/src/main/java/me/hatter/tools/yubikeyca/YubikeyCaConstant.java @@ -2,5 +2,5 @@ package me.hatter.tools.yubikeyca; public interface YubikeyCaConstant { String NAME = "yubikey-ca"; - String VERSION = "0.2.3"; + String VERSION = "0.2.4"; } diff --git a/yubikey-ca-java/src/main/java/me/hatter/tools/yubikeyca/YubikeyCaMain.java b/yubikey-ca-java/src/main/java/me/hatter/tools/yubikeyca/YubikeyCaMain.java index d769d37..8912ffe 100644 --- a/yubikey-ca-java/src/main/java/me/hatter/tools/yubikeyca/YubikeyCaMain.java +++ b/yubikey-ca-java/src/main/java/me/hatter/tools/yubikeyca/YubikeyCaMain.java @@ -1,5 +1,6 @@ package me.hatter.tools.yubikeyca; +import me.hatter.tools.commons.datetime.DateTimeUtil; import me.hatter.tools.commons.io.RFile; import me.hatter.tools.commons.log.LogConfig; import me.hatter.tools.commons.log.LogTool; @@ -15,11 +16,14 @@ import me.hatter.tools.yubikeyca.cardcli.CardCliUtil; import me.hatter.tools.yubikeyca.cardcli.PivMeta; import me.hatter.tools.yubikeyca.hatterink.CertificateUtil; +import java.io.FileOutputStream; import java.security.KeyPair; +import java.security.KeyStore; import java.security.PrivateKey; import java.security.PublicKey; import java.security.cert.X509Certificate; import java.util.Arrays; +import java.util.Date; public class YubikeyCaMain { private static final LogTool log; @@ -110,6 +114,48 @@ public class YubikeyCaMain { } else { log.info("Issued CA private Key: \n" + privateKeyPem); } + final String suffix = DateTimeUtil.format("yyyyMMddHHmmss", new Date()); + if (privateKey != null) { + log.info("Write key file: " + "key-" + suffix + ".pem" + "..."); + RFile.from("key-" + suffix + ".pem").write(privateKeyPem); + } + log.info("Write cert file: " + "cert-" + suffix + ".pem" + "..."); + RFile.from("cert-" + suffix + ".pem").write(certPem); + + if (privateKey != null) { + log.info("Write PKCS#12 file: " + "p12-" + suffix + ".pfx" + "..."); + try (final FileOutputStream fos = new FileOutputStream("p12-" + suffix + ".pfx")) { + final String defaultPin = "changeit"; + final KeyStore ks = KeyStore.getInstance("PKCS12"); + ks.load(null, null); + final String privateKeyAlias = getCn(args.subject); + log.info("PKCS#12 private key alias: " + privateKeyAlias); + ks.setKeyEntry( + privateKeyAlias, privateKey, defaultPin.toCharArray(), + new X509Certificate[]{cert} + ); + ks.store(fos, defaultPin.toCharArray()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + + private static String getCn(String subject) { + if (StringUtil.isNotBlank(subject)) { + final int indexOfCn = subject.toUpperCase().indexOf("CN="); + if (indexOfCn >= 0) { + String name = subject.substring(indexOfCn + 3); + if (name.contains(",")) { + name = StringUtil.substringBefore(name, ","); + } + if (name.contains(";")) { + name = StringUtil.substringBefore(name, ";"); + } + return name; + } + } + return "default"; } private static void issueIntermediateCa(YubikeyCaArgs args) {