dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / cmd-crypto / pktool / export.c
blob6ff21d6fc4579355f88fdc3247066aa9ccd1a7b4
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
21 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
22 * Copyright 2012 Milan Jurik. All rights reserved.
26 * This file implements the export operation for this tool.
27 * The basic flow of the process is to find the soft token,
28 * log into it, find the PKCS#11 objects in the soft token
29 * to be exported matching keys with their certificates, export
30 * them to the PKCS#12 file encrypting them with a file password
31 * if desired, and log out.
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <errno.h>
38 #include <fcntl.h>
39 #include "common.h"
41 #include <kmfapi.h>
43 static KMF_RETURN
44 pk_find_export_cert(KMF_HANDLE_T kmfhandle, KMF_ATTRIBUTE *attrlist,
45 int numattr, KMF_X509_DER_CERT *cert)
47 KMF_RETURN rv = KMF_OK;
48 uint32_t numcerts = 0;
50 numcerts = 0;
51 (void) memset(cert, 0, sizeof (KMF_X509_DER_CERT));
53 kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
54 &numcerts, sizeof (uint32_t));
55 numattr++;
57 rv = kmf_find_cert(kmfhandle, numattr, attrlist);
58 if (rv != KMF_OK) {
59 return (rv);
61 if (numcerts == 0) {
62 cryptoerror(LOG_STDERR,
63 gettext("No matching certificates found."));
64 return (KMF_ERR_CERT_NOT_FOUND);
66 } else if (numcerts == 1) {
67 kmf_set_attr_at_index(attrlist, numattr,
68 KMF_X509_DER_CERT_ATTR, cert,
69 sizeof (KMF_X509_DER_CERT));
70 numattr++;
71 rv = kmf_find_cert(kmfhandle, numattr, attrlist);
73 } else if (numcerts > 1) {
74 cryptoerror(LOG_STDERR,
75 gettext("%d certificates found, refine the "
76 "search parameters to eliminate ambiguity\n"),
77 numcerts);
78 return (KMF_ERR_BAD_PARAMETER);
80 return (rv);
83 static KMF_RETURN
84 pk_export_file_objects(KMF_HANDLE_T kmfhandle, int oclass,
85 char *issuer, char *subject, KMF_BIGINT *serial,
86 char *infile, char *filename)
88 KMF_RETURN rv = KMF_OK;
89 KMF_X509_DER_CERT kmfcert;
90 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
91 int numattr = 0;
92 KMF_ATTRIBUTE attrlist[16];
94 /* If searching for public objects or certificates, find certs now */
95 if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
96 kmf_set_attr_at_index(attrlist, numattr,
97 KMF_KEYSTORE_TYPE_ATTR, &kstype,
98 sizeof (kstype));
99 numattr++;
101 if (issuer != NULL) {
102 kmf_set_attr_at_index(attrlist, numattr,
103 KMF_ISSUER_NAME_ATTR, issuer,
104 strlen(issuer));
105 numattr++;
108 if (subject != NULL) {
109 kmf_set_attr_at_index(attrlist, numattr,
110 KMF_SUBJECT_NAME_ATTR, subject,
111 strlen(subject));
112 numattr++;
115 if (serial != NULL) {
116 kmf_set_attr_at_index(attrlist, numattr,
117 KMF_BIGINT_ATTR, serial,
118 sizeof (KMF_BIGINT));
119 numattr++;
122 if (infile != NULL) {
123 kmf_set_attr_at_index(attrlist, numattr,
124 KMF_CERT_FILENAME_ATTR, infile,
125 strlen(infile));
126 numattr++;
129 rv = pk_find_export_cert(kmfhandle, attrlist, numattr,
130 &kmfcert);
131 if (rv == KMF_OK) {
132 kstype = KMF_KEYSTORE_OPENSSL;
133 numattr = 0;
135 kmf_set_attr_at_index(attrlist, numattr,
136 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
137 numattr++;
139 kmf_set_attr_at_index(attrlist, numattr,
140 KMF_CERT_DATA_ATTR, &kmfcert.certificate,
141 sizeof (KMF_DATA));
142 numattr++;
144 kmf_set_attr_at_index(attrlist, numattr,
145 KMF_CERT_FILENAME_ATTR, filename,
146 strlen(filename));
147 numattr++;
149 rv = kmf_store_cert(kmfhandle, numattr,
150 attrlist);
152 kmf_free_kmf_cert(kmfhandle, &kmfcert);
155 return (rv);
158 static KMF_RETURN
159 pk_export_pk12_nss(KMF_HANDLE_T kmfhandle,
160 char *token_spec, char *dir, char *prefix,
161 char *certlabel, char *issuer, char *subject,
162 KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred,
163 char *filename)
165 KMF_RETURN rv = KMF_OK;
166 KMF_KEYSTORE_TYPE kstype;
167 KMF_CREDENTIAL p12cred = { NULL, 0 };
168 KMF_ATTRIBUTE attrlist[16];
169 int numattr = 0;
171 rv = configure_nss(kmfhandle, dir, prefix);
172 if (rv != KMF_OK)
173 return (rv);
175 if (token_spec == NULL)
176 token_spec = DEFAULT_NSS_TOKEN;
178 kstype = KMF_KEYSTORE_NSS;
179 kmf_set_attr_at_index(attrlist, numattr,
180 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
181 numattr++;
183 if (certlabel != NULL) {
184 kmf_set_attr_at_index(attrlist, numattr,
185 KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel));
186 numattr++;
189 if (issuer != NULL) {
190 kmf_set_attr_at_index(attrlist, numattr,
191 KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer));
192 numattr++;
195 if (subject != NULL) {
196 kmf_set_attr_at_index(attrlist, numattr,
197 KMF_SUBJECT_NAME_ATTR, subject, strlen(subject));
198 numattr++;
201 if (serial != NULL) {
202 kmf_set_attr_at_index(attrlist, numattr,
203 KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT));
204 numattr++;
207 if (tokencred != NULL) {
208 kmf_set_attr_at_index(attrlist, numattr,
209 KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL));
210 numattr++;
213 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
214 token_spec, strlen(token_spec));
215 numattr++;
217 (void) get_pk12_password(&p12cred);
218 kmf_set_attr_at_index(attrlist, numattr,
219 KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL));
220 numattr++;
222 kmf_set_attr_at_index(attrlist, numattr,
223 KMF_OUTPUT_FILENAME_ATTR, filename, strlen(filename));
224 numattr++;
226 rv = kmf_export_pk12(kmfhandle, numattr, attrlist);
228 free(p12cred.cred);
230 return (rv);
233 static KMF_RETURN
234 pk_export_pk12_files(KMF_HANDLE_T kmfhandle,
235 char *certfile, char *keyfile,
236 char *outfile)
238 KMF_RETURN rv;
239 KMF_KEYSTORE_TYPE kstype;
240 KMF_CREDENTIAL p12cred = { NULL, 0 };
241 KMF_ATTRIBUTE attrlist[16];
242 int numattr = 0;
244 kstype = KMF_KEYSTORE_OPENSSL;
245 kmf_set_attr_at_index(attrlist, numattr,
246 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
247 numattr++;
249 if (certfile != NULL) {
250 kmf_set_attr_at_index(attrlist, numattr,
251 KMF_CERT_FILENAME_ATTR, certfile, strlen(certfile));
252 numattr++;
255 if (keyfile != NULL) {
256 kmf_set_attr_at_index(attrlist, numattr,
257 KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile));
258 numattr++;
261 (void) get_pk12_password(&p12cred);
262 kmf_set_attr_at_index(attrlist, numattr,
263 KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL));
264 numattr++;
266 kmf_set_attr_at_index(attrlist, numattr,
267 KMF_OUTPUT_FILENAME_ATTR, outfile, strlen(outfile));
268 numattr++;
270 rv = kmf_export_pk12(kmfhandle, numattr, attrlist);
272 free(p12cred.cred);
274 return (rv);
277 static KMF_RETURN
278 pk_export_nss_objects(KMF_HANDLE_T kmfhandle, char *token_spec,
279 int oclass, char *certlabel, char *issuer, char *subject,
280 KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt, char *dir,
281 char *prefix, char *filename)
283 KMF_RETURN rv = KMF_OK;
284 KMF_X509_DER_CERT kmfcert;
285 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
286 KMF_ATTRIBUTE attrlist[16];
287 int numattr = 0;
289 rv = configure_nss(kmfhandle, dir, prefix);
290 if (rv != KMF_OK)
291 return (rv);
293 /* If searching for public objects or certificates, find certs now */
294 if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
295 kmf_set_attr_at_index(attrlist, numattr,
296 KMF_KEYSTORE_TYPE_ATTR, &kstype,
297 sizeof (kstype));
298 numattr++;
300 if (certlabel != NULL) {
301 kmf_set_attr_at_index(attrlist, numattr,
302 KMF_CERT_LABEL_ATTR, certlabel,
303 strlen(certlabel));
304 numattr++;
307 if (issuer != NULL) {
308 kmf_set_attr_at_index(attrlist, numattr,
309 KMF_ISSUER_NAME_ATTR, issuer,
310 strlen(issuer));
311 numattr++;
314 if (subject != NULL) {
315 kmf_set_attr_at_index(attrlist, numattr,
316 KMF_SUBJECT_NAME_ATTR, subject,
317 strlen(subject));
318 numattr++;
321 if (serial != NULL) {
322 kmf_set_attr_at_index(attrlist, numattr,
323 KMF_BIGINT_ATTR, serial,
324 sizeof (KMF_BIGINT));
325 numattr++;
328 if (token_spec != NULL) {
329 kmf_set_attr_at_index(attrlist, numattr,
330 KMF_TOKEN_LABEL_ATTR, token_spec,
331 strlen(token_spec));
332 numattr++;
335 rv = pk_find_export_cert(kmfhandle, attrlist, numattr,
336 &kmfcert);
337 if (rv == KMF_OK) {
338 kstype = KMF_KEYSTORE_OPENSSL;
339 numattr = 0;
341 kmf_set_attr_at_index(attrlist, numattr,
342 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
343 numattr++;
345 kmf_set_attr_at_index(attrlist, numattr,
346 KMF_CERT_DATA_ATTR, &kmfcert.certificate,
347 sizeof (KMF_DATA));
348 numattr++;
350 kmf_set_attr_at_index(attrlist, numattr,
351 KMF_CERT_FILENAME_ATTR, filename,
352 strlen(filename));
353 numattr++;
355 kmf_set_attr_at_index(attrlist, numattr,
356 KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt));
357 numattr++;
359 rv = kmf_store_cert(kmfhandle, numattr, attrlist);
361 kmf_free_kmf_cert(kmfhandle, &kmfcert);
364 return (rv);
367 static KMF_RETURN
368 pk_export_pk12_pk11(KMF_HANDLE_T kmfhandle, char *token_spec,
369 char *certlabel, char *issuer, char *subject,
370 KMF_BIGINT *serial, KMF_CREDENTIAL *tokencred, char *filename)
372 KMF_RETURN rv = KMF_OK;
373 KMF_KEYSTORE_TYPE kstype;
374 KMF_CREDENTIAL p12cred = { NULL, 0 };
375 KMF_ATTRIBUTE attrlist[16];
376 int numattr = 0;
378 rv = select_token(kmfhandle, token_spec, TRUE);
379 if (rv != KMF_OK) {
380 return (rv);
383 kstype = KMF_KEYSTORE_PK11TOKEN;
384 kmf_set_attr_at_index(attrlist, numattr,
385 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
386 numattr++;
388 if (certlabel != NULL) {
389 kmf_set_attr_at_index(attrlist, numattr,
390 KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel));
391 numattr++;
394 if (issuer != NULL) {
395 kmf_set_attr_at_index(attrlist, numattr,
396 KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer));
397 numattr++;
400 if (subject != NULL) {
401 kmf_set_attr_at_index(attrlist, numattr,
402 KMF_SUBJECT_NAME_ATTR, subject, strlen(subject));
403 numattr++;
406 if (serial != NULL) {
407 kmf_set_attr_at_index(attrlist, numattr,
408 KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT));
409 numattr++;
412 if (tokencred != NULL) {
413 kmf_set_attr_at_index(attrlist, numattr,
414 KMF_CREDENTIAL_ATTR, tokencred, sizeof (KMF_CREDENTIAL));
415 numattr++;
418 (void) get_pk12_password(&p12cred);
419 kmf_set_attr_at_index(attrlist, numattr,
420 KMF_PK12CRED_ATTR, &p12cred, sizeof (KMF_CREDENTIAL));
421 numattr++;
423 kmf_set_attr_at_index(attrlist, numattr,
424 KMF_OUTPUT_FILENAME_ATTR, filename, strlen(filename));
425 numattr++;
427 rv = kmf_export_pk12(kmfhandle, numattr, attrlist);
429 free(p12cred.cred);
431 return (rv);
434 static KMF_RETURN
435 pk_export_pk11_keys(KMF_HANDLE_T kmfhandle, char *token,
436 KMF_CREDENTIAL *cred, KMF_ENCODE_FORMAT format,
437 char *label, char *filename, int oclass)
439 KMF_RETURN rv = KMF_OK;
440 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
441 KMF_KEY_CLASS kclass = KMF_KEYCLASS_NONE;
442 int numattr = 0;
443 uint32_t numkeys = 1;
444 KMF_ATTRIBUTE attrlist[16];
445 KMF_KEY_HANDLE key;
446 boolean_t is_token = B_TRUE;
448 if (EMPTYSTRING(label)) {
449 cryptoerror(LOG_STDERR, gettext("A label "
450 "must be specified to export a key."));
451 return (KMF_ERR_BAD_PARAMETER);
454 rv = select_token(kmfhandle, token, TRUE);
455 if (rv != KMF_OK) {
456 return (rv);
459 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
460 &kstype, sizeof (kstype));
461 numattr++;
463 if (cred != NULL) {
464 kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
465 cred, sizeof (KMF_CREDENTIAL));
466 numattr++;
469 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR,
470 label, strlen(label));
471 numattr++;
473 kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
474 &numkeys, sizeof (numkeys));
475 numattr++;
477 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
478 &key, sizeof (key));
479 numattr++;
481 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR,
482 &is_token, sizeof (is_token));
483 numattr++;
485 kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR,
486 &format, sizeof (format));
487 numattr++;
489 /* Check to see if we are exporting private or public only */
490 if ((oclass & PK_KEY_OBJ) == PK_PRIKEY_OBJ)
491 kclass = KMF_ASYM_PRI;
492 else if ((oclass & PK_KEY_OBJ) == PK_PUBKEY_OBJ)
493 kclass = KMF_ASYM_PUB;
494 else if ((oclass & PK_KEY_OBJ) == PK_SYMKEY_OBJ)
495 kclass = KMF_SYMMETRIC;
496 else /* only 1 key at a time can be exported here, so default to pri */
497 kclass = KMF_ASYM_PRI;
499 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
500 &kclass, sizeof (kclass));
501 numattr++;
503 rv = kmf_find_key(kmfhandle, numattr, attrlist);
505 * If nothing found but caller wanted ALL keys, try symmetric
506 * this time.
508 if (rv == KMF_ERR_KEY_NOT_FOUND && (oclass == PK_KEY_OBJ)) {
509 kclass = KMF_SYMMETRIC;
510 rv = kmf_find_key(kmfhandle, numattr, attrlist);
513 * If nothing found but caller wanted ALL keys, try asymmetric
514 * public this time.
516 if (rv == KMF_ERR_KEY_NOT_FOUND && (oclass == PK_KEY_OBJ)) {
517 kclass = KMF_ASYM_PUB;
518 rv = kmf_find_key(kmfhandle, numattr, attrlist);
520 if (rv == KMF_OK && key.keyclass == KMF_SYMMETRIC) {
521 KMF_RAW_SYM_KEY rkey;
523 (void) memset(&rkey, 0, sizeof (KMF_RAW_SYM_KEY));
524 rv = kmf_get_sym_key_value(kmfhandle, &key, &rkey);
525 if (rv == KMF_OK) {
526 int fd, n, total = 0;
528 fd = open(filename, O_CREAT | O_RDWR |O_TRUNC, 0600);
529 if (fd == -1) {
530 rv = KMF_ERR_OPEN_FILE;
531 goto done;
533 do {
534 n = write(fd, rkey.keydata.val + total,
535 rkey.keydata.len - total);
536 if (n < 0) {
537 if (errno == EINTR)
538 continue;
539 (void) close(fd);
540 rv = KMF_ERR_WRITE_FILE;
541 goto done;
543 total += n;
545 } while (total < rkey.keydata.len);
546 (void) close(fd);
548 done:
549 kmf_free_bigint(&rkey.keydata);
550 kmf_free_kmf_key(kmfhandle, &key);
551 } else if (rv == KMF_OK) {
552 KMF_KEYSTORE_TYPE sslks = KMF_KEYSTORE_OPENSSL;
553 (void) printf(gettext("Found %d asymmetric keys\n"), numkeys);
555 numattr = 0;
556 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
557 &sslks, sizeof (sslks));
558 numattr++;
560 kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR,
561 key.keyp, sizeof (KMF_RAW_KEY_DATA));
562 numattr++;
564 kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR,
565 &format, sizeof (format));
566 numattr++;
568 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
569 filename, strlen(filename));
570 numattr++;
572 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
573 &key.keyclass, sizeof (KMF_KEY_CLASS));
574 numattr++;
576 rv = kmf_store_key(kmfhandle, numattr, attrlist);
577 kmf_free_kmf_key(kmfhandle, &key);
580 return (rv);
583 static KMF_RETURN
584 pk_export_pk11_objects(KMF_HANDLE_T kmfhandle, char *token_spec,
585 KMF_CREDENTIAL *cred, char *certlabel, char *issuer, char *subject,
586 KMF_BIGINT *serial, KMF_ENCODE_FORMAT kfmt,
587 char *filename)
589 KMF_RETURN rv = KMF_OK;
590 KMF_X509_DER_CERT kmfcert;
591 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
592 int numattr = 0;
593 KMF_ATTRIBUTE attrlist[16];
595 rv = select_token(kmfhandle, token_spec, TRUE);
597 if (rv != KMF_OK)
598 return (rv);
600 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
601 &kstype, sizeof (kstype));
602 numattr++;
604 if (cred != NULL) {
605 kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
606 cred, sizeof (KMF_CREDENTIAL));
607 numattr++;
609 if (certlabel != NULL) {
610 kmf_set_attr_at_index(attrlist, numattr,
611 KMF_CERT_LABEL_ATTR, certlabel,
612 strlen(certlabel));
613 numattr++;
616 if (issuer != NULL) {
617 kmf_set_attr_at_index(attrlist, numattr,
618 KMF_ISSUER_NAME_ATTR, issuer,
619 strlen(issuer));
620 numattr++;
623 if (subject != NULL) {
624 kmf_set_attr_at_index(attrlist, numattr,
625 KMF_SUBJECT_NAME_ATTR, subject,
626 strlen(subject));
627 numattr++;
630 if (serial != NULL) {
631 kmf_set_attr_at_index(attrlist, numattr,
632 KMF_BIGINT_ATTR, serial,
633 sizeof (KMF_BIGINT));
634 numattr++;
637 rv = pk_find_export_cert(kmfhandle, attrlist, numattr, &kmfcert);
639 if (rv == KMF_OK) {
640 kstype = KMF_KEYSTORE_OPENSSL;
641 numattr = 0;
643 kmf_set_attr_at_index(attrlist, numattr,
644 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
645 numattr++;
647 kmf_set_attr_at_index(attrlist, numattr,
648 KMF_CERT_DATA_ATTR, &kmfcert.certificate,
649 sizeof (KMF_DATA));
650 numattr++;
652 kmf_set_attr_at_index(attrlist, numattr,
653 KMF_CERT_FILENAME_ATTR, filename, strlen(filename));
654 numattr++;
656 kmf_set_attr_at_index(attrlist, numattr,
657 KMF_ENCODE_FORMAT_ATTR, &kfmt, sizeof (kfmt));
658 numattr++;
660 rv = kmf_store_cert(kmfhandle, numattr, attrlist);
662 kmf_free_kmf_cert(kmfhandle, &kmfcert);
664 return (rv);
668 * Export objects from one keystore to a file.
671 pk_export(int argc, char *argv[])
673 int opt;
674 extern int optind_av;
675 extern char *optarg_av;
676 char *token_spec = NULL;
677 char *filename = NULL;
678 char *dir = NULL;
679 char *prefix = NULL;
680 char *certlabel = NULL;
681 char *subject = NULL;
682 char *issuer = NULL;
683 char *infile = NULL;
684 char *keyfile = NULL;
685 char *certfile = NULL;
686 char *serstr = NULL;
687 KMF_KEYSTORE_TYPE kstype = 0;
688 KMF_ENCODE_FORMAT kfmt = KMF_FORMAT_PKCS12;
689 KMF_RETURN rv = KMF_OK;
690 int oclass = PK_CERT_OBJ;
691 KMF_BIGINT serial = { NULL, 0 };
692 KMF_HANDLE_T kmfhandle = NULL;
693 KMF_CREDENTIAL tokencred = { NULL, 0 };
695 /* Parse command line options. Do NOT i18n/l10n. */
696 while ((opt = getopt_av(argc, argv,
697 "k:(keystore)y:(objtype)T:(token)"
698 "d:(dir)p:(prefix)"
699 "l:(label)n:(nickname)s:(subject)"
700 "i:(issuer)S:(serial)"
701 "K:(keyfile)c:(certfile)"
702 "F:(outformat)"
703 "I:(infile)o:(outfile)")) != EOF) {
704 if (EMPTYSTRING(optarg_av))
705 return (PK_ERR_USAGE);
706 switch (opt) {
707 case 'k':
708 kstype = KS2Int(optarg_av);
709 if (kstype == 0)
710 return (PK_ERR_USAGE);
711 break;
712 case 'y':
713 oclass = OT2Int(optarg_av);
714 if (oclass == -1)
715 return (PK_ERR_USAGE);
716 break;
717 case 'T': /* token specifier */
718 if (token_spec)
719 return (PK_ERR_USAGE);
720 token_spec = optarg_av;
721 break;
722 case 'd':
723 if (dir)
724 return (PK_ERR_USAGE);
725 dir = optarg_av;
726 break;
727 case 'p':
728 if (prefix)
729 return (PK_ERR_USAGE);
730 prefix = optarg_av;
731 break;
732 case 'n':
733 case 'l':
734 if (certlabel)
735 return (PK_ERR_USAGE);
736 certlabel = optarg_av;
737 break;
738 case 's':
739 if (subject)
740 return (PK_ERR_USAGE);
741 subject = optarg_av;
742 break;
743 case 'i':
744 if (issuer)
745 return (PK_ERR_USAGE);
746 issuer = optarg_av;
747 break;
748 case 'S':
749 serstr = optarg_av;
750 break;
751 case 'F':
752 kfmt = Str2Format(optarg_av);
753 if (kfmt == KMF_FORMAT_UNDEF)
754 return (PK_ERR_USAGE);
755 break;
756 case 'I': /* output file name */
757 if (infile)
758 return (PK_ERR_USAGE);
759 infile = optarg_av;
760 break;
761 case 'o': /* output file name */
762 if (filename)
763 return (PK_ERR_USAGE);
764 filename = optarg_av;
765 break;
766 case 'c': /* input cert file name */
767 if (certfile)
768 return (PK_ERR_USAGE);
769 certfile = optarg_av;
770 break;
771 case 'K': /* input key file name */
772 if (keyfile)
773 return (PK_ERR_USAGE);
774 keyfile = optarg_av;
775 break;
776 default:
777 return (PK_ERR_USAGE);
781 /* Assume keystore = PKCS#11 if not specified */
782 if (kstype == 0)
783 kstype = KMF_KEYSTORE_PK11TOKEN;
785 /* Filename arg is required. */
786 if (EMPTYSTRING(filename)) {
787 cryptoerror(LOG_STDERR, gettext("You must specify "
788 "an 'outfile' parameter when exporting.\n"));
789 return (PK_ERR_USAGE);
792 /* No additional args allowed. */
793 argc -= optind_av;
794 argv += optind_av;
795 if (argc)
796 return (PK_ERR_USAGE);
798 DIR_OPTION_CHECK(kstype, dir);
800 /* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
801 if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
802 kstype != KMF_KEYSTORE_PK11TOKEN) {
804 (void) fprintf(stderr, gettext("The objtype parameter "
805 "is only relevant if keystore=pkcs11\n"));
806 return (PK_ERR_USAGE);
809 if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec))
810 token_spec = PK_DEFAULT_PK11TOKEN;
811 else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec))
812 token_spec = DEFAULT_NSS_TOKEN;
814 if (kstype == KMF_KEYSTORE_OPENSSL) {
815 if (kfmt != KMF_FORMAT_PKCS12) {
816 cryptoerror(LOG_STDERR, gettext("PKCS12 "
817 "is the only export format "
818 "supported for the 'file' "
819 "keystore.\n"));
820 return (PK_ERR_USAGE);
822 if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) {
823 cryptoerror(LOG_STDERR, gettext("A cert file"
824 "and a key file must be specified "
825 "when exporting to PKCS12 from the "
826 "'file' keystore.\n"));
827 return (PK_ERR_USAGE);
831 /* Check if the file exists */
832 if (verify_file(filename) != KMF_OK) {
833 cryptoerror(LOG_STDERR,
834 gettext("Warning: file \"%s\" exists, "
835 "will be overwritten."), filename);
836 if (yesno(gettext("Continue with export? "),
837 gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) {
838 return (0);
839 } else {
840 /* remove the file */
841 (void) unlink(filename);
845 if (serstr != NULL) {
846 uchar_t *bytes = NULL;
847 size_t bytelen;
849 rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen);
850 if (rv != KMF_OK || bytes == NULL) {
851 (void) fprintf(stderr, gettext("serial number "
852 "must be specified as a hex number "
853 "(ex: 0x0102030405ffeeddee)\n"));
854 return (PK_ERR_USAGE);
856 serial.val = bytes;
857 serial.len = bytelen;
861 * We need a password in the following situations:
862 * 1. When accessing PKCS11 token
863 * 2. If NSS keystore, when making a PKCS12 file or when
864 * accessing any private object or key.
866 if (kstype == KMF_KEYSTORE_PK11TOKEN ||
867 ((kstype == KMF_KEYSTORE_NSS) &&
868 ((oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ)) ||
869 (kfmt == KMF_FORMAT_PKCS12)))) {
870 (void) get_token_password(kstype, token_spec,
871 &tokencred);
874 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
875 cryptoerror(LOG_STDERR, gettext("Error initializing "
876 "KMF: 0x%02x\n"), rv);
877 return (rv);
880 switch (kstype) {
881 case KMF_KEYSTORE_PK11TOKEN:
882 if (kfmt == KMF_FORMAT_PKCS12)
883 rv = pk_export_pk12_pk11(kmfhandle,
884 token_spec, certlabel,
885 issuer, subject,
886 &serial, &tokencred,
887 filename);
888 else if ((oclass & PK_KEY_OBJ) ||
889 kfmt == KMF_FORMAT_RAWKEY)
890 rv = pk_export_pk11_keys(kmfhandle,
891 token_spec, &tokencred, kfmt,
892 certlabel, filename, oclass);
893 else
894 rv = pk_export_pk11_objects(kmfhandle,
895 token_spec, &tokencred, certlabel,
896 issuer, subject, &serial, kfmt,
897 filename);
898 break;
899 case KMF_KEYSTORE_NSS:
900 if (dir == NULL)
901 dir = PK_DEFAULT_DIRECTORY;
902 if (kfmt == KMF_FORMAT_PKCS12)
903 rv = pk_export_pk12_nss(kmfhandle,
904 token_spec, dir, prefix,
905 certlabel, issuer,
906 subject, &serial,
907 &tokencred, filename);
908 else
909 rv = pk_export_nss_objects(kmfhandle,
910 token_spec,
911 oclass, certlabel, issuer, subject,
912 &serial, kfmt, dir, prefix, filename);
913 break;
914 case KMF_KEYSTORE_OPENSSL:
915 if (kfmt == KMF_FORMAT_PKCS12)
916 rv = pk_export_pk12_files(kmfhandle,
917 certfile, keyfile, filename);
918 else
919 rv = pk_export_file_objects(kmfhandle, oclass,
920 issuer, subject, &serial,
921 infile, filename);
922 break;
923 default:
924 rv = PK_ERR_USAGE;
925 break;
928 if (rv != KMF_OK) {
929 display_error(kmfhandle, rv,
930 gettext("Error exporting objects"));
933 free(serial.val);
935 (void) kmf_finalize(kmfhandle);
937 return (rv);