PageRenderTime 79ms CodeModel.GetById 37ms RepoModel.GetById 1ms app.codeStats 1ms

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

https://bitbucket.org/dilos/onarm-gate
C | 4034 lines | 3187 code | 565 blank | 282 comment | 1105 complexity | 3b2553b83ef8703fd92e0000aae5cb9d MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, AGPL-3.0, MIT, Apache-2.0, 0BSD, GPL-2.0, LGPL-2.0, AGPL-1.0, BSD-3-Clause, LGPL-3.0, BSD-3-Clause-No-Nuclear-License-2014

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

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