PageRenderTime 74ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 1ms

/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c

https://bitbucket.org/nexenta/illumos-nexenta
C | 4225 lines | 3368 code | 563 blank | 294 comment | 1167 complexity | dcbe07d60444ede06d478e15ac2f7ed2 MD5 | raw file
Possible License(s): LGPL-2.0, BSD-3-Clause-No-Nuclear-License-2014, MPL-2.0-no-copyleft-exception, AGPL-1.0, GPL-3.0, LGPL-3.0, BSD-2-Clause, AGPL-3.0, BSD-3-Clause, GPL-2.0, LGPL-2.1, 0BSD

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * CDDL HEADER START
  3. *
  4. * The contents of this file are subject to the terms of the
  5. * Common Development and Distribution License (the "License").
  6. * You may not use this file except in compliance with the License.
  7. *
  8. * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  9. * or http://www.opensolaris.org/os/licensing.
  10. * See the License for the specific language governing permissions
  11. * and limitations under the License.
  12. *
  13. * When distributing Covered Code, include this CDDL HEADER in each
  14. * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15. * If applicable, add the following below this CDDL HEADER, with the
  16. * fields enclosed by brackets "[]" replaced with your own identifying
  17. * information: Portions Copyright [yyyy] [name of copyright owner]
  18. *
  19. * CDDL HEADER END
  20. *
  21. * PKCS11 token KMF Plugin
  22. *
  23. * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  24. */
  25. #include <stdio.h> /* debugging only */
  26. #include <errno.h>
  27. #include <values.h>
  28. #include <kmfapiP.h>
  29. #include <ber_der.h>
  30. #include <fcntl.h>
  31. #include <sha1.h>
  32. #include <bignum.h>
  33. #include <cryptoutil.h>
  34. #include <security/cryptoki.h>
  35. #include <security/pkcs11.h>
  36. #define DEV_RANDOM "/dev/random"
  37. #define SETATTR(t, n, atype, value, size) \
  38. t[n].type = atype; \
  39. t[n].pValue = (CK_BYTE *)value; \
  40. t[n].ulValueLen = (CK_ULONG)size;
  41. #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; \
  42. h->lasterr.errcode = c;
  43. typedef struct _objlist {
  44. CK_OBJECT_HANDLE handle;
  45. struct _objlist *next;
  46. } OBJLIST;
  47. static KMF_RETURN
  48. search_certs(KMF_HANDLE_T, char *, char *, char *, KMF_BIGINT *,
  49. boolean_t, KMF_CERT_VALIDITY, OBJLIST **, uint32_t *);
  50. static CK_RV
  51. getObjectLabel(KMF_HANDLE_T, CK_OBJECT_HANDLE, char **);
  52. static KMF_RETURN
  53. keyObj2RawKey(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_KEY_DATA **);
  54. static KMF_RETURN
  55. create_generic_secret_key(KMF_HANDLE_T,
  56. int, KMF_ATTRIBUTE *, CK_OBJECT_HANDLE *);
  57. KMF_RETURN
  58. KMFPK11_ConfigureKeystore(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  59. KMF_RETURN
  60. KMFPK11_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  61. void
  62. KMFPK11_FreeKMFCert(KMF_HANDLE_T,
  63. KMF_X509_DER_CERT *kmf_cert);
  64. KMF_RETURN
  65. KMFPK11_StoreCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  66. KMF_RETURN
  67. KMFPK11_ImportCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  68. KMF_RETURN
  69. KMFPK11_DeleteCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  70. KMF_RETURN
  71. KMFPK11_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  72. KMF_RETURN
  73. KMFPK11_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  74. KMF_RETURN
  75. KMFPK11_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  76. KMF_RETURN
  77. KMFPK11_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *);
  78. KMF_RETURN
  79. KMFPK11_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
  80. KMF_DATA *, KMF_DATA *);
  81. KMF_RETURN
  82. KMFPK11_GetErrorString(KMF_HANDLE_T, char **);
  83. KMF_RETURN
  84. KMFPK11_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  85. KMF_RETURN
  86. KMFPK11_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
  87. KMF_DATA *, KMF_DATA *);
  88. KMF_RETURN
  89. KMFPK11_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  90. KMF_RETURN
  91. KMFPK11_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  92. KMF_RETURN
  93. KMFPK11_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *);
  94. KMF_RETURN
  95. KMFPK11_SetTokenPin(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  96. KMF_RETURN
  97. KMFPK11_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  98. static
  99. KMF_PLUGIN_FUNCLIST pk11token_plugin_table =
  100. {
  101. 1, /* Version */
  102. KMFPK11_ConfigureKeystore,
  103. KMFPK11_FindCert,
  104. KMFPK11_FreeKMFCert,
  105. KMFPK11_StoreCert,
  106. KMFPK11_ImportCert,
  107. NULL, /* ImportCRL */
  108. KMFPK11_DeleteCert,
  109. NULL, /* DeleteCRL */
  110. KMFPK11_CreateKeypair,
  111. KMFPK11_FindKey,
  112. KMFPK11_EncodePubKeyData,
  113. KMFPK11_SignData,
  114. KMFPK11_DeleteKey,
  115. NULL, /* ListCRL */
  116. NULL, /* FindCRL */
  117. NULL, /* FindCertInCRL */
  118. KMFPK11_GetErrorString,
  119. KMFPK11_FindPrikeyByCert,
  120. KMFPK11_DecryptData,
  121. KMFPK11_ExportPK12,
  122. KMFPK11_CreateSymKey,
  123. KMFPK11_GetSymKeyValue,
  124. KMFPK11_SetTokenPin,
  125. KMFPK11_StoreKey,
  126. NULL /* Finalize */
  127. };
  128. KMF_PLUGIN_FUNCLIST *
  129. KMF_Plugin_Initialize()
  130. {
  131. return (&pk11token_plugin_table);
  132. }
  133. KMF_RETURN
  134. KMFPK11_ConfigureKeystore(KMF_HANDLE_T handle,
  135. int numattr, KMF_ATTRIBUTE *attrlist)
  136. {
  137. KMF_RETURN rv = KMF_OK;
  138. char *label;
  139. boolean_t readonly = B_TRUE;
  140. label = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr);
  141. if (label == NULL) {
  142. return (KMF_ERR_BAD_PARAMETER);
  143. }
  144. /* "readonly" is optional. Default is TRUE */
  145. (void) kmf_get_attr(KMF_READONLY_ATTR, attrlist, numattr,
  146. (void *)&readonly, NULL);
  147. rv = kmf_select_token(handle, label, readonly);
  148. return (rv);
  149. }
  150. static KMF_RETURN
  151. pk11_authenticate(KMF_HANDLE_T handle,
  152. KMF_CREDENTIAL *cred)
  153. {
  154. CK_RV ck_rv = CKR_OK;
  155. CK_SESSION_HANDLE hSession = (CK_SESSION_HANDLE)handle->pk11handle;
  156. if (hSession == NULL)
  157. return (KMF_ERR_NO_TOKEN_SELECTED);
  158. if (cred == NULL || cred->cred == NULL) {
  159. return (KMF_ERR_BAD_PARAMETER);
  160. }
  161. if ((ck_rv = C_Login(hSession, CKU_USER, (uchar_t *)cred->cred,
  162. cred->credlen)) != CKR_OK) {
  163. if (ck_rv != CKR_USER_ALREADY_LOGGED_IN) {
  164. handle->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
  165. handle->lasterr.errcode = ck_rv;
  166. return (KMF_ERR_AUTH_FAILED);
  167. }
  168. }
  169. return (KMF_OK);
  170. }
  171. static KMF_RETURN
  172. PK11Cert2KMFCert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE hObj,
  173. KMF_X509_DER_CERT *kmfcert)
  174. {
  175. KMF_RETURN rv = 0;
  176. CK_RV ckrv = CKR_OK;
  177. CK_CERTIFICATE_TYPE cktype;
  178. CK_OBJECT_CLASS class;
  179. CK_ULONG subject_len, value_len, issuer_len, serno_len, id_len;
  180. CK_BYTE *subject = NULL, *value = NULL;
  181. char *label = NULL;
  182. CK_ATTRIBUTE templ[10];
  183. (void) memset(templ, 0, 10 * sizeof (CK_ATTRIBUTE));
  184. SETATTR(templ, 0, CKA_CLASS, &class, sizeof (class));
  185. /* Is this a certificate object ? */
  186. ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1);
  187. if (ckrv != CKR_OK || class != CKO_CERTIFICATE) {
  188. SET_ERROR(kmfh, ckrv);
  189. return (KMF_ERR_INTERNAL);
  190. }
  191. SETATTR(templ, 0, CKA_CERTIFICATE_TYPE, &cktype, sizeof (cktype));
  192. ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1);
  193. if (ckrv != CKR_OK || cktype != CKC_X_509) {
  194. SET_ERROR(kmfh, ckrv);
  195. return (ckrv);
  196. } else {
  197. int i = 0;
  198. /* What attributes are available and how big are they? */
  199. subject_len = issuer_len = serno_len = id_len = value_len = 0;
  200. SETATTR(templ, i, CKA_SUBJECT, NULL, subject_len);
  201. i++;
  202. SETATTR(templ, i, CKA_ISSUER, NULL, issuer_len);
  203. i++;
  204. SETATTR(templ, i, CKA_SERIAL_NUMBER, NULL, serno_len);
  205. i++;
  206. SETATTR(templ, i, CKA_ID, NULL, id_len);
  207. i++;
  208. SETATTR(templ, i, CKA_VALUE, NULL, value_len);
  209. i++;
  210. /*
  211. * Query the object with NULL values in the pValue spot
  212. * so we know how much space to allocate for each field.
  213. */
  214. ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, i);
  215. if (ckrv != CKR_OK) {
  216. SET_ERROR(kmfh, ckrv);
  217. return (KMF_ERR_INTERNAL); /* TODO - Error messages ? */
  218. }
  219. subject_len = templ[0].ulValueLen;
  220. issuer_len = templ[1].ulValueLen;
  221. serno_len = templ[2].ulValueLen;
  222. id_len = templ[3].ulValueLen;
  223. value_len = templ[4].ulValueLen;
  224. /*
  225. * For PKCS#11 CKC_X_509 certificate objects,
  226. * the following attributes must be defined.
  227. * CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER,
  228. * CKA_VALUE.
  229. */
  230. if (subject_len == 0 || issuer_len == 0 ||
  231. serno_len == 0 || value_len == 0) {
  232. return (KMF_ERR_INTERNAL);
  233. }
  234. /* Only fetch the value field if we are saving the data */
  235. if (kmfcert != NULL) {
  236. int i = 0;
  237. value = malloc(value_len);
  238. if (value == NULL) {
  239. rv = KMF_ERR_MEMORY;
  240. goto errout;
  241. }
  242. SETATTR(templ, i, CKA_VALUE, value, value_len);
  243. i++;
  244. /* re-query the object with room for the value attr */
  245. ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj,
  246. templ, i);
  247. if (ckrv != CKR_OK) {
  248. SET_ERROR(kmfh, ckrv);
  249. rv = KMF_ERR_INTERNAL;
  250. goto errout;
  251. }
  252. kmfcert->certificate.Data = value;
  253. kmfcert->certificate.Length = value_len;
  254. kmfcert->kmf_private.flags |= KMF_FLAG_CERT_SIGNED;
  255. kmfcert->kmf_private.keystore_type =
  256. KMF_KEYSTORE_PK11TOKEN;
  257. ckrv = getObjectLabel(kmfh, hObj, &label);
  258. if (ckrv == CKR_OK && label != NULL) {
  259. kmfcert->kmf_private.label = (char *)label;
  260. }
  261. rv = KMF_OK;
  262. }
  263. }
  264. errout:
  265. if (rv != KMF_OK) {
  266. if (subject)
  267. free(subject);
  268. if (value)
  269. free(value);
  270. if (kmfcert) {
  271. kmfcert->certificate.Data = NULL;
  272. kmfcert->certificate.Length = 0;
  273. }
  274. }
  275. return (rv);
  276. }
  277. static void
  278. free_objlist(OBJLIST *head)
  279. {
  280. OBJLIST *temp = head;
  281. while (temp != NULL) {
  282. head = head->next;
  283. free(temp);
  284. temp = head;
  285. }
  286. }
  287. /*
  288. * The caller should make sure that the templ->pValue is NULL since
  289. * it will be overwritten below.
  290. */
  291. static KMF_RETURN
  292. get_attr(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj,
  293. CK_ATTRIBUTE *templ)
  294. {
  295. CK_RV rv;
  296. rv = C_GetAttributeValue(kmfh->pk11handle, obj, templ, 1);
  297. if (rv != CKR_OK) {
  298. SET_ERROR(kmfh, rv);
  299. return (KMF_ERR_INTERNAL);
  300. }
  301. if (templ->ulValueLen > 0) {
  302. templ->pValue = malloc(templ->ulValueLen);
  303. if (templ->pValue == NULL)
  304. return (KMF_ERR_MEMORY);
  305. rv = C_GetAttributeValue(kmfh->pk11handle, obj, templ, 1);
  306. if (rv != CKR_OK) {
  307. SET_ERROR(kmfh, rv);
  308. return (KMF_ERR_INTERNAL);
  309. }
  310. }
  311. return (KMF_OK);
  312. }
  313. /*
  314. * Match a certificate with an issuer and/or subject name.
  315. * This is tricky because we cannot reliably compare DER encodings
  316. * because RDNs may have their AV-pairs in different orders even
  317. * if the values are the same. You must compare individual
  318. * AV pairs for the RDNs.
  319. *
  320. * RETURN: 0 for a match, non-zero for a non-match.
  321. */
  322. static KMF_RETURN
  323. matchcert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj,
  324. KMF_X509_NAME *issuer, KMF_X509_NAME *subject)
  325. {
  326. KMF_RETURN rv = KMF_OK;
  327. CK_ATTRIBUTE certattr;
  328. KMF_DATA name;
  329. KMF_X509_NAME dn;
  330. if (issuer->numberOfRDNs > 0) {
  331. certattr.type = CKA_ISSUER;
  332. certattr.pValue = NULL;
  333. certattr.ulValueLen = 0;
  334. rv = get_attr(kmfh, obj, &certattr);
  335. if (rv == KMF_OK) {
  336. name.Data = certattr.pValue;
  337. name.Length = certattr.ulValueLen;
  338. rv = DerDecodeName(&name, &dn);
  339. if (rv == KMF_OK) {
  340. rv = kmf_compare_rdns(issuer, &dn);
  341. kmf_free_dn(&dn);
  342. }
  343. free(certattr.pValue);
  344. }
  345. if (rv != KMF_OK)
  346. return (rv);
  347. }
  348. if (subject->numberOfRDNs > 0) {
  349. certattr.type = CKA_SUBJECT;
  350. certattr.pValue = NULL;
  351. certattr.ulValueLen = 0;
  352. rv = get_attr(kmfh, obj, &certattr);
  353. if (rv == KMF_OK) {
  354. name.Data = certattr.pValue;
  355. name.Length = certattr.ulValueLen;
  356. rv = DerDecodeName(&name, &dn);
  357. if (rv == KMF_OK) {
  358. rv = kmf_compare_rdns(subject, &dn);
  359. kmf_free_dn(&dn);
  360. }
  361. free(certattr.pValue);
  362. }
  363. }
  364. return (rv);
  365. }
  366. /*
  367. * delete "curr" node from the "newlist".
  368. */
  369. static void
  370. pk11_delete_obj_from_list(OBJLIST **newlist,
  371. OBJLIST **prev, OBJLIST **curr)
  372. {
  373. if (*curr == *newlist) {
  374. /* first node in the list */
  375. *newlist = (*curr)->next;
  376. *prev = (*curr)->next;
  377. free(*curr);
  378. *curr = *newlist;
  379. } else {
  380. (*prev)->next = (*curr)->next;
  381. free(*curr);
  382. *curr = (*prev)->next;
  383. }
  384. }
  385. /*
  386. * search_certs
  387. *
  388. * Because this code is shared by the FindCert and
  389. * DeleteCert functions, put it in a separate routine
  390. * to save some work and make code easier to debug and
  391. * read.
  392. */
  393. static KMF_RETURN
  394. search_certs(KMF_HANDLE_T handle,
  395. char *label, char *issuer, char *subject, KMF_BIGINT *serial,
  396. boolean_t private, KMF_CERT_VALIDITY validity,
  397. OBJLIST **objlist, uint32_t *numobj)
  398. {
  399. KMF_RETURN rv = KMF_OK;
  400. CK_RV ckrv = CKR_OK;
  401. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  402. CK_ATTRIBUTE templ[10];
  403. CK_BBOOL true = TRUE;
  404. CK_OBJECT_CLASS oclass = CKO_CERTIFICATE;
  405. CK_CERTIFICATE_TYPE ctype = CKC_X_509;
  406. KMF_X509_NAME subjectDN, issuerDN;
  407. int i;
  408. OBJLIST *newlist, *tail;
  409. CK_ULONG num = 0;
  410. uint32_t num_ok_certs = 0; /* number of non-expired or expired certs */
  411. (void) memset(&templ, 0, 10 * sizeof (CK_ATTRIBUTE));
  412. (void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME));
  413. (void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME));
  414. i = 0;
  415. SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true)); i++;
  416. SETATTR(templ, i, CKA_CLASS, &oclass, sizeof (oclass)); i++;
  417. SETATTR(templ, i, CKA_CERTIFICATE_TYPE, &ctype, sizeof (ctype)); i++;
  418. if (label != NULL && strlen(label)) {
  419. SETATTR(templ, i, CKA_LABEL, label, strlen(label));
  420. i++;
  421. }
  422. if (private) {
  423. SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true)); i++;
  424. }
  425. if (issuer != NULL && strlen(issuer)) {
  426. if ((rv = kmf_dn_parser(issuer, &issuerDN)) != KMF_OK)
  427. return (rv);
  428. }
  429. if (subject != NULL && strlen(subject)) {
  430. if ((rv = kmf_dn_parser(subject, &subjectDN)) != KMF_OK)
  431. return (rv);
  432. }
  433. if (serial != NULL && serial->val != NULL && serial->len > 0) {
  434. SETATTR(templ, i, CKA_SERIAL_NUMBER, serial->val, serial->len);
  435. i++;
  436. }
  437. (*numobj) = 0;
  438. *objlist = NULL;
  439. newlist = NULL;
  440. ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, i);
  441. if (ckrv != CKR_OK)
  442. goto cleanup;
  443. tail = newlist = NULL;
  444. while (ckrv == CKR_OK) {
  445. CK_OBJECT_HANDLE tObj;
  446. ckrv = C_FindObjects(kmfh->pk11handle, &tObj, 1, &num);
  447. if (ckrv != CKR_OK || num == 0)
  448. break;
  449. /*
  450. * 'matchcert' returns 0 if subject/issuer match
  451. *
  452. * If no match, move on to the next one
  453. */
  454. if (matchcert(kmfh, tObj, &issuerDN, &subjectDN))
  455. continue;
  456. if (newlist == NULL) {
  457. newlist = malloc(sizeof (OBJLIST));
  458. if (newlist == NULL) {
  459. rv = KMF_ERR_MEMORY;
  460. break;
  461. }
  462. newlist->handle = tObj;
  463. newlist->next = NULL;
  464. tail = newlist;
  465. } else {
  466. tail->next = malloc(sizeof (OBJLIST));
  467. if (tail->next != NULL) {
  468. tail = tail->next;
  469. } else {
  470. rv = KMF_ERR_MEMORY;
  471. break;
  472. }
  473. tail->handle = tObj;
  474. tail->next = NULL;
  475. }
  476. (*numobj)++;
  477. }
  478. ckrv = C_FindObjectsFinal(kmfh->pk11handle);
  479. cleanup:
  480. if (ckrv != CKR_OK) {
  481. SET_ERROR(kmfh, ckrv);
  482. rv = KMF_ERR_INTERNAL;
  483. if (newlist != NULL) {
  484. free_objlist(newlist);
  485. *numobj = 0;
  486. newlist = NULL;
  487. }
  488. } else {
  489. if (validity == KMF_ALL_CERTS) {
  490. *objlist = newlist;
  491. } else {
  492. OBJLIST *node, *prev;
  493. KMF_X509_DER_CERT tmp_kmf_cert;
  494. uint32_t i = 0;
  495. node = prev = newlist;
  496. /*
  497. * Now check to see if any found certificate is expired
  498. * or valid.
  499. */
  500. while (node != NULL && i < (*numobj)) {
  501. (void) memset(&tmp_kmf_cert, 0,
  502. sizeof (KMF_X509_DER_CERT));
  503. rv = PK11Cert2KMFCert(kmfh, node->handle,
  504. &tmp_kmf_cert);
  505. if (rv != KMF_OK) {
  506. goto cleanup1;
  507. }
  508. rv = kmf_check_cert_date(handle,
  509. &tmp_kmf_cert.certificate);
  510. if (validity == KMF_NONEXPIRED_CERTS) {
  511. if (rv == KMF_OK) {
  512. num_ok_certs++;
  513. prev = node;
  514. node = node->next;
  515. } else if (rv ==
  516. KMF_ERR_VALIDITY_PERIOD) {
  517. /*
  518. * expired - remove it from list
  519. */
  520. pk11_delete_obj_from_list(
  521. &newlist, &prev, &node);
  522. } else {
  523. goto cleanup1;
  524. }
  525. }
  526. if (validity == KMF_EXPIRED_CERTS) {
  527. if (rv == KMF_ERR_VALIDITY_PERIOD) {
  528. num_ok_certs++;
  529. prev = node;
  530. node = node->next;
  531. rv = KMF_OK;
  532. } else if (rv == KMF_OK) {
  533. /*
  534. * valid - remove it from list
  535. */
  536. pk11_delete_obj_from_list(
  537. &newlist, &prev, &node);
  538. } else {
  539. goto cleanup1;
  540. }
  541. }
  542. i++;
  543. kmf_free_kmf_cert(handle, &tmp_kmf_cert);
  544. }
  545. *numobj = num_ok_certs;
  546. *objlist = newlist;
  547. }
  548. }
  549. cleanup1:
  550. if (rv != KMF_OK && newlist != NULL) {
  551. free_objlist(newlist);
  552. *numobj = 0;
  553. *objlist = NULL;
  554. }
  555. if (issuer != NULL)
  556. kmf_free_dn(&issuerDN);
  557. if (subject != NULL)
  558. kmf_free_dn(&subjectDN);
  559. return (rv);
  560. }
  561. /*
  562. * The caller may pass a NULL value for kmf_cert below and the function will
  563. * just return the number of certs found (in num_certs).
  564. */
  565. KMF_RETURN
  566. KMFPK11_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
  567. {
  568. KMF_RETURN rv = 0;
  569. uint32_t want_certs;
  570. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  571. OBJLIST *objlist = NULL;
  572. uint32_t *num_certs;
  573. KMF_X509_DER_CERT *kmf_cert = NULL;
  574. char *certlabel = NULL;
  575. char *issuer = NULL;
  576. char *subject = NULL;
  577. KMF_BIGINT *serial = NULL;
  578. KMF_CERT_VALIDITY validity;
  579. KMF_CREDENTIAL *cred = NULL;
  580. boolean_t private;
  581. if (kmfh == NULL)
  582. return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
  583. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  584. return (KMF_ERR_NO_TOKEN_SELECTED);
  585. num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
  586. if (num_certs == NULL)
  587. return (KMF_ERR_BAD_PARAMETER);
  588. if (*num_certs > 0)
  589. want_certs = *num_certs;
  590. else
  591. want_certs = MAXINT; /* count them all */
  592. *num_certs = 0;
  593. /* Get the optional returned certificate list */
  594. kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist,
  595. numattr);
  596. /* Get optional search criteria attributes */
  597. certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
  598. issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
  599. subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
  600. serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
  601. rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
  602. &validity, NULL);
  603. if (rv != KMF_OK) {
  604. validity = KMF_ALL_CERTS;
  605. rv = KMF_OK;
  606. }
  607. rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
  608. (void *)&private, NULL);
  609. if (rv != KMF_OK) {
  610. private = B_FALSE;
  611. rv = KMF_OK;
  612. }
  613. cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
  614. if (cred != NULL) {
  615. rv = pk11_authenticate(handle, cred);
  616. if (rv != KMF_OK)
  617. return (rv);
  618. }
  619. /* Start searching */
  620. rv = search_certs(handle, certlabel, issuer, subject, serial, private,
  621. validity, &objlist, num_certs);
  622. if (rv == KMF_OK && objlist != NULL && kmf_cert != NULL) {
  623. OBJLIST *node = objlist;
  624. int i = 0;
  625. while (node != NULL && i < want_certs) {
  626. rv = PK11Cert2KMFCert(kmfh, node->handle,
  627. &kmf_cert[i]);
  628. i++;
  629. node = node->next;
  630. }
  631. }
  632. if (objlist != NULL)
  633. free_objlist(objlist);
  634. if (*num_certs == 0)
  635. rv = KMF_ERR_CERT_NOT_FOUND;
  636. return (rv);
  637. }
  638. /*ARGSUSED*/
  639. void
  640. KMFPK11_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert)
  641. {
  642. if (kmf_cert != NULL && kmf_cert->certificate.Data != NULL) {
  643. free(kmf_cert->certificate.Data);
  644. kmf_cert->certificate.Data = NULL;
  645. kmf_cert->certificate.Length = 0;
  646. if (kmf_cert->kmf_private.label != NULL) {
  647. free(kmf_cert->kmf_private.label);
  648. kmf_cert->kmf_private.label = NULL;
  649. }
  650. }
  651. }
  652. KMF_RETURN
  653. KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey,
  654. KMF_DATA *eData)
  655. {
  656. KMF_RETURN ret = KMF_OK;
  657. CK_RV rv;
  658. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  659. CK_OBJECT_CLASS ckObjClass = CKO_PUBLIC_KEY;
  660. CK_KEY_TYPE ckKeyType;
  661. KMF_DATA Modulus, Exponent, Prime, Subprime, Base, Value;
  662. KMF_OID *Algorithm;
  663. BerElement *asn1 = NULL;
  664. BerValue *PubKeyParams = NULL, *EncodedKey = NULL;
  665. KMF_X509_SPKI spki;
  666. CK_BYTE ec_params[256], ec_point[256];
  667. CK_ATTRIBUTE rsaTemplate[4];
  668. CK_ATTRIBUTE dsaTemplate[6];
  669. CK_ATTRIBUTE ecdsaTemplate[6];
  670. if (kmfh == NULL)
  671. return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
  672. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  673. return (KMF_ERR_NO_TOKEN_SELECTED);
  674. if (pKey == NULL || pKey->keyp == CK_INVALID_HANDLE)
  675. return (KMF_ERR_BAD_PARAMETER);
  676. (void) memset(&Modulus, 0, sizeof (Modulus));
  677. (void) memset(&Exponent, 0, sizeof (Exponent));
  678. (void) memset(&Prime, 0, sizeof (Prime));
  679. (void) memset(&Subprime, 0, sizeof (Subprime));
  680. (void) memset(&Base, 0, sizeof (Base));
  681. (void) memset(&Value, 0, sizeof (Value));
  682. switch (pKey->keyalg) {
  683. case KMF_RSA:
  684. SETATTR(rsaTemplate, 0, CKA_CLASS, &ckObjClass,
  685. sizeof (ckObjClass));
  686. SETATTR(rsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType,
  687. sizeof (ckKeyType));
  688. SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data,
  689. Modulus.Length);
  690. SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT,
  691. Exponent.Data, Exponent.Length);
  692. /* Get the length of the fields */
  693. rv = C_GetAttributeValue(kmfh->pk11handle,
  694. (CK_OBJECT_HANDLE)pKey->keyp, rsaTemplate, 4);
  695. if (rv != CKR_OK) {
  696. SET_ERROR(kmfh, rv);
  697. return (KMF_ERR_BAD_PARAMETER);
  698. }
  699. Modulus.Length = rsaTemplate[2].ulValueLen;
  700. Modulus.Data = malloc(Modulus.Length);
  701. if (Modulus.Data == NULL)
  702. return (KMF_ERR_MEMORY);
  703. Exponent.Length = rsaTemplate[3].ulValueLen;
  704. Exponent.Data = malloc(Exponent.Length);
  705. if (Exponent.Data == NULL) {
  706. free(Modulus.Data);
  707. return (KMF_ERR_MEMORY);
  708. }
  709. SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data,
  710. Modulus.Length);
  711. SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT,
  712. Exponent.Data, Exponent.Length);
  713. /* Now get the values */
  714. rv = C_GetAttributeValue(kmfh->pk11handle,
  715. (CK_OBJECT_HANDLE)pKey->keyp, rsaTemplate, 4);
  716. if (rv != CKR_OK) {
  717. SET_ERROR(kmfh, rv);
  718. free(Modulus.Data);
  719. free(Exponent.Data);
  720. return (KMF_ERR_BAD_PARAMETER);
  721. }
  722. /*
  723. * This is the KEY algorithm, not the
  724. * signature algorithm.
  725. */
  726. Algorithm = x509_algid_to_algoid(KMF_ALGID_RSA);
  727. if (Algorithm != NULL) {
  728. /* Encode the RSA Key Data */
  729. if ((asn1 = kmfder_alloc()) == NULL) {
  730. free(Modulus.Data);
  731. free(Exponent.Data);
  732. return (KMF_ERR_MEMORY);
  733. }
  734. if (kmfber_printf(asn1, "{II}", Modulus.Data,
  735. Modulus.Length, Exponent.Data,
  736. Exponent.Length) == -1) {
  737. kmfber_free(asn1, 1);
  738. free(Modulus.Data);
  739. free(Exponent.Data);
  740. return (KMF_ERR_ENCODING);
  741. }
  742. if (kmfber_flatten(asn1, &EncodedKey) == -1) {
  743. kmfber_free(asn1, 1);
  744. free(Modulus.Data);
  745. free(Exponent.Data);
  746. return (KMF_ERR_ENCODING);
  747. }
  748. kmfber_free(asn1, 1);
  749. }
  750. free(Exponent.Data);
  751. free(Modulus.Data);
  752. break;
  753. case KMF_DSA:
  754. SETATTR(dsaTemplate, 0, CKA_CLASS, &ckObjClass,
  755. sizeof (ckObjClass));
  756. SETATTR(dsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType,
  757. sizeof (ckKeyType));
  758. SETATTR(dsaTemplate, 2, CKA_PRIME, Prime.Data,
  759. Prime.Length);
  760. SETATTR(dsaTemplate, 3, CKA_SUBPRIME, Subprime.Data,
  761. Subprime.Length);
  762. SETATTR(dsaTemplate, 4, CKA_BASE, Base.Data,
  763. Base.Length);
  764. SETATTR(dsaTemplate, 5, CKA_VALUE, Value.Data,
  765. Value.Length);
  766. /* Get the length of the fields */
  767. rv = C_GetAttributeValue(kmfh->pk11handle,
  768. (CK_OBJECT_HANDLE)pKey->keyp, dsaTemplate, 6);
  769. if (rv != CKR_OK) {
  770. SET_ERROR(kmfh, rv);
  771. return (KMF_ERR_BAD_PARAMETER);
  772. }
  773. Prime.Length = dsaTemplate[2].ulValueLen;
  774. Prime.Data = malloc(Prime.Length);
  775. if (Prime.Data == NULL) {
  776. return (KMF_ERR_MEMORY);
  777. }
  778. Subprime.Length = dsaTemplate[3].ulValueLen;
  779. Subprime.Data = malloc(Subprime.Length);
  780. if (Subprime.Data == NULL) {
  781. free(Prime.Data);
  782. return (KMF_ERR_MEMORY);
  783. }
  784. Base.Length = dsaTemplate[4].ulValueLen;
  785. Base.Data = malloc(Base.Length);
  786. if (Base.Data == NULL) {
  787. free(Prime.Data);
  788. free(Subprime.Data);
  789. return (KMF_ERR_MEMORY);
  790. }
  791. Value.Length = dsaTemplate[5].ulValueLen;
  792. Value.Data = malloc(Value.Length);
  793. if (Value.Data == NULL) {
  794. free(Prime.Data);
  795. free(Subprime.Data);
  796. free(Base.Data);
  797. return (KMF_ERR_MEMORY);
  798. }
  799. SETATTR(dsaTemplate, 2, CKA_PRIME, Prime.Data,
  800. Prime.Length);
  801. SETATTR(dsaTemplate, 3, CKA_SUBPRIME, Subprime.Data,
  802. Subprime.Length);
  803. SETATTR(dsaTemplate, 4, CKA_BASE, Base.Data,
  804. Base.Length);
  805. SETATTR(dsaTemplate, 5, CKA_VALUE, Value.Data,
  806. Value.Length);
  807. /* Now get the values */
  808. rv = C_GetAttributeValue(kmfh->pk11handle,
  809. (CK_OBJECT_HANDLE)pKey->keyp, dsaTemplate, 6);
  810. if (rv != CKR_OK) {
  811. free(Prime.Data);
  812. free(Subprime.Data);
  813. free(Base.Data);
  814. free(Value.Data);
  815. SET_ERROR(kmfh, rv);
  816. return (KMF_ERR_BAD_PARAMETER);
  817. }
  818. /*
  819. * This is the KEY algorithm, not the
  820. * signature algorithm.
  821. */
  822. Algorithm = x509_algid_to_algoid(KMF_ALGID_DSA);
  823. /* Encode the DSA Algorithm Parameters */
  824. if ((asn1 = kmfder_alloc()) == NULL) {
  825. free(Prime.Data);
  826. free(Subprime.Data);
  827. free(Base.Data);
  828. free(Value.Data);
  829. return (KMF_ERR_MEMORY);
  830. }
  831. if (kmfber_printf(asn1, "{III}", Prime.Data,
  832. Prime.Length, Subprime.Data, Subprime.Length,
  833. Base.Data, Base.Length) == -1) {
  834. kmfber_free(asn1, 1);
  835. free(Prime.Data);
  836. free(Subprime.Data);
  837. free(Base.Data);
  838. free(Value.Data);
  839. return (KMF_ERR_ENCODING);
  840. }
  841. if (kmfber_flatten(asn1, &PubKeyParams) == -1) {
  842. kmfber_free(asn1, 1);
  843. free(Prime.Data);
  844. free(Subprime.Data);
  845. free(Base.Data);
  846. free(Value.Data);
  847. return (KMF_ERR_ENCODING);
  848. }
  849. kmfber_free(asn1, 1);
  850. free(Prime.Data);
  851. free(Subprime.Data);
  852. free(Base.Data);
  853. /* Encode the DSA Key Value */
  854. if ((asn1 = kmfder_alloc()) == NULL) {
  855. free(Value.Data);
  856. return (KMF_ERR_MEMORY);
  857. }
  858. if (kmfber_printf(asn1, "I",
  859. Value.Data, Value.Length) == -1) {
  860. kmfber_free(asn1, 1);
  861. free(Value.Data);
  862. return (KMF_ERR_ENCODING);
  863. }
  864. if (kmfber_flatten(asn1, &EncodedKey) == -1) {
  865. kmfber_free(asn1, 1);
  866. free(Value.Data);
  867. return (KMF_ERR_ENCODING);
  868. }
  869. kmfber_free(asn1, 1);
  870. free(Value.Data);
  871. break;
  872. case KMF_ECDSA:
  873. /* The EC_PARAMS are the PubKey algorithm parameters */
  874. PubKeyParams = calloc(1, sizeof (BerValue));
  875. if (PubKeyParams == NULL)
  876. return (KMF_ERR_MEMORY);
  877. EncodedKey = calloc(1, sizeof (BerValue));
  878. if (EncodedKey == NULL) {
  879. free(PubKeyParams);
  880. return (KMF_ERR_MEMORY);
  881. }
  882. SETATTR(ecdsaTemplate, 0, CKA_EC_PARAMS,
  883. &ec_params, sizeof (ec_params));
  884. SETATTR(ecdsaTemplate, 1, CKA_EC_POINT,
  885. &ec_point, sizeof (ec_point));
  886. /* Get the length of the fields */
  887. rv = C_GetAttributeValue(kmfh->pk11handle,
  888. (CK_OBJECT_HANDLE)pKey->keyp,
  889. ecdsaTemplate, 2);
  890. if (rv != CKR_OK) {
  891. SET_ERROR(kmfh, rv);
  892. return (KMF_ERR_BAD_PARAMETER);
  893. }
  894. /* The params are to be used as algorithm parameters */
  895. PubKeyParams->bv_val = (char *)ec_params;
  896. PubKeyParams->bv_len = ecdsaTemplate[0].ulValueLen;
  897. /*
  898. * The EC_POINT is to be used as the subject pub key.
  899. */
  900. EncodedKey->bv_val = (char *)ec_point;
  901. EncodedKey->bv_len = ecdsaTemplate[1].ulValueLen;
  902. /* Use the EC_PUBLIC_KEY OID */
  903. Algorithm = (KMF_OID *)&KMFOID_EC_PUBLIC_KEY;
  904. break;
  905. default:
  906. return (KMF_ERR_BAD_PARAMETER);
  907. }
  908. /* Now, build an SPKI structure for the final encoding step */
  909. spki.algorithm.algorithm = *Algorithm;
  910. if (PubKeyParams != NULL) {
  911. spki.algorithm.parameters.Data =
  912. (uchar_t *)PubKeyParams->bv_val;
  913. spki.algorithm.parameters.Length = PubKeyParams->bv_len;
  914. } else {
  915. spki.algorithm.parameters.Data = NULL;
  916. spki.algorithm.parameters.Length = 0;
  917. }
  918. if (EncodedKey != NULL) {
  919. spki.subjectPublicKey.Data = (uchar_t *)EncodedKey->bv_val;
  920. spki.subjectPublicKey.Length = EncodedKey->bv_len;
  921. } else {
  922. spki.subjectPublicKey.Data = NULL;
  923. spki.subjectPublicKey.Length = 0;
  924. }
  925. /* Finally, encode the entire SPKI record */
  926. ret = DerEncodeSPKI(&spki, eData);
  927. cleanup:
  928. if (EncodedKey) {
  929. if (pKey->keyalg != KMF_ECDSA)
  930. free(EncodedKey->bv_val);
  931. free(EncodedKey);
  932. }
  933. if (PubKeyParams) {
  934. if (pKey->keyalg != KMF_ECDSA)
  935. free(PubKeyParams->bv_val);
  936. free(PubKeyParams);
  937. }
  938. return (ret);
  939. }
  940. static KMF_RETURN
  941. CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert)
  942. {
  943. KMF_RETURN rv = 0;
  944. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  945. KMF_X509_CERTIFICATE *signed_cert_ptr = NULL;
  946. KMF_DATA data;
  947. KMF_DATA Id;
  948. CK_RV ckrv;
  949. CK_ULONG subject_len, issuer_len, serno_len;
  950. CK_BYTE *subject, *issuer, *serial, nullserno;
  951. CK_BBOOL true = TRUE;
  952. CK_CERTIFICATE_TYPE certtype = CKC_X_509;
  953. CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
  954. CK_ATTRIBUTE x509templ[11];
  955. CK_OBJECT_HANDLE hCert = NULL;
  956. int i;
  957. if (kmfh == NULL)
  958. return (KMF_ERR_INTERNAL); /* should not happen */
  959. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  960. return (KMF_ERR_INTERNAL); /* should not happen */
  961. if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0)
  962. return (KMF_ERR_INTERNAL); /* should not happen */
  963. /*
  964. * The data *must* be a DER encoded X.509 certificate.
  965. * Convert it to a CSSM cert and then parse the fields so
  966. * the PKCS#11 attributes can be filled in correctly.
  967. */
  968. rv = DerDecodeSignedCertificate((const KMF_DATA *)pcert,
  969. &signed_cert_ptr);
  970. if (rv != KMF_OK) {
  971. return (KMF_ERR_ENCODING);
  972. }
  973. /*
  974. * Encode fields into PKCS#11 attributes.
  975. */
  976. /* Get the subject name */
  977. rv = DerEncodeName(&signed_cert_ptr->certificate.subject, &data);
  978. if (rv == KMF_OK) {
  979. subject = data.Data;
  980. subject_len = data.Length;
  981. } else {
  982. rv = KMF_ERR_ENCODING;
  983. goto cleanup;
  984. }
  985. /* Encode the issuer */
  986. rv = DerEncodeName(&signed_cert_ptr->certificate.issuer, &data);
  987. if (rv == KMF_OK) {
  988. issuer = data.Data;
  989. issuer_len = data.Length;
  990. } else {
  991. rv = KMF_ERR_ENCODING;
  992. goto cleanup;
  993. }
  994. /* Encode serial number */
  995. if (signed_cert_ptr->certificate.serialNumber.len > 0 &&
  996. signed_cert_ptr->certificate.serialNumber.val != NULL) {
  997. serial = signed_cert_ptr->certificate.serialNumber.val;
  998. serno_len = signed_cert_ptr->certificate.serialNumber.len;
  999. } else {
  1000. /*
  1001. * RFC3280 says to gracefully handle certs with serial numbers
  1002. * of 0.
  1003. */
  1004. nullserno = '\0';
  1005. serial = &nullserno;
  1006. serno_len = 1;
  1007. }
  1008. /* Generate an ID from the SPKI data */
  1009. rv = GetIDFromSPKI(&signed_cert_ptr->certificate.subjectPublicKeyInfo,
  1010. &Id);
  1011. if (rv != KMF_OK) {
  1012. goto cleanup;
  1013. }
  1014. i = 0;
  1015. SETATTR(x509templ, i, CKA_CLASS, &certClass, sizeof (certClass)); i++;
  1016. SETATTR(x509templ, i, CKA_CERTIFICATE_TYPE, &certtype,
  1017. sizeof (certtype));
  1018. i++;
  1019. SETATTR(x509templ, i, CKA_TOKEN, &true, sizeof (true)); i++;
  1020. SETATTR(x509templ, i, CKA_SUBJECT, subject, subject_len); i++;
  1021. SETATTR(x509templ, i, CKA_ISSUER, issuer, issuer_len); i++;
  1022. SETATTR(x509templ, i, CKA_SERIAL_NUMBER, serial, serno_len); i++;
  1023. SETATTR(x509templ, i, CKA_VALUE, pcert->Data, pcert->Length); i++;
  1024. SETATTR(x509templ, i, CKA_ID, Id.Data, Id.Length); i++;
  1025. if (label != NULL && strlen(label)) {
  1026. SETATTR(x509templ, i, CKA_LABEL, label, strlen(label)); i++;
  1027. }
  1028. /*
  1029. * The cert object handle is actually "leaked" here. If the app
  1030. * really wants to clean up the data space, it will have to call
  1031. * KMF_DeleteCert and specify the softtoken keystore.
  1032. */
  1033. ckrv = C_CreateObject(kmfh->pk11handle, x509templ, i, &hCert);
  1034. if (ckrv != CKR_OK) {
  1035. /* Report authentication failures to the caller */
  1036. if (ckrv == CKR_USER_NOT_LOGGED_IN ||
  1037. ckrv == CKR_PIN_INCORRECT ||
  1038. ckrv == CKR_PIN_INVALID ||
  1039. ckrv == CKR_PIN_EXPIRED ||
  1040. ckrv == CKR_PIN_LOCKED ||
  1041. ckrv == CKR_SESSION_READ_ONLY)
  1042. rv = KMF_ERR_AUTH_FAILED;
  1043. else
  1044. rv = KMF_ERR_INTERNAL;
  1045. SET_ERROR(kmfh, ckrv);
  1046. }
  1047. free(subject);
  1048. free(issuer);
  1049. cleanup:
  1050. if (Id.Data != NULL)
  1051. free(Id.Data);
  1052. if (signed_cert_ptr) {
  1053. kmf_free_signed_cert(signed_cert_ptr);
  1054. free(signed_cert_ptr);
  1055. }
  1056. return (rv);
  1057. }
  1058. KMF_RETURN
  1059. KMFPK11_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
  1060. {
  1061. KMF_RETURN rv = 0;
  1062. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  1063. KMF_DATA *cert = NULL;
  1064. KMF_CREDENTIAL *cred = NULL;
  1065. char *label = NULL;
  1066. if (kmfh == NULL)
  1067. return (KMF_ERR_UNINITIALIZED);
  1068. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  1069. return (KMF_ERR_NO_TOKEN_SELECTED);
  1070. cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
  1071. if (cert == NULL || cert->Data == NULL || cert->Length == 0)
  1072. return (KMF_ERR_BAD_PARAMETER);
  1073. /* label attribute is optional */
  1074. label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
  1075. cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
  1076. if (cred != NULL) {
  1077. rv = pk11_authenticate(handle, cred);
  1078. if (rv != KMF_OK)
  1079. return (rv);
  1080. }
  1081. rv = CreateCertObject(handle, label, cert);
  1082. return (rv);
  1083. }
  1084. KMF_RETURN
  1085. KMFPK11_ImportCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
  1086. {
  1087. KMF_RETURN rv = 0;
  1088. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  1089. char *certfile = NULL;
  1090. char *label = NULL;
  1091. KMF_ENCODE_FORMAT format;
  1092. KMF_CREDENTIAL *cred = NULL;
  1093. KMF_DATA cert1 = { NULL, 0};
  1094. KMF_DATA cert2 = { NULL, 0};
  1095. if (kmfh == NULL)
  1096. return (KMF_ERR_UNINITIALIZED);
  1097. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  1098. return (KMF_ERR_NO_TOKEN_SELECTED);
  1099. /*
  1100. * Get the input cert filename attribute, check if it is a valid
  1101. * certificate and auto-detect the file format of it.
  1102. */
  1103. certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
  1104. if (certfile == NULL)
  1105. return (KMF_ERR_BAD_PARAMETER);
  1106. rv = kmf_is_cert_file(handle, certfile, &format);
  1107. if (rv != KMF_OK)
  1108. return (rv);
  1109. /* Read in the CERT file */
  1110. rv = kmf_read_input_file(handle, certfile, &cert1);
  1111. if (rv != KMF_OK) {
  1112. return (rv);
  1113. }
  1114. /* The label attribute is optional */
  1115. label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
  1116. /*
  1117. * If the input certificate is in PEM format, we need to convert
  1118. * it to DER first.
  1119. */
  1120. if (format == KMF_FORMAT_PEM) {
  1121. int derlen;
  1122. rv = kmf_pem_to_der(cert1.Data, cert1.Length,
  1123. &cert2.Data, &derlen);
  1124. if (rv != KMF_OK) {
  1125. goto out;
  1126. }
  1127. cert2.Length = (size_t)derlen;
  1128. }
  1129. cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
  1130. if (cred != NULL) {
  1131. rv = pk11_authenticate(handle, cred);
  1132. if (rv != KMF_OK)
  1133. return (rv);
  1134. }
  1135. rv = CreateCertObject(handle, label,
  1136. format == KMF_FORMAT_ASN1 ? &cert1 : &cert2);
  1137. out:
  1138. if (cert1.Data != NULL) {
  1139. free(cert1.Data);
  1140. }
  1141. if (cert2.Data != NULL) {
  1142. free(cert2.Data);
  1143. }
  1144. return (rv);
  1145. }
  1146. KMF_RETURN
  1147. KMFPK11_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
  1148. {
  1149. KMF_RETURN rv = 0;
  1150. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  1151. OBJLIST *objlist;
  1152. uint32_t numObjects = 0;
  1153. char *certlabel = NULL;
  1154. char *issuer = NULL;
  1155. char *subject = NULL;
  1156. KMF_BIGINT *serial = NULL;
  1157. KMF_CERT_VALIDITY validity;
  1158. boolean_t private;
  1159. if (kmfh == NULL)
  1160. return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
  1161. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  1162. return (KMF_ERR_NO_TOKEN_SELECTED);
  1163. /* Get the search criteria attributes. They are all optional. */
  1164. certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
  1165. issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
  1166. subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
  1167. serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
  1168. rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
  1169. &validity, NULL);
  1170. if (rv != KMF_OK) {
  1171. validity = KMF_ALL_CERTS;
  1172. rv = KMF_OK;
  1173. }
  1174. rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
  1175. (void *)&private, NULL);
  1176. if (rv != KMF_OK) {
  1177. private = B_FALSE;
  1178. rv = KMF_OK;
  1179. }
  1180. /*
  1181. * Start searching for certificates that match the criteria and
  1182. * delete them.
  1183. */
  1184. objlist = NULL;
  1185. rv = search_certs(handle, certlabel, issuer, subject, serial,
  1186. private, validity, &objlist, &numObjects);
  1187. if (rv == KMF_OK && objlist != NULL) {
  1188. OBJLIST *node = objlist;
  1189. while (node != NULL) {
  1190. CK_RV ckrv;
  1191. ckrv = C_DestroyObject(kmfh->pk11handle, node->handle);
  1192. if (ckrv != CKR_OK) {
  1193. SET_ERROR(kmfh, ckrv);
  1194. rv = KMF_ERR_INTERNAL;
  1195. break;
  1196. }
  1197. node = node->next;
  1198. }
  1199. free_objlist(objlist);
  1200. }
  1201. if (rv == KMF_OK && numObjects == 0)
  1202. rv = KMF_ERR_CERT_NOT_FOUND;
  1203. out:
  1204. return (rv);
  1205. }
  1206. static CK_RV
  1207. gendsa_keypair(KMF_HANDLE *kmfh, boolean_t storekey,
  1208. CK_OBJECT_HANDLE *pubKey,
  1209. CK_OBJECT_HANDLE *priKey)
  1210. {
  1211. CK_RV ckrv = CKR_OK;
  1212. CK_SESSION_HANDLE hSession = kmfh->pk11handle;
  1213. static CK_ULONG dsaKeyType = CKK_DSA;
  1214. static CK_BBOOL true = TRUE;
  1215. static CK_BBOOL false = FALSE;
  1216. static CK_OBJECT_CLASS priClass = CKO_PRIVATE_KEY;
  1217. static CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
  1218. static CK_BYTE ckDsaPrime[128] = {
  1219. 0xb2, 0x6b, 0xc3, 0xfb, 0xe3, 0x26, 0xf4, 0xc2,
  1220. 0xcf, 0xdd, 0xf9, 0xae, 0x3e, 0x39, 0x7f, 0x9c,
  1221. 0xa7, 0x73, 0xc3, 0x00, 0xa3, 0x50, 0x67, 0xc3,
  1222. 0xab, 0x49, 0x2c, 0xea, 0x59, 0x10, 0xa4, 0xbc,
  1223. 0x09, 0x94, 0xa9, 0x05, 0x3b, 0x0d, 0x35, 0x3c,
  1224. 0x55, 0x52, 0x47, 0xf0, 0xe3, 0x72, 0x5b, 0xe8,
  1225. 0x72, 0xa0, 0x71, 0x1c, 0x23, 0x4f, 0x6d, 0xe8,
  1226. 0xac, 0xe5, 0x21, 0x1b, 0xc0, 0xd8, 0x42, 0xd3,
  1227. 0x87, 0xae, 0x83, 0x5e, 0x52, 0x7e, 0x46, 0x09,
  1228. 0xb5, 0xc7, 0x3d, 0xd6, 0x00, 0xf5, 0xf2, 0x9c,
  1229. 0x84, 0x30, 0x81, 0x7e, 0x7b, 0x30, 0x5b, 0xd5,
  1230. 0xab, 0xd0, 0x2f, 0x21, 0xb3, 0xd8, 0xed, 0xdb,
  1231. 0x97, 0x77, 0xe4, 0x7e, 0x6c, 0xcc, 0xb9, 0x6b,
  1232. 0xdd, 0xaa, 0x96, 0x04, 0xe7, 0xd4, 0x55, 0x11,
  1233. 0x53, 0xab, 0xba, 0x95, 0x9a, 0xa2, 0x8c, 0x27,
  1234. 0xd9, 0xcf, 0xad, 0xf3, 0xcf, 0x3a, 0x0c, 0x4b};
  1235. static CK_BYTE ckDsaSubPrime[20] = {
  1236. 0xa4, 0x5f, 0x2a, 0x27, 0x09, 0x49, 0xb6, 0xfe,
  1237. 0x73, 0xeb, 0x95, 0x7d, 0x00, 0xf3, 0x42, 0xfc,
  1238. 0x78, 0x47, 0xb0, 0xd5};
  1239. static CK_BYTE ckDsaBase[128] = {
  1240. 0x5c, 0x57, 0x16, 0x49, 0xef, 0xc8, 0xfb, 0x4b,
  1241. 0xee, 0x07, 0x45, 0x3b, 0x6a, 0x1d, 0xf3, 0xe5,
  1242. 0xeb, 0xee, 0xad, 0x11, 0x13, 0xe3, 0x52, 0xe3,
  1243. 0x0d, 0xc0, 0x21, 0x25, 0xfa, 0xf0, 0x93, 0x1c,
  1244. 0x53, 0x4d, 0xdc, 0x0d, 0x76, 0xd2, 0xfe, 0xc2,
  1245. 0xd7, 0x72, 0x64, 0x69, 0x53, 0x3d, 0x33, 0xbd,
  1246. 0xe1, 0x34, 0xf2, 0x5a, 0x67, 0x83, 0xe0, 0xd3,
  1247. 0x1c, 0xd6, 0x41, 0x4d, 0x16, 0xe8, 0x6c, 0x5a,
  1248. 0x07, 0x95, 0x21, 0x9a, 0xa3, 0xc4, 0xb9, 0x05,
  1249. 0x9d, 0x11, 0xcb, 0xc8, 0xc4, 0x9d, 0x00, 0x1a,
  1250. 0xf4, 0x85, 0x2a, 0xa9, 0x20, 0x3c, 0xba, 0x67,
  1251. 0xe5, 0xed, 0x31, 0xb2, 0x11, 0xfb, 0x1f, 0x73,
  1252. 0xec, 0x61, 0x29, 0xad, 0xc7, 0x68, 0xb2, 0x3f,
  1253. 0x38, 0xea, 0xd9, 0x87, 0x83, 0x9e, 0x7e, 0x19,
  1254. 0x18, 0xdd, 0xc2, 0xc3, 0x5b, 0x16, 0x6d, 0xce,
  1255. 0xcf, 0x88, 0x91, 0x07, 0xe0, 0x2b, 0xa8, 0x54 };
  1256. static CK_ATTRIBUTE ckDsaPubKeyTemplate[] = {
  1257. { CKA_CLASS, &pubClass, sizeof (pubClass) },
  1258. { CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType) },
  1259. { CKA_TOKEN, &true, sizeof (true)},
  1260. { CKA_PRIVATE, &false, sizeof (false)},
  1261. { CKA_PRIME, &ckDsaPrime, sizeof (ckDsaPrime) },
  1262. { CKA_SUBPRIME, &ckDsaSubPrime, sizeof (ckDsaSubPrime)},
  1263. { CKA_BASE, &ckDsaBase, sizeof (ckDsaBase) },
  1264. { CKA_VERIFY, &true, sizeof (true) },
  1265. };
  1266. #define NUMBER_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \
  1267. sizeof (CK_ATTRIBUTE))
  1268. #define MAX_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \
  1269. sizeof (CK_ATTRIBUTE))
  1270. static CK_ATTRIBUTE ckDsaPriKeyTemplate[] = {
  1271. {CKA_CLASS, &priClass, sizeof (priClass)},
  1272. {CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType)},
  1273. {CKA_TOKEN, &true, sizeof (true)},
  1274. {CKA_PRIVATE, &true, sizeof (true)},
  1275. {CKA_SIGN, &true, sizeof (true)},
  1276. };
  1277. #define NUMBER_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \
  1278. sizeof (CK_ATTRIBUTE))
  1279. #define MAX_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \
  1280. sizeof (CK_ATTRIBUTE))
  1281. CK_MECHANISM keyGenMech = {CKM_DSA_KEY_PAIR_GEN, NULL, 0};
  1282. SETATTR(ckDsaPriKeyTemplate, 2, CKA_TOKEN,
  1283. (storekey ? &true : &false), sizeof (CK_BBOOL));
  1284. ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
  1285. ckDsaPubKeyTemplate,
  1286. (sizeof (ckDsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)),
  1287. ckDsaPriKeyTemplate,
  1288. (sizeof (ckDsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)),
  1289. pubKey, priKey);
  1290. if (ckrv != CKR_OK) {
  1291. SET_ERROR(kmfh, ckrv);
  1292. return (KMF_ERR_KEYGEN_FAILED);
  1293. }
  1294. return (ckrv);
  1295. }
  1296. static CK_RV
  1297. genrsa_keypair(KMF_HANDLE *kmfh, CK_ULONG modulusBits,
  1298. boolean_t storekey, KMF_BIGINT *rsaexp,
  1299. CK_OBJECT_HANDLE *pubKey,
  1300. CK_OBJECT_HANDLE *priKey)
  1301. {
  1302. CK_RV ckrv = CKR_OK;
  1303. CK_SESSION_HANDLE hSession = kmfh->pk11handle;
  1304. CK_ATTRIBUTE rsaPubKeyTemplate[16];
  1305. CK_ATTRIBUTE rsaPriKeyTemplate[16];
  1306. CK_MECHANISM keyGenMech = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0};
  1307. int numpubattr = 0, numpriattr = 0;
  1308. static CK_BYTE PubExpo[3] = {0x01, 0x00, 0x01};
  1309. static CK_BBOOL true = TRUE;
  1310. static CK_BBOOL false = FALSE;
  1311. SETATTR(rsaPubKeyTemplate, numpubattr, CKA_TOKEN,
  1312. (storekey ? &true : &false), sizeof (CK_BBOOL));
  1313. numpubattr++;
  1314. SETATTR(rsaPubKeyTemplate, numpubattr, CKA_MODULUS_BITS,
  1315. &modulusBits, sizeof (modulusBits));
  1316. numpubattr++;
  1317. if (rsaexp != NULL && (rsaexp->len > 0 && rsaexp->val != NULL)) {
  1318. SETATTR(rsaPubKeyTemplate, numpubattr,
  1319. CKA_PUBLIC_EXPONENT,
  1320. rsaexp->val, rsaexp->len);
  1321. numpubattr++;
  1322. } else {
  1323. SETATTR(rsaPubKeyTemplate, numpubattr,
  1324. CKA_PUBLIC_EXPONENT, &PubExpo, sizeof (PubExpo));
  1325. numpubattr++;
  1326. }
  1327. SETATTR(rsaPubKeyTemplate, numpubattr, CKA_ENCRYPT,
  1328. &true, sizeof (true));
  1329. numpubattr++;
  1330. SETATTR(rsaPubKeyTemplate, numpubattr, CKA_VERIFY,
  1331. &true, sizeof (true));
  1332. numpubattr++;
  1333. SETATTR(rsaPubKeyTemplate, numpubattr, CKA_WRAP,
  1334. &true, sizeof (true));
  1335. numpubattr++;
  1336. SETATTR(rsaPriKeyTemplate, numpriattr, CKA_TOKEN,
  1337. (storekey ? &true : &false), sizeof (CK_BBOOL));
  1338. numpriattr++;
  1339. SETATTR(rsaPriKeyTemplate, numpriattr, CKA_PRIVATE, &true,
  1340. sizeof (true));
  1341. numpriattr++;
  1342. SETATTR(rsaPriKeyTemplate, numpriattr, CKA_DECRYPT, &true,
  1343. sizeof (true));
  1344. numpriattr++;
  1345. SETATTR(rsaPriKeyTemplate, numpriattr, CKA_SIGN, &true,
  1346. sizeof (true));
  1347. numpriattr++;
  1348. SETATTR(rsaPriKeyTemplate, numpriattr, CKA_UNWRAP, &true,
  1349. sizeof (true));
  1350. numpriattr++;
  1351. ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
  1352. rsaPubKeyTemplate, numpubattr,
  1353. rsaPriKeyTemplate, numpriattr,
  1354. pubKey, priKey);
  1355. if (ckrv != CKR_OK) {
  1356. SET_ERROR(kmfh, ckrv);
  1357. return (ckrv);
  1358. }
  1359. return (ckrv);
  1360. }
  1361. static CK_RV
  1362. genecc_keypair(KMF_HANDLE *kmfh,
  1363. boolean_t ontoken,
  1364. KMF_OID *curveoid,
  1365. CK_OBJECT_HANDLE *pubKey,
  1366. CK_OBJECT_HANDLE *priKey)
  1367. {
  1368. CK_RV ckrv;
  1369. CK_SESSION_HANDLE hSession = kmfh->pk11handle;
  1370. CK_MECHANISM keyGenMech = {CKM_EC_KEY_PAIR_GEN, NULL, 0};
  1371. const ulong_t publicKey = CKO_PUBLIC_KEY;
  1372. const ulong_t privateKey = CKO_PRIVATE_KEY;
  1373. const ulong_t keytype = CKK_EC;
  1374. static CK_BBOOL true = TRUE;
  1375. static CK_BBOOL false = FALSE;
  1376. CK_ATTRIBUTE public_template[6];
  1377. CK_ATTRIBUTE private_template[6];
  1378. int numpubattr, numpriattr;
  1379. numpubattr = 0;
  1380. SETATTR(public_template, numpubattr, CKA_CLASS,
  1381. &publicKey, sizeof (publicKey));
  1382. numpubattr++;
  1383. SETATTR(public_template, numpubattr, CKA_KEY_TYPE,
  1384. &keytype, sizeof (keytype));
  1385. numpubattr++;
  1386. SETATTR(public_template, numpubattr, CKA_EC_PARAMS,
  1387. curveoid->Data, curveoid->Length);
  1388. numpubattr++;
  1389. SETATTR(public_template, numpubattr, CKA_TOKEN,
  1390. ontoken ? &true : &false, sizeof (true));
  1391. numpubattr++;
  1392. SETATTR(public_template, numpubattr, CKA_VERIFY,
  1393. &true, sizeof (true));
  1394. numpubattr++;
  1395. SETATTR(public_template, numpubattr, CKA_PRIVATE,
  1396. &false, sizeof (false));
  1397. numpubattr++;
  1398. numpriattr = 0;
  1399. SETATTR(private_template, numpriattr, CKA_CLASS,
  1400. &privateKey, sizeof (privateKey));
  1401. numpriattr++;
  1402. SETATTR(private_template, numpriattr, CKA_KEY_TYPE,
  1403. &keytype, sizeof (keytype));
  1404. numpriattr++;
  1405. SETATTR(private_template, numpriattr, CKA_TOKEN,
  1406. ontoken ? &true : &false, sizeof (true));
  1407. numpriattr++;
  1408. SETATTR(private_template, numpriattr, CKA_PRIVATE,
  1409. &true, sizeof (true));
  1410. numpriattr++;
  1411. SETATTR(private_template, numpriattr, CKA_SIGN,
  1412. &true, sizeof (true));
  1413. numpriattr++;
  1414. SETATTR(private_template, numpriattr, CKA_DERIVE,
  1415. &true, sizeof (true));
  1416. numpriattr++;
  1417. ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
  1418. public_template, numpubattr,
  1419. private_template, numpriattr,
  1420. pubKey, priKey);
  1421. if (ckrv != CKR_OK) {
  1422. SET_ERROR(kmfh, ckrv);
  1423. return (ckrv);
  1424. }
  1425. return (ckrv);
  1426. }
  1427. KMF_RETURN
  1428. KMFPK11_CreateKeypair(KMF_HANDLE_T handle,
  1429. int numattr,
  1430. KMF_ATTRIBUTE *attlist)
  1431. {
  1432. KMF_RETURN rv = KMF_OK;
  1433. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  1434. KMF_DATA IDInput, IDOutput;
  1435. KMF_CREDENTIAL *cred;
  1436. KMF_KEY_ALG keytype = KMF_RSA;
  1437. KMF_KEY_HANDLE *pubkey, *privkey;
  1438. CK_RV ckrv = 0;
  1439. CK_SESSION_HANDLE hSession = kmfh->pk11handle;
  1440. CK_ATTRIBUTE labelattr[1];
  1441. CK_ATTRIBUTE idattr[1];
  1442. CK_OBJECT_HANDLE pubKey, priKey;
  1443. char IDHashData[SHA1_HASH_LENGTH];
  1444. static CK_ULONG modulusBits = 1024;
  1445. uint32_t modulusBits_size = sizeof (CK_ULONG);
  1446. SHA1_CTX ctx;
  1447. boolean_t storekey = TRUE;
  1448. char *keylabel = NULL;
  1449. if (kmfh == NULL)
  1450. return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
  1451. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  1452. return (KMF_ERR_NO_TOKEN_SELECTED);
  1453. /* "storekey" is optional. Default is TRUE */
  1454. (void) kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attlist, numattr,
  1455. &storekey, NULL);
  1456. cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attlist, numattr);
  1457. if (cred == NULL)
  1458. return (KMF_ERR_BAD_PARAMETER);
  1459. rv = pk11_authenticate(handle, cred);
  1460. if (rv != KMF_OK)
  1461. return (rv);
  1462. /* keytype is optional. KMF_RSA is default */
  1463. (void) kmf_get_attr(KMF_KEYALG_ATTR, attlist, numattr,
  1464. (void *)&keytype, NULL);
  1465. pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr);
  1466. if (pubkey == NULL)
  1467. return (KMF_ERR_BAD_PARAMETER);
  1468. privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist, numattr);
  1469. if (privkey == NULL)
  1470. return (KMF_ERR_BAD_PARAMETER);
  1471. (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE));
  1472. (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE));
  1473. if (keytype == KMF_RSA) {
  1474. CK_BYTE *modulus = NULL;
  1475. CK_ULONG modulusLength = 0;
  1476. KMF_BIGINT *rsaexp = NULL;
  1477. CK_ATTRIBUTE modattr[1];
  1478. rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attlist, numattr,
  1479. &modulusBits, &modulusBits_size);
  1480. if (rv == KMF_ERR_ATTR_NOT_FOUND)
  1481. /* Default modulusBits = 1024 */
  1482. rv = KMF_OK;
  1483. if (rv != KMF_OK)
  1484. return (KMF_ERR_BAD_PARAMETER);
  1485. rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attlist, numattr);
  1486. /* Generate the RSA keypair */
  1487. ckrv = genrsa_keypair(kmfh, modulusBits, storekey,
  1488. rsaexp, &pubKey, &priKey);
  1489. if (ckrv != CKR_OK)
  1490. return (KMF_ERR_BAD_PARAMETER);
  1491. privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
  1492. privkey->keyalg = KMF_RSA;
  1493. privkey->keyclass = KMF_ASYM_PRI;
  1494. privkey->keyp = (void *)priKey;
  1495. pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
  1496. pubkey->keyalg = KMF_RSA;
  1497. pubkey->keyclass = KMF_ASYM_PUB;
  1498. pubkey->keyp = (void *)pubKey;
  1499. SETATTR(modattr, 0, CKA_MODULUS, NULL, modulusLength);
  1500. /* Get the Modulus field to use as input for creating the ID */
  1501. ckrv = C_GetAttributeValue(kmfh->pk11handle,
  1502. (CK_OBJECT_HANDLE)pubKey, modattr, 1);
  1503. if (ckrv != CKR_OK) {
  1504. SET_ERROR(kmfh, ckrv);
  1505. return (KMF_ERR_BAD_PARAMETER);
  1506. }
  1507. modulusLength = modattr[0].ulValueLen;
  1508. modulus = malloc(modulusLength);
  1509. if (modulus == NULL)
  1510. return (KMF_ERR_MEMORY);
  1511. modattr[0].pValue = modulus;
  1512. ckrv = C_GetAttributeValue(kmfh->pk11handle,
  1513. (CK_OBJECT_HANDLE)pubKey, modattr, 1);
  1514. if (ckrv != CKR_OK) {
  1515. SET_ERROR(kmfh, ckrv);
  1516. free(modulus);
  1517. return (KMF_ERR_BAD_PARAMETER);
  1518. }
  1519. IDInput.Data = modulus;
  1520. IDInput.Length = modulusLength;
  1521. } else if (keytype == KMF_DSA) {
  1522. CK_BYTE *keyvalue;
  1523. CK_ULONG valueLen;
  1524. CK_ATTRIBUTE valattr[1];
  1525. /* Generate the DSA keypair */
  1526. ckrv = gendsa_keypair(kmfh, storekey, &pubKey, &priKey);
  1527. if (ckrv != CKR_OK)
  1528. return (KMF_ERR_BAD_PARAMETER);
  1529. privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
  1530. privkey->keyalg = KMF_DSA;
  1531. privkey->keyclass = KMF_ASYM_PRI;
  1532. privkey->keyp = (void *)priKey;
  1533. pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
  1534. pubkey->keyalg = KMF_DSA;
  1535. pubkey->keyclass = KMF_ASYM_PUB;
  1536. pubkey->keyp = (void *)pubKey;
  1537. /* Get the Public Value to use as input for creating the ID */
  1538. SETATTR(valattr, 0, CKA_VALUE, NULL, &valueLen);
  1539. ckrv = C_GetAttributeValue(hSession,
  1540. (CK_OBJECT_HANDLE)pubKey, valattr, 1);
  1541. if (ckrv != CKR_OK) {
  1542. SET_ERROR(kmfh, ckrv);
  1543. return (KMF_ERR_BAD_PARAMETER);
  1544. }
  1545. valueLen = valattr[0].ulValueLen;
  1546. keyvalue = malloc(valueLen);
  1547. if (keyvalue == NULL)
  1548. return (KMF_ERR_MEMORY);
  1549. valattr[0].pValue = keyvalue;
  1550. ckrv = C_GetAttributeValue(hSession,
  1551. (CK_OBJECT_HANDLE)pubKey, valattr, 1);
  1552. if (ckrv != CKR_OK) {
  1553. SET_ERROR(kmfh, ckrv);
  1554. free(keyvalue);
  1555. return (KMF_ERR_BAD_PARAMETER);
  1556. }
  1557. IDInput.Data = keyvalue;
  1558. IDInput.Length = valueLen;
  1559. } else if (keytype == KMF_ECDSA) {
  1560. CK_BYTE *keyvalue;
  1561. CK_ULONG valueLen;
  1562. CK_ATTRIBUTE valattr[1];
  1563. KMF_OID *eccoid = kmf_get_attr_ptr(KMF_ECC_CURVE_OID_ATTR,
  1564. attlist, numattr);
  1565. if (eccoid == NULL)
  1566. return (KMF_ERR_BAD_PARAMETER);
  1567. ckrv = genecc_keypair(kmfh, storekey, eccoid,
  1568. &pubKey, &priKey);
  1569. if (ckrv != CKR_OK)
  1570. return (KMF_ERR_BAD_PARAMETER);
  1571. privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
  1572. privkey->keyalg = KMF_ECDSA;
  1573. privkey->keyclass = KMF_ASYM_PRI;
  1574. privkey->keyp = (void *)priKey;
  1575. pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
  1576. pubkey->keyalg = KMF_ECDSA;
  1577. pubkey->keyclass = KMF_ASYM_PUB;
  1578. pubkey->keyp = (void *)pubKey;
  1579. /* Get the EC_POINT to use as input for creating the ID */
  1580. SETATTR(valattr, 0, CKA_EC_POINT, NULL, &valueLen);
  1581. ckrv = C_GetAttributeValue(hSession,
  1582. (CK_OBJECT_HANDLE)pubKey, valattr, 1);
  1583. if (ckrv != CKR_OK) {
  1584. SET_ERROR(kmfh, ckrv);
  1585. return (KMF_ERR_BAD_PARAMETER);
  1586. }
  1587. valueLen = valattr[0].ulValueLen;
  1588. keyvalue = malloc(valueLen);
  1589. if (keyvalue == NULL)
  1590. return (KMF_ERR_MEMORY);
  1591. valattr[0].pValue = keyvalue;
  1592. ckrv = C_GetAttributeValue(hSession,
  1593. (CK_OBJECT_HANDLE)pubKey, valattr, 1);
  1594. if (ckrv != CKR_OK) {
  1595. SET_ERROR(kmfh, ckrv);
  1596. free(keyvalue);
  1597. return (KMF_ERR_BAD_PARAMETER);
  1598. }
  1599. IDInput.Data = keyvalue;
  1600. IDInput.Length = valueLen;
  1601. } else {
  1602. return (KMF_ERR_BAD_PARAMETER);
  1603. }
  1604. keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attlist, numattr);
  1605. if (keylabel != NULL && strlen(keylabel)) {
  1606. SETATTR(labelattr, 0, CKA_LABEL, keylabel, strlen(keylabel));
  1607. /* Set the CKA_LABEL if one was indicated */
  1608. if ((ckrv = C_SetAttributeValue(hSession, pubKey,
  1609. labelattr, 1)) != CKR_OK) {
  1610. SET_ERROR(kmfh, ckrv);
  1611. rv = KMF_ERR_INTERNAL;
  1612. goto cleanup;
  1613. }
  1614. pubkey->keylabel = (char *)strdup(keylabel);
  1615. if (pubkey->keylabel == NULL) {
  1616. rv = KMF_ERR_MEMORY;
  1617. goto cleanup;
  1618. }
  1619. if ((ckrv = C_SetAttributeValue(hSession, priKey,
  1620. labelattr, 1)) != CKR_OK) {
  1621. SET_ERROR(kmfh, ckrv);
  1622. rv = KMF_ERR_INTERNAL;
  1623. goto cleanup;
  1624. }
  1625. privkey->keylabel = (char *)strdup(keylabel);
  1626. if (privkey->keylabel == NULL) {
  1627. rv = KMF_ERR_MEMORY;
  1628. goto cleanup;
  1629. }
  1630. } else {
  1631. rv = KMF_OK;
  1632. }
  1633. /* Now, assign a CKA_ID value so it can be searched */
  1634. /* ID_Input was assigned above in the RSA or DSA keygen section */
  1635. IDOutput.Data = (uchar_t *)IDHashData;
  1636. IDOutput.Length = sizeof (IDHashData);
  1637. SHA1Init(&ctx);
  1638. SHA1Update

Large files files are truncated, but you can click here to view the full file