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