Skip to content

Commit

Permalink
Refactor ClientCertRequestCLI.generatePkcs10Request()
Browse files Browse the repository at this point in the history
The ClientCertRequestCLI.generatePkcs10Request() has been
modified to create a PKCS #10 request directly instead of
calling PKCS10Client.
  • Loading branch information
edewata committed Feb 7, 2025
1 parent 465671f commit e86084a
Showing 1 changed file with 96 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@

import java.io.ByteArrayOutputStream;
import java.io.Console;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyPair;
import java.util.ArrayList;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

Expand All @@ -37,16 +38,20 @@
import org.dogtagpki.cli.CommandCLI;
import org.dogtagpki.common.CAInfoClient;
import org.dogtagpki.nss.NSSDatabase;
import org.dogtagpki.util.cert.CertUtil;
import org.mozilla.jss.CryptoManager;
import org.mozilla.jss.crypto.CryptoToken;
import org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage;
import org.mozilla.jss.crypto.KeyWrapAlgorithm;
import org.mozilla.jss.crypto.Signature;
import org.mozilla.jss.crypto.SignatureAlgorithm;
import org.mozilla.jss.crypto.X509Certificate;
import org.mozilla.jss.netscape.security.pkcs.PKCS10;
import org.mozilla.jss.netscape.security.util.Cert;
import org.mozilla.jss.netscape.security.util.Utils;
import org.mozilla.jss.netscape.security.x509.Extensions;
import org.mozilla.jss.netscape.security.x509.X500Name;
import org.mozilla.jss.netscape.security.x509.X509Key;
import org.mozilla.jss.pkix.crmf.CertRequest;
import org.mozilla.jss.pkix.crmf.ProofOfPossession;
import org.mozilla.jss.pkix.primitive.Name;
Expand Down Expand Up @@ -109,13 +114,16 @@ public void createOptions() {
option.setArgName("key length");
options.addOption(option);

option = new Option(null, "curve", true, "ECC key curve name (default: nistp256)");
option.setArgName("curve name");
option = new Option(null, "wrap", false, "Generate RSA key for wrapping/unwrapping");
options.addOption(option);

option = new Option(null, "oaep", false, "Use OAEP key wrap algorithm.");
options.addOption(option);

option = new Option(null, "curve", true, "ECC key curve name (default: nistp256)");
option.setArgName("curve name");
options.addOption(option);

option = new Option(null, "ssl-ecdh", false, "SSL certificate with ECDH ECDSA");
options.addOption(option);

Expand Down Expand Up @@ -183,6 +191,8 @@ public void execute(CommandLine cmd) throws Exception {
// rsa, ec
String algorithm = cmd.getOptionValue("algorithm", "rsa");
int length = Integer.parseInt(cmd.getOptionValue("length", "2048"));
boolean wrap = cmd.hasOption("wrap");
boolean useOAEP = cmd.hasOption("oaep");

String curve = cmd.getOptionValue("curve", "nistp256");
boolean sslECDH = cmd.hasOption("ssl-ecdh");
Expand Down Expand Up @@ -250,43 +260,40 @@ public void execute(CommandLine cmd) throws Exception {
MainCLI mainCLI = (MainCLI) getRoot();
NSSDatabase nssdb = mainCLI.getNSSDatabase();

String password = mainCLI.config.getNSSPassword();
mainCLI.init();
PKIClient client = getClient();

String csr;
PKIClient client;
if ("pkcs10".equals(requestType)) {

KeyPair keyPair;

if ("rsa".equals(algorithm)) {
csr = generatePkcs10Request(
nssdb.getDirectory(),
password,
algorithm,
Integer.toString(length),
subjectDN);
}

else if ("ec".equals(algorithm)) {
csr = generatePkcs10Request(
nssdb.getDirectory(),
password,
algorithm,
keyPair = generateRSAKeyPair(
length,
wrap);

} else if ("ec".equals(algorithm)) {

keyPair = generateECCKeyPair(
curve,
subjectDN);
sslECDH,
temporary,
sensitive,
extractable);

} else {
throw new Exception("Error: Unknown algorithm: " + algorithm);
}

// initialize database after PKCS10Client to avoid conflict
mainCLI.init();
client = getClient();
csr = createPKCS10Request(
nssdb,
keyPair,
subjectDN);

} else if ("crmf".equals(requestType)) {

// initialize database before CRMFPopClient to load transport certificate
mainCLI.init();
client = getClient();

boolean useOAEP = cmd.hasOption("oaep");

String encoded;
if (transportCertFilename == null) {
CASystemCertClient certClient = new CASystemCertClient(client, "ca");
Expand Down Expand Up @@ -396,46 +403,74 @@ else if ("ec".equals(algorithm)) {
CACertRequestCLI.printCertRequestInfos(infos);
}

public String generatePkcs10Request(
File certDatabase,
String password,
String algorithm,
String length,
String subjectDN) throws Exception {
public KeyPair generateRSAKeyPair(
int length,
boolean wrap) throws Exception {

File csrFile = File.createTempFile("pki-client-cert-request-", ".csr", certDatabase);
csrFile.deleteOnExit();
CryptoManager manager = CryptoManager.getInstance();
CryptoToken token = manager.getThreadToken();

String lenOrCurve = "ec".equals(algorithm) ? "-c" : "-l";
Usage[] usages = wrap ? CryptoUtil.RSA_KEYPAIR_USAGES : null;
Usage[] usagesMask = wrap ? CryptoUtil.RSA_KEYPAIR_USAGES_MASK : null;

List<String> command = new ArrayList<>();
command.add("PKCS10Client");
command.add("-d");
command.add(certDatabase.getAbsolutePath());
return CryptoUtil.generateRSAKeyPair(
token,
length,
usages,
usagesMask);
}

if (password != null) {
command.add("-p");
command.add(password);
}
public KeyPair generateECCKeyPair(
String curve,
boolean sslECDH,
boolean temporary,
int sensitive,
int extractable) throws Exception {

CryptoManager manager = CryptoManager.getInstance();
CryptoToken token = manager.getThreadToken();

Usage[] usages = null;
Usage[] usagesMask = sslECDH ? CryptoUtil.ECDH_USAGES_MASK : CryptoUtil.ECDHE_USAGES_MASK;

command.add("-a");
command.add(algorithm);
command.add(lenOrCurve);
command.add("" + length);
command.add("-o");
command.add(csrFile.getAbsolutePath());
command.add("-n");
command.add(subjectDN);

try {
runExternal(command);
} catch (Exception e) {
throw new Exception("Unable to generate CSR: " + e.getMessage(), e);
return CryptoUtil.generateECCKeyPair(
token,
curve,
temporary,
sensitive,
extractable,
usages,
usagesMask);
}

public String createPKCS10Request(
NSSDatabase nssdb,
KeyPair keyPair,
String subjectDN) throws Exception {

PublicKey publicKey = keyPair.getPublic();
X509Key key = CryptoUtil.createX509Key(publicKey);

String keyAlgorithm;
if (publicKey instanceof RSAPublicKey) {
keyAlgorithm = "SHA256withRSA";
} else if (CryptoUtil.isECCKey(key)) {
keyAlgorithm = "SHA256withEC";
} else if (publicKey instanceof DSAPublicKey) {
keyAlgorithm = "DSA";
} else {
throw new NoSuchAlgorithmException("Unsupported algorithm: " + publicKey.getAlgorithm());
}

logger.info("CSR generated: " + csrFile);
Extensions extensions = new Extensions();

PKCS10 pkcs10 = nssdb.createPKCS10Request(
keyPair,
subjectDN,
keyAlgorithm,
extensions);

return new String(Files.readAllBytes(csrFile.toPath()));
return CertUtil.toPEM(pkcs10);
}

public String generateCrmfRequest(
Expand Down

0 comments on commit e86084a

Please sign in to comment.