PageRenderTime 69ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 1ms

/usr/src/lib/pkcs11/libpkcs11/common/metaObjectManager.c

https://bitbucket.org/a3217055/illumos-gate
C | 2175 lines | 1389 code | 341 blank | 445 comment | 374 complexity | c321995512a4cc841b239a4324dadf53 MD5 | raw file
Possible License(s): BSD-2-Clause, BSD-3-Clause, LGPL-2.0, 0BSD, AGPL-3.0, GPL-2.0, GPL-3.0, LGPL-2.1, LGPL-3.0, BSD-3-Clause-No-Nuclear-License-2014, MPL-2.0-no-copyleft-exception, AGPL-1.0

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. * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  23. */
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <strings.h>
  27. #include <errno.h>
  28. #include <fcntl.h>
  29. #include <sys/types.h>
  30. #include <sys/stat.h>
  31. #include "metaGlobal.h"
  32. /* Size of the template for creating key used for wrap/unwrap */
  33. #define WRAP_KEY_TEMPLATE_SIZE 7
  34. /*
  35. * Information necessary to create keys for C_WrapKey/C_UnwrapKey
  36. */
  37. typedef struct _wrap_info {
  38. CK_OBJECT_CLASS class; /* class of the key for wrap/unwrap */
  39. CK_KEY_TYPE key_type; /* key type of key for wrap/unwrap */
  40. CK_ULONG key_length; /* length of key */
  41. CK_MECHANISM_TYPE mech_type; /* mech used for wrap/unwrap */
  42. CK_ULONG iv_length; /* length of iv for mech */
  43. boolean_t src_supports;
  44. boolean_t dst_supports;
  45. } wrap_info_t;
  46. extern pthread_rwlock_t meta_sessionlist_lock;
  47. extern meta_session_t *meta_sessionlist_head;
  48. static wrap_info_t common_wrap_info[] = {
  49. {CKO_SECRET_KEY, CKK_AES, 16, CKM_AES_CBC_PAD, 16, B_FALSE, B_FALSE},
  50. {CKO_SECRET_KEY, CKK_DES3, 24, CKM_DES3_CBC_PAD, 8, B_FALSE, B_FALSE},
  51. {CKO_SECRET_KEY, CKK_DES, 8, CKM_DES_CBC_PAD, 8, B_FALSE, B_FALSE},
  52. };
  53. static unsigned int num_common_wrap_info =
  54. sizeof (common_wrap_info) / sizeof (wrap_info_t);
  55. static wrap_info_t special_wrap_info[] = {
  56. {CKO_SECRET_KEY, CKK_SKIPJACK, 12, CKM_SKIPJACK_WRAP, 0,
  57. B_FALSE, B_FALSE},
  58. {CKO_SECRET_KEY, CKK_BATON, 40, CKM_BATON_WRAP, 0,
  59. B_FALSE, B_FALSE},
  60. {CKO_SECRET_KEY, CKK_JUNIPER, 40, CKM_JUNIPER_WRAP, 0,
  61. B_FALSE, B_FALSE},
  62. };
  63. static unsigned int num_special_wrap_info =
  64. sizeof (special_wrap_info) / sizeof (wrap_info_t);
  65. static wrap_info_t rsa_wrap_info[] = {
  66. {CKO_PUBLIC_KEY, CKK_RSA, 0, CKM_RSA_PKCS, 0,
  67. B_FALSE, B_FALSE},
  68. {CKO_PUBLIC_KEY, CKK_RSA, 0, CKM_RSA_X_509, 0,
  69. B_FALSE, B_FALSE},
  70. };
  71. static unsigned int num_rsa_wrap_info =
  72. sizeof (rsa_wrap_info) / sizeof (wrap_info_t);
  73. static pthread_rwlock_t meta_objectclose_lock;
  74. static pthread_rwlock_t tokenobject_list_lock;
  75. static meta_object_t *tokenobject_list_head;
  76. CK_BBOOL falsevalue = FALSE;
  77. CK_BBOOL truevalue = TRUE;
  78. /*
  79. * Public and private exponent, and Module value for
  80. * creating the RSA public/private key.
  81. *
  82. */
  83. static CK_BYTE PubExpo[3] = {0x01, 0x00, 0x01};
  84. CK_BYTE PriExpo[128] = {
  85. 0x8e, 0xc9, 0x70, 0x57, 0x6b, 0xcd, 0xfb, 0xa9,
  86. 0x19, 0xad, 0xcd, 0x91, 0x69, 0xd5, 0x52, 0xec,
  87. 0x72, 0x1e, 0x45, 0x15, 0x06, 0xdc, 0x65, 0x2d,
  88. 0x98, 0xc4, 0xce, 0x33, 0x54, 0x15, 0x70, 0x8d,
  89. 0xfa, 0x65, 0xea, 0x53, 0x44, 0xf3, 0x3e, 0x3f,
  90. 0xb4, 0x4c, 0x60, 0xd5, 0x01, 0x2d, 0xa4, 0x12,
  91. 0x99, 0xbf, 0x3f, 0x0b, 0xcd, 0xbb, 0x24, 0x10,
  92. 0x60, 0x30, 0x5e, 0x58, 0xf8, 0x59, 0xaa, 0xd1,
  93. 0x63, 0x3b, 0xbc, 0xcb, 0x94, 0x58, 0x38, 0x24,
  94. 0xfc, 0x65, 0x25, 0xc5, 0xa6, 0x51, 0xa2, 0x2e,
  95. 0xf1, 0x5e, 0xf5, 0xc1, 0xf5, 0x46, 0xf7, 0xbd,
  96. 0xc7, 0x62, 0xa8, 0xe2, 0x27, 0xd6, 0x94, 0x5b,
  97. 0xd3, 0xa2, 0xb5, 0x76, 0x42, 0x67, 0x6b, 0x86,
  98. 0x91, 0x97, 0x4d, 0x07, 0x92, 0x00, 0x4a, 0xdf,
  99. 0x0b, 0x65, 0x64, 0x05, 0x03, 0x48, 0x27, 0xeb,
  100. 0xce, 0x9a, 0x49, 0x7f, 0x3e, 0x10, 0xe0, 0x01};
  101. static CK_BYTE Modulus[128] = {
  102. 0x94, 0x32, 0xb9, 0x12, 0x1d, 0x68, 0x2c, 0xda,
  103. 0x2b, 0xe0, 0xe4, 0x97, 0x1b, 0x4d, 0xdc, 0x43,
  104. 0xdf, 0x38, 0x6e, 0x7b, 0x9f, 0x07, 0x58, 0xae,
  105. 0x9d, 0x82, 0x1e, 0xc7, 0xbc, 0x92, 0xbf, 0xd3,
  106. 0xce, 0x00, 0xbb, 0x91, 0xc9, 0x79, 0x06, 0x03,
  107. 0x1f, 0xbc, 0x9f, 0x94, 0x75, 0x29, 0x5f, 0xd7,
  108. 0xc5, 0xf3, 0x73, 0x8a, 0xa4, 0x35, 0x43, 0x7a,
  109. 0x00, 0x32, 0x97, 0x3e, 0x86, 0xef, 0x70, 0x6f,
  110. 0x18, 0x56, 0x15, 0xaa, 0x6a, 0x87, 0xe7, 0x8d,
  111. 0x7d, 0xdd, 0x1f, 0xa4, 0xe4, 0x31, 0xd4, 0x7a,
  112. 0x8c, 0x0e, 0x20, 0xd2, 0x23, 0xf5, 0x57, 0x3c,
  113. 0x1b, 0xa8, 0x44, 0xa4, 0x57, 0x8f, 0x33, 0x52,
  114. 0xad, 0x83, 0xae, 0x4a, 0x97, 0xa6, 0x1e, 0xa6,
  115. 0x2b, 0xfa, 0xea, 0xeb, 0x6e, 0x71, 0xb8, 0xb6,
  116. 0x0a, 0x36, 0xed, 0x83, 0xce, 0xb0, 0xdf, 0xc1,
  117. 0xd4, 0x3a, 0xe9, 0x99, 0x6f, 0xf3, 0x96, 0xb7};
  118. static CK_RV
  119. meta_clone_template_setup(meta_object_t *object,
  120. const generic_attr_t *attributes, size_t num_attributes);
  121. /*
  122. * meta_objectManager_initialize
  123. *
  124. * Called from meta_Initialize. Initializes all the variables used
  125. * by the object manager.
  126. */
  127. CK_RV
  128. meta_objectManager_initialize()
  129. {
  130. if (pthread_rwlock_init(&meta_objectclose_lock, NULL) != 0) {
  131. return (CKR_FUNCTION_FAILED);
  132. }
  133. if (pthread_rwlock_init(&tokenobject_list_lock, NULL) != 0) {
  134. (void) pthread_rwlock_destroy(&meta_objectclose_lock);
  135. return (CKR_FUNCTION_FAILED);
  136. }
  137. tokenobject_list_head = NULL;
  138. return (CKR_OK);
  139. }
  140. void
  141. meta_objectManager_finalize()
  142. {
  143. /*
  144. * If there are still any token object in the list, need to
  145. * deactivate all of them.
  146. */
  147. (void) meta_token_object_deactivate(ALL_TOKEN);
  148. (void) pthread_rwlock_destroy(&meta_objectclose_lock);
  149. (void) pthread_rwlock_destroy(&tokenobject_list_lock);
  150. }
  151. /*
  152. * meta_handle2object
  153. *
  154. * Convert a CK_OBJECT_HANDLE to the corresponding metaobject. If
  155. * successful, a reader-lock on the object will be held to indicate
  156. * that it's in use. Call OBJRELEASE() when finished.
  157. *
  158. */
  159. CK_RV
  160. meta_handle2object(CK_OBJECT_HANDLE hObject, meta_object_t **object)
  161. {
  162. meta_object_t *tmp_object = (meta_object_t *)(hObject);
  163. /* Check for bad args (eg CK_INVALID_HANDLE, which is 0/NULL). */
  164. if (tmp_object == NULL) {
  165. *object = NULL;
  166. return (CKR_OBJECT_HANDLE_INVALID);
  167. }
  168. /* Lock to ensure the magic-check + read-lock is atomic. */
  169. (void) pthread_rwlock_rdlock(&meta_objectclose_lock);
  170. if (tmp_object->magic_marker != METASLOT_OBJECT_MAGIC) {
  171. (void) pthread_rwlock_unlock(&meta_objectclose_lock);
  172. *object = NULL;
  173. return (CKR_OBJECT_HANDLE_INVALID);
  174. }
  175. (void) pthread_rwlock_rdlock(&tmp_object->object_lock);
  176. (void) pthread_rwlock_unlock(&meta_objectclose_lock);
  177. *object = tmp_object;
  178. return (CKR_OK);
  179. }
  180. /*
  181. * meta_object_alloc
  182. *
  183. * Creates a new metaobject, but does not yet add it to the object list.
  184. * Once the caller has finished initializing the object (by setting
  185. * object attributes), meta_object_add should be called. This two-step
  186. * process prevents others from seeing the object until fully intitialized.
  187. *
  188. */
  189. CK_RV
  190. meta_object_alloc(meta_session_t *session, meta_object_t **object)
  191. {
  192. meta_object_t *new_object;
  193. CK_ULONG num_slots;
  194. /* Allocate memory for the object. */
  195. new_object = calloc(1, sizeof (meta_object_t));
  196. if (new_object == NULL)
  197. return (CKR_HOST_MEMORY);
  198. num_slots = meta_slotManager_get_slotcount();
  199. new_object->clones = calloc(num_slots, sizeof (slot_object_t *));
  200. if (new_object->clones == NULL) {
  201. free(new_object);
  202. return (CKR_HOST_MEMORY);
  203. }
  204. new_object->tried_create_clone = calloc(num_slots, sizeof (boolean_t));
  205. if (new_object->tried_create_clone == NULL) {
  206. free(new_object->clones);
  207. free(new_object);
  208. return (CKR_HOST_MEMORY);
  209. }
  210. /* Initialize the object fields. */
  211. new_object->magic_marker = METASLOT_OBJECT_MAGIC;
  212. (void) pthread_rwlock_init(&new_object->object_lock, NULL);
  213. (void) pthread_rwlock_init(&new_object->attribute_lock, NULL);
  214. (void) pthread_mutex_init(&new_object->clone_create_lock, NULL);
  215. (void) pthread_mutex_init(&new_object->isClosingObject_lock, NULL);
  216. new_object->creator_session = session;
  217. *object = new_object;
  218. return (CKR_OK);
  219. }
  220. /*
  221. * meta_object_get_attr
  222. *
  223. * Get attribute values to fill in attribute values
  224. * being kept in the metaslot object. The following 4 attributes
  225. * in the meta_object_t structure will be filled in:
  226. * isToken, isPrivate, isSensitive, isExtractable
  227. *
  228. * It's basically an easy way to do a C_GetAttributeValue.
  229. * So, the hSession argument is assumed
  230. * to be valid, and the pointer to meta_object_t is also assumed
  231. * to be valid.
  232. */
  233. CK_RV
  234. meta_object_get_attr(slot_session_t *slot_session, CK_OBJECT_HANDLE hObject,
  235. meta_object_t *object)
  236. {
  237. CK_BBOOL is_sensitive = object->isSensitive;
  238. CK_BBOOL is_extractable = object->isExtractable;
  239. CK_BBOOL is_token = B_FALSE, is_private = B_FALSE;
  240. CK_KEY_TYPE keytype;
  241. CK_OBJECT_CLASS class;
  242. CK_ATTRIBUTE attrs[3];
  243. CK_RV rv;
  244. CK_SESSION_HANDLE hSession = slot_session->hSession;
  245. CK_SLOT_ID fw_st_id = slot_session->fw_st_id;
  246. int count = 1;
  247. attrs[0].type = CKA_CLASS;
  248. attrs[0].pValue = &class;
  249. attrs[0].ulValueLen = sizeof (class);
  250. if (object->isFreeObject != FREE_ENABLED) {
  251. attrs[1].type = CKA_TOKEN;
  252. attrs[1].pValue = &is_token;
  253. attrs[1].ulValueLen = sizeof (is_token);
  254. count++;
  255. }
  256. /*
  257. * If this is a freeobject, we already know the Private value
  258. * and we don't want to overwrite it with the wrong value
  259. */
  260. if (object->isFreeObject <= FREE_DISABLED) {
  261. attrs[count].type = CKA_PRIVATE;
  262. attrs[count].pValue = &is_private;
  263. attrs[count].ulValueLen = sizeof (is_private);
  264. count++;
  265. } else
  266. is_private = object->isPrivate;
  267. rv = FUNCLIST(fw_st_id)->C_GetAttributeValue(hSession, hObject,
  268. attrs, count);
  269. if (rv != CKR_OK) {
  270. return (rv);
  271. }
  272. count = 0;
  273. switch (class) {
  274. case CKO_PRIVATE_KEY:
  275. case CKO_SECRET_KEY:
  276. /* Only need to check these for private & secret keys */
  277. attrs[0].type = CKA_EXTRACTABLE;
  278. attrs[0].pValue = &is_extractable;
  279. attrs[0].ulValueLen = sizeof (is_extractable);
  280. count = 1;
  281. /*
  282. * If this is a freeobject, we already know the Sensitive
  283. * value and we don't want to overwrite it with the wrong
  284. * value.
  285. */
  286. if (object->isFreeObject <= FREE_DISABLED) {
  287. attrs[1].type = CKA_SENSITIVE;
  288. attrs[1].pValue = &is_sensitive;
  289. attrs[1].ulValueLen = sizeof (is_sensitive);
  290. count = 2;
  291. /*
  292. * We only need the key type if this is the first
  293. * time we've looked at the object
  294. */
  295. if (object->isFreeObject == FREE_UNCHECKED) {
  296. attrs[2].type = CKA_KEY_TYPE;
  297. attrs[2].pValue = &keytype;
  298. attrs[2].ulValueLen = sizeof (keytype);
  299. count = 3;
  300. }
  301. }
  302. break;
  303. case CKO_PUBLIC_KEY:
  304. if (object->isFreeObject == FREE_UNCHECKED) {
  305. attrs[count].type = CKA_KEY_TYPE;
  306. attrs[count].pValue = &keytype;
  307. attrs[count].ulValueLen = sizeof (keytype);
  308. count++;
  309. }
  310. is_sensitive = CK_FALSE;
  311. is_extractable = CK_TRUE;
  312. break;
  313. default:
  314. object->isFreeObject = FREE_DISABLED;
  315. is_sensitive = CK_FALSE;
  316. is_extractable = CK_TRUE;
  317. };
  318. if (count > 0) {
  319. rv = FUNCLIST(fw_st_id)->C_GetAttributeValue(hSession, hObject,
  320. attrs, count);
  321. if (rv != CKR_OK) {
  322. return (rv);
  323. }
  324. if (object->isFreeObject == FREE_UNCHECKED) {
  325. if (keytype == CKK_EC || keytype == CKK_RSA ||
  326. keytype == CKK_DH) {
  327. if (metaslot_config.auto_key_migrate) {
  328. object->isFreeObject = FREE_DISABLED;
  329. object->isFreeToken = FREE_DISABLED;
  330. }
  331. object->isFreeObject = FREE_ENABLED;
  332. if (is_token)
  333. object->isFreeToken = FREE_ENABLED;
  334. } else
  335. object->isFreeObject = FREE_DISABLED;
  336. }
  337. }
  338. object->isToken = is_token;
  339. object->isPrivate = is_private;
  340. object->isSensitive = is_sensitive;
  341. object->isExtractable = is_extractable;
  342. return (CKR_OK);
  343. }
  344. /*
  345. * meta_object_activate
  346. *
  347. * Add a new metaobject to the list of objects. See also meta_object_create,
  348. * which would be called to create an object before it is added.
  349. */
  350. void
  351. meta_object_activate(meta_object_t *new_object)
  352. {
  353. pthread_rwlock_t *list_lock;
  354. meta_object_t **list_head;
  355. /*
  356. * For session objects, we keep the list in the session that created
  357. * this object, because this object will be destroyed when that session
  358. * is closed.
  359. *
  360. * For token objects, the list is global (ie, not associated with any
  361. * particular session).
  362. */
  363. if (new_object->isToken) {
  364. list_lock = &tokenobject_list_lock;
  365. list_head = &tokenobject_list_head;
  366. } else {
  367. list_lock = &new_object->creator_session->object_list_lock;
  368. list_head = &new_object->creator_session->object_list_head;
  369. }
  370. /* Add object to the list of objects. */
  371. (void) pthread_rwlock_wrlock(list_lock);
  372. INSERT_INTO_LIST(*list_head, new_object);
  373. (void) pthread_rwlock_unlock(list_lock);
  374. }
  375. /*
  376. * meta_object_deactivate
  377. *
  378. * Removes the object from the list of valid meta objects. Note
  379. * that this function does not clean up any allocated
  380. * resources (memory, object clones, etc). Cleaning up of
  381. * allocated resources is done by calling the meta_object_dealloc()
  382. *
  383. */
  384. CK_RV
  385. meta_object_deactivate(meta_object_t *object, boolean_t have_list_lock,
  386. boolean_t have_object_lock)
  387. {
  388. pthread_rwlock_t *list_lock;
  389. meta_object_t **list_head;
  390. if (!have_object_lock) {
  391. (void) pthread_rwlock_rdlock(&object->object_lock);
  392. }
  393. (void) pthread_mutex_lock(&object->isClosingObject_lock);
  394. if (object->isClosingObject) {
  395. /* Lost a delete race. */
  396. (void) pthread_mutex_unlock(&object->isClosingObject_lock);
  397. OBJRELEASE(object);
  398. return (CKR_OBJECT_HANDLE_INVALID);
  399. }
  400. object->isClosingObject = B_TRUE;
  401. (void) pthread_mutex_unlock(&object->isClosingObject_lock);
  402. if (object->isToken || (object->isFreeToken == FREE_ENABLED)) {
  403. list_lock = &tokenobject_list_lock;
  404. list_head = &tokenobject_list_head;
  405. } else {
  406. list_lock = &object->creator_session->object_list_lock;
  407. list_head = &object->creator_session->object_list_head;
  408. }
  409. /*
  410. * Remove object from the object list. Once removed, it will not
  411. * be possible for another thread to begin using the object.
  412. */
  413. (void) pthread_rwlock_wrlock(&meta_objectclose_lock);
  414. if (!have_list_lock) {
  415. (void) pthread_rwlock_wrlock(list_lock);
  416. }
  417. object->magic_marker = METASLOT_OBJECT_BADMAGIC;
  418. /*
  419. * Can't use the regular REMOVE_FROM_LIST() function because
  420. * that will miss the "error cleanup" situation where object is not yet
  421. * in the list (object->next == NULL && object->prev == NULL)
  422. */
  423. if (*list_head == object) {
  424. /* Object is the first one in the list */
  425. if (object->next) {
  426. *list_head = object->next;
  427. object->next->prev = NULL;
  428. } else {
  429. /* Object is the only one in the list */
  430. *list_head = NULL;
  431. }
  432. } else if (object->next != NULL || object->prev != NULL) {
  433. if (object->next) {
  434. object->prev->next = object->next;
  435. object->next->prev = object->prev;
  436. } else {
  437. /* Object is the last one in the list */
  438. object->prev->next = NULL;
  439. }
  440. }
  441. if (!have_list_lock) {
  442. (void) pthread_rwlock_unlock(list_lock);
  443. }
  444. (void) pthread_rwlock_unlock(&meta_objectclose_lock);
  445. /*
  446. * Wait for anyone already using object to finish, by obtaining
  447. * a writer-lock (need to release our reader-lock first). Once we
  448. * get the write lock, we can just release it and finish cleaning
  449. * up the object.
  450. */
  451. (void) pthread_rwlock_unlock(&object->object_lock); /* rdlock */
  452. (void) pthread_rwlock_wrlock(&object->object_lock);
  453. (void) pthread_rwlock_unlock(&object->object_lock); /* wrlock */
  454. return (CKR_OK);
  455. }
  456. /*
  457. * meta_object_dealloc
  458. *
  459. * Performs final object cleanup, releasing any allocated memory and
  460. * destroying any clones on other slots. Caller is assumed to have
  461. * called meta_object_deactivate() before this function.
  462. *
  463. * Caller is assumed to have only reference to object, but should have
  464. * released any lock.
  465. *
  466. * If "nukeSourceObj" argument is true, we will actually delete the
  467. * object from the underlying slot.
  468. */
  469. CK_RV
  470. meta_object_dealloc(meta_session_t *session, meta_object_t *object,
  471. boolean_t nukeSourceObj)
  472. {
  473. CK_RV rv, save_rv = CKR_OK;
  474. CK_ULONG slotnum, num_slots;
  475. CK_ULONG i;
  476. /* First, delete all the clones of this object on other slots. */
  477. num_slots = meta_slotManager_get_slotcount();
  478. for (slotnum = 0; slotnum < num_slots; slotnum++) {
  479. slot_session_t *obj_session;
  480. slot_object_t *clone;
  481. clone = object->clones[slotnum];
  482. if (clone == NULL)
  483. continue;
  484. if (nukeSourceObj || (!object->isToken &&
  485. !(object->isFreeToken == FREE_ENABLED &&
  486. get_keystore_slotnum() == slotnum))) {
  487. rv = meta_get_slot_session(slotnum, &obj_session,
  488. (session == NULL) ?
  489. object->creator_session->session_flags :
  490. session->session_flags);
  491. if (rv == CKR_OK) {
  492. rv = FUNCLIST(obj_session->fw_st_id)->\
  493. C_DestroyObject(obj_session->hSession,
  494. clone->hObject);
  495. meta_release_slot_session(obj_session);
  496. if ((rv != CKR_OK) && (save_rv == CKR_OK)) {
  497. save_rv = rv;
  498. }
  499. }
  500. }
  501. meta_slot_object_deactivate(clone);
  502. meta_slot_object_dealloc(clone);
  503. object->clones[slotnum] = NULL;
  504. }
  505. /* Now erase and delete any attributes in the metaobject. */
  506. dealloc_attributes(object->attributes, object->num_attributes);
  507. free(object->clones);
  508. free(object->tried_create_clone);
  509. if (object->clone_template) {
  510. for (i = 0; i < object->clone_template_size; i++) {
  511. free(((object->clone_template)[i]).pValue);
  512. }
  513. free(object->clone_template);
  514. }
  515. /* Cleanup remaining object fields. */
  516. (void) pthread_rwlock_destroy(&object->object_lock);
  517. (void) pthread_rwlock_destroy(&object->attribute_lock);
  518. (void) pthread_mutex_destroy(&object->isClosingObject_lock);
  519. (void) pthread_mutex_destroy(&object->clone_create_lock);
  520. meta_object_delay_free(object);
  521. return (save_rv);
  522. }
  523. /*
  524. * meta_slot_object_alloc
  525. */
  526. CK_RV
  527. meta_slot_object_alloc(slot_object_t **object) {
  528. slot_object_t *new_object;
  529. new_object = calloc(1, sizeof (slot_object_t));
  530. if (new_object == NULL)
  531. return (CKR_HOST_MEMORY);
  532. *object = new_object;
  533. return (CKR_OK);
  534. }
  535. /*
  536. * meta_slot_object_activate
  537. */
  538. void
  539. meta_slot_object_activate(slot_object_t *object,
  540. slot_session_t *creator_session, boolean_t isToken)
  541. {
  542. object->creator_session = creator_session;
  543. if (isToken) {
  544. extern slot_data_t *slots;
  545. slot_data_t *slot;
  546. slot = &(slots[object->creator_session->slotnum]);
  547. (void) pthread_rwlock_wrlock(&slot->tokenobject_list_lock);
  548. INSERT_INTO_LIST(slot->tokenobject_list_head, object);
  549. (void) pthread_rwlock_unlock(&slot->tokenobject_list_lock);
  550. } else {
  551. slot_session_t *session = object->creator_session;
  552. /* Add to session's list of session objects. */
  553. (void) pthread_rwlock_wrlock(&session->object_list_lock);
  554. INSERT_INTO_LIST(session->object_list_head, object);
  555. (void) pthread_rwlock_unlock(&session->object_list_lock);
  556. }
  557. /*
  558. * This set tells the slot object that we are in the token list,
  559. * but does not cause harm with the metaobject knowing the object
  560. * isn't a token, but a freetoken
  561. */
  562. object->isToken = isToken;
  563. }
  564. /*
  565. * meta_slot_object_deactivate
  566. *
  567. * Remove the specified slot object from the appropriate object list.
  568. */
  569. void
  570. meta_slot_object_deactivate(slot_object_t *object)
  571. {
  572. slot_object_t **list_head;
  573. pthread_rwlock_t *list_lock;
  574. if (object->isToken) {
  575. extern slot_data_t *slots;
  576. slot_data_t *slot;
  577. slot = &(slots[object->creator_session->slotnum]);
  578. list_head = &slot->tokenobject_list_head;
  579. list_lock = &slot->tokenobject_list_lock;
  580. } else {
  581. list_head = &object->creator_session->object_list_head;
  582. list_lock = &object->creator_session->object_list_lock;
  583. }
  584. (void) pthread_rwlock_wrlock(list_lock);
  585. REMOVE_FROM_LIST(*list_head, object);
  586. (void) pthread_rwlock_unlock(list_lock);
  587. }
  588. /*
  589. * meta_slot_object_dealloc
  590. */
  591. void
  592. meta_slot_object_dealloc(slot_object_t *object)
  593. {
  594. /* Not much cleanup for slot objects, unlike meta objects... */
  595. free(object);
  596. }
  597. /*
  598. * meta_object_copyin
  599. *
  600. * When a key is generated/derived/unwrapped, the attribute values
  601. * created by the token are not immediately read into our copy of the
  602. * attributes. We defer this work until we actually need to know.
  603. */
  604. CK_RV
  605. meta_object_copyin(meta_object_t *object)
  606. {
  607. CK_RV rv = CKR_OK;
  608. slot_session_t *session = NULL;
  609. CK_ATTRIBUTE *attrs = NULL, *attrs_with_val = NULL;
  610. slot_object_t *slot_object = NULL;
  611. CK_ULONG num_attrs = 0, i, num_attrs_with_val;
  612. CK_SESSION_HANDLE hSession;
  613. CK_SLOT_ID fw_st_id;
  614. /* Make sure no one else is looking at attributes. */
  615. (void) pthread_rwlock_wrlock(&object->attribute_lock);
  616. /* Did we just lose a copyin race with another thread */
  617. if (object->attributes != NULL) {
  618. goto finish;
  619. }
  620. slot_object = object->clones[object->master_clone_slotnum];
  621. rv = meta_get_slot_session(object->master_clone_slotnum, &session,
  622. object->creator_session->session_flags);
  623. if (rv != CKR_OK) {
  624. goto finish;
  625. }
  626. /*
  627. * first, get the master template of all the attributes
  628. * for this object
  629. */
  630. rv = get_master_attributes_by_object(session, slot_object,
  631. &(object->attributes), &(object->num_attributes));
  632. if (rv != CKR_OK) {
  633. goto finish;
  634. }
  635. /*
  636. * Get value for each attribute items.
  637. *
  638. * Some attributes are required by the given object type.
  639. * Some are optional. Get all the values first, and then
  640. * make sure we have value for all required values,
  641. */
  642. attrs = calloc(object->num_attributes, sizeof (CK_ATTRIBUTE));
  643. if (attrs == NULL) {
  644. rv = CKR_HOST_MEMORY;
  645. goto finish;
  646. }
  647. for (i = 0; i < object->num_attributes; i++) {
  648. attrs[i].type =
  649. ((object->attributes[i]).attribute).type;
  650. }
  651. num_attrs = object->num_attributes;
  652. hSession = session->hSession;
  653. fw_st_id = session->fw_st_id;
  654. /* first, call C_GetAttributeValue() to get size for each attribute */
  655. rv = FUNCLIST(fw_st_id)->C_GetAttributeValue(hSession,
  656. slot_object->hObject, attrs, num_attrs);
  657. /*
  658. * If the return value is not CKR_OK, allow it to be
  659. * CKR_ATTRIBUTE_TYPE_INVALID for now.
  660. * Some attributes defined in PKCS#11 version 2.11
  661. * might not be defined in earlier versions. We will
  662. * TRY to work with those providers if the attribute
  663. * is optional.
  664. */
  665. if ((rv != CKR_OK) && (rv != CKR_ATTRIBUTE_TYPE_INVALID)) {
  666. rv = CKR_FUNCTION_FAILED; /* make sure rv is appropriate */
  667. goto finish;
  668. }
  669. /*
  670. * allocate space.
  671. * Since we don't know how many attributes have
  672. * values at this time, just assume all of them
  673. * have values so we save one loop to count the number
  674. * of attributes that have value.
  675. */
  676. attrs_with_val = calloc(num_attrs, sizeof (CK_ATTRIBUTE));
  677. if (attrs_with_val == NULL) {
  678. rv = CKR_HOST_MEMORY;
  679. goto finish;
  680. }
  681. num_attrs_with_val = 0;
  682. for (i = 0; i < num_attrs; i++) {
  683. if (!(((CK_LONG)(attrs[i].ulValueLen)) > 0)) {
  684. /* if it isn't an optional attr, len should be > 0 */
  685. if (!object->attributes[i].canBeEmptyValue) {
  686. rv = CKR_FUNCTION_FAILED;
  687. goto finish;
  688. }
  689. } else {
  690. attrs_with_val[num_attrs_with_val].type = attrs[i].type;
  691. attrs_with_val[num_attrs_with_val].ulValueLen =
  692. attrs[i].ulValueLen;
  693. attrs_with_val[num_attrs_with_val].pValue =
  694. malloc(attrs[i].ulValueLen);
  695. if (attrs_with_val[num_attrs_with_val].pValue == NULL) {
  696. rv = CKR_HOST_MEMORY;
  697. goto finish;
  698. }
  699. num_attrs_with_val++;
  700. }
  701. }
  702. rv = FUNCLIST(fw_st_id)->C_GetAttributeValue(hSession,
  703. slot_object->hObject, attrs_with_val, num_attrs_with_val);
  704. if (rv != CKR_OK) {
  705. goto finish;
  706. }
  707. /* store these values into the meta object */
  708. for (i = 0; i < num_attrs_with_val; i++) {
  709. rv = attribute_set_value(&(attrs_with_val[i]),
  710. object->attributes, object->num_attributes);
  711. if (rv != CKR_OK) {
  712. goto finish;
  713. }
  714. }
  715. finish:
  716. (void) pthread_rwlock_unlock(&object->attribute_lock);
  717. if (session)
  718. meta_release_slot_session(session);
  719. if (attrs) {
  720. for (i = 0; i < num_attrs; i++) {
  721. if (attrs[i].pValue != NULL) {
  722. free(attrs[i].pValue);
  723. }
  724. }
  725. free(attrs);
  726. }
  727. if (attrs_with_val) {
  728. for (i = 0; i < num_attrs; i++) {
  729. if (attrs_with_val[i].pValue != NULL) {
  730. free(attrs_with_val[i].pValue);
  731. }
  732. }
  733. free(attrs_with_val);
  734. }
  735. return (rv);
  736. }
  737. /*
  738. * Create an object to be used for wrapping and unwrapping.
  739. * The same template will be used for all wrapping/unwrapping keys all
  740. * the time
  741. */
  742. static CK_RV
  743. create_wrap_unwrap_key(slot_session_t *slot_session, CK_OBJECT_HANDLE *hObject,
  744. wrap_info_t *wrap_info, char *key_data, CK_ULONG key_len)
  745. {
  746. CK_OBJECT_CLASS objclass;
  747. CK_KEY_TYPE keytype;
  748. CK_RV rv = CKR_OK;
  749. int i;
  750. CK_ATTRIBUTE template[WRAP_KEY_TEMPLATE_SIZE];
  751. i = 0;
  752. objclass = wrap_info->class;
  753. template[i].type = CKA_CLASS;
  754. template[i].pValue = &objclass;
  755. template[i].ulValueLen = sizeof (objclass);
  756. i++;
  757. keytype = wrap_info->key_type;
  758. template[i].type = CKA_KEY_TYPE;
  759. template[i].pValue = &keytype;
  760. template[i].ulValueLen = sizeof (keytype);
  761. i++;
  762. template[i].type = CKA_TOKEN;
  763. template[i].pValue = &falsevalue;
  764. template[i].ulValueLen = sizeof (falsevalue);
  765. if (objclass == CKO_SECRET_KEY) {
  766. i++;
  767. template[i].type = CKA_VALUE;
  768. template[i].pValue = key_data;
  769. template[i].ulValueLen = key_len;
  770. i++;
  771. template[i].type = CKA_WRAP;
  772. template[i].pValue = &truevalue;
  773. template[i].ulValueLen = sizeof (truevalue);
  774. i++;
  775. template[i].type = CKA_UNWRAP;
  776. template[i].pValue = &truevalue;
  777. template[i].ulValueLen = sizeof (truevalue);
  778. } else {
  779. /* Modulus is the same for rsa public and private key */
  780. i++;
  781. template[i].type = CKA_MODULUS;
  782. template[i].pValue = Modulus;
  783. template[i].ulValueLen = sizeof (Modulus);
  784. if (objclass == CKO_PUBLIC_KEY) {
  785. /* RSA public key */
  786. i++;
  787. template[i].type = CKA_PUBLIC_EXPONENT;
  788. template[i].pValue = PubExpo;
  789. template[i].ulValueLen = sizeof (PubExpo);
  790. i++;
  791. template[i].type = CKA_WRAP;
  792. template[i].pValue = &truevalue;
  793. template[i].ulValueLen = sizeof (truevalue);
  794. } else {
  795. /* RSA private key */
  796. i++;
  797. template[i].type = CKA_PRIVATE_EXPONENT;
  798. template[i].pValue = PriExpo;
  799. template[i].ulValueLen = sizeof (PriExpo);
  800. i++;
  801. template[i].type = CKA_UNWRAP;
  802. template[i].pValue = &truevalue;
  803. template[i].ulValueLen = sizeof (truevalue);
  804. }
  805. }
  806. rv = FUNCLIST(slot_session->fw_st_id)->C_CreateObject(
  807. slot_session->hSession, template, i + 1, hObject);
  808. return (rv);
  809. }
  810. /*
  811. * Create a clone of a non-sensitive and extractable object.
  812. * If the template required for creating the clone doesn't exist,
  813. * it will be retrieved from the master clone.
  814. */
  815. static CK_RV
  816. clone_by_create(meta_object_t *object, slot_object_t *new_clone,
  817. slot_session_t *dst_slot_session)
  818. {
  819. CK_RV rv;
  820. int free_token_index = -1;
  821. if (object->attributes == NULL) {
  822. rv = meta_object_copyin(object);
  823. if (rv != CKR_OK) {
  824. return (rv);
  825. }
  826. }
  827. if (object->clone_template == NULL) {
  828. rv = meta_clone_template_setup(object, object->attributes,
  829. object->num_attributes);
  830. if (rv != CKR_OK) {
  831. return (rv);
  832. }
  833. }
  834. if (object->isFreeToken == FREE_ENABLED) {
  835. if (dst_slot_session->slotnum == get_keystore_slotnum())
  836. free_token_index = set_template_boolean(CKA_TOKEN,
  837. object->clone_template,
  838. object->clone_template_size, B_FALSE, &truevalue);
  839. else
  840. free_token_index = set_template_boolean(CKA_TOKEN,
  841. object->clone_template,
  842. object->clone_template_size, B_FALSE, &falsevalue);
  843. }
  844. /* Create the clone... */
  845. rv = FUNCLIST(dst_slot_session->fw_st_id)->C_CreateObject(
  846. dst_slot_session->hSession, object->clone_template,
  847. object->clone_template_size, &(new_clone->hObject));
  848. if (free_token_index != -1) {
  849. free_token_index = set_template_boolean(CKA_TOKEN,
  850. object->clone_template, object->clone_template_size,
  851. B_FALSE, &falsevalue);
  852. }
  853. if (rv != CKR_OK) {
  854. return (rv);
  855. }
  856. return (CKR_OK);
  857. }
  858. /*
  859. * Goes through the list of wraping mechanisms, and returns the first
  860. * one that is supported by both the source and the destination slot.
  861. * If none of the mechanisms are supported by both slot, return the
  862. * first mechanism that's supported by the source slot
  863. */
  864. static CK_RV
  865. find_best_match_wrap_mech(wrap_info_t *wrap_info, int num_info,
  866. CK_ULONG src_slotnum, CK_ULONG dst_slotnum, int *first_both_mech,
  867. int *first_src_mech)
  868. {
  869. int i;
  870. boolean_t src_supports, dst_supports;
  871. CK_RV rv;
  872. CK_MECHANISM_INFO mech_info;
  873. mech_info.flags = CKF_WRAP;
  874. for (i = 0; i < num_info; i++) {
  875. src_supports = B_FALSE;
  876. dst_supports = B_FALSE;
  877. rv = meta_mechManager_slot_supports_mech(
  878. (wrap_info[i]).mech_type, src_slotnum,
  879. &src_supports, NULL, B_FALSE, &mech_info);
  880. if (rv != CKR_OK) {
  881. return (rv);
  882. }
  883. rv = meta_mechManager_slot_supports_mech(
  884. (wrap_info[i]).mech_type, dst_slotnum,
  885. &dst_supports, NULL, B_FALSE, &mech_info);
  886. if (rv != CKR_OK) {
  887. return (rv);
  888. }
  889. /* both source and destination supports the mech */
  890. if ((src_supports) && (dst_supports)) {
  891. *first_both_mech = i;
  892. return (CKR_OK);
  893. }
  894. if ((src_supports) && (*first_src_mech == -1)) {
  895. *first_src_mech = i;
  896. }
  897. }
  898. return (CKR_OK);
  899. }
  900. /*
  901. * Determine the wrapping/unwrapping mechanism to be used
  902. *
  903. * If possible, select a mechanism that's supported by both source
  904. * and destination slot. If none of the mechanisms are supported
  905. * by both slot, then, select the first one supported by
  906. * the source slot.
  907. */
  908. static CK_RV
  909. get_wrap_mechanism(CK_OBJECT_CLASS obj_class, CK_KEY_TYPE key_type,
  910. CK_ULONG src_slotnum, CK_ULONG dst_slotnum, wrap_info_t *wrap_info)
  911. {
  912. wrap_info_t *wrap_info_to_search = NULL;
  913. unsigned int num_wrap_info;
  914. CK_RV rv;
  915. int i;
  916. boolean_t src_supports = B_FALSE, dst_supports = B_FALSE;
  917. int first_src_mech, rsa_first_src_mech, first_both_mech;
  918. CK_MECHANISM_INFO mech_info;
  919. mech_info.flags = CKF_WRAP;
  920. if ((obj_class == CKO_PRIVATE_KEY) && (key_type == CKK_KEA)) {
  921. /*
  922. * only SKIPJACK keys can be used for wrapping
  923. * KEA private keys
  924. */
  925. for (i = 0; i < num_special_wrap_info; i++) {
  926. if ((special_wrap_info[i]).mech_type
  927. != CKM_SKIPJACK_WRAP) {
  928. continue;
  929. }
  930. src_supports = B_FALSE;
  931. dst_supports = B_FALSE;
  932. rv = meta_mechManager_slot_supports_mech(
  933. (special_wrap_info[i]).mech_type, src_slotnum,
  934. &src_supports, NULL, B_FALSE, &mech_info);
  935. if (rv != CKR_OK) {
  936. goto finish;
  937. }
  938. rv = meta_mechManager_slot_supports_mech(
  939. (special_wrap_info[i]).mech_type, dst_slotnum,
  940. &dst_supports, NULL, B_FALSE, &mech_info);
  941. if (rv != CKR_OK) {
  942. goto finish;
  943. }
  944. if (src_supports) {
  945. /*
  946. * both src and dst supports the mech or
  947. * only the src supports the mech
  948. */
  949. (void) memcpy(wrap_info,
  950. &(special_wrap_info[i]),
  951. sizeof (wrap_info_t));
  952. wrap_info->src_supports = src_supports;
  953. wrap_info->dst_supports = dst_supports;
  954. rv = CKR_OK;
  955. goto finish;
  956. }
  957. }
  958. /*
  959. * if we are here, that means neither the source slot
  960. * nor the destination slots supports CKM_SKIPJACK_WRAP.
  961. */
  962. rv = CKR_FUNCTION_FAILED;
  963. goto finish;
  964. }
  965. if ((key_type == CKK_SKIPJACK) || (key_type == CKK_BATON) ||
  966. (key_type == CKK_JUNIPER)) {
  967. /* special key types */
  968. wrap_info_to_search = special_wrap_info;
  969. num_wrap_info = num_special_wrap_info;
  970. } else {
  971. /* use the regular wrapping mechanisms */
  972. wrap_info_to_search = common_wrap_info;
  973. num_wrap_info = num_common_wrap_info;
  974. }
  975. first_both_mech = -1;
  976. first_src_mech = -1;
  977. rv = find_best_match_wrap_mech(wrap_info_to_search, num_wrap_info,
  978. src_slotnum, dst_slotnum, &first_both_mech, &first_src_mech);
  979. if (rv != CKR_OK) {
  980. goto finish;
  981. }
  982. if (first_both_mech != -1) {
  983. (void) memcpy(wrap_info,
  984. &(wrap_info_to_search[first_both_mech]),
  985. sizeof (wrap_info_t));
  986. wrap_info->src_supports = B_TRUE;
  987. wrap_info->dst_supports = B_TRUE;
  988. rv = CKR_OK;
  989. goto finish;
  990. }
  991. /*
  992. * If we are here, we did not find a mechanism that's supported
  993. * by both source and destination slot.
  994. *
  995. * If it is a secret key, can also try to wrap it with
  996. * a RSA public key
  997. */
  998. if (obj_class == CKO_SECRET_KEY) {
  999. first_both_mech = -1;
  1000. rsa_first_src_mech = -1;
  1001. rv = find_best_match_wrap_mech(rsa_wrap_info,
  1002. num_rsa_wrap_info, src_slotnum, dst_slotnum,
  1003. &first_both_mech, &rsa_first_src_mech);
  1004. if (rv != CKR_OK) {
  1005. goto finish;
  1006. }
  1007. if (first_both_mech > -1) {
  1008. (void) memcpy(wrap_info,
  1009. &(rsa_wrap_info[first_both_mech]),
  1010. sizeof (wrap_info_t));
  1011. wrap_info->src_supports = B_TRUE;
  1012. wrap_info->dst_supports = B_TRUE;
  1013. rv = CKR_OK;
  1014. goto finish;
  1015. }
  1016. }
  1017. /*
  1018. * if we are here, that means none of the mechanisms are supported
  1019. * by both the source and the destination
  1020. */
  1021. if (first_src_mech > -1) {
  1022. /* source slot support one of the secret key mechs */
  1023. (void) memcpy(wrap_info,
  1024. &(wrap_info_to_search[first_src_mech]),
  1025. sizeof (wrap_info_t));
  1026. wrap_info->src_supports = B_TRUE;
  1027. wrap_info->dst_supports = B_FALSE;
  1028. rv = CKR_OK;
  1029. } else if (rsa_first_src_mech > -1) {
  1030. /* source slot support one of the RSA mechs */
  1031. (void) memcpy(wrap_info, &(rsa_wrap_info[rsa_first_src_mech]),
  1032. sizeof (wrap_info_t));
  1033. wrap_info->src_supports = B_TRUE;
  1034. wrap_info->dst_supports = B_FALSE;
  1035. rv = CKR_OK;
  1036. } else {
  1037. /* neither source nor destination support any wrap mechs */
  1038. rv = CKR_FUNCTION_FAILED;
  1039. }
  1040. finish:
  1041. return (rv);
  1042. }
  1043. /*
  1044. * This is called if the object to be cloned is a sensitive object
  1045. */
  1046. static CK_RV
  1047. clone_by_wrap(meta_object_t *object, slot_object_t *new_clone,
  1048. slot_session_t *dst_slot_session)
  1049. {
  1050. slot_session_t *src_slot_session = NULL;
  1051. CK_OBJECT_HANDLE wrappingKey = NULL, unwrappingKey = NULL;
  1052. CK_MECHANISM wrappingMech;
  1053. CK_BYTE *wrappedKey = NULL;
  1054. CK_ULONG wrappedKeyLen = 0;
  1055. slot_object_t *slot_object = NULL;
  1056. CK_RV rv = CKR_OK;
  1057. CK_OBJECT_HANDLE unwrapped_obj;
  1058. meta_object_t *tmp_meta_obj = NULL;
  1059. slot_object_t *tmp_slot_obj = NULL;
  1060. CK_OBJECT_CLASS obj_class;
  1061. CK_KEY_TYPE key_type;
  1062. meta_session_t *tmp_meta_session = NULL;
  1063. CK_ATTRIBUTE unwrap_template[4];
  1064. char key_data[1024]; /* should be big enough for any key size */
  1065. char ivbuf[1024]; /* should be big enough for any mech */
  1066. wrap_info_t wrap_info;
  1067. CK_ULONG key_len, unwrap_template_size;
  1068. slot_object = object->clones[object->master_clone_slotnum];
  1069. rv = meta_get_slot_session(object->master_clone_slotnum,
  1070. &src_slot_session, object->creator_session->session_flags);
  1071. if (rv != CKR_OK) {
  1072. return (rv);
  1073. }
  1074. /*
  1075. * get the object class and key type for unwrap template
  1076. * This information will also be used for determining
  1077. * which wrap mechanism and which key to use for
  1078. * doing the wrapping
  1079. */
  1080. unwrap_template[0].type = CKA_CLASS;
  1081. unwrap_template[0].pValue = &obj_class;
  1082. unwrap_template[0].ulValueLen = sizeof (obj_class);
  1083. unwrap_template[1].type = CKA_KEY_TYPE;
  1084. unwrap_template[1].pValue = &key_type;
  1085. unwrap_template[1].ulValueLen = sizeof (key_type);
  1086. rv = FUNCLIST(src_slot_session->fw_st_id)->C_GetAttributeValue(
  1087. src_slot_session->hSession, slot_object->hObject,
  1088. unwrap_template, 2);
  1089. if (rv != CKR_OK) {
  1090. goto finish;
  1091. }
  1092. rv = get_wrap_mechanism(obj_class, key_type, src_slot_session->slotnum,
  1093. dst_slot_session->slotnum, &wrap_info);
  1094. if (rv != CKR_OK) {
  1095. goto finish;
  1096. }
  1097. /*
  1098. * read number of bytes required from random device for
  1099. * creating a secret key for wrapping and unwrapping
  1100. */
  1101. if (wrap_info.class == CKO_SECRET_KEY) {
  1102. /*
  1103. * /dev/urandom will be used for generating the key used
  1104. * for doing the wrap/unwrap. It's should be ok to
  1105. * use /dev/urandom because this key is used for this
  1106. * one time operation only. It doesn't need to be stored.
  1107. */
  1108. key_len = wrap_info.key_length;
  1109. if (pkcs11_get_urandom(key_data, key_len) < 0) {
  1110. rv = CKR_FUNCTION_FAILED;
  1111. goto finish;
  1112. }
  1113. if (wrap_info.iv_length > 0) {
  1114. if (pkcs11_get_urandom(
  1115. ivbuf, wrap_info.iv_length) < 0) {
  1116. rv = CKR_FUNCTION_FAILED;
  1117. goto finish;
  1118. }
  1119. }
  1120. }
  1121. /* create the wrapping key */
  1122. rv = create_wrap_unwrap_key(src_slot_session, &wrappingKey,
  1123. &wrap_info, key_data, key_len);
  1124. if (rv != CKR_OK) {
  1125. goto finish;
  1126. }
  1127. wrappingMech.mechanism = wrap_info.mech_type;
  1128. wrappingMech.pParameter = ((wrap_info.iv_length > 0) ? ivbuf : NULL);
  1129. wrappingMech.ulParameterLen = wrap_info.iv_length;
  1130. /* get the size of the wrapped key */
  1131. rv = FUNCLIST(src_slot_session->fw_st_id)->C_WrapKey(
  1132. src_slot_session->hSession, &wrappingMech,
  1133. wrappingKey, slot_object->hObject, NULL, &wrappedKeyLen);
  1134. if (rv != CKR_OK) {
  1135. goto finish;
  1136. }
  1137. wrappedKey = malloc(wrappedKeyLen * sizeof (CK_BYTE));
  1138. if (wrappedKey == NULL) {
  1139. rv = CKR_HOST_MEMORY;
  1140. goto finish;
  1141. }
  1142. /* do the actual key wrapping */
  1143. rv = FUNCLIST(src_slot_session->fw_st_id)->C_WrapKey(
  1144. src_slot_session->hSession, &wrappingMech,
  1145. wrappingKey, slot_object->hObject, wrappedKey, &wrappedKeyLen);
  1146. if (rv != CKR_OK) {
  1147. goto finish;
  1148. }
  1149. /* explicitly force the unwrapped object to be not sensitive */
  1150. unwrap_template[2].type = CKA_SENSITIVE;
  1151. unwrap_template[2].pValue = &falsevalue;
  1152. unwrap_template[2].ulValueLen = sizeof (falsevalue);
  1153. unwrap_template[3].type = CKA_TOKEN;
  1154. unwrap_template[3].pValue = &falsevalue;
  1155. unwrap_template[3].ulValueLen = sizeof (falsevalue);
  1156. unwrap_template_size =
  1157. sizeof (unwrap_template) / sizeof (CK_ATTRIBUTE);
  1158. if (!wrap_info.dst_supports) {
  1159. /*
  1160. * if we know for sure that the destination slot doesn't
  1161. * support the wrapping mechanism, no point in trying.
  1162. * go directly to unwrap in source slot, and create key
  1163. * in destination
  1164. */
  1165. goto unwrap_in_source;
  1166. }
  1167. /* create the unwrapping key in destination slot */
  1168. if (wrap_info.key_type == CKK_RSA) {
  1169. /* for RSA key, the unwrapping key need to be private key */
  1170. wrap_info.class = CKO_PRIVATE_KEY;
  1171. }
  1172. rv = create_wrap_unwrap_key(dst_slot_session,
  1173. &unwrappingKey, &wrap_info, key_data, key_len);
  1174. if (rv != CKR_OK) {
  1175. goto finish;
  1176. }
  1177. rv = FUNCLIST(dst_slot_session->fw_st_id)->C_UnwrapKey(
  1178. dst_slot_session->hSession, &wrappingMech,
  1179. unwrappingKey, wrappedKey, wrappedKeyLen, unwrap_template,
  1180. unwrap_template_size, &(new_clone->hObject));
  1181. if (rv != CKR_OK) {
  1182. unwrap_in_source:
  1183. /*
  1184. * There seemed to be a problem with unwrapping in the
  1185. * destination slot.
  1186. * Try to do the unwrap in the src slot so it becomes
  1187. * a non-sensitive object, then, get all the attributes
  1188. * and create the object in the destination slot
  1189. */
  1190. if (wrap_info.class == CKO_SECRET_KEY) {
  1191. /* unwrap with same key used for wrapping */
  1192. rv = FUNCLIST(src_slot_session->fw_st_id)->C_UnwrapKey(
  1193. src_slot_session->hSession,
  1194. &wrappingMech, wrappingKey, wrappedKey,
  1195. wrappedKeyLen, unwrap_template,
  1196. unwrap_template_size, &(unwrapped_obj));
  1197. } else {
  1198. /*
  1199. * If the object is wrapping with RSA public key, need
  1200. * need to create RSA private key for unwrapping
  1201. */
  1202. wrap_info.class = CKO_PRIVATE_KEY;
  1203. rv = create_wrap_unwrap_key(src_slot_session,
  1204. &unwrappingKey, &wrap_info, key_data, key_len);
  1205. if (rv != CKR_OK) {
  1206. goto finish;
  1207. }
  1208. rv = FUNCLIST(src_slot_session->fw_st_id)->C_UnwrapKey(
  1209. src_slot_session->hSession,
  1210. &wrappingMech, unwrappingKey, wrappedKey,
  1211. wrappedKeyLen, unwrap_template,
  1212. unwrap_template_size, &(unwrapped_obj));
  1213. }
  1214. if (rv != CKR_OK) {
  1215. goto finish;
  1216. }
  1217. rv = meta_session_alloc(&tmp_meta_session);
  1218. if (rv != CKR_OK) {
  1219. goto finish;
  1220. }
  1221. tmp_meta_session->session_flags = CKF_SERIAL_SESSION;
  1222. rv = meta_object_alloc(tmp_meta_session, &tmp_meta_obj);
  1223. if (rv != CKR_OK) {
  1224. goto finish;
  1225. }
  1226. rv = meta_slot_object_alloc(&tmp_slot_obj);
  1227. if (rv != CKR_OK) {
  1228. goto finish;
  1229. }
  1230. tmp_meta_obj->master_clone_slotnum = src_slot_session->slotnum;
  1231. tmp_slot_obj->hObject = unwrapped_obj;
  1232. tmp_meta_obj->clones[tmp_meta_obj->master_clone_slotnum]
  1233. = tmp_slot_obj;
  1234. meta_slot_object_activate(tmp_slot_obj, src_slot_session,
  1235. B_FALSE);
  1236. tmp_slot_obj = NULL;
  1237. rv = clone_by_create(tmp_meta_obj, new_clone,
  1238. dst_slot_session);
  1239. if (rv != CKR_OK) {
  1240. goto finish;
  1241. }
  1242. }
  1243. finish:
  1244. if (unwrappingKey) {
  1245. (void) FUNCLIST(dst_slot_session->fw_st_id)->C_DestroyObject(
  1246. dst_slot_session->hSession, unwrappingKey);
  1247. }
  1248. if (wrappingKey) {
  1249. (void) FUNCLIST(src_slot_session->fw_st_id)->C_DestroyObject(
  1250. src_slot_session->hSession, wrappingKey);
  1251. }
  1252. if (tmp_slot_obj) {
  1253. (void) meta_slot_object_dealloc(tmp_slot_obj);
  1254. }
  1255. if (tmp_meta_obj) {
  1256. (void) meta_object_dealloc(tmp_meta_session, tmp_meta_obj,
  1257. B_TRUE);
  1258. }
  1259. if (tmp_meta_session) {
  1260. (void) meta_session_dealloc(tmp_meta_session);
  1261. }
  1262. if (wrappedKey) {
  1263. free(wrappedKey);
  1264. }
  1265. if (src_slot_session) {
  1266. meta_release_slot_session(src_slot_session);
  1267. }
  1268. return (rv);
  1269. }
  1270. /*
  1271. * meta_object_get_clone
  1272. *
  1273. * Creates a "clone" of a metaobject on the specified slot. A clone is a
  1274. * copy of the object.
  1275. *
  1276. * Clones are cached, so that they can be reused with subsequent operations.
  1277. */
  1278. CK_RV
  1279. meta_object_get_clone(meta_object_t *object,
  1280. CK_ULONG slot_num, slot_session_t *slot_session,
  1281. slot_object_t **clone)
  1282. {
  1283. CK_RV rv = CKR_OK;
  1284. slot_object_t *newclone = NULL;
  1285. /* Does a clone already exist? */
  1286. if (object->clones[slot_num] != NULL) {
  1287. *clone = object->clones[slot_num];
  1288. return (CKR_OK);
  1289. }
  1290. if ((object->isSensitive) && (object->isToken) &&
  1291. (!metaslot_auto_key_migrate)) {
  1292. /*
  1293. * if the object is a sensitive token object, and auto
  1294. * key migrate is not allowed, will not create the clone
  1295. * in another slot
  1296. */
  1297. return (CKR_FUNCTION_FAILED);
  1298. }
  1299. /* object attributes can't be extracted and attributes are not known */
  1300. if ((!object->isExtractable) && (object->attributes == NULL)) {
  1301. return (CKR_FUNCTION_FAILED);
  1302. }
  1303. (void) pthread_mutex_lock(&object->clone_create_lock);
  1304. /* Maybe someone just created one? */
  1305. if (object->clones[slot_num] != NULL) {
  1306. *clone = object->clones[slot_num];
  1307. goto finish;
  1308. }
  1309. /*
  1310. * has an attempt already been made to create this object in
  1311. * slot? If yes, and there's no clone, as indicated above,
  1312. * that means this object can't be created in this slot.
  1313. */
  1314. if (object->tried_create_clone[slot_num]) {
  1315. (void) pthread_mutex_unlock(&object->clone_create_lock);
  1316. return (CKR_FUNCTION_FAILED);
  1317. }
  1318. rv = meta_slot_object_alloc(&newclone);
  1319. if (rv != CKR_OK)
  1320. goto finish;
  1321. object->tried_create_clone[slot_num] = B_TRUE;
  1322. /*
  1323. * If this object is sensitive and we do not have not copied in the
  1324. * attributes via FreeObject functionality, then we need to wrap it off
  1325. * the provider. If we do have attributes, we can just create the
  1326. * clone
  1327. */
  1328. if (object->isSensitive && object->attributes == NULL) {
  1329. rv = clone_by_wrap(object, newclone, slot_session);
  1330. } else {
  1331. rv = clone_by_create(object, newclone, slot_session);
  1332. }
  1333. if (rv != CKR_OK) {
  1334. goto finish;
  1335. }
  1336. object->clones[slot_num] = newclone;
  1337. meta_slot_object_activate(newclone, slot_session, object->isToken);
  1338. *clone = newclone;
  1339. newclone = NULL;
  1340. finish:
  1341. (void) pthread_mutex_unlock(&object->clone_create_lock);
  1342. if (newclone)
  1343. meta_slot_object_dealloc(newclone);
  1344. return (rv);
  1345. }
  1346. /*
  1347. * meta_setup_clone_template
  1348. *
  1349. * Create a clone template for the specified object.
  1350. */
  1351. static CK_RV
  1352. meta_clone_template_setup(meta_object_t *object,
  1353. const generic_attr_t *attributes, size_t num_attributes)
  1354. {
  1355. CK_RV rv = CKR_OK;
  1356. CK_ATTRIBUTE *clone_template;
  1357. size_t i, c = 0;
  1358. clone_template = malloc(num_attributes * sizeof (CK_ATTRIBUTE));
  1359. if (clone_template == NULL) {
  1360. rv = CKR_HOST_MEMORY;
  1361. goto finish;
  1362. }
  1363. /* Don't allow attributes to change while we look at them. */
  1364. (void) pthread_rwlock_rdlock(&object->attribute_lock);
  1365. for (i = 0; i < num_attributes; i++) {
  1366. if (!attributes[i].isCloneAttr ||
  1367. (attributes[i].attribute.type == CKA_TOKEN &&
  1368. object->isFreeToken == FREE_DISABLED)) {
  1369. continue;
  1370. }
  1371. if ((!(attributes[i].hasValueForClone)) &&
  1372. (attributes[i].canBeEmptyValue)) {
  1373. continue;
  1374. }
  1375. clone_template[c].type = attributes[i].attribute.type;
  1376. clone_template[c].ulValueLen =
  1377. attributes[i].attribute.ulValueLen;
  1378. /* Allocate space to store the attribute value. */
  1379. clone_template[c].pValue = malloc(clone_template[c].ulValueLen);
  1380. if (clone_template[c].pValue == NULL) {
  1381. free(clone_template);
  1382. rv = CKR_HOST_MEMORY;
  1383. (void) pthread_rwlock_unlock(&object->attribute_lock);
  1384. goto finish;
  1385. }
  1386. (void) memcpy(clone_template[c].pValue,
  1387. object->attributes[i].attribute.pValue,
  1388. clone_template[c].ulValueLen);
  1389. c++;
  1390. }
  1391. (void) pthread_rwlock_unlock(&object->attribute_lock);
  1392. object->clone_template = clone_template;
  1393. object->clone_template_size = c;
  1394. finish:
  1395. return (rv);
  1396. }
  1397. /*
  1398. * meta_object_find_by_handle
  1399. *
  1400. * Search for an existing metaobject, using the object handle of a clone
  1401. * on a particular slot.
  1402. *
  1403. * Returns a matching metaobject, or NULL if no match was found.
  1404. */
  1405. meta_object_t *
  1406. meta_object_find_by_handle(CK_OBJECT_HANDLE hObject, CK_ULONG slotnum,
  1407. boolean_t token_only)
  1408. {
  1409. meta_object_t *object = NULL, *tmp_obj;
  1410. meta_session_t *session;
  1411. if (!token_only) {
  1412. (void) pthread_rwlock_rdlock(&meta_sessionlist_lock);
  1413. session = meta_sessionlist_head;
  1414. while (session != NULL) {
  1415. /* lock the objects list while we look at it */
  1416. (void) pthread_rwlock_rdlock(
  1417. &(session->object_list_lock));
  1418. tmp_obj = session->object_list_head;
  1419. while (tmp_obj != NULL) {
  1420. slot_object_t *slot_object;
  1421. (void) pthread_rwlock_rdlock(
  1422. &(tmp_obj->object_lock));
  1423. slot_object = tmp_obj->clones[slotnum];
  1424. if (slot_object != NULL) {
  1425. if (slot_object->hObject == hObject) {
  1426. object = tmp_obj;
  1427. }
  1428. }
  1429. (void) pthread_rwlock_unlock(
  1430. &(tmp_obj->object_lock));
  1431. if (object != NULL) {
  1432. break;
  1433. }
  1434. tmp_obj = tmp_obj->next;
  1435. }
  1436. (void) pthread_rwlock_unlock(
  1437. &(session->object_list_lock));
  1438. if (object != NULL) {
  1439. break;
  1440. }
  1441. session = session->next;
  1442. }
  1443. (void) pthread_rwlock_unlock(&meta_sessionlist_lock);
  1444. }
  1445. if (object != NULL) {
  1446. /* found the object, no need to look further */
  1447. return (object);
  1448. }
  1449. /*
  1450. * Look at list of token objects
  1451. */
  1452. (void) pthread_rwlock_rdlock(&tokenobject_list_lock);
  1453. tmp_obj = tokenobject_list_head;
  1454. while (tmp_obj != NULL) {
  1455. slot_object_t *slot_object;
  1456. (void) pthread_rwlock_rdlock(&(tmp_obj->object_lock));
  1457. slot_object = tmp_obj->clones[slotnum];
  1458. if (slot_object != NULL) {
  1459. if (slot_object->hObject == hObject)
  1460. object = tmp_obj;
  1461. }
  1462. (void) pthread_rwlock_unlock(&(tmp_obj->object_lock));
  1463. if (object != NULL) {
  1464. break;
  1465. }
  1466. tmp_obj = tmp_obj->next;
  1467. }
  1468. (void) pthread_rwlock_unlock(&tokenobject_list_lock);
  1469. return (object);
  1470. }
  1471. CK_RV
  1472. meta_token_object_deactivate(token_obj_type_t token_type)
  1473. {
  1474. meta_object_t *object, *tmp_object;
  1475. CK_RV save_rv = CKR_OK, rv;
  1476. /* get a write lock on the token object list */
  1477. (void) pthread_rwlock_wrlock(&tokenobject_list_lock);
  1478. object = tokenobject_list_head;
  1479. /* go through each object and delete the one with matching type */
  1480. while (object != NULL) {
  1481. tmp_object = object->next;
  1482. if ((token_type == ALL_TOKEN) ||
  1483. ((object->isPrivate) && (token_type == PRIVATE_TOKEN)) ||
  1484. ((!object->isPrivate) && (token_type == PUBLIC_TOKEN))) {
  1485. rv = meta_object_deactivate(object, B_TRUE, B_FALSE);
  1486. if ((rv != CKR_OK) && (save_rv == CKR_OK)) {
  1487. save_rv = rv;
  1488. goto finish;
  1489. }
  1490. rv = meta_object_dealloc(NULL, object, B_FALSE);
  1491. if ((rv != CKR_OK) && (save_rv == CKR_OK)) {
  1492. save_rv = rv;
  1493. goto finish;
  1494. }
  1495. }
  1496. object = tmp_object;
  1497. }
  1498. finish:
  1499. (void) pthread_rwlock_unlock(&tokenobject_list_lock);
  1500. return (save_rv);
  1501. }
  1502. /*
  1503. * This function adds the to-be-freed meta object to a linked list.
  1504. * When the number of objects queued in the linked list reaches the
  1505. * maximum threshold MAX_OBJ_TO_BE_FREED, it will free the first
  1506. * object (FIFO) in the list.
  1507. */
  1508. void
  1509. meta_object_delay_free(meta_object_t *objp)
  1510. {
  1511. meta_object_t *tmp;
  1512. (void) pthread_mutex_lock(&obj_delay_freed.obj_to_be_free_mutex);
  1513. /* Add the newly deleted object at the end of the list */
  1514. objp->next = NULL;
  1515. if (obj_delay_freed.first == NULL) {
  1516. obj_delay_freed.last = objp;
  1517. obj_delay_freed.first = objp;
  1518. } else {
  1519. obj_delay_freed.last->next = objp;
  1520. obj_delay_freed.last = objp;
  1521. }
  1522. if (++obj_delay_freed.count >= MAX_OBJ_TO_BE_FREED) {
  1523. /*
  1524. * Free the first object in the list only if
  1525. * the total count reaches maximum threshold.
  1526. */
  1527. obj_delay_freed.count--;
  1528. tmp = obj_delay_freed.first->next;
  1529. free(obj_delay_freed.first);
  1530. obj_delay_freed.first = tmp;
  1531. }
  1532. (void) pthread_mutex_unlock(&obj_delay_freed.obj_to_be_free_mutex);
  1533. }
  1534. /*
  1535. * This function checks if the object passed can be a freeobject.
  1536. *
  1537. * If there is more than one provider that supports the supported freeobject
  1538. * mechanisms then allow freeobjects to be an option.
  1539. */
  1540. boolean_t
  1541. meta_freeobject_check(meta_session_t *session, meta_object_t *object,
  1542. CK_MECHANISM *pMech, CK_ATTRIBUTE *tmpl, CK_ULONG tmpl_len,
  1543. CK_KEY_TYPE keytype)
  1544. {
  1545. mech_support_info_t *info = &(session->mech_support_info);
  1546. /*
  1547. * If key migration is turned off, or the object does not has any of
  1548. * the required flags and there is only one slot, then we don't need
  1549. * FreeObjects.
  1550. */
  1551. if (!metaslot_auto_key_migrate ||
  1552. (!object->isToken && !object->isSensitive &&
  1553. meta_slotManager_get_slotcount() < 2))
  1554. goto failure;
  1555. /*
  1556. * If this call is for key generation, check pMech for supported
  1557. * FreeObject mechs
  1558. */
  1559. if (pMech != NULL) {
  1560. if (pMech->mechanism == CKM_RSA_PKCS_KEY_PAIR_GEN ||
  1561. pMech->mechanism == CKM_EC_KEY_PAIR_GEN ||
  1562. pMech->mechanism == CKM_DH_PKCS_KEY_PAIR_GEN ||
  1563. pMech->mechanism == CKM_DH_PKCS_DERIVE)
  1564. info->mech = pMech->mechanism;
  1565. else
  1566. goto failure;
  1567. /*
  1568. * If this call is for an object creation, look inside the template
  1569. * for supported FreeObject mechs
  1570. */
  1571. } else if (tmpl_len > 0) {
  1572. if (!get_template_ulong(CKA_KEY_TYPE, tmpl, tmpl_len, &keytype))
  1573. goto failure;
  1574. switch (keytype) {
  1575. case CKK_RSA:
  1576. info->mech = CKM_RSA_PKCS_KEY_PAIR_GEN;
  1577. break;
  1578. case CKK_EC:
  1579. info->mech = CKM_EC_KEY_PAIR_GEN;
  1580. break;
  1581. case CKK_DH:

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