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

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

https://bitbucket.org/a3217055/illumos-joyent
C | 1174 lines | 948 code | 142 blank | 84 comment | 298 complexity | a31102d7ffa7dfeaad030161484e1792 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, GPL-2.0, GPL-3.0, 0BSD, BSD-2-Clause, BSD-3-Clause-No-Nuclear-License-2014, MPL-2.0-no-copyleft-exception, AGPL-1.0, LGPL-2.1, LGPL-2.0
  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 2009 Sun Microsystems, Inc. All rights reserved.
  23. * Use is subject to license terms.
  24. */
  25. /*
  26. * This file implements the import operation for this tool.
  27. * The basic flow of the process is to decrypt the PKCS#12
  28. * input file if it has a password, parse the elements in
  29. * the file, find the soft token, log into it, import the
  30. * PKCS#11 objects into the soft token, and log out.
  31. */
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include <ctype.h>
  36. #include <errno.h>
  37. #include <fcntl.h>
  38. #include <sys/types.h>
  39. #include <sys/stat.h>
  40. #include "common.h"
  41. #include <kmfapi.h>
  42. #define NEW_ATTRLIST(a, n) \
  43. { \
  44. a = (KMF_ATTRIBUTE *)malloc(n * sizeof (KMF_ATTRIBUTE)); \
  45. if (a == NULL) { \
  46. rv = KMF_ERR_MEMORY; \
  47. goto end; \
  48. } \
  49. (void) memset(a, 0, n * sizeof (KMF_ATTRIBUTE)); \
  50. }
  51. static KMF_RETURN
  52. pk_import_pk12_files(KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *cred,
  53. char *outfile, char *certfile, char *keyfile,
  54. KMF_ENCODE_FORMAT outformat)
  55. {
  56. KMF_RETURN rv = KMF_OK;
  57. KMF_X509_DER_CERT *certs = NULL;
  58. KMF_RAW_KEY_DATA *keys = NULL;
  59. int ncerts = 0;
  60. int nkeys = 0;
  61. int i;
  62. KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
  63. KMF_ATTRIBUTE *attrlist = NULL;
  64. int numattr = 0;
  65. rv = kmf_import_objects(kmfhandle, outfile, cred,
  66. &certs, &ncerts, &keys, &nkeys);
  67. if (rv == KMF_OK) {
  68. (void) printf(gettext("Found %d certificate(s) and %d "
  69. "key(s) in %s\n"), ncerts, nkeys, outfile);
  70. }
  71. if (rv == KMF_OK && ncerts > 0) {
  72. char newcertfile[MAXPATHLEN];
  73. NEW_ATTRLIST(attrlist, (3 + (3 * ncerts)));
  74. kmf_set_attr_at_index(attrlist, numattr,
  75. KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
  76. numattr++;
  77. kmf_set_attr_at_index(attrlist, numattr,
  78. KMF_ENCODE_FORMAT_ATTR, &outformat, sizeof (outformat));
  79. numattr++;
  80. for (i = 0; rv == KMF_OK && i < ncerts; i++) {
  81. int num = numattr;
  82. /*
  83. * If storing more than 1 cert, gotta change
  84. * the name so we don't overwrite the previous one.
  85. * Just append a _# to the name.
  86. */
  87. if (i > 0) {
  88. (void) snprintf(newcertfile,
  89. sizeof (newcertfile), "%s_%d", certfile, i);
  90. kmf_set_attr_at_index(attrlist, num,
  91. KMF_CERT_FILENAME_ATTR, newcertfile,
  92. strlen(newcertfile));
  93. num++;
  94. } else {
  95. kmf_set_attr_at_index(attrlist, num,
  96. KMF_CERT_FILENAME_ATTR, certfile,
  97. strlen(certfile));
  98. num++;
  99. }
  100. if (certs[i].kmf_private.label != NULL) {
  101. kmf_set_attr_at_index(attrlist, num,
  102. KMF_CERT_LABEL_ATTR,
  103. certs[i].kmf_private.label,
  104. strlen(certs[i].kmf_private.label));
  105. num++;
  106. }
  107. kmf_set_attr_at_index(attrlist, num,
  108. KMF_CERT_DATA_ATTR, &certs[i].certificate,
  109. sizeof (KMF_DATA));
  110. num++;
  111. rv = kmf_store_cert(kmfhandle, num, attrlist);
  112. }
  113. free(attrlist);
  114. }
  115. if (rv == KMF_OK && nkeys > 0) {
  116. char newkeyfile[MAXPATHLEN];
  117. numattr = 0;
  118. NEW_ATTRLIST(attrlist, (4 + (4 * nkeys)));
  119. kmf_set_attr_at_index(attrlist, numattr,
  120. KMF_KEYSTORE_TYPE_ATTR, &kstype,
  121. sizeof (kstype));
  122. numattr++;
  123. kmf_set_attr_at_index(attrlist, numattr,
  124. KMF_ENCODE_FORMAT_ATTR, &outformat,
  125. sizeof (outformat));
  126. numattr++;
  127. if (cred != NULL && cred->credlen > 0) {
  128. kmf_set_attr_at_index(attrlist, numattr,
  129. KMF_CREDENTIAL_ATTR, cred,
  130. sizeof (KMF_CREDENTIAL));
  131. numattr++;
  132. }
  133. /* The order of certificates and keys should match */
  134. for (i = 0; rv == KMF_OK && i < nkeys; i++) {
  135. int num = numattr;
  136. if (i > 0) {
  137. (void) snprintf(newkeyfile,
  138. sizeof (newkeyfile), "%s_%d", keyfile, i);
  139. kmf_set_attr_at_index(attrlist, num,
  140. KMF_KEY_FILENAME_ATTR, newkeyfile,
  141. strlen(newkeyfile));
  142. num++;
  143. } else {
  144. kmf_set_attr_at_index(attrlist, num,
  145. KMF_KEY_FILENAME_ATTR, keyfile,
  146. strlen(keyfile));
  147. num++;
  148. }
  149. if (i < ncerts) {
  150. kmf_set_attr_at_index(attrlist, num,
  151. KMF_CERT_DATA_ATTR, &certs[i],
  152. sizeof (KMF_CERT_DATA_ATTR));
  153. num++;
  154. }
  155. kmf_set_attr_at_index(attrlist, num,
  156. KMF_RAW_KEY_ATTR, &keys[i],
  157. sizeof (KMF_RAW_KEY_DATA));
  158. num++;
  159. rv = kmf_store_key(kmfhandle, num, attrlist);
  160. }
  161. free(attrlist);
  162. }
  163. end:
  164. /*
  165. * Cleanup memory.
  166. */
  167. if (certs) {
  168. for (i = 0; i < ncerts; i++)
  169. kmf_free_kmf_cert(kmfhandle, &certs[i]);
  170. free(certs);
  171. }
  172. if (keys) {
  173. for (i = 0; i < nkeys; i++)
  174. kmf_free_raw_key(&keys[i]);
  175. free(keys);
  176. }
  177. return (rv);
  178. }
  179. static KMF_RETURN
  180. pk_import_pk12_nss(
  181. KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *kmfcred,
  182. KMF_CREDENTIAL *tokencred,
  183. char *token_spec, char *dir, char *prefix,
  184. char *nickname, char *trustflags, char *filename)
  185. {
  186. KMF_RETURN rv = KMF_OK;
  187. KMF_X509_DER_CERT *certs = NULL;
  188. KMF_RAW_KEY_DATA *keys = NULL;
  189. int ncerts = 0;
  190. int nkeys = 0;
  191. int i;
  192. KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
  193. KMF_ATTRIBUTE *attrlist = NULL;
  194. int numattr = 0;
  195. rv = configure_nss(kmfhandle, dir, prefix);
  196. if (rv != KMF_OK)
  197. return (rv);
  198. rv = kmf_import_objects(kmfhandle, filename, kmfcred,
  199. &certs, &ncerts, &keys, &nkeys);
  200. if (rv == KMF_OK)
  201. (void) printf(gettext("Found %d certificate(s) and %d "
  202. "key(s) in %s\n"), ncerts, nkeys, filename);
  203. if (rv == KMF_OK) {
  204. numattr = 0;
  205. NEW_ATTRLIST(attrlist, (4 + (2 * nkeys)));
  206. kmf_set_attr_at_index(attrlist, numattr,
  207. KMF_KEYSTORE_TYPE_ATTR, &kstype,
  208. sizeof (kstype));
  209. numattr++;
  210. if (token_spec != NULL) {
  211. kmf_set_attr_at_index(attrlist, numattr,
  212. KMF_TOKEN_LABEL_ATTR, token_spec,
  213. strlen(token_spec));
  214. numattr++;
  215. }
  216. if (nickname != NULL) {
  217. kmf_set_attr_at_index(attrlist, numattr,
  218. KMF_KEYLABEL_ATTR, nickname,
  219. strlen(nickname));
  220. numattr++;
  221. }
  222. if (tokencred->credlen > 0) {
  223. kmf_set_attr_at_index(attrlist, numattr,
  224. KMF_CREDENTIAL_ATTR, tokencred,
  225. sizeof (KMF_CREDENTIAL));
  226. numattr++;
  227. }
  228. /* The order of certificates and keys should match */
  229. for (i = 0; i < nkeys; i++) {
  230. int num = numattr;
  231. if (i < ncerts) {
  232. kmf_set_attr_at_index(attrlist, num,
  233. KMF_CERT_DATA_ATTR, &certs[i],
  234. sizeof (KMF_DATA));
  235. num++;
  236. }
  237. kmf_set_attr_at_index(attrlist, num,
  238. KMF_RAW_KEY_ATTR, &keys[i],
  239. sizeof (KMF_RAW_KEY_DATA));
  240. num++;
  241. rv = kmf_store_key(kmfhandle, num, attrlist);
  242. }
  243. free(attrlist);
  244. attrlist = NULL;
  245. }
  246. if (rv == KMF_OK) {
  247. numattr = 0;
  248. NEW_ATTRLIST(attrlist, (3 + (2 * ncerts)));
  249. kmf_set_attr_at_index(attrlist, numattr,
  250. KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
  251. numattr++;
  252. if (token_spec != NULL) {
  253. kmf_set_attr_at_index(attrlist, numattr,
  254. KMF_TOKEN_LABEL_ATTR, token_spec,
  255. strlen(token_spec));
  256. numattr++;
  257. }
  258. if (trustflags != NULL) {
  259. kmf_set_attr_at_index(attrlist, numattr,
  260. KMF_TRUSTFLAG_ATTR, trustflags,
  261. strlen(trustflags));
  262. numattr++;
  263. }
  264. for (i = 0; rv == KMF_OK && i < ncerts; i++) {
  265. int num = numattr;
  266. if (certs[i].kmf_private.label != NULL) {
  267. kmf_set_attr_at_index(attrlist, num,
  268. KMF_CERT_LABEL_ATTR,
  269. certs[i].kmf_private.label,
  270. strlen(certs[i].kmf_private.label));
  271. num++;
  272. } else if (i == 0 && nickname != NULL) {
  273. kmf_set_attr_at_index(attrlist, num,
  274. KMF_CERT_LABEL_ATTR, nickname,
  275. strlen(nickname));
  276. num++;
  277. }
  278. kmf_set_attr_at_index(attrlist, num,
  279. KMF_CERT_DATA_ATTR,
  280. &certs[i].certificate, sizeof (KMF_DATA));
  281. num++;
  282. rv = kmf_store_cert(kmfhandle, num, attrlist);
  283. }
  284. free(attrlist);
  285. attrlist = NULL;
  286. if (rv != KMF_OK) {
  287. display_error(kmfhandle, rv,
  288. gettext("Error storing certificate in NSS token"));
  289. }
  290. }
  291. end:
  292. /*
  293. * Cleanup memory.
  294. */
  295. if (certs) {
  296. for (i = 0; i < ncerts; i++)
  297. kmf_free_kmf_cert(kmfhandle, &certs[i]);
  298. free(certs);
  299. }
  300. if (keys) {
  301. for (i = 0; i < nkeys; i++)
  302. kmf_free_raw_key(&keys[i]);
  303. free(keys);
  304. }
  305. return (rv);
  306. }
  307. static KMF_RETURN
  308. pk_import_cert(
  309. KMF_HANDLE_T kmfhandle,
  310. KMF_KEYSTORE_TYPE kstype,
  311. char *label, char *token_spec, char *filename,
  312. char *dir, char *prefix, char *trustflags)
  313. {
  314. KMF_RETURN rv = KMF_OK;
  315. KMF_ATTRIBUTE attrlist[32];
  316. KMF_CREDENTIAL tokencred;
  317. int i = 0;
  318. if (kstype == KMF_KEYSTORE_PK11TOKEN) {
  319. rv = select_token(kmfhandle, token_spec, FALSE);
  320. } else if (kstype == KMF_KEYSTORE_NSS) {
  321. rv = configure_nss(kmfhandle, dir, prefix);
  322. }
  323. if (rv != KMF_OK)
  324. return (rv);
  325. kmf_set_attr_at_index(attrlist, i,
  326. KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (KMF_KEYSTORE_TYPE));
  327. i++;
  328. kmf_set_attr_at_index(attrlist, i, KMF_CERT_FILENAME_ATTR,
  329. filename, strlen(filename));
  330. i++;
  331. if (label != NULL) {
  332. kmf_set_attr_at_index(attrlist, i, KMF_CERT_LABEL_ATTR,
  333. label, strlen(label));
  334. i++;
  335. }
  336. if (kstype == KMF_KEYSTORE_NSS) {
  337. if (trustflags != NULL) {
  338. kmf_set_attr_at_index(attrlist, i, KMF_TRUSTFLAG_ATTR,
  339. trustflags, strlen(trustflags));
  340. i++;
  341. }
  342. if (token_spec != NULL) {
  343. kmf_set_attr_at_index(attrlist, i,
  344. KMF_TOKEN_LABEL_ATTR,
  345. token_spec, strlen(token_spec));
  346. i++;
  347. }
  348. }
  349. rv = kmf_import_cert(kmfhandle, i, attrlist);
  350. if (rv == KMF_ERR_AUTH_FAILED) {
  351. /*
  352. * The token requires a credential, prompt and try again.
  353. */
  354. (void) get_token_password(kstype, token_spec, &tokencred);
  355. kmf_set_attr_at_index(attrlist, i, KMF_CREDENTIAL_ATTR,
  356. &tokencred, sizeof (KMF_CREDENTIAL));
  357. i++;
  358. rv = kmf_import_cert(kmfhandle, i, attrlist);
  359. }
  360. return (rv);
  361. }
  362. static KMF_RETURN
  363. pk_import_file_crl(void *kmfhandle,
  364. char *infile,
  365. char *outfile,
  366. KMF_ENCODE_FORMAT outfmt)
  367. {
  368. int numattr = 0;
  369. KMF_ATTRIBUTE attrlist[8];
  370. KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
  371. kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
  372. &kstype, sizeof (kstype));
  373. numattr++;
  374. if (infile) {
  375. kmf_set_attr_at_index(attrlist, numattr,
  376. KMF_CRL_FILENAME_ATTR, infile, strlen(infile));
  377. numattr++;
  378. }
  379. if (outfile) {
  380. kmf_set_attr_at_index(attrlist, numattr,
  381. KMF_CRL_OUTFILE_ATTR, outfile, strlen(outfile));
  382. numattr++;
  383. }
  384. kmf_set_attr_at_index(attrlist, numattr,
  385. KMF_ENCODE_FORMAT_ATTR, &outfmt, sizeof (outfmt));
  386. numattr++;
  387. return (kmf_import_crl(kmfhandle, numattr, attrlist));
  388. }
  389. static KMF_RETURN
  390. pk_import_nss_crl(void *kmfhandle,
  391. boolean_t verify_crl_flag,
  392. char *infile,
  393. char *outdir,
  394. char *prefix)
  395. {
  396. KMF_RETURN rv;
  397. int numattr = 0;
  398. KMF_ATTRIBUTE attrlist[4];
  399. KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
  400. rv = configure_nss(kmfhandle, outdir, prefix);
  401. if (rv != KMF_OK)
  402. return (rv);
  403. kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
  404. &kstype, sizeof (kstype));
  405. numattr++;
  406. if (infile) {
  407. kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR,
  408. infile, strlen(infile));
  409. numattr++;
  410. }
  411. kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_CHECK_ATTR,
  412. &verify_crl_flag, sizeof (verify_crl_flag));
  413. numattr++;
  414. return (kmf_import_crl(kmfhandle, numattr, attrlist));
  415. }
  416. static KMF_RETURN
  417. pk_import_pk12_pk11(
  418. KMF_HANDLE_T kmfhandle,
  419. KMF_CREDENTIAL *p12cred,
  420. KMF_CREDENTIAL *tokencred,
  421. char *label, char *token_spec,
  422. char *filename)
  423. {
  424. KMF_RETURN rv = KMF_OK;
  425. KMF_X509_DER_CERT *certs = NULL;
  426. KMF_RAW_KEY_DATA *keys = NULL;
  427. int ncerts = 0;
  428. int nkeys = 0;
  429. int i;
  430. KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
  431. KMF_ATTRIBUTE *attrlist = NULL;
  432. int numattr = 0;
  433. rv = select_token(kmfhandle, token_spec, FALSE);
  434. if (rv != KMF_OK) {
  435. return (rv);
  436. }
  437. rv = kmf_import_objects(kmfhandle, filename, p12cred,
  438. &certs, &ncerts, &keys, &nkeys);
  439. if (rv == KMF_OK) {
  440. NEW_ATTRLIST(attrlist, (3 + (2 * nkeys)));
  441. kmf_set_attr_at_index(attrlist, numattr,
  442. KMF_KEYSTORE_TYPE_ATTR, &kstype,
  443. sizeof (kstype));
  444. numattr++;
  445. if (label != NULL) {
  446. kmf_set_attr_at_index(attrlist, numattr,
  447. KMF_KEYLABEL_ATTR, label,
  448. strlen(label));
  449. numattr++;
  450. }
  451. if (tokencred != NULL && tokencred->credlen > 0) {
  452. kmf_set_attr_at_index(attrlist, numattr,
  453. KMF_CREDENTIAL_ATTR, tokencred,
  454. sizeof (KMF_CREDENTIAL));
  455. numattr++;
  456. }
  457. /* The order of certificates and keys should match */
  458. for (i = 0; i < nkeys; i++) {
  459. int num = numattr;
  460. if (i < ncerts) {
  461. kmf_set_attr_at_index(attrlist, num,
  462. KMF_CERT_DATA_ATTR, &certs[i].certificate,
  463. sizeof (KMF_DATA));
  464. num++;
  465. }
  466. kmf_set_attr_at_index(attrlist, num,
  467. KMF_RAW_KEY_ATTR, &keys[i],
  468. sizeof (KMF_RAW_KEY_DATA));
  469. num++;
  470. rv = kmf_store_key(kmfhandle, num, attrlist);
  471. }
  472. free(attrlist);
  473. }
  474. if (rv == KMF_OK) {
  475. numattr = 0;
  476. NEW_ATTRLIST(attrlist, (1 + (2 * ncerts)));
  477. (void) printf(gettext("Found %d certificate(s) and %d "
  478. "key(s) in %s\n"), ncerts, nkeys, filename);
  479. kmf_set_attr_at_index(attrlist, numattr,
  480. KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
  481. numattr++;
  482. for (i = 0; rv == KMF_OK && i < ncerts; i++) {
  483. int num = numattr;
  484. if (certs[i].kmf_private.label != NULL) {
  485. kmf_set_attr_at_index(attrlist, num,
  486. KMF_CERT_LABEL_ATTR,
  487. certs[i].kmf_private.label,
  488. strlen(certs[i].kmf_private.label));
  489. num++;
  490. } else if (i == 0 && label != NULL) {
  491. kmf_set_attr_at_index(attrlist, num,
  492. KMF_CERT_LABEL_ATTR, label, strlen(label));
  493. num++;
  494. }
  495. kmf_set_attr_at_index(attrlist, num,
  496. KMF_CERT_DATA_ATTR, &certs[i].certificate,
  497. sizeof (KMF_DATA));
  498. num++;
  499. rv = kmf_store_cert(kmfhandle, num, attrlist);
  500. }
  501. free(attrlist);
  502. }
  503. end:
  504. /*
  505. * Cleanup memory.
  506. */
  507. if (certs) {
  508. for (i = 0; i < ncerts; i++)
  509. kmf_free_kmf_cert(kmfhandle, &certs[i]);
  510. free(certs);
  511. }
  512. if (keys) {
  513. for (i = 0; i < nkeys; i++)
  514. kmf_free_raw_key(&keys[i]);
  515. free(keys);
  516. }
  517. return (rv);
  518. }
  519. /*ARGSUSED*/
  520. static KMF_RETURN
  521. pk_import_keys(KMF_HANDLE_T kmfhandle,
  522. KMF_KEYSTORE_TYPE kstype, char *token_spec,
  523. KMF_CREDENTIAL *cred, char *filename,
  524. char *label, char *senstr, char *extstr)
  525. {
  526. KMF_RETURN rv = KMF_OK;
  527. KMF_ATTRIBUTE attrlist[16];
  528. KMF_KEYSTORE_TYPE fileks = KMF_KEYSTORE_OPENSSL;
  529. int numattr = 0;
  530. KMF_KEY_HANDLE key;
  531. KMF_RAW_KEY_DATA rawkey;
  532. KMF_KEY_CLASS class = KMF_ASYM_PRI;
  533. int numkeys = 1;
  534. if (kstype == KMF_KEYSTORE_PK11TOKEN) {
  535. rv = select_token(kmfhandle, token_spec, FALSE);
  536. }
  537. if (rv != KMF_OK)
  538. return (rv);
  539. /*
  540. * First, set up to read the keyfile using the FILE plugin
  541. * mechanisms.
  542. */
  543. kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
  544. &fileks, sizeof (fileks));
  545. numattr++;
  546. kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
  547. &numkeys, sizeof (numkeys));
  548. numattr++;
  549. kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
  550. &key, sizeof (key));
  551. numattr++;
  552. kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR,
  553. &rawkey, sizeof (rawkey));
  554. numattr++;
  555. kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
  556. &class, sizeof (class));
  557. numattr++;
  558. kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
  559. filename, strlen(filename));
  560. numattr++;
  561. rv = kmf_find_key(kmfhandle, numattr, attrlist);
  562. if (rv == KMF_OK) {
  563. numattr = 0;
  564. kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
  565. &kstype, sizeof (kstype));
  566. numattr++;
  567. if (cred != NULL && cred->credlen > 0) {
  568. kmf_set_attr_at_index(attrlist, numattr,
  569. KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
  570. numattr++;
  571. }
  572. if (label != NULL) {
  573. kmf_set_attr_at_index(attrlist, numattr,
  574. KMF_KEYLABEL_ATTR, label, strlen(label));
  575. numattr++;
  576. }
  577. kmf_set_attr_at_index(attrlist, numattr,
  578. KMF_RAW_KEY_ATTR, &rawkey, sizeof (rawkey));
  579. numattr++;
  580. rv = kmf_store_key(kmfhandle, numattr, attrlist);
  581. if (rv == KMF_OK) {
  582. (void) printf(gettext("Importing %d keys\n"), numkeys);
  583. }
  584. kmf_free_kmf_key(kmfhandle, &key);
  585. kmf_free_raw_key(&rawkey);
  586. } else {
  587. cryptoerror(LOG_STDERR,
  588. gettext("Failed to load key from file (%s)\n"),
  589. filename);
  590. }
  591. return (rv);
  592. }
  593. static KMF_RETURN
  594. pk_import_rawkey(KMF_HANDLE_T kmfhandle,
  595. KMF_KEYSTORE_TYPE kstype, char *token,
  596. KMF_CREDENTIAL *cred,
  597. char *filename, char *label, KMF_KEY_ALG keyAlg,
  598. char *senstr, char *extstr)
  599. {
  600. KMF_RETURN rv = KMF_OK;
  601. KMF_ATTRIBUTE attrlist[16];
  602. int numattr = 0;
  603. uint32_t keylen;
  604. boolean_t sensitive = B_FALSE;
  605. boolean_t not_extractable = B_FALSE;
  606. KMF_DATA keydata = {NULL, 0};
  607. KMF_KEY_HANDLE rawkey;
  608. rv = kmf_read_input_file(kmfhandle, filename, &keydata);
  609. if (rv != KMF_OK)
  610. return (rv);
  611. rv = select_token(kmfhandle, token, FALSE);
  612. if (rv != KMF_OK) {
  613. return (rv);
  614. }
  615. if (senstr != NULL) {
  616. if (tolower(senstr[0]) == 'y')
  617. sensitive = B_TRUE;
  618. else if (tolower(senstr[0]) == 'n')
  619. sensitive = B_FALSE;
  620. else {
  621. cryptoerror(LOG_STDERR,
  622. gettext("Incorrect sensitive option value.\n"));
  623. return (KMF_ERR_BAD_PARAMETER);
  624. }
  625. }
  626. if (extstr != NULL) {
  627. if (tolower(extstr[0]) == 'y')
  628. not_extractable = B_FALSE;
  629. else if (tolower(extstr[0]) == 'n')
  630. not_extractable = B_TRUE;
  631. else {
  632. cryptoerror(LOG_STDERR,
  633. gettext("Incorrect extractable option value.\n"));
  634. return (KMF_ERR_BAD_PARAMETER);
  635. }
  636. }
  637. kmf_set_attr_at_index(attrlist, numattr,
  638. KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
  639. numattr++;
  640. kmf_set_attr_at_index(attrlist, numattr,
  641. KMF_KEY_HANDLE_ATTR, &rawkey, sizeof (rawkey));
  642. numattr++;
  643. kmf_set_attr_at_index(attrlist, numattr,
  644. KMF_KEYALG_ATTR, &keyAlg, sizeof (KMF_KEY_ALG));
  645. numattr++;
  646. kmf_set_attr_at_index(attrlist, numattr,
  647. KMF_KEY_DATA_ATTR, keydata.Data, keydata.Length);
  648. numattr++;
  649. /* Key length is given in bits not bytes */
  650. keylen = keydata.Length * 8;
  651. kmf_set_attr_at_index(attrlist, numattr,
  652. KMF_KEYLENGTH_ATTR, &keylen, sizeof (keydata.Length));
  653. numattr++;
  654. kmf_set_attr_at_index(attrlist, numattr,
  655. KMF_SENSITIVE_BOOL_ATTR, &sensitive, sizeof (sensitive));
  656. numattr++;
  657. kmf_set_attr_at_index(attrlist, numattr,
  658. KMF_NON_EXTRACTABLE_BOOL_ATTR, &not_extractable,
  659. sizeof (not_extractable));
  660. numattr++;
  661. if (label != NULL) {
  662. kmf_set_attr_at_index(attrlist, numattr,
  663. KMF_KEYLABEL_ATTR, label, strlen(label));
  664. numattr++;
  665. }
  666. if (cred != NULL && cred->credlen > 0) {
  667. kmf_set_attr_at_index(attrlist, numattr,
  668. KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
  669. numattr++;
  670. }
  671. rv = kmf_create_sym_key(kmfhandle, numattr, attrlist);
  672. return (rv);
  673. }
  674. /*
  675. * Import objects from into KMF repositories.
  676. */
  677. int
  678. pk_import(int argc, char *argv[])
  679. {
  680. int opt;
  681. extern int optind_av;
  682. extern char *optarg_av;
  683. char *token_spec = NULL;
  684. char *filename = NULL;
  685. char *keyfile = NULL;
  686. char *certfile = NULL;
  687. char *crlfile = NULL;
  688. char *label = NULL;
  689. char *dir = NULL;
  690. char *prefix = NULL;
  691. char *trustflags = NULL;
  692. char *verify_crl = NULL;
  693. char *keytype = "generic";
  694. char *senstr = NULL;
  695. char *extstr = NULL;
  696. boolean_t verify_crl_flag = B_FALSE;
  697. int oclass = 0;
  698. KMF_KEYSTORE_TYPE kstype = 0;
  699. KMF_ENCODE_FORMAT kfmt = 0;
  700. KMF_ENCODE_FORMAT okfmt = KMF_FORMAT_ASN1;
  701. KMF_RETURN rv = KMF_OK;
  702. KMF_CREDENTIAL pk12cred = { NULL, 0 };
  703. KMF_CREDENTIAL tokencred = { NULL, 0 };
  704. KMF_HANDLE_T kmfhandle = NULL;
  705. KMF_KEY_ALG keyAlg = KMF_GENERIC_SECRET;
  706. /* Parse command line options. Do NOT i18n/l10n. */
  707. while ((opt = getopt_av(argc, argv,
  708. "T:(token)i:(infile)"
  709. "k:(keystore)y:(objtype)"
  710. "d:(dir)p:(prefix)"
  711. "n:(certlabel)N:(label)"
  712. "K:(outkey)c:(outcert)"
  713. "v:(verifycrl)l:(outcrl)"
  714. "E:(keytype)s:(sensitive)x:(extractable)"
  715. "t:(trust)F:(outformat)")) != EOF) {
  716. if (EMPTYSTRING(optarg_av))
  717. return (PK_ERR_USAGE);
  718. switch (opt) {
  719. case 'T': /* token specifier */
  720. if (token_spec)
  721. return (PK_ERR_USAGE);
  722. token_spec = optarg_av;
  723. break;
  724. case 'c': /* output cert file name */
  725. if (certfile)
  726. return (PK_ERR_USAGE);
  727. certfile = optarg_av;
  728. break;
  729. case 'l': /* output CRL file name */
  730. if (crlfile)
  731. return (PK_ERR_USAGE);
  732. crlfile = optarg_av;
  733. break;
  734. case 'K': /* output key file name */
  735. if (keyfile)
  736. return (PK_ERR_USAGE);
  737. keyfile = optarg_av;
  738. break;
  739. case 'i': /* input file name */
  740. if (filename)
  741. return (PK_ERR_USAGE);
  742. filename = optarg_av;
  743. break;
  744. case 'k':
  745. kstype = KS2Int(optarg_av);
  746. if (kstype == 0)
  747. return (PK_ERR_USAGE);
  748. break;
  749. case 'y':
  750. oclass = OT2Int(optarg_av);
  751. if (oclass == -1)
  752. return (PK_ERR_USAGE);
  753. break;
  754. case 'd':
  755. dir = optarg_av;
  756. break;
  757. case 'p':
  758. if (prefix)
  759. return (PK_ERR_USAGE);
  760. prefix = optarg_av;
  761. break;
  762. case 'n':
  763. case 'N':
  764. if (label)
  765. return (PK_ERR_USAGE);
  766. label = optarg_av;
  767. break;
  768. case 'F':
  769. okfmt = Str2Format(optarg_av);
  770. if (okfmt == KMF_FORMAT_UNDEF)
  771. return (PK_ERR_USAGE);
  772. break;
  773. case 't':
  774. if (trustflags)
  775. return (PK_ERR_USAGE);
  776. trustflags = optarg_av;
  777. break;
  778. case 'v':
  779. verify_crl = optarg_av;
  780. if (tolower(verify_crl[0]) == 'y')
  781. verify_crl_flag = B_TRUE;
  782. else if (tolower(verify_crl[0]) == 'n')
  783. verify_crl_flag = B_FALSE;
  784. else
  785. return (PK_ERR_USAGE);
  786. break;
  787. case 'E':
  788. keytype = optarg_av;
  789. break;
  790. case 's':
  791. if (senstr)
  792. return (PK_ERR_USAGE);
  793. senstr = optarg_av;
  794. break;
  795. case 'x':
  796. if (extstr)
  797. return (PK_ERR_USAGE);
  798. extstr = optarg_av;
  799. break;
  800. default:
  801. return (PK_ERR_USAGE);
  802. break;
  803. }
  804. }
  805. /* Assume keystore = PKCS#11 if not specified */
  806. if (kstype == 0)
  807. kstype = KMF_KEYSTORE_PK11TOKEN;
  808. /* Filename arg is required. */
  809. if (EMPTYSTRING(filename)) {
  810. cryptoerror(LOG_STDERR, gettext("The 'infile' parameter"
  811. "is required for the import operation.\n"));
  812. return (PK_ERR_USAGE);
  813. }
  814. /* No additional args allowed. */
  815. argc -= optind_av;
  816. argv += optind_av;
  817. if (argc)
  818. return (PK_ERR_USAGE);
  819. DIR_OPTION_CHECK(kstype, dir);
  820. /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
  821. if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
  822. kstype != KMF_KEYSTORE_PK11TOKEN) {
  823. (void) fprintf(stderr, gettext("The objtype parameter "
  824. "is only relevant if keystore=pkcs11\n"));
  825. return (PK_ERR_USAGE);
  826. }
  827. /*
  828. * You must specify a certlabel (cert label) when importing
  829. * into NSS or PKCS#11.
  830. */
  831. if (kstype == KMF_KEYSTORE_NSS &&
  832. (oclass != PK_CRL_OBJ) && EMPTYSTRING(label)) {
  833. cryptoerror(LOG_STDERR, gettext("The 'label' argument "
  834. "is required for this operation\n"));
  835. return (PK_ERR_USAGE);
  836. }
  837. if ((rv = kmf_get_file_format(filename, &kfmt)) != KMF_OK) {
  838. char *kmferrstr = NULL;
  839. KMF_RETURN rv2;
  840. /*
  841. * Allow for raw key data to be imported.
  842. */
  843. if (rv == KMF_ERR_ENCODING) {
  844. rv = KMF_OK;
  845. kfmt = KMF_FORMAT_RAWKEY;
  846. /*
  847. * Set the object class only if it was not
  848. * given on the command line or if it was
  849. * specified as a symmetric key object.
  850. */
  851. if (oclass == 0 || (oclass & PK_SYMKEY_OBJ)) {
  852. oclass = PK_SYMKEY_OBJ;
  853. } else {
  854. cryptoerror(LOG_STDERR, gettext(
  855. "The input file does not contain the "
  856. "object type indicated on command "
  857. "line."));
  858. return (KMF_ERR_BAD_PARAMETER);
  859. }
  860. } else {
  861. if (rv == KMF_ERR_OPEN_FILE) {
  862. cryptoerror(LOG_STDERR,
  863. gettext("Cannot open file (%s)\n."),
  864. filename);
  865. } else {
  866. rv2 = kmf_get_kmf_error_str(rv, &kmferrstr);
  867. if (rv2 == KMF_OK && kmferrstr) {
  868. cryptoerror(LOG_STDERR,
  869. gettext("libkmf error: %s"),
  870. kmferrstr);
  871. kmf_free_str(kmferrstr);
  872. }
  873. }
  874. return (rv);
  875. }
  876. }
  877. /* Check parameters for raw key import operation */
  878. if (kfmt == KMF_FORMAT_RAWKEY) {
  879. if (keytype != NULL &&
  880. Str2SymKeyType(keytype, &keyAlg) != 0) {
  881. cryptoerror(LOG_STDERR,
  882. gettext("Unrecognized keytype(%s).\n"), keytype);
  883. return (PK_ERR_USAGE);
  884. }
  885. if (senstr != NULL && extstr != NULL &&
  886. kstype != KMF_KEYSTORE_PK11TOKEN) {
  887. cryptoerror(LOG_STDERR,
  888. gettext("The sensitive or extractable option "
  889. "applies only when importing a key from a file "
  890. "into a PKCS#11 keystore.\n"));
  891. return (PK_ERR_USAGE);
  892. }
  893. }
  894. /* If no objtype was given, treat it as a certificate */
  895. if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 ||
  896. kfmt == KMF_FORMAT_PEM))
  897. oclass = PK_CERT_OBJ;
  898. if (kstype == KMF_KEYSTORE_NSS) {
  899. if (oclass == PK_CRL_OBJ &&
  900. (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
  901. cryptoerror(LOG_STDERR, gettext(
  902. "CRL data can only be imported as DER or "
  903. "PEM format"));
  904. return (PK_ERR_USAGE);
  905. }
  906. if (oclass == PK_CERT_OBJ &&
  907. (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
  908. cryptoerror(LOG_STDERR, gettext(
  909. "Certificates can only be imported as DER or "
  910. "PEM format"));
  911. return (PK_ERR_USAGE);
  912. }
  913. /* we do not import private keys except in PKCS12 bundles */
  914. if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) {
  915. cryptoerror(LOG_STDERR, gettext(
  916. "Private key data can only be imported as part "
  917. "of a PKCS12 file.\n"));
  918. return (PK_ERR_USAGE);
  919. }
  920. }
  921. if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) {
  922. if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) {
  923. cryptoerror(LOG_STDERR, gettext(
  924. "The 'outkey' and 'outcert' parameters "
  925. "are required for the import operation "
  926. "when the 'file' keystore is used.\n"));
  927. return (PK_ERR_USAGE);
  928. }
  929. }
  930. if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec))
  931. token_spec = PK_DEFAULT_PK11TOKEN;
  932. else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec))
  933. token_spec = DEFAULT_NSS_TOKEN;
  934. if (kfmt == KMF_FORMAT_PKCS12) {
  935. (void) get_pk12_password(&pk12cred);
  936. }
  937. if ((kfmt == KMF_FORMAT_PKCS12 || kfmt == KMF_FORMAT_RAWKEY ||
  938. (kfmt == KMF_FORMAT_PEM && (oclass & PK_KEY_OBJ))) &&
  939. (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)) {
  940. (void) get_token_password(kstype, token_spec, &tokencred);
  941. }
  942. if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
  943. cryptoerror(LOG_STDERR, gettext("Error initializing "
  944. "KMF: 0x%02x\n"), rv);
  945. goto end;
  946. }
  947. switch (kstype) {
  948. case KMF_KEYSTORE_PK11TOKEN:
  949. if (kfmt == KMF_FORMAT_PKCS12)
  950. rv = pk_import_pk12_pk11(
  951. kmfhandle, &pk12cred,
  952. &tokencred, label,
  953. token_spec, filename);
  954. else if (oclass == PK_CERT_OBJ)
  955. rv = pk_import_cert(
  956. kmfhandle, kstype,
  957. label, token_spec,
  958. filename,
  959. NULL, NULL, NULL);
  960. else if (oclass == PK_CRL_OBJ)
  961. rv = pk_import_file_crl(
  962. kmfhandle, filename,
  963. crlfile, okfmt);
  964. else if (kfmt == KMF_FORMAT_RAWKEY &&
  965. oclass == PK_SYMKEY_OBJ) {
  966. rv = pk_import_rawkey(kmfhandle,
  967. kstype, token_spec, &tokencred,
  968. filename, label,
  969. keyAlg, senstr, extstr);
  970. } else if (kfmt == KMF_FORMAT_PEM ||
  971. kfmt == KMF_FORMAT_PEM_KEYPAIR) {
  972. rv = pk_import_keys(kmfhandle,
  973. kstype, token_spec, &tokencred,
  974. filename, label, senstr, extstr);
  975. } else {
  976. rv = PK_ERR_USAGE;
  977. }
  978. break;
  979. case KMF_KEYSTORE_NSS:
  980. if (dir == NULL)
  981. dir = PK_DEFAULT_DIRECTORY;
  982. if (kfmt == KMF_FORMAT_PKCS12)
  983. rv = pk_import_pk12_nss(
  984. kmfhandle, &pk12cred,
  985. &tokencred,
  986. token_spec, dir, prefix,
  987. label, trustflags, filename);
  988. else if (oclass == PK_CERT_OBJ) {
  989. rv = pk_import_cert(
  990. kmfhandle, kstype,
  991. label, token_spec,
  992. filename, dir, prefix, trustflags);
  993. } else if (oclass == PK_CRL_OBJ) {
  994. rv = pk_import_nss_crl(
  995. kmfhandle, verify_crl_flag,
  996. filename, dir, prefix);
  997. }
  998. break;
  999. case KMF_KEYSTORE_OPENSSL:
  1000. if (kfmt == KMF_FORMAT_PKCS12)
  1001. rv = pk_import_pk12_files(
  1002. kmfhandle, &pk12cred,
  1003. filename, certfile, keyfile,
  1004. okfmt);
  1005. else if (oclass == PK_CRL_OBJ) {
  1006. rv = pk_import_file_crl(
  1007. kmfhandle, filename,
  1008. crlfile, okfmt);
  1009. } else
  1010. /*
  1011. * It doesn't make sense to import anything
  1012. * else for the files plugin.
  1013. */
  1014. return (PK_ERR_USAGE);
  1015. break;
  1016. default:
  1017. rv = PK_ERR_USAGE;
  1018. break;
  1019. }
  1020. end:
  1021. if (rv != KMF_OK)
  1022. display_error(kmfhandle, rv,
  1023. gettext("Error importing objects"));
  1024. if (tokencred.cred != NULL)
  1025. free(tokencred.cred);
  1026. if (pk12cred.cred != NULL)
  1027. free(pk12cred.cred);
  1028. (void) kmf_finalize(kmfhandle);
  1029. if (rv != KMF_OK)
  1030. return (PK_ERR_USAGE);
  1031. return (0);
  1032. }