From a9f9c2266c3b697c25fdb1ee132b3a144165ec2f Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Tue, 31 Oct 2023 00:14:49 +0800 Subject: [PATCH] feat: v0.2.0, support client ca from piv card --- yubikey-ca-java/README.md | 10 ++++++ .../tools/yubikeyca/YubikeyCaConstant.java | 2 +- .../hatter/tools/yubikeyca/YubikeyCaMain.java | 32 +++++++++++++------ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/yubikey-ca-java/README.md b/yubikey-ca-java/README.md index 39fb230..3774705 100644 --- a/yubikey-ca-java/README.md +++ b/yubikey-ca-java/README.md @@ -58,3 +58,13 @@ $ java -jar yubikey-ca-java.jar --issue-client-code-ca \ --pin ****** \ [--add-to-remote] ``` + +or + +```shell +$ java -jar yubikey-ca-java.jar --issue-client-code-ca \ + --sign-slot 89 --cert-slot 90 --subject 'CN=Hatter Signing CA' --valid-years 10 \ + --intermediate-ca-id 44 \ + --pin ****** \ + [--add-to-remote] +``` 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 2e379fc..9632cb1 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.1.1"; + String VERSION = "0.2.0"; } 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 e137ed5..24460c6 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 @@ -15,6 +15,8 @@ import me.hatter.tools.yubikeyca.cardcli.PivMeta; import me.hatter.tools.yubikeyca.hatterink.CertificateUtil; import java.security.KeyPair; +import java.security.PrivateKey; +import java.security.PublicKey; import java.security.cert.X509Certificate; import java.util.Arrays; @@ -49,8 +51,8 @@ public class YubikeyCaMain { log.error("Intermediate CA id is required."); return; } - if (StringUtil.isEmpty(args.keypairType)) { - log.error("Keypair type is required."); + if (StringUtil.isEmpty(args.keypairType) && StringUtil.isEmpty(args.certSlot)) { + log.error("Keypair type or cert slot is required."); return; } if (args.issueServerCa && (args.dnsNames == null || args.dnsNames.length == 0)) { @@ -58,20 +60,28 @@ public class YubikeyCaMain { return; } - final PKType pkType = getPkTypeFromArgs(args); - if (pkType == null) return; - final X509Certificate interCertificate = CertificateUtil.getCertificate(args.pin, args.intermediateCaId); final PivMeta signPivMeta = CardCliUtil.getPivPublicKey(args.signSlot); - final KeyPair keyPair = KeyPairTool.instance(pkType).generateKeyPair().getKeyPair(); + final PublicKey publicKey; + PrivateKey privateKey = null; + if (StringUtil.isEmpty(args.certSlot)) { + final PKType pkType = getPkTypeFromArgs(args); + if (pkType == null) return; + final KeyPair keyPair = KeyPairTool.instance(pkType).generateKeyPair().getKeyPair(); + publicKey = keyPair.getPublic(); + privateKey = keyPair.getPrivate(); + } else { + final PivMeta certPivMeta = CardCliUtil.getPivPublicKey(args.certSlot); + publicKey = certPivMeta.getPublicKey(); + } final String cardCliCmd = CardCliUtil.getCardCliCmd(); final CertificateAuthority ca = CertificateAuthority.instance() .subject(args.subject) .signCert(interCertificate) - .certPubKey(keyPair.getPublic()) + .certPubKey(publicKey) .validYears(validYears(args, 2)) .customerSigner(new CardCliPivCustomerSigner( args.pin, args.signSlot, signPivMeta.getAlgorithm(), cardCliCmd)); @@ -85,7 +95,10 @@ public class YubikeyCaMain { cert = ca.createClientCert(); } final String certPem = X509CertUtil.serializeX509CertificateToPEM(cert); - final String privateKeyPem = KeyUtil.serializePrivateKeyToPEM(keyPair.getPrivate()); + String privateKeyPem = null; + if (privateKey != null) { + privateKeyPem = KeyUtil.serializePrivateKeyToPEM(privateKey); + } log.info("Issued CA: \n" + certPem); if (args.addToRemote) { @@ -108,6 +121,7 @@ public class YubikeyCaMain { final X509Certificate rootCertificate = CertificateUtil.getCertificate(args.pin, args.rootCaId); + final PivMeta signPivMeta = CardCliUtil.getPivPublicKey(args.signSlot); final PivMeta certPivMeta = CardCliUtil.getPivPublicKey(args.certSlot); final String cardCliCmd = CardCliUtil.getCardCliCmd(); @@ -117,7 +131,7 @@ public class YubikeyCaMain { .certPubKey(certPivMeta.getPublicKey()) .validYears(validYears(args, 10)) .customerSigner(new CardCliPivCustomerSigner( - args.pin, args.signSlot, certPivMeta.getAlgorithm(), cardCliCmd)) + args.pin, args.signSlot, signPivMeta.getAlgorithm(), cardCliCmd)) .createIntermediateCert(); final String intermediateCaPem = X509CertUtil.serializeX509CertificateToPEM(intermediateCa);