PageRenderTime 39ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

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

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