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

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

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