summaryrefslogtreecommitdiffstats
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
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)
-rw-r--r--base/common/src/com/netscape/certsrv/request/IRequest.java2
-rw-r--r--base/common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java44
-rw-r--r--base/kra/src/com/netscape/kra/NetkeyKeygenService.java235
-rw-r--r--base/tps/src/channel/Secure_Channel.cpp110
-rw-r--r--base/tps/src/include/cms/CertEnroll.h10
-rw-r--r--base/tps/src/include/engine/RA.h14
-rw-r--r--base/tps/src/include/main/Buffer.h3
-rw-r--r--base/tps/src/include/processor/RA_Enroll_Processor.h68
-rw-r--r--base/tps/src/main/Buffer.cpp10
-rw-r--r--base/tps/src/main/ObjectSpec.cpp13
-rw-r--r--base/tps/src/processor/RA_Enroll_Processor.cpp314
11 files changed, 579 insertions, 244 deletions
diff --git a/base/common/src/com/netscape/certsrv/request/IRequest.java b/base/common/src/com/netscape/certsrv/request/IRequest.java
index 3459af602..6438205ab 100644
--- a/base/common/src/com/netscape/certsrv/request/IRequest.java
+++ b/base/common/src/com/netscape/certsrv/request/IRequest.java
@@ -150,6 +150,8 @@ public interface IRequest extends Serializable {
public final static String NETKEY_ATTR_ENC_PRIVKEY_FLAG = "encryptPrivKey";
public final static String NETKEY_ATTR_USER_CERT = "cert";
public final static String NETKEY_ATTR_KEY_SIZE = "keysize";
+ public final static String NETKEY_ATTR_KEY_TYPE = "keytype";
+ public final static String NETKEY_ATTR_KEY_EC_CURVE = "eckeycurve";
//Security Data request attributes
public static final String SECURITY_DATA_ENROLLMENT_REQUEST = "securityDataEnrollment";
diff --git a/base/common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java b/base/common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java
index 597b50741..d8a125994 100644
--- a/base/common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java
+++ b/base/common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java
@@ -24,6 +24,7 @@ import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import java.util.Hashtable;
import com.netscape.certsrv.apps.CMS;
import com.netscape.certsrv.authentication.IAuthSubsystem;
@@ -31,6 +32,7 @@ import com.netscape.certsrv.authentication.IAuthToken;
import com.netscape.certsrv.authority.IAuthority;
import com.netscape.certsrv.authorization.AuthzToken;
import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
import com.netscape.certsrv.base.IPrettyPrintFormat;
import com.netscape.certsrv.logging.ILogger;
import com.netscape.certsrv.request.IRequest;
@@ -61,6 +63,7 @@ public class GenerateKeyPairServlet extends CMSServlet {
IPrettyPrintFormat pp = CMS.getPrettyPrintFormat(":");
protected IAuthSubsystem mAuthSubsystem = null;
protected ILogger mLogger = CMS.getLogger();
+ private Hashtable supportedECCurves_ht = null;
/**
* Constructs GenerateKeyPair servlet.
@@ -73,6 +76,7 @@ public class GenerateKeyPairServlet extends CMSServlet {
public void init(ServletConfig config) throws ServletException {
super.init(config);
mConfig = config;
+ IConfigStore sconfig = CMS.getConfigStore();
String authority = config.getInitParameter(PROP_AUTHORITY);
if (authority != null)
@@ -80,6 +84,21 @@ public class GenerateKeyPairServlet extends CMSServlet {
CMS.getSubsystem(authority);
mAuthSubsystem = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
+ // supported EC cuves by the smart cards
+ String curveList = null;
+ try {
+ curveList = sconfig.getString("kra.keygen.curvelist",
+ "nistp256,nistp384,nistp521");
+ } catch (EBaseException e) {
+ curveList = "nistp256,nistp384,nistp521";
+ }
+
+ supportedECCurves_ht = new Hashtable();
+ String[] supportedECCurves = curveList.split(",");
+ for ( int i = 0; i < supportedECCurves.length; i++) {
+ supportedECCurves_ht.put(supportedECCurves[i], supportedECCurves[i]);
+ }
+
}
/**
@@ -119,6 +138,8 @@ public class GenerateKeyPairServlet extends CMSServlet {
String rdesKeyString = req.getParameter("drm_trans_desKey");
String rArchive = req.getParameter("archive");
String rKeysize = req.getParameter("keysize");
+ String rKeytype = req.getParameter("keytype");
+ String rKeycurve = req.getParameter("eckeycurve");
if ((rCUID == null) || (rCUID.equals(""))) {
CMS.debug("GenerateKeyPairServlet: processServerSideKeygen(): missing request parameter: CUID");
@@ -130,10 +151,29 @@ public class GenerateKeyPairServlet extends CMSServlet {
missingParam = true;
}
- if ((rKeysize == null) || (rKeysize.equals(""))) {
+ // keysize is for non-EC (EC uses keycurve)
+ if (!rKeytype.equals("EC") && ((rKeysize == null) || (rKeysize.equals("")))) {
rKeysize = "1024"; // default to 1024
}
+ // if not specified, default to RSA
+ if ((rKeytype == null) || (rKeytype.equals(""))) {
+ rKeytype = "RSA";
+ }
+ if (rKeytype.equals("EC")) {
+ if ((rKeycurve == null) || (rKeycurve.equals(""))) {
+ rKeycurve = "nistp256";
+ }
+ // is the specified curve supported?
+ boolean isSupportedCurve = supportedECCurves_ht.containsKey(rKeycurve);
+ if (isSupportedCurve == false) {
+ CMS.debug("GenerateKeyPairServlet: processServerSideKeygen(): unsupported curve:"+ rKeycurve);
+ missingParam = true;
+ } else {
+ CMS.debug("GenerateKeyPairServlet: processServerSideKeygen(): curve to be generated:"+ rKeycurve);
+ }
+ }
+
if ((rdesKeyString == null) ||
(rdesKeyString.equals(""))) {
CMS.debug("GenerateKeyPairServlet: processServerSideKeygen(): missing request parameter: DRM-transportKey-wrapped DES key");
@@ -154,6 +194,8 @@ public class GenerateKeyPairServlet extends CMSServlet {
thisreq.setExtData(IRequest.NETKEY_ATTR_DRMTRANS_DES_KEY, rdesKeyString);
thisreq.setExtData(IRequest.NETKEY_ATTR_ARCHIVE_FLAG, rArchive);
thisreq.setExtData(IRequest.NETKEY_ATTR_KEY_SIZE, rKeysize);
+ thisreq.setExtData(IRequest.NETKEY_ATTR_KEY_TYPE, rKeytype);
+ thisreq.setExtData(IRequest.NETKEY_ATTR_KEY_EC_CURVE, rKeycurve);
queue.processRequest(thisreq);
Integer result = thisreq.getExtDataInInteger(IRequest.RESULT);
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();
diff --git a/base/tps/src/channel/Secure_Channel.cpp b/base/tps/src/channel/Secure_Channel.cpp
index 50b24ae99..27dfaaebf 100644
--- a/base/tps/src/channel/Secure_Channel.cpp
+++ b/base/tps/src/channel/Secure_Channel.cpp
@@ -38,6 +38,7 @@
#include "apdu/Read_Object_APDU.h"
#include "apdu/Write_Object_APDU.h"
#include "apdu/Generate_Key_APDU.h"
+#include "apdu/Generate_Key_ECC_APDU.h"
#include "apdu/Put_Key_APDU.h"
#include "apdu/Delete_File_APDU.h"
#include "apdu/Load_File_APDU.h"
@@ -142,6 +143,7 @@ int Secure_Channel::ComputeAPDU(APDU *apdu)
}
}
+ RA::Debug(LL_PER_PDU,"Secure_Channel::ComputeAPDU","Completed apdu.");
rc = 1;
loser:
if( mac != NULL ) {
@@ -180,6 +182,8 @@ Buffer *Secure_Channel::ComputeAPDUMac(APDU *apdu)
apdu->SetMAC(*mac);
m_icv = *mac;
+ RA::DebugBuffer("Secure_Channel::ComputeAPDUMac ", "mac",
+ mac);
return mac;
} /* EncodeAPDUMac */
@@ -1340,6 +1344,8 @@ int Secure_Channel::StartEnrollment(BYTE p1, BYTE p2, Buffer *wrapped_challenge,
{
int rc = -1;
Generate_Key_APDU *generate_key_apdu = NULL;
+ Generate_Key_ECC_APDU *generate_key_ecc_apdu = NULL;
+
APDU_Response *response = NULL;
RA_Token_PDU_Request_Msg *token_pdu_request_msg = NULL;
RA_Token_PDU_Response_Msg *token_pdu_response_msg = NULL;
@@ -1348,9 +1354,19 @@ int Secure_Channel::StartEnrollment(BYTE p1, BYTE p2, Buffer *wrapped_challenge,
RA::Debug("Secure_Channel::GenerateKey",
"Secure_Channel::GenerateKey");
- generate_key_apdu = new Generate_Key_APDU(p1, p2, alg, keysize, option,
- alg, *wrapped_challenge, *key_check);
- rc = ComputeAPDU(generate_key_apdu);
+
+ bool isECC = RA::isAlgorithmECC(alg);
+
+ if (isECC) {
+ generate_key_ecc_apdu = new Generate_Key_ECC_APDU(p1, p2, alg, keysize, option,
+ alg, *wrapped_challenge, *key_check);
+ rc = ComputeAPDU(generate_key_ecc_apdu);
+ } else {
+ generate_key_apdu = new Generate_Key_APDU(p1, p2, alg, keysize, option,
+ alg, *wrapped_challenge, *key_check);
+ rc = ComputeAPDU(generate_key_apdu);
+ }
+
if (rc == -1)
goto loser;
@@ -1358,8 +1374,15 @@ int Secure_Channel::StartEnrollment(BYTE p1, BYTE p2, Buffer *wrapped_challenge,
mac = ComputeAPDUMac(generate_key_apdu);
generate_key_apdu->SetMAC(*mac);
*/
- token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
- generate_key_apdu);
+
+ if (generate_key_ecc_apdu != NULL ) {
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ generate_key_ecc_apdu);
+ } else {
+ token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
+ generate_key_apdu);
+ }
+
m_session->WriteMsg(token_pdu_request_msg);
RA::Debug("Secure_Channel::GenerateKey",
"Sent token_pdu_request_msg");
@@ -2177,9 +2200,9 @@ Buffer Secure_Channel::CreatePKCS11CertAttrsBuffer(TokenKeyType key_type, const
Buffer b(256); // allocate some space
b.resize(7); // this keeps the allocated space around
- RA::Debug("Secure_Channel::CreatePKCS11CertAttrs", "id=%s", id);
- RA::Debug("Secure_Channel::CreatePKCS11CertAttrs", "label=%s", label);
- RA::DebugBuffer("Secure_Channel::CreatePKCS11CertAttrs", "keyid", keyid);
+ RA::Debug("Secure_Channel::CreatePKCS11CertAttrsBuffer", "id=%s", id);
+ RA::Debug("Secure_Channel::CreatePKCS11CertAttrsBuffer", "label=%s", label);
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11CertAttrsBuffer", "keyid", keyid);
AppendAttribute(b, CKA_LABEL, strlen(label), (BYTE*)label);
// hash of pubk
AppendAttribute(b, CKA_ID, keyid->size(), (BYTE*)*keyid);
@@ -2301,6 +2324,7 @@ mine:
M 00020001010000000100010100000100
M 00040000000000000000000403000000
*/
+
Buffer Secure_Channel::CreatePKCS11PriKeyAttrsBuffer(TokenKeyType key_type, const char *id, const char *label, Buffer *keyid,
Buffer *modulus, const char *opType, const char *tokenType, const char *keyTypePrefix)
{
@@ -2383,6 +2407,39 @@ int Secure_Channel::CreatePKCS11PriKeyAttrs(TokenKeyType key_type, const char *i
} /* CreatePKCS11PriKeyAttrs */
+Buffer Secure_Channel::CreatePKCS11ECCPriKeyAttrsBuffer(TokenKeyType type, const char *id, const char *label, Buffer *keyid,
+ SECKEYECParams *ecParams, const char *opType, const char *tokenType, const char *keyTypePrefix)
+{
+
+ BYTE keytype[8] = { 3,0,0,0 };
+ BYTE p11class[4] = { 3,0,0,0 };
+
+ Buffer b(256); // allocate some space
+ b.resize(7); // this keeps the allocated space around
+
+ if (label != NULL)
+ RA::Debug("Secure_Channel::CreatePKCS11ECCPriKeyAttrsBuffer", "label=%s", label);
+ if (keyid != NULL)
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11ECCPriKeyAttrsBuffer", "keyid", keyid);
+ if (id != NULL)
+ RA::Debug("Secure_Channel::CreatePKCS11ECCPriKeyAttrsBuffer", "id=%s",id);
+
+ AppendAttribute(b,CKA_KEY_TYPE, 4, keytype);
+ AppendAttribute(b,CKA_CLASS, 4, p11class );
+ // hash of pubk
+ AppendAttribute(b,CKA_ID, keyid->size(), (BYTE*)*keyid);
+
+ AppendAttribute(b,CKA_EC_PARAMS, ecParams->len, ecParams->data);
+ AppendKeyCapabilities(b, opType, tokenType, keyTypePrefix, "private");
+
+ FinalizeBuffer(b, id);
+
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11ECCPriKeyAttrsBuffer", "buffer", &b);
+
+ return b;
+
+}
+
/*
Public Key: (k1)
CKA_PUBLIC_EXPONENT(0x0122)
@@ -2461,6 +2518,43 @@ Buffer Secure_Channel::CreatePKCS11PubKeyAttrsBuffer(TokenKeyType key_type, cons
return b;
} /* CreatePKCS11PubKeyAttrs */
+
+Buffer Secure_Channel::CreatePKCS11ECCPubKeyAttrsBuffer(TokenKeyType key_type, const char *id, const char *label, Buffer *keyid,
+ SECKEYECPublicKey *publicKey, SECKEYECParams *ecParams, const char *opType, const char *tokenType, const char *keyTypePrefix)
+{
+ BYTE p11class[4] = { 2,0,0,0 };
+ // BYTE ZERO[1] = { 0 };
+ // BYTE ONE[1] = { 1 };
+ // char configname[256];
+
+ BYTE keytype[4] = { 3,0,0,0 };
+ Buffer b(256); // allocate some space
+ b.resize(7); // this keeps the allocated space around
+
+ if (label != NULL)
+ RA::Debug("Secure_Channel::CreatePKCS11ECCPubAttrsBuffer", "label=%s", label);
+ if (keyid != NULL)
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11ECCPubAttrsBuffer", "keyid", keyid);
+
+ // XXX TUES
+ // hash of pubk
+ AppendAttribute(b,CKA_ID, keyid->size(), (BYTE*)*keyid);
+ AppendAttribute(b, CKA_CLASS, 4, p11class ); // type of object
+ AppendAttribute(b,CKA_KEY_TYPE, 4, keytype); // CKK_EC key type
+ AppendAttribute(b,CKA_EC_PARAMS, ecParams->len, (BYTE *) ecParams->data);
+ AppendAttribute(b, CKA_EC_POINT, publicKey->publicValue.len, (BYTE *) publicKey->publicValue.data);
+
+ AppendKeyCapabilities(b, opType, tokenType, keyTypePrefix, "public");
+
+ FinalizeBuffer(b, id);
+
+ RA::DebugBuffer("Secure_Channel::CreatePKCS11ECCPubAttrsBuffer", "buffer", &b);
+
+ return b;
+} /* CreatePKCS11ECCPubKeyAttrs */
+
+
+
int Secure_Channel::CreatePKCS11PubKeyAttrs(TokenKeyType key_type, const char *id, const char *label, Buffer *keyid,
Buffer *exponent, Buffer *modulus, const char *opType, const char *tokenType, const char *keyTypePrefix)
{
diff --git a/base/tps/src/include/cms/CertEnroll.h b/base/tps/src/include/cms/CertEnroll.h
index 442e28e8c..4f06961d5 100644
--- a/base/tps/src/include/cms/CertEnroll.h
+++ b/base/tps/src/include/cms/CertEnroll.h
@@ -55,8 +55,9 @@ class CertEnroll
TOKENDB_PUBLIC CertEnroll();
TOKENDB_PUBLIC ~CertEnroll();
+
SECKEYPublicKey *ParsePublicKeyBlob(unsigned char * /*blob*/,
- Buffer * /*challenge*/);
+ Buffer * /*challenge*/, bool isECC);
Buffer *EnrollCertificate(SECKEYPublicKey * /*pk_parsed*/,
const char *profileId,
const char * /*uid*/,
@@ -64,12 +65,15 @@ class CertEnroll
char *error_msg,
SECItem** encodedPublicKeyInfo = NULL);
ReturnStatus verifyProof(SECKEYPublicKey* /*pk*/, SECItem* /*siProof*/,
- unsigned short /*pkeyb_len*/, unsigned char* /*pkeyb*/,
- Buffer* /*challenge*/);
+ unsigned short /*pkeyb_len*/, unsigned char* /*pkeyb*/,
+ Buffer* /*challenge*/, bool /*isECC*/);
TOKENDB_PUBLIC Buffer *RenewCertificate(PRUint64 serialno, const char *connid, const char *profileId, char *error_msg);
TOKENDB_PUBLIC int RevokeCertificate(const char *reason, const char *serialno, const char *connid, char *&status);
TOKENDB_PUBLIC int UnrevokeCertificate(const char *serialno, const char *connid, char *&status);
PSHttpResponse * sendReqToCA(const char *servlet, const char *parameters, const char *connid);
Buffer * parseResponse(PSHttpResponse * /*resp*/);
+
+ SECKEYECParams * encode_ec_params(char *curve);
+
};
#endif /* CERTENROLL_H */
diff --git a/base/tps/src/include/engine/RA.h b/base/tps/src/include/engine/RA.h
index ea04aa4d5..3ec0143d8 100644
--- a/base/tps/src/include/engine/RA.h
+++ b/base/tps/src/include/engine/RA.h
@@ -80,6 +80,13 @@ enum RA_Log_Level {
LL_ALL_DATA_IN_PDU = 9
};
+enum RA_Algs {
+ ALG_RSA = 1,
+ ALG_RSA_CRT = 2,
+ ALG_DSA = 3,
+ ALG_EC_F2M = 4,
+ ALG_EC_FP = 5
+};
#ifdef XP_WIN32
#define TPS_PUBLIC __declspec(dllexport)
@@ -125,12 +132,12 @@ class RA
char** kek_kekSessionKey_s,
char **keycheck_s,
const char *connId);
- static void ServerSideKeyGen(RA_Session *session, const char* cuid,
+ static void ServerSideKeyGen(RA_Session *session, const char* cuid,
const char *userid, char* kekSessionKey_s,
- char **publickey_s,
+ char **publickey_s,
char **wrappedPrivateKey_s,
char **ivParam_s, const char *connId,
- bool archive, int keysize);
+ bool archive, int keysize, bool isECC);
static void RecoverKey(RA_Session *session, const char* cuid,
const char *userid, char* kekSessionKey_s,
char *cert_s, char **publickey_s,
@@ -368,6 +375,7 @@ class RA
static void CleanupPublishers();
static int Failover(HttpConnection *&conn, int len);
+ static bool isAlgorithmECC(BYTE algorithm);
TPS_PUBLIC static SECCertificateUsage getCertificateUsage(const char *certusage);
TPS_PUBLIC static bool verifySystemCertByNickname(const char *nickname, const char *certUsage);
TPS_PUBLIC static bool verifySystemCerts();
diff --git a/base/tps/src/include/main/Buffer.h b/base/tps/src/include/main/Buffer.h
index 4fa7af6df..e3f08925e 100644
--- a/base/tps/src/include/main/Buffer.h
+++ b/base/tps/src/include/main/Buffer.h
@@ -167,6 +167,9 @@ class Buffer {
*/
TPS_PUBLIC void replace(unsigned int i, const BYTE* cpy, unsigned int n);
+ TPS_PUBLIC unsigned char* getBuf();
+ TPS_PUBLIC unsigned int getLen();
+
/**
* returns a hex version of the buffer
*/
diff --git a/base/tps/src/include/processor/RA_Enroll_Processor.h b/base/tps/src/include/processor/RA_Enroll_Processor.h
index b78d33f36..373465064 100644
--- a/base/tps/src/include/processor/RA_Enroll_Processor.h
+++ b/base/tps/src/include/processor/RA_Enroll_Processor.h
@@ -50,40 +50,40 @@
class RA_Enroll_Processor : public RA_Processor
{
- public:
- TPS_PUBLIC RA_Enroll_Processor();
- TPS_PUBLIC ~RA_Enroll_Processor();
- public:
- int ParsePublicKeyBlob(unsigned char *blob,
- unsigned char *challenge,
- SECKEYPublicKey *pk);
- RA_Status DoEnrollment(AuthParams *login, RA_Session *session,
- CERTCertificate **certificates,
- char **origins,
- char **ktypes,
- int pkcs11obj,
- PKCS11Obj * pkcs_objx,
- NameValueSet *extensions,
- int index, int keyTypeNum,
- int start_progress,
- int end_progress,
- Secure_Channel *channel, Buffer *wrapped_challenge,
- const char *tokenType,
- const char *keyType,
- Buffer *key_check,
- Buffer *plaintext_challenge,
- const char *cuid,
- const char *msn,
- const char *khex,
- TokenKeyType key_type,
- const char *profileId,
- const char *userid,
- const char *cert_id,
- const char *publisher_id,
- const char *cert_attr_id,
- const char *pri_attr_id,
- const char *pub_attr_id,
- BYTE se_p1, BYTE se_p2, int keysize, const char *connid, const char *keyTypePrefix,char * applet_version);
+ public:
+ TPS_PUBLIC RA_Enroll_Processor();
+ TPS_PUBLIC ~RA_Enroll_Processor();
+ public:
+ int ParsePublicKeyBlob(unsigned char *blob,
+ unsigned char *challenge,
+ SECKEYPublicKey *pk);
+ RA_Status DoEnrollment(AuthParams *login, RA_Session *session,
+ CERTCertificate **certificates,
+ char **origins,
+ char **ktypes,
+ int pkcs11obj,
+ PKCS11Obj * pkcs_objx,
+ NameValueSet *extensions,
+ int index, int keyTypeNum,
+ int start_progress,
+ int end_progress,
+ Secure_Channel *channel, Buffer *wrapped_challenge,
+ const char *tokenType,
+ const char *keyType,
+ Buffer *key_check,
+ Buffer *plaintext_challenge,
+ const char *cuid,
+ const char *msn,
+ const char *khex,
+ TokenKeyType key_type,
+ const char *profileId,
+ const char *userid,
+ const char *cert_id,
+ const char *publisher_id,
+ const char *cert_attr_id,
+ const char *pri_attr_id,
+ const char *pub_attr_id,
+ BYTE se_p1, BYTE se_p2, BYTE algorithm, int keysize, const char *connid, const char *keyTypePrefix,char * applet_version);
bool DoRenewal(const char *connid,
const char *profileId,
diff --git a/base/tps/src/main/Buffer.cpp b/base/tps/src/main/Buffer.cpp
index 2a547feea..94311fc50 100644
--- a/base/tps/src/main/Buffer.cpp
+++ b/base/tps/src/main/Buffer.cpp
@@ -222,6 +222,16 @@ Buffer::string()
return s;
}
+TPS_PUBLIC unsigned char*
+Buffer::getBuf() {
+ return (unsigned char *) buf;
+}
+
+TPS_PUBLIC unsigned int
+Buffer::getLen() {
+ return len;
+}
+
TPS_PUBLIC char *
Buffer::toHex()
{
diff --git a/base/tps/src/main/ObjectSpec.cpp b/base/tps/src/main/ObjectSpec.cpp
index 2896a85f0..b339fcfa6 100644
--- a/base/tps/src/main/ObjectSpec.cpp
+++ b/base/tps/src/main/ObjectSpec.cpp
@@ -190,6 +190,7 @@ void ObjectSpec::ParseAttributes(char *objectID, ObjectSpec *ObjectSpec, Buffer
case CKA_KEY_TYPE:
type = DATATYPE_INTEGER;
data = b->substr(curpos+6, 4);
+ found = 1;
/* build by PKCS11 */
break;
case CKA_CLASS:
@@ -208,6 +209,18 @@ void ObjectSpec::ParseAttributes(char *objectID, ObjectSpec *ObjectSpec, Buffer
data = b->substr(curpos+6, 4);
/* build by PKCS11 */
break;
+
+ case CKA_EC_PARAMS:
+ type = DATATYPE_STRING;
+ data = b->substr(curpos+6, attribute_size);
+ found = 1;
+ break;
+
+ case CKA_EC_POINT:
+ type = DATATYPE_STRING;
+ data = b->substr(curpos+6, attribute_size);
+ found = 1;
+ break;
default:
RA::Debug("ObjectSpec::ParseKeyBlob",
"skipped attribute_id = %lx",
diff --git a/base/tps/src/processor/RA_Enroll_Processor.cpp b/base/tps/src/processor/RA_Enroll_Processor.cpp
index ba751646e..874720685 100644
--- a/base/tps/src/processor/RA_Enroll_Processor.cpp
+++ b/base/tps/src/processor/RA_Enroll_Processor.cpp
@@ -184,7 +184,7 @@ RA_Status RA_Enroll_Processor::DoEnrollment(AuthParams *login, RA_Session *sessi
const char *cert_attr_id,
const char *pri_attr_id,
const char *pub_attr_id,
- BYTE se_p1, BYTE se_p2, int keysize, const char *connid, const char *keyTypePrefix,char * applet_version)
+ BYTE se_p1, BYTE se_p2, BYTE algorithm, int keysize, const char *connid, const char *keyTypePrefix,char * applet_version)
{
RA_Status status = STATUS_NO_ERROR;
int rc = -1;
@@ -231,6 +231,9 @@ RA_Status RA_Enroll_Processor::DoEnrollment(AuthParams *login, RA_Session *sessi
RA::Debug(LL_PER_CONNECTION,FN,
"Start of keygen/certificate enrollment");
+ bool isECC = RA::isAlgorithmECC(algorithm);
+ SECKEYECParams *eccParams = NULL;
+
// get key version for audit logs
if (channel != NULL) {
if( keyVersion != NULL ) {
@@ -288,8 +291,8 @@ RA_Status RA_Enroll_Processor::DoEnrollment(AuthParams *login, RA_Session *sessi
(progress_block_size * 15/100) /* progress */,
"PROGRESS_KEY_GENERATION");
- if (key_type == KEY_TYPE_ENCRYPTION) {// do serverSide keygen?
-
+ if (key_type == KEY_TYPE_ENCRYPTION) {
+ // do serverSide keygen?
PR_snprintf((char *)configname, 256, "%s.serverKeygen.enable", keyTypePrefix);
RA::Debug(LL_PER_CONNECTION,FN,
"looking for config %s", configname);
@@ -300,57 +303,58 @@ RA_Status RA_Enroll_Processor::DoEnrollment(AuthParams *login, RA_Session *sessi
if (serverKeygen) {
RA::Debug(LL_PER_CONNECTION,FN,
- "Private key is to be generated on server");
+ "Private key is to be generated on server");
PR_snprintf((char *)configname, 256, "%s.serverKeygen.drm.conn", keyTypePrefix);
RA::Debug(LL_PER_CONNECTION,FN,
- "looking for config %s", configname);
+ "looking for config %s", configname);
drmconnid = RA::GetConfigStore()->GetConfigAsString(configname);
PR_snprintf((char *)configname, 256, "%s.serverKeygen.archive", keyTypePrefix);
bool archive = RA::GetConfigStore()->GetConfigAsBool(configname, true);
RA::Debug(LL_PER_CONNECTION,FN,
- "calling ServerSideKeyGen with userid =%s, archive=%s", userid, archive? "true":"false");
+ "calling ServerSideKeyGen with userid =%s, archive=%s", userid, archive? "true":"false");
RA::ServerSideKeyGen(session, cuid, userid,
channel->getDrmWrappedDESKey(), &pKey,
&wrappedPrivKey, &ivParam, drmconnid,
- archive, keysize);
+ archive, keysize, isECC);
if (pKey == NULL) {
- RA::Error(LL_PER_CONNECTION,FN,
- "Failed to generate key on server. Please check DRM.");
- RA::Debug(LL_PER_CONNECTION,FN,
- "ServerSideKeyGen called, pKey is NULL");
- status = STATUS_ERROR_MAC_ENROLL_PDU;
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Failed to generate key on server. Please check DRM.");
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "ServerSideKeyGen called, pKey is NULL");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
PR_snprintf(audit_msg, 512, "ServerSideKeyGen called, failed to generate key on server");
- goto loser;
- } else
- RA::Debug(LL_PER_CONNECTION,FN,
- "key value = %s", pKey);
+ goto loser;
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "key value = %s", pKey);
+ }
if (wrappedPrivKey == NULL) {
- RA::Debug(LL_PER_CONNECTION,FN,
- "ServerSideKeyGen called, wrappedPrivKey is NULL");
- status = STATUS_ERROR_MAC_ENROLL_PDU;
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "ServerSideKeyGen called, wrappedPrivKey is NULL");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
PR_snprintf(audit_msg, 512, "ServerSideKeyGen called, wrappedPrivKey is NULL");
- goto loser;
- } else
- RA::Debug(LL_PER_CONNECTION,FN,
- "wrappedPrivKey = %s", wrappedPrivKey);
+ goto loser;
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "wrappedPrivKey = %s", wrappedPrivKey);
+ }
if (ivParam == NULL) {
- RA::Debug(LL_PER_CONNECTION,FN,
- "ServerSideKeyGen called, ivParam is NULL");
- status = STATUS_ERROR_MAC_ENROLL_PDU;
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "ServerSideKeyGen called, ivParam is NULL");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
PR_snprintf(audit_msg, 512, "ServerSideKeyGen called, ivParam is NULL");
- goto loser;
+ goto loser;
} else
- RA::Debug(LL_PER_CONNECTION,FN,
- "ivParam = %s", ivParam);
+ RA::Debug(LL_PER_CONNECTION,FN, "ivParam = %s", ivParam);
/*
* the following code converts b64-encoded public key info into SECKEYPublicKey
@@ -359,39 +363,47 @@ RA_Status RA_Enroll_Processor::DoEnrollment(AuthParams *login, RA_Session *sessi
SECItem der;
CERTSubjectPublicKeyInfo* spki = NULL;
+ Buffer *decodePubKey = Util::URLDecode(pKey);
+ char *pKey_ascii = NULL;
+ if (decodePubKey != NULL) {
+ pKey_ascii =
+ BTOA_DataToAscii(decodePubKey->getBuf(), decodePubKey->size());
+
+ } else {
+ PR_snprintf(audit_msg, 512, "ServerSideKeyGen: failed to URL decode public key");
+ goto loser;
+ }
+
der.type = (SECItemType) 0; /* initialize it, since convertAsciiToItem does not set it */
- rv = ATOB_ConvertAsciiToItem (&der, pKey);
+ rv = ATOB_ConvertAsciiToItem (&der, pKey_ascii);
if (rv != SECSuccess){
- RA::Debug(LL_PER_CONNECTION,FN,
- "failed to convert b64 private key to binary");
- SECITEM_FreeItem(&der, PR_FALSE);
- status = STATUS_ERROR_MAC_ENROLL_PDU;
- PR_snprintf(audit_msg, 512, "ServerSideKeyGen: failed to convert b64 private key to binary");
- goto loser;
- }else {
- RA::Debug(LL_PER_CONNECTION,FN,
- "decoded private key as: secitem (len=%d)",der.len);
-
- spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&der);
-
- if (spki != NULL) {
- RA::Debug(LL_PER_CONNECTION,FN,
- "Successfully decoded DER SubjectPublicKeyInfo structure");
- pk_p = SECKEY_ExtractPublicKey(spki);
- if (pk_p != NULL)
- RA::Debug(LL_PER_CONNECTION,FN,
- "Successfully extracted public key from SPKI structure");
- else
- RA::Debug(LL_PER_CONNECTION,FN,
- "Failed to extract public key from SPKI");
- } else {
- RA::Debug(LL_PER_CONNECTION,FN,
- "Failed to decode SPKI structure");
- }
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "failed to convert b64 public key to binary");
+ SECITEM_FreeItem(&der, PR_FALSE);
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "ServerSideKeyGen: failed to convert b64 public key to binary");
+ goto loser;
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "decoded public key as: secitem (len=%d)",der.len);
+
+ spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&der);
+
+ if (spki != NULL) {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Successfully decoded DER SubjectPublicKeyInfo structure");
+ pk_p = SECKEY_ExtractPublicKey(spki);
+ if (pk_p != NULL)
+ RA::Debug(LL_PER_CONNECTION,FN, "Successfully extracted public key from SPKI structure");
+ else
+ RA::Debug(LL_PER_CONNECTION,FN, "Failed to extract public key from SPKI");
+ } else {
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Failed to decode SPKI structure");
+ }
- SECITEM_FreeItem(&der, PR_FALSE);
- SECKEY_DestroySubjectPublicKeyInfo(spki);
-
+ SECITEM_FreeItem(&der, PR_FALSE);
+ SECKEY_DestroySubjectPublicKeyInfo(spki);
}
} else { //generate keys on token
@@ -404,6 +416,11 @@ RA_Status RA_Enroll_Processor::DoEnrollment(AuthParams *login, RA_Session *sessi
if(key_check && key_check->size())
alg = 0x81;
+
+ if (isECC) {
+ alg = algorithm;
+ }
+
len = channel->StartEnrollment(
se_p1, se_p2,
wrapped_challenge,
@@ -412,7 +429,7 @@ RA_Status RA_Enroll_Processor::DoEnrollment(AuthParams *login, RA_Session *sessi
0x00 /* option */);
RA::Debug(LL_PER_CONNECTION,FN,
- "channel->StartEnrollment returned length of public key blob: len=%d", len);
+ "channel->StartEnrollment returned length of public key blob: len=%d", len);
StatusUpdate(session, extensions,
start_progress + (index * progress_block_size) +
@@ -460,6 +477,8 @@ RA_Status RA_Enroll_Processor::DoEnrollment(AuthParams *login, RA_Session *sessi
plaintext_challenge);
+ // We have received the public key blob for ECC
+
// send status update to the client
StatusUpdate(session, extensions,
start_progress + (index * progress_block_size) +
@@ -471,7 +490,7 @@ RA_Status RA_Enroll_Processor::DoEnrollment(AuthParams *login, RA_Session *sessi
pk_p = certEnroll->ParsePublicKeyBlob(
(unsigned char *)(BYTE *)*public_key /*blob*/,
- plaintext_challenge);
+ plaintext_challenge, isECC);
if (pk_p == NULL) {
RA::Error(LL_PER_CONNECTION,FN,
@@ -550,8 +569,10 @@ RA_Status RA_Enroll_Processor::DoEnrollment(AuthParams *login, RA_Session *sessi
goto loser;
}
- si_mod = pk_p->u.rsa.modulus;
- modulus = new Buffer((BYTE*) si_mod.data, si_mod.len);
+ if (!isECC) {
+ si_mod = pk_p->u.rsa.modulus;
+ modulus = new Buffer((BYTE*) si_mod.data, si_mod.len);
+ }
/*
* RFC 3279
@@ -569,14 +590,14 @@ RA_Status RA_Enroll_Processor::DoEnrollment(AuthParams *login, RA_Session *sessi
si_kid = PK11_MakeIDFromPubKey(&spkix->subjectPublicKey);
spkix->subjectPublicKey.len <<= 3;
-
keyid = new Buffer((BYTE*) si_kid->data, si_kid->len);
- si_exp = pk_p->u.rsa.publicExponent;
- exponent = new Buffer((BYTE*) si_exp.data, si_exp.len);
-
- RA::Debug(LL_PER_CONNECTION,FN,
- "Keyid, modulus and exponent have been extracted from public key");
+ if (!isECC) {
+ si_exp = pk_p->u.rsa.publicExponent;
+ exponent = new Buffer((BYTE*) si_exp.data, si_exp.len);
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Keyid, modulus and exponent have been extracted from public key");
+ }
SECKEY_DestroySubjectPublicKeyInfo(spkix);
@@ -788,67 +809,77 @@ RA_Status RA_Enroll_Processor::DoEnrollment(AuthParams *login, RA_Session *sessi
/* write certificate from CA to netkey */
if (pkcs11obj_enable) {
- ObjectSpec *objSpec =
- ObjectSpec::ParseFromTokenData(
- (cert_id[0] << 24) +
- (cert_id[1] << 16),
- cert);
- pkcs_objx->AddObjectSpec(objSpec);
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (cert_id[0] << 24) +
+ (cert_id[1] << 16),
+ cert);
+ pkcs_objx->AddObjectSpec(objSpec);
} else {
- RA::Debug(LL_PER_CONNECTION,FN,
- "About to create certificate object on token");
- rc = channel->CreateCertificate(cert_id, cert);
- if (rc == -1) {
- RA::Error(LL_PER_CONNECTION,FN,
- "Failed to create certificate object on token");
- status = STATUS_ERROR_MAC_ENROLL_PDU;
- PR_snprintf(audit_msg, 512, "Failed to create certificate object on token");
- goto loser;
- }
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "About to create certificate object on token");
+ rc = channel->CreateCertificate(cert_id, cert);
+ if (rc == -1) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "Failed to create certificate object on token");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
+ PR_snprintf(audit_msg, 512, "Failed to create certificate object on token");
+ goto loser;
+ }
}
// build label
PR_snprintf((char *)configname, 256, "%s.%s.keyGen.%s.label",
- OP_PREFIX, tokenType, keyType);
+ OP_PREFIX, tokenType, keyType);
RA::Debug(LL_PER_CONNECTION,FN,
- "label '%s'", configname);
+ "label '%s'", configname);
pattern = RA::GetConfigStore()->GetConfigAsString(configname);
label = MapPattern(&nv, (char *) pattern);
if (pkcs11obj_enable) {
- Buffer b = channel->CreatePKCS11CertAttrsBuffer(
- key_type, cert_attr_id, label, keyid);
- ObjectSpec *objSpec =
- ObjectSpec::ParseFromTokenData(
- (cert_attr_id[0] << 24) +
- (cert_attr_id[1] << 16),
- &b);
- pkcs_objx->AddObjectSpec(objSpec);
+ Buffer b = channel->CreatePKCS11CertAttrsBuffer(
+ key_type, cert_attr_id, label, keyid);
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (cert_attr_id[0] << 24) +
+ (cert_attr_id[1] << 16),
+ &b);
+ pkcs_objx->AddObjectSpec(objSpec);
} else {
- RA::Debug(LL_PER_CONNECTION,FN,
- "About to create PKCS#11 certificate Attributes");
- rc = channel->CreatePKCS11CertAttrs(key_type, cert_attr_id, label, keyid);
- if (rc == -1) {
- RA::Error(LL_PER_CONNECTION,FN,
- "PKCS11 Certificate attributes creation failed");
- status = STATUS_ERROR_MAC_ENROLL_PDU;
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "About to create PKCS#11 certificate Attributes");
+ rc = channel->CreatePKCS11CertAttrs(key_type, cert_attr_id, label, keyid);
+ if (rc == -1) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "PKCS11 Certificate attributes creation failed");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
PR_snprintf(audit_msg, 512, "PKCS11 Certificate attributes creation failed");
- goto loser;
- }
+ goto loser;
+ }
}
if (pkcs11obj_enable) {
- RA::Debug(LL_PER_CONNECTION,FN,
- "Create PKCS11 Private Key Attributes Buffer");
- Buffer b = channel->CreatePKCS11PriKeyAttrsBuffer(key_type,
- pri_attr_id, label, keyid, modulus, OP_PREFIX,
- tokenType, keyTypePrefix);
- ObjectSpec *objSpec =
- ObjectSpec::ParseFromTokenData(
- (pri_attr_id[0] << 24) +
- (pri_attr_id[1] << 16),
- &b);
- pkcs_objx->AddObjectSpec(objSpec);
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Create PKCS11 Private Key Attributes Buffer");
+
+ Buffer b;
+ if (!isECC) {
+ b = channel->CreatePKCS11PriKeyAttrsBuffer(key_type,
+ pri_attr_id, label, keyid, modulus, OP_PREFIX,
+ tokenType, keyTypePrefix);
+
+ } else { //isECC
+ eccParams = &pk_p->u.ec.DEREncodedParams;
+ b = channel->CreatePKCS11ECCPriKeyAttrsBuffer(key_type,
+ pri_attr_id, label, keyid, eccParams, OP_PREFIX,
+ tokenType, keyTypePrefix);
+ }
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (pri_attr_id[0] << 24) +
+ (pri_attr_id[1] << 16),
+ &b);
+ pkcs_objx->AddObjectSpec(objSpec);
} else {
RA::Debug(LL_PER_CONNECTION,FN,
"Create PKCS11 Private Key Attributes");
@@ -863,27 +894,34 @@ RA_Status RA_Enroll_Processor::DoEnrollment(AuthParams *login, RA_Session *sessi
}
if (pkcs11obj_enable) {
- Buffer b = channel->CreatePKCS11PubKeyAttrsBuffer(key_type,
- pub_attr_id, label, keyid,
- exponent, modulus, OP_PREFIX, tokenType, keyTypePrefix);
- ObjectSpec *objSpec =
- ObjectSpec::ParseFromTokenData(
- (pub_attr_id[0] << 24) +
- (pub_attr_id[1] << 16),
- &b);
- pkcs_objx->AddObjectSpec(objSpec);
+ Buffer b;
+ if (!isECC) {
+ b = channel->CreatePKCS11PubKeyAttrsBuffer(key_type,
+ pub_attr_id, label, keyid,
+ exponent, modulus, OP_PREFIX, tokenType, keyTypePrefix);
+ } else {
+ b = channel->CreatePKCS11ECCPubKeyAttrsBuffer(key_type,
+ pub_attr_id, label, keyid,&pk_p->u.ec, eccParams,
+ OP_PREFIX, tokenType, keyTypePrefix);
+ }
+ ObjectSpec *objSpec =
+ ObjectSpec::ParseFromTokenData(
+ (pub_attr_id[0] << 24) +
+ (pub_attr_id[1] << 16),
+ &b);
+ pkcs_objx->AddObjectSpec(objSpec);
} else {
- RA::Debug(LL_PER_CONNECTION,FN,
- "Create PKCS11 Public Key Attributes");
- rc = channel->CreatePKCS11PubKeyAttrs(key_type, pub_attr_id, label, keyid,
+ RA::Debug(LL_PER_CONNECTION,FN,
+ "Create PKCS11 Public Key Attributes");
+ rc = channel->CreatePKCS11PubKeyAttrs(key_type, pub_attr_id, label, keyid,
exponent, modulus, OP_PREFIX, tokenType, keyTypePrefix);
- if (rc == -1) {
- RA::Error(LL_PER_CONNECTION,FN,
- "PKCS11 public key attributes creation failed");
- status = STATUS_ERROR_MAC_ENROLL_PDU;
+ if (rc == -1) {
+ RA::Error(LL_PER_CONNECTION,FN,
+ "PKCS11 public key attributes creation failed");
+ status = STATUS_ERROR_MAC_ENROLL_PDU;
PR_snprintf(audit_msg, 512, "PKCS11 public key attributes creation failed");
- goto loser;
- }
+ goto loser;
+ }
}
RA::Debug(LL_PER_CONNECTION,FN, "End of keygen/certificate enrollment");
@@ -983,10 +1021,13 @@ loser:
}
if (pk_p != NULL) {
if (serverKeygen) {
+ RA::Debug(LL_PER_CONNECTION,FN,"DoEnrollment about to call SECKEY_DestroyPublicKey on pk_p");
SECKEY_DestroyPublicKey(pk_p);
} else {
+ RA::Debug(LL_PER_CONNECTION,FN,"DoEnrollment about to call free on pk_p");
free(pk_p);
}
+
pk_p = NULL;
}
return status;
@@ -3063,6 +3104,11 @@ bool RA_Enroll_Processor::GenerateCertificate(AuthParams *login, int keyTypeNum,
PR_snprintf((char *)configname, 256, "%s.keySize", keyTypePrefix);
int keySize = RA::GetConfigStore()->GetConfigAsInt(configname, 1024);
+
+ PR_snprintf((char *)configname, 256, "%s.alg", keyTypePrefix);
+ //Default RSA_CRT=2
+ BYTE algorithm = (BYTE) RA::GetConfigStore()->GetConfigAsInt(configname, 2);
+
PR_snprintf((char *)configname, 256, "%s.publisherId", keyTypePrefix);
const char *publisherId = RA::GetConfigStore()->GetConfigAsString(configname, NULL);
@@ -3113,7 +3159,7 @@ bool RA_Enroll_Processor::GenerateCertificate(AuthParams *login, int keyTypeNum,
msn,
khex, (TokenKeyType)keyTypeEnum, profileId, userid, certId,publisherId, certAttrId, priKeyAttrId,
pubKeyAttrId, (keyUser << 4)+priKeyNumber,
- (keyUsage << 4)+pubKeyNumber, keySize, caconnid, keyTypePrefix,(char *)final_applet_version);
+ (keyUsage << 4)+pubKeyNumber, algorithm, keySize, caconnid, keyTypePrefix,(char *)final_applet_version);
if (o_status != STATUS_NO_ERROR) {
r = false;