PageRenderTime 73ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 1ms

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

https://bitbucket.org/nexenta/onnv_134
C | 4096 lines | 3243 code | 570 blank | 283 comment | 1148 complexity | 696a743d9b34b54392aa7b91903c83af MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, GPL-2.0, AGPL-1.0, LGPL-2.1, BSD-3-Clause-No-Nuclear-License-2014, LGPL-2.0, AGPL-3.0, BSD-3-Clause, GPL-3.0, LGPL-3.0, 0BSD

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

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

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