summaryrefslogtreecommitdiffstats
path: root/base/java-tools
diff options
context:
space:
mode:
authorAde Lee <alee@redhat.com>2017-04-11 14:18:32 -0400
committerAde Lee <alee@redhat.com>2017-04-12 15:19:34 -0400
commiteb7c9139c1ab017a8749d87e163e9dcc42037fb2 (patch)
tree3f2b2ab15fe3427b29275c55da35501627dce445 /base/java-tools
parent20a307e4683e62b033f7662ed4aa2f18dfad6226 (diff)
downloadpki-eb7c9139c1ab017a8749d87e163e9dcc42037fb2.tar.gz
pki-eb7c9139c1ab017a8749d87e163e9dcc42037fb2.tar.xz
pki-eb7c9139c1ab017a8749d87e163e9dcc42037fb2.zip
Modified CRMFPopClient to use correct wrapping for encrypt case
When the server cannot do key wrapping using the AES KeyWrap, probably because the backend HSM cannot do key wrapping, then there is a setting to allow it to use encrypt/decrypt instead. If the key wrap algorithm is something simple like 3DES or AES-CBC, then the client can just use key wrapping to wrap the key on its token, and the server can use an encryption algorithm to decrypt. The client does not need to know that the server cannot handle a key wrap, because keywrapping and encryption are pretty much the same mechanism - just either in server memory or not. When we do key wrapping using AES KeyWrap though, there is no corresponding encryption algorithm used to decrypt. So the server cannot simply decrypt a message wrapped with AES Keywrap (or at least not in any obvious way). So in this case, the client needs to know if the server can handle keywrap. The patch therefore does the following: 1. For CRMFPopClient, adds a command line option to specify if key wrapping or encryption is required. 2. Reads an environment variable if no option is provided. 3. If encryption is specified, uses key wrapping using AES-CBC which can be decrypted on the server side. 4. For cert-client, contacts the server to determine from the CAInfoResource if keywrapping is supported. Change-Id: If66f51c929cfde1c0ff3b9f39cb57b92fcdc150c
Diffstat (limited to 'base/java-tools')
-rw-r--r--base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java43
-rw-r--r--base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java28
2 files changed, 63 insertions, 8 deletions
diff --git a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
index 9d81a72a6..c5da9cf3a 100644
--- a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
+++ b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
@@ -40,6 +40,7 @@ import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
+import org.dogtagpki.common.KRAInfoResource;
import org.mozilla.jss.CryptoManager;
import org.mozilla.jss.asn1.ASN1Util;
import org.mozilla.jss.asn1.BIT_STRING;
@@ -182,6 +183,10 @@ public class CRMFPopClient {
option.setArgName("extractable");
options.addOption(option);
+ option = new Option("g", true, "KeyWrap");
+ option.setArgName("keyWrap");
+ options.addOption(option);
+
options.addOption("v", "verbose", false, "Run in verbose mode.");
options.addOption(null, "help", false, "Show help message.");
@@ -210,6 +215,9 @@ public class CRMFPopClient {
System.out.println(" - POP_NONE: without POP");
System.out.println(" - POP_SUCCESS: with valid POP");
System.out.println(" - POP_FAIL: with invalid POP (for testing)");
+ System.out.println(" -g <true|false> Use KeyWrapping to wrap private key (default: true)");
+ System.out.println(" - true: use a key wrapping algorithm");
+ System.out.println(" - false: use an encryption algorithm");
System.out.println(" -b <transport cert> PEM transport certificate (default: transport.txt)");
System.out.println(" -v, --verbose Run in verbose mode.");
System.out.println(" --help Show help message.");
@@ -302,6 +310,16 @@ public class CRMFPopClient {
int sensitive = Integer.parseInt(cmd.getOptionValue("s", "-1"));
int extractable = Integer.parseInt(cmd.getOptionValue("e", "-1"));
+ boolean keyWrap = true;
+ if (cmd.hasOption("g")) {
+ keyWrap = Boolean.parseBoolean(cmd.getOptionValue("g"));
+ } else {
+ String useKeyWrap = System.getenv("KEY_ARCHIVAL_USE_KEY_WRAPPING");
+ if (useKeyWrap != null) {
+ keyWrap = Boolean.parseBoolean(useKeyWrap);
+ }
+ }
+
String output = cmd.getOptionValue("o");
String hostPort = cmd.getOptionValue("m");
@@ -440,8 +458,11 @@ public class CRMFPopClient {
String kid = CryptoUtil.byte2string(id);
System.out.println("Keypair private key id: " + kid);
+ String archivalMechanism = keyWrap ? KRAInfoResource.KEYWRAP_MECHANISM :
+ KRAInfoResource.ENCRYPT_MECHANISM;
if (verbose) System.out.println("Creating certificate request");
- CertRequest certRequest = client.createCertRequest(token, transportCert, algorithm, keyPair, subject);
+ CertRequest certRequest = client.createCertRequest(
+ token, transportCert, algorithm, keyPair, subject, archivalMechanism);
ProofOfPossession pop = null;
@@ -550,7 +571,8 @@ public class CRMFPopClient {
X509Certificate transportCert,
String algorithm,
KeyPair keyPair,
- Name subject) throws Exception {
+ Name subject,
+ String archivalMechanism) throws Exception {
EncryptionAlgorithm encryptAlg = null;
String keyset = System.getenv("KEY_WRAP_PARAMETER_SET");
@@ -563,7 +585,7 @@ public class CRMFPopClient {
byte[] iv = CryptoUtil.getNonceData(encryptAlg.getIVLength());
AlgorithmIdentifier aid = new AlgorithmIdentifier(encryptAlg.toOID(), new OCTET_STRING(iv));
- WrappingParams params = getWrappingParams(encryptAlg, iv);
+ WrappingParams params = getWrappingParams(encryptAlg, iv, archivalMechanism);
PKIArchiveOptions opts = CryptoUtil.createPKIArchiveOptions(
token,
@@ -583,12 +605,23 @@ public class CRMFPopClient {
return new CertRequest(new INTEGER(1), certTemplate, seq);
}
- private WrappingParams getWrappingParams(EncryptionAlgorithm encryptAlg, byte[] wrapIV) throws Exception {
+ private WrappingParams getWrappingParams(EncryptionAlgorithm encryptAlg, byte[] wrapIV,
+ String archivalMechanism) throws Exception {
if (encryptAlg.getAlg().toString().equalsIgnoreCase("AES")) {
+ KeyWrapAlgorithm wrapAlg = null;
+ IVParameterSpec wrapIVS = null;
+ if (archivalMechanism.equals(KRAInfoResource.ENCRYPT_MECHANISM)) {
+ // We will use AES_CBC_PAD as the a key wrap mechanism. This
+ // can be decrypted using the same mechanism on the server.
+ wrapAlg = KeyWrapAlgorithm.AES_CBC_PAD;
+ wrapIVS = new IVParameterSpec(wrapIV);
+ } else {
+ wrapAlg = KeyWrapAlgorithm.AES_KEY_WRAP_PAD;
+ }
return new WrappingParams(
SymmetricKey.AES, KeyGenAlgorithm.AES, 128,
KeyWrapAlgorithm.RSA, encryptAlg,
- KeyWrapAlgorithm.AES_KEY_WRAP_PAD, null, null);
+ wrapAlg, wrapIVS, wrapIVS);
} else if (encryptAlg.getAlg().toString().equalsIgnoreCase("DESede")) {
return new WrappingParams(
SymmetricKey.DES3, KeyGenAlgorithm.DES3, 168,
diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java
index 6562699cf..8ca857bcb 100644
--- a/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java
@@ -29,6 +29,8 @@ import java.util.Vector;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Option;
import org.apache.commons.io.FileUtils;
+import org.dogtagpki.common.CAInfoClient;
+import org.dogtagpki.common.KRAInfoResource;
import org.mozilla.jss.CryptoManager;
import org.mozilla.jss.crypto.CryptoToken;
import org.mozilla.jss.crypto.Signature;
@@ -245,8 +247,26 @@ public class ClientCertRequestCLI extends CLI {
CryptoManager manager = CryptoManager.getInstance();
X509Certificate transportCert = manager.importCACertPackage(transportCertData);
+ // get archival mechanism
+ CAInfoClient infoClient = new CAInfoClient(client, "ca");
+ String archivalMechanism = KRAInfoResource.KEYWRAP_MECHANISM;
+ try {
+ archivalMechanism = infoClient.getInfo().getArchivalMechanism();
+ } catch (Exception e) {
+ // this could be an older server, check for environment variable.
+ String useKeyWrapping = System.getenv("KEY_ARCHIVAL_USE_KEY_WRAPPING");
+ if (useKeyWrapping != null) {
+ if (Boolean.parseBoolean(useKeyWrapping)) {
+ archivalMechanism = KRAInfoResource.KEYWRAP_MECHANISM;
+ } else {
+ archivalMechanism = KRAInfoResource.ENCRYPT_MECHANISM;
+ }
+ }
+ }
+
csr = generateCrmfRequest(transportCert, subjectDN, attributeEncoding,
- algorithm, length, curve, sslECDH, temporary, sensitive, extractable, withPop);
+ algorithm, length, curve, sslECDH, temporary, sensitive, extractable, withPop,
+ archivalMechanism);
} else {
throw new Exception("Unknown request type: " + requestType);
@@ -387,7 +407,8 @@ public class ClientCertRequestCLI extends CLI {
boolean temporary,
int sensitive,
int extractable,
- boolean withPop
+ boolean withPop,
+ String archivalMechanism
) throws Exception {
CryptoManager manager = CryptoManager.getInstance();
@@ -408,7 +429,8 @@ public class ClientCertRequestCLI extends CLI {
throw new Exception("Unknown algorithm: " + algorithm);
}
- CertRequest certRequest = client.createCertRequest(token, transportCert, algorithm, keyPair, subject);
+ CertRequest certRequest = client.createCertRequest(
+ token, transportCert, algorithm, keyPair, subject, archivalMechanism);
ProofOfPossession pop = null;
if (withPop) {