PageRenderTime 37ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

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

https://bitbucket.org/dilos/onarm-gate
C | 4034 lines | 3187 code | 565 blank | 282 comment | 1105 complexity | 3b2553b83ef8703fd92e0000aae5cb9d MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, AGPL-3.0, MIT, Apache-2.0, 0BSD, GPL-2.0, LGPL-2.0, AGPL-1.0, BSD-3-Clause, LGPL-3.0, BSD-3-Clause-No-Nuclear-License-2014
  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. /*
  22. * PKCS11 token KMF Plugin
  23. *
  24. * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
  25. * Use is subject to license terms.
  26. */
  27. #pragma ident "%Z%%M% %I% %E% SMI"
  28. #include <stdio.h> /* debugging only */
  29. #include <errno.h>
  30. #include <values.h>
  31. #include <kmfapiP.h>
  32. #include <ber_der.h>
  33. #include <algorithm.h>
  34. #include <fcntl.h>
  35. #include <sha1.h>
  36. #include <bignum.h>
  37. #include <cryptoutil.h>
  38. #include <security/cryptoki.h>
  39. #include <security/pkcs11.h>
  40. #define DEV_RANDOM "/dev/random"
  41. #define SETATTR(t, n, atype, value, size) \
  42. t[n].type = atype; \
  43. t[n].pValue = (CK_BYTE *)value; \
  44. t[n].ulValueLen = (CK_ULONG)size;
  45. #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; \
  46. h->lasterr.errcode = c;
  47. typedef struct _objlist {
  48. CK_OBJECT_HANDLE handle;
  49. struct _objlist *next;
  50. } OBJLIST;
  51. static KMF_RETURN
  52. search_certs(KMF_HANDLE_T, char *, char *, char *, KMF_BIGINT *,
  53. boolean_t, KMF_CERT_VALIDITY, OBJLIST **, uint32_t *);
  54. static CK_RV
  55. getObjectLabel(KMF_HANDLE_T, CK_OBJECT_HANDLE, char **);
  56. static KMF_RETURN
  57. keyObj2RawKey(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_KEY_DATA **);
  58. static KMF_RETURN
  59. create_generic_secret_key(KMF_HANDLE_T,
  60. int, KMF_ATTRIBUTE *, CK_OBJECT_HANDLE *);
  61. KMF_RETURN
  62. KMFPK11_ConfigureKeystore(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  63. KMF_RETURN
  64. KMFPK11_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  65. void
  66. KMFPK11_FreeKMFCert(KMF_HANDLE_T,
  67. KMF_X509_DER_CERT *kmf_cert);
  68. KMF_RETURN
  69. KMFPK11_StoreCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  70. KMF_RETURN
  71. KMFPK11_ImportCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  72. KMF_RETURN
  73. KMFPK11_DeleteCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  74. KMF_RETURN
  75. KMFPK11_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  76. KMF_RETURN
  77. KMFPK11_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  78. KMF_RETURN
  79. KMFPK11_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  80. KMF_RETURN
  81. KMFPK11_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *);
  82. KMF_RETURN
  83. KMFPK11_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
  84. KMF_DATA *, KMF_DATA *);
  85. KMF_RETURN
  86. KMFPK11_GetErrorString(KMF_HANDLE_T, char **);
  87. KMF_RETURN
  88. KMFPK11_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  89. KMF_RETURN
  90. KMFPK11_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
  91. KMF_DATA *, KMF_DATA *);
  92. KMF_RETURN
  93. KMFPK11_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  94. KMF_RETURN
  95. KMFPK11_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  96. KMF_RETURN
  97. KMFPK11_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *);
  98. KMF_RETURN
  99. KMFPK11_SetTokenPin(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  100. KMF_RETURN
  101. KMFPK11_VerifyDataWithCert(KMF_HANDLE_T, KMF_ALGORITHM_INDEX, KMF_DATA *,
  102. KMF_DATA *, KMF_DATA *);
  103. KMF_RETURN
  104. KMFPK11_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
  105. static
  106. KMF_PLUGIN_FUNCLIST pk11token_plugin_table =
  107. {
  108. 1, /* Version */
  109. KMFPK11_ConfigureKeystore,
  110. KMFPK11_FindCert,
  111. KMFPK11_FreeKMFCert,
  112. KMFPK11_StoreCert,
  113. KMFPK11_ImportCert,
  114. NULL, /* ImportCRL */
  115. KMFPK11_DeleteCert,
  116. NULL, /* DeleteCRL */
  117. KMFPK11_CreateKeypair,
  118. KMFPK11_FindKey,
  119. KMFPK11_EncodePubKeyData,
  120. KMFPK11_SignData,
  121. KMFPK11_DeleteKey,
  122. NULL, /* ListCRL */
  123. NULL, /* FindCRL */
  124. NULL, /* FindCertInCRL */
  125. KMFPK11_GetErrorString,
  126. KMFPK11_FindPrikeyByCert,
  127. KMFPK11_DecryptData,
  128. KMFPK11_ExportPK12,
  129. KMFPK11_CreateSymKey,
  130. KMFPK11_GetSymKeyValue,
  131. KMFPK11_SetTokenPin,
  132. KMFPK11_VerifyDataWithCert,
  133. KMFPK11_StoreKey,
  134. NULL /* Finalize */
  135. };
  136. KMF_PLUGIN_FUNCLIST *
  137. KMF_Plugin_Initialize()
  138. {
  139. return (&pk11token_plugin_table);
  140. }
  141. KMF_RETURN
  142. KMFPK11_ConfigureKeystore(KMF_HANDLE_T handle,
  143. int numattr, KMF_ATTRIBUTE *attrlist)
  144. {
  145. KMF_RETURN rv = KMF_OK;
  146. char *label;
  147. boolean_t readonly = B_TRUE;
  148. label = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr);
  149. if (label == NULL) {
  150. return (KMF_ERR_BAD_PARAMETER);
  151. }
  152. /* "readonly" is optional. Default is TRUE */
  153. (void) kmf_get_attr(KMF_READONLY_ATTR, attrlist, numattr,
  154. (void *)&readonly, NULL);
  155. rv = kmf_select_token(handle, label, readonly);
  156. return (rv);
  157. }
  158. static KMF_RETURN
  159. pk11_authenticate(KMF_HANDLE_T handle,
  160. KMF_CREDENTIAL *cred)
  161. {
  162. CK_RV ck_rv = CKR_OK;
  163. CK_SESSION_HANDLE hSession = (CK_SESSION_HANDLE)handle->pk11handle;
  164. if (hSession == NULL)
  165. return (KMF_ERR_NO_TOKEN_SELECTED);
  166. if (cred == NULL || cred->cred == NULL || cred->credlen == 0) {
  167. return (KMF_ERR_BAD_PARAMETER);
  168. }
  169. if ((ck_rv = C_Login(hSession, CKU_USER, (uchar_t *)cred->cred,
  170. cred->credlen)) != CKR_OK) {
  171. if (ck_rv != CKR_USER_ALREADY_LOGGED_IN) {
  172. handle->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
  173. handle->lasterr.errcode = ck_rv;
  174. return (KMF_ERR_AUTH_FAILED);
  175. }
  176. }
  177. return (KMF_OK);
  178. }
  179. static KMF_RETURN
  180. PK11Cert2KMFCert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE hObj,
  181. KMF_X509_DER_CERT *kmfcert)
  182. {
  183. KMF_RETURN rv = 0;
  184. CK_RV ckrv = CKR_OK;
  185. CK_CERTIFICATE_TYPE cktype;
  186. CK_OBJECT_CLASS class;
  187. CK_ULONG subject_len, value_len, issuer_len, serno_len, id_len;
  188. CK_BYTE *subject = NULL, *value = NULL;
  189. char *label = NULL;
  190. CK_ATTRIBUTE templ[10];
  191. (void) memset(templ, 0, 10 * sizeof (CK_ATTRIBUTE));
  192. SETATTR(templ, 0, CKA_CLASS, &class, sizeof (class));
  193. /* Is this a certificate object ? */
  194. ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1);
  195. if (ckrv != CKR_OK || class != CKO_CERTIFICATE) {
  196. SET_ERROR(kmfh, ckrv);
  197. return (KMF_ERR_INTERNAL);
  198. }
  199. SETATTR(templ, 0, CKA_CERTIFICATE_TYPE, &cktype, sizeof (cktype));
  200. ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1);
  201. if (ckrv != CKR_OK || cktype != CKC_X_509) {
  202. SET_ERROR(kmfh, ckrv);
  203. return (ckrv);
  204. } else {
  205. int i = 0;
  206. /* What attributes are available and how big are they? */
  207. subject_len = issuer_len = serno_len = id_len = value_len = 0;
  208. SETATTR(templ, i, CKA_SUBJECT, NULL, subject_len);
  209. i++;
  210. SETATTR(templ, i, CKA_ISSUER, NULL, issuer_len);
  211. i++;
  212. SETATTR(templ, i, CKA_SERIAL_NUMBER, NULL, serno_len);
  213. i++;
  214. SETATTR(templ, i, CKA_ID, NULL, id_len);
  215. i++;
  216. SETATTR(templ, i, CKA_VALUE, NULL, value_len);
  217. i++;
  218. /*
  219. * Query the object with NULL values in the pValue spot
  220. * so we know how much space to allocate for each field.
  221. */
  222. ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, i);
  223. if (ckrv != CKR_OK) {
  224. SET_ERROR(kmfh, ckrv);
  225. return (KMF_ERR_INTERNAL); /* TODO - Error messages ? */
  226. }
  227. subject_len = templ[0].ulValueLen;
  228. issuer_len = templ[1].ulValueLen;
  229. serno_len = templ[2].ulValueLen;
  230. id_len = templ[3].ulValueLen;
  231. value_len = templ[4].ulValueLen;
  232. /*
  233. * For PKCS#11 CKC_X_509 certificate objects,
  234. * the following attributes must be defined.
  235. * CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER,
  236. * CKA_VALUE.
  237. */
  238. if (subject_len == 0 || issuer_len == 0 ||
  239. serno_len == 0 || value_len == 0) {
  240. return (KMF_ERR_INTERNAL);
  241. }
  242. /* Only fetch the value field if we are saving the data */
  243. if (kmfcert != NULL) {
  244. int i = 0;
  245. value = malloc(value_len);
  246. if (value == NULL) {
  247. rv = KMF_ERR_MEMORY;
  248. goto errout;
  249. }
  250. SETATTR(templ, i, CKA_VALUE, value, value_len);
  251. i++;
  252. /* re-query the object with room for the value attr */
  253. ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj,
  254. templ, i);
  255. if (ckrv != CKR_OK) {
  256. SET_ERROR(kmfh, ckrv);
  257. rv = KMF_ERR_INTERNAL;
  258. goto errout;
  259. }
  260. kmfcert->certificate.Data = value;
  261. kmfcert->certificate.Length = value_len;
  262. kmfcert->kmf_private.flags |= KMF_FLAG_CERT_SIGNED;
  263. kmfcert->kmf_private.keystore_type =
  264. KMF_KEYSTORE_PK11TOKEN;
  265. ckrv = getObjectLabel(kmfh, hObj, &label);
  266. if (ckrv == CKR_OK && label != NULL) {
  267. kmfcert->kmf_private.label = (char *)label;
  268. }
  269. rv = KMF_OK;
  270. }
  271. }
  272. errout:
  273. if (rv != KMF_OK) {
  274. if (subject)
  275. free(subject);
  276. if (value)
  277. free(value);
  278. if (kmfcert) {
  279. kmfcert->certificate.Data = NULL;
  280. kmfcert->certificate.Length = 0;
  281. }
  282. }
  283. return (rv);
  284. }
  285. static void
  286. free_objlist(OBJLIST *head)
  287. {
  288. OBJLIST *temp = head;
  289. while (temp != NULL) {
  290. head = head->next;
  291. free(temp);
  292. temp = head;
  293. }
  294. }
  295. /*
  296. * The caller should make sure that the templ->pValue is NULL since
  297. * it will be overwritten below.
  298. */
  299. static KMF_RETURN
  300. get_attr(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj,
  301. CK_ATTRIBUTE *templ)
  302. {
  303. CK_RV rv;
  304. rv = C_GetAttributeValue(kmfh->pk11handle, obj, templ, 1);
  305. if (rv != CKR_OK) {
  306. SET_ERROR(kmfh, rv);
  307. return (KMF_ERR_INTERNAL);
  308. }
  309. if (templ->ulValueLen > 0) {
  310. templ->pValue = malloc(templ->ulValueLen);
  311. if (templ->pValue == NULL)
  312. return (KMF_ERR_MEMORY);
  313. rv = C_GetAttributeValue(kmfh->pk11handle, obj, templ, 1);
  314. if (rv != CKR_OK) {
  315. SET_ERROR(kmfh, rv);
  316. return (KMF_ERR_INTERNAL);
  317. }
  318. }
  319. return (KMF_OK);
  320. }
  321. /*
  322. * Match a certificate with an issuer and/or subject name.
  323. * This is tricky because we cannot reliably compare DER encodings
  324. * because RDNs may have their AV-pairs in different orders even
  325. * if the values are the same. You must compare individual
  326. * AV pairs for the RDNs.
  327. *
  328. * RETURN: 0 for a match, non-zero for a non-match.
  329. */
  330. static KMF_RETURN
  331. matchcert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj,
  332. KMF_X509_NAME *issuer, KMF_X509_NAME *subject)
  333. {
  334. KMF_RETURN rv = KMF_OK;
  335. CK_ATTRIBUTE certattr;
  336. KMF_DATA name;
  337. KMF_X509_NAME dn;
  338. if (issuer->numberOfRDNs > 0) {
  339. certattr.type = CKA_ISSUER;
  340. certattr.pValue = NULL;
  341. certattr.ulValueLen = 0;
  342. rv = get_attr(kmfh, obj, &certattr);
  343. if (rv == KMF_OK) {
  344. name.Data = certattr.pValue;
  345. name.Length = certattr.ulValueLen;
  346. rv = DerDecodeName(&name, &dn);
  347. if (rv == KMF_OK) {
  348. rv = kmf_compare_rdns(issuer, &dn);
  349. kmf_free_dn(&dn);
  350. }
  351. free(certattr.pValue);
  352. }
  353. if (rv != KMF_OK)
  354. return (rv);
  355. }
  356. if (subject->numberOfRDNs > 0) {
  357. certattr.type = CKA_SUBJECT;
  358. certattr.pValue = NULL;
  359. certattr.ulValueLen = 0;
  360. rv = get_attr(kmfh, obj, &certattr);
  361. if (rv == KMF_OK) {
  362. name.Data = certattr.pValue;
  363. name.Length = certattr.ulValueLen;
  364. rv = DerDecodeName(&name, &dn);
  365. if (rv == KMF_OK) {
  366. rv = kmf_compare_rdns(subject, &dn);
  367. kmf_free_dn(&dn);
  368. }
  369. free(certattr.pValue);
  370. }
  371. }
  372. return (rv);
  373. }
  374. /*
  375. * delete "curr" node from the "newlist".
  376. */
  377. static void
  378. pk11_delete_obj_from_list(OBJLIST **newlist,
  379. OBJLIST **prev, OBJLIST **curr)
  380. {
  381. if (*curr == *newlist) {
  382. /* first node in the list */
  383. *newlist = (*curr)->next;
  384. *prev = (*curr)->next;
  385. free(*curr);
  386. *curr = *newlist;
  387. } else {
  388. (*prev)->next = (*curr)->next;
  389. free(*curr);
  390. *curr = (*prev)->next;
  391. }
  392. }
  393. /*
  394. * search_certs
  395. *
  396. * Because this code is shared by the FindCert and
  397. * DeleteCert functions, put it in a separate routine
  398. * to save some work and make code easier to debug and
  399. * read.
  400. */
  401. static KMF_RETURN
  402. search_certs(KMF_HANDLE_T handle,
  403. char *label, char *issuer, char *subject, KMF_BIGINT *serial,
  404. boolean_t private, KMF_CERT_VALIDITY validity,
  405. OBJLIST **objlist, uint32_t *numobj)
  406. {
  407. KMF_RETURN rv = KMF_OK;
  408. CK_RV ckrv = CKR_OK;
  409. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  410. CK_ATTRIBUTE templ[10];
  411. CK_BBOOL true = TRUE;
  412. CK_OBJECT_CLASS oclass = CKO_CERTIFICATE;
  413. CK_CERTIFICATE_TYPE ctype = CKC_X_509;
  414. KMF_X509_NAME subjectDN, issuerDN;
  415. int i;
  416. OBJLIST *newlist, *tail;
  417. CK_ULONG num = 0;
  418. uint32_t num_ok_certs = 0; /* number of non-expired or expired certs */
  419. (void) memset(&templ, 0, 10 * sizeof (CK_ATTRIBUTE));
  420. (void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME));
  421. (void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME));
  422. i = 0;
  423. SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true)); i++;
  424. SETATTR(templ, i, CKA_CLASS, &oclass, sizeof (oclass)); i++;
  425. SETATTR(templ, i, CKA_CERTIFICATE_TYPE, &ctype, sizeof (ctype)); i++;
  426. if (label != NULL && strlen(label)) {
  427. SETATTR(templ, i, CKA_LABEL, label, strlen(label));
  428. i++;
  429. }
  430. if (private) {
  431. SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true)); i++;
  432. }
  433. if (issuer != NULL && strlen(issuer)) {
  434. if ((rv = kmf_dn_parser(issuer, &issuerDN)) != KMF_OK)
  435. return (rv);
  436. }
  437. if (subject != NULL && strlen(subject)) {
  438. if ((rv = kmf_dn_parser(subject, &subjectDN)) != KMF_OK)
  439. return (rv);
  440. }
  441. if (serial != NULL && serial->val != NULL && serial->len > 0) {
  442. SETATTR(templ, i, CKA_SERIAL_NUMBER, serial->val, serial->len);
  443. i++;
  444. }
  445. (*numobj) = 0;
  446. *objlist = NULL;
  447. newlist = NULL;
  448. ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, i);
  449. if (ckrv != CKR_OK)
  450. goto cleanup;
  451. tail = newlist = NULL;
  452. while (ckrv == CKR_OK) {
  453. CK_OBJECT_HANDLE tObj;
  454. ckrv = C_FindObjects(kmfh->pk11handle, &tObj, 1, &num);
  455. if (ckrv != CKR_OK || num == 0)
  456. break;
  457. /*
  458. * 'matchcert' returns 0 if subject/issuer match
  459. *
  460. * If no match, move on to the next one
  461. */
  462. if (matchcert(kmfh, tObj, &issuerDN, &subjectDN))
  463. continue;
  464. if (newlist == NULL) {
  465. newlist = malloc(sizeof (OBJLIST));
  466. if (newlist == NULL) {
  467. rv = KMF_ERR_MEMORY;
  468. break;
  469. }
  470. newlist->handle = tObj;
  471. newlist->next = NULL;
  472. tail = newlist;
  473. } else {
  474. tail->next = malloc(sizeof (OBJLIST));
  475. if (tail->next != NULL) {
  476. tail = tail->next;
  477. } else {
  478. rv = KMF_ERR_MEMORY;
  479. break;
  480. }
  481. tail->handle = tObj;
  482. tail->next = NULL;
  483. }
  484. (*numobj)++;
  485. }
  486. ckrv = C_FindObjectsFinal(kmfh->pk11handle);
  487. cleanup:
  488. if (ckrv != CKR_OK) {
  489. SET_ERROR(kmfh, ckrv);
  490. rv = KMF_ERR_INTERNAL;
  491. if (newlist != NULL) {
  492. free_objlist(newlist);
  493. *numobj = 0;
  494. newlist = NULL;
  495. }
  496. } else {
  497. if (validity == KMF_ALL_CERTS) {
  498. *objlist = newlist;
  499. } else {
  500. OBJLIST *node, *prev;
  501. KMF_X509_DER_CERT tmp_kmf_cert;
  502. uint32_t i = 0;
  503. node = prev = newlist;
  504. /*
  505. * Now check to see if any found certificate is expired
  506. * or valid.
  507. */
  508. while (node != NULL && i < (*numobj)) {
  509. (void) memset(&tmp_kmf_cert, 0,
  510. sizeof (KMF_X509_DER_CERT));
  511. rv = PK11Cert2KMFCert(kmfh, node->handle,
  512. &tmp_kmf_cert);
  513. if (rv != KMF_OK) {
  514. goto cleanup1;
  515. }
  516. rv = kmf_check_cert_date(handle,
  517. &tmp_kmf_cert.certificate);
  518. if (validity == KMF_NONEXPIRED_CERTS) {
  519. if (rv == KMF_OK) {
  520. num_ok_certs++;
  521. prev = node;
  522. node = node->next;
  523. } else if (rv ==
  524. KMF_ERR_VALIDITY_PERIOD) {
  525. /*
  526. * expired - remove it from list
  527. */
  528. pk11_delete_obj_from_list(
  529. &newlist, &prev, &node);
  530. } else {
  531. goto cleanup1;
  532. }
  533. }
  534. if (validity == KMF_EXPIRED_CERTS) {
  535. if (rv == KMF_ERR_VALIDITY_PERIOD) {
  536. num_ok_certs++;
  537. prev = node;
  538. node = node->next;
  539. rv = KMF_OK;
  540. } else if (rv == KMF_OK) {
  541. /*
  542. * valid - remove it from list
  543. */
  544. pk11_delete_obj_from_list(
  545. &newlist, &prev, &node);
  546. } else {
  547. goto cleanup1;
  548. }
  549. }
  550. i++;
  551. kmf_free_kmf_cert(handle, &tmp_kmf_cert);
  552. }
  553. *numobj = num_ok_certs;
  554. *objlist = newlist;
  555. }
  556. }
  557. cleanup1:
  558. if (rv != KMF_OK && newlist != NULL) {
  559. free_objlist(newlist);
  560. *numobj = 0;
  561. *objlist = NULL;
  562. }
  563. if (issuer != NULL)
  564. kmf_free_dn(&issuerDN);
  565. if (subject != NULL)
  566. kmf_free_dn(&subjectDN);
  567. return (rv);
  568. }
  569. /*
  570. * The caller may pass a NULL value for kmf_cert below and the function will
  571. * just return the number of certs found (in num_certs).
  572. */
  573. KMF_RETURN
  574. KMFPK11_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
  575. {
  576. KMF_RETURN rv = 0;
  577. uint32_t want_certs;
  578. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  579. OBJLIST *objlist = NULL;
  580. uint32_t *num_certs;
  581. KMF_X509_DER_CERT *kmf_cert = NULL;
  582. char *certlabel = NULL;
  583. char *issuer = NULL;
  584. char *subject = NULL;
  585. KMF_BIGINT *serial = NULL;
  586. KMF_CERT_VALIDITY validity;
  587. boolean_t private;
  588. if (kmfh == NULL)
  589. return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
  590. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  591. return (KMF_ERR_NO_TOKEN_SELECTED);
  592. num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
  593. if (num_certs == NULL)
  594. return (KMF_ERR_BAD_PARAMETER);
  595. if (*num_certs > 0)
  596. want_certs = *num_certs;
  597. else
  598. want_certs = MAXINT; /* count them all */
  599. *num_certs = 0;
  600. /* Get the optional returned certificate list */
  601. kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist,
  602. numattr);
  603. /* Get optional search criteria attributes */
  604. certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
  605. issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
  606. subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
  607. serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
  608. rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
  609. &validity, NULL);
  610. if (rv != KMF_OK) {
  611. validity = KMF_ALL_CERTS;
  612. rv = KMF_OK;
  613. }
  614. rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
  615. (void *)&private, NULL);
  616. if (rv != KMF_OK) {
  617. private = B_FALSE;
  618. rv = KMF_OK;
  619. }
  620. /* Start searching */
  621. rv = search_certs(handle, certlabel, issuer, subject, serial, private,
  622. validity, &objlist, num_certs);
  623. if (rv == KMF_OK && objlist != NULL && kmf_cert != NULL) {
  624. OBJLIST *node = objlist;
  625. int i = 0;
  626. while (node != NULL && i < want_certs) {
  627. rv = PK11Cert2KMFCert(kmfh, node->handle,
  628. &kmf_cert[i]);
  629. i++;
  630. node = node->next;
  631. }
  632. }
  633. if (objlist != NULL)
  634. free_objlist(objlist);
  635. if (*num_certs == 0)
  636. rv = KMF_ERR_CERT_NOT_FOUND;
  637. return (rv);
  638. }
  639. /*ARGSUSED*/
  640. void
  641. KMFPK11_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert)
  642. {
  643. if (kmf_cert != NULL && kmf_cert->certificate.Data != NULL) {
  644. free(kmf_cert->certificate.Data);
  645. kmf_cert->certificate.Data = NULL;
  646. kmf_cert->certificate.Length = 0;
  647. if (kmf_cert->kmf_private.label != NULL) {
  648. free(kmf_cert->kmf_private.label);
  649. kmf_cert->kmf_private.label = NULL;
  650. }
  651. }
  652. }
  653. KMF_RETURN
  654. KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey,
  655. KMF_DATA *eData)
  656. {
  657. KMF_RETURN ret = KMF_OK;
  658. CK_RV rv;
  659. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  660. CK_OBJECT_CLASS ckObjClass = CKO_PUBLIC_KEY;
  661. CK_KEY_TYPE ckKeyType;
  662. KMF_DATA Modulus, Exponent, Prime, Subprime, Base, Value;
  663. KMF_OID *Algorithm;
  664. BerElement *asn1 = NULL;
  665. BerValue *PubKeyParams = NULL, *EncodedKey = NULL;
  666. KMF_X509_SPKI spki;
  667. CK_ATTRIBUTE rsaTemplate[4];
  668. CK_ATTRIBUTE dsaTemplate[6];
  669. if (kmfh == NULL)
  670. return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
  671. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  672. return (KMF_ERR_NO_TOKEN_SELECTED);
  673. if (pKey == NULL || pKey->keyp == CK_INVALID_HANDLE)
  674. return (KMF_ERR_BAD_PARAMETER);
  675. (void) memset(&Modulus, 0, sizeof (Modulus));
  676. (void) memset(&Exponent, 0, sizeof (Exponent));
  677. (void) memset(&Prime, 0, sizeof (Prime));
  678. (void) memset(&Subprime, 0, sizeof (Subprime));
  679. (void) memset(&Base, 0, sizeof (Base));
  680. (void) memset(&Value, 0, sizeof (Value));
  681. SETATTR(rsaTemplate, 0, CKA_CLASS, &ckObjClass, sizeof (ckObjClass));
  682. SETATTR(rsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType, sizeof (ckKeyType));
  683. SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data, &Modulus.Length);
  684. SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT, Exponent.Data,
  685. &Exponent.Length);
  686. SETATTR(dsaTemplate, 0, CKA_CLASS, &ckObjClass, sizeof (ckObjClass));
  687. SETATTR(dsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType, sizeof (ckKeyType));
  688. SETATTR(dsaTemplate, 2, CKA_PRIME, Prime.Data, &Prime.Length);
  689. SETATTR(dsaTemplate, 3, CKA_SUBPRIME, Subprime.Data, &Subprime.Length);
  690. SETATTR(dsaTemplate, 4, CKA_BASE, Base.Data, &Base.Length);
  691. SETATTR(dsaTemplate, 5, CKA_VALUE, Value.Data, &Value.Length);
  692. switch (pKey->keyalg) {
  693. case KMF_RSA:
  694. /* Get the length of the fields */
  695. rv = C_GetAttributeValue(kmfh->pk11handle,
  696. (CK_OBJECT_HANDLE)pKey->keyp, rsaTemplate, 4);
  697. if (rv != CKR_OK) {
  698. SET_ERROR(kmfh, rv);
  699. return (KMF_ERR_BAD_PARAMETER);
  700. }
  701. Modulus.Length = rsaTemplate[2].ulValueLen;
  702. Modulus.Data = malloc(Modulus.Length);
  703. if (Modulus.Data == NULL)
  704. return (KMF_ERR_MEMORY);
  705. Exponent.Length = rsaTemplate[3].ulValueLen;
  706. Exponent.Data = malloc(Exponent.Length);
  707. if (Exponent.Data == NULL) {
  708. free(Modulus.Data);
  709. return (KMF_ERR_MEMORY);
  710. }
  711. SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data,
  712. Modulus.Length);
  713. SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT,
  714. Exponent.Data, Exponent.Length);
  715. /* Now get the values */
  716. rv = C_GetAttributeValue(kmfh->pk11handle,
  717. (CK_OBJECT_HANDLE)pKey->keyp, rsaTemplate, 4);
  718. if (rv != CKR_OK) {
  719. SET_ERROR(kmfh, rv);
  720. free(Modulus.Data);
  721. free(Exponent.Data);
  722. return (KMF_ERR_BAD_PARAMETER);
  723. }
  724. /*
  725. * This is the KEY algorithm, not the
  726. * signature algorithm.
  727. */
  728. Algorithm = x509_algid_to_algoid(KMF_ALGID_RSA);
  729. if (Algorithm != NULL) {
  730. /* Encode the RSA Key Data */
  731. if ((asn1 = kmfder_alloc()) == NULL) {
  732. free(Modulus.Data);
  733. free(Exponent.Data);
  734. return (KMF_ERR_MEMORY);
  735. }
  736. if (kmfber_printf(asn1, "{II}", Modulus.Data,
  737. Modulus.Length, Exponent.Data,
  738. Exponent.Length) == -1) {
  739. kmfber_free(asn1, 1);
  740. free(Modulus.Data);
  741. free(Exponent.Data);
  742. return (KMF_ERR_ENCODING);
  743. }
  744. if (kmfber_flatten(asn1, &EncodedKey) == -1) {
  745. kmfber_free(asn1, 1);
  746. free(Modulus.Data);
  747. free(Exponent.Data);
  748. return (KMF_ERR_ENCODING);
  749. }
  750. kmfber_free(asn1, 1);
  751. }
  752. free(Exponent.Data);
  753. free(Modulus.Data);
  754. break;
  755. case KMF_DSA:
  756. /* Get the length of the fields */
  757. rv = C_GetAttributeValue(kmfh->pk11handle,
  758. (CK_OBJECT_HANDLE)pKey->keyp, dsaTemplate, 6);
  759. if (rv != CKR_OK) {
  760. SET_ERROR(kmfh, rv);
  761. return (KMF_ERR_BAD_PARAMETER);
  762. }
  763. Prime.Length = dsaTemplate[2].ulValueLen;
  764. Prime.Data = malloc(Prime.Length);
  765. if (Prime.Data == NULL) {
  766. return (KMF_ERR_MEMORY);
  767. }
  768. Subprime.Length = dsaTemplate[3].ulValueLen;
  769. Subprime.Data = malloc(Subprime.Length);
  770. if (Subprime.Data == NULL) {
  771. free(Prime.Data);
  772. return (KMF_ERR_MEMORY);
  773. }
  774. Base.Length = dsaTemplate[4].ulValueLen;
  775. Base.Data = malloc(Base.Length);
  776. if (Base.Data == NULL) {
  777. free(Prime.Data);
  778. free(Subprime.Data);
  779. return (KMF_ERR_MEMORY);
  780. }
  781. Value.Length = dsaTemplate[5].ulValueLen;
  782. Value.Data = malloc(Value.Length);
  783. if (Value.Data == NULL) {
  784. free(Prime.Data);
  785. free(Subprime.Data);
  786. free(Base.Data);
  787. return (KMF_ERR_MEMORY);
  788. }
  789. SETATTR(dsaTemplate, 2, CKA_PRIME, Prime.Data,
  790. Prime.Length);
  791. SETATTR(dsaTemplate, 3, CKA_SUBPRIME, Subprime.Data,
  792. Subprime.Length);
  793. SETATTR(dsaTemplate, 4, CKA_BASE, Base.Data,
  794. Base.Length);
  795. SETATTR(dsaTemplate, 5, CKA_VALUE, Value.Data,
  796. Value.Length);
  797. /* Now get the values */
  798. rv = C_GetAttributeValue(kmfh->pk11handle,
  799. (CK_OBJECT_HANDLE)pKey->keyp, dsaTemplate, 6);
  800. if (rv != CKR_OK) {
  801. free(Prime.Data);
  802. free(Subprime.Data);
  803. free(Base.Data);
  804. free(Value.Data);
  805. SET_ERROR(kmfh, rv);
  806. return (KMF_ERR_BAD_PARAMETER);
  807. }
  808. /*
  809. * This is the KEY algorithm, not the
  810. * signature algorithm.
  811. */
  812. Algorithm = x509_algid_to_algoid(KMF_ALGID_DSA);
  813. /* Encode the DSA Algorithm Parameters */
  814. if ((asn1 = kmfder_alloc()) == NULL) {
  815. free(Prime.Data);
  816. free(Subprime.Data);
  817. free(Base.Data);
  818. free(Value.Data);
  819. return (KMF_ERR_MEMORY);
  820. }
  821. if (kmfber_printf(asn1, "{III}", Prime.Data,
  822. Prime.Length, Subprime.Data, Subprime.Length,
  823. Base.Data, Base.Length) == -1) {
  824. kmfber_free(asn1, 1);
  825. free(Prime.Data);
  826. free(Subprime.Data);
  827. free(Base.Data);
  828. free(Value.Data);
  829. return (KMF_ERR_ENCODING);
  830. }
  831. if (kmfber_flatten(asn1, &PubKeyParams) == -1) {
  832. kmfber_free(asn1, 1);
  833. free(Prime.Data);
  834. free(Subprime.Data);
  835. free(Base.Data);
  836. free(Value.Data);
  837. return (KMF_ERR_ENCODING);
  838. }
  839. kmfber_free(asn1, 1);
  840. free(Prime.Data);
  841. free(Subprime.Data);
  842. free(Base.Data);
  843. /* Encode the DSA Key Value */
  844. if ((asn1 = kmfder_alloc()) == NULL) {
  845. free(Value.Data);
  846. return (KMF_ERR_MEMORY);
  847. }
  848. if (kmfber_printf(asn1, "I",
  849. Value.Data, Value.Length) == -1) {
  850. kmfber_free(asn1, 1);
  851. free(Value.Data);
  852. return (KMF_ERR_ENCODING);
  853. }
  854. if (kmfber_flatten(asn1, &EncodedKey) == -1) {
  855. kmfber_free(asn1, 1);
  856. free(Value.Data);
  857. return (KMF_ERR_ENCODING);
  858. }
  859. kmfber_free(asn1, 1);
  860. free(Value.Data);
  861. break;
  862. default:
  863. return (KMF_ERR_BAD_PARAMETER);
  864. }
  865. /* Now, build an SPKI structure for the final encoding step */
  866. spki.algorithm.algorithm = *Algorithm;
  867. if (PubKeyParams != NULL) {
  868. spki.algorithm.parameters.Data =
  869. (uchar_t *)PubKeyParams->bv_val;
  870. spki.algorithm.parameters.Length = PubKeyParams->bv_len;
  871. } else {
  872. spki.algorithm.parameters.Data = NULL;
  873. spki.algorithm.parameters.Length = 0;
  874. }
  875. if (EncodedKey != NULL) {
  876. spki.subjectPublicKey.Data = (uchar_t *)EncodedKey->bv_val;
  877. spki.subjectPublicKey.Length = EncodedKey->bv_len;
  878. } else {
  879. spki.subjectPublicKey.Data = NULL;
  880. spki.subjectPublicKey.Length = 0;
  881. }
  882. /* Finally, encode the entire SPKI record */
  883. ret = DerEncodeSPKI(&spki, eData);
  884. cleanup:
  885. if (EncodedKey) {
  886. free(EncodedKey->bv_val);
  887. free(EncodedKey);
  888. }
  889. if (PubKeyParams) {
  890. free(PubKeyParams->bv_val);
  891. free(PubKeyParams);
  892. }
  893. return (ret);
  894. }
  895. static KMF_RETURN
  896. CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert)
  897. {
  898. KMF_RETURN rv = 0;
  899. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  900. KMF_X509_CERTIFICATE *signed_cert_ptr = NULL;
  901. KMF_DATA data;
  902. KMF_DATA Id;
  903. CK_RV ckrv;
  904. CK_ULONG subject_len, issuer_len, serno_len;
  905. CK_BYTE *subject, *issuer, *serial, nullserno;
  906. CK_BBOOL true = TRUE;
  907. CK_CERTIFICATE_TYPE certtype = CKC_X_509;
  908. CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
  909. CK_ATTRIBUTE x509templ[11];
  910. CK_OBJECT_HANDLE hCert = NULL;
  911. int i;
  912. if (kmfh == NULL)
  913. return (KMF_ERR_INTERNAL); /* should not happen */
  914. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  915. return (KMF_ERR_INTERNAL); /* should not happen */
  916. if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0)
  917. return (KMF_ERR_INTERNAL); /* should not happen */
  918. /*
  919. * The data *must* be a DER encoded X.509 certificate.
  920. * Convert it to a CSSM cert and then parse the fields so
  921. * the PKCS#11 attributes can be filled in correctly.
  922. */
  923. rv = DerDecodeSignedCertificate((const KMF_DATA *)pcert,
  924. &signed_cert_ptr);
  925. if (rv != KMF_OK) {
  926. return (KMF_ERR_ENCODING);
  927. }
  928. /*
  929. * Encode fields into PKCS#11 attributes.
  930. */
  931. /* Get the subject name */
  932. rv = DerEncodeName(&signed_cert_ptr->certificate.subject, &data);
  933. if (rv == KMF_OK) {
  934. subject = data.Data;
  935. subject_len = data.Length;
  936. } else {
  937. rv = KMF_ERR_ENCODING;
  938. goto cleanup;
  939. }
  940. /* Encode the issuer */
  941. rv = DerEncodeName(&signed_cert_ptr->certificate.issuer, &data);
  942. if (rv == KMF_OK) {
  943. issuer = data.Data;
  944. issuer_len = data.Length;
  945. } else {
  946. rv = KMF_ERR_ENCODING;
  947. goto cleanup;
  948. }
  949. /* Encode serial number */
  950. if (signed_cert_ptr->certificate.serialNumber.len > 0 &&
  951. signed_cert_ptr->certificate.serialNumber.val != NULL) {
  952. serial = signed_cert_ptr->certificate.serialNumber.val;
  953. serno_len = signed_cert_ptr->certificate.serialNumber.len;
  954. } else {
  955. /*
  956. * RFC3280 says to gracefully handle certs with serial numbers
  957. * of 0.
  958. */
  959. nullserno = '\0';
  960. serial = &nullserno;
  961. serno_len = 1;
  962. }
  963. /* Generate an ID from the SPKI data */
  964. rv = GetIDFromSPKI(&signed_cert_ptr->certificate.subjectPublicKeyInfo,
  965. &Id);
  966. if (rv != KMF_OK) {
  967. SET_ERROR(kmfh, rv);
  968. goto cleanup;
  969. }
  970. i = 0;
  971. SETATTR(x509templ, i, CKA_CLASS, &certClass, sizeof (certClass)); i++;
  972. SETATTR(x509templ, i, CKA_CERTIFICATE_TYPE, &certtype,
  973. sizeof (certtype));
  974. i++;
  975. SETATTR(x509templ, i, CKA_TOKEN, &true, sizeof (true)); i++;
  976. SETATTR(x509templ, i, CKA_SUBJECT, subject, subject_len); i++;
  977. SETATTR(x509templ, i, CKA_ISSUER, issuer, issuer_len); i++;
  978. SETATTR(x509templ, i, CKA_SERIAL_NUMBER, serial, serno_len); i++;
  979. SETATTR(x509templ, i, CKA_VALUE, pcert->Data, pcert->Length); i++;
  980. SETATTR(x509templ, i, CKA_ID, Id.Data, Id.Length); i++;
  981. if (label != NULL && strlen(label)) {
  982. SETATTR(x509templ, i, CKA_LABEL, label, strlen(label)); i++;
  983. }
  984. /*
  985. * The cert object handle is actually "leaked" here. If the app
  986. * really wants to clean up the data space, it will have to call
  987. * KMF_DeleteCert and specify the softtoken keystore.
  988. */
  989. ckrv = C_CreateObject(kmfh->pk11handle, x509templ, i, &hCert);
  990. if (ckrv != CKR_OK) {
  991. SET_ERROR(kmfh, rv);
  992. rv = KMF_ERR_INTERNAL;
  993. }
  994. free(subject);
  995. free(issuer);
  996. cleanup:
  997. if (Id.Data != NULL)
  998. free(Id.Data);
  999. if (signed_cert_ptr) {
  1000. kmf_free_signed_cert(signed_cert_ptr);
  1001. free(signed_cert_ptr);
  1002. }
  1003. return (rv);
  1004. }
  1005. KMF_RETURN
  1006. KMFPK11_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
  1007. {
  1008. KMF_RETURN rv = 0;
  1009. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  1010. KMF_DATA *cert = NULL;
  1011. char *label = NULL;
  1012. if (kmfh == NULL)
  1013. return (KMF_ERR_UNINITIALIZED);
  1014. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  1015. return (KMF_ERR_NO_TOKEN_SELECTED);
  1016. cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
  1017. if (cert == NULL || cert->Data == NULL || cert->Length == 0)
  1018. return (KMF_ERR_BAD_PARAMETER);
  1019. /* label attribute is optional */
  1020. label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
  1021. rv = CreateCertObject(handle, label, cert);
  1022. return (rv);
  1023. }
  1024. KMF_RETURN
  1025. KMFPK11_ImportCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
  1026. {
  1027. KMF_RETURN rv = 0;
  1028. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  1029. char *certfile = NULL;
  1030. char *label = NULL;
  1031. KMF_ENCODE_FORMAT format;
  1032. KMF_DATA cert1 = { NULL, 0};
  1033. KMF_DATA cert2 = { NULL, 0};
  1034. if (kmfh == NULL)
  1035. return (KMF_ERR_UNINITIALIZED);
  1036. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  1037. return (KMF_ERR_NO_TOKEN_SELECTED);
  1038. /*
  1039. * Get the input cert filename attribute, check if it is a valid
  1040. * certificate and auto-detect the file format of it.
  1041. */
  1042. certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
  1043. if (certfile == NULL)
  1044. return (KMF_ERR_BAD_PARAMETER);
  1045. rv = kmf_is_cert_file(handle, certfile, &format);
  1046. if (rv != KMF_OK)
  1047. return (rv);
  1048. /* Read in the CERT file */
  1049. rv = kmf_read_input_file(handle, certfile, &cert1);
  1050. if (rv != KMF_OK) {
  1051. return (rv);
  1052. }
  1053. /* The label attribute is optional */
  1054. label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
  1055. /*
  1056. * If the input certificate is in PEM format, we need to convert
  1057. * it to DER first.
  1058. */
  1059. if (format == KMF_FORMAT_PEM) {
  1060. int derlen;
  1061. rv = kmf_pem_to_der(cert1.Data, cert1.Length,
  1062. &cert2.Data, &derlen);
  1063. if (rv != KMF_OK) {
  1064. goto out;
  1065. }
  1066. cert2.Length = (size_t)derlen;
  1067. }
  1068. rv = CreateCertObject(handle, label,
  1069. format == KMF_FORMAT_ASN1 ? &cert1 : &cert2);
  1070. out:
  1071. if (cert1.Data != NULL) {
  1072. free(cert1.Data);
  1073. }
  1074. if (cert2.Data != NULL) {
  1075. free(cert2.Data);
  1076. }
  1077. return (rv);
  1078. }
  1079. KMF_RETURN
  1080. KMFPK11_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
  1081. {
  1082. KMF_RETURN rv = 0;
  1083. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  1084. OBJLIST *objlist;
  1085. uint32_t numObjects = 0;
  1086. char *certlabel = NULL;
  1087. char *issuer = NULL;
  1088. char *subject = NULL;
  1089. KMF_BIGINT *serial = NULL;
  1090. KMF_CERT_VALIDITY validity;
  1091. boolean_t private;
  1092. if (kmfh == NULL)
  1093. return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
  1094. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  1095. return (KMF_ERR_NO_TOKEN_SELECTED);
  1096. /* Get the search criteria attributes. They are all optional. */
  1097. certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
  1098. issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
  1099. subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
  1100. serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
  1101. rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
  1102. &validity, NULL);
  1103. if (rv != KMF_OK) {
  1104. validity = KMF_ALL_CERTS;
  1105. rv = KMF_OK;
  1106. }
  1107. rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
  1108. (void *)&private, NULL);
  1109. if (rv != KMF_OK) {
  1110. private = B_FALSE;
  1111. rv = KMF_OK;
  1112. }
  1113. /*
  1114. * Start searching for certificates that match the criteria and
  1115. * delete them.
  1116. */
  1117. objlist = NULL;
  1118. rv = search_certs(handle, certlabel, issuer, subject, serial,
  1119. private, validity, &objlist, &numObjects);
  1120. if (rv == KMF_OK && objlist != NULL) {
  1121. OBJLIST *node = objlist;
  1122. while (node != NULL) {
  1123. CK_RV ckrv;
  1124. ckrv = C_DestroyObject(kmfh->pk11handle, node->handle);
  1125. if (ckrv != CKR_OK) {
  1126. SET_ERROR(kmfh, ckrv);
  1127. rv = KMF_ERR_INTERNAL;
  1128. break;
  1129. }
  1130. node = node->next;
  1131. }
  1132. free_objlist(objlist);
  1133. }
  1134. if (rv == KMF_OK && numObjects == 0)
  1135. rv = KMF_ERR_CERT_NOT_FOUND;
  1136. out:
  1137. return (rv);
  1138. }
  1139. KMF_RETURN
  1140. KMFPK11_CreateKeypair(KMF_HANDLE_T handle,
  1141. int numattr,
  1142. KMF_ATTRIBUTE *attlist)
  1143. {
  1144. KMF_RETURN rv = KMF_OK;
  1145. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  1146. CK_RV ckrv = 0;
  1147. CK_OBJECT_HANDLE pubKey = CK_INVALID_HANDLE;
  1148. CK_OBJECT_HANDLE priKey = CK_INVALID_HANDLE;
  1149. CK_SESSION_HANDLE hSession = kmfh->pk11handle;
  1150. static CK_OBJECT_CLASS priClass = CKO_PRIVATE_KEY;
  1151. static CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
  1152. static CK_ULONG rsaKeyType = CKK_RSA;
  1153. static CK_ULONG modulusBits = 1024;
  1154. uint32_t modulusBits_size = sizeof (CK_ULONG);
  1155. static CK_BYTE PubExpo[3] = {0x01, 0x00, 0x01};
  1156. static CK_BBOOL true = TRUE;
  1157. static CK_BBOOL ontoken = TRUE;
  1158. static CK_BBOOL false = FALSE;
  1159. static CK_ULONG dsaKeyType = CKK_DSA;
  1160. CK_ATTRIBUTE rsaPubKeyTemplate[16];
  1161. CK_ATTRIBUTE rsaPriKeyTemplate[16];
  1162. static CK_BYTE ckDsaPrime[128] = {
  1163. 0xb2, 0x6b, 0xc3, 0xfb, 0xe3, 0x26, 0xf4, 0xc2,
  1164. 0xcf, 0xdd, 0xf9, 0xae, 0x3e, 0x39, 0x7f, 0x9c,
  1165. 0xa7, 0x73, 0xc3, 0x00, 0xa3, 0x50, 0x67, 0xc3,
  1166. 0xab, 0x49, 0x2c, 0xea, 0x59, 0x10, 0xa4, 0xbc,
  1167. 0x09, 0x94, 0xa9, 0x05, 0x3b, 0x0d, 0x35, 0x3c,
  1168. 0x55, 0x52, 0x47, 0xf0, 0xe3, 0x72, 0x5b, 0xe8,
  1169. 0x72, 0xa0, 0x71, 0x1c, 0x23, 0x4f, 0x6d, 0xe8,
  1170. 0xac, 0xe5, 0x21, 0x1b, 0xc0, 0xd8, 0x42, 0xd3,
  1171. 0x87, 0xae, 0x83, 0x5e, 0x52, 0x7e, 0x46, 0x09,
  1172. 0xb5, 0xc7, 0x3d, 0xd6, 0x00, 0xf5, 0xf2, 0x9c,
  1173. 0x84, 0x30, 0x81, 0x7e, 0x7b, 0x30, 0x5b, 0xd5,
  1174. 0xab, 0xd0, 0x2f, 0x21, 0xb3, 0xd8, 0xed, 0xdb,
  1175. 0x97, 0x77, 0xe4, 0x7e, 0x6c, 0xcc, 0xb9, 0x6b,
  1176. 0xdd, 0xaa, 0x96, 0x04, 0xe7, 0xd4, 0x55, 0x11,
  1177. 0x53, 0xab, 0xba, 0x95, 0x9a, 0xa2, 0x8c, 0x27,
  1178. 0xd9, 0xcf, 0xad, 0xf3, 0xcf, 0x3a, 0x0c, 0x4b};
  1179. static CK_BYTE ckDsaSubPrime[20] = {
  1180. 0xa4, 0x5f, 0x2a, 0x27, 0x09, 0x49, 0xb6, 0xfe,
  1181. 0x73, 0xeb, 0x95, 0x7d, 0x00, 0xf3, 0x42, 0xfc,
  1182. 0x78, 0x47, 0xb0, 0xd5};
  1183. static CK_BYTE ckDsaBase[128] = {
  1184. 0x5c, 0x57, 0x16, 0x49, 0xef, 0xc8, 0xfb, 0x4b,
  1185. 0xee, 0x07, 0x45, 0x3b, 0x6a, 0x1d, 0xf3, 0xe5,
  1186. 0xeb, 0xee, 0xad, 0x11, 0x13, 0xe3, 0x52, 0xe3,
  1187. 0x0d, 0xc0, 0x21, 0x25, 0xfa, 0xf0, 0x93, 0x1c,
  1188. 0x53, 0x4d, 0xdc, 0x0d, 0x76, 0xd2, 0xfe, 0xc2,
  1189. 0xd7, 0x72, 0x64, 0x69, 0x53, 0x3d, 0x33, 0xbd,
  1190. 0xe1, 0x34, 0xf2, 0x5a, 0x67, 0x83, 0xe0, 0xd3,
  1191. 0x1c, 0xd6, 0x41, 0x4d, 0x16, 0xe8, 0x6c, 0x5a,
  1192. 0x07, 0x95, 0x21, 0x9a, 0xa3, 0xc4, 0xb9, 0x05,
  1193. 0x9d, 0x11, 0xcb, 0xc8, 0xc4, 0x9d, 0x00, 0x1a,
  1194. 0xf4, 0x85, 0x2a, 0xa9, 0x20, 0x3c, 0xba, 0x67,
  1195. 0xe5, 0xed, 0x31, 0xb2, 0x11, 0xfb, 0x1f, 0x73,
  1196. 0xec, 0x61, 0x29, 0xad, 0xc7, 0x68, 0xb2, 0x3f,
  1197. 0x38, 0xea, 0xd9, 0x87, 0x83, 0x9e, 0x7e, 0x19,
  1198. 0x18, 0xdd, 0xc2, 0xc3, 0x5b, 0x16, 0x6d, 0xce,
  1199. 0xcf, 0x88, 0x91, 0x07, 0xe0, 0x2b, 0xa8, 0x54 };
  1200. static CK_ATTRIBUTE ckDsaPubKeyTemplate[] = {
  1201. { CKA_CLASS, &pubClass, sizeof (pubClass) },
  1202. { CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType) },
  1203. { CKA_TOKEN, &ontoken, sizeof (ontoken)},
  1204. { CKA_PRIVATE, &false, sizeof (false)},
  1205. { CKA_PRIME, &ckDsaPrime, sizeof (ckDsaPrime) },
  1206. { CKA_SUBPRIME, &ckDsaSubPrime, sizeof (ckDsaSubPrime)},
  1207. { CKA_BASE, &ckDsaBase, sizeof (ckDsaBase) },
  1208. { CKA_VERIFY, &true, sizeof (true) },
  1209. };
  1210. #define NUMBER_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \
  1211. sizeof (CK_ATTRIBUTE))
  1212. #define MAX_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \
  1213. sizeof (CK_ATTRIBUTE))
  1214. static CK_ATTRIBUTE ckDsaPriKeyTemplate[] = {
  1215. {CKA_CLASS, &priClass, sizeof (priClass)},
  1216. {CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType)},
  1217. {CKA_TOKEN, &ontoken, sizeof (ontoken)},
  1218. {CKA_PRIVATE, &true, sizeof (true)},
  1219. {CKA_SIGN, &true, sizeof (true)},
  1220. };
  1221. CK_ATTRIBUTE labelattr[1];
  1222. CK_ATTRIBUTE idattr[1];
  1223. char IDHashData[SHA1_HASH_LENGTH];
  1224. KMF_DATA IDInput, IDOutput;
  1225. SHA1_CTX ctx;
  1226. KMF_CREDENTIAL *cred;
  1227. KMF_KEY_ALG keytype = KMF_RSA;
  1228. boolean_t storekey = TRUE;
  1229. char *keylabel = NULL;
  1230. KMF_KEY_HANDLE *pubkey, *privkey;
  1231. #define NUMBER_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \
  1232. sizeof (CK_ATTRIBUTE))
  1233. #define MAX_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \
  1234. sizeof (CK_ATTRIBUTE))
  1235. if (kmfh == NULL)
  1236. return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
  1237. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  1238. return (KMF_ERR_NO_TOKEN_SELECTED);
  1239. /* "storekey" is optional. Default is TRUE */
  1240. (void) kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attlist, numattr,
  1241. &storekey, NULL);
  1242. cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attlist, numattr);
  1243. if (cred == NULL)
  1244. return (KMF_ERR_BAD_PARAMETER);
  1245. rv = pk11_authenticate(handle, cred);
  1246. if (rv != KMF_OK)
  1247. return (rv);
  1248. /* keytype is optional. KMF_RSA is default */
  1249. (void) kmf_get_attr(KMF_KEYALG_ATTR, attlist, numattr,
  1250. (void *)&keytype, NULL);
  1251. pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr);
  1252. if (pubkey == NULL)
  1253. return (KMF_ERR_BAD_PARAMETER);
  1254. privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist, numattr);
  1255. if (privkey == NULL)
  1256. return (KMF_ERR_BAD_PARAMETER);
  1257. (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE));
  1258. (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE));
  1259. if (keytype == KMF_RSA) {
  1260. CK_MECHANISM keyGenMech = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0};
  1261. CK_BYTE *modulus;
  1262. CK_ULONG modulusLength;
  1263. CK_ATTRIBUTE modattr[1];
  1264. KMF_BIGINT *rsaexp = NULL;
  1265. int numpubattr = 0, numpriattr = 0;
  1266. rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attlist, numattr,
  1267. &modulusBits, &modulusBits_size);
  1268. if (rv == KMF_ERR_ATTR_NOT_FOUND)
  1269. /* Default modulusBits = 1024 */
  1270. rv = KMF_OK;
  1271. if (rv != KMF_OK)
  1272. return (KMF_ERR_BAD_PARAMETER);
  1273. SETATTR(rsaPubKeyTemplate, numpubattr, CKA_CLASS,
  1274. &pubClass, sizeof (pubClass));
  1275. numpubattr++;
  1276. SETATTR(rsaPubKeyTemplate, numpubattr, CKA_KEY_TYPE,
  1277. &rsaKeyType, sizeof (rsaKeyType));
  1278. numpubattr++;
  1279. SETATTR(rsaPubKeyTemplate, numpubattr, CKA_TOKEN,
  1280. (storekey ? &true : &false), sizeof (CK_BBOOL));
  1281. numpubattr++;
  1282. SETATTR(rsaPubKeyTemplate, numpubattr, CKA_PRIVATE,
  1283. &false, sizeof (false));
  1284. numpubattr++;
  1285. SETATTR(rsaPubKeyTemplate, numpubattr, CKA_MODULUS_BITS,
  1286. &modulusBits, sizeof (modulusBits));
  1287. numpubattr++;
  1288. if ((rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attlist,
  1289. numattr)) != NULL &&
  1290. (rsaexp->len > 0 && rsaexp->val != NULL)) {
  1291. SETATTR(rsaPubKeyTemplate, numpubattr,
  1292. CKA_PUBLIC_EXPONENT,
  1293. rsaexp->val, rsaexp->len);
  1294. numpubattr++;
  1295. } else {
  1296. rv = KMF_OK;
  1297. SETATTR(rsaPubKeyTemplate, numpubattr,
  1298. CKA_PUBLIC_EXPONENT, &PubExpo, sizeof (PubExpo));
  1299. numpubattr++;
  1300. }
  1301. SETATTR(rsaPubKeyTemplate, numpubattr, CKA_ENCRYPT,
  1302. &true, sizeof (true));
  1303. numpubattr++;
  1304. SETATTR(rsaPubKeyTemplate, numpubattr, CKA_VERIFY,
  1305. &true, sizeof (true));
  1306. numpubattr++;
  1307. SETATTR(rsaPriKeyTemplate, numpriattr, CKA_CLASS, &priClass,
  1308. sizeof (priClass));
  1309. numpriattr++;
  1310. SETATTR(rsaPriKeyTemplate, numpriattr, CKA_KEY_TYPE,
  1311. &rsaKeyType, sizeof (rsaKeyType));
  1312. numpriattr++;
  1313. SETATTR(rsaPriKeyTemplate, numpriattr, CKA_TOKEN,
  1314. (storekey ? &true : &false), sizeof (CK_BBOOL));
  1315. numpriattr++;
  1316. SETATTR(rsaPriKeyTemplate, numpriattr, CKA_PRIVATE, &true,
  1317. sizeof (true));
  1318. numpriattr++;
  1319. SETATTR(rsaPriKeyTemplate, numpriattr, CKA_DECRYPT, &true,
  1320. sizeof (true));
  1321. numpriattr++;
  1322. SETATTR(rsaPriKeyTemplate, numpriattr, CKA_SIGN, &true,
  1323. sizeof (true));
  1324. numpriattr++;
  1325. SETATTR(modattr, 0, CKA_MODULUS, NULL, &modulusLength);
  1326. pubKey = CK_INVALID_HANDLE;
  1327. priKey = CK_INVALID_HANDLE;
  1328. ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
  1329. rsaPubKeyTemplate, numpubattr,
  1330. rsaPriKeyTemplate, numpriattr,
  1331. &pubKey, &priKey);
  1332. if (ckrv != CKR_OK) {
  1333. SET_ERROR(kmfh, ckrv);
  1334. return (KMF_ERR_KEYGEN_FAILED);
  1335. }
  1336. privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
  1337. privkey->keyalg = KMF_RSA;
  1338. privkey->keyclass = KMF_ASYM_PRI;
  1339. privkey->keyp = (void *)priKey;
  1340. pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
  1341. pubkey->keyalg = KMF_RSA;
  1342. pubkey->keyclass = KMF_ASYM_PUB;
  1343. pubkey->keyp = (void *)pubKey;
  1344. /* Get the Modulus field to use as input for creating the ID */
  1345. rv = C_GetAttributeValue(kmfh->pk11handle,
  1346. (CK_OBJECT_HANDLE)pubKey, modattr, 1);
  1347. if (rv != CKR_OK) {
  1348. SET_ERROR(kmfh, ckrv);
  1349. return (KMF_ERR_BAD_PARAMETER);
  1350. }
  1351. modulusLength = modattr[0].ulValueLen;
  1352. modulus = malloc(modulusLength);
  1353. if (modulus == NULL)
  1354. return (KMF_ERR_MEMORY);
  1355. modattr[0].pValue = modulus;
  1356. rv = C_GetAttributeValue(kmfh->pk11handle,
  1357. (CK_OBJECT_HANDLE)pubKey, modattr, 1);
  1358. if (rv != CKR_OK) {
  1359. SET_ERROR(kmfh, ckrv);
  1360. free(modulus);
  1361. return (KMF_ERR_BAD_PARAMETER);
  1362. }
  1363. IDInput.Data = modulus;
  1364. IDInput.Length = modulusLength;
  1365. } else if (keytype == KMF_DSA) {
  1366. CK_MECHANISM keyGenMech = {CKM_DSA_KEY_PAIR_GEN, NULL, 0};
  1367. CK_BYTE *keyvalue;
  1368. CK_ULONG valueLen;
  1369. CK_ATTRIBUTE valattr[1];
  1370. SETATTR(ckDsaPriKeyTemplate, 2, CKA_TOKEN,
  1371. (storekey ? &true : &false), sizeof (CK_BBOOL));
  1372. SETATTR(valattr, 0, CKA_VALUE, NULL, &valueLen);
  1373. ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
  1374. ckDsaPubKeyTemplate,
  1375. (sizeof (ckDsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)),
  1376. ckDsaPriKeyTemplate,
  1377. (sizeof (ckDsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)),
  1378. &pubKey, &priKey);
  1379. if (ckrv != CKR_OK) {
  1380. SET_ERROR(kmfh, ckrv);
  1381. return (KMF_ERR_KEYGEN_FAILED);
  1382. }
  1383. privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
  1384. privkey->keyalg = KMF_DSA;
  1385. privkey->keyclass = KMF_ASYM_PRI;
  1386. privkey->keyp = (void *)priKey;
  1387. pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
  1388. pubkey->keyalg = KMF_DSA;
  1389. pubkey->keyclass = KMF_ASYM_PUB;
  1390. pubkey->keyp = (void *)pubKey;
  1391. /* Get the Public Value to use as input for creating the ID */
  1392. rv = C_GetAttributeValue(hSession,
  1393. (CK_OBJECT_HANDLE)pubKey, valattr, 1);
  1394. if (rv != CKR_OK) {
  1395. SET_ERROR(kmfh, ckrv);
  1396. return (KMF_ERR_BAD_PARAMETER);
  1397. }
  1398. valueLen = valattr[0].ulValueLen;
  1399. keyvalue = malloc(valueLen);
  1400. if (keyvalue == NULL)
  1401. return (KMF_ERR_MEMORY);
  1402. valattr[0].pValue = keyvalue;
  1403. rv = C_GetAttributeValue(hSession,
  1404. (CK_OBJECT_HANDLE)pubKey, valattr, 1);
  1405. if (rv != CKR_OK) {
  1406. SET_ERROR(kmfh, ckrv);
  1407. free(keyvalue);
  1408. return (KMF_ERR_BAD_PARAMETER);
  1409. }
  1410. IDInput.Data = keyvalue;
  1411. IDInput.Length = valueLen;
  1412. } else {
  1413. return (KMF_ERR_BAD_PARAMETER);
  1414. }
  1415. keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attlist, numattr);
  1416. if (keylabel != NULL && strlen(keylabel)) {
  1417. SETATTR(labelattr, 0, CKA_LABEL, keylabel, strlen(keylabel));
  1418. /* Set the CKA_LABEL if one was indicated */
  1419. if ((ckrv = C_SetAttributeValue(hSession, pubKey,
  1420. labelattr, 1)) != CKR_OK) {
  1421. SET_ERROR(kmfh, ckrv);
  1422. rv = KMF_ERR_INTERNAL;
  1423. goto cleanup;
  1424. }
  1425. pubkey->keylabel = (char *)strdup(keylabel);
  1426. if (pubkey->keylabel == NULL) {
  1427. rv = KMF_ERR_MEMORY;
  1428. goto cleanup;
  1429. }
  1430. if ((ckrv = C_SetAttributeValue(hSession, priKey,
  1431. labelattr, 1)) != CKR_OK) {
  1432. SET_ERROR(kmfh, ckrv);
  1433. rv = KMF_ERR_INTERNAL;
  1434. goto cleanup;
  1435. }
  1436. privkey->keylabel = (char *)strdup(keylabel);
  1437. if (privkey->keylabel == NULL) {
  1438. rv = KMF_ERR_MEMORY;
  1439. goto cleanup;
  1440. }
  1441. } else {
  1442. rv = KMF_OK;
  1443. }
  1444. /* Now, assign a CKA_ID value so it can be searched */
  1445. /* ID_Input was assigned above in the RSA or DSA keygen section */
  1446. IDOutput.Data = (uchar_t *)IDHashData;
  1447. IDOutput.Length = sizeof (IDHashData);
  1448. SHA1Init(&ctx);
  1449. SHA1Update(&ctx, IDInput.Data, IDInput.Length);
  1450. SHA1Final(IDOutput.Data, &ctx);
  1451. IDOutput.Length = SHA1_DIGEST_LENGTH;
  1452. free(IDInput.Data);
  1453. if (rv != CKR_OK) {
  1454. SET_ERROR(kmfh, rv);
  1455. goto cleanup;
  1456. }
  1457. SETATTR(idattr, 0, CKA_ID, IDOutput.Data, IDOutput.Length);
  1458. if ((ckrv = C_SetAttributeValue(hSession, pubKey,
  1459. idattr, 1)) != CKR_OK) {
  1460. SET_ERROR(kmfh, ckrv);
  1461. rv = KMF_ERR_INTERNAL;
  1462. goto cleanup;
  1463. }
  1464. if ((ckrv = C_SetAttributeValue(hSession, priKey,
  1465. idattr, 1)) != CKR_OK) {
  1466. SET_ERROR(kmfh, ckrv);
  1467. rv = KMF_ERR_INTERNAL;
  1468. goto cleanup;
  1469. }
  1470. cleanup:
  1471. if (rv != KMF_OK) {
  1472. if (pubKey != CK_INVALID_HANDLE)
  1473. (void) C_DestroyObject(hSession, pubKey);
  1474. if (priKey != CK_INVALID_HANDLE)
  1475. (void) C_DestroyObject(hSession, priKey);
  1476. if (privkey->keylabel)
  1477. free(privkey->keylabel);
  1478. if (pubkey->keylabel)
  1479. free(pubkey->keylabel);
  1480. }
  1481. return (rv);
  1482. }
  1483. KMF_RETURN
  1484. KMFPK11_DeleteKey(KMF_HANDLE_T handle,
  1485. int numattr, KMF_ATTRIBUTE *attrlist)
  1486. {
  1487. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  1488. CK_RV ckrv = CKR_OK;
  1489. KMF_RETURN rv = KMF_OK;
  1490. KMF_KEY_HANDLE *key;
  1491. KMF_CREDENTIAL cred;
  1492. boolean_t destroy = B_TRUE;
  1493. if (kmfh == NULL)
  1494. return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
  1495. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  1496. return (KMF_ERR_NO_TOKEN_SELECTED);
  1497. key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
  1498. if (key == NULL || key->keyp == NULL)
  1499. return (KMF_ERR_BAD_PARAMETER);
  1500. if (key->keyclass != KMF_ASYM_PUB &&
  1501. key->keyclass != KMF_ASYM_PRI &&
  1502. key->keyclass != KMF_SYMMETRIC)
  1503. return (KMF_ERR_BAD_KEY_CLASS);
  1504. /* "destroy" is optional. Default is TRUE */
  1505. (void) kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
  1506. (void *)&destroy, NULL);
  1507. if (destroy) {
  1508. rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
  1509. (void *)&cred, NULL);
  1510. if (rv != KMF_OK)
  1511. return (KMF_ERR_BAD_PARAMETER);
  1512. rv = pk11_authenticate(handle, &cred);
  1513. if (rv != KMF_OK) {
  1514. return (rv);
  1515. }
  1516. }
  1517. if (!key->israw && destroy)
  1518. ckrv = C_DestroyObject(kmfh->pk11handle,
  1519. (CK_OBJECT_HANDLE)key->keyp);
  1520. if (ckrv != CKR_OK) {
  1521. SET_ERROR(kmfh, ckrv);
  1522. /* Report authentication failures to the caller */
  1523. if (ckrv == CKR_PIN_EXPIRED || ckrv == CKR_SESSION_READ_ONLY)
  1524. rv = KMF_ERR_AUTH_FAILED;
  1525. else
  1526. rv = KMF_ERR_INTERNAL;
  1527. }
  1528. return (rv);
  1529. }
  1530. KMF_RETURN
  1531. KMFPK11_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp,
  1532. KMF_OID *algOID,
  1533. KMF_DATA *tobesigned,
  1534. KMF_DATA *output)
  1535. {
  1536. CK_RV ckrv;
  1537. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  1538. CK_SESSION_HANDLE hSession = kmfh->pk11handle;
  1539. CK_MECHANISM mechanism;
  1540. PKCS_ALGORITHM_MAP *pAlgMap;
  1541. KMF_ALGORITHM_INDEX AlgId;
  1542. if (kmfh == NULL)
  1543. return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
  1544. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  1545. return (KMF_ERR_NO_TOKEN_SELECTED);
  1546. if (keyp == NULL || algOID == NULL ||
  1547. tobesigned == NULL || output == NULL)
  1548. return (KMF_ERR_BAD_PARAMETER);
  1549. /* These functions are available to the plugin from libkmf */
  1550. AlgId = x509_algoid_to_algid(algOID);
  1551. if (AlgId == KMF_ALGID_NONE)
  1552. return (KMF_ERR_BAD_PARAMETER);
  1553. /* Map the Algorithm OID to a PKCS#11 mechanism */
  1554. pAlgMap = pkcs_get_alg_map(KMF_ALGCLASS_SIGNATURE,
  1555. AlgId, PKCS_GetDefaultSignatureMode(AlgId));
  1556. if (pAlgMap == NULL)
  1557. return (KMF_ERR_BAD_PARAMETER);
  1558. mechanism.mechanism = pAlgMap->pkcs_mechanism;
  1559. mechanism.pParameter = NULL;
  1560. mechanism.ulParameterLen = 0;
  1561. ckrv = C_SignInit(hSession, &mechanism, (CK_OBJECT_HANDLE)keyp->keyp);
  1562. if (ckrv != CKR_OK) {
  1563. SET_ERROR(kmfh, ckrv);
  1564. return (KMF_ERR_INTERNAL);
  1565. }
  1566. ckrv = C_Sign(hSession, tobesigned->Data, tobesigned->Length,
  1567. output->Data, (CK_ULONG *)&output->Length);
  1568. if (ckrv != CKR_OK) {
  1569. SET_ERROR(kmfh, ckrv);
  1570. return (KMF_ERR_INTERNAL);
  1571. }
  1572. return (KMF_OK);
  1573. }
  1574. KMF_RETURN
  1575. KMFPK11_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
  1576. {
  1577. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  1578. *msgstr = NULL;
  1579. if (kmfh->lasterr.errcode != 0) {
  1580. char *e = pkcs11_strerror(kmfh->lasterr.errcode);
  1581. if (e == NULL || (*msgstr = (char *)strdup(e)) == NULL) {
  1582. return (KMF_ERR_MEMORY);
  1583. }
  1584. }
  1585. return (KMF_OK);
  1586. }
  1587. static CK_RV
  1588. getObjectKeytype(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
  1589. CK_ULONG *keytype)
  1590. {
  1591. CK_RV rv = CKR_OK;
  1592. CK_ATTRIBUTE templ;
  1593. CK_ULONG len = sizeof (CK_ULONG);
  1594. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  1595. templ.type = CKA_KEY_TYPE;
  1596. templ.pValue = keytype;
  1597. templ.ulValueLen = len;
  1598. rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
  1599. return (rv);
  1600. }
  1601. static CK_RV
  1602. getObjectLabel(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
  1603. char **outlabel)
  1604. {
  1605. CK_RV rv = CKR_OK;
  1606. CK_ATTRIBUTE templ;
  1607. char Label[BUFSIZ];
  1608. CK_ULONG len = sizeof (Label);
  1609. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  1610. (void) memset(Label, 0, len);
  1611. templ.type = CKA_LABEL;
  1612. templ.pValue = Label;
  1613. templ.ulValueLen = len;
  1614. rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
  1615. if (rv == CKR_OK) {
  1616. *outlabel = (char *)strdup(Label);
  1617. } else {
  1618. *outlabel = NULL;
  1619. }
  1620. return (rv);
  1621. }
  1622. static CK_RV
  1623. getObjectKeyclass(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
  1624. KMF_KEY_CLASS *keyclass)
  1625. {
  1626. CK_RV rv = CKR_OK;
  1627. CK_ATTRIBUTE templ;
  1628. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  1629. CK_OBJECT_CLASS class;
  1630. templ.type = CKA_CLASS;
  1631. templ.pValue = &class;
  1632. templ.ulValueLen = sizeof (CK_OBJECT_CLASS);
  1633. rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
  1634. if (rv == CKR_OK) {
  1635. if (class == CKO_PUBLIC_KEY) {
  1636. *keyclass = KMF_ASYM_PUB;
  1637. } else if (class == CKO_PRIVATE_KEY) {
  1638. *keyclass = KMF_ASYM_PRI;
  1639. } else if (class == CKO_SECRET_KEY) {
  1640. *keyclass = KMF_SYMMETRIC;
  1641. }
  1642. } else {
  1643. *keyclass = KMF_KEYCLASS_NONE;
  1644. }
  1645. return (rv);
  1646. }
  1647. KMF_RETURN
  1648. KMFPK11_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr,
  1649. KMF_ATTRIBUTE *attrlist)
  1650. {
  1651. KMF_X509_SPKI *pubkey;
  1652. KMF_X509_CERTIFICATE *SignerCert = NULL;
  1653. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  1654. KMF_RETURN rv = KMF_OK;
  1655. CK_RV ckrv = CKR_OK;
  1656. CK_ATTRIBUTE templ[4];
  1657. CK_OBJECT_HANDLE pri_obj = CK_INVALID_HANDLE;
  1658. CK_ULONG obj_count;
  1659. CK_OBJECT_CLASS certClass = CKO_PRIVATE_KEY;
  1660. CK_BBOOL true = TRUE;
  1661. KMF_DATA Id = { NULL, 0 };
  1662. KMF_KEY_HANDLE *key = NULL;
  1663. KMF_DATA *cert = NULL;
  1664. KMF_CREDENTIAL cred;
  1665. KMF_ENCODE_FORMAT format = KMF_FORMAT_UNDEF;
  1666. CK_ULONG keytype;
  1667. /* Get the key handle */
  1668. key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
  1669. if (key == NULL)
  1670. return (KMF_ERR_BAD_PARAMETER);
  1671. /* Get the optional encoded format */
  1672. (void) kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
  1673. (void *)&format, NULL);
  1674. /* Decode the signer cert so we can get the SPKI data */
  1675. cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
  1676. if (cert == NULL || cert->Data == NULL)
  1677. return (KMF_ERR_BAD_PARAMETER);
  1678. if ((rv = DerDecodeSignedCertificate(cert,
  1679. &SignerCert)) != KMF_OK)
  1680. return (rv);
  1681. /* Get the public key info from the signer certificate */
  1682. pubkey = &SignerCert->certificate.subjectPublicKeyInfo;
  1683. /* Generate an ID from the SPKI data */
  1684. rv = GetIDFromSPKI(pubkey, &Id);
  1685. if (rv != KMF_OK) {
  1686. SET_ERROR(kmfh, rv);
  1687. goto errout;
  1688. }
  1689. /* Get the credential and login */
  1690. rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
  1691. (void *)&cred, NULL);
  1692. if (rv != KMF_OK)
  1693. return (KMF_ERR_BAD_PARAMETER);
  1694. rv = pk11_authenticate(handle, &cred);
  1695. if (rv != KMF_OK) {
  1696. return (rv);
  1697. }
  1698. /* Start searching */
  1699. SETATTR(templ, 0, CKA_CLASS, &certClass, sizeof (certClass));
  1700. SETATTR(templ, 1, CKA_TOKEN, &true, sizeof (true));
  1701. SETATTR(templ, 2, CKA_PRIVATE, &true, sizeof (true));
  1702. SETATTR(templ, 3, CKA_ID, Id.Data, Id.Length);
  1703. if ((ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, 4)) != CKR_OK) {
  1704. SET_ERROR(kmfh, ckrv);
  1705. rv = KMF_ERR_INTERNAL;
  1706. goto errout;
  1707. }
  1708. if ((rv = C_FindObjects(kmfh->pk11handle, &pri_obj, 1,
  1709. &obj_count)) != CKR_OK) {
  1710. SET_ERROR(kmfh, ckrv);
  1711. rv = KMF_ERR_INTERNAL;
  1712. goto errout;
  1713. }
  1714. if (obj_count == 0) {
  1715. SET_ERROR(kmfh, ckrv);
  1716. rv = KMF_ERR_INTERNAL;
  1717. goto errout;
  1718. }
  1719. key->kstype = KMF_KEYSTORE_PK11TOKEN;
  1720. key->keyclass = KMF_ASYM_PRI;
  1721. key->keyp = (void *)pri_obj;
  1722. key->israw = FALSE;
  1723. (void) C_FindObjectsFinal(kmfh->pk11handle);
  1724. ckrv = getObjectLabel(handle, (CK_OBJECT_HANDLE)key->keyp,
  1725. &key->keylabel);
  1726. if (ckrv != CKR_OK) {
  1727. SET_ERROR(handle, ckrv);
  1728. rv = KMF_ERR_INTERNAL;
  1729. } else {
  1730. rv = KMF_OK;
  1731. }
  1732. /*
  1733. * The key->keyalg value is needed if we need to convert the key
  1734. * to raw key. However, the key->keyalg value will not be set if
  1735. * this function is not called thru the kmf_find_prikey_by_cert()
  1736. * framework function. To be safe, we will get the keytype from
  1737. * the key object and set key->keyalg value here.
  1738. */
  1739. ckrv = getObjectKeytype(handle, (CK_OBJECT_HANDLE)key->keyp,
  1740. &keytype);
  1741. if (ckrv != CKR_OK) {
  1742. SET_ERROR(handle, ckrv);
  1743. rv = KMF_ERR_INTERNAL;
  1744. } else {
  1745. rv = KMF_OK;
  1746. }
  1747. if (keytype == CKK_RSA)
  1748. key->keyalg = KMF_RSA;
  1749. else if (keytype == CKK_DSA)
  1750. key->keyalg = KMF_DSA;
  1751. else {
  1752. /* For asymmetric keys, we only support RSA and DSA */
  1753. rv = KMF_ERR_KEY_NOT_FOUND;
  1754. goto errout;
  1755. }
  1756. if (rv == KMF_OK && format == KMF_FORMAT_RAWKEY) {
  1757. KMF_RAW_KEY_DATA *rkey = NULL;
  1758. rv = keyObj2RawKey(handle, key, &rkey);
  1759. if (rv == KMF_OK) {
  1760. key->keyp = rkey;
  1761. key->israw = TRUE;
  1762. }
  1763. }
  1764. errout:
  1765. if (Id.Data != NULL)
  1766. free(Id.Data);
  1767. if (SignerCert != NULL) {
  1768. kmf_free_signed_cert(SignerCert);
  1769. free(SignerCert);
  1770. }
  1771. return (rv);
  1772. }
  1773. KMF_RETURN
  1774. KMFPK11_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
  1775. KMF_OID *algOID, KMF_DATA *ciphertext,
  1776. KMF_DATA *output)
  1777. {
  1778. CK_RV ckrv;
  1779. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  1780. CK_SESSION_HANDLE hSession = kmfh->pk11handle;
  1781. CK_MECHANISM mechanism;
  1782. PKCS_ALGORITHM_MAP *pAlgMap;
  1783. KMF_ALGORITHM_INDEX AlgId;
  1784. CK_ULONG out_len = 0, block_len = 0, total_decrypted = 0;
  1785. uint8_t *in_data, *out_data;
  1786. int i, blocks;
  1787. CK_ATTRIBUTE ckTemplate[1];
  1788. if (kmfh == NULL)
  1789. return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
  1790. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  1791. return (KMF_ERR_NO_TOKEN_SELECTED);
  1792. if (key == NULL || algOID == NULL ||
  1793. ciphertext == NULL || output == NULL)
  1794. return (KMF_ERR_BAD_PARAMETER);
  1795. AlgId = x509_algoid_to_algid(algOID);
  1796. if (AlgId == KMF_ALGID_NONE)
  1797. return (KMF_ERR_BAD_PARAMETER);
  1798. /* Map the Algorithm ID to a PKCS#11 mechanism */
  1799. pAlgMap = pkcs_get_alg_map(KMF_ALGCLASS_SIGNATURE,
  1800. AlgId, PKCS_GetDefaultSignatureMode(AlgId));
  1801. if (pAlgMap == NULL)
  1802. return (KMF_ERR_BAD_PARAMETER);
  1803. mechanism.mechanism = pAlgMap->pkcs_mechanism;
  1804. mechanism.pParameter = NULL;
  1805. mechanism.ulParameterLen = 0;
  1806. SETATTR(ckTemplate, 0, CKA_MODULUS, (CK_BYTE *)NULL,
  1807. sizeof (CK_ULONG));
  1808. /* Get the modulus length */
  1809. ckrv = C_GetAttributeValue(hSession,
  1810. (CK_OBJECT_HANDLE)key->keyp, ckTemplate, 1);
  1811. if (ckrv != CKR_OK) {
  1812. SET_ERROR(kmfh, ckrv);
  1813. return (KMF_ERR_INTERNAL);
  1814. }
  1815. block_len = ckTemplate[0].ulValueLen;
  1816. /* Compute the number of times to do single-part decryption */
  1817. blocks = ciphertext->Length/block_len;
  1818. out_data = output->Data;
  1819. in_data = ciphertext->Data;
  1820. out_len = block_len - 11;
  1821. for (i = 0; i < blocks; i++) {
  1822. ckrv = C_DecryptInit(hSession, &mechanism,
  1823. (CK_OBJECT_HANDLE)key->keyp);
  1824. if (ckrv != CKR_OK) {
  1825. SET_ERROR(kmfh, ckrv);
  1826. return (KMF_ERR_INTERNAL);
  1827. }
  1828. ckrv = C_Decrypt(hSession, in_data, block_len,
  1829. out_data, (CK_ULONG *)&out_len);
  1830. if (ckrv != CKR_OK) {
  1831. SET_ERROR(kmfh, ckrv);
  1832. return (KMF_ERR_INTERNAL);
  1833. }
  1834. out_data += out_len;
  1835. total_decrypted += out_len;
  1836. in_data += block_len;
  1837. }
  1838. output->Length = total_decrypted;
  1839. return (KMF_OK);
  1840. }
  1841. static void
  1842. attr2bigint(CK_ATTRIBUTE_PTR attr, KMF_BIGINT *big)
  1843. {
  1844. big->val = attr->pValue;
  1845. big->len = attr->ulValueLen;
  1846. }
  1847. static KMF_RETURN
  1848. get_bigint_attr(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj,
  1849. CK_ATTRIBUTE_TYPE attrtype, KMF_BIGINT *bigint)
  1850. {
  1851. CK_RV ckrv;
  1852. CK_ATTRIBUTE attr;
  1853. attr.type = attrtype;
  1854. attr.pValue = NULL;
  1855. attr.ulValueLen = 0;
  1856. if ((ckrv = C_GetAttributeValue(sess, obj,
  1857. &attr, 1)) != CKR_OK) {
  1858. /* Mask this error so the caller can continue */
  1859. if (ckrv == CKR_ATTRIBUTE_TYPE_INVALID)
  1860. return (KMF_OK);
  1861. else
  1862. return (KMF_ERR_INTERNAL);
  1863. }
  1864. if (attr.ulValueLen > 0 && bigint != NULL) {
  1865. attr.pValue = malloc(attr.ulValueLen);
  1866. if (attr.pValue == NULL)
  1867. return (KMF_ERR_MEMORY);
  1868. if ((ckrv = C_GetAttributeValue(sess, obj,
  1869. &attr, 1)) != CKR_OK)
  1870. if (ckrv != CKR_OK) {
  1871. free(attr.pValue);
  1872. return (KMF_ERR_INTERNAL);
  1873. }
  1874. bigint->val = attr.pValue;
  1875. bigint->len = attr.ulValueLen;
  1876. }
  1877. return (KMF_OK);
  1878. }
  1879. static KMF_RETURN
  1880. get_raw_rsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_RSA_KEY *rawrsa)
  1881. {
  1882. KMF_RETURN rv = KMF_OK;
  1883. CK_RV ckrv;
  1884. CK_SESSION_HANDLE sess = kmfh->pk11handle;
  1885. CK_ATTRIBUTE rsa_pri_attrs[2] = {
  1886. { CKA_MODULUS, NULL, 0 },
  1887. { CKA_PUBLIC_EXPONENT, NULL, 0 }
  1888. };
  1889. CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE);
  1890. int i;
  1891. if (rawrsa == NULL)
  1892. return (KMF_ERR_BAD_PARAMETER);
  1893. (void) memset(rawrsa, 0, sizeof (KMF_RAW_RSA_KEY));
  1894. if ((ckrv = C_GetAttributeValue(sess, obj,
  1895. rsa_pri_attrs, count)) != CKR_OK) {
  1896. SET_ERROR(kmfh, ckrv);
  1897. /* Tell the caller know why the key data cannot be retrieved. */
  1898. if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
  1899. return (KMF_ERR_SENSITIVE_KEY);
  1900. else if (ckrv == CKR_KEY_UNEXTRACTABLE)
  1901. return (KMF_ERR_UNEXTRACTABLE_KEY);
  1902. else
  1903. return (KMF_ERR_INTERNAL);
  1904. }
  1905. /* Allocate memory for each attribute. */
  1906. for (i = 0; i < count; i++) {
  1907. if (rsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 ||
  1908. rsa_pri_attrs[i].ulValueLen == 0) {
  1909. rsa_pri_attrs[i].ulValueLen = 0;
  1910. continue;
  1911. }
  1912. if ((rsa_pri_attrs[i].pValue =
  1913. malloc(rsa_pri_attrs[i].ulValueLen)) == NULL) {
  1914. rv = KMF_ERR_MEMORY;
  1915. goto end;
  1916. }
  1917. }
  1918. /* Now that we have space, really get the attributes */
  1919. if ((rv = C_GetAttributeValue(sess, obj,
  1920. rsa_pri_attrs, count)) != CKR_OK) {
  1921. SET_ERROR(kmfh, rv);
  1922. rv = KMF_ERR_INTERNAL;
  1923. goto end;
  1924. }
  1925. i = 0;
  1926. attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->mod);
  1927. attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->pubexp);
  1928. /* Now get the optional parameters */
  1929. rv = get_bigint_attr(sess, obj, CKA_PRIVATE_EXPONENT, &rawrsa->priexp);
  1930. if (rv != KMF_OK)
  1931. goto end;
  1932. rv = get_bigint_attr(sess, obj, CKA_PRIME_1, &rawrsa->prime1);
  1933. if (rv != KMF_OK)
  1934. goto end;
  1935. rv = get_bigint_attr(sess, obj, CKA_PRIME_2, &rawrsa->prime2);
  1936. if (rv != KMF_OK)
  1937. goto end;
  1938. rv = get_bigint_attr(sess, obj, CKA_EXPONENT_1, &rawrsa->exp1);
  1939. if (rv != KMF_OK)
  1940. goto end;
  1941. rv = get_bigint_attr(sess, obj, CKA_EXPONENT_2, &rawrsa->exp2);
  1942. if (rv != KMF_OK)
  1943. goto end;
  1944. rv = get_bigint_attr(sess, obj, CKA_COEFFICIENT, &rawrsa->coef);
  1945. if (rv != KMF_OK)
  1946. goto end;
  1947. end:
  1948. if (rv != KMF_OK) {
  1949. for (i = 0; i < count; i++) {
  1950. if (rsa_pri_attrs[i].pValue != NULL)
  1951. free(rsa_pri_attrs[i].pValue);
  1952. }
  1953. if (rawrsa->priexp.val)
  1954. free(rawrsa->priexp.val);
  1955. if (rawrsa->prime1.val)
  1956. free(rawrsa->prime1.val);
  1957. if (rawrsa->prime2.val)
  1958. free(rawrsa->prime2.val);
  1959. if (rawrsa->exp1.val)
  1960. free(rawrsa->exp1.val);
  1961. if (rawrsa->exp2.val)
  1962. free(rawrsa->exp2.val);
  1963. if (rawrsa->coef.val)
  1964. free(rawrsa->coef.val);
  1965. (void) memset(rawrsa, 0, sizeof (KMF_RAW_RSA_KEY));
  1966. }
  1967. return (rv);
  1968. }
  1969. #define DSA_PRIME_BUFSIZE 256 /* 8192 bits */
  1970. #define DSA_PRIVATE_BUFSIZE 5 /* 160 bits */
  1971. /*
  1972. * This function calculates the pubkey value from the prime,
  1973. * base and private key values of a DSA key.
  1974. */
  1975. static KMF_RETURN
  1976. compute_dsa_pubvalue(KMF_RAW_DSA_KEY *rawdsa)
  1977. {
  1978. KMF_RETURN rv = KMF_OK;
  1979. BIGNUM p, g, x, y;
  1980. BIG_ERR_CODE err;
  1981. uchar_t *pubvalue;
  1982. uint32_t pubvalue_len;
  1983. if ((err = big_init1(&p, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
  1984. rv = KMF_ERR_MEMORY;
  1985. return (rv);
  1986. }
  1987. bytestring2bignum(&p, rawdsa->prime.val, rawdsa->prime.len);
  1988. if ((err = big_init1(&g, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
  1989. rv = KMF_ERR_MEMORY;
  1990. goto ret1;
  1991. }
  1992. bytestring2bignum(&g, rawdsa->base.val, rawdsa->base.len);
  1993. if ((err = big_init1(&x, DSA_PRIVATE_BUFSIZE, NULL, 0)) != BIG_OK) {
  1994. rv = KMF_ERR_MEMORY;
  1995. goto ret2;
  1996. }
  1997. bytestring2bignum(&x, rawdsa->value.val, rawdsa->value.len);
  1998. if ((err = big_init1(&y, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
  1999. rv = KMF_ERR_MEMORY;
  2000. goto ret3;
  2001. }
  2002. err = big_modexp(&y, &g, &x, &p, NULL);
  2003. if (err != BIG_OK) {
  2004. rv = KMF_ERR_INTERNAL;
  2005. goto ret3;
  2006. }
  2007. pubvalue_len = y.len * (int)sizeof (uint32_t);
  2008. if ((pubvalue = malloc(pubvalue_len)) == NULL) {
  2009. rv = KMF_ERR_MEMORY;
  2010. goto ret4;
  2011. }
  2012. bignum2bytestring(pubvalue, &y, pubvalue_len);
  2013. rawdsa->pubvalue.val = pubvalue;
  2014. rawdsa->pubvalue.len = pubvalue_len;
  2015. ret4:
  2016. big_finish(&y);
  2017. ret3:
  2018. big_finish(&x);
  2019. ret2:
  2020. big_finish(&g);
  2021. ret1:
  2022. big_finish(&p);
  2023. return (rv);
  2024. }
  2025. static KMF_RETURN
  2026. get_raw_dsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_DSA_KEY *rawdsa)
  2027. {
  2028. KMF_RETURN rv = KMF_OK;
  2029. CK_RV ckrv;
  2030. CK_SESSION_HANDLE sess = kmfh->pk11handle;
  2031. CK_ATTRIBUTE dsa_pri_attrs[8] = {
  2032. { CKA_PRIME, NULL, 0 },
  2033. { CKA_SUBPRIME, NULL, 0 },
  2034. { CKA_BASE, NULL, 0 },
  2035. { CKA_VALUE, NULL, 0 }
  2036. };
  2037. CK_ULONG count = sizeof (dsa_pri_attrs) / sizeof (CK_ATTRIBUTE);
  2038. int i;
  2039. if ((ckrv = C_GetAttributeValue(sess, obj,
  2040. dsa_pri_attrs, count)) != CKR_OK) {
  2041. SET_ERROR(kmfh, ckrv);
  2042. /* Tell the caller know why the key data cannot be retrieved. */
  2043. if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
  2044. return (KMF_ERR_SENSITIVE_KEY);
  2045. else if (ckrv == CKR_KEY_UNEXTRACTABLE)
  2046. return (KMF_ERR_UNEXTRACTABLE_KEY);
  2047. return (KMF_ERR_INTERNAL);
  2048. }
  2049. /* Allocate memory for each attribute. */
  2050. for (i = 0; i < count; i++) {
  2051. if (dsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 ||
  2052. dsa_pri_attrs[i].ulValueLen == 0) {
  2053. dsa_pri_attrs[i].ulValueLen = 0;
  2054. continue;
  2055. }
  2056. if ((dsa_pri_attrs[i].pValue =
  2057. malloc(dsa_pri_attrs[i].ulValueLen)) == NULL) {
  2058. rv = KMF_ERR_MEMORY;
  2059. goto end;
  2060. }
  2061. }
  2062. if ((rv = C_GetAttributeValue(sess, obj,
  2063. dsa_pri_attrs, count)) != CKR_OK) {
  2064. SET_ERROR(kmfh, rv);
  2065. rv = KMF_ERR_INTERNAL;
  2066. goto end;
  2067. }
  2068. /* Fill in all the temp variables. They are all required. */
  2069. i = 0;
  2070. attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->prime);
  2071. attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->subprime);
  2072. attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->base);
  2073. attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->value);
  2074. /* Compute the public key value and store it */
  2075. rv = compute_dsa_pubvalue(rawdsa);
  2076. end:
  2077. if (rv != KMF_OK) {
  2078. for (i = 0; i < count; i++) {
  2079. if (dsa_pri_attrs[i].pValue != NULL)
  2080. free(dsa_pri_attrs[i].pValue);
  2081. }
  2082. (void) memset(rawdsa, 0, sizeof (KMF_RAW_DSA_KEY));
  2083. }
  2084. return (rv);
  2085. }
  2086. static KMF_RETURN
  2087. get_raw_sym(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_SYM_KEY *rawsym)
  2088. {
  2089. KMF_RETURN rv = KMF_OK;
  2090. CK_RV ckrv;
  2091. CK_SESSION_HANDLE sess = kmfh->pk11handle;
  2092. CK_ATTRIBUTE sym_attr[1];
  2093. CK_ULONG value_len = 0;
  2094. /* find the key length first */
  2095. sym_attr[0].type = CKA_VALUE;
  2096. sym_attr[0].pValue = NULL;
  2097. sym_attr[0].ulValueLen = value_len;
  2098. if ((ckrv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) {
  2099. rawsym->keydata.val = NULL;
  2100. rawsym->keydata.len = 0;
  2101. if (ckrv == CKR_ATTRIBUTE_SENSITIVE) {
  2102. return (KMF_ERR_SENSITIVE_KEY);
  2103. } else if (ckrv == CKR_KEY_UNEXTRACTABLE) {
  2104. return (KMF_ERR_UNEXTRACTABLE_KEY);
  2105. } else {
  2106. SET_ERROR(kmfh, ckrv);
  2107. return (KMF_ERR_INTERNAL);
  2108. }
  2109. }
  2110. /* Allocate memory for pValue */
  2111. sym_attr[0].pValue = malloc(sym_attr[0].ulValueLen);
  2112. if (sym_attr[0].pValue == NULL) {
  2113. return (KMF_ERR_MEMORY);
  2114. }
  2115. /* get the key data */
  2116. if ((rv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) {
  2117. SET_ERROR(kmfh, rv);
  2118. free(sym_attr[0].pValue);
  2119. return (KMF_ERR_INTERNAL);
  2120. }
  2121. rawsym->keydata.val = sym_attr[0].pValue;
  2122. rawsym->keydata.len = sym_attr[0].ulValueLen;
  2123. return (rv);
  2124. }
  2125. static KMF_RETURN
  2126. keyObj2RawKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *inkey,
  2127. KMF_RAW_KEY_DATA **outkey)
  2128. {
  2129. KMF_RETURN rv = KMF_OK;
  2130. KMF_RAW_KEY_DATA *rkey;
  2131. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  2132. rkey = malloc(sizeof (KMF_RAW_KEY_DATA));
  2133. if (rkey == NULL)
  2134. return (KMF_ERR_MEMORY);
  2135. (void) memset(rkey, 0, sizeof (KMF_RAW_KEY_DATA));
  2136. rkey->keytype = inkey->keyalg;
  2137. if (inkey->keyalg == KMF_RSA) {
  2138. rv = get_raw_rsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
  2139. &rkey->rawdata.rsa);
  2140. } else if (inkey->keyalg == KMF_DSA) {
  2141. rv = get_raw_dsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
  2142. &rkey->rawdata.dsa);
  2143. } else if (inkey->keyalg == KMF_AES ||
  2144. inkey->keyalg == KMF_RC4 ||
  2145. inkey->keyalg == KMF_DES ||
  2146. inkey->keyalg == KMF_DES3 ||
  2147. inkey->keyalg == KMF_GENERIC_SECRET) {
  2148. rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
  2149. &rkey->rawdata.sym);
  2150. /*
  2151. * If sensitive or non-extractable, mark them as such
  2152. * but return "OK" status so the keys get counted
  2153. * when doing FindKey operations.
  2154. */
  2155. if (rv == KMF_ERR_SENSITIVE_KEY) {
  2156. rkey->sensitive = B_TRUE;
  2157. rv = KMF_OK;
  2158. } else if (rv == KMF_ERR_UNEXTRACTABLE_KEY) {
  2159. rkey->not_extractable = B_TRUE;
  2160. rv = KMF_OK;
  2161. }
  2162. } else {
  2163. rv = KMF_ERR_BAD_PARAMETER;
  2164. }
  2165. if (rv == KMF_OK) {
  2166. *outkey = rkey;
  2167. } else if (rkey != NULL) {
  2168. free(rkey);
  2169. *outkey = NULL;
  2170. }
  2171. return (rv);
  2172. }
  2173. static KMF_RETURN
  2174. kmf2pk11keytype(KMF_KEY_ALG keyalg, CK_KEY_TYPE *type)
  2175. {
  2176. switch (keyalg) {
  2177. case KMF_RSA:
  2178. *type = CKK_RSA;
  2179. break;
  2180. case KMF_DSA:
  2181. *type = CKK_DSA;
  2182. break;
  2183. case KMF_AES:
  2184. *type = CKK_AES;
  2185. break;
  2186. case KMF_RC4:
  2187. *type = CKK_RC4;
  2188. break;
  2189. case KMF_DES:
  2190. *type = CKK_DES;
  2191. break;
  2192. case KMF_DES3:
  2193. *type = CKK_DES3;
  2194. break;
  2195. case KMF_GENERIC_SECRET:
  2196. *type = CKK_GENERIC_SECRET;
  2197. break;
  2198. default:
  2199. return (KMF_ERR_BAD_KEY_TYPE);
  2200. }
  2201. return (KMF_OK);
  2202. }
  2203. static int
  2204. IDStringToData(char *idstr, KMF_DATA *iddata)
  2205. {
  2206. int len, i;
  2207. char *iddup, *byte;
  2208. uint_t lvalue;
  2209. if (idstr == NULL || !strlen(idstr))
  2210. return (-1);
  2211. iddup = (char *)strdup(idstr);
  2212. if (iddup == NULL)
  2213. return (KMF_ERR_MEMORY);
  2214. len = strlen(iddup) / 3 + 1;
  2215. iddata->Data = malloc(len);
  2216. if (iddata->Data == NULL)
  2217. return (KMF_ERR_MEMORY);
  2218. (void) memset(iddata->Data, 0, len);
  2219. iddata->Length = len;
  2220. byte = strtok(iddup, ":");
  2221. if (byte == NULL) {
  2222. free(iddup);
  2223. free(iddata->Data);
  2224. iddata->Data = NULL;
  2225. iddata->Length = 0;
  2226. return (-1);
  2227. }
  2228. i = 0;
  2229. do {
  2230. (void) sscanf(byte, "%x", &lvalue);
  2231. iddata->Data[i++] = (uchar_t)(lvalue & 0x000000FF);
  2232. byte = strtok(NULL, ":");
  2233. } while (byte != NULL && i < len);
  2234. iddata->Length = i;
  2235. free(iddup);
  2236. return (0);
  2237. }
  2238. KMF_RETURN
  2239. KMFPK11_FindKey(KMF_HANDLE_T handle,
  2240. int numattr, KMF_ATTRIBUTE *attrlist)
  2241. {
  2242. KMF_RETURN rv = KMF_OK;
  2243. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  2244. uint32_t want_keys, i;
  2245. CK_RV ckrv;
  2246. CK_ATTRIBUTE pTmpl[10];
  2247. CK_OBJECT_CLASS class;
  2248. CK_BBOOL true = TRUE;
  2249. CK_ULONG alg;
  2250. boolean_t is_token = B_TRUE, is_private = B_FALSE;
  2251. KMF_KEY_HANDLE *keys;
  2252. uint32_t *numkeys;
  2253. KMF_CREDENTIAL *cred = NULL;
  2254. KMF_KEY_CLASS keyclass = KMF_KEYCLASS_NONE;
  2255. char *findLabel, *idstr;
  2256. KMF_KEY_ALG keytype = KMF_KEYALG_NONE;
  2257. KMF_ENCODE_FORMAT format;
  2258. if (kmfh == NULL)
  2259. return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
  2260. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  2261. return (KMF_ERR_NO_TOKEN_SELECTED);
  2262. numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
  2263. if (numkeys == NULL)
  2264. return (KMF_ERR_BAD_PARAMETER);
  2265. if (*numkeys > 0)
  2266. want_keys = *numkeys;
  2267. else
  2268. want_keys = MAXINT; /* count them all */
  2269. /* keyclass is optional */
  2270. (void) kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
  2271. (void *)&keyclass, NULL);
  2272. if (keyclass == KMF_ASYM_PUB) {
  2273. class = CKO_PUBLIC_KEY;
  2274. } else if (keyclass == KMF_ASYM_PRI) {
  2275. class = CKO_PRIVATE_KEY;
  2276. } else if (keyclass == KMF_SYMMETRIC) {
  2277. class = CKO_SECRET_KEY;
  2278. }
  2279. rv = kmf_get_attr(KMF_TOKEN_BOOL_ATTR, attrlist, numattr,
  2280. (void *)&is_token, NULL);
  2281. if (rv != KMF_OK)
  2282. return (rv);
  2283. i = 0;
  2284. if (is_token) {
  2285. SETATTR(pTmpl, i, CKA_TOKEN, &true, sizeof (true));
  2286. i++;
  2287. }
  2288. if (keyclass != KMF_KEYCLASS_NONE) {
  2289. SETATTR(pTmpl, i, CKA_CLASS, &class, sizeof (class));
  2290. i++;
  2291. }
  2292. findLabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
  2293. if (findLabel != NULL && strlen(findLabel)) {
  2294. SETATTR(pTmpl, i, CKA_LABEL, findLabel, strlen(findLabel));
  2295. i++;
  2296. }
  2297. /* keytype is optional */
  2298. (void) kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
  2299. (void *)&keytype, NULL);
  2300. if (keytype != 0) {
  2301. rv = kmf2pk11keytype(keytype, &alg);
  2302. if (rv != KMF_OK) {
  2303. return (KMF_ERR_BAD_KEY_TYPE);
  2304. }
  2305. SETATTR(pTmpl, i, CKA_KEY_TYPE, &alg, sizeof (alg));
  2306. i++;
  2307. }
  2308. idstr = kmf_get_attr_ptr(KMF_IDSTR_ATTR, attrlist, numattr);
  2309. if (idstr != NULL) {
  2310. KMF_DATA iddata = { NULL, 0 };
  2311. /*
  2312. * ID String parameter is assumed to be of form:
  2313. * XX:XX:XX:XX:XX ... :XX
  2314. * where XX is a hex number.
  2315. *
  2316. * We must convert this back to binary in order to
  2317. * use it in a search.
  2318. */
  2319. rv = IDStringToData(idstr, &iddata);
  2320. if (rv == KMF_OK) {
  2321. SETATTR(pTmpl, i, CKA_ID, iddata.Data, iddata.Length);
  2322. i++;
  2323. } else {
  2324. return (rv);
  2325. }
  2326. }
  2327. /* is_private is optional */
  2328. (void) kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
  2329. (void *)&is_private, NULL);
  2330. if (is_private) {
  2331. SETATTR(pTmpl, i, CKA_PRIVATE, &true, sizeof (true));
  2332. i++;
  2333. }
  2334. /*
  2335. * Authenticate if the object is a token object,
  2336. * a private or secred key, or if the user passed in credentials.
  2337. */
  2338. cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
  2339. if (cred != NULL && (cred->credlen > 0)) {
  2340. rv = pk11_authenticate(handle, cred);
  2341. if (rv != KMF_OK)
  2342. return (rv);
  2343. }
  2344. keys = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
  2345. /* it is okay to have "keys" contains NULL */
  2346. ckrv = C_FindObjectsInit(kmfh->pk11handle, pTmpl, i);
  2347. if (ckrv == CKR_OK) {
  2348. CK_ULONG obj_count, n = 0;
  2349. while (ckrv == CKR_OK && n < want_keys) {
  2350. CK_OBJECT_HANDLE hObj;
  2351. ckrv = C_FindObjects(kmfh->pk11handle, &hObj,
  2352. 1, &obj_count);
  2353. if (ckrv == CKR_OK && obj_count == 1) {
  2354. if (keys != NULL) {
  2355. CK_ULONG keytype;
  2356. keys[n].kstype = KMF_KEYSTORE_PK11TOKEN;
  2357. keys[n].israw = FALSE;
  2358. keys[n].keyp = (void *)hObj;
  2359. ckrv = getObjectKeytype(handle,
  2360. (CK_OBJECT_HANDLE)keys[n].keyp,
  2361. &keytype);
  2362. if (ckrv != CKR_OK)
  2363. goto end;
  2364. ckrv = getObjectLabel(handle,
  2365. (CK_OBJECT_HANDLE)keys[n].keyp,
  2366. &(keys[n].keylabel));
  2367. if (ckrv != CKR_OK)
  2368. goto end;
  2369. if (keyclass == KMF_KEYCLASS_NONE) {
  2370. ckrv = getObjectKeyclass(handle,
  2371. (CK_OBJECT_HANDLE)
  2372. keys[n].keyp,
  2373. &(keys[n].keyclass));
  2374. if (ckrv != CKR_OK)
  2375. goto end;
  2376. } else {
  2377. keys[n].keyclass = keyclass;
  2378. }
  2379. if (keytype == CKK_RSA) {
  2380. keys[n].keyalg = KMF_RSA;
  2381. } else if (keytype == CKK_DSA) {
  2382. keys[n].keyalg = KMF_DSA;
  2383. } else if (keytype == CKK_AES) {
  2384. keys[n].keyalg = KMF_AES;
  2385. keys[n].keyclass =
  2386. KMF_SYMMETRIC;
  2387. } else if (keytype == CKK_RC4) {
  2388. keys[n].keyalg = KMF_RC4;
  2389. keys[n].keyclass =
  2390. KMF_SYMMETRIC;
  2391. } else if (keytype == CKK_DES) {
  2392. keys[n].keyalg = KMF_DES;
  2393. keys[n].keyclass =
  2394. KMF_SYMMETRIC;
  2395. } else if (keytype == CKK_DES3) {
  2396. keys[n].keyalg = KMF_DES3;
  2397. keys[n].keyclass =
  2398. KMF_SYMMETRIC;
  2399. } else if (keytype ==
  2400. CKK_GENERIC_SECRET) {
  2401. keys[n].keyalg =
  2402. KMF_GENERIC_SECRET;
  2403. keys[n].keyclass =
  2404. KMF_SYMMETRIC;
  2405. }
  2406. }
  2407. n++;
  2408. } else {
  2409. break;
  2410. }
  2411. }
  2412. ckrv = C_FindObjectsFinal(kmfh->pk11handle);
  2413. /* "numkeys" indicates the number that were actually found */
  2414. *numkeys = n;
  2415. }
  2416. if (ckrv == KMF_OK && keys != NULL && (*numkeys) > 0) {
  2417. if ((rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist,
  2418. numattr, (void *)&format, NULL)) == KMF_OK) {
  2419. if (format == KMF_FORMAT_RAWKEY ||
  2420. format == KMF_FORMAT_PEM) {
  2421. /* Convert keys to "rawkey" format */
  2422. for (i = 0; i < (*numkeys); i++) {
  2423. KMF_RAW_KEY_DATA *rkey = NULL;
  2424. rv = keyObj2RawKey(handle, &keys[i],
  2425. &rkey);
  2426. if (rv == KMF_OK) {
  2427. keys[i].keyp = rkey;
  2428. keys[i].israw = TRUE;
  2429. } else {
  2430. break;
  2431. }
  2432. }
  2433. }
  2434. } else {
  2435. rv = KMF_OK; /* format is optional */
  2436. }
  2437. }
  2438. end:
  2439. if (ckrv != CKR_OK) {
  2440. SET_ERROR(kmfh, ckrv);
  2441. /* Report authentication failures to the caller */
  2442. if (ckrv == CKR_USER_NOT_LOGGED_IN ||
  2443. ckrv == CKR_PIN_INCORRECT ||
  2444. ckrv == CKR_PIN_INVALID ||
  2445. ckrv == CKR_PIN_EXPIRED ||
  2446. ckrv == CKR_PIN_LOCKED ||
  2447. ckrv == CKR_SESSION_READ_ONLY)
  2448. rv = KMF_ERR_AUTH_FAILED;
  2449. else
  2450. rv = KMF_ERR_INTERNAL;
  2451. } else if ((*numkeys) == 0) {
  2452. rv = KMF_ERR_KEY_NOT_FOUND;
  2453. }
  2454. return (rv);
  2455. }
  2456. static char *
  2457. convertDate(char *fulldate)
  2458. {
  2459. struct tm tms;
  2460. char newtime[9];
  2461. (void) strptime(fulldate, "%b %d %T %Y %Z", &tms);
  2462. if (tms.tm_year < 69)
  2463. tms.tm_year += 100;
  2464. (void) strftime(newtime, sizeof (newtime), "m%d", &tms);
  2465. newtime[8] = 0;
  2466. /* memory returned must be freed by the caller */
  2467. return ((char *)strdup(newtime));
  2468. }
  2469. static KMF_RETURN
  2470. store_raw_key(KMF_HANDLE_T handle,
  2471. KMF_ATTRIBUTE *attrlist, int numattr,
  2472. KMF_RAW_KEY_DATA *rawkey)
  2473. {
  2474. KMF_RETURN rv = KMF_OK;
  2475. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  2476. int i;
  2477. CK_RV ckrv = CKR_OK;
  2478. CK_ATTRIBUTE templ[32];
  2479. CK_OBJECT_HANDLE keyobj;
  2480. CK_KEY_TYPE keytype;
  2481. CK_OBJECT_CLASS oClass = CKO_PRIVATE_KEY;
  2482. CK_BBOOL cktrue = TRUE;
  2483. CK_DATE startdate, enddate;
  2484. KMF_DATA id = {NULL, 0};
  2485. KMF_DATA subject = {NULL, 0};
  2486. KMF_X509EXT_KEY_USAGE kuext;
  2487. KMF_X509_CERTIFICATE *x509 = NULL;
  2488. CK_BBOOL kufound = B_FALSE;
  2489. KMF_DATA *cert = NULL;
  2490. char *notbefore = NULL, *start = NULL;
  2491. char *notafter = NULL, *end = NULL;
  2492. char *keylabel = NULL;
  2493. if (kmfh == NULL)
  2494. return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
  2495. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  2496. return (KMF_ERR_NO_TOKEN_SELECTED);
  2497. if (rawkey->keytype == KMF_RSA)
  2498. keytype = CKK_RSA;
  2499. else if (rawkey->keytype == KMF_DSA)
  2500. keytype = CKK_DSA;
  2501. else
  2502. return (KMF_ERR_BAD_PARAMETER);
  2503. keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
  2504. /*
  2505. * If the caller did not specify a label, see if the raw key
  2506. * came with one (possible if it came from a PKCS#12 file).
  2507. */
  2508. if (keylabel == NULL) {
  2509. keylabel = rawkey->label;
  2510. }
  2511. i = 0;
  2512. SETATTR(templ, i, CKA_CLASS, &oClass, sizeof (CK_OBJECT_CLASS)); i++;
  2513. SETATTR(templ, i, CKA_KEY_TYPE, &keytype, sizeof (keytype)); i++;
  2514. SETATTR(templ, i, CKA_TOKEN, &cktrue, sizeof (cktrue)); i++;
  2515. SETATTR(templ, i, CKA_PRIVATE, &cktrue, sizeof (cktrue)); i++;
  2516. SETATTR(templ, i, CKA_DECRYPT, &cktrue, sizeof (cktrue)); i++;
  2517. cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
  2518. if (cert != NULL) {
  2519. id.Data = NULL;
  2520. id.Length = 0;
  2521. rv = kmf_get_cert_id_data(cert, &id);
  2522. if (rv != KMF_OK) {
  2523. goto cleanup;
  2524. }
  2525. rv = DerDecodeSignedCertificate((const KMF_DATA *)cert, &x509);
  2526. if (rv != KMF_OK) {
  2527. goto cleanup;
  2528. }
  2529. rv = DerEncodeName(&x509->certificate.subject, &subject);
  2530. if (rv != KMF_OK) {
  2531. goto cleanup;
  2532. }
  2533. SETATTR(templ, i, CKA_SUBJECT, subject.Data, subject.Length);
  2534. i++;
  2535. rv = kmf_get_cert_start_date_str(handle, cert, &notbefore);
  2536. if (rv != KMF_OK) {
  2537. goto cleanup;
  2538. }
  2539. start = convertDate(notbefore);
  2540. free(notbefore);
  2541. rv = kmf_get_cert_end_date_str(handle, cert, &notafter);
  2542. if (rv != KMF_OK) {
  2543. goto cleanup;
  2544. }
  2545. end = convertDate(notafter);
  2546. free(notafter);
  2547. if (id.Data != NULL && id.Data != NULL && id.Length > 0) {
  2548. SETATTR(templ, i, CKA_ID, id.Data, id.Length);
  2549. i++;
  2550. }
  2551. if (start != NULL) {
  2552. /*
  2553. * This makes some potentially dangerous assumptions:
  2554. * 1. that the startdate in the parameter block is
  2555. * properly formatted as YYYYMMDD
  2556. * 2. That the CK_DATE structure is always the same.
  2557. */
  2558. (void) memcpy(&startdate, start, sizeof (CK_DATE));
  2559. SETATTR(templ, i, CKA_START_DATE, &startdate,
  2560. sizeof (startdate));
  2561. i++;
  2562. }
  2563. if (end != NULL) {
  2564. (void) memcpy(&enddate, end, sizeof (CK_DATE));
  2565. SETATTR(templ, i, CKA_END_DATE, &enddate,
  2566. sizeof (enddate));
  2567. i++;
  2568. }
  2569. if ((rv = kmf_get_cert_ku(cert, &kuext)) != KMF_OK &&
  2570. rv != KMF_ERR_EXTENSION_NOT_FOUND)
  2571. goto cleanup;
  2572. kufound = (rv == KMF_OK);
  2573. rv = KMF_OK; /* reset if we got KMF_ERR_EXTENSION_NOT_FOUND */
  2574. }
  2575. /*
  2576. * Only set the KeyUsage stuff if the KU extension was present.
  2577. */
  2578. if (kufound) {
  2579. CK_BBOOL condition;
  2580. condition = (kuext.KeyUsageBits & KMF_keyEncipherment) ?
  2581. B_TRUE : B_FALSE;
  2582. SETATTR(templ, i, CKA_UNWRAP, &condition, sizeof (CK_BBOOL));
  2583. i++;
  2584. condition = (kuext.KeyUsageBits & KMF_dataEncipherment) ?
  2585. B_TRUE : B_FALSE;
  2586. SETATTR(templ, i, CKA_DECRYPT, &condition, sizeof (CK_BBOOL));
  2587. i++;
  2588. condition = (kuext.KeyUsageBits & KMF_digitalSignature) ?
  2589. B_TRUE : B_FALSE;
  2590. SETATTR(templ, i, CKA_SIGN, &condition, sizeof (CK_BBOOL));
  2591. i++;
  2592. condition = (kuext.KeyUsageBits & KMF_digitalSignature) ?
  2593. B_TRUE : B_FALSE;
  2594. SETATTR(templ, i, CKA_SIGN_RECOVER, &condition,
  2595. sizeof (CK_BBOOL));
  2596. i++;
  2597. }
  2598. if (keylabel != NULL) {
  2599. SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
  2600. i++;
  2601. }
  2602. if (id.Data == NULL && rawkey->id.Data != NULL) {
  2603. SETATTR(templ, i, CKA_ID, rawkey->id.Data,
  2604. rawkey->id.Length);
  2605. i++;
  2606. }
  2607. if (keytype == CKK_RSA) {
  2608. SETATTR(templ, i, CKA_MODULUS,
  2609. rawkey->rawdata.rsa.mod.val,
  2610. rawkey->rawdata.rsa.mod.len);
  2611. i++;
  2612. SETATTR(templ, i, CKA_PUBLIC_EXPONENT,
  2613. rawkey->rawdata.rsa.pubexp.val,
  2614. rawkey->rawdata.rsa.pubexp.len);
  2615. i++;
  2616. if (rawkey->rawdata.rsa.priexp.val != NULL) {
  2617. SETATTR(templ, i, CKA_PRIVATE_EXPONENT,
  2618. rawkey->rawdata.rsa.priexp.val,
  2619. rawkey->rawdata.rsa.priexp.len);
  2620. i++;
  2621. }
  2622. if (rawkey->rawdata.rsa.prime1.val != NULL) {
  2623. SETATTR(templ, i, CKA_PRIME_1,
  2624. rawkey->rawdata.rsa.prime1.val,
  2625. rawkey->rawdata.rsa.prime1.len);
  2626. i++;
  2627. }
  2628. if (rawkey->rawdata.rsa.prime2.val != NULL) {
  2629. SETATTR(templ, i, CKA_PRIME_2,
  2630. rawkey->rawdata.rsa.prime2.val,
  2631. rawkey->rawdata.rsa.prime2.len);
  2632. i++;
  2633. }
  2634. if (rawkey->rawdata.rsa.exp1.val != NULL) {
  2635. SETATTR(templ, i, CKA_EXPONENT_1,
  2636. rawkey->rawdata.rsa.exp1.val,
  2637. rawkey->rawdata.rsa.exp1.len);
  2638. i++;
  2639. }
  2640. if (rawkey->rawdata.rsa.exp2.val != NULL) {
  2641. SETATTR(templ, i, CKA_EXPONENT_2,
  2642. rawkey->rawdata.rsa.exp2.val,
  2643. rawkey->rawdata.rsa.exp2.len);
  2644. i++;
  2645. }
  2646. if (rawkey->rawdata.rsa.coef.val != NULL) {
  2647. SETATTR(templ, i, CKA_COEFFICIENT,
  2648. rawkey->rawdata.rsa.coef.val,
  2649. rawkey->rawdata.rsa.coef.len);
  2650. i++;
  2651. }
  2652. } else {
  2653. SETATTR(templ, i, CKA_PRIME,
  2654. rawkey->rawdata.dsa.prime.val,
  2655. rawkey->rawdata.dsa.prime.len);
  2656. i++;
  2657. SETATTR(templ, i, CKA_SUBPRIME,
  2658. rawkey->rawdata.dsa.subprime.val,
  2659. rawkey->rawdata.dsa.subprime.len);
  2660. i++;
  2661. SETATTR(templ, i, CKA_BASE,
  2662. rawkey->rawdata.dsa.base.val,
  2663. rawkey->rawdata.dsa.base.len);
  2664. i++;
  2665. SETATTR(templ, i, CKA_VALUE,
  2666. rawkey->rawdata.dsa.value.val,
  2667. rawkey->rawdata.dsa.value.len);
  2668. i++;
  2669. }
  2670. ckrv = C_CreateObject(kmfh->pk11handle, templ, i, &keyobj);
  2671. if (ckrv != CKR_OK) {
  2672. SET_ERROR(kmfh, ckrv);
  2673. /* Report authentication failures to the caller */
  2674. if (ckrv == CKR_USER_NOT_LOGGED_IN ||
  2675. ckrv == CKR_PIN_INCORRECT ||
  2676. ckrv == CKR_PIN_INVALID ||
  2677. ckrv == CKR_PIN_EXPIRED ||
  2678. ckrv == CKR_PIN_LOCKED ||
  2679. ckrv == CKR_SESSION_READ_ONLY)
  2680. rv = KMF_ERR_AUTH_FAILED;
  2681. else
  2682. rv = KMF_ERR_INTERNAL;
  2683. }
  2684. cleanup:
  2685. if (start != NULL)
  2686. free(start);
  2687. if (end != NULL)
  2688. free(end);
  2689. kmf_free_data(&id);
  2690. kmf_free_data(&subject);
  2691. kmf_free_signed_cert(x509);
  2692. free(x509);
  2693. return (rv);
  2694. }
  2695. KMF_RETURN
  2696. KMFPK11_CreateSymKey(KMF_HANDLE_T handle,
  2697. int numattr, KMF_ATTRIBUTE *attrlist)
  2698. {
  2699. KMF_RETURN rv = KMF_OK;
  2700. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  2701. CK_RV ckrv;
  2702. CK_SESSION_HANDLE hSession = kmfh->pk11handle;
  2703. CK_OBJECT_HANDLE keyhandle;
  2704. CK_MECHANISM keyGenMech;
  2705. CK_OBJECT_CLASS class = CKO_SECRET_KEY;
  2706. CK_ULONG secKeyType;
  2707. CK_ULONG secKeyLen; /* for RC4 and AES */
  2708. CK_BBOOL true = TRUE;
  2709. CK_BBOOL false = FALSE;
  2710. CK_ATTRIBUTE templ[15];
  2711. CK_BYTE *keydata = NULL;
  2712. int i = 0;
  2713. KMF_KEY_HANDLE *symkey;
  2714. KMF_KEY_ALG keytype;
  2715. uint32_t keylen = 0;
  2716. uint32_t attrkeylen = 0;
  2717. uint32_t keylen_size = sizeof (uint32_t);
  2718. char *keylabel = NULL;
  2719. KMF_CREDENTIAL *cred = NULL;
  2720. uint32_t is_sensitive = B_FALSE;
  2721. uint32_t is_not_extractable = B_FALSE;
  2722. if (kmfh == NULL)
  2723. return (KMF_ERR_UNINITIALIZED);
  2724. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  2725. return (KMF_ERR_NO_TOKEN_SELECTED);
  2726. symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
  2727. if (symkey == NULL)
  2728. return (KMF_ERR_BAD_PARAMETER);
  2729. rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
  2730. (void *)&keytype, NULL);
  2731. if (rv != KMF_OK)
  2732. return (KMF_ERR_BAD_PARAMETER);
  2733. keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
  2734. if (keylabel == NULL)
  2735. return (KMF_ERR_BAD_PARAMETER);
  2736. rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr,
  2737. (void *)&is_sensitive, NULL);
  2738. if (rv != KMF_OK)
  2739. return (KMF_ERR_BAD_PARAMETER);
  2740. rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr,
  2741. (void *)&is_not_extractable, NULL);
  2742. if (rv != KMF_OK)
  2743. return (KMF_ERR_BAD_PARAMETER);
  2744. /*
  2745. * For AES, RC4, DES and 3DES, call C_GenerateKey() to create a key.
  2746. *
  2747. * For a generic secret key, because it may not be supported in
  2748. * C_GenerateKey() for some PKCS11 providers, we will handle it
  2749. * differently.
  2750. */
  2751. if (keytype == KMF_GENERIC_SECRET) {
  2752. rv = create_generic_secret_key(handle, numattr,
  2753. attrlist, &keyhandle);
  2754. if (rv != KMF_OK)
  2755. goto out;
  2756. else
  2757. goto setup;
  2758. }
  2759. rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr,
  2760. NULL, &attrkeylen);
  2761. if (rv == KMF_OK && attrkeylen > 0) {
  2762. keydata = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist,
  2763. numattr);
  2764. } else {
  2765. keydata = NULL;
  2766. attrkeylen = 0;
  2767. rv = KMF_OK;
  2768. }
  2769. if (keydata != NULL) {
  2770. if (keytype == KMF_DES && attrkeylen != 8) {
  2771. rv = KMF_ERR_BAD_KEY_SIZE;
  2772. goto out;
  2773. }
  2774. if (keytype == KMF_DES3 && attrkeylen != 24) {
  2775. rv = KMF_ERR_BAD_KEY_SIZE;
  2776. goto out;
  2777. }
  2778. /*
  2779. * This may override what the user gave on the
  2780. * command line.
  2781. */
  2782. keylen = attrkeylen * 8; /* bytes to bits */
  2783. } else {
  2784. /*
  2785. * If keydata was not given, key length must be
  2786. * provided.
  2787. */
  2788. rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
  2789. &keylen, &keylen_size);
  2790. if (rv == KMF_ERR_ATTR_NOT_FOUND &&
  2791. (keytype == KMF_DES || keytype == KMF_DES3))
  2792. /* keylength is not required for DES and 3DES */
  2793. rv = KMF_OK;
  2794. if (rv != KMF_OK)
  2795. return (KMF_ERR_BAD_PARAMETER);
  2796. }
  2797. if ((keylen % 8) != 0) {
  2798. return (KMF_ERR_BAD_KEY_SIZE);
  2799. }
  2800. secKeyLen = keylen / 8; /* in bytes for RC4/AES */
  2801. /*
  2802. * Only set CKA_VALUE_LEN if the key data was not given and
  2803. * we are creating an RC4 or AES key.
  2804. */
  2805. if (keydata == NULL &&
  2806. (keytype == KMF_AES || keytype == KMF_RC4)) {
  2807. SETATTR(templ, i, CKA_VALUE_LEN, &secKeyLen,
  2808. sizeof (secKeyLen));
  2809. i++;
  2810. }
  2811. /* Other keytypes */
  2812. keyGenMech.pParameter = NULL_PTR;
  2813. keyGenMech.ulParameterLen = 0;
  2814. switch (keytype) {
  2815. case KMF_AES:
  2816. keyGenMech.mechanism = CKM_AES_KEY_GEN;
  2817. secKeyType = CKK_AES;
  2818. break;
  2819. case KMF_RC4:
  2820. keyGenMech.mechanism = CKM_RC4_KEY_GEN;
  2821. secKeyType = CKK_RC4;
  2822. break;
  2823. case KMF_DES:
  2824. keyGenMech.mechanism = CKM_DES_KEY_GEN;
  2825. secKeyType = CKK_DES;
  2826. break;
  2827. case KMF_DES3:
  2828. keyGenMech.mechanism = CKM_DES3_KEY_GEN;
  2829. secKeyType = CKK_DES3;
  2830. break;
  2831. default:
  2832. return (KMF_ERR_BAD_KEY_TYPE);
  2833. }
  2834. if (keydata != NULL) {
  2835. SETATTR(templ, i, CKA_VALUE, keydata, secKeyLen);
  2836. i++;
  2837. }
  2838. SETATTR(templ, i, CKA_CLASS, &class, sizeof (class));
  2839. i++;
  2840. SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType));
  2841. i++;
  2842. if (keylabel != NULL) {
  2843. SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
  2844. i++;
  2845. }
  2846. if (is_sensitive == B_TRUE) {
  2847. SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true));
  2848. } else {
  2849. SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false));
  2850. }
  2851. i++;
  2852. if (is_not_extractable == B_TRUE) {
  2853. SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false));
  2854. } else {
  2855. SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true));
  2856. }
  2857. i++;
  2858. SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true));
  2859. i++;
  2860. SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true));
  2861. i++;
  2862. SETATTR(templ, i, CKA_ENCRYPT, &true, sizeof (true));
  2863. i++;
  2864. SETATTR(templ, i, CKA_DECRYPT, &true, sizeof (true));
  2865. i++;
  2866. SETATTR(templ, i, CKA_SIGN, &true, sizeof (true));
  2867. i++;
  2868. SETATTR(templ, i, CKA_VERIFY, &true, sizeof (true));
  2869. i++;
  2870. cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
  2871. if (cred == NULL)
  2872. return (KMF_ERR_BAD_PARAMETER);
  2873. rv = pk11_authenticate(handle, cred);
  2874. if (rv != KMF_OK) {
  2875. return (rv);
  2876. }
  2877. /* If the key data was given, use C_CreateObject */
  2878. if (keydata != NULL) {
  2879. ckrv = C_CreateObject(hSession, templ, i, &keyhandle);
  2880. } else {
  2881. ckrv = C_GenerateKey(hSession, &keyGenMech, templ, i,
  2882. &keyhandle);
  2883. }
  2884. if (ckrv != CKR_OK) {
  2885. SET_ERROR(kmfh, ckrv);
  2886. rv = KMF_ERR_KEYGEN_FAILED;
  2887. goto out;
  2888. }
  2889. setup:
  2890. symkey->kstype = KMF_KEYSTORE_PK11TOKEN;
  2891. symkey->keyalg = keytype;
  2892. symkey->keyclass = KMF_SYMMETRIC;
  2893. symkey->israw = FALSE;
  2894. symkey->keyp = (void *)keyhandle;
  2895. out:
  2896. return (rv);
  2897. }
  2898. KMF_RETURN
  2899. KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
  2900. KMF_RAW_SYM_KEY *rkey)
  2901. {
  2902. KMF_RETURN rv = KMF_OK;
  2903. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  2904. if (kmfh == NULL)
  2905. return (KMF_ERR_UNINITIALIZED);
  2906. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  2907. return (KMF_ERR_NO_TOKEN_SELECTED);
  2908. if (symkey == NULL || rkey == NULL)
  2909. return (KMF_ERR_BAD_PARAMETER);
  2910. else if (symkey->keyclass != KMF_SYMMETRIC)
  2911. return (KMF_ERR_BAD_KEY_CLASS);
  2912. /*
  2913. * If the key is already in "raw" format, copy the data
  2914. * to the new record if possible.
  2915. */
  2916. if (symkey->israw) {
  2917. KMF_RAW_KEY_DATA *rawkey = (KMF_RAW_KEY_DATA *)symkey->keyp;
  2918. if (rawkey == NULL)
  2919. return (KMF_ERR_BAD_KEYHANDLE);
  2920. if (rawkey->sensitive)
  2921. return (KMF_ERR_SENSITIVE_KEY);
  2922. if (rawkey->not_extractable)
  2923. return (KMF_ERR_UNEXTRACTABLE_KEY);
  2924. if (rawkey->rawdata.sym.keydata.val == NULL ||
  2925. rawkey->rawdata.sym.keydata.len == 0)
  2926. return (KMF_ERR_GETKEYVALUE_FAILED);
  2927. rkey->keydata.len = rawkey->rawdata.sym.keydata.len;
  2928. if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
  2929. return (KMF_ERR_MEMORY);
  2930. (void) memcpy(rkey->keydata.val,
  2931. rawkey->rawdata.sym.keydata.val, rkey->keydata.len);
  2932. } else {
  2933. rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)symkey->keyp, rkey);
  2934. }
  2935. return (rv);
  2936. }
  2937. KMF_RETURN
  2938. KMFPK11_SetTokenPin(KMF_HANDLE_T handle,
  2939. int numattr, KMF_ATTRIBUTE *attrlist)
  2940. {
  2941. KMF_RETURN ret = KMF_OK;
  2942. CK_RV rv = CKR_OK;
  2943. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  2944. CK_SESSION_HANDLE session = NULL;
  2945. KMF_CREDENTIAL *oldcred;
  2946. KMF_CREDENTIAL *newcred;
  2947. CK_SLOT_ID slotid;
  2948. if (handle == NULL || attrlist == NULL || numattr == 0)
  2949. return (KMF_ERR_BAD_PARAMETER);
  2950. oldcred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
  2951. if (oldcred == NULL)
  2952. return (KMF_ERR_BAD_PARAMETER);
  2953. newcred = kmf_get_attr_ptr(KMF_NEWPIN_ATTR, attrlist, numattr);
  2954. if (newcred == NULL)
  2955. return (KMF_ERR_BAD_PARAMETER);
  2956. rv = kmf_get_attr(KMF_SLOT_ID_ATTR, attrlist, numattr,
  2957. (void *)&slotid, NULL);
  2958. if (rv != KMF_OK) {
  2959. char *tokenlabel = NULL;
  2960. /*
  2961. * If a slot wasn't given, the user must pass
  2962. * a token label so we can find the slot here.
  2963. */
  2964. tokenlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist,
  2965. numattr);
  2966. if (tokenlabel == NULL)
  2967. return (KMF_ERR_BAD_PARAMETER);
  2968. rv = kmf_pk11_token_lookup(handle, tokenlabel, &slotid);
  2969. if (rv != KMF_OK)
  2970. return (rv);
  2971. }
  2972. rv = C_OpenSession(slotid, CKF_SERIAL_SESSION | CKF_RW_SESSION,
  2973. NULL, NULL, &session);
  2974. if (rv != CKR_OK) {
  2975. SET_ERROR(kmfh, rv);
  2976. ret = KMF_ERR_UNINITIALIZED;
  2977. goto end;
  2978. }
  2979. rv = C_SetPIN(session,
  2980. (CK_BYTE *)oldcred->cred, oldcred->credlen,
  2981. (CK_BYTE *)newcred->cred, newcred->credlen);
  2982. if (rv != CKR_OK) {
  2983. SET_ERROR(kmfh, rv);
  2984. if (rv == CKR_PIN_INCORRECT ||
  2985. rv == CKR_PIN_INVALID ||
  2986. rv == CKR_PIN_EXPIRED ||
  2987. rv == CKR_PIN_LOCKED)
  2988. ret = KMF_ERR_AUTH_FAILED;
  2989. else
  2990. ret = KMF_ERR_INTERNAL;
  2991. }
  2992. end:
  2993. if (session != NULL)
  2994. (void) C_CloseSession(session);
  2995. return (ret);
  2996. }
  2997. static KMF_RETURN
  2998. create_pk11_session(CK_SESSION_HANDLE *sessionp, CK_MECHANISM_TYPE wanted_mech,
  2999. CK_FLAGS wanted_flags)
  3000. {
  3001. CK_RV rv;
  3002. KMF_RETURN kmf_rv = KMF_OK;
  3003. CK_SLOT_ID_PTR pSlotList;
  3004. CK_ULONG pulCount;
  3005. CK_MECHANISM_INFO info;
  3006. int i;
  3007. rv = C_Initialize(NULL);
  3008. if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) {
  3009. kmf_rv = KMF_ERR_UNINITIALIZED;
  3010. goto out;
  3011. }
  3012. rv = C_GetSlotList(0, NULL, &pulCount);
  3013. if (rv != CKR_OK) {
  3014. kmf_rv = KMF_ERR_UNINITIALIZED;
  3015. goto out;
  3016. }
  3017. pSlotList = (CK_SLOT_ID_PTR) malloc(pulCount * sizeof (CK_SLOT_ID));
  3018. if (pSlotList == NULL) {
  3019. kmf_rv = KMF_ERR_MEMORY;
  3020. goto out;
  3021. }
  3022. rv = C_GetSlotList(0, pSlotList, &pulCount);
  3023. if (rv != CKR_OK) {
  3024. kmf_rv = KMF_ERR_UNINITIALIZED;
  3025. goto out;
  3026. }
  3027. for (i = 0; i < pulCount; i++) {
  3028. rv = C_GetMechanismInfo(pSlotList[i], wanted_mech, &info);
  3029. if (rv == CKR_OK && (info.flags & wanted_flags))
  3030. break;
  3031. }
  3032. if (i < pulCount) {
  3033. rv = C_OpenSession(pSlotList[i], CKF_SERIAL_SESSION,
  3034. NULL, NULL, sessionp);
  3035. if (rv != CKR_OK) {
  3036. kmf_rv = KMF_ERR_UNINITIALIZED;
  3037. }
  3038. } else {
  3039. kmf_rv = KMF_ERR_UNINITIALIZED;
  3040. }
  3041. out:
  3042. if (pSlotList != NULL)
  3043. free(pSlotList);
  3044. return (kmf_rv);
  3045. }
  3046. static KMF_RETURN
  3047. verify_data(KMF_HANDLE_T handle,
  3048. KMF_ALGORITHM_INDEX AlgorithmId,
  3049. KMF_X509_SPKI *keyp,
  3050. KMF_DATA *data,
  3051. KMF_DATA *signed_data)
  3052. {
  3053. KMF_RETURN ret;
  3054. PKCS_ALGORITHM_MAP *pAlgMap = NULL;
  3055. CK_RV ckRv;
  3056. CK_MECHANISM ckMechanism;
  3057. CK_OBJECT_HANDLE ckKeyHandle;
  3058. KMF_BOOL bTempKey;
  3059. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  3060. CK_SESSION_HANDLE ckSession = NULL;
  3061. if (AlgorithmId == KMF_ALGID_NONE)
  3062. return (KMF_ERR_BAD_ALGORITHM);
  3063. pAlgMap = pkcs_get_alg_map(KMF_ALGCLASS_SIGNATURE,
  3064. AlgorithmId, PKCS_GetDefaultSignatureMode(AlgorithmId));
  3065. if (!pAlgMap)
  3066. return (KMF_ERR_BAD_ALGORITHM);
  3067. ret = create_pk11_session(&ckSession, pAlgMap->pkcs_mechanism,
  3068. CKF_VERIFY);
  3069. if (ret != KMF_OK)
  3070. return (ret);
  3071. /* Fetch the verifying key */
  3072. ret = PKCS_AcquirePublicKeyHandle(ckSession, keyp,
  3073. pAlgMap->key_type, &ckKeyHandle, &bTempKey);
  3074. if (ret != KMF_OK) {
  3075. return (ret);
  3076. }
  3077. ckMechanism.mechanism = pAlgMap->pkcs_mechanism;
  3078. ckMechanism.pParameter = NULL;
  3079. ckMechanism.ulParameterLen = 0;
  3080. ckRv = C_VerifyInit(ckSession, &ckMechanism, ckKeyHandle);
  3081. if (ckRv != CKR_OK) {
  3082. if (bTempKey)
  3083. (void) C_DestroyObject(ckSession, ckKeyHandle);
  3084. SET_ERROR(kmfh, ckRv);
  3085. ret = KMF_ERR_INTERNAL;
  3086. goto cleanup;
  3087. }
  3088. ckRv = C_Verify(ckSession, (CK_BYTE *)data->Data,
  3089. (CK_ULONG)data->Length, (CK_BYTE *)signed_data->Data,
  3090. (CK_ULONG)signed_data->Length);
  3091. if (ckRv != CKR_OK) {
  3092. SET_ERROR(kmfh, ckRv);
  3093. ret = KMF_ERR_INTERNAL;
  3094. }
  3095. cleanup:
  3096. if (bTempKey)
  3097. (void) C_DestroyObject(ckSession, ckKeyHandle);
  3098. (void) C_CloseSession(ckSession);
  3099. return (ret);
  3100. }
  3101. KMF_RETURN
  3102. KMFPK11_VerifyDataWithCert(KMF_HANDLE_T handle,
  3103. KMF_ALGORITHM_INDEX algid, KMF_DATA *indata,
  3104. KMF_DATA *insig, KMF_DATA *SignerCertData)
  3105. {
  3106. KMF_RETURN ret = KMF_OK;
  3107. KMF_X509_CERTIFICATE *SignerCert = NULL;
  3108. KMF_X509_SPKI *pubkey;
  3109. if (handle == NULL || indata == NULL ||
  3110. indata->Data == NULL || indata->Length == 0 ||
  3111. insig == NULL|| insig->Data == NULL || insig->Length == 0 ||
  3112. SignerCertData == NULL || SignerCertData->Data == NULL ||
  3113. SignerCertData->Length == 0)
  3114. return (KMF_ERR_BAD_PARAMETER);
  3115. /* Decode the signer cert so we can get the SPKI data */
  3116. ret = DerDecodeSignedCertificate(SignerCertData, &SignerCert);
  3117. if (ret != KMF_OK)
  3118. goto cleanup;
  3119. /* Get the public key info from the signer certificate */
  3120. pubkey = &SignerCert->certificate.subjectPublicKeyInfo;
  3121. /* If no algorithm specified, use the certs signature algorithm */
  3122. if (algid == KMF_ALGID_NONE) {
  3123. algid = x509_algoid_to_algid(CERT_ALG_OID(SignerCert));
  3124. }
  3125. if (algid == KMF_ALGID_NONE) {
  3126. ret = KMF_ERR_BAD_ALGORITHM;
  3127. } else {
  3128. ret = verify_data(handle, algid, pubkey, indata, insig);
  3129. }
  3130. cleanup:
  3131. if (SignerCert) {
  3132. kmf_free_signed_cert(SignerCert);
  3133. free(SignerCert);
  3134. }
  3135. return (ret);
  3136. }
  3137. static KMF_RETURN
  3138. create_generic_secret_key(KMF_HANDLE_T handle,
  3139. int numattr, KMF_ATTRIBUTE *attrlist, CK_OBJECT_HANDLE *key)
  3140. {
  3141. KMF_RETURN rv = KMF_OK;
  3142. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  3143. CK_RV ckrv;
  3144. CK_SESSION_HANDLE hSession = kmfh->pk11handle;
  3145. CK_OBJECT_CLASS class = CKO_SECRET_KEY;
  3146. CK_ULONG secKeyType = CKK_GENERIC_SECRET;
  3147. CK_ULONG secKeyLen;
  3148. CK_BBOOL true = TRUE;
  3149. CK_BBOOL false = FALSE;
  3150. CK_ATTRIBUTE templ[15];
  3151. int i;
  3152. int random_fd = -1;
  3153. int nread;
  3154. int freebuf = 0;
  3155. char *buf = NULL;
  3156. uint32_t keylen = 0, attrkeylen = 0;
  3157. char *keylabel = NULL;
  3158. KMF_CREDENTIAL *cred;
  3159. uint32_t is_sensitive, is_not_extractable;
  3160. keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
  3161. if (keylabel == NULL)
  3162. return (KMF_ERR_BAD_PARAMETER);
  3163. cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
  3164. if (cred == NULL)
  3165. return (KMF_ERR_BAD_PARAMETER);
  3166. rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr,
  3167. (void *)&is_sensitive, NULL);
  3168. if (rv != KMF_OK)
  3169. return (KMF_ERR_BAD_PARAMETER);
  3170. rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr,
  3171. (void *)&is_not_extractable, NULL);
  3172. if (rv != KMF_OK)
  3173. return (KMF_ERR_BAD_PARAMETER);
  3174. rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr,
  3175. NULL, &attrkeylen);
  3176. if (rv == KMF_OK && attrkeylen > 0) {
  3177. buf = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist,
  3178. numattr);
  3179. secKeyLen = attrkeylen;
  3180. } else {
  3181. buf = NULL;
  3182. rv = KMF_OK;
  3183. }
  3184. if (buf == NULL) {
  3185. /*
  3186. * If the key data was not given, key length must
  3187. * be provided.
  3188. */
  3189. rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
  3190. &keylen, NULL);
  3191. if (rv != KMF_OK)
  3192. return (KMF_ERR_BAD_PARAMETER);
  3193. /*
  3194. * Check the key size.
  3195. */
  3196. if ((keylen % 8) != 0) {
  3197. return (KMF_ERR_BAD_KEY_SIZE);
  3198. } else {
  3199. secKeyLen = keylen/8; /* in bytes */
  3200. }
  3201. /*
  3202. * Generate a random number with the key size first.
  3203. */
  3204. buf = malloc(secKeyLen);
  3205. if (buf == NULL)
  3206. return (KMF_ERR_MEMORY);
  3207. freebuf = 1;
  3208. while ((random_fd = open(DEV_RANDOM, O_RDONLY)) < 0) {
  3209. if (errno != EINTR)
  3210. break;
  3211. }
  3212. if (random_fd < 0) {
  3213. rv = KMF_ERR_KEYGEN_FAILED;
  3214. goto out;
  3215. }
  3216. nread = read(random_fd, buf, secKeyLen);
  3217. if (nread <= 0 || nread != secKeyLen) {
  3218. rv = KMF_ERR_KEYGEN_FAILED;
  3219. goto out;
  3220. }
  3221. }
  3222. /*
  3223. * Authenticate into the token and call C_CreateObject to generate
  3224. * a generic secret token key.
  3225. */
  3226. rv = pk11_authenticate(handle, cred);
  3227. if (rv != KMF_OK) {
  3228. goto out;
  3229. }
  3230. i = 0;
  3231. SETATTR(templ, i, CKA_CLASS, &class, sizeof (class));
  3232. i++;
  3233. SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType));
  3234. i++;
  3235. SETATTR(templ, i, CKA_VALUE, buf, secKeyLen);
  3236. i++;
  3237. if (keylabel != NULL) {
  3238. SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
  3239. i++;
  3240. }
  3241. if (is_sensitive == B_TRUE) {
  3242. SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true));
  3243. } else {
  3244. SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false));
  3245. }
  3246. i++;
  3247. if (is_not_extractable == B_TRUE) {
  3248. SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false));
  3249. } else {
  3250. SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true));
  3251. }
  3252. i++;
  3253. SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true));
  3254. i++;
  3255. SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true));
  3256. i++;
  3257. SETATTR(templ, i, CKA_SIGN, &true, sizeof (true));
  3258. i++;
  3259. ckrv = C_CreateObject(hSession, templ, i, key);
  3260. if (ckrv != CKR_OK) {
  3261. SET_ERROR(kmfh, ckrv);
  3262. rv = KMF_ERR_KEYGEN_FAILED;
  3263. }
  3264. out:
  3265. if (buf != NULL && freebuf)
  3266. free(buf);
  3267. if (random_fd != -1)
  3268. (void) close(random_fd);
  3269. return (rv);
  3270. }
  3271. KMF_RETURN
  3272. KMFPK11_StoreKey(KMF_HANDLE_T handle,
  3273. int numattr,
  3274. KMF_ATTRIBUTE *attlist)
  3275. {
  3276. KMF_RETURN rv = KMF_OK;
  3277. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  3278. KMF_CREDENTIAL cred = {NULL, 0};
  3279. KMF_KEY_HANDLE *key;
  3280. KMF_RAW_KEY_DATA *rawkey = NULL;
  3281. CK_BBOOL btrue = TRUE;
  3282. CK_ATTRIBUTE tokenattr[1];
  3283. CK_OBJECT_HANDLE newobj;
  3284. CK_RV ckrv;
  3285. if (kmfh == NULL)
  3286. return (KMF_ERR_UNINITIALIZED);
  3287. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  3288. return (KMF_ERR_NO_TOKEN_SELECTED);
  3289. rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attlist, numattr,
  3290. (void *)&cred, NULL);
  3291. if (rv != KMF_OK)
  3292. return (KMF_ERR_BAD_PARAMETER);
  3293. rv = pk11_authenticate(handle, &cred);
  3294. if (rv != KMF_OK)
  3295. return (rv);
  3296. key = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr);
  3297. if (key == NULL) {
  3298. key = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist,
  3299. numattr);
  3300. if (key == NULL)
  3301. rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attlist,
  3302. numattr);
  3303. }
  3304. if (key == NULL && rawkey == NULL)
  3305. return (KMF_ERR_ATTR_NOT_FOUND);
  3306. if (rawkey != NULL) {
  3307. rv = store_raw_key(handle, attlist, numattr, rawkey);
  3308. } else if (key && key->kstype == KMF_KEYSTORE_PK11TOKEN) {
  3309. SETATTR(tokenattr, 0, CKA_TOKEN, &btrue, sizeof (btrue));
  3310. /* Copy the key object to the token */
  3311. ckrv = C_CopyObject(kmfh->pk11handle,
  3312. (CK_OBJECT_HANDLE)key->keyp, tokenattr, 1, &newobj);
  3313. if (ckrv != CKR_OK) {
  3314. SET_ERROR(kmfh, ckrv);
  3315. return (KMF_ERR_INTERNAL);
  3316. }
  3317. /* Replace the object handle with the new token-based one */
  3318. ckrv = C_DestroyObject(kmfh->pk11handle,
  3319. (CK_OBJECT_HANDLE)key->keyp);
  3320. if (ckrv != CKR_OK) {
  3321. SET_ERROR(kmfh, ckrv);
  3322. return (KMF_ERR_INTERNAL);
  3323. }
  3324. key->keyp = (void *)newobj;
  3325. } else {
  3326. rv = KMF_ERR_BAD_PARAMETER;
  3327. }
  3328. return (rv);
  3329. }
  3330. KMF_RETURN
  3331. KMFPK11_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
  3332. {
  3333. KMF_RETURN rv = KMF_OK;
  3334. KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
  3335. KMF_CREDENTIAL *cred = NULL;
  3336. KMF_CREDENTIAL *p12cred = NULL;
  3337. char *filename = NULL;
  3338. KMF_X509_DER_CERT *certlist = NULL;
  3339. KMF_KEY_HANDLE *keylist = NULL;
  3340. uint32_t numcerts;
  3341. uint32_t numkeys;
  3342. char *certlabel = NULL;
  3343. char *issuer = NULL;
  3344. char *subject = NULL;
  3345. KMF_BIGINT *serial = NULL;
  3346. KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
  3347. KMF_ATTRIBUTE fc_attrlist[16];
  3348. int i;
  3349. if (kmfh == NULL)
  3350. return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
  3351. if (kmfh->pk11handle == CK_INVALID_HANDLE)
  3352. return (KMF_ERR_NO_TOKEN_SELECTED);
  3353. /* First get the required attributes */
  3354. cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
  3355. if (cred == NULL)
  3356. return (KMF_ERR_BAD_PARAMETER);
  3357. p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr);
  3358. if (p12cred == NULL)
  3359. return (KMF_ERR_BAD_PARAMETER);
  3360. filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist,
  3361. numattr);
  3362. if (filename == NULL)
  3363. return (KMF_ERR_BAD_PARAMETER);
  3364. /* Find all the certificates that match the searching criteria */
  3365. i = 0;
  3366. kmf_set_attr_at_index(fc_attrlist, i,
  3367. KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
  3368. i++;
  3369. kmf_set_attr_at_index(fc_attrlist, i,
  3370. KMF_COUNT_ATTR, &numcerts, sizeof (uint32_t));
  3371. i++;
  3372. certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
  3373. if (certlabel != NULL) {
  3374. kmf_set_attr_at_index(fc_attrlist, i,
  3375. KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel));
  3376. i++;
  3377. }
  3378. issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
  3379. if (issuer != NULL) {
  3380. kmf_set_attr_at_index(fc_attrlist, i,
  3381. KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer));
  3382. i++;
  3383. }
  3384. subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
  3385. if (subject != NULL) {
  3386. kmf_set_attr_at_index(fc_attrlist, i,
  3387. KMF_SUBJECT_NAME_ATTR, subject, strlen(subject));
  3388. i++;
  3389. }
  3390. serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
  3391. if (serial != NULL) {
  3392. kmf_set_attr_at_index(fc_attrlist, i,
  3393. KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT));
  3394. i++;
  3395. }
  3396. rv = KMFPK11_FindCert(handle, i, fc_attrlist);
  3397. if (rv == KMF_OK && numcerts > 0) {
  3398. certlist = (KMF_X509_DER_CERT *)malloc(numcerts *
  3399. sizeof (KMF_X509_DER_CERT));
  3400. if (certlist == NULL)
  3401. return (KMF_ERR_MEMORY);
  3402. (void) memset(certlist, 0, numcerts *
  3403. sizeof (KMF_X509_DER_CERT));
  3404. kmf_set_attr_at_index(fc_attrlist, i, KMF_X509_DER_CERT_ATTR,
  3405. certlist, sizeof (KMF_X509_DER_CERT));
  3406. i++;
  3407. rv = kmf_find_cert(handle, i, fc_attrlist);
  3408. if (rv != KMF_OK) {
  3409. free(certlist);
  3410. return (rv);
  3411. }
  3412. } else {
  3413. return (rv);
  3414. }
  3415. /* For each certificate, find the matching private key */
  3416. numkeys = 0;
  3417. for (i = 0; i < numcerts; i++) {
  3418. KMF_ATTRIBUTE fk_attrlist[16];
  3419. int j = 0;
  3420. KMF_KEY_HANDLE newkey;
  3421. KMF_ENCODE_FORMAT format = KMF_FORMAT_RAWKEY;
  3422. kmf_set_attr_at_index(fk_attrlist, j,
  3423. KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
  3424. j++;
  3425. kmf_set_attr_at_index(fk_attrlist, j,
  3426. KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format));
  3427. j++;
  3428. kmf_set_attr_at_index(fk_attrlist, j,
  3429. KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
  3430. j++;
  3431. kmf_set_attr_at_index(fk_attrlist, j,
  3432. KMF_CERT_DATA_ATTR, &certlist[i].certificate,
  3433. sizeof (KMF_DATA));
  3434. j++;
  3435. kmf_set_attr_at_index(fk_attrlist, j,
  3436. KMF_KEY_HANDLE_ATTR, &newkey, sizeof (KMF_KEY_HANDLE));
  3437. j++;
  3438. rv = KMFPK11_FindPrikeyByCert(handle, j, fk_attrlist);
  3439. if (rv == KMF_OK) {
  3440. numkeys++;
  3441. keylist = realloc(keylist,
  3442. numkeys * sizeof (KMF_KEY_HANDLE));
  3443. if (keylist == NULL) {
  3444. rv = KMF_ERR_MEMORY;
  3445. goto out;
  3446. }
  3447. keylist[numkeys - 1] = newkey;
  3448. } else if (rv == KMF_ERR_KEY_NOT_FOUND) {
  3449. /* it is OK if a key is not found */
  3450. rv = KMF_OK;
  3451. }
  3452. }
  3453. if (rv != KMF_OK)
  3454. goto out;
  3455. rv = kmf_build_pk12(handle, numcerts, certlist, numkeys, keylist,
  3456. p12cred, filename);
  3457. out:
  3458. if (certlist != NULL) {
  3459. for (i = 0; i < numcerts; i++)
  3460. kmf_free_kmf_cert(handle, &certlist[i]);
  3461. free(certlist);
  3462. }
  3463. if (keylist != NULL) {
  3464. for (i = 0; i < numkeys; i++)
  3465. kmf_free_kmf_key(handle, &keylist[i]);
  3466. free(keylist);
  3467. }
  3468. return (rv);
  3469. }