PageRenderTime 29ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/usr/src/cmd/cmd-crypto/pktool/genkey.c

https://bitbucket.org/nexenta/illumos-nexenta
C | 562 lines | 451 code | 73 blank | 38 comment | 149 complexity | 7c66f8cd92b70273383d510a54521544 MD5 | raw file
Possible License(s): LGPL-2.0, BSD-3-Clause-No-Nuclear-License-2014, MPL-2.0-no-copyleft-exception, AGPL-1.0, GPL-3.0, LGPL-3.0, BSD-2-Clause, AGPL-3.0, BSD-3-Clause, GPL-2.0, LGPL-2.1, 0BSD
  1. /*
  2. * CDDL HEADER START
  3. *
  4. * The contents of this file are subject to the terms of the
  5. * Common Development and Distribution License (the "License").
  6. * You may not use this file except in compliance with the License.
  7. *
  8. * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  9. * or http://www.opensolaris.org/os/licensing.
  10. * See the License for the specific language governing permissions
  11. * and limitations under the License.
  12. *
  13. * When distributing Covered Code, include this CDDL HEADER in each
  14. * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15. * If applicable, add the following below this CDDL HEADER, with the
  16. * fields enclosed by brackets "[]" replaced with your own identifying
  17. * information: Portions Copyright [yyyy] [name of copyright owner]
  18. *
  19. * CDDL HEADER END
  20. */
  21. /*
  22. * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
  23. * Use is subject to license terms.
  24. */
  25. #pragma ident "%Z%%M% %I% %E% SMI"
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include <ctype.h>
  29. #include <malloc.h>
  30. #include <libgen.h>
  31. #include <errno.h>
  32. #include <cryptoutil.h>
  33. #include <security/cryptoki.h>
  34. #include "common.h"
  35. #include <kmfapi.h>
  36. static KMF_RETURN
  37. genkey_nss(KMF_HANDLE_T kmfhandle, char *token, char *dir, char *prefix,
  38. char *keylabel, KMF_KEY_ALG keyAlg, int keylen, KMF_CREDENTIAL *tokencred)
  39. {
  40. KMF_RETURN kmfrv = KMF_OK;
  41. KMF_KEY_HANDLE key;
  42. KMF_ATTRIBUTE attlist[20];
  43. int i = 0;
  44. KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
  45. KMF_KEY_ALG keytype;
  46. uint32_t keylength;
  47. if (keylabel == NULL) {
  48. cryptoerror(LOG_STDERR,
  49. gettext("A key label must be specified \n"));
  50. return (KMF_ERR_BAD_PARAMETER);
  51. }
  52. kmfrv = configure_nss(kmfhandle, dir, prefix);
  53. if (kmfrv != KMF_OK)
  54. return (kmfrv);
  55. (void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
  56. keytype = keyAlg;
  57. keylength = keylen;
  58. kmf_set_attr_at_index(attlist, i,
  59. KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
  60. i++;
  61. kmf_set_attr_at_index(attlist, i,
  62. KMF_KEY_HANDLE_ATTR, &key, sizeof (KMF_KEY_HANDLE));
  63. i++;
  64. kmf_set_attr_at_index(attlist, i,
  65. KMF_KEYALG_ATTR, &keytype, sizeof (keytype));
  66. i++;
  67. kmf_set_attr_at_index(attlist, i,
  68. KMF_KEYLENGTH_ATTR, &keylength, sizeof (keylength));
  69. i++;
  70. if (keylabel != NULL) {
  71. kmf_set_attr_at_index(attlist, i,
  72. KMF_KEYLABEL_ATTR, keylabel,
  73. strlen(keylabel));
  74. i++;
  75. }
  76. if (tokencred != NULL && tokencred->cred != NULL) {
  77. kmf_set_attr_at_index(attlist, i,
  78. KMF_CREDENTIAL_ATTR, tokencred,
  79. sizeof (KMF_CREDENTIAL));
  80. i++;
  81. }
  82. if (token != NULL) {
  83. kmf_set_attr_at_index(attlist, i,
  84. KMF_TOKEN_LABEL_ATTR, token,
  85. strlen(token));
  86. i++;
  87. }
  88. kmfrv = kmf_create_sym_key(kmfhandle, i, attlist);
  89. return (kmfrv);
  90. }
  91. static KMF_RETURN
  92. genkey_pkcs11(KMF_HANDLE_T kmfhandle, char *token,
  93. char *keylabel, KMF_KEY_ALG keyAlg, int keylen,
  94. char *senstr, char *extstr, boolean_t print_hex,
  95. KMF_CREDENTIAL *tokencred)
  96. {
  97. KMF_RETURN kmfrv = KMF_OK;
  98. KMF_KEY_HANDLE key;
  99. KMF_RAW_SYM_KEY *rkey = NULL;
  100. boolean_t sensitive = B_FALSE;
  101. boolean_t not_extractable = B_FALSE;
  102. char *hexstr = NULL;
  103. int hexstrlen;
  104. KMF_ATTRIBUTE attlist[20];
  105. int i = 0;
  106. KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
  107. KMF_KEY_ALG keytype;
  108. uint32_t keylength;
  109. if (keylabel == NULL) {
  110. cryptoerror(LOG_STDERR,
  111. gettext("A key label must be specified \n"));
  112. return (KMF_ERR_BAD_PARAMETER);
  113. }
  114. /* Check the sensitive option value if specified. */
  115. if (senstr != NULL) {
  116. if (tolower(senstr[0]) == 'y')
  117. sensitive = B_TRUE;
  118. else if (tolower(senstr[0]) == 'n')
  119. sensitive = B_FALSE;
  120. else {
  121. cryptoerror(LOG_STDERR,
  122. gettext("Incorrect sensitive option value.\n"));
  123. return (KMF_ERR_BAD_PARAMETER);
  124. }
  125. }
  126. /* Check the extractable option value if specified. */
  127. if (extstr != NULL) {
  128. if (tolower(extstr[0]) == 'y')
  129. not_extractable = B_FALSE;
  130. else if (tolower(extstr[0]) == 'n')
  131. not_extractable = B_TRUE;
  132. else {
  133. cryptoerror(LOG_STDERR,
  134. gettext("Incorrect extractable option value.\n"));
  135. return (KMF_ERR_BAD_PARAMETER);
  136. }
  137. }
  138. /* Select a PKCS11 token first */
  139. kmfrv = select_token(kmfhandle, token, FALSE);
  140. if (kmfrv != KMF_OK) {
  141. return (kmfrv);
  142. }
  143. (void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
  144. keytype = keyAlg;
  145. keylength = keylen; /* bits */
  146. kmf_set_attr_at_index(attlist, i,
  147. KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
  148. i++;
  149. kmf_set_attr_at_index(attlist, i,
  150. KMF_KEY_HANDLE_ATTR, &key, sizeof (KMF_KEY_HANDLE));
  151. i++;
  152. kmf_set_attr_at_index(attlist, i,
  153. KMF_KEYALG_ATTR, &keytype, sizeof (keytype));
  154. i++;
  155. kmf_set_attr_at_index(attlist, i,
  156. KMF_KEYLENGTH_ATTR, &keylength, sizeof (keylength));
  157. i++;
  158. if (keylabel != NULL) {
  159. kmf_set_attr_at_index(attlist, i,
  160. KMF_KEYLABEL_ATTR, keylabel,
  161. strlen(keylabel));
  162. i++;
  163. }
  164. if (tokencred != NULL && tokencred->cred != NULL) {
  165. kmf_set_attr_at_index(attlist, i,
  166. KMF_CREDENTIAL_ATTR, tokencred,
  167. sizeof (KMF_CREDENTIAL));
  168. i++;
  169. }
  170. kmf_set_attr_at_index(attlist, i,
  171. KMF_SENSITIVE_BOOL_ATTR, &sensitive,
  172. sizeof (sensitive));
  173. i++;
  174. kmf_set_attr_at_index(attlist, i,
  175. KMF_NON_EXTRACTABLE_BOOL_ATTR, &not_extractable,
  176. sizeof (not_extractable));
  177. i++;
  178. kmfrv = kmf_create_sym_key(kmfhandle, i, attlist);
  179. if (kmfrv != KMF_OK) {
  180. goto out;
  181. }
  182. if (print_hex) {
  183. if (sensitive == B_TRUE || not_extractable == B_TRUE) {
  184. cryptoerror(LOG_STDERR,
  185. gettext("Warning: can not reveal the key value "
  186. "for a sensitive or non-extractable key.\n"));
  187. goto out;
  188. } else {
  189. rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
  190. if (rkey == NULL) {
  191. kmfrv = KMF_ERR_MEMORY;
  192. goto out;
  193. }
  194. (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
  195. kmfrv = kmf_get_sym_key_value(kmfhandle, &key, rkey);
  196. if (kmfrv != KMF_OK) {
  197. goto out;
  198. }
  199. hexstrlen = 2 * rkey->keydata.len + 1;
  200. hexstr = malloc(hexstrlen);
  201. if (hexstr == NULL) {
  202. kmfrv = KMF_ERR_MEMORY;
  203. goto out;
  204. }
  205. tohexstr(rkey->keydata.val, rkey->keydata.len, hexstr,
  206. hexstrlen);
  207. (void) printf(gettext("\tKey Value =\"%s\"\n"), hexstr);
  208. }
  209. }
  210. out:
  211. kmf_free_raw_sym_key(rkey);
  212. if (hexstr != NULL)
  213. free(hexstr);
  214. return (kmfrv);
  215. }
  216. static KMF_RETURN
  217. genkey_file(KMF_HANDLE_T kmfhandle, KMF_KEY_ALG keyAlg, int keylen, char *dir,
  218. char *outkey, boolean_t print_hex)
  219. {
  220. KMF_RETURN kmfrv = KMF_OK;
  221. KMF_KEY_HANDLE key;
  222. KMF_RAW_SYM_KEY *rkey = NULL;
  223. char *hexstr = NULL;
  224. int hexstrlen;
  225. KMF_ATTRIBUTE attlist[20];
  226. int i = 0;
  227. KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
  228. KMF_KEY_ALG keytype;
  229. uint32_t keylength;
  230. char *dirpath;
  231. if (EMPTYSTRING(outkey)) {
  232. cryptoerror(LOG_STDERR,
  233. gettext("No output key file was specified for the key\n"));
  234. return (KMF_ERR_BAD_PARAMETER);
  235. }
  236. if (verify_file(outkey)) {
  237. cryptoerror(LOG_STDERR,
  238. gettext("Cannot write the indicated output "
  239. "key file (%s).\n"), outkey);
  240. return (KMF_ERR_BAD_PARAMETER);
  241. }
  242. (void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
  243. keytype = keyAlg;
  244. keylength = keylen;
  245. dirpath = dir;
  246. kmf_set_attr_at_index(attlist, i,
  247. KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
  248. i++;
  249. kmf_set_attr_at_index(attlist, i,
  250. KMF_KEY_HANDLE_ATTR, &key, sizeof (KMF_KEY_HANDLE));
  251. i++;
  252. kmf_set_attr_at_index(attlist, i,
  253. KMF_KEYALG_ATTR, &keytype, sizeof (keytype));
  254. i++;
  255. kmf_set_attr_at_index(attlist, i,
  256. KMF_KEYLENGTH_ATTR, &keylength, sizeof (keylength));
  257. i++;
  258. if (dirpath != NULL) {
  259. kmf_set_attr_at_index(attlist, i,
  260. KMF_DIRPATH_ATTR, dirpath,
  261. strlen(dirpath));
  262. i++;
  263. }
  264. if (outkey != NULL) {
  265. kmf_set_attr_at_index(attlist, i,
  266. KMF_KEY_FILENAME_ATTR, outkey,
  267. strlen(outkey));
  268. i++;
  269. }
  270. kmfrv = kmf_create_sym_key(kmfhandle, i, attlist);
  271. if (kmfrv != KMF_OK) {
  272. goto out;
  273. }
  274. if (print_hex) {
  275. rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
  276. if (rkey == NULL) {
  277. kmfrv = KMF_ERR_MEMORY;
  278. goto out;
  279. }
  280. (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
  281. kmfrv = kmf_get_sym_key_value(kmfhandle, &key, rkey);
  282. if (kmfrv != KMF_OK) {
  283. goto out;
  284. }
  285. hexstrlen = 2 * rkey->keydata.len + 1;
  286. hexstr = malloc(hexstrlen);
  287. if (hexstr == NULL) {
  288. kmfrv = KMF_ERR_MEMORY;
  289. goto out;
  290. }
  291. tohexstr(rkey->keydata.val, rkey->keydata.len, hexstr,
  292. hexstrlen);
  293. (void) printf(gettext("\tKey Value =\"%s\"\n"), hexstr);
  294. }
  295. out:
  296. kmf_free_raw_sym_key(rkey);
  297. if (hexstr != NULL)
  298. free(hexstr);
  299. return (kmfrv);
  300. }
  301. int
  302. pk_genkey(int argc, char *argv[])
  303. {
  304. int rv;
  305. int opt;
  306. extern int optind_av;
  307. extern char *optarg_av;
  308. KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
  309. char *tokenname = NULL;
  310. char *dir = NULL;
  311. char *prefix = NULL;
  312. char *keytype = "generic";
  313. char *keylenstr = NULL;
  314. int keylen = 0;
  315. char *keylabel = NULL;
  316. char *outkey = NULL;
  317. char *senstr = NULL;
  318. char *extstr = NULL;
  319. char *printstr = NULL;
  320. KMF_HANDLE_T kmfhandle = NULL;
  321. KMF_KEY_ALG keyAlg = KMF_GENERIC_SECRET;
  322. boolean_t print_hex = B_FALSE;
  323. KMF_CREDENTIAL tokencred = {NULL, 0};
  324. while ((opt = getopt_av(argc, argv,
  325. "k:(keystore)l:(label)T:(token)d:(dir)p:(prefix)"
  326. "t:(keytype)y:(keylen)K:(outkey)P:(print)"
  327. "s:(sensitive)e:(extractable)")) != EOF) {
  328. if (EMPTYSTRING(optarg_av))
  329. return (PK_ERR_USAGE);
  330. switch (opt) {
  331. case 'k':
  332. kstype = KS2Int(optarg_av);
  333. if (kstype == 0)
  334. return (PK_ERR_USAGE);
  335. break;
  336. case 'l':
  337. if (keylabel)
  338. return (PK_ERR_USAGE);
  339. keylabel = optarg_av;
  340. break;
  341. case 'T':
  342. if (tokenname)
  343. return (PK_ERR_USAGE);
  344. tokenname = optarg_av;
  345. break;
  346. case 'd':
  347. if (dir)
  348. return (PK_ERR_USAGE);
  349. dir = optarg_av;
  350. break;
  351. case 'p':
  352. if (prefix)
  353. return (PK_ERR_USAGE);
  354. prefix = optarg_av;
  355. break;
  356. case 't':
  357. keytype = optarg_av;
  358. break;
  359. case 'y':
  360. if (keylenstr)
  361. return (PK_ERR_USAGE);
  362. keylenstr = optarg_av;
  363. break;
  364. case 'K':
  365. if (outkey)
  366. return (PK_ERR_USAGE);
  367. outkey = optarg_av;
  368. break;
  369. case 'P':
  370. if (printstr)
  371. return (PK_ERR_USAGE);
  372. printstr = optarg_av;
  373. break;
  374. case 's':
  375. if (senstr)
  376. return (PK_ERR_USAGE);
  377. senstr = optarg_av;
  378. break;
  379. case 'e':
  380. if (extstr)
  381. return (PK_ERR_USAGE);
  382. extstr = optarg_av;
  383. break;
  384. default:
  385. return (PK_ERR_USAGE);
  386. }
  387. }
  388. /* No additional args allowed. */
  389. argc -= optind_av;
  390. argv += optind_av;
  391. if (argc) {
  392. return (PK_ERR_USAGE);
  393. }
  394. /* Check keytype. If not specified, default to AES */
  395. if (keytype != NULL && Str2SymKeyType(keytype, &keyAlg) != 0) {
  396. cryptoerror(LOG_STDERR, gettext("Unrecognized keytype(%s).\n"),
  397. keytype);
  398. return (PK_ERR_USAGE);
  399. }
  400. /*
  401. * Check and set the key length.
  402. * - For DES and 3DES, the key size are fixed. Ingore the keylen
  403. * option, even if it is specified.
  404. * - For AES and ARCFOUR, if keylen is not specified, default to
  405. * 128 bits.
  406. */
  407. if (keyAlg == KMF_DES)
  408. keylen = 64; /* fixed size; ignore input */
  409. else if (keyAlg == KMF_DES3)
  410. keylen = 192; /* fixed size; ignore input */
  411. else /* AES, ARCFOUR, or GENERIC SECRET */ {
  412. if (keylenstr == NULL) {
  413. cryptoerror(LOG_STDERR,
  414. gettext("Key length must be specified for "
  415. "AES, ARCFOUR or GENERIC symmetric keys.\n"));
  416. return (PK_ERR_USAGE);
  417. }
  418. if (sscanf(keylenstr, "%d", &keylen) != 1) {
  419. cryptoerror(LOG_STDERR,
  420. gettext("Unrecognized key length (%s).\n"),
  421. keytype);
  422. return (PK_ERR_USAGE);
  423. }
  424. if (keylen == 0 || (keylen % 8) != 0) {
  425. cryptoerror(LOG_STDERR,
  426. gettext("Key length bitlength must be a "
  427. "multiple of 8.\n"));
  428. return (PK_ERR_USAGE);
  429. }
  430. }
  431. /* check the print option */
  432. if (printstr != NULL) {
  433. if (kstype == KMF_KEYSTORE_NSS) {
  434. cryptoerror(LOG_STDERR,
  435. gettext("The print option does not apply "
  436. "to the NSS keystore.\n"));
  437. return (PK_ERR_USAGE);
  438. }
  439. if (tolower(printstr[0]) == 'y')
  440. print_hex = B_TRUE;
  441. else if (tolower(printstr[0]) == 'n')
  442. print_hex = B_FALSE;
  443. else {
  444. cryptoerror(LOG_STDERR,
  445. gettext("Incorrect print option value.\n"));
  446. return (PK_ERR_USAGE);
  447. }
  448. }
  449. /* check the sensitive and extractable options */
  450. if ((senstr != NULL || extstr != NULL) &&
  451. (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_OPENSSL)) {
  452. cryptoerror(LOG_STDERR,
  453. gettext("The sensitive or extractable option applies "
  454. "to the PKCS11 keystore only.\n"));
  455. return (PK_ERR_USAGE);
  456. }
  457. if (kstype == KMF_KEYSTORE_PK11TOKEN && tokenname == NULL) {
  458. tokenname = PK_DEFAULT_PK11TOKEN;
  459. } else if (kstype == KMF_KEYSTORE_NSS && tokenname == NULL) {
  460. tokenname = DEFAULT_NSS_TOKEN;
  461. }
  462. DIR_OPTION_CHECK(kstype, dir);
  463. if (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)
  464. (void) get_token_password(kstype, tokenname, &tokencred);
  465. if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
  466. cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n"));
  467. goto end;
  468. }
  469. if (kstype == KMF_KEYSTORE_NSS) {
  470. rv = genkey_nss(kmfhandle, tokenname, dir, prefix,
  471. keylabel, keyAlg, keylen, &tokencred);
  472. } else if (kstype == KMF_KEYSTORE_OPENSSL) {
  473. rv = genkey_file(kmfhandle, keyAlg, keylen, dir, outkey,
  474. print_hex);
  475. } else {
  476. rv = genkey_pkcs11(kmfhandle, tokenname, keylabel, keyAlg,
  477. keylen, senstr, extstr, print_hex, &tokencred);
  478. }
  479. end:
  480. if (rv != KMF_OK)
  481. display_error(kmfhandle, rv,
  482. gettext("Error generating key"));
  483. if (tokencred.cred != NULL)
  484. free(tokencred.cred);
  485. (void) kmf_finalize(kmfhandle);
  486. if (rv != KMF_OK)
  487. return (PK_ERR_USAGE);
  488. return (0);
  489. }