#304 TMS ECC infrastructure (enrollment with client-side and server-side key generation, and key archival)
Closed Opened by cfu.

The TMS infrastructure was initially created with only RSA in mind.
This task specifically deals with adding initial ECC support for TMS.
It will support basic token enrollment both with client-side and server-side key generation, as well as key archival (minus key injection, which is task #235).


TPS ECC infrastructure
TPS-ECC.patch2

addressed review comments.
TPS-ECC.forReview2

RHCS8.1 Errata checkin

base]$ svn commit
Enter passphrase for key '/home/cfu/.ssh/id_rsa':
Sending base/common/src/com/netscape/certsrv/request/IRequest.java
Sending base/common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java
Sending base/kra/src/com/netscape/kra/NetkeyKeygenService.java
Sending base/tps/src/channel/Secure_Channel.cpp
Sending base/tps/src/cms/CertEnroll.cpp
Sending base/tps/src/engine/RA.cpp
Sending base/tps/src/include/channel/Secure_Channel.h
Sending base/tps/src/include/cms/CertEnroll.h
Sending base/tps/src/include/engine/RA.h
Sending base/tps/src/include/main/Buffer.h
Sending base/tps/src/include/processor/RA_Enroll_Processor.h
Sending base/tps/src/main/Buffer.cpp
Sending base/tps/src/main/ObjectSpec.cpp
Sending base/tps/src/processor/RA_Enroll_Processor.cpp
Transmitting file data ..............
Committed revision 2491.

RHCS82 checkin

base]$ svn commit
Enter passphrase for key '/home/cfu/.ssh/id_rsa':
Sending base/common/src/com/netscape/certsrv/request/IRequest.java
Sending base/common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java
Sending base/kra/src/com/netscape/kra/NetkeyKeygenService.java
Sending base/tps/src/channel/Secure_Channel.cpp
Sending base/tps/src/cms/CertEnroll.cpp
Sending base/tps/src/engine/RA.cpp
Sending base/tps/src/include/channel/Secure_Channel.h
Sending base/tps/src/include/cms/CertEnroll.h
Sending base/tps/src/include/engine/RA.h
Sending base/tps/src/include/main/Buffer.h
Sending base/tps/src/include/processor/RA_Enroll_Processor.h
Sending base/tps/src/main/Buffer.cpp
Sending base/tps/src/main/ObjectSpec.cpp
Sending base/tps/src/processor/RA_Enroll_Processor.cpp
Transmitting file data ..............
Committed revision 2492.

DOGTAG_9_BRANCH checkin

pki]$ git push
Enter passphrase for key '/home/cfu/.ssh/id_rsa':
Counting objects: 86, done.
Compressing objects: 100% (40/40), done.
Writing objects: 100% (44/44), 12.10 KiB, done.
Total 44 (delta 32), reused 0 (delta 0)
To ssh://git.fedorahosted.org/git/pki.git
809c5f8..4e7bb35 DOGTAG_9_BRANCH -> DOGTAG_9_BRANCH

dogtag10 checkin

pki]$ git push
Counting objects: 92, done.
Compressing objects: 100% (46/46), done.
Writing objects: 100% (50/50), 12.19 KiB, done.
Total 50 (delta 38), reused 0 (delta 0)
To ssh://cfu@git.fedorahosted.org/git/pki.git
8ed86a7..e689561 master -> master

example tpsclient enrollment config file
enroll.tps.ec

example ECC format config file for tpsclient
format.tps.ec.7994

example tokenname file (contains ECC token name, like certicom)
tokenname

CS.cfg sample for client-side key generation
CS.cfg.clientSideKeyGenEC

CS.cfg example for ECC server-side key generation
CS.cfg.serverSideKeyGenEC

CS.cfg example for ECC key recovery
CS.cfg.recoveryECC

(for reference) CS.cfg example for RSA server-side key generation
CS.cfg.serverSideKeyGenRSA

Metadata Update from @cfu:
- Issue assigned to cfu
- Issue set to the milestone: ECC Effort

Two initial attachments:
* TPS-ECC.patch2​ (72.8 KB) - added by cfu 4 years ago.
TPS ECC infrastructure
* TPS-ECC.forReview2​ (73.6 KB) - added by cfu 4 years ago.
addressed review comments.

Metadata Update from @mharmsen:
- Custom field feature adjusted to ''
- Custom field origin adjusted to Community
- Custom field proposedmilestone adjusted to ''
- Custom field proposedpriority adjusted to ''
- Custom field reviewer adjusted to ''
- Custom field version adjusted to ''
- Issue close_status updated to: None (was: Fixed)

TPS-ECC.patch2​

Index: common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java
2 ===================================================================
3 --- common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java (revision 2471)
4 +++ common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java (working copy)
5 @@ -74,6 +74,7 @@
6 CMS.getSubsystem(authority);
7
8 mAuthSubsystem = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
9 +
10 }
11
12 /
13 @@ -110,11 +111,23 @@
14
15 CMS.debug("processServerSideKeyGen begins:");
16
17 + // supported EC cuves by the smart cards
18 + String curveList = sconfig.getString("kra.keygen.curvelist"
19 + "nistp256,nistp384,nistp521");
20 + StringTokenizer st = new StringTokenizer(curveList, ",");
21 + int num = st.contTokens();
22 + String[] supportedECCurves = new String[num];
23 + for (int i=0; i< num; i++) {
24 + supportedECCurves[i] = st.nextToken();
25 + }
26 +
27 String rCUID = req.getParameter("CUID");
28 String rUserid = req.getParameter("userid");
29 String rdesKeyString = req.getParameter("drm_trans_desKey");
30 - String rArchive = req.getParameter("archive");
31 - String rKeysize = req.getParameter("keysize");
32 + String rArchive = req.getParameter("archive");
33 + String rKeysize = req.getParameter("keysize");
34 + String rKeytype = req.getParameter("keytype");
35 + String rKeycurve = req.getParameter("eckeycurve");
36
37 if ((rCUID == null) || (rCUID.equals(""))) {
38 CMS.debug("GenerateKeyPairServlet: processServerSideKeygen(): missing request parameter: CUID");
39 @@ -126,10 +139,35 @@
40 missingParam = true;
41 }
42
43 - if ((rKeysize == null) || (rKeysize.equals(""))) {
44 - rKeysize = "1024"; // default to 1024
45 - }
46 + // keysize is for non-EC (EC uses keycurve)
47 + if ((!rKeytype.equals("EC") && (rKeysize == null) || (rKeysize.equals(""))) {
48 + rKeysize = "1024"; // default to 1024
49 + }
50
51 + // if not specified, default to RSA
52 + if ((rKeytype == null) || (rKeytype.equals(""))) {
53 + rKeytype = "RSA";
54 + }
55 +
56 + if (rKeytype.equals("EC")) {
57 + if ((rKeycurve == null) || (rKeycurve.equals(""))) {
58 + rKeycurve = "nistp256";
59 + }
60 + // is the specified curve supported?
61 + boolean isSupportedCurve = false;
62 + for (int i=0; i80 if ((rArchive == null) || (rArchive.equals(""))) { 81 CMS.debug("GenerateKeyPairServlet: processServerSideKeygen(): missing key archival flag 'archive' ,default to true"); 82 - rArchive = "true"; 83 + rArchive = "true"; 84 } 85
86 String selectedToken = null; 87 @@ -150,17 +188,19 @@ 88 thisreq.setExtData(IRequest.NETKEY_ATTR_CUID, rCUID); 89 thisreq.setExtData(IRequest.NETKEY_ATTR_USERID, rUserid); 90 thisreq.setExtData(IRequest.NETKEY_ATTR_DRMTRANS_DES_KEY, rdesKeyString); 91 - thisreq.setExtData(IRequest.NETKEY_ATTR_ARCHIVE_FLAG, rArchive); 92 - thisreq.setExtData(IRequest.NETKEY_ATTR_KEY_SIZE, rKeysize); 93 + thisreq.setExtData(IRequest.NETKEY_ATTR_ARCHIVE_FLAG, rArchive); 94 + thisreq.setExtData(IRequest.NETKEY_ATTR_KEY_SIZE, rKeysize); 95 + thisreq.setExtData(IRequest.NETKEY_ATTR_KEY_TYPE, rKeytype); 96 + thisreq.setExtData(IRequest.NETKEY_ATTR_KEY_EC_CURVE, rKeycurve); 97
98 queue.processRequest( thisreq ); 99 Integer result = thisreq.getExtDataInInteger(IRequest.RESULT); 100 if (result != null) { 101 - // sighs! tps thinks 0 is good, and DRM thinks 1 is good 102 - if (result.intValue() == 1) 103 - status = "0"; 104 - else 105 - status = result.toString(); 106 + // sighs! tps thinks 0 is good, and DRM thinks 1 is good 107 + if (result.intValue() == 1) 108 + status = "0"; 109 + else 110 + status = result.toString(); 111 } else 112 status = "7"; 113
114 @@ -183,7 +223,7 @@ 115 publicKeyString = thisreq.getExtDataInString("public_key"); 116 wrappedPrivKeyString = thisreq.getExtDataInString("wrappedUserPrivate"); 117
118 - String ivString = thisreq.getExtDataInString("iv_s"); 119 + String ivString = thisreq.getExtDataInString("iv_s"); 120
121 /* 122 if (selectedToken == null) 123 @@ -194,12 +234,12 @@ 124 else { 125 StringBuffer sb = new StringBuffer(); 126 sb.append("status=0&"); 127 - sb.append("wrapped_priv_key="); 128 - sb.append(wrappedPrivKeyString); 129 - sb.append("&iv_param="); 130 - sb.append(ivString); 131 + sb.append("wrapped_priv_key="); 132 + sb.append(wrappedPrivKeyString); 133 + sb.append("&iv_param="); 134 + sb.append(ivString); 135 sb.append("&public_key="); 136 - sb.append(publicKeyString); 137 + sb.append(publicKeyString); 138 value = sb.toString(); 139
140 } 141 @@ -267,9 +307,9 @@ 142 } 143
144 // begin Netkey serverSideKeyGen and archival 145 - CMS.debug("GenerateKeyPairServlet: processServerSideKeyGen would be called"); 146 - processServerSideKeyGen(req, resp); 147 - return; 148 + CMS.debug("GenerateKeyPairServlet: processServerSideKeyGen would be called"); 149 + processServerSideKeyGen(req, resp); 150 + return; 151 // end Netkey functions 152
153 } 154 Index: common/src/com/netscape/certsrv/request/IRequest.java 155 =================================================================== 156 --- common/src/com/netscape/certsrv/request/IRequest.java (revision 2471) 157 +++ common/src/com/netscape/certsrv/request/IRequest.java (working copy) 158 @@ -153,6 +153,8 @@ 159 public final static String NETKEY_ATTR_ENC_PRIVKEY_FLAG ="encryptPrivKey"; 160 public final static String NETKEY_ATTR_USER_CERT = "cert"; 161 public final static String NETKEY_ATTR_KEY_SIZE = "keysize"; 162 + public final static String NETKEY_ATTR_KEY_TYPE = "keytype"; 163 + public final static String NETKEY_ATTR_KEY_EC_CURVE = "eckeycurve"; 164
165 // requestor type values. 166 public static final String REQUESTOR_EE = "EE"; 167 Index: tps/src/processor/RA_Enroll_Processor.cpp 168 =================================================================== 169 --- tps/src/processor/RA_Enroll_Processor.cpp (revision 2471) 170 +++ tps/src/processor/RA_Enroll_Processor.cpp (working copy) 171 @@ -184,7 +184,7 @@ 172 const char *cert_attr_id, 173 const char *pri_attr_id, 174 const char *pub_attr_id, 175 - BYTE se_p1, BYTE se_p2, int keysize, const char *connid, const char *keyTypePrefix,char * applet_version) 176 + BYTE se_p1, BYTE se_p2, BYTE algorithm, int keysize, const char *connid, const char *keyTypePrefix,char * applet_version) 177 { 178 RA_Status status = STATUS_NO_ERROR; 179 int rc = -1; 180 @@ -231,6 +231,9 @@ 181 RA::Debug(LL_PER_CONNECTION,FN, 182 "Start of keygen/certificate enrollment"); 183
184 + bool isECC = RA::isAlgorithmECC(algorithm); 185 + SECKEYECParams *eccParams = NULL; 186 + 187 // get key version for audit logs 188 if (channel != NULL) { 189 if( keyVersion != NULL ) { 190 @@ -288,8 +291,8 @@ 191 (progress_block_size * 15/100) /* progress */, 192 "PROGRESS_KEY_GENERATION"); 193
194 - if (key_type == KEY_TYPE_ENCRYPTION) {// do serverSide keygen? 195 -
196 + if (key_type == KEY_TYPE_ENCRYPTION) { 197 + // do serverSide keygen? 198 PR_snprintf((char *)configname, 256, "%s.serverKeygen.enable", keyTypePrefix); 199 RA::Debug(LL_PER_CONNECTION,FN, 200 "looking for config %s", configname); 201 @@ -300,57 +303,56 @@ 202
203 if (serverKeygen) { 204 RA::Debug(LL_PER_CONNECTION,FN, 205 - "Private key is to be generated on server"); 206 + "Private key is to be generated on server"); 207
208 PR_snprintf((char *)configname, 256, "%s.serverKeygen.drm.conn", keyTypePrefix); 209 RA::Debug(LL_PER_CONNECTION,FN, 210 - "looking for config %s", configname); 211 + "looking for config %s", configname); 212 drmconnid = RA::GetConfigStore()->GetConfigAsString(configname);
213
214 PR_snprintf((char )configname, 256, "%s.serverKeygen.archive", keyTypePrefix);
215 bool archive = RA::GetConfigStore()->GetConfigAsBool(configname, true);
216
217 RA::Debug(LL_PER_CONNECTION,FN,
218 - "calling ServerSideKeyGen with userid =%s, archive=%s", userid, archive? "true":"false");
219 + "calling ServerSideKeyGen with userid =%s, archive=%s", userid, archive? "true":"false");
220
221 RA::ServerSideKeyGen(session, cuid, userid,
222 channel->getDrmWrappedDESKey(), &pKey,
223 &wrappedPrivKey, &ivParam, drmconnid,
224 - archive, keysize);
225 + archive, keysize, isECC);
226
227 if (pKey == NULL) {
228 - RA::Error(LL_PER_CONNECTION,FN,
229 - "Failed to generate key on server. Please check DRM.");
230 - RA::Debug(LL_PER_CONNECTION,FN,
231 - "ServerSideKeyGen called, pKey is NULL");
232 - status = STATUS_ERROR_MAC_ENROLL_PDU;
233 + RA::Error(LL_PER_CONNECTION,FN,
234 + "Failed to generate key on server. Please check DRM.");
235 + RA::Debug(LL_PER_CONNECTION,FN,
236 + "ServerSideKeyGen called, pKey is NULL");
237 + status = STATUS_ERROR_MAC_ENROLL_PDU;
238
239 PR_snprintf(audit_msg, 512, "ServerSideKeyGen called, failed to generate key on server");
240 - goto loser;
241 + goto loser;
242 } else
243 - RA::Debug(LL_PER_CONNECTION,FN,
244 - "key value = %s", pKey);
245 + RA::Debug(LL_PER_CONNECTION,FN,
246 + "key value = %s", pKey);
247
248
249 if (wrappedPrivKey == NULL) {
250 - RA::Debug(LL_PER_CONNECTION,FN,
251 - "ServerSideKeyGen called, wrappedPrivKey is NULL");
252 - status = STATUS_ERROR_MAC_ENROLL_PDU;
253 + RA::Debug(LL_PER_CONNECTION,FN,
254 + "ServerSideKeyGen called, wrappedPrivKey is NULL");
255 + status = STATUS_ERROR_MAC_ENROLL_PDU;
256 PR_snprintf(audit_msg, 512, "ServerSideKeyGen called, wrappedPrivKey is NULL");
257 - goto loser;
258 + goto loser;
259 } else
260 - RA::Debug(LL_PER_CONNECTION,FN,
261 - "wrappedPrivKey = %s", wrappedPrivKey);
262 + RA::Debug(LL_PER_CONNECTION,FN,
263 + "wrappedPrivKey = %s", wrappedPrivKey);
264
265 if (ivParam == NULL) {
266 - RA::Debug(LL_PER_CONNECTION,FN,
267 - "ServerSideKeyGen called, ivParam is NULL");
268 - status = STATUS_ERROR_MAC_ENROLL_PDU;
269 + RA::Debug(LL_PER_CONNECTION,FN,
270 + "ServerSideKeyGen called, ivParam is NULL");
271 + status = STATUS_ERROR_MAC_ENROLL_PDU;
272 PR_snprintf(audit_msg, 512, "ServerSideKeyGen called, ivParam is NULL");
273 - goto loser;
274 + goto loser;
275 } else
276 - RA::Debug(LL_PER_CONNECTION,FN,
277 - "ivParam = %s", ivParam);
278 + RA::Debug(LL_PER_CONNECTION,FN, "ivParam = %s", ivParam);
279
280 /
281 * the following code converts b64-encoded public key info into SECKEYPublicKey
282 @@ -359,39 +361,40 @@
283 SECItem der;
284 CERTSubjectPublicKeyInfo
spki = NULL;
285
286 + Buffer decodePubKey = Util::URLDecode(pKey);
287 + char
pKey_ascii =
288 + BTOA_DataToAscii(decodePubKey->getBuf(), decodePubKey->getLen());
289 +
290 der.type = (SECItemType) 0; / initialize it, since convertAsciiToItem does not set it /
291 - rv = ATOB_ConvertAsciiToItem (&der, pKey);
292 + rv = ATOB_ConvertAsciiToItem (&der, pKey_ascii);
293 if (rv != SECSuccess){
294 - RA::Debug(LL_PER_CONNECTION,FN,
295 - "failed to convert b64 private key to binary");
296 - SECITEM_FreeItem(&der, PR_FALSE);
297 - status = STATUS_ERROR_MAC_ENROLL_PDU;
298 - PR_snprintf(audit_msg, 512, "ServerSideKeyGen: failed to convert b64 private key to binary");
299 - goto loser;
300 - }else {
301 - RA::Debug(LL_PER_CONNECTION,FN,
302 - "decoded private key as: secitem (len=%d)",der.len);
303 + RA::Debug(LL_PER_CONNECTION,FN,
304 + "failed to convert b64 private key to binary");
305 + SECITEM_FreeItem(&der, PR_FALSE);
306 + status = STATUS_ERROR_MAC_ENROLL_PDU;
307 + PR_snprintf(audit_msg, 512, "ServerSideKeyGen: failed to convert b64 private key to binary");
308 + goto loser;
309 + } else {
310 + RA::Debug(LL_PER_CONNECTION,FN,
311 + "decoded private key as: secitem (len=%d)",der.len);
312
313 - spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&der);
314 + spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&der);
315
316 - if (spki != NULL) {
317 - RA::Debug(LL_PER_CONNECTION,FN,
318 - "Successfully decoded DER SubjectPublicKeyInfo structure");
319 - pk_p = SECKEY_ExtractPublicKey(spki);
320 - if (pk_p != NULL)
321 - RA::Debug(LL_PER_CONNECTION,FN,
322 - "Successfully extracted public key from SPKI structure");
323 - else
324 - RA::Debug(LL_PER_CONNECTION,FN,
325 - "Failed to extract public key from SPKI");
326 - } else {
327 - RA::Debug(LL_PER_CONNECTION,FN,
328 - "Failed to decode SPKI structure");
329 - }
330 + if (spki != NULL) {
331 + RA::Debug(LL_PER_CONNECTION,FN,
332 + "Successfully decoded DER SubjectPublicKeyInfo structure");
333 + pk_p = SECKEY_ExtractPublicKey(spki);
334 + if (pk_p != NULL)
335 + RA::Debug(LL_PER_CONNECTION,FN, "Successfully extracted public key from SPKI structure");
336 + else
337 + RA::Debug(LL_PER_CONNECTION,FN, "Failed to extract public key from SPKI");
338 + } else {
339 + RA::Debug(LL_PER_CONNECTION,FN,
340 + "Failed to decode SPKI structure");
341 + }
342
343 - SECITEM_FreeItem(&der, PR_FALSE);
344 - SECKEY_DestroySubjectPublicKeyInfo(spki);
345 -
346 + SECITEM_FreeItem(&der, PR_FALSE);
347 + SECKEY_DestroySubjectPublicKeyInfo(spki);
348 }
349
350 } else { //generate keys on token
351 @@ -404,6 +407,12 @@
352 if(key_check && key_check->size())
353 alg = 0x81;
354
355 +
356 + if (isECC) {
357 + alg = algorithm;
358 + }
359 +
360 +
361 len = channel->StartEnrollment(
362 se_p1, se_p2,
363 wrapped_challenge,
364 @@ -460,6 +469,8 @@
365 plaintext_challenge);
366
367
368 + // We have received the public key blob for ECC
369 +
370 // send status update to the client
371 StatusUpdate(session, extensions,
372 start_progress + (index * progress_block_size) +
373 @@ -471,7 +482,7 @@
374
375 pk_p = certEnroll->ParsePublicKeyBlob(
376 (unsigned char )(BYTE )public_key /blob/,
377 - plaintext_challenge);
378 + plaintext_challenge, isECC);
379
380 if (pk_p == NULL) {
381 RA::Error(LL_PER_CONNECTION,FN,
382 @@ -550,8 +561,10 @@
383 goto loser;
384 }
385
386 - si_mod = pk_p->u.rsa.modulus;
387 - modulus = new Buffer((BYTE
) si_mod.data, si_mod.len);
388 + if (!isECC) {
389 + si_mod = pk_p->u.rsa.modulus;
390 + modulus = new Buffer((BYTE) si_mod.data, si_mod.len);
391 + }
392
393 /

394 * RFC 3279
395 @@ -569,15 +582,15 @@
396 si_kid = PK11_MakeIDFromPubKey(&spkix->subjectPublicKey);
397 spkix->subjectPublicKey.len <<= 3;
398
399 -
400 keyid = new Buffer((BYTE) si_kid->data, si_kid->len);
401
402 - si_exp = pk_p->u.rsa.publicExponent;
403 - exponent = new Buffer((BYTE
) si_exp.data, si_exp.len);
404 + if (!isECC) {
405 + si_exp = pk_p->u.rsa.publicExponent;
406 + exponent = new Buffer((BYTE) si_exp.data, si_exp.len);
407 + RA::Debug(LL_PER_CONNECTION,FN,
408 + "Keyid, modulus and exponent have been extracted from public key");
409 + }
410
411 - RA::Debug(LL_PER_CONNECTION,FN,
412 - "Keyid, modulus and exponent have been extracted from public key");
413 -
414 SECKEY_DestroySubjectPublicKeyInfo(spkix);
415
416 cert_string = (char
) cert->string();
417 @@ -788,67 +801,77 @@
418
419 / write certificate from CA to netkey /
420 if (pkcs11obj_enable) {
421 - ObjectSpec objSpec =
422 - ObjectSpec::ParseFromTokenData(
423 - (cert_id[0] << 24) +
424 - (cert_id[1] << 16),
425 - cert);
426 - pkcs_objx->AddObjectSpec(objSpec);
427 + ObjectSpec
objSpec =
428 + ObjectSpec::ParseFromTokenData(
429 + (cert_id[0] << 24) +
430 + (cert_id[1] << 16),
431 + cert);
432 + pkcs_objx->AddObjectSpec(objSpec);
433 } else {
434 - RA::Debug(LL_PER_CONNECTION,FN,
435 - "About to create certificate object on token");
436 - rc = channel->CreateCertificate(cert_id, cert);
437 - if (rc == -1) {
438 - RA::Error(LL_PER_CONNECTION,FN,
439 - "Failed to create certificate object on token");
440 - status = STATUS_ERROR_MAC_ENROLL_PDU;
441 - PR_snprintf(audit_msg, 512, "Failed to create certificate object on token");
442 - goto loser;
443 - }
444 + RA::Debug(LL_PER_CONNECTION,FN,
445 + "About to create certificate object on token");
446 + rc = channel->CreateCertificate(cert_id, cert);
447 + if (rc == -1) {
448 + RA::Error(LL_PER_CONNECTION,FN,
449 + "Failed to create certificate object on token");
450 + status = STATUS_ERROR_MAC_ENROLL_PDU;
451 + PR_snprintf(audit_msg, 512, "Failed to create certificate object on token");
452 + goto loser;
453 + }
454 }
455
456 // build label
457 PR_snprintf((char )configname, 256, "%s.%s.keyGen.%s.label",
458 - OP_PREFIX, tokenType, keyType);
459 + OP_PREFIX, tokenType, keyType);
460 RA::Debug(LL_PER_CONNECTION,FN,
461 - "label '%s'", configname);
462 + "label '%s'", configname);
463 pattern = RA::GetConfigStore()->GetConfigAsString(configname);
464 label = MapPattern(&nv, (char
) pattern);
465
466 if (pkcs11obj_enable) {
467 - Buffer b = channel->CreatePKCS11CertAttrsBuffer(
468 - key_type, cert_attr_id, label, keyid);
469 - ObjectSpec objSpec =
470 - ObjectSpec::ParseFromTokenData(
471 - (cert_attr_id[0] << 24) +
472 - (cert_attr_id[1] << 16),
473 - &b);
474 - pkcs_objx->AddObjectSpec(objSpec);
475 + Buffer b = channel->CreatePKCS11CertAttrsBuffer(
476 + key_type, cert_attr_id, label, keyid);
477 + ObjectSpec
objSpec =
478 + ObjectSpec::ParseFromTokenData(
479 + (cert_attr_id[0] << 24) +
480 + (cert_attr_id[1] << 16),
481 + &b);
482 + pkcs_objx->AddObjectSpec(objSpec);
483 } else {
484 - RA::Debug(LL_PER_CONNECTION,FN,
485 - "About to create PKCS#11 certificate Attributes");
486 - rc = channel->CreatePKCS11CertAttrs(key_type, cert_attr_id, label, keyid);
487 - if (rc == -1) {
488 - RA::Error(LL_PER_CONNECTION,FN,
489 - "PKCS11 Certificate attributes creation failed");
490 - status = STATUS_ERROR_MAC_ENROLL_PDU;
491 + RA::Debug(LL_PER_CONNECTION,FN,
492 + "About to create PKCS#11 certificate Attributes");
493 + rc = channel->CreatePKCS11CertAttrs(key_type, cert_attr_id, label, keyid);
494 + if (rc == -1) {
495 + RA::Error(LL_PER_CONNECTION,FN,
496 + "PKCS11 Certificate attributes creation failed");
497 + status = STATUS_ERROR_MAC_ENROLL_PDU;
498 PR_snprintf(audit_msg, 512, "PKCS11 Certificate attributes creation failed");
499 - goto loser;
500 - }
501 + goto loser;
502 + }
503 }
504
505 if (pkcs11obj_enable) {
506 - RA::Debug(LL_PER_CONNECTION,FN,
507 - "Create PKCS11 Private Key Attributes Buffer");
508 - Buffer b = channel->CreatePKCS11PriKeyAttrsBuffer(key_type,
509 - pri_attr_id, label, keyid, modulus, OP_PREFIX,
510 - tokenType, keyTypePrefix);
511 - ObjectSpec objSpec =
512 - ObjectSpec::ParseFromTokenData(
513 - (pri_attr_id[0] << 24) +
514 - (pri_attr_id[1] << 16),
515 - &b);
516 - pkcs_objx->AddObjectSpec(objSpec);
517 + RA::Debug(LL_PER_CONNECTION,FN,
518 + "Create PKCS11 Private Key Attributes Buffer");
519 +
520 + Buffer b;
521 + if (!isECC) {
522 + b = channel->CreatePKCS11PriKeyAttrsBuffer(key_type,
523 + pri_attr_id, label, keyid, modulus, OP_PREFIX,
524 + tokenType, keyTypePrefix);
525 +
526 + } else { //isECC
527 + eccParams = &pk_p->u.ec.DEREncodedParams;
528 + b = channel->CreatePKCS11ECCPriKeyAttrsBuffer(key_type,
529 + pri_attr_id, label, keyid, eccParams, OP_PREFIX,
530 + tokenType, keyTypePrefix);
531 + }
532 + ObjectSpec
objSpec =
533 + ObjectSpec::ParseFromTokenData(
534 + (pri_attr_id[0] << 24) +
535 + (pri_attr_id[1] << 16),
536 + &b);
537 + pkcs_objx->AddObjectSpec(objSpec);
538 } else {
539 RA::Debug(LL_PER_CONNECTION,FN,
540 "Create PKCS11 Private Key Attributes");
541 @@ -863,27 +886,34 @@
542 }
543
544 if (pkcs11obj_enable) {
545 - Buffer b = channel->CreatePKCS11PubKeyAttrsBuffer(key_type,
546 - pub_attr_id, label, keyid,
547 - exponent, modulus, OP_PREFIX, tokenType, keyTypePrefix);
548 - ObjectSpec objSpec =
549 - ObjectSpec::ParseFromTokenData(
550 - (pub_attr_id[0] << 24) +
551 - (pub_attr_id[1] << 16),
552 - &b);
553 - pkcs_objx->AddObjectSpec(objSpec);
554 + Buffer b;
555 + if (!isECC) {
556 + b = channel->CreatePKCS11PubKeyAttrsBuffer(key_type,
557 + pub_attr_id, label, keyid,
558 + exponent, modulus, OP_PREFIX, tokenType, keyTypePrefix);
559 + } else {
560 + b = channel->CreatePKCS11ECCPubKeyAttrsBuffer(key_type,
561 + pub_attr_id, label, keyid,&pk_p->u.ec, eccParams,
562 + OP_PREFIX, tokenType, keyTypePrefix);
563 + }
564 + ObjectSpec
objSpec =
565 + ObjectSpec::ParseFromTokenData(
566 + (pub_attr_id[0] << 24) +
567 + (pub_attr_id[1] << 16),
568 + &b);
569 + pkcs_objx->AddObjectSpec(objSpec);
570 } else {
571 - RA::Debug(LL_PER_CONNECTION,FN,
572 - "Create PKCS11 Public Key Attributes");
573 - rc = channel->CreatePKCS11PubKeyAttrs(key_type, pub_attr_id, label, keyid,
574 + RA::Debug(LL_PER_CONNECTION,FN,
575 + "Create PKCS11 Public Key Attributes");
576 + rc = channel->CreatePKCS11PubKeyAttrs(key_type, pub_attr_id, label, keyid,
577 exponent, modulus, OP_PREFIX, tokenType, keyTypePrefix);
578 - if (rc == -1) {
579 - RA::Error(LL_PER_CONNECTION,FN,
580 - "PKCS11 public key attributes creation failed");
581 - status = STATUS_ERROR_MAC_ENROLL_PDU;
582 + if (rc == -1) {
583 + RA::Error(LL_PER_CONNECTION,FN,
584 + "PKCS11 public key attributes creation failed");
585 + status = STATUS_ERROR_MAC_ENROLL_PDU;
586 PR_snprintf(audit_msg, 512, "PKCS11 public key attributes creation failed");
587 - goto loser;
588 - }
589 + goto loser;
590 + }
591 }
592 RA::Debug(LL_PER_CONNECTION,FN, "End of keygen/certificate enrollment");
593
594 @@ -982,11 +1012,22 @@
595 pretty_cuid = NULL;
596 }
597 if (pk_p != NULL) {
598 + // Handle ECC case
599 +/
600 + if (isECC && (eccParams != NULL)) {
601 + RA::Debug(LL_PER_CONNECTION,FN,"DoEnrollment about to free eccParams");
602 + SECITEM_FreeItem((SECItem
) eccParams, PR_TRUE);
603 + }
604 +/
605 +
606 if (serverKeygen) {
607 + RA::Debug(LL_PER_CONNECTION,FN,"DoEnrollment about to call SECKEY_DestroyPublicKey on pk_p");
608 SECKEY_DestroyPublicKey(pk_p);
609 } else {
610 + RA::Debug(LL_PER_CONNECTION,FN,"DoEnrollment about to call free on pk_p");
611 free(pk_p);
612 }
613 +
614 pk_p = NULL;
615 }
616 return status;
617 @@ -3055,6 +3096,11 @@
618 PR_snprintf((char
)configname, 256, "%s.keySize", keyTypePrefix);
619 int keySize = RA::GetConfigStore()->GetConfigAsInt(configname, 1024);
620
621 +
622 + PR_snprintf((char )configname, 256, "%s.alg", keyTypePrefix);
623 + //Default RSA_CRT=2
624 + BYTE algorithm = (BYTE) RA::GetConfigStore()->GetConfigAsInt(configname, 2);
625 +
626 PR_snprintf((char
)configname, 256, "%s.publisherId", keyTypePrefix);
627 const char publisherId = RA::GetConfigStore()->GetConfigAsString(configname, NULL);
628
629 @@ -3105,7 +3151,7 @@
630 msn,
631 khex, (TokenKeyType)keyTypeEnum, profileId, userid, certId,publisherId, certAttrId, priKeyAttrId,
632 pubKeyAttrId, (keyUser << 4)+priKeyNumber,
633 - (keyUsage << 4)+pubKeyNumber, keySize, caconnid, keyTypePrefix,(char
)final_applet_version);
634 + (keyUsage << 4)+pubKeyNumber, algorithm, keySize, caconnid, keyTypePrefix,(char )final_applet_version);
635
636 if (o_status != STATUS_NO_ERROR) {
637 r = false;
638 Index: tps/src/cms/CertEnroll.cpp
639 ===================================================================
640 --- tps/src/cms/CertEnroll.cpp (revision 2471)
641 +++ tps/src/cms/CertEnroll.cpp (working copy)
642 @@ -19,6 +19,7 @@
643 // --- END COPYRIGHT BLOCK ---
644
645 #include
646 +#include
647
648 #include "main/RA_Session.h"
649 #include "main/RA_Msg.h"
650 @@ -35,6 +36,7 @@
651 #include "base64.h"
652 #include "nssb64.h"
653 #include "prlock.h"
654 +#include "secoidt.h"
655
656 #include "main/Memory.h"
657
658 @@ -49,6 +51,131 @@
659 #define TOKENDB_PUBLIC
660 #endif /
!XP_WIN32 /
661
662 +//ECC curve information
663 +
664 +typedef struct curveNameTagPairStr {
665 + char
curveName;
666 + SECOidTag curveOidTag;
667 +} CurveNameTagPair;
668 +
669 +
670 +static CurveNameTagPair nameTagPair[] =
671 +{
672 + { "prime192v1", SEC_OID_ANSIX962_EC_PRIME192V1 },
673 + { "prime192v2", SEC_OID_ANSIX962_EC_PRIME192V2 },
674 + { "prime192v3", SEC_OID_ANSIX962_EC_PRIME192V3 },
675 + { "prime239v1", SEC_OID_ANSIX962_EC_PRIME239V1 },
676 + { "prime239v2", SEC_OID_ANSIX962_EC_PRIME239V2 },
677 + { "prime239v3", SEC_OID_ANSIX962_EC_PRIME239V3 },
678 + { "prime256v1", SEC_OID_ANSIX962_EC_PRIME256V1 },
679 +
680 + { "secp112r1", SEC_OID_SECG_EC_SECP112R1},
681 + { "secp112r2", SEC_OID_SECG_EC_SECP112R2},
682 + { "secp128r1", SEC_OID_SECG_EC_SECP128R1},
683 + { "secp128r2", SEC_OID_SECG_EC_SECP128R2},
684 + { "secp160k1", SEC_OID_SECG_EC_SECP160K1},
685 + { "secp160r1", SEC_OID_SECG_EC_SECP160R1},
686 + { "secp160r2", SEC_OID_SECG_EC_SECP160R2},
687 + { "secp192k1", SEC_OID_SECG_EC_SECP192K1},
688 + { "secp192r1", SEC_OID_ANSIX962_EC_PRIME192V1 },
689 + { "nistp192", SEC_OID_ANSIX962_EC_PRIME192V1 },
690 + { "secp224k1", SEC_OID_SECG_EC_SECP224K1},
691 + { "secp224r1", SEC_OID_SECG_EC_SECP224R1},
692 + { "nistp224", SEC_OID_SECG_EC_SECP224R1},
693 + { "secp256k1", SEC_OID_SECG_EC_SECP256K1},
694 + { "secp256r1", SEC_OID_ANSIX962_EC_PRIME256V1 },
695 + { "nistp256", SEC_OID_ANSIX962_EC_PRIME256V1 },
696 + { "secp384r1", SEC_OID_SECG_EC_SECP384R1},
697 + { "nistp384", SEC_OID_SECG_EC_SECP384R1},
698 + { "secp521r1", SEC_OID_SECG_EC_SECP521R1},
699 + { "nistp521", SEC_OID_SECG_EC_SECP521R1},
700 +
701 + { "c2pnb163v1", SEC_OID_ANSIX962_EC_C2PNB163V1 },
702 + { "c2pnb163v2", SEC_OID_ANSIX962_EC_C2PNB163V2 },
703 + { "c2pnb163v3", SEC_OID_ANSIX962_EC_C2PNB163V3 },
704 + { "c2pnb176v1", SEC_OID_ANSIX962_EC_C2PNB176V1 },
705 + { "c2tnb191v1", SEC_OID_ANSIX962_EC_C2TNB191V1 },
706 + { "c2tnb191v2", SEC_OID_ANSIX962_EC_C2TNB191V2 },
707 + { "c2tnb191v3", SEC_OID_ANSIX962_EC_C2TNB191V3 },
708 + { "c2onb191v4", SEC_OID_ANSIX962_EC_C2ONB191V4 },
709 + { "c2onb191v5", SEC_OID_ANSIX962_EC_C2ONB191V5 },
710 + { "c2pnb208w1", SEC_OID_ANSIX962_EC_C2PNB208W1 },
711 + { "c2tnb239v1", SEC_OID_ANSIX962_EC_C2TNB239V1 },
712 + { "c2tnb239v2", SEC_OID_ANSIX962_EC_C2TNB239V2 },
713 + { "c2tnb239v3", SEC_OID_ANSIX962_EC_C2TNB239V3 },
714 + { "c2onb239v4", SEC_OID_ANSIX962_EC_C2ONB239V4 },
715 + { "c2onb239v5", SEC_OID_ANSIX962_EC_C2ONB239V5 },
716 + { "c2pnb272w1", SEC_OID_ANSIX962_EC_C2PNB272W1 },
717 + { "c2pnb304w1", SEC_OID_ANSIX962_EC_C2PNB304W1 },
718 + { "c2tnb359v1", SEC_OID_ANSIX962_EC_C2TNB359V1 },
719 + { "c2pnb368w1", SEC_OID_ANSIX962_EC_C2PNB368W1 },
720 + { "c2tnb431r1", SEC_OID_ANSIX962_EC_C2TNB431R1 },
721 +
722 + { "sect113r1", SEC_OID_SECG_EC_SECT113R1},
723 + { "sect113r2", SEC_OID_SECG_EC_SECT113R2},
724 + { "sect131r1", SEC_OID_SECG_EC_SECT131R1},
725 + { "sect131r2", SEC_OID_SECG_EC_SECT131R2},
726 + { "sect163k1", SEC_OID_SECG_EC_SECT163K1},
727 + { "nistk163", SEC_OID_SECG_EC_SECT163K1},
728 + { "sect163r1", SEC_OID_SECG_EC_SECT163R1},
729 + { "sect163r2", SEC_OID_SECG_EC_SECT163R2},
730 + { "nistb163", SEC_OID_SECG_EC_SECT163R2},
731 + { "sect193r1", SEC_OID_SECG_EC_SECT193R1},
732 + { "sect193r2", SEC_OID_SECG_EC_SECT193R2},
733 + { "sect233k1", SEC_OID_SECG_EC_SECT233K1},
734 + { "nistk233", SEC_OID_SECG_EC_SECT233K1},
735 + { "sect233r1", SEC_OID_SECG_EC_SECT233R1},
736 + { "nistb233", SEC_OID_SECG_EC_SECT233R1},
737 + { "sect239k1", SEC_OID_SECG_EC_SECT239K1},
738 + { "sect283k1", SEC_OID_SECG_EC_SECT283K1},
739 + { "nistk283", SEC_OID_SECG_EC_SECT283K1},
740 + { "sect283r1", SEC_OID_SECG_EC_SECT283R1},
741 + { "nistb283", SEC_OID_SECG_EC_SECT283R1},
742 + { "sect409k1", SEC_OID_SECG_EC_SECT409K1},
743 + { "nistk409", SEC_OID_SECG_EC_SECT409K1},
744 + { "sect409r1", SEC_OID_SECG_EC_SECT409R1},
745 + { "nistb409", SEC_OID_SECG_EC_SECT409R1},
746 + { "sect571k1", SEC_OID_SECG_EC_SECT571K1},
747 + { "nistk571", SEC_OID_SECG_EC_SECT571K1},
748 + { "sect571r1", SEC_OID_SECG_EC_SECT571R1},
749 + { "nistb571", SEC_OID_SECG_EC_SECT571R1},
750 +
751 +};
752 +
753 +SECKEYECParams *
754 +CertEnroll::encode_ec_params(char curve)
755 +{
756 + SECKEYECParams
ecparams;
757 + SECOidData oidData = NULL;
758 + SECOidTag curveOidTag = SEC_OID_UNKNOWN; /
default /
759 + int i, numCurves;
760 +
761 + if (curve &&
curve) {
762 + numCurves = sizeof(nameTagPair)/sizeof(CurveNameTagPair);
763 + for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN));
764 + i++) {
765 + if (PL_strcmp(curve, nameTagPair[i].curveName) == 0)
766 + curveOidTag = nameTagPair[i].curveOidTag;
767 + }
768 + }
769 +
770 + if ((curveOidTag == SEC_OID_UNKNOWN) ||
771 + (oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) {
772 + return NULL;
773 + }
774 +
775 + ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));
776 +
777 + if (!ecparams)
778 + return NULL;
779 +
780 + ecparams->data[0] = SEC_ASN1_OBJECT_ID;
781 + ecparams->data[1] = oidData->oid.len;
782 + memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len);
783 +
784 + return ecparams;
785 +}
786 +
787 /*
788 * Constructs handle for Certificate Enrollment
789
/
790 @@ -328,8 +455,20 @@
791 * Short Exponent Length
792 *
793 * Byte[] Exponent
794 + *
795 + *
796 + * ECC KeyBlob Format (ECC Public Key)
797 + * ----------------------------------
798 + *
799 + * Byte Encoding (0 for plaintext)
800 *
801 - *
802 + * Byte Key Type (10 for ECC public)
803 + *
804 + * Short Key Length (256, 384, 521 high byte first)
805 + *
806 + * Byte[] Key (W)
807 + *
808 + *
809 * Signature Format (Proof)
810 * ---------------------------------------
811 *
812 @@ -369,7 +508,7 @@
813
/
814
815 SECKEYPublicKey
CertEnroll::ParsePublicKeyBlob(unsigned char blob,
816 - Buffer
challenge)
817 + Buffer challenge, bool isECC)
818 {
819 char configname[5000];
820 SECKEYPublicKey
pk = NULL;
821 @@ -404,7 +543,7 @@
822 pkeyb_len = (unsigned short) ((len0 << 8) | (len1 & 0xFF));
823
824 RA::Debug(LL_PER_PDU, "CertEnroll::ParsePublicKeyBlob",
825 - "pkeyb_len =%d",pkeyb_len);
826 + "pkeyb_len =%d isECC: %d",pkeyb_len, isECC);
827
828 if (pkeyb_len <= 0) {
829 RA::Error("CertEnroll::ParsePublicKeyBlob", "public key blob length = %d", pkeyb_len);
830 @@ -431,51 +570,112 @@
831
832 // convert pkeyb to pkey
833 // 1 byte encoding, 1 byte key type, 2 bytes key length, then the key
834 +
835 + // for ECC
836 + unsigned short ecc_pkey_len = 0;
837 + // ecc key blob
838 + unsigned char eccpb = NULL;
839 +
840 + // for RSA
841 + unsigned short mod_len = 0;
842 + unsigned short exp_len = 0;
843 + // public key mod blob
844 + unsigned char * modb = NULL;
845 + // public key exp blob
846 + unsigned char * expb = NULL;
847 +
848 unsigned short pkey_offset = 4;
849 - // now, convert lengths for modulus and exponent
850 len0 = pkeyb[pkey_offset];
851 len1 = pkeyb[pkey_offset + 1];
852 - unsigned short mod_len = (len0 << 8 | len1);
853
854 - len0 = pkeyb[pkey_offset + 2 + mod_len];
855 - len1 = pkeyb[pkey_offset + 2 + mod_len + 1];
856 - unsigned short exp_len = (len0 << 8 | len1);
857 + if (!isECC) {
858 + // now, convert lengths for modulus and exponent
859 + mod_len = (len0 << 8 | len1);
860
861 + len0 = pkeyb[pkey_offset + 2 + mod_len];
862 + len1 = pkeyb[pkey_offset + 2 + mod_len + 1];
863 + exp_len = (len0 << 8 | len1);
864
865 - // public key mod blob
866 - unsigned char * modb = &pkeyb[pkey_offset + 2];
867 + modb = &pkeyb[pkey_offset + 2];
868 + expb = &pkeyb[pkey_offset + 2 + mod_len + 2];
869
870 - // public key exp blob
871 - unsigned char * expb = &pkeyb[pkey_offset + 2 + mod_len + 2];
872 + } else {
873 + ecc_pkey_len = (len0 << 8 | len1);
874 + eccpb = &pkeyb[pkey_offset + 2];
875 + }
876
877 // construct SECItem
878 +
879 + // for RSA
880 SECItem siMod;
881 - siMod.type = (SECItemType) 0;
882 - siMod.data = (unsigned char
) modb;
883 - siMod.len = mod_len;
884 -
885 SECItem siExp;
886 - siExp.type = (SECItemType) 0;
887 - siExp.data = (unsigned char )expb;
888 - siExp.len = exp_len;
889 -
890 - // construct SECKEYRSAPublicKeyStr
891 SECKEYRSAPublicKeyStr rsa_pks;
892 - rsa_pks.modulus = siMod;
893 - rsa_pks.publicExponent = siExp;
894
895 - // construct SECKEYPublicKey
896 - // this is to be returned
897 + // for ECC
898 + SECItem eccValue;
899 + SECKEYECPublicKeyStr ecc_pks;
900 + SECKEYECParams
ecc_key_params = NULL;
901 +
902 pk = (SECKEYPublicKey ) malloc(sizeof(SECKEYPublicKey));
903 - pk->keyType = rsaKey;
904 - pk->pkcs11Slot = NULL;
905 - pk->pkcs11ID = CK_INVALID_HANDLE;
906 - pk->u.rsa = rsa_pks;
907
908 + assert(pk);
909 +
910 + if (!isECC) {
911 +
912 + siMod.type = (SECItemType) 0;
913 + siMod.data = (unsigned char
) modb;
914 + siMod.len = mod_len;
915 +
916 + siExp.type = (SECItemType) 0;
917 + siExp.data = (unsigned char )expb;
918 + siExp.len = exp_len;
919 +
920 + // construct SECKEYRSAPublicKeyStr
921 + rsa_pks.modulus = siMod;
922 + rsa_pks.publicExponent = siExp;
923 +
924 + pk->keyType = rsaKey;
925 + pk->pkcs11Slot = NULL;
926 + pk->pkcs11ID = CK_INVALID_HANDLE;
927 + pk->u.rsa = rsa_pks;
928 + } else {
929 + // ECC
930 + len0 = blob[pkeyb_len_offset +4];
931 + len1 = blob[pkeyb_len_offset +5];
932 + int keyCurveSize = (len0 << 8 | len1);
933 +
934 + RA::Debug(LL_PER_PDU, "CertEnroll::ParsePublicKeyBlob",
935 + "keyCurveSize =%d",keyCurveSize);
936 +
937 + char curve[56] = "";
938 + snprintf(curve, 56, "nistp%d",keyCurveSize );
939 +
940 + ecc_key_params = encode_ec_params(curve);
941 +
942 + if (ecc_key_params == NULL) {
943 + free(pk);
944 + pk = NULL;
945 + return NULL;
946 + }
947 +
948 + eccValue.type = (SECItemType) 0;
949 + eccValue.data = (unsigned char
) eccpb;
950 + eccValue.len = ecc_pkey_len;
951 +
952 + ecc_pks.size = keyCurveSize;
953 + ecc_pks.publicValue = eccValue;
954 + ecc_pks.DEREncodedParams = ecc_key_params;
955 +
956 + pk->keyType = ecKey;
957 + pk->pkcs11Slot = NULL;
958 + pk->pkcs11ID = CK_INVALID_HANDLE;
959 + pk->u.ec = ecc_pks;
960 + }
961 +
962 PR_snprintf((char
)configname, 256, "general.verifyProof");
963 int verifyProofEnable = RA::GetConfigStore()->GetConfigAsInt(configname, 0x1);
964 if (verifyProofEnable) {
965 - rs = verifyProof(pk, &siProof, pkeyb_len, pkeyb, challenge);
966 + rs = verifyProof(pk, &siProof, pkeyb_len, pkeyb, challenge, isECC);
967 if (rs.status == PR_FAILURE) {
968 RA::Error("CertEnroll::ParsePublicKeyBlob",
969 "verify proof failed");
970 @@ -487,7 +687,33 @@
971 return pk;
972 }
973
974 +/
975 + * for debugging tokens
976 + * -- list out all tokens and thier login status
977 +
/
978 +static SECStatus
979 +ListModules(void)
980 +{
981 + PK11SlotList list;
982 + PK11SlotListElement
le;
983
984 + / get them all! /
985 + list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_FALSE,NULL);
986 + if (list == NULL) return SECFailure;
987 +
988 + / look at each slot/
989 + for (le = list->head ; le; le = le->next) {
990 + RA::Debug( LL_PER_PDU, "CertEnroll::ListModules",
991 + " slot: %s\n, loggedIn? %d, token: %s\n", PK11_GetSlotName(le->slot),
992 + (PK11_IsLoggedIn(le->slot, NULL) == PR_TRUE)? 1:0,
993 + PK11_GetTokenName(le->slot));
994 + }
995 + PK11_FreeSlotList(list);
996 +
997 + return SECSuccess;
998 +}
999 +
1000 +
1001 /

1002 * verify the proof.
1003 * @param pk the public key from the input blob
1004 @@ -502,18 +728,24 @@
1005 /
1006 ReturnStatus CertEnroll::verifyProof(SECKEYPublicKey
pk, SECItem siProof,
1007 unsigned short pkeyb_len, unsigned char
pkeyb,
1008 - Buffer challenge) {
1009 + Buffer
challenge, bool isECC) {
1010
1011 ReturnStatus rs;
1012 VFYContext * vc = NULL;
1013 rs.statusNum = ::VRFY_SUCCESS;
1014 rs.status = PR_SUCCESS;
1015
1016 + // ListModules();
1017 +
1018 // verify proof (signature)
1019 RA::Debug(LL_PER_PDU, "CertEnroll::verifyProof",
1020 "verify proof begins");
1021
1022 - vc = VFY_CreateContext(pk, siProof, SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE, NULL);
1023 + if(isECC) {
1024 + vc = VFY_CreateContext(pk, siProof, SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE , NULL);
1025 + } else {
1026 + vc = VFY_CreateContext(pk, siProof, SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE, NULL);
1027 + }
1028
1029 if (vc == NULL) {
1030 RA::Error("CertEnroll::verifyProof",
1031 @@ -530,14 +762,15 @@
1032 int i =0;
1033 for (i = 0; i<pkeyb_len; i++) {
1034 proof[i] = pkeyb[i];
1035 + RA::Debug(LL_PER_PDU,"CertEnroll::VerifyProof", "proof[%d]=%x", i, proof[i]);
1036 }
1037 - // RA::DebugBuffer("CertEnroll::VerifyProof","VerifyProof:: challenge =", challenge);
1038 + RA::DebugBuffer("CertEnroll::VerifyProof","VerifyProof:: challenge =", challenge);
1039 unsigned char chal = (unsigned char )(BYTE ) (challenge);
1040 unsigned int j = 0;
1041 for (j=0; j < challenge->size(); i++, j++) {
1042 proof[i] = chal[j];
1043 - // RA::Debug(LL_PER_PDU, "CertEnroll::VerifyProof","proof[%d]= %x",
1044 - // i, proof[i]);
1045 + RA::Debug(LL_PER_PDU, "CertEnroll::VerifyProof","proof[%d]= %x",
1046 + i, proof[i]);
1047 }
1048
1049 SECStatus vs = VFY_Begin(vc);
1050 @@ -547,7 +780,7 @@
1051 vs = VFY_End(vc);
1052 if (vs == SECFailure) {
1053 RA::Error("CertEnroll::verifyProof",
1054 - "VFY_End() failed pkeyb_len=%d challenge_size=%d", pkeyb_len, challenge->size());
1055 + "VFY_End() failed pkeyb_len=%d challenge_size=%d error=%d", pkeyb_len, challenge->size(),PR_GetError());
1056 rs.statusNum = ::VFY_UPDATE_FAILURE;
1057 rs.status = PR_FAILURE;
1058 }
1059 Index: tps/src/include/processor/RA_Enroll_Processor.h
1060 ===================================================================
1061 --- tps/src/include/processor/RA_Enroll_Processor.h (revision 2471)
1062 +++ tps/src/include/processor/RA_Enroll_Processor.h (working copy)
1063 @@ -50,40 +50,40 @@
1064
1065 class RA_Enroll_Processor : public RA_Processor
1066 {
1067 - public:
1068 - TPS_PUBLIC RA_Enroll_Processor();
1069 - TPS_PUBLIC ~RA_Enroll_Processor();
1070 - public:
1071 - int ParsePublicKeyBlob(unsigned char blob,
1072 - unsigned char
challenge,
1073 - SECKEYPublicKey pk);
1074 - RA_Status DoEnrollment(AuthParams
login, RA_Session session,
1075 - CERTCertificate
certificates,
1076 - char
origins,
1077 - char
ktypes,
1078 - int pkcs11obj,
1079 - PKCS11Obj * pkcs_objx,
1080 - NameValueSet
extensions,
1081 - int index, int keyTypeNum,
1082 - int start_progress,
1083 - int end_progress,
1084 - Secure_Channel channel, Buffer wrapped_challenge,
1085 - const char tokenType,
1086 - const char
keyType,
1087 - Buffer key_check,
1088 - Buffer
plaintext_challenge,
1089 - const char cuid,
1090 - const char
msn,
1091 - const char khex,
1092 - TokenKeyType key_type,
1093 - const char
profileId,
1094 - const char userid,
1095 - const char
cert_id,
1096 - const char publisher_id,
1097 - const char
cert_attr_id,
1098 - const char pri_attr_id,
1099 - const char
pub_attr_id,
1100 - BYTE se_p1, BYTE se_p2, int keysize, const char connid, const char keyTypePrefix,char * applet_version);
1101 + public:
1102 + TPS_PUBLIC RA_Enroll_Processor();
1103 + TPS_PUBLIC ~RA_Enroll_Processor();
1104 + public:
1105 + int ParsePublicKeyBlob(unsigned char blob,
1106 + unsigned char
challenge,
1107 + SECKEYPublicKey pk);
1108 + RA_Status DoEnrollment(AuthParams
login, RA_Session session,
1109 + CERTCertificate
certificates,
1110 + char
origins,
1111 + char
ktypes,
1112 + int pkcs11obj,
1113 + PKCS11Obj * pkcs_objx,
1114 + NameValueSet
extensions,
1115 + int index, int keyTypeNum,
1116 + int start_progress,
1117 + int end_progress,
1118 + Secure_Channel channel, Buffer wrapped_challenge,
1119 + const char tokenType,
1120 + const char
keyType,
1121 + Buffer key_check,
1122 + Buffer
plaintext_challenge,
1123 + const char cuid,
1124 + const char
msn,
1125 + const char khex,
1126 + TokenKeyType key_type,
1127 + const char
profileId,
1128 + const char userid,
1129 + const char
cert_id,
1130 + const char publisher_id,
1131 + const char
cert_attr_id,
1132 + const char pri_attr_id,
1133 + const char
pub_attr_id,
1134 + BYTE se_p1, BYTE se_p2, BYTE algorithm, int keysize, const char connid, const char keyTypePrefix,char * applet_version);
1135
1136 bool DoRenewal(const char connid,
1137 const char
profileId,
1138 Index: tps/src/include/cms/CertEnroll.h
1139 ===================================================================
1140 --- tps/src/include/cms/CertEnroll.h (revision 2471)
1141 +++ tps/src/include/cms/CertEnroll.h (working copy)
1142 @@ -55,8 +55,9 @@
1143 TOKENDB_PUBLIC CertEnroll();
1144 TOKENDB_PUBLIC ~CertEnroll();
1145
1146 +
1147 SECKEYPublicKey ParsePublicKeyBlob(unsigned char * /blob/,
1148 - Buffer * /
challenge/);
1149 + Buffer * /
challenge/, bool isECC);
1150 Buffer
EnrollCertificate(SECKEYPublicKey * /pk_parsed/,
1151 const char profileId,
1152 const char * /
uid/,
1153 @@ -64,12 +65,15 @@
1154 char
error_msg,
1155 SECItem encodedPublicKeyInfo = NULL);
1156 ReturnStatus verifyProof(SECKEYPublicKey /pk/, SECItem /siProof/,
1157 - unsigned short /pkeyb_len/, unsigned char /pkeyb/,
1158 - Buffer
/challenge/);
1159 + unsigned short /pkeyb_len/, unsigned char /pkeyb/,
1160 + Buffer
/challenge/, bool /isECC/);
1161 TOKENDB_PUBLIC Buffer RenewCertificate(PRUint64 serialno, const char connid, const char profileId, char error_msg);
1162 TOKENDB_PUBLIC int RevokeCertificate(const char reason, const char serialno, const char connid, char &status);
1163 TOKENDB_PUBLIC int UnrevokeCertificate(const char serialno, const char connid, char &status);
1164 PSHttpResponse * sendReqToCA(const char
servlet, const char parameters, const char connid);
1165 Buffer * parseResponse(PSHttpResponse * /resp/);
1166 +
1167 + SECKEYECParams * encode_ec_params(char curve);
1168 +
1169 };
1170 #endif /
CERTENROLL_H /
1171 Index: tps/src/include/main/Buffer.h
1172 ===================================================================
1173 --- tps/src/include/main/Buffer.h (revision 2471)
1174 +++ tps/src/include/main/Buffer.h (working copy)
1175 @@ -167,6 +167,9 @@
1176
/
1177 TPS_PUBLIC void replace(unsigned int i, const BYTE cpy, unsigned int n);
1178
1179 + TPS_PUBLIC unsigned char
getBuf();
1180 + TPS_PUBLIC unsigned int getLen();
1181 +
1182 /

1183 * returns a hex version of the buffer
1184 /
1185 Index: tps/src/include/engine/RA.h
1186 ===================================================================
1187 --- tps/src/include/engine/RA.h (revision 2471)
1188 +++ tps/src/include/engine/RA.h (working copy)
1189 @@ -79,6 +79,13 @@
1190 LL_ALL_DATA_IN_PDU = 9
1191 };
1192
1193 +enum RA_Algs {
1194 + ALG_RSA = 1,
1195 + ALG_RSA_CRT = 2,
1196 + ALG_DSA = 3,
1197 + ALG_EC_F2M = 4,
1198 + ALG_EC_FP = 5
1199 +};
1200
1201 #ifdef XP_WIN32
1202 #define TPS_PUBLIC __declspec(dllexport)
1203 @@ -124,12 +131,12 @@
1204 char
kek_kekSessionKey_s,
1205 char
keycheck_s,
1206 const char
connId);
1207 - static void ServerSideKeyGen(RA_Session session, const char cuid,
1208 + static void ServerSideKeyGen(RA_Session session, const char cuid,
1209 const char userid, char kekSessionKey_s,
1210 - char publickey_s,
1211 + char
publickey_s,
1212 char wrappedPrivateKey_s,
1213 char
ivParam_s, const char connId,
1214 - bool archive, int keysize);
1215 + bool archive, int keysize, bool isECC);
1216 static void RecoverKey(RA_Session
session, const char cuid,
1217 const char
userid, char kekSessionKey_s,
1218 char
cert_s, char publickey_s,
1219 @@ -363,6 +370,7 @@
1220 static void CleanupPublishers();
1221 static int Failover(HttpConnection &conn, int len);
1222
1223 + static bool isAlgorithmECC(BYTE algorithm);
1224 TPS_PUBLIC static SECCertificateUsage getCertificateUsage(const char
certusage);
1225 TPS_PUBLIC static bool verifySystemCertByNickname(const char nickname, const char certUsage);
1226 TPS_PUBLIC static bool verifySystemCerts();
1227 Index: tps/src/include/channel/Secure_Channel.h
1228 ===================================================================
1229 --- tps/src/include/channel/Secure_Channel.h (revision 2471)
1230 +++ tps/src/include/channel/Secure_Channel.h (working copy)
1231 @@ -125,10 +125,18 @@
1232 int CreatePKCS11CertAttrs(TokenKeyType type, const char id, const char label, Buffer keyid);
1233 Buffer CreatePKCS11PriKeyAttrsBuffer(TokenKeyType type, const char
id, const char label, Buffer keyid,
1234 Buffer modulus, const char opType, const char tokenType, const char keyTypePrefix);
1235 +
1236 + Buffer CreatePKCS11ECCPriKeyAttrsBuffer(TokenKeyType type, const char id, const char label, Buffer keyid,
1237 + SECKEYECParams
ecParams, const char opType, const char tokenType, const char keyTypePrefix);
1238 +
1239 int CreatePKCS11PriKeyAttrs(TokenKeyType type, const char
id, const char label, Buffer keyid,
1240 Buffer modulus, const char opType, const char tokenType, const char keyTypePrefix);
1241 Buffer CreatePKCS11PubKeyAttrsBuffer(TokenKeyType type, const char id, const char label, Buffer keyid,
1242 Buffer
exponent, Buffer modulus, const char opType, const char tokenType, const char keyTypePrefix);
1243 +
1244 + Buffer CreatePKCS11ECCPubKeyAttrsBuffer(TokenKeyType key_type, const char id, const char label, Buffer keyid, SECKEYECPublicKey publicKey,
1245 + SECKEYECParams ecParams, const char opType, const char tokenType, const char keyTypePrefix);
1246 +
1247 int CreatePKCS11PubKeyAttrs(TokenKeyType type, const char id, const char label, Buffer keyid,
1248 Buffer
exponent, Buffer modulus, const char opType, const char tokenType, const char keyTypePrefix);
1249 APDU_Response SendTokenAPU(APDU apdu);
1250 Index: tps/src/main/Buffer.cpp
1251 ===================================================================
1252 --- tps/src/main/Buffer.cpp (revision 2471)
1253 +++ tps/src/main/Buffer.cpp (working copy)
1254 @@ -222,6 +222,16 @@
1255 return s;
1256 }
1257
1258 +TPS_PUBLIC unsigned char
1259 +Buffer::getBuf() {
1260 + return (unsigned char
) buf;
1261 +}
1262 +
1263 +TPS_PUBLIC unsigned int
1264 +Buffer::getLen() {
1265 + return len;
1266 +}
1267 +
1268 TPS_PUBLIC char *
1269 Buffer::toHex()
1270 {
1271 Index: tps/src/main/ObjectSpec.cpp
1272 ===================================================================
1273 --- tps/src/main/ObjectSpec.cpp (revision 2471)
1274 +++ tps/src/main/ObjectSpec.cpp (working copy)
1275 @@ -190,6 +190,7 @@
1276 case CKA_KEY_TYPE:
1277 type = DATATYPE_INTEGER;
1278 data = b->substr(curpos+6, 4);
1279 + found = 1;
1280 / build by PKCS11 /
1281 break;
1282 case CKA_CLASS:
1283 @@ -208,6 +209,18 @@
1284 data = b->substr(curpos+6, 4);
1285 / build by PKCS11 /
1286 break;
1287 +
1288 + case CKA_EC_PARAMS:
1289 + type = DATATYPE_STRING;
1290 + data = b->substr(curpos+6, attribute_size);
1291 + found = 1;
1292 + break;
1293 +
1294 + case CKA_EC_POINT:
1295 + type = DATATYPE_STRING;
1296 + data = b->substr(curpos+6, attribute_size);
1297 + found = 1;
1298 + break;
1299 default:
1300 RA::Debug("ObjectSpec::ParseKeyBlob",
1301 "skipped attribute_id = %lx",
1302 Index: tps/src/engine/RA.cpp
1303 ===================================================================
1304 --- tps/src/engine/RA.cpp (revision 2471)
1305 +++ tps/src/engine/RA.cpp (working copy)
1306 @@ -1287,7 +1287,7 @@
1307 char
publicKey_s,
1308 char wrappedPrivateKey_s,
1309 char
ivParam_s, const char connId,
1310 - bool archive, int keysize)
1311 + bool archive, int keysize, bool isECC)
1312 {
1313
1314 const char
FN="RA::ServerSideKeyGen";
1315 @@ -1357,8 +1357,26 @@
1316 RA::Debug(LL_PER_CONNECTION, FN,
1317 "wrappedDESKey_s=%s", wrappedDESKey_s);
1318
1319 - PR_snprintf((char )body, MAX_BODY_LEN,
1320 - "archive=%s&CUID=%s&userid=%s&keysize=%d&drm_trans_desKey=%s",archive?"true":"false",cuid, userid, keysize, wrappedDESKey_s);
1321 + if (isECC) {
1322 + char
eckeycurve = NULL;
1323 + if (keysize == 521) {
1324 + eckeycurve = "nistp521";
1325 + } else if (keysize == 384) {
1326 + eckeycurve = "nistp384";
1327 + } else if (keysize == 256) {
1328 + eckeycurve = "nistp256";
1329 + } else {
1330 + RA::Debug(LL_PER_CONNECTION, FN,
1331 + "unrecognized ECC keysize %d, setting to 256", keysize);
1332 + keysize = 256;
1333 + eckeycurve = "nistp256";
1334 + }
1335 + PR_snprintf((char )body, MAX_BODY_LEN,
1336 + "archive=%s&CUID=%s&userid=%s&keytype=EC&eckeycurve=%s&drm_trans_desKey=%s",archive?"true":"false",cuid, userid, eckeycurve, wrappedDESKey_s);
1337 + } else {
1338 + PR_snprintf((char
)body, MAX_BODY_LEN,
1339 + "archive=%s&CUID=%s&userid=%s&keysize=%d&keytype=RSA&drm_trans_desKey=%s",archive?"true":"false",cuid, userid, keysize, wrappedDESKey_s);
1340 + }
1341 RA::Debug(LL_PER_CONNECTION, FN,
1342 "sending to DRM: query=%s", body);
1343
1344 @@ -3612,3 +3630,15 @@
1345 return newKey;
1346 }
1347
1348 +bool RA::isAlgorithmECC(BYTE alg)
1349 +{
1350 + bool result = false;
1351 +
1352 + if (alg == ALG_EC_F2M || alg == ALG_EC_FP)
1353 + result = true;
1354 +
1355 + RA::Debug(LL_PER_SERVER, "RA::isAlgorithmECC", " alg: %d result: %d", alg, result);
1356 +
1357 + return result;
1358 +}
1359 +
1360 Index: tps/src/channel/Secure_Channel.cpp
1361 ===================================================================
1362 --- tps/src/channel/Secure_Channel.cpp (revision 2471)
1363 +++ tps/src/channel/Secure_Channel.cpp (working copy)
1364 @@ -38,6 +38,7 @@
1365 #include "apdu/Read_Object_APDU.h"
1366 #include "apdu/Write_Object_APDU.h"
1367 #include "apdu/Generate_Key_APDU.h"
1368 +#include "apdu/Generate_Key_ECC_APDU.h"
1369 #include "apdu/Put_Key_APDU.h"
1370 #include "apdu/Delete_File_APDU.h"
1371 #include "apdu/Load_File_APDU.h"
1372 @@ -142,6 +143,7 @@
1373 }
1374 }
1375
1376 + RA::Debug(LL_PER_PDU,"Secure_Channel::ComputeAPDU","Completed apdu.");
1377 rc = 1;
1378 loser:
1379 if( mac != NULL ) {
1380 @@ -171,8 +173,8 @@
1381 apdu->GetDataToMAC(data);
1382
1383 // developer debugging only - not for deployment
1384 - // RA::DebugBuffer("Secure_Channel::ComputeAPDUMac", "Data To MAC'ed",
1385 - // &data);
1386 + RA::DebugBuffer("Secure_Channel::ComputeAPDUMac", "Data To MAC'ed",
1387 + &data);
1388
1389 // Compute MAC will padd the data if it is
1390 // not in 8 byte multiples
1391 @@ -180,6 +182,8 @@
1392 apdu->SetMAC(mac);
1393 m_icv =
mac;
1394
1395 + RA::DebugBuffer("Secure_Channel::ComputeAPDUMac ", "mac",
1396 + mac);
1397 return mac;
1398 } / EncodeAPDUMac /
1399
1400 @@ -1340,6 +1344,8 @@
1401 {
1402 int rc = -1;
1403 Generate_Key_APDU generate_key_apdu = NULL;
1404 + Generate_Key_ECC_APDU
generate_key_ecc_apdu = NULL;
1405 +
1406 APDU_Response response = NULL;
1407 RA_Token_PDU_Request_Msg
token_pdu_request_msg = NULL;
1408 RA_Token_PDU_Response_Msg token_pdu_response_msg = NULL;
1409 @@ -1348,9 +1354,19 @@
1410
1411 RA::Debug("Secure_Channel::GenerateKey",
1412 "Secure_Channel::GenerateKey");
1413 - generate_key_apdu = new Generate_Key_APDU(p1, p2, alg, keysize, option,
1414 - alg,
wrapped_challenge, key_check);
1415 - rc = ComputeAPDU(generate_key_apdu);
1416 +
1417 + bool isECC = RA::isAlgorithmECC(alg);
1418 +
1419 + if (isECC) {
1420 + generate_key_ecc_apdu = new Generate_Key_ECC_APDU(p1, p2, alg, keysize, option,
1421 + alg,
wrapped_challenge, key_check);
1422 + rc = ComputeAPDU(generate_key_ecc_apdu);
1423 + } else {
1424 + generate_key_apdu = new Generate_Key_APDU(p1, p2, alg, keysize, option,
1425 + alg,
wrapped_challenge, key_check);
1426 + rc = ComputeAPDU(generate_key_apdu);
1427 + }
1428 +
1429 if (rc == -1)
1430 goto loser;
1431
1432 @@ -1358,8 +1374,15 @@
1433 mac = ComputeAPDUMac(generate_key_apdu);
1434 generate_key_apdu->SetMAC(
mac);
1435 /
1436 - token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
1437 - generate_key_apdu);
1438 +
1439 + if (generate_key_ecc_apdu != NULL ) {
1440 + token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
1441 + generate_key_ecc_apdu);
1442 + } else {
1443 + token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
1444 + generate_key_apdu);
1445 + }
1446 +
1447 m_session->WriteMsg(token_pdu_request_msg);
1448 RA::Debug("Secure_Channel::GenerateKey",
1449 "Sent token_pdu_request_msg");
1450 @@ -2177,9 +2200,9 @@
1451 Buffer b(256); // allocate some space
1452 b.resize(7); // this keeps the allocated space around
1453
1454 - RA::Debug("Secure_Channel::CreatePKCS11CertAttrs", "id=%s", id);
1455 - RA::Debug("Secure_Channel::CreatePKCS11CertAttrs", "label=%s", label);
1456 - RA::DebugBuffer("Secure_Channel::CreatePKCS11CertAttrs", "keyid", keyid);
1457 + RA::Debug("Secure_Channel::CreatePKCS11CertAttrsBuffer", "id=%s", id);
1458 + RA::Debug("Secure_Channel::CreatePKCS11CertAttrsBuffer", "label=%s", label);
1459 + RA::DebugBuffer("Secure_Channel::CreatePKCS11CertAttrsBuffer", "keyid", keyid);
1460 AppendAttribute(b, CKA_LABEL, strlen(label), (BYTE
)label);
1461 // hash of pubk
1462 AppendAttribute(b, CKA_ID, keyid->size(), (BYTE)keyid);
1463 @@ -2301,6 +2324,7 @@
1464 M 00020001010000000100010100000100
1465 M 00040000000000000000000403000000
1466 /
1467 +
1468 Buffer Secure_Channel::CreatePKCS11PriKeyAttrsBuffer(TokenKeyType key_type, const char
id, const char label, Buffer keyid,
1469 Buffer modulus, const char opType, const char tokenType, const char keyTypePrefix)
1470 {
1471 @@ -2383,6 +2407,39 @@
1472
1473 } / CreatePKCS11PriKeyAttrs /
1474
1475 +Buffer Secure_Channel::CreatePKCS11ECCPriKeyAttrsBuffer(TokenKeyType type, const char id, const char label, Buffer keyid,
1476 + SECKEYECParams
ecParams, const char opType, const char tokenType, const char keyTypePrefix)
1477 +{
1478 +
1479 + BYTE keytype[8] = { 3,0,0,0 };
1480 + BYTE p11class[4] = { 3,0,0,0 };
1481 +
1482 + Buffer b(256); // allocate some space
1483 + b.resize(7); // this keeps the allocated space around
1484 +
1485 + if (label != NULL)
1486 + RA::Debug("Secure_Channel::CreatePKCS11ECCPriKeyAttrsBuffer", "label=%s", label);
1487 + if (keyid != NULL)
1488 + RA::DebugBuffer("Secure_Channel::CreatePKCS11ECCPriKeyAttrsBuffer", "keyid", keyid);
1489 + if (id != NULL)
1490 + RA::Debug("Secure_Channel::CreatePKCS11ECCPriKeyAttrsBuffer", "id=%s",id);
1491 +
1492 + AppendAttribute(b,CKA_KEY_TYPE, 4, keytype);
1493 + AppendAttribute(b,CKA_CLASS, 4, p11class );
1494 + // hash of pubk
1495 + AppendAttribute(b,CKA_ID, keyid->size(), (BYTE
)keyid);
1496 +
1497 + AppendAttribute(b,CKA_EC_PARAMS, ecParams->len, ecParams->data);
1498 + AppendKeyCapabilities(b, opType, tokenType, keyTypePrefix, "private");
1499 +
1500 + FinalizeBuffer(b, id);
1501 +
1502 + RA::DebugBuffer("Secure_Channel::CreatePKCS11ECCPriKeyAttrsBuffer", "buffer", &b);
1503 +
1504 + return b;
1505 +
1506 +}
1507 +
1508 /

1509 Public Key: (k1)
1510 CKA_PUBLIC_EXPONENT(0x0122)
1511 @@ -2461,6 +2518,43 @@
1512 return b;
1513 } / CreatePKCS11PubKeyAttrs /
1514
1515 +
1516 +Buffer Secure_Channel::CreatePKCS11ECCPubKeyAttrsBuffer(TokenKeyType key_type, const char id, const char label, Buffer keyid,
1517 + SECKEYECPublicKey
publicKey, SECKEYECParams ecParams, const char opType, const char tokenType, const char keyTypePrefix)
1518 +{
1519 + BYTE p11class[4] = { 2,0,0,0 };
1520 + // BYTE ZERO[1] = { 0 };
1521 + // BYTE ONE[1] = { 1 };
1522 + // char configname[256];
1523 +
1524 + BYTE keytype[4] = { 3,0,0,0 };
1525 + Buffer b(256); // allocate some space
1526 + b.resize(7); // this keeps the allocated space around
1527 +
1528 + RA::Debug("Secure_Channel::CreatePKCS11ECCPubAttrsBuffer", "label=%s", label);
1529 + RA::DebugBuffer("Secure_Channel::CreatePKCS11ECCPubAttrsBuffer", "keyid", keyid);
1530 +
1531 + // XXX TUES
1532 + // hash of pubk
1533 + AppendAttribute(b,CKA_ID, keyid->size(), (BYTE)keyid);
1534 + AppendAttribute(b, CKA_CLASS, 4, p11class ); // type of object
1535 + AppendAttribute(b,CKA_KEY_TYPE, 4, keytype); // CKK_EC key type
1536 + AppendAttribute(b,CKA_EC_PARAMS, ecParams->len, (BYTE ) ecParams->data);
1537 + AppendAttribute(b, CKA_EC_POINT, publicKey->publicValue.len, (BYTE
) publicKey->publicValue.data);
1538 +
1539 + AppendKeyCapabilities(b, opType, tokenType, keyTypePrefix, "public");
1540 +
1541 +
1542 + FinalizeBuffer(b, id);
1543 +
1544 + RA::DebugBuffer("Secure_Channel::CreatePKCS11ECCPubAttrsBuffer", "buffer", &b);
1545 +
1546 + return b;
1547 +} / CreatePKCS11ECCPubKeyAttrs /
1548 +
1549 +
1550 +
1551 +
1552 int Secure_Channel::CreatePKCS11PubKeyAttrs(TokenKeyType key_type, const char id, const char label, Buffer keyid,
1553 Buffer
exponent, Buffer modulus, const char opType, const char tokenType, const char keyTypePrefix)
1554 {
1555 Index: kra/src/com/netscape/kra/NetkeyKeygenService.java
1556 ===================================================================
1557 --- kra/src/com/netscape/kra/NetkeyKeygenService.java (revision 2471)
1558 +++ kra/src/com/netscape/kra/NetkeyKeygenService.java (working copy)
1559 @@ -62,7 +62,10 @@
1560 import com.netscape.certsrv.authentication.;
1561 import com.netscape.certsrv.apps.
;
1562 import com.netscape.certsrv.apps.CMS;
1563 +import com.netscape.cmsutil.crypto.CryptoUtil;
1564 +import com.netscape.cms.servlet.key.KeyRecordParser;
1565
1566 +
1567 //for b64 encoding
1568 import org.mozilla.jss.util.Base64OutputStream;
1569 import java.io.ByteArrayOutputStream;
1570 @@ -146,7 +149,7 @@
1571 }
1572
1573 public KeyPair generateKeyPair(
1574 - KeyPairAlgorithm kpAlg, int keySize, PQGParams pqg)
1575 + KeyPairAlgorithm kpAlg, int keySize, String keyCurve, PQGParams pqg)
1576 throws NoSuchAlgorithmException, TokenException, InvalidAlgorithmParameterException,
1577 InvalidParameterException, PQGParamGenException {
1578
1579 @@ -165,20 +168,29 @@
1580 sensitive == true
1581 extractable == true
1582 /
1583 +
1584 KeyPairGenerator kpGen = token.getKeyPairGenerator(kpAlg);
1585 IConfigStore config = CMS.getConfigStore();
1586 IConfigStore kgConfig = config.getSubStore("kra.keygen");
1587 boolean tp = false;
1588 boolean sp = false;
1589 boolean ep = false;
1590 - if (kgConfig != null) {
1591 + if ((kgConfig != null) && (!kgConfig.equals(""))) {
1592 try {
1593 tp = kgConfig.getBoolean("temporaryPairs", false);
1594 sp = kgConfig.getBoolean("sensitivePairs", false);
1595 ep = kgConfig.getBoolean("extractablePairs", false);
1596 // by default, let nethsm work
1597 + CMS.debug("NetkeyKeygenService: found config store: kra.keygen");
1598 + // by default, let nethsm work
1599 if ((tp == false) && (sp == false) && (ep == false)) {
1600 tp = true;
1601 + if (kpAlg == KeyPairAlgorithm.EC) {
1602 + // set to what works for nethsm
1603 + tp = true;
1604 + sp = false;
1605 + ep = true;
1606 + }
1607 }
1608 } catch (Exception e) {
1609 CMS.debug("NetkeyKeygenService: kgConfig.getBoolean failed");
1610 @@ -189,69 +201,109 @@
1611 // by default, let nethsm work
1612 CMS.debug("NetkeyKeygenService: cannot find config store: kra.keygen, assume temporaryPairs==true");
1613 tp = true;
1614 + if (kpAlg == KeyPairAlgorithm.EC) {
1615 + // set to what works for nethsm
1616 + tp = true;
1617 + sp = false;
1618 + ep = true;
1619 + }
1620 }
1621 - /
only specified to "true" will it be set /
1622 - if (tp == true) {
1623 - CMS.debug("NetkeyKeygenService: setting temporaryPairs to true");
1624 - kpGen.temporaryPairs(true);
1625 - }
1626 - if (sp == true) {
1627 - CMS.debug("NetkeyKeygenService: setting sensitivePairs to true");
1628 - kpGen.sensitivePairs(true);
1629 - }
1630 - if (ep == true) {
1631 - CMS.debug("NetkeyKeygenService: setting extractablePairs to true");
1632 - kpGen.extractablePairs(true);
1633 - }
1634 +
1635 + if (kpAlg == KeyPairAlgorithm.EC) {
1636 +
1637 + boolean isECDHE = false;
1638 + KeyPair pair = null;
1639 +
1640 + // used with isECDHE == true
1641 + org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage usages_mask_ECDSA[] = {
1642 + org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.DERIVE
1643 + };
1644 +
1645 + // used with isECDHE == false
1646 + org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage usages_mask_ECDH[] = {
1647 + org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN,
1648 + org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN_RECOVER
1649 + };
1650 +
1651 + try {
1652 + pair = CryptoUtil.generateECCKeyPair(token.getName(), /
ECC_curve default/ keyCurve ,
1653 + null,
1654 + (isECDHE==true) ? usages_mask_ECDSA: usages_mask_ECDH,
1655 + tp /
temporary/, sp? 1:0 /sensitive/, ep? 1:0 /extractable/);
1656 + CMS.debug("NetkeyKeygenService: after key pair generation" );
1657 + } catch (Exception e) {
1658 + CMS.debug("NetkeyKeygenService: key pair generation with exception:"+e.toString());
1659 + }
1660 + return pair;
1661 +
1662 + } else { // !EC
1663 + //only specified to "true" will it be set
1664 + if (tp == true) {
1665 + CMS.debug("NetkeyKeygenService: setting temporaryPairs to true");
1666 + kpGen.temporaryPairs(true);
1667 + }
1668 +
1669 + if (sp == true) {
1670 + CMS.debug("NetkeyKeygenService: setting sensitivePairs to true");
1671 + kpGen.sensitivePairs(true);
1672 + }
1673 +
1674 + if (ep == true) {
1675 + CMS.debug("NetkeyKeygenService: setting extractablePairs to true");
1676 + kpGen.extractablePairs(true);
1677 + }
1678
1679 - if (kpAlg == KeyPairAlgorithm.DSA) {
1680 - if (pqg == null) {
1681 + if (kpAlg == KeyPairAlgorithm.DSA) {
1682 + if (pqg == null) {
1683 + kpGen.initialize(keySize);
1684 + } else {
1685 + kpGen.initialize(pqg);
1686 + }
1687 + } else {
1688 kpGen.initialize(keySize);
1689 - } else {
1690 - kpGen.initialize(pqg);
1691 }
1692 - } else {
1693 - kpGen.initialize(keySize);
1694 - }
1695
1696 - if (pqg == null) {
1697 - KeyPair kp = null;
1698 - synchronized (new Object()) {
1699 - CMS.debug("NetkeyKeygenService: key pair generation begins");
1700 - kp = kpGen.genKeyPair();
1701 - CMS.debug("NetkeyKeygenService: key pair generation done");
1702 - mKRA.addEntropy(true);
1703 - }
1704 - return kp;
1705 - } else {
1706 - // DSA
1707 - KeyPair kp = null;
1708 + if (pqg == null) {
1709 + KeyPair kp = null;
1710 + synchronized (new Object()) {
1711 + CMS.debug("NetkeyKeygenService: key pair generation begins");
1712 + kp = kpGen.genKeyPair();
1713 + CMS.debug("NetkeyKeygenService: key pair generation done");
1714 + mKRA.addEntropy(true);
1715 + }
1716 + return kp;
1717 + } else {
1718 + // DSA
1719 + KeyPair kp = null;
1720
1721 - /
no DSA for now... netkey prototype
1722 - do {
1723 - // 602548 NSS bug - to overcome it, we use isBadDSAKeyPair
1724 - kp = kpGen.genKeyPair();
1725 + / no DSA for now... netkey prototype
1726 + do {
1727 + // 602548 NSS bug - to overcome it, we use isBadDSAKeyPair
1728 + kp = kpGen.genKeyPair();
1729 + }
1730 + while (isBadDSAKeyPair(kp));
1731 +
/
1732 + return kp;
1733 }
1734 - while (isBadDSAKeyPair(kp));
1735 - /
1736 - return kp;
1737 }
1738 }
1739
1740
1741
1742 public KeyPair generateKeyPair( String alg,
1743 - int keySize, PQGParams pqg) throws EBaseException {
1744 + int keySize, String keyCurve, PQGParams pqg) throws EBaseException {
1745
1746 KeyPairAlgorithm kpAlg = null;
1747
1748 if (alg.equals("RSA"))
1749 kpAlg = KeyPairAlgorithm.RSA;
1750 + else if (alg.equals("EC"))
1751 + kpAlg = KeyPairAlgorithm.EC;
1752 else
1753 kpAlg = KeyPairAlgorithm.DSA;
1754
1755 try {
1756 - KeyPair kp = generateKeyPair( kpAlg, keySize, pqg);
1757 + KeyPair kp = generateKeyPair( kpAlg, keySize, keyCurve, pqg);
1758
1759 return kp;
1760 } catch (InvalidParameterException e) {
1761 @@ -324,7 +376,7 @@
1762 byte[] wrapped_des_key;
1763
1764 byte iv[] = {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1};
1765 - String iv_s ="";
1766 + String iv_s ="";
1767 try {
1768 SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
1769 random.nextBytes(iv);
1770 @@ -332,34 +384,35 @@
1771 CMS.debug("NetkeyKeygenService.serviceRequest: "+ e.toString());
1772 }
1773
1774 - IVParameterSpec algParam = new IVParameterSpec(iv);
1775 + IVParameterSpec algParam = new IVParameterSpec(iv);
1776
1777 wrapped_des_key = null;
1778 - boolean archive = true;
1779 - PK11SymKey sk= null;
1780 - byte[] publicKeyData = null;;
1781 - String PubKey = "";
1782 + boolean archive = true;
1783 + PK11SymKey sk= null;
1784 + byte[] publicKeyData = null;;
1785 + String PubKey = "";
1786
1787 String id = request.getRequestId().toString();
1788 if (id != null) {
1789 auditArchiveID = id.trim();
1790 }
1791
1792 - String rArchive = request.getExtDataInString(IRequest.NETKEY_ATTR_ARCHIVE_FLAG);
1793 - if (rArchive.equals("true")) {
1794 - archive = true;
1795 + String rArchive = request.getExtDataInString(IRequest.NETKEY_ATTR_ARCHIVE_FLAG);
1796 + if (rArchive.equals("true")) {
1797 + archive = true;
1798 CMS.debug("NetkeyKeygenService: serviceRequest " +"archival requested for serverSideKeyGen");
1799 - } else {
1800 - archive = false;
1801 + } else {
1802 + archive = false;
1803 CMS.debug("NetkeyKeygenService: serviceRequest " +"archival not requested for serverSideKeyGen");
1804 }
1805
1806 String rCUID = request.getExtDataInString(IRequest.NETKEY_ATTR_CUID);
1807 String rUserid = request.getExtDataInString(IRequest.NETKEY_ATTR_USERID);
1808 - String rKeysize = request.getExtDataInString(IRequest.NETKEY_ATTR_KEY_SIZE);
1809 - int keysize = Integer.parseInt(rKeysize);
1810 - auditSubjectID=rCUID+":"+rUserid;
1811
1812 + String rKeytype = request.getExtDataInString(IRequest.NETKEY_ATTR_KEY_TYPE);
1813 +
1814 + auditSubjectID=rCUID+":"+rUserid;
1815 +
1816 SessionContext sContext = SessionContext.getContext();
1817 String agentId="";
1818 if (sContext != null) {
1819 @@ -381,15 +434,41 @@
1820 wrapped_des_key = com.netscape.cmsutil.util.Utils.SpecialDecode(rWrappedDesKeyString);
1821 CMS.debug("NetkeyKeygenService: wrapped_des_key specialDecoded");
1822
1823 - // get the token for generating user keys
1824 - CryptoToken keygenToken = mKRA.getKeygenToken();
1825 - if (keygenToken == null) {
1826 - CMS.debug("NetkeyKeygenService: failed getting keygenToken");
1827 - request.setExtData(IRequest.RESULT, Integer.valueOf(10));
1828 - return false;
1829 - } else
1830 - CMS.debug("NetkeyKeygenService: got keygenToken");
1831 +/

1832 + if ((rKeytype == null) || (rKeytype.equals(""))) {
1833 + rKeytype = "RSA";
1834 + }
1835 +/
1836
1837 + if ((rKeytype == null) || (rKeytype.equals(""))) {
1838 + CMS.debug("NetkeyKeygenService: serviceRequest: key type is null");
1839 + rKeytype = "RSA";
1840 + } else
1841 + CMS.debug("NetkeyKeygenService: serviceRequest: key type = "+ rKeytype);
1842 +
1843 + /
for EC, keysize is ignored, only key curve is used /
1844 + String rKeysize = "2048";
1845 + int keysize = 2048;
1846 + String rKeycurve = "nistp256";
1847 + if (rKeytype.equals("EC")) {
1848 + rKeycurve = request.getExtDataInString(IRequest.NETKEY_ATTR_KEY_EC_CURVE);
1849 + if ((rKeycurve == null) || (rKeycurve.equals(""))) {
1850 + rKeycurve = "nistp256";
1851 + }
1852 + } else {
1853 + rKeysize = request.getExtDataInString(IRequest.NETKEY_ATTR_KEY_SIZE);
1854 + keysize = Integer.parseInt(rKeysize);
1855 + }
1856 +
1857 + // get the token for generating user keys
1858 + CryptoToken keygenToken = mKRA.getKeygenToken();
1859 + if (keygenToken == null) {
1860 + CMS.debug("NetkeyKeygenService: failed getting keygenToken");
1861 + request.setExtData(IRequest.RESULT, Integer.valueOf(10));
1862 + return false;
1863 + } else
1864 + CMS.debug("NetkeyKeygenService: got keygenToken");
1865 +
1866 if ((wrapped_des_key != null) &&
1867 (wrapped_des_key.length > 0)) {
1868
1869 @@ -401,8 +480,10 @@
1870
1871 CMS.debug("NetkeyKeygenService: about to generate key pair");
1872
1873 - keypair = generateKeyPair("RSA"/
alg/,
1874 - keysize /
Integer.parseInt(len)/, null /pqgParams/);
1875 + keypair = generateKeyPair(rKeytype /
rKeytype: "RSA" or "EC" /,
1876 + keysize /
Integer.parseInt(len)/,
1877 + rKeycurve /
for "EC" only /,
1878 + null /
pqgParams/);
1879
1880 if (keypair == null) {
1881 CMS.debug("NetkeyKeygenService: failed generating key pair for "+rCUID+":"+rUserid);
1882 @@ -421,18 +502,20 @@
1883 CMS.debug("NetkeyKeygenService: finished generate key pair for " +rCUID+":"+rUserid);
1884
1885 try {
1886 - publicKeyData = keypair.getPublic().getEncoded();
1887 - if (publicKeyData == null) {
1888 - request.setExtData(IRequest.RESULT, Integer.valueOf(4));
1889 - CMS.debug("NetkeyKeygenService: failed getting publickey encoded");
1890 - return false;
1891 - } else {
1892 - //CMS.debug("NetkeyKeygenService: public key binary length ="+ publicKeyData.length);
1893 - PubKey = base64Encode(publicKeyData);
1894 + publicKeyData = keypair.getPublic().getEncoded();
1895 + if (publicKeyData == null) {
1896 + request.setExtData(IRequest.RESULT, Integer.valueOf(4));
1897 + CMS.debug("NetkeyKeygenService: failed getting publickey encoded");
1898 + return false;
1899 + } else {
1900 + //CMS.debug("NetkeyKeygenService: public key binary length ="+ publicKeyData.length);
1901 + /
url encode /
1902 + PubKey = com.netscape.cmsutil.util.Utils.SpecialEncode(publicKeyData);
1903 + CMS.debug("NetkeyKeygenService: EC PubKey special encoded");
1904
1905 - //CMS.debug("NetkeyKeygenService: public key length =" + PubKey.length());
1906 - request.setExtData("public_key", PubKey);
1907 - }
1908 + //CMS.debug("NetkeyKeygenService: public key length =" + PubKey.length());
1909 + request.setExtData("public_key", PubKey);
1910 + }
1911
1912 auditMessage = CMS.getLogMessage(
1913 LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS,
1914 @@ -558,18 +641,52 @@
1915 CMS.debug("NetkeyKeygenService: privatekey recording failed");
1916 return false;
1917 } else
1918 - CMS.debug("NetkeyKeygenService: got key record");
1919 + CMS.debug("NetkeyKeygenService: got key record");
1920
1921 - // we deal with RSA key only
1922 - try {
1923 - RSAPublicKey rsaPublicKey = new RSAPublicKey(publicKeyData);
1924 + if (rKeytype.equals("RSA")) {
1925 + try {
1926 + RSAPublicKey rsaPublicKey = new RSAPublicKey(publicKeyData);
1927
1928 - rec.setKeySize(Integer.valueOf(rsaPublicKey.getKeySize()));
1929 - } catch (InvalidKeyException e) {
1930 - request.setExtData(IRequest.RESULT, Integer.valueOf(11));
1931 - CMS.debug("NetkeyKeygenService: failed:InvalidKeyException");
1932 - return false;
1933 - }
1934 + rec.setKeySize(Integer.valueOf(rsaPublicKey.getKeySize()));
1935 + } catch (InvalidKeyException e) {
1936 + request.setExtData(IRequest.RESULT, Integer.valueOf(11));
1937 + CMS.debug("NetkeyKeygenService: failed:InvalidKeyException");
1938 + return false;
1939 + }
1940 + } else if (rKeytype.equals("EC")) { //cfu
1941 + CMS.debug("NetkeyKeygenService: alg is EC");
1942 + String oidDescription = "UNDETERMINED";
1943 + // for KeyRecordParser
1944 + MetaInfo metaInfo = new MetaInfo();
1945 +
1946 + try {
1947 + byte curve[] =
1948 + ASN1Util.getECCurveBytesByX509PublicKeyBytes(publicKeyData,
1949 + false /
without tag and size /);
1950 + if (curve.length != 0) {
1951 + oidDescription = ASN1Util.getOIDdescription(curve);
1952 + } else {
1953 + /
this is to be used by derdump /
1954 + byte curveTS[] =
1955 + ASN1Util.getECCurveBytesByX509PublicKeyBytes(publicKeyData,
1956 + true /
with tag and size */);
1957 + if (curveTS.length != 0) {
1958 + oidDescription = CMS.BtoA(curveTS);
1959 + }
1960 + }
1961 + } catch (Exception e) {
1962 + CMS.debug("NetkeyKeygenService: ASN1Util.getECCurveBytesByX509PublicKeyByte() throws exception: "+ e.toString());
1963 + CMS.debug("NetkeyKeygenService: exception allowed. continue");
1964 + }
1965 +
1966 + metaInfo.set(KeyRecordParser.OUT_KEY_EC_CURVE,
1967 + oidDescription);
1968 +
1969 + rec.set(IKeyRecord.ATTR_META_INFO, metaInfo);
1970 + // key size does not apply to EC;
1971 + rec.setKeySize(-1);
1972 + }
1973 +
1974 //??
1975 IKeyRepository storage = mKRA.getKeyRepository();
1976 BigInteger serialNo = storage.getNextSerialNumber();

TPS ECC infrastructure TPS-ECC.forReview2

Index: common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java
2 ===================================================================
3 --- common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java (revision 2471)
4 +++ common/src/com/netscape/cms/servlet/connector/GenerateKeyPairServlet.java (working copy)
5 @@ -24,6 +24,7 @@
6 import javax.servlet.http.;
7
8 import java.io.
;
9 +import java.util.Hashtable;
10
11 import com.netscape.certsrv.common.;
12 import com.netscape.certsrv.request.
;
13 @@ -55,6 +56,7 @@
14 IPrettyPrintFormat pp = CMS.getPrettyPrintFormat(":");
15 protected IAuthSubsystem mAuthSubsystem = null;
16 protected ILogger mLogger = CMS.getLogger();
17 + Hashtable supportedECCurves_ht = null;
18
19 /
20 * Constructs GenerateKeyPair servlet.
21 @@ -67,6 +69,7 @@
22 public void init(ServletConfig config) throws ServletException {
23 super.init(config);
24 mConfig = config;
25 + IConfigStore sconfig = CMS.getConfigStore();
26 String authority = config.getInitParameter(PROP_AUTHORITY);
27
28 if (authority != null)
29 @@ -74,6 +77,22 @@
30 CMS.getSubsystem(authority);
31
32 mAuthSubsystem = (IAuthSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTH);
33 +
34 + // supported EC cuves by the smart cards
35 + String curveList = null;
36 + try {
37 + curveList = sconfig.getString("kra.keygen.curvelist",
38 + "nistp256,nistp384,nistp521");
39 + } catch (EBaseException e) {
40 + curveList = "nistp256,nistp384,nistp521";
41 + }
42 +
43 + supportedECCurves_ht = new Hashtable();
44 + String[] supportedECCurves = curveList.split(",");
45 + for ( int i = 0; i < supportedECCurves.length; i++) {
46 + supportedECCurves_ht.put(supportedECCurves[i], supportedECCurves[i]);
47 + }
48 +
49 }
50
51 /

52 @@ -113,8 +132,10 @@
53 String rCUID = req.getParameter("CUID");
54 String rUserid = req.getParameter("userid");
55 String rdesKeyString = req.getParameter("drm_trans_desKey");
56 - String rArchive = req.getParameter("archive");
57 - String rKeysize = req.getParameter("keysize");
58 + String rArchive = req.getParameter("archive");
59 + String rKeysize = req.getParameter("keysize");
60 + String rKeytype = req.getParameter("keytype");
61 + String rKeycurve = req.getParameter("eckeycurve");
62
63 if ((rCUID == null) || (rCUID.equals(""))) {
64 CMS.debug("GenerateKeyPairServlet: processServerSideKeygen(): missing request parameter: CUID");
65 @@ -126,10 +147,30 @@
66 missingParam = true;
67 }
68
69 - if ((rKeysize == null) || (rKeysize.equals(""))) {
70 - rKeysize = "1024"; // default to 1024
71 - }
72 + // keysize is for non-EC (EC uses keycurve)
73 + if (!rKeytype.equals("EC") && ((rKeysize == null) || (rKeysize.equals("")))) {
74 + rKeysize = "1024"; // default to 1024
75 + }
76
77 + // if not specified, default to RSA
78 + if ((rKeytype == null) || (rKeytype.equals(""))) {
79 + rKeytype = "RSA";
80 + }
81 +
82 + if (rKeytype.equals("EC")) {
83 + if ((rKeycurve == null) || (rKeycurve.equals(""))) {
84 + rKeycurve = "nistp256";
85 + }
86 + // is the specified curve supported?
87 + boolean isSupportedCurve = supportedECCurves_ht.containsKey(rKeycurve);
88 + if (isSupportedCurve == false) {
89 + CMS.debug("GenerateKeyPairServlet: processServerSideKeygen(): unsupported curve:"+ rKeycurve);
90 + missingParam = true;
91 + } else {
92 + CMS.debug("GenerateKeyPairServlet: processServerSideKeygen(): curve to be generated:"+ rKeycurve);
93 + }
94 + }
95 +
96 if ((rdesKeyString == null) ||
97 (rdesKeyString.equals(""))) {
98 CMS.debug("GenerateKeyPairServlet: processServerSideKeygen(): missing request parameter: DRM-transportKey-wrapped DES key");
99 @@ -138,7 +179,7 @@
100
101 if ((rArchive == null) || (rArchive.equals(""))) {
102 CMS.debug("GenerateKeyPairServlet: processServerSideKeygen(): missing key archival flag 'archive' ,default to true");
103 - rArchive = "true";
104 + rArchive = "true";
105 }
106
107 String selectedToken = null;
108 @@ -150,17 +191,19 @@
109 thisreq.setExtData(IRequest.NETKEY_ATTR_CUID, rCUID);
110 thisreq.setExtData(IRequest.NETKEY_ATTR_USERID, rUserid);
111 thisreq.setExtData(IRequest.NETKEY_ATTR_DRMTRANS_DES_KEY, rdesKeyString);
112 - thisreq.setExtData(IRequest.NETKEY_ATTR_ARCHIVE_FLAG, rArchive);
113 - thisreq.setExtData(IRequest.NETKEY_ATTR_KEY_SIZE, rKeysize);
114 + thisreq.setExtData(IRequest.NETKEY_ATTR_ARCHIVE_FLAG, rArchive);
115 + thisreq.setExtData(IRequest.NETKEY_ATTR_KEY_SIZE, rKeysize);
116 + thisreq.setExtData(IRequest.NETKEY_ATTR_KEY_TYPE, rKeytype);
117 + thisreq.setExtData(IRequest.NETKEY_ATTR_KEY_EC_CURVE, rKeycurve);
118
119 queue.processRequest( thisreq );
120 Integer result = thisreq.getExtDataInInteger(IRequest.RESULT);
121 if (result != null) {
122 - // sighs! tps thinks 0 is good, and DRM thinks 1 is good
123 - if (result.intValue() == 1)
124 - status = "0";
125 - else
126 - status = result.toString();
127 + // sighs! tps thinks 0 is good, and DRM thinks 1 is good
128 + if (result.intValue() == 1)
129 + status = "0";
130 + else
131 + status = result.toString();
132 } else
133 status = "7";
134
135 @@ -183,7 +226,7 @@
136 publicKeyString = thisreq.getExtDataInString("public_key");
137 wrappedPrivKeyString = thisreq.getExtDataInString("wrappedUserPrivate");
138
139 - String ivString = thisreq.getExtDataInString("iv_s");
140 + String ivString = thisreq.getExtDataInString("iv_s");
141
142 /
143 if (selectedToken == null)
144 @@ -194,12 +237,12 @@
145 else {
146 StringBuffer sb = new StringBuffer();
147 sb.append("status=0&");
148 - sb.append("wrapped_priv_key=");
149 - sb.append(wrappedPrivKeyString);
150 - sb.append("&iv_param=");
151 - sb.append(ivString);
152 + sb.append("wrapped_priv_key=");
153 + sb.append(wrappedPrivKeyString);
154 + sb.append("&iv_param=");
155 + sb.append(ivString);
156 sb.append("&public_key=");
157 - sb.append(publicKeyString);
158 + sb.append(publicKeyString);
159 value = sb.toString();
160
161 }
162 @@ -267,9 +310,9 @@
163 }
164
165 // begin Netkey serverSideKeyGen and archival
166 - CMS.debug("GenerateKeyPairServlet: processServerSideKeyGen would be called");
167 - processServerSideKeyGen(req, resp);
168 - return;
169 + CMS.debug("GenerateKeyPairServlet: processServerSideKeyGen would be called");
170 + processServerSideKeyGen(req, resp);
171 + return;
172 // end Netkey functions
173
174 }
175 Index: common/src/com/netscape/certsrv/request/IRequest.java
176 ===================================================================
177 --- common/src/com/netscape/certsrv/request/IRequest.java (revision 2471)
178 +++ common/src/com/netscape/certsrv/request/IRequest.java (working copy)
179 @@ -153,6 +153,8 @@
180 public final static String NETKEY_ATTR_ENC_PRIVKEY_FLAG ="encryptPrivKey";
181 public final static String NETKEY_ATTR_USER_CERT = "cert";
182 public final static String NETKEY_ATTR_KEY_SIZE = "keysize";
183 + public final static String NETKEY_ATTR_KEY_TYPE = "keytype";
184 + public final static String NETKEY_ATTR_KEY_EC_CURVE = "eckeycurve";
185
186 // requestor type values.
187 public static final String REQUESTOR_EE = "EE";
188 Index: tps/src/processor/RA_Enroll_Processor.cpp
189 ===================================================================
190 --- tps/src/processor/RA_Enroll_Processor.cpp (revision 2471)
191 +++ tps/src/processor/RA_Enroll_Processor.cpp (working copy)
192 @@ -184,7 +184,7 @@
193 const char
cert_attr_id,
194 const char pri_attr_id,
195 const char
pub_attr_id,
196 - BYTE se_p1, BYTE se_p2, int keysize, const char connid, const char keyTypePrefix,char * applet_version)
197 + BYTE se_p1, BYTE se_p2, BYTE algorithm, int keysize, const char connid, const char keyTypePrefix,char * applet_version)
198 {
199 RA_Status status = STATUS_NO_ERROR;
200 int rc = -1;
201 @@ -231,6 +231,9 @@
202 RA::Debug(LL_PER_CONNECTION,FN,
203 "Start of keygen/certificate enrollment");
204
205 + bool isECC = RA::isAlgorithmECC(algorithm);
206 + SECKEYECParams eccParams = NULL;
207 +
208 // get key version for audit logs
209 if (channel != NULL) {
210 if( keyVersion != NULL ) {
211 @@ -288,8 +291,8 @@
212 (progress_block_size * 15/100) /
progress /,
213 "PROGRESS_KEY_GENERATION");
214
215 - if (key_type == KEY_TYPE_ENCRYPTION) {// do serverSide keygen?
216 -
217 + if (key_type == KEY_TYPE_ENCRYPTION) {
218 + // do serverSide keygen?
219 PR_snprintf((char
)configname, 256, "%s.serverKeygen.enable", keyTypePrefix);
220 RA::Debug(LL_PER_CONNECTION,FN,
221 "looking for config %s", configname);
222 @@ -300,57 +303,58 @@
223
224 if (serverKeygen) {
225 RA::Debug(LL_PER_CONNECTION,FN,
226 - "Private key is to be generated on server");
227 + "Private key is to be generated on server");
228
229 PR_snprintf((char )configname, 256, "%s.serverKeygen.drm.conn", keyTypePrefix);
230 RA::Debug(LL_PER_CONNECTION,FN,
231 - "looking for config %s", configname);
232 + "looking for config %s", configname);
233 drmconnid = RA::GetConfigStore()->GetConfigAsString(configname);
234
235 PR_snprintf((char
)configname, 256, "%s.serverKeygen.archive", keyTypePrefix);
236 bool archive = RA::GetConfigStore()->GetConfigAsBool(configname, true);
237
238 RA::Debug(LL_PER_CONNECTION,FN,
239 - "calling ServerSideKeyGen with userid =%s, archive=%s", userid, archive? "true":"false");
240 + "calling ServerSideKeyGen with userid =%s, archive=%s", userid, archive? "true":"false");
241
242 RA::ServerSideKeyGen(session, cuid, userid,
243 channel->getDrmWrappedDESKey(), &pKey,
244 &wrappedPrivKey, &ivParam, drmconnid,
245 - archive, keysize);
246 + archive, keysize, isECC);
247
248 if (pKey == NULL) {
249 - RA::Error(LL_PER_CONNECTION,FN,
250 - "Failed to generate key on server. Please check DRM.");
251 - RA::Debug(LL_PER_CONNECTION,FN,
252 - "ServerSideKeyGen called, pKey is NULL");
253 - status = STATUS_ERROR_MAC_ENROLL_PDU;
254 + RA::Error(LL_PER_CONNECTION,FN,
255 + "Failed to generate key on server. Please check DRM.");
256 + RA::Debug(LL_PER_CONNECTION,FN,
257 + "ServerSideKeyGen called, pKey is NULL");
258 + status = STATUS_ERROR_MAC_ENROLL_PDU;
259
260 PR_snprintf(audit_msg, 512, "ServerSideKeyGen called, failed to generate key on server");
261 - goto loser;
262 - } else
263 - RA::Debug(LL_PER_CONNECTION,FN,
264 - "key value = %s", pKey);
265 + goto loser;
266 + } else {
267 + RA::Debug(LL_PER_CONNECTION,FN,
268 + "key value = %s", pKey);
269 + }
270
271
272 if (wrappedPrivKey == NULL) {
273 - RA::Debug(LL_PER_CONNECTION,FN,
274 - "ServerSideKeyGen called, wrappedPrivKey is NULL");
275 - status = STATUS_ERROR_MAC_ENROLL_PDU;
276 + RA::Debug(LL_PER_CONNECTION,FN,
277 + "ServerSideKeyGen called, wrappedPrivKey is NULL");
278 + status = STATUS_ERROR_MAC_ENROLL_PDU;
279 PR_snprintf(audit_msg, 512, "ServerSideKeyGen called, wrappedPrivKey is NULL");
280 - goto loser;
281 - } else
282 - RA::Debug(LL_PER_CONNECTION,FN,
283 - "wrappedPrivKey = %s", wrappedPrivKey);
284 + goto loser;
285 + } else {
286 + RA::Debug(LL_PER_CONNECTION,FN,
287 + "wrappedPrivKey = %s", wrappedPrivKey);
288 + }
289
290 if (ivParam == NULL) {
291 - RA::Debug(LL_PER_CONNECTION,FN,
292 - "ServerSideKeyGen called, ivParam is NULL");
293 - status = STATUS_ERROR_MAC_ENROLL_PDU;
294 + RA::Debug(LL_PER_CONNECTION,FN,
295 + "ServerSideKeyGen called, ivParam is NULL");
296 + status = STATUS_ERROR_MAC_ENROLL_PDU;
297 PR_snprintf(audit_msg, 512, "ServerSideKeyGen called, ivParam is NULL");
298 - goto loser;
299 + goto loser;
300 } else
301 - RA::Debug(LL_PER_CONNECTION,FN,
302 - "ivParam = %s", ivParam);
303 + RA::Debug(LL_PER_CONNECTION,FN, "ivParam = %s", ivParam);
304
305 /
306 * the following code converts b64-encoded public key info into SECKEYPublicKey
307 @@ -359,39 +363,46 @@
308 SECItem der;
309 CERTSubjectPublicKeyInfo
spki = NULL;
310
311 + Buffer decodePubKey = Util::URLDecode(pKey);
312 + char
pKey_ascii = NULL;
313 + if (decodePubKey != NULL) {
314 + pKey_ascii =
315 + BTOA_DataToAscii(decodePubKey->getBuf(), decodePubKey->getLen());
316 + } else {
317 + PR_snprintf(audit_msg, 512, "ServerSideKeyGen: failed to URL decode public key");
318 + goto loser;
319 + }
320 +
321 der.type = (SECItemType) 0; / initialize it, since convertAsciiToItem does not set it /
322 - rv = ATOB_ConvertAsciiToItem (&der, pKey);
323 + rv = ATOB_ConvertAsciiToItem (&der, pKey_ascii);
324 if (rv != SECSuccess){
325 - RA::Debug(LL_PER_CONNECTION,FN,
326 - "failed to convert b64 private key to binary");
327 - SECITEM_FreeItem(&der, PR_FALSE);
328 - status = STATUS_ERROR_MAC_ENROLL_PDU;
329 - PR_snprintf(audit_msg, 512, "ServerSideKeyGen: failed to convert b64 private key to binary");
330 - goto loser;
331 - }else {
332 - RA::Debug(LL_PER_CONNECTION,FN,
333 - "decoded private key as: secitem (len=%d)",der.len);
334 + RA::Debug(LL_PER_CONNECTION,FN,
335 + "failed to convert b64 public key to binary");
336 + SECITEM_FreeItem(&der, PR_FALSE);
337 + status = STATUS_ERROR_MAC_ENROLL_PDU;
338 + PR_snprintf(audit_msg, 512, "ServerSideKeyGen: failed to convert b64 public key to binary");
339 + goto loser;
340 + } else {
341 + RA::Debug(LL_PER_CONNECTION,FN,
342 + "decoded public key as: secitem (len=%d)",der.len);
343
344 - spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&der);
345 + spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&der);
346
347 - if (spki != NULL) {
348 - RA::Debug(LL_PER_CONNECTION,FN,
349 - "Successfully decoded DER SubjectPublicKeyInfo structure");
350 - pk_p = SECKEY_ExtractPublicKey(spki);
351 - if (pk_p != NULL)
352 - RA::Debug(LL_PER_CONNECTION,FN,
353 - "Successfully extracted public key from SPKI structure");
354 - else
355 - RA::Debug(LL_PER_CONNECTION,FN,
356 - "Failed to extract public key from SPKI");
357 - } else {
358 - RA::Debug(LL_PER_CONNECTION,FN,
359 - "Failed to decode SPKI structure");
360 - }
361 + if (spki != NULL) {
362 + RA::Debug(LL_PER_CONNECTION,FN,
363 + "Successfully decoded DER SubjectPublicKeyInfo structure");
364 + pk_p = SECKEY_ExtractPublicKey(spki);
365 + if (pk_p != NULL)
366 + RA::Debug(LL_PER_CONNECTION,FN, "Successfully extracted public key from SPKI structure");
367 + else
368 + RA::Debug(LL_PER_CONNECTION,FN, "Failed to extract public key from SPKI");
369 + } else {
370 + RA::Debug(LL_PER_CONNECTION,FN,
371 + "Failed to decode SPKI structure");
372 + }
373
374 - SECITEM_FreeItem(&der, PR_FALSE);
375 - SECKEY_DestroySubjectPublicKeyInfo(spki);
376 -
377 + SECITEM_FreeItem(&der, PR_FALSE);
378 + SECKEY_DestroySubjectPublicKeyInfo(spki);
379 }
380
381 } else { //generate keys on token
382 @@ -404,6 +415,11 @@
383 if(key_check && key_check->size())
384 alg = 0x81;
385
386 +
387 + if (isECC) {
388 + alg = algorithm;
389 + }
390 +
391 len = channel->StartEnrollment(
392 se_p1, se_p2,
393 wrapped_challenge,
394 @@ -412,7 +428,7 @@
395 0x00 / option /);
396
397 RA::Debug(LL_PER_CONNECTION,FN,
398 - "channel->StartEnrollment returned length of public key blob: len=%d", len);
399 + "channel->StartEnrollment returned length of public key blob: len=%d", len);
400
401 StatusUpdate(session, extensions,
402 start_progress + (index * progress_block_size) +
403 @@ -460,6 +476,8 @@
404 plaintext_challenge);
405
406
407 + // We have received the public key blob for ECC
408 +
409 // send status update to the client
410 StatusUpdate(session, extensions,
411 start_progress + (index * progress_block_size) +
412 @@ -471,7 +489,7 @@
413
414 pk_p = certEnroll->ParsePublicKeyBlob(
415 (unsigned char )(BYTE )public_key /blob/,
416 - plaintext_challenge);
417 + plaintext_challenge, isECC);
418
419 if (pk_p == NULL) {
420 RA::Error(LL_PER_CONNECTION,FN,
421 @@ -550,8 +568,10 @@
422 goto loser;
423 }
424
425 - si_mod = pk_p->u.rsa.modulus;
426 - modulus = new Buffer((BYTE
) si_mod.data, si_mod.len);
427 + if (!isECC) {
428 + si_mod = pk_p->u.rsa.modulus;
429 + modulus = new Buffer((BYTE) si_mod.data, si_mod.len);
430 + }
431
432 /

433 * RFC 3279
434 @@ -569,15 +589,15 @@
435 si_kid = PK11_MakeIDFromPubKey(&spkix->subjectPublicKey);
436 spkix->subjectPublicKey.len <<= 3;
437
438 -
439 keyid = new Buffer((BYTE) si_kid->data, si_kid->len);
440
441 - si_exp = pk_p->u.rsa.publicExponent;
442 - exponent = new Buffer((BYTE
) si_exp.data, si_exp.len);
443 + if (!isECC) {
444 + si_exp = pk_p->u.rsa.publicExponent;
445 + exponent = new Buffer((BYTE) si_exp.data, si_exp.len);
446 + RA::Debug(LL_PER_CONNECTION,FN,
447 + "Keyid, modulus and exponent have been extracted from public key");
448 + }
449
450 - RA::Debug(LL_PER_CONNECTION,FN,
451 - "Keyid, modulus and exponent have been extracted from public key");
452 -
453 SECKEY_DestroySubjectPublicKeyInfo(spkix);
454
455 cert_string = (char
) cert->string();
456 @@ -788,67 +808,77 @@
457
458 / write certificate from CA to netkey /
459 if (pkcs11obj_enable) {
460 - ObjectSpec objSpec =
461 - ObjectSpec::ParseFromTokenData(
462 - (cert_id[0] << 24) +
463 - (cert_id[1] << 16),
464 - cert);
465 - pkcs_objx->AddObjectSpec(objSpec);
466 + ObjectSpec
objSpec =
467 + ObjectSpec::ParseFromTokenData(
468 + (cert_id[0] << 24) +
469 + (cert_id[1] << 16),
470 + cert);
471 + pkcs_objx->AddObjectSpec(objSpec);
472 } else {
473 - RA::Debug(LL_PER_CONNECTION,FN,
474 - "About to create certificate object on token");
475 - rc = channel->CreateCertificate(cert_id, cert);
476 - if (rc == -1) {
477 - RA::Error(LL_PER_CONNECTION,FN,
478 - "Failed to create certificate object on token");
479 - status = STATUS_ERROR_MAC_ENROLL_PDU;
480 - PR_snprintf(audit_msg, 512, "Failed to create certificate object on token");
481 - goto loser;
482 - }
483 + RA::Debug(LL_PER_CONNECTION,FN,
484 + "About to create certificate object on token");
485 + rc = channel->CreateCertificate(cert_id, cert);
486 + if (rc == -1) {
487 + RA::Error(LL_PER_CONNECTION,FN,
488 + "Failed to create certificate object on token");
489 + status = STATUS_ERROR_MAC_ENROLL_PDU;
490 + PR_snprintf(audit_msg, 512, "Failed to create certificate object on token");
491 + goto loser;
492 + }
493 }
494
495 // build label
496 PR_snprintf((char )configname, 256, "%s.%s.keyGen.%s.label",
497 - OP_PREFIX, tokenType, keyType);
498 + OP_PREFIX, tokenType, keyType);
499 RA::Debug(LL_PER_CONNECTION,FN,
500 - "label '%s'", configname);
501 + "label '%s'", configname);
502 pattern = RA::GetConfigStore()->GetConfigAsString(configname);
503 label = MapPattern(&nv, (char
) pattern);
504
505 if (pkcs11obj_enable) {
506 - Buffer b = channel->CreatePKCS11CertAttrsBuffer(
507 - key_type, cert_attr_id, label, keyid);
508 - ObjectSpec objSpec =
509 - ObjectSpec::ParseFromTokenData(
510 - (cert_attr_id[0] << 24) +
511 - (cert_attr_id[1] << 16),
512 - &b);
513 - pkcs_objx->AddObjectSpec(objSpec);
514 + Buffer b = channel->CreatePKCS11CertAttrsBuffer(
515 + key_type, cert_attr_id, label, keyid);
516 + ObjectSpec
objSpec =
517 + ObjectSpec::ParseFromTokenData(
518 + (cert_attr_id[0] << 24) +
519 + (cert_attr_id[1] << 16),
520 + &b);
521 + pkcs_objx->AddObjectSpec(objSpec);
522 } else {
523 - RA::Debug(LL_PER_CONNECTION,FN,
524 - "About to create PKCS#11 certificate Attributes");
525 - rc = channel->CreatePKCS11CertAttrs(key_type, cert_attr_id, label, keyid);
526 - if (rc == -1) {
527 - RA::Error(LL_PER_CONNECTION,FN,
528 - "PKCS11 Certificate attributes creation failed");
529 - status = STATUS_ERROR_MAC_ENROLL_PDU;
530 + RA::Debug(LL_PER_CONNECTION,FN,
531 + "About to create PKCS#11 certificate Attributes");
532 + rc = channel->CreatePKCS11CertAttrs(key_type, cert_attr_id, label, keyid);
533 + if (rc == -1) {
534 + RA::Error(LL_PER_CONNECTION,FN,
535 + "PKCS11 Certificate attributes creation failed");
536 + status = STATUS_ERROR_MAC_ENROLL_PDU;
537 PR_snprintf(audit_msg, 512, "PKCS11 Certificate attributes creation failed");
538 - goto loser;
539 - }
540 + goto loser;
541 + }
542 }
543
544 if (pkcs11obj_enable) {
545 - RA::Debug(LL_PER_CONNECTION,FN,
546 - "Create PKCS11 Private Key Attributes Buffer");
547 - Buffer b = channel->CreatePKCS11PriKeyAttrsBuffer(key_type,
548 - pri_attr_id, label, keyid, modulus, OP_PREFIX,
549 - tokenType, keyTypePrefix);
550 - ObjectSpec objSpec =
551 - ObjectSpec::ParseFromTokenData(
552 - (pri_attr_id[0] << 24) +
553 - (pri_attr_id[1] << 16),
554 - &b);
555 - pkcs_objx->AddObjectSpec(objSpec);
556 + RA::Debug(LL_PER_CONNECTION,FN,
557 + "Create PKCS11 Private Key Attributes Buffer");
558 +
559 + Buffer b;
560 + if (!isECC) {
561 + b = channel->CreatePKCS11PriKeyAttrsBuffer(key_type,
562 + pri_attr_id, label, keyid, modulus, OP_PREFIX,
563 + tokenType, keyTypePrefix);
564 +
565 + } else { //isECC
566 + eccParams = &pk_p->u.ec.DEREncodedParams;
567 + b = channel->CreatePKCS11ECCPriKeyAttrsBuffer(key_type,
568 + pri_attr_id, label, keyid, eccParams, OP_PREFIX,
569 + tokenType, keyTypePrefix);
570 + }
571 + ObjectSpec
objSpec =
572 + ObjectSpec::ParseFromTokenData(
573 + (pri_attr_id[0] << 24) +
574 + (pri_attr_id[1] << 16),
575 + &b);
576 + pkcs_objx->AddObjectSpec(objSpec);
577 } else {
578 RA::Debug(LL_PER_CONNECTION,FN,
579 "Create PKCS11 Private Key Attributes");
580 @@ -863,27 +893,34 @@
581 }
582
583 if (pkcs11obj_enable) {
584 - Buffer b = channel->CreatePKCS11PubKeyAttrsBuffer(key_type,
585 - pub_attr_id, label, keyid,
586 - exponent, modulus, OP_PREFIX, tokenType, keyTypePrefix);
587 - ObjectSpec objSpec =
588 - ObjectSpec::ParseFromTokenData(
589 - (pub_attr_id[0] << 24) +
590 - (pub_attr_id[1] << 16),
591 - &b);
592 - pkcs_objx->AddObjectSpec(objSpec);
593 + Buffer b;
594 + if (!isECC) {
595 + b = channel->CreatePKCS11PubKeyAttrsBuffer(key_type,
596 + pub_attr_id, label, keyid,
597 + exponent, modulus, OP_PREFIX, tokenType, keyTypePrefix);
598 + } else {
599 + b = channel->CreatePKCS11ECCPubKeyAttrsBuffer(key_type,
600 + pub_attr_id, label, keyid,&pk_p->u.ec, eccParams,
601 + OP_PREFIX, tokenType, keyTypePrefix);
602 + }
603 + ObjectSpec
objSpec =
604 + ObjectSpec::ParseFromTokenData(
605 + (pub_attr_id[0] << 24) +
606 + (pub_attr_id[1] << 16),
607 + &b);
608 + pkcs_objx->AddObjectSpec(objSpec);
609 } else {
610 - RA::Debug(LL_PER_CONNECTION,FN,
611 - "Create PKCS11 Public Key Attributes");
612 - rc = channel->CreatePKCS11PubKeyAttrs(key_type, pub_attr_id, label, keyid,
613 + RA::Debug(LL_PER_CONNECTION,FN,
614 + "Create PKCS11 Public Key Attributes");
615 + rc = channel->CreatePKCS11PubKeyAttrs(key_type, pub_attr_id, label, keyid,
616 exponent, modulus, OP_PREFIX, tokenType, keyTypePrefix);
617 - if (rc == -1) {
618 - RA::Error(LL_PER_CONNECTION,FN,
619 - "PKCS11 public key attributes creation failed");
620 - status = STATUS_ERROR_MAC_ENROLL_PDU;
621 + if (rc == -1) {
622 + RA::Error(LL_PER_CONNECTION,FN,
623 + "PKCS11 public key attributes creation failed");
624 + status = STATUS_ERROR_MAC_ENROLL_PDU;
625 PR_snprintf(audit_msg, 512, "PKCS11 public key attributes creation failed");
626 - goto loser;
627 - }
628 + goto loser;
629 + }
630 }
631 RA::Debug(LL_PER_CONNECTION,FN, "End of keygen/certificate enrollment");
632
633 @@ -983,10 +1020,13 @@
634 }
635 if (pk_p != NULL) {
636 if (serverKeygen) {
637 + RA::Debug(LL_PER_CONNECTION,FN,"DoEnrollment about to call SECKEY_DestroyPublicKey on pk_p");
638 SECKEY_DestroyPublicKey(pk_p);
639 } else {
640 + RA::Debug(LL_PER_CONNECTION,FN,"DoEnrollment about to call free on pk_p");
641 free(pk_p);
642 }
643 +
644 pk_p = NULL;
645 }
646 return status;
647 @@ -3055,6 +3095,11 @@
648 PR_snprintf((char )configname, 256, "%s.keySize", keyTypePrefix);
649 int keySize = RA::GetConfigStore()->GetConfigAsInt(configname, 1024);
650
651 +
652 + PR_snprintf((char
)configname, 256, "%s.alg", keyTypePrefix);
653 + //Default RSA_CRT=2
654 + BYTE algorithm = (BYTE) RA::GetConfigStore()->GetConfigAsInt(configname, 2);
655 +
656 PR_snprintf((char )configname, 256, "%s.publisherId", keyTypePrefix);
657 const char
publisherId = RA::GetConfigStore()->GetConfigAsString(configname, NULL);
658
659 @@ -3105,7 +3150,7 @@
660 msn,
661 khex, (TokenKeyType)keyTypeEnum, profileId, userid, certId,publisherId, certAttrId, priKeyAttrId,
662 pubKeyAttrId, (keyUser << 4)+priKeyNumber,
663 - (keyUsage << 4)+pubKeyNumber, keySize, caconnid, keyTypePrefix,(char )final_applet_version);
664 + (keyUsage << 4)+pubKeyNumber, algorithm, keySize, caconnid, keyTypePrefix,(char
)final_applet_version);
665
666 if (o_status != STATUS_NO_ERROR) {
667 r = false;
668 Index: tps/src/cms/CertEnroll.cpp
669 ===================================================================
670 --- tps/src/cms/CertEnroll.cpp (revision 2471)
671 +++ tps/src/cms/CertEnroll.cpp (working copy)
672 @@ -19,6 +19,7 @@
673 // --- END COPYRIGHT BLOCK ---
674
675 #include
676 +#include
677
678 #include "main/RA_Session.h"
679 #include "main/RA_Msg.h"
680 @@ -35,6 +36,7 @@
681 #include "base64.h"
682 #include "nssb64.h"
683 #include "prlock.h"
684 +#include "secoidt.h"
685
686 #include "main/Memory.h"
687
688 @@ -49,6 +51,131 @@
689 #define TOKENDB_PUBLIC
690 #endif / !XP_WIN32 /
691
692 +//ECC curve information
693 +
694 +typedef struct curveNameTagPairStr {
695 + char curveName;
696 + SECOidTag curveOidTag;
697 +} CurveNameTagPair;
698 +
699 +
700 +static CurveNameTagPair nameTagPair[] =
701 +{
702 + { "prime192v1", SEC_OID_ANSIX962_EC_PRIME192V1 },
703 + { "prime192v2", SEC_OID_ANSIX962_EC_PRIME192V2 },
704 + { "prime192v3", SEC_OID_ANSIX962_EC_PRIME192V3 },
705 + { "prime239v1", SEC_OID_ANSIX962_EC_PRIME239V1 },
706 + { "prime239v2", SEC_OID_ANSIX962_EC_PRIME239V2 },
707 + { "prime239v3", SEC_OID_ANSIX962_EC_PRIME239V3 },
708 + { "prime256v1", SEC_OID_ANSIX962_EC_PRIME256V1 },
709 +
710 + { "secp112r1", SEC_OID_SECG_EC_SECP112R1},
711 + { "secp112r2", SEC_OID_SECG_EC_SECP112R2},
712 + { "secp128r1", SEC_OID_SECG_EC_SECP128R1},
713 + { "secp128r2", SEC_OID_SECG_EC_SECP128R2},
714 + { "secp160k1", SEC_OID_SECG_EC_SECP160K1},
715 + { "secp160r1", SEC_OID_SECG_EC_SECP160R1},
716 + { "secp160r2", SEC_OID_SECG_EC_SECP160R2},
717 + { "secp192k1", SEC_OID_SECG_EC_SECP192K1},
718 + { "secp192r1", SEC_OID_ANSIX962_EC_PRIME192V1 },
719 + { "nistp192", SEC_OID_ANSIX962_EC_PRIME192V1 },
720 + { "secp224k1", SEC_OID_SECG_EC_SECP224K1},
721 + { "secp224r1", SEC_OID_SECG_EC_SECP224R1},
722 + { "nistp224", SEC_OID_SECG_EC_SECP224R1},
723 + { "secp256k1", SEC_OID_SECG_EC_SECP256K1},
724 + { "secp256r1", SEC_OID_ANSIX962_EC_PRIME256V1 },
725 + { "nistp256", SEC_OID_ANSIX962_EC_PRIME256V1 },
726 + { "secp384r1", SEC_OID_SECG_EC_SECP384R1},
727 + { "nistp384", SEC_OID_SECG_EC_SECP384R1},
728 + { "secp521r1", SEC_OID_SECG_EC_SECP521R1},
729 + { "nistp521", SEC_OID_SECG_EC_SECP521R1},
730 +
731 + { "c2pnb163v1", SEC_OID_ANSIX962_EC_C2PNB163V1 },
732 + { "c2pnb163v2", SEC_OID_ANSIX962_EC_C2PNB163V2 },
733 + { "c2pnb163v3", SEC_OID_ANSIX962_EC_C2PNB163V3 },
734 + { "c2pnb176v1", SEC_OID_ANSIX962_EC_C2PNB176V1 },
735 + { "c2tnb191v1", SEC_OID_ANSIX962_EC_C2TNB191V1 },
736 + { "c2tnb191v2", SEC_OID_ANSIX962_EC_C2TNB191V2 },
737 + { "c2tnb191v3", SEC_OID_ANSIX962_EC_C2TNB191V3 },
738 + { "c2onb191v4", SEC_OID_ANSIX962_EC_C2ONB191V4 },
739 + { "c2onb191v5", SEC_OID_ANSIX962_EC_C2ONB191V5 },
740 + { "c2pnb208w1", SEC_OID_ANSIX962_EC_C2PNB208W1 },
741 + { "c2tnb239v1", SEC_OID_ANSIX962_EC_C2TNB239V1 },
742 + { "c2tnb239v2", SEC_OID_ANSIX962_EC_C2TNB239V2 },
743 + { "c2tnb239v3", SEC_OID_ANSIX962_EC_C2TNB239V3 },
744 + { "c2onb239v4", SEC_OID_ANSIX962_EC_C2ONB239V4 },
745 + { "c2onb239v5", SEC_OID_ANSIX962_EC_C2ONB239V5 },
746 + { "c2pnb272w1", SEC_OID_ANSIX962_EC_C2PNB272W1 },
747 + { "c2pnb304w1", SEC_OID_ANSIX962_EC_C2PNB304W1 },
748 + { "c2tnb359v1", SEC_OID_ANSIX962_EC_C2TNB359V1 },
749 + { "c2pnb368w1", SEC_OID_ANSIX962_EC_C2PNB368W1 },
750 + { "c2tnb431r1", SEC_OID_ANSIX962_EC_C2TNB431R1 },
751 +
752 + { "sect113r1", SEC_OID_SECG_EC_SECT113R1},
753 + { "sect113r2", SEC_OID_SECG_EC_SECT113R2},
754 + { "sect131r1", SEC_OID_SECG_EC_SECT131R1},
755 + { "sect131r2", SEC_OID_SECG_EC_SECT131R2},
756 + { "sect163k1", SEC_OID_SECG_EC_SECT163K1},
757 + { "nistk163", SEC_OID_SECG_EC_SECT163K1},
758 + { "sect163r1", SEC_OID_SECG_EC_SECT163R1},
759 + { "sect163r2", SEC_OID_SECG_EC_SECT163R2},
760 + { "nistb163", SEC_OID_SECG_EC_SECT163R2},
761 + { "sect193r1", SEC_OID_SECG_EC_SECT193R1},
762 + { "sect193r2", SEC_OID_SECG_EC_SECT193R2},
763 + { "sect233k1", SEC_OID_SECG_EC_SECT233K1},
764 + { "nistk233", SEC_OID_SECG_EC_SECT233K1},
765 + { "sect233r1", SEC_OID_SECG_EC_SECT233R1},
766 + { "nistb233", SEC_OID_SECG_EC_SECT233R1},
767 + { "sect239k1", SEC_OID_SECG_EC_SECT239K1},
768 + { "sect283k1", SEC_OID_SECG_EC_SECT283K1},
769 + { "nistk283", SEC_OID_SECG_EC_SECT283K1},
770 + { "sect283r1", SEC_OID_SECG_EC_SECT283R1},
771 + { "nistb283", SEC_OID_SECG_EC_SECT283R1},
772 + { "sect409k1", SEC_OID_SECG_EC_SECT409K1},
773 + { "nistk409", SEC_OID_SECG_EC_SECT409K1},
774 + { "sect409r1", SEC_OID_SECG_EC_SECT409R1},
775 + { "nistb409", SEC_OID_SECG_EC_SECT409R1},
776 + { "sect571k1", SEC_OID_SECG_EC_SECT571K1},
777 + { "nistk571", SEC_OID_SECG_EC_SECT571K1},
778 + { "sect571r1", SEC_OID_SECG_EC_SECT571R1},
779 + { "nistb571", SEC_OID_SECG_EC_SECT571R1},
780 +
781 +};
782 +
783 +SECKEYECParams *
784 +CertEnroll::encode_ec_params(char
curve)
785 +{
786 + SECKEYECParams ecparams;
787 + SECOidData
oidData = NULL;
788 + SECOidTag curveOidTag = SEC_OID_UNKNOWN; / default /
789 + int i, numCurves;
790 +
791 + if (curve && curve) {
792 + numCurves = sizeof(nameTagPair)/sizeof(CurveNameTagPair);
793 + for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN));
794 + i++) {
795 + if (PL_strcmp(curve, nameTagPair[i].curveName) == 0)
796 + curveOidTag = nameTagPair[i].curveOidTag;
797 + }
798 + }
799 +
800 + if ((curveOidTag == SEC_OID_UNKNOWN) ||
801 + (oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) {
802 + return NULL;
803 + }
804 +
805 + ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));
806 +
807 + if (!ecparams)
808 + return NULL;
809 +
810 + ecparams->data[0] = SEC_ASN1_OBJECT_ID;
811 + ecparams->data[1] = oidData->oid.len;
812 + memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len);
813 +
814 + return ecparams;
815 +}
816 +
817 /

818 * Constructs handle for Certificate Enrollment
819
/
820 @@ -328,8 +455,20 @@
821 * Short Exponent Length
822 *
823 * Byte[] Exponent
824 + *
825 + *
826 + * ECC KeyBlob Format (ECC Public Key)
827 + * ----------------------------------
828 + *
829 + * Byte Encoding (0 for plaintext)
830 *
831 - *
832 + * Byte Key Type (10 for ECC public)
833 + *
834 + * Short Key Length (256, 384, 521 high byte first)
835 + *
836 + * Byte[] Key (W)
837 + *
838 + *
839 * Signature Format (Proof)
840 * ---------------------------------------
841 *
842 @@ -369,7 +508,7 @@
843 */
844
845 SECKEYPublicKey
CertEnroll::ParsePublicKeyBlob(unsigned char blob,
846 - Buffer
challenge)
847 + Buffer challenge, bool isECC)
848 {
849 char configname[5000];
850 SECKEYPublicKey
pk = NULL;
851 @@ -404,7 +543,7 @@
852 pkeyb_len = (unsigned short) ((len0 << 8) | (len1 & 0xFF));
853
854 RA::Debug(LL_PER_PDU, "CertEnroll::ParsePublicKeyBlob",
855 - "pkeyb_len =%d",pkeyb_len);
856 + "pkeyb_len =%d isECC: %d",pkeyb_len, isECC);
857
858 if (pkeyb_len <= 0) {
859 RA::Error("CertEnroll::ParsePublicKeyBlob", "public key blob length = %d", pkeyb_len);
860 @@ -431,51 +570,112 @@
861
862 // convert pkeyb to pkey
863 // 1 byte encoding, 1 byte key type, 2 bytes key length, then the key
864 +
865 + // for ECC
866 + unsigned short ecc_pkey_len = 0;
867 + // ecc key blob
868 + unsigned char eccpb = NULL;
869 +
870 + // for RSA
871 + unsigned short mod_len = 0;
872 + unsigned short exp_len = 0;
873 + // public key mod blob
874 + unsigned char * modb = NULL;
875 + // public key exp blob
876 + unsigned char * expb = NULL;
877 +
878 unsigned short pkey_offset = 4;
879 - // now, convert lengths for modulus and exponent
880 len0 = pkeyb[pkey_offset];
881 len1 = pkeyb[pkey_offset + 1];
882 - unsigned short mod_len = (len0 << 8 | len1);
883
884 - len0 = pkeyb[pkey_offset + 2 + mod_len];
885 - len1 = pkeyb[pkey_offset + 2 + mod_len + 1];
886 - unsigned short exp_len = (len0 << 8 | len1);
887 + if (!isECC) {
888 + // now, convert lengths for modulus and exponent
889 + mod_len = (len0 << 8 | len1);
890
891 + len0 = pkeyb[pkey_offset + 2 + mod_len];
892 + len1 = pkeyb[pkey_offset + 2 + mod_len + 1];
893 + exp_len = (len0 << 8 | len1);
894
895 - // public key mod blob
896 - unsigned char * modb = &pkeyb[pkey_offset + 2];
897 + modb = &pkeyb[pkey_offset + 2];
898 + expb = &pkeyb[pkey_offset + 2 + mod_len + 2];
899
900 - // public key exp blob
901 - unsigned char * expb = &pkeyb[pkey_offset + 2 + mod_len + 2];
902 + } else {
903 + ecc_pkey_len = (len0 << 8 | len1);
904 + eccpb = &pkeyb[pkey_offset + 2];
905 + }
906
907 // construct SECItem
908 +
909 + // for RSA
910 SECItem siMod;
911 - siMod.type = (SECItemType) 0;
912 - siMod.data = (unsigned char
) modb;
913 - siMod.len = mod_len;
914 -
915 SECItem siExp;
916 - siExp.type = (SECItemType) 0;
917 - siExp.data = (unsigned char )expb;
918 - siExp.len = exp_len;
919 -
920 - // construct SECKEYRSAPublicKeyStr
921 SECKEYRSAPublicKeyStr rsa_pks;
922 - rsa_pks.modulus = siMod;
923 - rsa_pks.publicExponent = siExp;
924
925 - // construct SECKEYPublicKey
926 - // this is to be returned
927 + // for ECC
928 + SECItem eccValue;
929 + SECKEYECPublicKeyStr ecc_pks;
930 + SECKEYECParams
ecc_key_params = NULL;
931 +
932 pk = (SECKEYPublicKey ) malloc(sizeof(SECKEYPublicKey));
933 - pk->keyType = rsaKey;
934 - pk->pkcs11Slot = NULL;
935 - pk->pkcs11ID = CK_INVALID_HANDLE;
936 - pk->u.rsa = rsa_pks;
937
938 + assert(pk);
939 +
940 + if (!isECC) {
941 +
942 + siMod.type = (SECItemType) 0;
943 + siMod.data = (unsigned char
) modb;
944 + siMod.len = mod_len;
945 +
946 + siExp.type = (SECItemType) 0;
947 + siExp.data = (unsigned char )expb;
948 + siExp.len = exp_len;
949 +
950 + // construct SECKEYRSAPublicKeyStr
951 + rsa_pks.modulus = siMod;
952 + rsa_pks.publicExponent = siExp;
953 +
954 + pk->keyType = rsaKey;
955 + pk->pkcs11Slot = NULL;
956 + pk->pkcs11ID = CK_INVALID_HANDLE;
957 + pk->u.rsa = rsa_pks;
958 + } else {
959 + // ECC
960 + len0 = blob[pkeyb_len_offset +4];
961 + len1 = blob[pkeyb_len_offset +5];
962 + int keyCurveSize = (len0 << 8 | len1);
963 +
964 + RA::Debug(LL_PER_PDU, "CertEnroll::ParsePublicKeyBlob",
965 + "keyCurveSize =%d",keyCurveSize);
966 +
967 + char curve[56] = "";
968 + snprintf(curve, 56, "nistp%d",keyCurveSize );
969 +
970 + ecc_key_params = encode_ec_params(curve);
971 +
972 + if (ecc_key_params == NULL) {
973 + free(pk);
974 + pk = NULL;
975 + return NULL;
976 + }
977 +
978 + eccValue.type = (SECItemType) 0;
979 + eccValue.data = (unsigned char
) eccpb;
980 + eccValue.len = ecc_pkey_len;
981 +
982 + ecc_pks.size = keyCurveSize;
983 + ecc_pks.publicValue = eccValue;
984 + ecc_pks.DEREncodedParams = ecc_key_params;
985 +
986 + pk->keyType = ecKey;
987 + pk->pkcs11Slot = NULL;
988 + pk->pkcs11ID = CK_INVALID_HANDLE;
989 + pk->u.ec = ecc_pks;
990 + }
991 +
992 PR_snprintf((char
)configname, 256, "general.verifyProof");
993 int verifyProofEnable = RA::GetConfigStore()->GetConfigAsInt(configname, 0x1);
994 if (verifyProofEnable) {
995 - rs = verifyProof(pk, &siProof, pkeyb_len, pkeyb, challenge);
996 + rs = verifyProof(pk, &siProof, pkeyb_len, pkeyb, challenge, isECC);
997 if (rs.status == PR_FAILURE) {
998 RA::Error("CertEnroll::ParsePublicKeyBlob",
999 "verify proof failed");
1000 @@ -487,7 +687,33 @@
1001 return pk;
1002 }
1003
1004 +/
1005 + * for debugging tokens
1006 + * -- list out all tokens and thier login status
1007 +
/
1008 +static SECStatus
1009 +ListModules(void)
1010 +{
1011 + PK11SlotList list;
1012 + PK11SlotListElement
le;
1013
1014 + / get them all! /
1015 + list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_FALSE,NULL);
1016 + if (list == NULL) return SECFailure;
1017 +
1018 + / look at each slot/
1019 + for (le = list->head ; le; le = le->next) {
1020 + RA::Debug( LL_PER_PDU, "CertEnroll::ListModules",
1021 + " slot: %s\n, loggedIn? %d, token: %s\n", PK11_GetSlotName(le->slot),
1022 + (PK11_IsLoggedIn(le->slot, NULL) == PR_TRUE)? 1:0,
1023 + PK11_GetTokenName(le->slot));
1024 + }
1025 + PK11_FreeSlotList(list);
1026 +
1027 + return SECSuccess;
1028 +}
1029 +
1030 +
1031 /

1032 * verify the proof.
1033 * @param pk the public key from the input blob
1034 @@ -502,18 +728,24 @@
1035 /
1036 ReturnStatus CertEnroll::verifyProof(SECKEYPublicKey
pk, SECItem siProof,
1037 unsigned short pkeyb_len, unsigned char
pkeyb,
1038 - Buffer challenge) {
1039 + Buffer
challenge, bool isECC) {
1040
1041 ReturnStatus rs;
1042 VFYContext * vc = NULL;
1043 rs.statusNum = ::VRFY_SUCCESS;
1044 rs.status = PR_SUCCESS;
1045
1046 + // ListModules();
1047 +
1048 // verify proof (signature)
1049 RA::Debug(LL_PER_PDU, "CertEnroll::verifyProof",
1050 "verify proof begins");
1051
1052 - vc = VFY_CreateContext(pk, siProof, SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE, NULL);
1053 + if(isECC) {
1054 + vc = VFY_CreateContext(pk, siProof, SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE , NULL);
1055 + } else {
1056 + vc = VFY_CreateContext(pk, siProof, SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE, NULL);
1057 + }
1058
1059 if (vc == NULL) {
1060 RA::Error("CertEnroll::verifyProof",
1061 @@ -530,14 +762,15 @@
1062 int i =0;
1063 for (i = 0; i<pkeyb_len; i++) {
1064 proof[i] = pkeyb[i];
1065 + RA::Debug(LL_PER_PDU,"CertEnroll::VerifyProof", "proof[%d]=%x", i, proof[i]);
1066 }
1067 - // RA::DebugBuffer("CertEnroll::VerifyProof","VerifyProof:: challenge =", challenge);
1068 + RA::DebugBuffer("CertEnroll::VerifyProof","VerifyProof:: challenge =", challenge);
1069 unsigned char chal = (unsigned char )(BYTE ) (challenge);
1070 unsigned int j = 0;
1071 for (j=0; j < challenge->size(); i++, j++) {
1072 proof[i] = chal[j];
1073 - // RA::Debug(LL_PER_PDU, "CertEnroll::VerifyProof","proof[%d]= %x",
1074 - // i, proof[i]);
1075 + RA::Debug(LL_PER_PDU, "CertEnroll::VerifyProof","proof[%d]= %x",
1076 + i, proof[i]);
1077 }
1078
1079 SECStatus vs = VFY_Begin(vc);
1080 @@ -547,7 +780,7 @@
1081 vs = VFY_End(vc);
1082 if (vs == SECFailure) {
1083 RA::Error("CertEnroll::verifyProof",
1084 - "VFY_End() failed pkeyb_len=%d challenge_size=%d", pkeyb_len, challenge->size());
1085 + "VFY_End() failed pkeyb_len=%d challenge_size=%d error=%d", pkeyb_len, challenge->size(),PR_GetError());
1086 rs.statusNum = ::VFY_UPDATE_FAILURE;
1087 rs.status = PR_FAILURE;
1088 }
1089 Index: tps/src/include/processor/RA_Enroll_Processor.h
1090 ===================================================================
1091 --- tps/src/include/processor/RA_Enroll_Processor.h (revision 2471)
1092 +++ tps/src/include/processor/RA_Enroll_Processor.h (working copy)
1093 @@ -50,40 +50,40 @@
1094
1095 class RA_Enroll_Processor : public RA_Processor
1096 {
1097 - public:
1098 - TPS_PUBLIC RA_Enroll_Processor();
1099 - TPS_PUBLIC ~RA_Enroll_Processor();
1100 - public:
1101 - int ParsePublicKeyBlob(unsigned char blob,
1102 - unsigned char
challenge,
1103 - SECKEYPublicKey pk);
1104 - RA_Status DoEnrollment(AuthParams
login, RA_Session session,
1105 - CERTCertificate
certificates,
1106 - char
origins,
1107 - char
ktypes,
1108 - int pkcs11obj,
1109 - PKCS11Obj * pkcs_objx,
1110 - NameValueSet
extensions,
1111 - int index, int keyTypeNum,
1112 - int start_progress,
1113 - int end_progress,
1114 - Secure_Channel channel, Buffer wrapped_challenge,
1115 - const char tokenType,
1116 - const char
keyType,
1117 - Buffer key_check,
1118 - Buffer
plaintext_challenge,
1119 - const char cuid,
1120 - const char
msn,
1121 - const char khex,
1122 - TokenKeyType key_type,
1123 - const char
profileId,
1124 - const char userid,
1125 - const char
cert_id,
1126 - const char publisher_id,
1127 - const char
cert_attr_id,
1128 - const char pri_attr_id,
1129 - const char
pub_attr_id,
1130 - BYTE se_p1, BYTE se_p2, int keysize, const char connid, const char keyTypePrefix,char * applet_version);
1131 + public:
1132 + TPS_PUBLIC RA_Enroll_Processor();
1133 + TPS_PUBLIC ~RA_Enroll_Processor();
1134 + public:
1135 + int ParsePublicKeyBlob(unsigned char blob,
1136 + unsigned char
challenge,
1137 + SECKEYPublicKey pk);
1138 + RA_Status DoEnrollment(AuthParams
login, RA_Session session,
1139 + CERTCertificate
certificates,
1140 + char
origins,
1141 + char
ktypes,
1142 + int pkcs11obj,
1143 + PKCS11Obj * pkcs_objx,
1144 + NameValueSet
extensions,
1145 + int index, int keyTypeNum,
1146 + int start_progress,
1147 + int end_progress,
1148 + Secure_Channel channel, Buffer wrapped_challenge,
1149 + const char tokenType,
1150 + const char
keyType,
1151 + Buffer key_check,
1152 + Buffer
plaintext_challenge,
1153 + const char cuid,
1154 + const char
msn,
1155 + const char khex,
1156 + TokenKeyType key_type,
1157 + const char
profileId,
1158 + const char userid,
1159 + const char
cert_id,
1160 + const char publisher_id,
1161 + const char
cert_attr_id,
1162 + const char pri_attr_id,
1163 + const char
pub_attr_id,
1164 + BYTE se_p1, BYTE se_p2, BYTE algorithm, int keysize, const char connid, const char keyTypePrefix,char * applet_version);
1165
1166 bool DoRenewal(const char connid,
1167 const char
profileId,
1168 Index: tps/src/include/cms/CertEnroll.h
1169 ===================================================================
1170 --- tps/src/include/cms/CertEnroll.h (revision 2471)
1171 +++ tps/src/include/cms/CertEnroll.h (working copy)
1172 @@ -55,8 +55,9 @@
1173 TOKENDB_PUBLIC CertEnroll();
1174 TOKENDB_PUBLIC ~CertEnroll();
1175
1176 +
1177 SECKEYPublicKey ParsePublicKeyBlob(unsigned char * /blob/,
1178 - Buffer * /
challenge/);
1179 + Buffer * /
challenge/, bool isECC);
1180 Buffer
EnrollCertificate(SECKEYPublicKey * /pk_parsed/,
1181 const char profileId,
1182 const char * /
uid/,
1183 @@ -64,12 +65,15 @@
1184 char
error_msg,
1185 SECItem encodedPublicKeyInfo = NULL);
1186 ReturnStatus verifyProof(SECKEYPublicKey /pk/, SECItem /siProof/,
1187 - unsigned short /pkeyb_len/, unsigned char /pkeyb/,
1188 - Buffer
/challenge/);
1189 + unsigned short /pkeyb_len/, unsigned char /pkeyb/,
1190 + Buffer
/challenge/, bool /isECC/);
1191 TOKENDB_PUBLIC Buffer RenewCertificate(PRUint64 serialno, const char connid, const char profileId, char error_msg);
1192 TOKENDB_PUBLIC int RevokeCertificate(const char reason, const char serialno, const char connid, char &status);
1193 TOKENDB_PUBLIC int UnrevokeCertificate(const char serialno, const char connid, char &status);
1194 PSHttpResponse * sendReqToCA(const char
servlet, const char parameters, const char connid);
1195 Buffer * parseResponse(PSHttpResponse * /resp/);
1196 +
1197 + SECKEYECParams * encode_ec_params(char curve);
1198 +
1199 };
1200 #endif /
CERTENROLL_H /
1201 Index: tps/src/include/main/Buffer.h
1202 ===================================================================
1203 --- tps/src/include/main/Buffer.h (revision 2471)
1204 +++ tps/src/include/main/Buffer.h (working copy)
1205 @@ -167,6 +167,9 @@
1206
/
1207 TPS_PUBLIC void replace(unsigned int i, const BYTE cpy, unsigned int n);
1208
1209 + TPS_PUBLIC unsigned char
getBuf();
1210 + TPS_PUBLIC unsigned int getLen();
1211 +
1212 /

1213 * returns a hex version of the buffer
1214 /
1215 Index: tps/src/include/engine/RA.h
1216 ===================================================================
1217 --- tps/src/include/engine/RA.h (revision 2471)
1218 +++ tps/src/include/engine/RA.h (working copy)
1219 @@ -79,6 +79,13 @@
1220 LL_ALL_DATA_IN_PDU = 9
1221 };
1222
1223 +enum RA_Algs {
1224 + ALG_RSA = 1,
1225 + ALG_RSA_CRT = 2,
1226 + ALG_DSA = 3,
1227 + ALG_EC_F2M = 4,
1228 + ALG_EC_FP = 5
1229 +};
1230
1231 #ifdef XP_WIN32
1232 #define TPS_PUBLIC __declspec(dllexport)
1233 @@ -124,12 +131,12 @@
1234 char
kek_kekSessionKey_s,
1235 char
keycheck_s,
1236 const char
connId);
1237 - static void ServerSideKeyGen(RA_Session session, const char cuid,
1238 + static void ServerSideKeyGen(RA_Session session, const char cuid,
1239 const char userid, char kekSessionKey_s,
1240 - char publickey_s,
1241 + char
publickey_s,
1242 char wrappedPrivateKey_s,
1243 char
ivParam_s, const char connId,
1244 - bool archive, int keysize);
1245 + bool archive, int keysize, bool isECC);
1246 static void RecoverKey(RA_Session
session, const char cuid,
1247 const char
userid, char kekSessionKey_s,
1248 char
cert_s, char publickey_s,
1249 @@ -363,6 +370,7 @@
1250 static void CleanupPublishers();
1251 static int Failover(HttpConnection &conn, int len);
1252
1253 + static bool isAlgorithmECC(BYTE algorithm);
1254 TPS_PUBLIC static SECCertificateUsage getCertificateUsage(const char
certusage);
1255 TPS_PUBLIC static bool verifySystemCertByNickname(const char nickname, const char certUsage);
1256 TPS_PUBLIC static bool verifySystemCerts();
1257 Index: tps/src/include/channel/Secure_Channel.h
1258 ===================================================================
1259 --- tps/src/include/channel/Secure_Channel.h (revision 2471)
1260 +++ tps/src/include/channel/Secure_Channel.h (working copy)
1261 @@ -125,10 +125,18 @@
1262 int CreatePKCS11CertAttrs(TokenKeyType type, const char id, const char label, Buffer keyid);
1263 Buffer CreatePKCS11PriKeyAttrsBuffer(TokenKeyType type, const char
id, const char label, Buffer keyid,
1264 Buffer modulus, const char opType, const char tokenType, const char keyTypePrefix);
1265 +
1266 + Buffer CreatePKCS11ECCPriKeyAttrsBuffer(TokenKeyType type, const char id, const char label, Buffer keyid,
1267 + SECKEYECParams
ecParams, const char opType, const char tokenType, const char keyTypePrefix);
1268 +
1269 int CreatePKCS11PriKeyAttrs(TokenKeyType type, const char
id, const char label, Buffer keyid,
1270 Buffer modulus, const char opType, const char tokenType, const char keyTypePrefix);
1271 Buffer CreatePKCS11PubKeyAttrsBuffer(TokenKeyType type, const char id, const char label, Buffer keyid,
1272 Buffer
exponent, Buffer modulus, const char opType, const char tokenType, const char keyTypePrefix);
1273 +
1274 + Buffer CreatePKCS11ECCPubKeyAttrsBuffer(TokenKeyType key_type, const char id, const char label, Buffer keyid, SECKEYECPublicKey publicKey,
1275 + SECKEYECParams ecParams, const char opType, const char tokenType, const char keyTypePrefix);
1276 +
1277 int CreatePKCS11PubKeyAttrs(TokenKeyType type, const char id, const char label, Buffer keyid,
1278 Buffer
exponent, Buffer modulus, const char opType, const char tokenType, const char keyTypePrefix);
1279 APDU_Response SendTokenAPU(APDU apdu);
1280 Index: tps/src/main/Buffer.cpp
1281 ===================================================================
1282 --- tps/src/main/Buffer.cpp (revision 2471)
1283 +++ tps/src/main/Buffer.cpp (working copy)
1284 @@ -222,6 +222,16 @@
1285 return s;
1286 }
1287
1288 +TPS_PUBLIC unsigned char
1289 +Buffer::getBuf() {
1290 + return (unsigned char
) buf;
1291 +}
1292 +
1293 +TPS_PUBLIC unsigned int
1294 +Buffer::getLen() {
1295 + return len;
1296 +}
1297 +
1298 TPS_PUBLIC char *
1299 Buffer::toHex()
1300 {
1301 Index: tps/src/main/ObjectSpec.cpp
1302 ===================================================================
1303 --- tps/src/main/ObjectSpec.cpp (revision 2471)
1304 +++ tps/src/main/ObjectSpec.cpp (working copy)
1305 @@ -190,6 +190,7 @@
1306 case CKA_KEY_TYPE:
1307 type = DATATYPE_INTEGER;
1308 data = b->substr(curpos+6, 4);
1309 + found = 1;
1310 / build by PKCS11 /
1311 break;
1312 case CKA_CLASS:
1313 @@ -208,6 +209,18 @@
1314 data = b->substr(curpos+6, 4);
1315 / build by PKCS11 /
1316 break;
1317 +
1318 + case CKA_EC_PARAMS:
1319 + type = DATATYPE_STRING;
1320 + data = b->substr(curpos+6, attribute_size);
1321 + found = 1;
1322 + break;
1323 +
1324 + case CKA_EC_POINT:
1325 + type = DATATYPE_STRING;
1326 + data = b->substr(curpos+6, attribute_size);
1327 + found = 1;
1328 + break;
1329 default:
1330 RA::Debug("ObjectSpec::ParseKeyBlob",
1331 "skipped attribute_id = %lx",
1332 Index: tps/src/engine/RA.cpp
1333 ===================================================================
1334 --- tps/src/engine/RA.cpp (revision 2471)
1335 +++ tps/src/engine/RA.cpp (working copy)
1336 @@ -1287,7 +1287,7 @@
1337 char
publicKey_s,
1338 char wrappedPrivateKey_s,
1339 char
ivParam_s, const char connId,
1340 - bool archive, int keysize)
1341 + bool archive, int keysize, bool isECC)
1342 {
1343
1344 const char
FN="RA::ServerSideKeyGen";
1345 @@ -1357,8 +1357,26 @@
1346 RA::Debug(LL_PER_CONNECTION, FN,
1347 "wrappedDESKey_s=%s", wrappedDESKey_s);
1348
1349 - PR_snprintf((char )body, MAX_BODY_LEN,
1350 - "archive=%s&CUID=%s&userid=%s&keysize=%d&drm_trans_desKey=%s",archive?"true":"false",cuid, userid, keysize, wrappedDESKey_s);
1351 + if (isECC) {
1352 + char
eckeycurve = NULL;
1353 + if (keysize == 521) {
1354 + eckeycurve = "nistp521";
1355 + } else if (keysize == 384) {
1356 + eckeycurve = "nistp384";
1357 + } else if (keysize == 256) {
1358 + eckeycurve = "nistp256";
1359 + } else {
1360 + RA::Debug(LL_PER_CONNECTION, FN,
1361 + "unrecognized ECC keysize %d, setting to nistp256", keysize);
1362 + keysize = 256;
1363 + eckeycurve = "nistp256";
1364 + }
1365 + PR_snprintf((char )body, MAX_BODY_LEN,
1366 + "archive=%s&CUID=%s&userid=%s&keytype=EC&eckeycurve=%s&drm_trans_desKey=%s",archive?"true":"false",cuid, userid, eckeycurve, wrappedDESKey_s);
1367 + } else {
1368 + PR_snprintf((char
)body, MAX_BODY_LEN,
1369 + "archive=%s&CUID=%s&userid=%s&keysize=%d&keytype=RSA&drm_trans_desKey=%s",archive?"true":"false",cuid, userid, keysize, wrappedDESKey_s);
1370 + }
1371 RA::Debug(LL_PER_CONNECTION, FN,
1372 "sending to DRM: query=%s", body);
1373
1374 @@ -3612,3 +3630,15 @@
1375 return newKey;
1376 }
1377
1378 +bool RA::isAlgorithmECC(BYTE alg)
1379 +{
1380 + bool result = false;
1381 +
1382 + if (alg == ALG_EC_F2M || alg == ALG_EC_FP)
1383 + result = true;
1384 +
1385 + RA::Debug(LL_PER_SERVER, "RA::isAlgorithmECC", " alg: %d result: %d", alg, result);
1386 +
1387 + return result;
1388 +}
1389 +
1390 Index: tps/src/channel/Secure_Channel.cpp
1391 ===================================================================
1392 --- tps/src/channel/Secure_Channel.cpp (revision 2471)
1393 +++ tps/src/channel/Secure_Channel.cpp (working copy)
1394 @@ -38,6 +38,7 @@
1395 #include "apdu/Read_Object_APDU.h"
1396 #include "apdu/Write_Object_APDU.h"
1397 #include "apdu/Generate_Key_APDU.h"
1398 +#include "apdu/Generate_Key_ECC_APDU.h"
1399 #include "apdu/Put_Key_APDU.h"
1400 #include "apdu/Delete_File_APDU.h"
1401 #include "apdu/Load_File_APDU.h"
1402 @@ -142,6 +143,7 @@
1403 }
1404 }
1405
1406 + RA::Debug(LL_PER_PDU,"Secure_Channel::ComputeAPDU","Completed apdu.");
1407 rc = 1;
1408 loser:
1409 if( mac != NULL ) {
1410 @@ -180,6 +182,8 @@
1411 apdu->SetMAC(mac);
1412 m_icv =
mac;
1413
1414 + RA::DebugBuffer("Secure_Channel::ComputeAPDUMac ", "mac",
1415 + mac);
1416 return mac;
1417 } / EncodeAPDUMac /
1418
1419 @@ -1340,6 +1344,8 @@
1420 {
1421 int rc = -1;
1422 Generate_Key_APDU generate_key_apdu = NULL;
1423 + Generate_Key_ECC_APDU
generate_key_ecc_apdu = NULL;
1424 +
1425 APDU_Response response = NULL;
1426 RA_Token_PDU_Request_Msg
token_pdu_request_msg = NULL;
1427 RA_Token_PDU_Response_Msg token_pdu_response_msg = NULL;
1428 @@ -1348,9 +1354,19 @@
1429
1430 RA::Debug("Secure_Channel::GenerateKey",
1431 "Secure_Channel::GenerateKey");
1432 - generate_key_apdu = new Generate_Key_APDU(p1, p2, alg, keysize, option,
1433 - alg,
wrapped_challenge, key_check);
1434 - rc = ComputeAPDU(generate_key_apdu);
1435 +
1436 + bool isECC = RA::isAlgorithmECC(alg);
1437 +
1438 + if (isECC) {
1439 + generate_key_ecc_apdu = new Generate_Key_ECC_APDU(p1, p2, alg, keysize, option,
1440 + alg,
wrapped_challenge, key_check);
1441 + rc = ComputeAPDU(generate_key_ecc_apdu);
1442 + } else {
1443 + generate_key_apdu = new Generate_Key_APDU(p1, p2, alg, keysize, option,
1444 + alg,
wrapped_challenge, key_check);
1445 + rc = ComputeAPDU(generate_key_apdu);
1446 + }
1447 +
1448 if (rc == -1)
1449 goto loser;
1450
1451 @@ -1358,8 +1374,15 @@
1452 mac = ComputeAPDUMac(generate_key_apdu);
1453 generate_key_apdu->SetMAC(
mac);
1454 /
1455 - token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
1456 - generate_key_apdu);
1457 +
1458 + if (generate_key_ecc_apdu != NULL ) {
1459 + token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
1460 + generate_key_ecc_apdu);
1461 + } else {
1462 + token_pdu_request_msg = new RA_Token_PDU_Request_Msg(
1463 + generate_key_apdu);
1464 + }
1465 +
1466 m_session->WriteMsg(token_pdu_request_msg);
1467 RA::Debug("Secure_Channel::GenerateKey",
1468 "Sent token_pdu_request_msg");
1469 @@ -2177,9 +2200,9 @@
1470 Buffer b(256); // allocate some space
1471 b.resize(7); // this keeps the allocated space around
1472
1473 - RA::Debug("Secure_Channel::CreatePKCS11CertAttrs", "id=%s", id);
1474 - RA::Debug("Secure_Channel::CreatePKCS11CertAttrs", "label=%s", label);
1475 - RA::DebugBuffer("Secure_Channel::CreatePKCS11CertAttrs", "keyid", keyid);
1476 + RA::Debug("Secure_Channel::CreatePKCS11CertAttrsBuffer", "id=%s", id);
1477 + RA::Debug("Secure_Channel::CreatePKCS11CertAttrsBuffer", "label=%s", label);
1478 + RA::DebugBuffer("Secure_Channel::CreatePKCS11CertAttrsBuffer", "keyid", keyid);
1479 AppendAttribute(b, CKA_LABEL, strlen(label), (BYTE
)label);
1480 // hash of pubk
1481 AppendAttribute(b, CKA_ID, keyid->size(), (BYTE)keyid);
1482 @@ -2301,6 +2324,7 @@
1483 M 00020001010000000100010100000100
1484 M 00040000000000000000000403000000
1485 /
1486 +
1487 Buffer Secure_Channel::CreatePKCS11PriKeyAttrsBuffer(TokenKeyType key_type, const char
id, const char label, Buffer keyid,
1488 Buffer modulus, const char opType, const char tokenType, const char keyTypePrefix)
1489 {
1490 @@ -2383,6 +2407,39 @@
1491
1492 } / CreatePKCS11PriKeyAttrs /
1493
1494 +Buffer Secure_Channel::CreatePKCS11ECCPriKeyAttrsBuffer(TokenKeyType type, const char id, const char label, Buffer keyid,
1495 + SECKEYECParams
ecParams, const char opType, const char tokenType, const char keyTypePrefix)
1496 +{
1497 +
1498 + BYTE keytype[8] = { 3,0,0,0 };
1499 + BYTE p11class[4] = { 3,0,0,0 };
1500 +
1501 + Buffer b(256); // allocate some space
1502 + b.resize(7); // this keeps the allocated space around
1503 +
1504 + if (label != NULL)
1505 + RA::Debug("Secure_Channel::CreatePKCS11ECCPriKeyAttrsBuffer", "label=%s", label);
1506 + if (keyid != NULL)
1507 + RA::DebugBuffer("Secure_Channel::CreatePKCS11ECCPriKeyAttrsBuffer", "keyid", keyid);
1508 + if (id != NULL)
1509 + RA::Debug("Secure_Channel::CreatePKCS11ECCPriKeyAttrsBuffer", "id=%s",id);
1510 +
1511 + AppendAttribute(b,CKA_KEY_TYPE, 4, keytype);
1512 + AppendAttribute(b,CKA_CLASS, 4, p11class );
1513 + // hash of pubk
1514 + AppendAttribute(b,CKA_ID, keyid->size(), (BYTE
)keyid);
1515 +
1516 + AppendAttribute(b,CKA_EC_PARAMS, ecParams->len, ecParams->data);
1517 + AppendKeyCapabilities(b, opType, tokenType, keyTypePrefix, "private");
1518 +
1519 + FinalizeBuffer(b, id);
1520 +
1521 + RA::DebugBuffer("Secure_Channel::CreatePKCS11ECCPriKeyAttrsBuffer", "buffer", &b);
1522 +
1523 + return b;
1524 +
1525 +}
1526 +
1527 /

1528 Public Key: (k1)
1529 CKA_PUBLIC_EXPONENT(0x0122)
1530 @@ -2461,6 +2518,43 @@
1531 return b;
1532 } / CreatePKCS11PubKeyAttrs /
1533
1534 +
1535 +Buffer Secure_Channel::CreatePKCS11ECCPubKeyAttrsBuffer(TokenKeyType key_type, const char id, const char label, Buffer keyid,
1536 + SECKEYECPublicKey
publicKey, SECKEYECParams ecParams, const char opType, const char tokenType, const char keyTypePrefix)
1537 +{
1538 + BYTE p11class[4] = { 2,0,0,0 };
1539 + // BYTE ZERO[1] = { 0 };
1540 + // BYTE ONE[1] = { 1 };
1541 + // char configname[256];
1542 +
1543 + BYTE keytype[4] = { 3,0,0,0 };
1544 + Buffer b(256); // allocate some space
1545 + b.resize(7); // this keeps the allocated space around
1546 +
1547 + if (label != NULL)
1548 + RA::Debug("Secure_Channel::CreatePKCS11ECCPubAttrsBuffer", "label=%s", label);
1549 + if (keyid != NULL)
1550 + RA::DebugBuffer("Secure_Channel::CreatePKCS11ECCPubAttrsBuffer", "keyid", keyid);
1551 +
1552 + // XXX TUES
1553 + // hash of pubk
1554 + AppendAttribute(b,CKA_ID, keyid->size(), (BYTE)keyid);
1555 + AppendAttribute(b, CKA_CLASS, 4, p11class ); // type of object
1556 + AppendAttribute(b,CKA_KEY_TYPE, 4, keytype); // CKK_EC key type
1557 + AppendAttribute(b,CKA_EC_PARAMS, ecParams->len, (BYTE ) ecParams->data);
1558 + AppendAttribute(b, CKA_EC_POINT, publicKey->publicValue.len, (BYTE
) publicKey->publicValue.data);
1559 +
1560 + AppendKeyCapabilities(b, opType, tokenType, keyTypePrefix, "public");
1561 +
1562 + FinalizeBuffer(b, id);
1563 +
1564 + RA::DebugBuffer("Secure_Channel::CreatePKCS11ECCPubAttrsBuffer", "buffer", &b);
1565 +
1566 + return b;
1567 +} / CreatePKCS11ECCPubKeyAttrs /
1568 +
1569 +
1570 +
1571 int Secure_Channel::CreatePKCS11PubKeyAttrs(TokenKeyType key_type, const char id, const char label, Buffer keyid,
1572 Buffer
exponent, Buffer modulus, const char opType, const char tokenType, const char keyTypePrefix)
1573 {
1574 Index: kra/src/com/netscape/kra/NetkeyKeygenService.java
1575 ===================================================================
1576 --- kra/src/com/netscape/kra/NetkeyKeygenService.java (revision 2471)
1577 +++ kra/src/com/netscape/kra/NetkeyKeygenService.java (working copy)
1578 @@ -62,7 +62,10 @@
1579 import com.netscape.certsrv.authentication.;
1580 import com.netscape.certsrv.apps.
;
1581 import com.netscape.certsrv.apps.CMS;
1582 +import com.netscape.cmsutil.crypto.CryptoUtil;
1583 +import com.netscape.cms.servlet.key.KeyRecordParser;
1584
1585 +
1586 //for b64 encoding
1587 import org.mozilla.jss.util.Base64OutputStream;
1588 import java.io.ByteArrayOutputStream;
1589 @@ -146,7 +149,7 @@
1590 }
1591
1592 public KeyPair generateKeyPair(
1593 - KeyPairAlgorithm kpAlg, int keySize, PQGParams pqg)
1594 + KeyPairAlgorithm kpAlg, int keySize, String keyCurve, PQGParams pqg)
1595 throws NoSuchAlgorithmException, TokenException, InvalidAlgorithmParameterException,
1596 InvalidParameterException, PQGParamGenException {
1597
1598 @@ -165,20 +168,28 @@
1599 sensitive == true
1600 extractable == true
1601 /
1602 +
1603 KeyPairGenerator kpGen = token.getKeyPairGenerator(kpAlg);
1604 IConfigStore config = CMS.getConfigStore();
1605 IConfigStore kgConfig = config.getSubStore("kra.keygen");
1606 boolean tp = false;
1607 boolean sp = false;
1608 boolean ep = false;
1609 - if (kgConfig != null) {
1610 + if ((kgConfig != null) && (!kgConfig.equals(""))) {
1611 try {
1612 tp = kgConfig.getBoolean("temporaryPairs", false);
1613 sp = kgConfig.getBoolean("sensitivePairs", false);
1614 ep = kgConfig.getBoolean("extractablePairs", false);
1615 + CMS.debug("NetkeyKeygenService: found config store: kra.keygen");
1616 // by default, let nethsm work
1617 if ((tp == false) && (sp == false) && (ep == false)) {
1618 - tp = true;
1619 + if (kpAlg == KeyPairAlgorithm.EC) {
1620 + // set to what works for nethsm
1621 + tp = true;
1622 + sp = false;
1623 + ep = true;
1624 + } else
1625 + tp = true;
1626 }
1627 } catch (Exception e) {
1628 CMS.debug("NetkeyKeygenService: kgConfig.getBoolean failed");
1629 @@ -188,70 +199,111 @@
1630 } else {
1631 // by default, let nethsm work
1632 CMS.debug("NetkeyKeygenService: cannot find config store: kra.keygen, assume temporaryPairs==true");
1633 - tp = true;
1634 + if (kpAlg == KeyPairAlgorithm.EC) {
1635 + // set to what works for nethsm
1636 + tp = true;
1637 + sp = false;
1638 + ep = true;
1639 + } else {
1640 + tp = true;
1641 + }
1642 }
1643 - /
only specified to "true" will it be set /
1644 - if (tp == true) {
1645 - CMS.debug("NetkeyKeygenService: setting temporaryPairs to true");
1646 - kpGen.temporaryPairs(true);
1647 - }
1648 - if (sp == true) {
1649 - CMS.debug("NetkeyKeygenService: setting sensitivePairs to true");
1650 - kpGen.sensitivePairs(true);
1651 - }
1652 - if (ep == true) {
1653 - CMS.debug("NetkeyKeygenService: setting extractablePairs to true");
1654 - kpGen.extractablePairs(true);
1655 - }
1656 +
1657 + if (kpAlg == KeyPairAlgorithm.EC) {
1658 +
1659 + boolean isECDHE = false;
1660 + KeyPair pair = null;
1661 +
1662 + // used with isECDHE == true
1663 + org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage usages_mask_ECDSA[] = {
1664 + org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.DERIVE
1665 + };
1666 +
1667 + // used with isECDHE == false
1668 + org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage usages_mask_ECDH[] = {
1669 + org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN,
1670 + org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage.SIGN_RECOVER
1671 + };
1672 +
1673 + try {
1674 + pair = CryptoUtil.generateECCKeyPair(token.getName(), /
ECC_curve default/ keyCurve ,
1675 + null,
1676 + (isECDHE==true) ? usages_mask_ECDSA: usages_mask_ECDH,
1677 + tp /
temporary/, sp? 1:0 /sensitive/, ep? 1:0 /extractable/);
1678 + CMS.debug("NetkeyKeygenService: after key pair generation" );
1679 + } catch (Exception e) {
1680 + CMS.debug("NetkeyKeygenService: key pair generation with exception:"+e.toString());
1681 + }
1682 + return pair;
1683 +
1684 + } else { // !EC
1685 + //only specified to "true" will it be set
1686 + if (tp == true) {
1687 + CMS.debug("NetkeyKeygenService: setting temporaryPairs to true");
1688 + kpGen.temporaryPairs(true);
1689 + }
1690 +
1691 + if (sp == true) {
1692 + CMS.debug("NetkeyKeygenService: setting sensitivePairs to true");
1693 + kpGen.sensitivePairs(true);
1694 + }
1695 +
1696 + if (ep == true) {
1697 + CMS.debug("NetkeyKeygenService: setting extractablePairs to true");
1698 + kpGen.extractablePairs(true);
1699 + }
1700
1701 - if (kpAlg == KeyPairAlgorithm.DSA) {
1702 - if (pqg == null) {
1703 + if (kpAlg == KeyPairAlgorithm.DSA) {
1704 + if (pqg == null) {
1705 + kpGen.initialize(keySize);
1706 + } else {
1707 + kpGen.initialize(pqg);
1708 + }
1709 + } else {
1710 kpGen.initialize(keySize);
1711 - } else {
1712 - kpGen.initialize(pqg);
1713 }
1714 - } else {
1715 - kpGen.initialize(keySize);
1716 - }
1717
1718 - if (pqg == null) {
1719 - KeyPair kp = null;
1720 - synchronized (new Object()) {
1721 - CMS.debug("NetkeyKeygenService: key pair generation begins");
1722 - kp = kpGen.genKeyPair();
1723 - CMS.debug("NetkeyKeygenService: key pair generation done");
1724 - mKRA.addEntropy(true);
1725 - }
1726 - return kp;
1727 - } else {
1728 - // DSA
1729 - KeyPair kp = null;
1730 + if (pqg == null) {
1731 + KeyPair kp = null;
1732 + synchronized (new Object()) {
1733 + CMS.debug("NetkeyKeygenService: key pair generation begins");
1734 + kp = kpGen.genKeyPair();
1735 + CMS.debug("NetkeyKeygenService: key pair generation done");
1736 + mKRA.addEntropy(true);
1737 + }
1738 + return kp;
1739 + } else {
1740 + // DSA
1741 + KeyPair kp = null;
1742
1743 - /
no DSA for now... netkey prototype
1744 - do {
1745 - // 602548 NSS bug - to overcome it, we use isBadDSAKeyPair
1746 - kp = kpGen.genKeyPair();
1747 + / no DSA for now... netkey prototype
1748 + do {
1749 + // 602548 NSS bug - to overcome it, we use isBadDSAKeyPair
1750 + kp = kpGen.genKeyPair();
1751 + }
1752 + while (isBadDSAKeyPair(kp));
1753 +
/
1754 + return kp;
1755 }
1756 - while (isBadDSAKeyPair(kp));
1757 - /
1758 - return kp;
1759 }
1760 }
1761
1762
1763
1764 public KeyPair generateKeyPair( String alg,
1765 - int keySize, PQGParams pqg) throws EBaseException {
1766 + int keySize, String keyCurve, PQGParams pqg) throws EBaseException {
1767
1768 KeyPairAlgorithm kpAlg = null;
1769
1770 if (alg.equals("RSA"))
1771 kpAlg = KeyPairAlgorithm.RSA;
1772 + else if (alg.equals("EC"))
1773 + kpAlg = KeyPairAlgorithm.EC;
1774 else
1775 kpAlg = KeyPairAlgorithm.DSA;
1776
1777 try {
1778 - KeyPair kp = generateKeyPair( kpAlg, keySize, pqg);
1779 + KeyPair kp = generateKeyPair( kpAlg, keySize, keyCurve, pqg);
1780
1781 return kp;
1782 } catch (InvalidParameterException e) {
1783 @@ -324,7 +376,7 @@
1784 byte[] wrapped_des_key;
1785
1786 byte iv[] = {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1};
1787 - String iv_s ="";
1788 + String iv_s ="";
1789 try {
1790 SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
1791 random.nextBytes(iv);
1792 @@ -332,34 +384,35 @@
1793 CMS.debug("NetkeyKeygenService.serviceRequest: "+ e.toString());
1794 }
1795
1796 - IVParameterSpec algParam = new IVParameterSpec(iv);
1797 + IVParameterSpec algParam = new IVParameterSpec(iv);
1798
1799 wrapped_des_key = null;
1800 - boolean archive = true;
1801 - PK11SymKey sk= null;
1802 - byte[] publicKeyData = null;;
1803 - String PubKey = "";
1804 + boolean archive = true;
1805 + PK11SymKey sk= null;
1806 + byte[] publicKeyData = null;;
1807 + String PubKey = "";
1808
1809 String id = request.getRequestId().toString();
1810 if (id != null) {
1811 auditArchiveID = id.trim();
1812 }
1813
1814 - String rArchive = request.getExtDataInString(IRequest.NETKEY_ATTR_ARCHIVE_FLAG);
1815 - if (rArchive.equals("true")) {
1816 - archive = true;
1817 + String rArchive = request.getExtDataInString(IRequest.NETKEY_ATTR_ARCHIVE_FLAG);
1818 + if (rArchive.equals("true")) {
1819 + archive = true;
1820 CMS.debug("NetkeyKeygenService: serviceRequest " +"archival requested for serverSideKeyGen");
1821 - } else {
1822 - archive = false;
1823 + } else {
1824 + archive = false;
1825 CMS.debug("NetkeyKeygenService: serviceRequest " +"archival not requested for serverSideKeyGen");
1826 }
1827
1828 String rCUID = request.getExtDataInString(IRequest.NETKEY_ATTR_CUID);
1829 String rUserid = request.getExtDataInString(IRequest.NETKEY_ATTR_USERID);
1830 - String rKeysize = request.getExtDataInString(IRequest.NETKEY_ATTR_KEY_SIZE);
1831 - int keysize = Integer.parseInt(rKeysize);
1832 - auditSubjectID=rCUID+":"+rUserid;
1833
1834 + String rKeytype = request.getExtDataInString(IRequest.NETKEY_ATTR_KEY_TYPE);
1835 +
1836 + auditSubjectID=rCUID+":"+rUserid;
1837 +
1838 SessionContext sContext = SessionContext.getContext();
1839 String agentId="";
1840 if (sContext != null) {
1841 @@ -381,15 +434,41 @@
1842 wrapped_des_key = com.netscape.cmsutil.util.Utils.SpecialDecode(rWrappedDesKeyString);
1843 CMS.debug("NetkeyKeygenService: wrapped_des_key specialDecoded");
1844
1845 - // get the token for generating user keys
1846 - CryptoToken keygenToken = mKRA.getKeygenToken();
1847 - if (keygenToken == null) {
1848 - CMS.debug("NetkeyKeygenService: failed getting keygenToken");
1849 - request.setExtData(IRequest.RESULT, Integer.valueOf(10));
1850 - return false;
1851 - } else
1852 - CMS.debug("NetkeyKeygenService: got keygenToken");
1853 +/

1854 + if ((rKeytype == null) || (rKeytype.equals(""))) {
1855 + rKeytype = "RSA";
1856 + }
1857 +/
1858
1859 + if ((rKeytype == null) || (rKeytype.equals(""))) {
1860 + CMS.debug("NetkeyKeygenService: serviceRequest: key type is null");
1861 + rKeytype = "RSA";
1862 + } else
1863 + CMS.debug("NetkeyKeygenService: serviceRequest: key type = "+ rKeytype);
1864 +
1865 + /
for EC, keysize is ignored, only key curve is used /
1866 + String rKeysize = "2048";
1867 + int keysize = 2048;
1868 + String rKeycurve = "nistp256";
1869 + if (rKeytype.equals("EC")) {
1870 + rKeycurve = request.getExtDataInString(IRequest.NETKEY_ATTR_KEY_EC_CURVE);
1871 + if ((rKeycurve == null) || (rKeycurve.equals(""))) {
1872 + rKeycurve = "nistp256";
1873 + }
1874 + } else {
1875 + rKeysize = request.getExtDataInString(IRequest.NETKEY_ATTR_KEY_SIZE);
1876 + keysize = Integer.parseInt(rKeysize);
1877 + }
1878 +
1879 + // get the token for generating user keys
1880 + CryptoToken keygenToken = mKRA.getKeygenToken();
1881 + if (keygenToken == null) {
1882 + CMS.debug("NetkeyKeygenService: failed getting keygenToken");
1883 + request.setExtData(IRequest.RESULT, Integer.valueOf(10));
1884 + return false;
1885 + } else
1886 + CMS.debug("NetkeyKeygenService: got keygenToken");
1887 +
1888 if ((wrapped_des_key != null) &&
1889 (wrapped_des_key.length > 0)) {
1890
1891 @@ -401,8 +480,10 @@
1892
1893 CMS.debug("NetkeyKeygenService: about to generate key pair");
1894
1895 - keypair = generateKeyPair("RSA"/
alg/,
1896 - keysize /
Integer.parseInt(len)/, null /pqgParams/);
1897 + keypair = generateKeyPair(rKeytype /
rKeytype: "RSA" or "EC" /,
1898 + keysize /
Integer.parseInt(len)/,
1899 + rKeycurve /
for "EC" only /,
1900 + null /
pqgParams/);
1901
1902 if (keypair == null) {
1903 CMS.debug("NetkeyKeygenService: failed generating key pair for "+rCUID+":"+rUserid);
1904 @@ -421,18 +502,20 @@
1905 CMS.debug("NetkeyKeygenService: finished generate key pair for " +rCUID+":"+rUserid);
1906
1907 try {
1908 - publicKeyData = keypair.getPublic().getEncoded();
1909 - if (publicKeyData == null) {
1910 - request.setExtData(IRequest.RESULT, Integer.valueOf(4));
1911 - CMS.debug("NetkeyKeygenService: failed getting publickey encoded");
1912 - return false;
1913 - } else {
1914 - //CMS.debug("NetkeyKeygenService: public key binary length ="+ publicKeyData.length);
1915 - PubKey = base64Encode(publicKeyData);
1916 + publicKeyData = keypair.getPublic().getEncoded();
1917 + if (publicKeyData == null) {
1918 + request.setExtData(IRequest.RESULT, Integer.valueOf(4));
1919 + CMS.debug("NetkeyKeygenService: failed getting publickey encoded");
1920 + return false;
1921 + } else {
1922 + //CMS.debug("NetkeyKeygenService: public key binary length ="+ publicKeyData.length);
1923 + /
url encode /
1924 + PubKey = com.netscape.cmsutil.util.Utils.SpecialEncode(publicKeyData);
1925 + CMS.debug("NetkeyKeygenService: EC PubKey special encoded");
1926
1927 - //CMS.debug("NetkeyKeygenService: public key length =" + PubKey.length());
1928 - request.setExtData("public_key", PubKey);
1929 - }
1930 + //CMS.debug("NetkeyKeygenService: public key length =" + PubKey.length());
1931 + request.setExtData("public_key", PubKey);
1932 + }
1933
1934 auditMessage = CMS.getLogMessage(
1935 LOGGING_SIGNED_AUDIT_SERVER_SIDE_KEYGEN_REQUEST_PROCESSED_SUCCESS,
1936 @@ -558,18 +641,52 @@
1937 CMS.debug("NetkeyKeygenService: privatekey recording failed");
1938 return false;
1939 } else
1940 - CMS.debug("NetkeyKeygenService: got key record");
1941 + CMS.debug("NetkeyKeygenService: got key record");
1942
1943 - // we deal with RSA key only
1944 - try {
1945 - RSAPublicKey rsaPublicKey = new RSAPublicKey(publicKeyData);
1946 + if (rKeytype.equals("RSA")) {
1947 + try {
1948 + RSAPublicKey rsaPublicKey = new RSAPublicKey(publicKeyData);
1949
1950 - rec.setKeySize(Integer.valueOf(rsaPublicKey.getKeySize()));
1951 - } catch (InvalidKeyException e) {
1952 - request.setExtData(IRequest.RESULT, Integer.valueOf(11));
1953 - CMS.debug("NetkeyKeygenService: failed:InvalidKeyException");
1954 - return false;
1955 - }
1956 + rec.setKeySize(Integer.valueOf(rsaPublicKey.getKeySize()));
1957 + } catch (InvalidKeyException e) {
1958 + request.setExtData(IRequest.RESULT, Integer.valueOf(11));
1959 + CMS.debug("NetkeyKeygenService: failed:InvalidKeyException");
1960 + return false;
1961 + }
1962 + } else if (rKeytype.equals("EC")) {
1963 + CMS.debug("NetkeyKeygenService: alg is EC");
1964 + String oidDescription = "UNDETERMINED";
1965 + // for KeyRecordParser
1966 + MetaInfo metaInfo = new MetaInfo();
1967 +
1968 + try {
1969 + byte curve[] =
1970 + ASN1Util.getECCurveBytesByX509PublicKeyBytes(publicKeyData,
1971 + false /
without tag and size /);
1972 + if (curve.length != 0) {
1973 + oidDescription = ASN1Util.getOIDdescription(curve);
1974 + } else {
1975 + /
this is to be used by derdump /
1976 + byte curveTS[] =
1977 + ASN1Util.getECCurveBytesByX509PublicKeyBytes(publicKeyData,
1978 + true /
with tag and size */);
1979 + if (curveTS.length != 0) {
1980 + oidDescription = CMS.BtoA(curveTS);
1981 + }
1982 + }
1983 + } catch (Exception e) {
1984 + CMS.debug("NetkeyKeygenService: ASN1Util.getECCurveBytesByX509PublicKeyByte() throws exception: "+ e.toString());
1985 + CMS.debug("NetkeyKeygenService: exception allowed. continue");
1986 + }
1987 +
1988 + metaInfo.set(KeyRecordParser.OUT_KEY_EC_CURVE,
1989 + oidDescription);
1990 +
1991 + rec.set(IKeyRecord.ATTR_META_INFO, metaInfo);
1992 + // key size does not apply to EC;
1993 + rec.setKeySize(-1);
1994 + }
1995 +
1996 //??
1997 IKeyRepository storage = mKRA.getKeyRepository();
1998 BigInteger serialNo = storage.getNextSerialNumber();

Dogtag PKI is moving from Pagure issues to GitHub issues. This means that existing or new
issues will be reported and tracked through Dogtag PKI's GitHub Issue tracker.

This issue has been cloned to GitHub and is available here:
https://github.com/dogtagpki/pki/issues/875

If you want to receive further updates on the issue, please navigate to the
GitHub issue and click on Subscribe button.

Thank you for understanding, and we apologize for any inconvenience.

Metadata