summaryrefslogtreecommitdiffstats
path: root/base/kra
diff options
context:
space:
mode:
authorChristina Fu <cfu@redhat.com>2012-09-18 14:47:17 -0700
committerChristina Fu <cfu@redhat.com>2012-09-18 14:53:01 -0700
commit6257d326cca9e55f9d6898bb2b227f22485322b7 (patch)
tree4fb62a51653394f9f5feb170f51ac7fae6b86ea0 /base/kra
parent8ed86a749548ed2c373026ec34f5284a329bb7c2 (diff)
downloadpki-6257d326cca9e55f9d6898bb2b227f22485322b7.tar.gz
pki-6257d326cca9e55f9d6898bb2b227f22485322b7.tar.xz
pki-6257d326cca9e55f9d6898bb2b227f22485322b7.zip
https://fedorahosted.org/pki/ticket/304
TMS ECC infrastructure (enrollment with client-side and server-side key generation, and key archival)
Diffstat (limited to 'base/kra')
-rw-r--r--base/kra/src/com/netscape/kra/NetkeyKeygenService.java235
1 files changed, 174 insertions, 61 deletions
diff --git a/base/kra/src/com/netscape/kra/NetkeyKeygenService.java b/base/kra/src/com/netscape/kra/NetkeyKeygenService.java
index 1fdf9f74e..f0eec6a26 100644
--- a/base/kra/src/com/netscape/kra/NetkeyKeygenService.java
+++ b/base/kra/src/com/netscape/kra/NetkeyKeygenService.java
@@ -32,6 +32,7 @@ import java.security.SecureRandom;
import netscape.security.provider.RSAPublicKey;
+import org.mozilla.jss.asn1.ASN1Util;
import org.mozilla.jss.crypto.Cipher;
import org.mozilla.jss.crypto.CryptoToken;
import org.mozilla.jss.crypto.EncryptionAlgorithm;
@@ -52,7 +53,9 @@ import org.mozilla.jss.util.Base64OutputStream;
import com.netscape.certsrv.apps.CMS;
import com.netscape.certsrv.base.EBaseException;
import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.MetaInfo;
import com.netscape.certsrv.base.SessionContext;
+import com.netscape.certsrv.dbs.keydb.IKeyRecord;
import com.netscape.certsrv.dbs.keydb.IKeyRepository;
import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
import com.netscape.certsrv.logging.ILogger;
@@ -60,8 +63,10 @@ import com.netscape.certsrv.request.IRequest;
import com.netscape.certsrv.request.IService;
import com.netscape.certsrv.security.IStorageKeyUnit;
import com.netscape.certsrv.security.ITransportKeyUnit;
+import com.netscape.cms.servlet.key.KeyRecordParser;
import com.netscape.cmscore.dbs.KeyRecord;
import com.netscape.cmscore.util.Debug;
+import com.netscape.cmsutil.crypto.CryptoUtil;
/**
* A class representing keygen/archival request procesor for requests
@@ -133,7 +138,7 @@ public class NetkeyKeygenService implements IService {
}
public KeyPair generateKeyPair(
- KeyPairAlgorithm kpAlg, int keySize, PQGParams pqg)
+ KeyPairAlgorithm kpAlg, int keySize, String keyCurve, PQGParams pqg)
throws NoSuchAlgorithmException, TokenException, InvalidAlgorithmParameterException,
InvalidParameterException, PQGParamGenException {
@@ -158,15 +163,22 @@ public class NetkeyKeygenService implements IService {
boolean tp = false;
boolean sp = false;
boolean ep = false;
- if (kgConfig != null) {
+ if ((kgConfig != null) && (!kgConfig.equals(""))) {
try {
tp = kgConfig.getBoolean("temporaryPairs", false);
sp = kgConfig.getBoolean("sensitivePairs", false);
ep = kgConfig.getBoolean("extractablePairs", false);
+ CMS.debug("NetkeyKeygenService: found config store: kra.keygen");
// by default, let nethsm work
if ((tp == false) && (sp == false) && (ep == false)) {
- tp = true;
- }
+ if (kpAlg == KeyPairAlgorithm.EC) {
+ // set to what works for nethsm
+ tp = true;
+ sp = false;
+ ep = true;
+ } else
+ tp = true;
+ }
} catch (Exception e) {
CMS.debug("NetkeyKeygenService: kgConfig.getBoolean failed");
// by default, let nethsm work
@@ -175,68 +187,110 @@ public class NetkeyKeygenService implements IService {
} else {
// by default, let nethsm work
CMS.debug("NetkeyKeygenService: cannot find config store: kra.keygen, assume temporaryPairs==true");
- tp = true;
- }
- /* only specified to "true" will it be set */
- if (tp == true) {
- CMS.debug("NetkeyKeygenService: setting temporaryPairs to true");
- kpGen.temporaryPairs(true);
- }
- if (sp == true) {
- CMS.debug("NetkeyKeygenService: setting sensitivePairs to true");
- kpGen.sensitivePairs(true);
- }
- if (ep == true) {
- CMS.debug("NetkeyKeygenService: setting extractablePairs to true");
- kpGen.extractablePairs(true);
- }
-
- if (kpAlg == KeyPairAlgorithm.DSA) {
- if (pqg == null) {
- kpGen.initialize(keySize);
+ if (kpAlg == KeyPairAlgorithm.EC) {
+ // set to what works for nethsm
+ tp = true;
+ sp = false;
+ ep = true;
} else {
- kpGen.initialize(pqg);
+ tp = true;
}
- } else {
- kpGen.initialize(keySize);
}
- if (pqg == null) {
- KeyPair kp = null;
- synchronized (new Object()) {
- CMS.debug("NetkeyKeygenService: key pair generation begins");
- kp = kpGen.genKeyPair();
- CMS.debug("NetkeyKeygenService: key pair generation done");
- mKRA.addEntropy(true);
+ if (kpAlg == KeyPairAlgorithm.EC) {
+
+ boolean isECDHE = false;
+ KeyPair pair = null;
+
+ // used with isECDHE == true
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage usages_mask_ECDSA[] = {
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.DERIVE
+ };
+
+ // used with isECDHE == false
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage usages_mask_ECDH[] = {
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN,
+ org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN_RECOVER
+ };
+
+ try {
+ pair = CryptoUtil.generateECCKeyPair(token.getName(),
+ keyCurve /*ECC_curve default*/,
+ null,
+ (isECDHE==true) ? usages_mask_ECDSA: usages_mask_ECDH,
+ tp /*temporary*/, sp? 1:0 /*sensitive*/, ep? 1:0 /*extractable*/);
+ CMS.debug("NetkeyKeygenService: after key pair generation" );
+ } catch (Exception e) {
+ CMS.debug("NetkeyKeygenService: key pair generation with exception:"+e.toString());
}
- return kp;
- } else {
- // DSA
- KeyPair kp = null;
+ return pair;
- /* no DSA for now... netkey prototype
- do {
- // 602548 NSS bug - to overcome it, we use isBadDSAKeyPair
- kp = kpGen.genKeyPair();
+ } else { // !EC
+ //only specified to "true" will it be set
+ if (tp == true) {
+ CMS.debug("NetkeyKeygenService: setting temporaryPairs to true");
+ kpGen.temporaryPairs(true);
+ }
+
+ if (sp == true) {
+ CMS.debug("NetkeyKeygenService: setting sensitivePairs to true");
+ kpGen.sensitivePairs(true);
+ }
+
+ if (ep == true) {
+ CMS.debug("NetkeyKeygenService: setting extractablePairs to true");
+ kpGen.extractablePairs(true);
+ }
+
+ if (kpAlg == KeyPairAlgorithm.DSA) {
+ if (pqg == null) {
+ kpGen.initialize(keySize);
+ } else {
+ kpGen.initialize(pqg);
+ }
+ } else {
+ kpGen.initialize(keySize);
+ }
+
+ if (pqg == null) {
+ KeyPair kp = null;
+ synchronized (new Object()) {
+ CMS.debug("NetkeyKeygenService: key pair generation begins");
+ kp = kpGen.genKeyPair();
+ CMS.debug("NetkeyKeygenService: key pair generation done");
+ mKRA.addEntropy(true);
+ }
+ return kp;
+ } else {
+ // DSA
+ KeyPair kp = null;
+
+ /* no DSA for now... netkey prototype
+ do {
+ // 602548 NSS bug - to overcome it, we use isBadDSAKeyPair
+ kp = kpGen.genKeyPair();
+ }
+ while (isBadDSAKeyPair(kp));
+ */
+ return kp;
}
- while (isBadDSAKeyPair(kp));
- */
- return kp;
}
}
public KeyPair generateKeyPair(String alg,
- int keySize, PQGParams pqg) throws EBaseException {
+ int keySize, String keyCurve, PQGParams pqg) throws EBaseException {
KeyPairAlgorithm kpAlg = null;
if (alg.equals("RSA"))
kpAlg = KeyPairAlgorithm.RSA;
+ else if (alg.equals("EC"))
+ kpAlg = KeyPairAlgorithm.EC;
else
kpAlg = KeyPairAlgorithm.DSA;
try {
- KeyPair kp = generateKeyPair(kpAlg, keySize, pqg);
+ KeyPair kp = generateKeyPair(kpAlg, keySize, keyCurve, pqg);
return kp;
} catch (InvalidParameterException e) {
@@ -338,8 +392,8 @@ public class NetkeyKeygenService implements IService {
String rCUID = request.getExtDataInString(IRequest.NETKEY_ATTR_CUID);
String rUserid = request.getExtDataInString(IRequest.NETKEY_ATTR_USERID);
- String rKeysize = request.getExtDataInString(IRequest.NETKEY_ATTR_KEY_SIZE);
- int keysize = Integer.parseInt(rKeysize);
+ String rKeytype = request.getExtDataInString(IRequest.NETKEY_ATTR_KEY_TYPE);
+
auditSubjectID = rCUID + ":" + rUserid;
SessionContext sContext = SessionContext.getContext();
@@ -362,13 +416,34 @@ public class NetkeyKeygenService implements IService {
wrapped_des_key = com.netscape.cmsutil.util.Utils.SpecialDecode(rWrappedDesKeyString);
CMS.debug("NetkeyKeygenService: wrapped_des_key specialDecoded");
+
+ if ((rKeytype == null) || (rKeytype.equals(""))) {
+ CMS.debug("NetkeyKeygenService: serviceRequest: key type is null");
+ rKeytype = "RSA";
+ } else
+ CMS.debug("NetkeyKeygenService: serviceRequest: key type = "+ rKeytype);
+
+ /* for EC, keysize is ignored, only key curve is used */
+ String rKeysize = "2048";
+ int keysize = 2048;
+ String rKeycurve = "nistp256";
+ if (rKeytype.equals("EC")) {
+ rKeycurve = request.getExtDataInString(IRequest.NETKEY_ATTR_KEY_EC_CURVE);
+ if ((rKeycurve == null) || (rKeycurve.equals(""))) {
+ rKeycurve = "nistp256";
+ }
+ } else {
+ rKeysize = request.getExtDataInString(IRequest.NETKEY_ATTR_KEY_SIZE);
+ keysize = Integer.parseInt(rKeysize);
+ }
+
// get the token for generating user keys
CryptoToken keygenToken = mKRA.getKeygenToken();
if (keygenToken == null) {
CMS.debug("NetkeyKeygenService: failed getting keygenToken");
request.setExtData(IRequest.RESULT, Integer.valueOf(10));
return false;
- } else
+ } else
CMS.debug("NetkeyKeygenService: got keygenToken");
if ((wrapped_des_key != null) &&
@@ -382,8 +457,10 @@ public class NetkeyKeygenService implements IService {
CMS.debug("NetkeyKeygenService: about to generate key pair");
- keypair = generateKeyPair("RSA"/*alg*/,
- keysize /*Integer.parseInt(len)*/, null /*pqgParams*/);
+ keypair = generateKeyPair(rKeytype /* rKeytype: "RSA" or "EC" */,
+ keysize /*Integer.parseInt(len)*/,
+ rKeycurve /* for "EC" only */,
+ null /*pqgParams*/);
if (keypair == null) {
CMS.debug("NetkeyKeygenService: failed generating key pair for " + rCUID + ":" + rUserid);
@@ -409,7 +486,9 @@ public class NetkeyKeygenService implements IService {
return false;
} else {
//CMS.debug("NetkeyKeygenService: public key binary length ="+ publicKeyData.length);
- PubKey = base64Encode(publicKeyData);
+ /* url encode */
+ PubKey = com.netscape.cmsutil.util.Utils.SpecialEncode(publicKeyData);
+ CMS.debug("NetkeyKeygenService: EC PubKey special encoded");
//CMS.debug("NetkeyKeygenService: public key length =" + PubKey.length());
request.setExtData("public_key", PubKey);
@@ -536,16 +615,50 @@ public class NetkeyKeygenService implements IService {
CMS.debug("NetkeyKeygenService: got key record");
- // we deal with RSA key only
- try {
- RSAPublicKey rsaPublicKey = new RSAPublicKey(publicKeyData);
-
- rec.setKeySize(Integer.valueOf(rsaPublicKey.getKeySize()));
- } catch (InvalidKeyException e) {
- request.setExtData(IRequest.RESULT, Integer.valueOf(11));
- CMS.debug("NetkeyKeygenService: failed:InvalidKeyException");
- return false;
+ if (rKeytype.equals("RSA")) {
+ try {
+ RSAPublicKey rsaPublicKey = new RSAPublicKey(publicKeyData);
+
+ rec.setKeySize(Integer.valueOf(rsaPublicKey.getKeySize()));
+ } catch (InvalidKeyException e) {
+ request.setExtData(IRequest.RESULT, Integer.valueOf(11));
+ CMS.debug("NetkeyKeygenService: failed:InvalidKeyException");
+ return false;
+ }
+ } else if (rKeytype.equals("EC")) {
+ CMS.debug("NetkeyKeygenService: alg is EC");
+ String oidDescription = "UNDETERMINED";
+ // for KeyRecordParser
+ MetaInfo metaInfo = new MetaInfo();
+
+ try {
+ byte curve[] =
+ ASN1Util.getECCurveBytesByX509PublicKeyBytes(publicKeyData,
+ false /* without tag and size */);
+ if (curve.length != 0) {
+ oidDescription = ASN1Util.getOIDdescription(curve);
+ } else {
+ /* this is to be used by derdump */
+ byte curveTS[] =
+ ASN1Util.getECCurveBytesByX509PublicKeyBytes(publicKeyData,
+ true /* with tag and size */);
+ if (curveTS.length != 0) {
+ oidDescription = CMS.BtoA(curveTS);
+ }
+ }
+ } catch (Exception e) {
+ CMS.debug("NetkeyKeygenService: ASN1Util.getECCurveBytesByX509PublicKeyByte() throws exception: "+ e.toString());
+ CMS.debug("NetkeyKeygenService: exception allowed. continue");
+ }
+
+ metaInfo.set(KeyRecordParser.OUT_KEY_EC_CURVE,
+ oidDescription);
+
+ rec.set(IKeyRecord.ATTR_META_INFO, metaInfo);
+ // key size does not apply to EC;
+ rec.setKeySize(-1);
}
+
//??
IKeyRepository storage = mKRA.getKeyRepository();
BigInteger serialNo = storage.getNextSerialNumber();