xref: /onnv-gate/usr/src/cmd/cmd-crypto/pktool/import.c (revision 5051:cbbb7c8b40a9)
117Sdinak /*
217Sdinak  * CDDL HEADER START
317Sdinak  *
417Sdinak  * The contents of this file are subject to the terms of the
53089Swyllys  * Common Development and Distribution License (the "License").
63089Swyllys  * You may not use this file except in compliance with the License.
717Sdinak  *
817Sdinak  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
917Sdinak  * or http://www.opensolaris.org/os/licensing.
1017Sdinak  * See the License for the specific language governing permissions
1117Sdinak  * and limitations under the License.
1217Sdinak  *
1317Sdinak  * When distributing Covered Code, include this CDDL HEADER in each
1417Sdinak  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1517Sdinak  * If applicable, add the following below this CDDL HEADER, with the
1617Sdinak  * fields enclosed by brackets "[]" replaced with your own identifying
1717Sdinak  * information: Portions Copyright [yyyy] [name of copyright owner]
1817Sdinak  *
1917Sdinak  * CDDL HEADER END
2017Sdinak  */
2117Sdinak /*
22*5051Swyllys  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
2317Sdinak  * Use is subject to license terms.
2417Sdinak  */
2517Sdinak 
2617Sdinak #pragma ident	"%Z%%M%	%I%	%E% SMI"
2717Sdinak 
2817Sdinak /*
2917Sdinak  * This file implements the import operation for this tool.
3017Sdinak  * The basic flow of the process is to decrypt the PKCS#12
3117Sdinak  * input file if it has a password, parse the elements in
3217Sdinak  * the file, find the soft token, log into it, import the
3317Sdinak  * PKCS#11 objects into the soft token, and log out.
3417Sdinak  */
3517Sdinak 
3617Sdinak #include <stdio.h>
3717Sdinak #include <stdlib.h>
3817Sdinak #include <string.h>
393089Swyllys #include <ctype.h>
4017Sdinak #include <errno.h>
4117Sdinak #include <fcntl.h>
4217Sdinak #include <sys/types.h>
4317Sdinak #include <sys/stat.h>
4417Sdinak #include "common.h"
453089Swyllys 
463089Swyllys #include <kmfapi.h>
4717Sdinak 
483089Swyllys static KMF_RETURN
493089Swyllys pk_import_pk12_files(KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *cred,
503089Swyllys 	char *outfile, char *certfile, char *keyfile,
513089Swyllys 	char *dir, char *keydir, KMF_ENCODE_FORMAT outformat)
5217Sdinak {
533089Swyllys 	KMF_RETURN rv = KMF_OK;
543089Swyllys 	KMF_DATA *certs = NULL;
553089Swyllys 	KMF_RAW_KEY_DATA *keys = NULL;
563089Swyllys 	int ncerts = 0;
573089Swyllys 	int nkeys = 0;
583089Swyllys 	int i;
59*5051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
60*5051Swyllys 	KMF_ATTRIBUTE attrlist[16];
61*5051Swyllys 	int numattr = 0;
6217Sdinak 
63*5051Swyllys 	rv = kmf_import_objects(kmfhandle, outfile, cred,
64*5051Swyllys 	    &certs, &ncerts, &keys, &nkeys);
6517Sdinak 
663089Swyllys 	if (rv == KMF_OK) {
673089Swyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
68*5051Swyllys 		    "key(s) in %s\n"), ncerts, nkeys, outfile);
6917Sdinak 	}
7017Sdinak 
713089Swyllys 	if (rv == KMF_OK && ncerts > 0) {
723089Swyllys 		char newcertfile[MAXPATHLEN];
733089Swyllys 
74*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
75*5051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
76*5051Swyllys 		numattr++;
77*5051Swyllys 
78*5051Swyllys 		if (dir != NULL) {
79*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
80*5051Swyllys 			    KMF_DIRPATH_ATTR, dir, strlen(dir));
81*5051Swyllys 			numattr++;
82*5051Swyllys 		}
83*5051Swyllys 
84*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
85*5051Swyllys 		    KMF_ENCODE_FORMAT_ATTR, &outformat, sizeof (outformat));
86*5051Swyllys 		numattr++;
873089Swyllys 
883089Swyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
89*5051Swyllys 			int num = numattr;
90*5051Swyllys 
913089Swyllys 			/*
923089Swyllys 			 * If storing more than 1 cert, gotta change
933089Swyllys 			 * the name so we don't overwrite the previous one.
943089Swyllys 			 * Just append a _# to the name.
953089Swyllys 			 */
963089Swyllys 			if (i > 0) {
973089Swyllys 				(void) snprintf(newcertfile,
98*5051Swyllys 				    sizeof (newcertfile), "%s_%d", certfile, i);
99*5051Swyllys 
100*5051Swyllys 				kmf_set_attr_at_index(attrlist, num,
101*5051Swyllys 				    KMF_CERT_FILENAME_ATTR, newcertfile,
102*5051Swyllys 				    strlen(newcertfile));
103*5051Swyllys 				num++;
1043089Swyllys 			} else {
105*5051Swyllys 				kmf_set_attr_at_index(attrlist, num,
106*5051Swyllys 				    KMF_CERT_FILENAME_ATTR, certfile,
107*5051Swyllys 				    strlen(certfile));
108*5051Swyllys 				num++;
1093089Swyllys 			}
110*5051Swyllys 
111*5051Swyllys 			kmf_set_attr_at_index(attrlist, num,
112*5051Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i], sizeof (KMF_DATA));
113*5051Swyllys 			num++;
114*5051Swyllys 			rv = kmf_store_cert(kmfhandle, num, attrlist);
1153089Swyllys 		}
1163089Swyllys 	}
1173089Swyllys 	if (rv == KMF_OK && nkeys > 0) {
1183089Swyllys 		char newkeyfile[MAXPATHLEN];
1193089Swyllys 
120*5051Swyllys 		numattr = 0;
121*5051Swyllys 
122*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
123*5051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
124*5051Swyllys 		    sizeof (kstype));
125*5051Swyllys 		numattr++;
126*5051Swyllys 
127*5051Swyllys 		if (keydir != NULL) {
128*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
129*5051Swyllys 			    KMF_DIRPATH_ATTR, keydir,
130*5051Swyllys 			    strlen(keydir));
131*5051Swyllys 			numattr++;
132*5051Swyllys 		}
133*5051Swyllys 
134*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
135*5051Swyllys 		    KMF_ENCODE_FORMAT_ATTR, &outformat,
136*5051Swyllys 		    sizeof (outformat));
137*5051Swyllys 		numattr++;
138*5051Swyllys 
139*5051Swyllys 		if (cred != NULL && cred->credlen > 0) {
140*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
141*5051Swyllys 			    KMF_CREDENTIAL_ATTR, cred,
142*5051Swyllys 			    sizeof (KMF_CREDENTIAL));
143*5051Swyllys 			numattr++;
144*5051Swyllys 		}
14517Sdinak 
1463089Swyllys 		/* The order of certificates and keys should match */
1473089Swyllys 		for (i = 0; rv == KMF_OK && i < nkeys; i++) {
148*5051Swyllys 			int num = numattr;
1493089Swyllys 
1503089Swyllys 			if (i > 0) {
1513089Swyllys 				(void) snprintf(newkeyfile,
152*5051Swyllys 				    sizeof (newkeyfile), "%s_%d", keyfile, i);
153*5051Swyllys 
154*5051Swyllys 				kmf_set_attr_at_index(attrlist, num,
155*5051Swyllys 				    KMF_KEY_FILENAME_ATTR, newkeyfile,
156*5051Swyllys 				    strlen(newkeyfile));
157*5051Swyllys 				num++;
1583089Swyllys 			} else {
159*5051Swyllys 				kmf_set_attr_at_index(attrlist, num,
160*5051Swyllys 				    KMF_KEY_FILENAME_ATTR, keyfile,
161*5051Swyllys 				    strlen(keyfile));
162*5051Swyllys 				num++;
1633089Swyllys 			}
16417Sdinak 
165*5051Swyllys 			kmf_set_attr_at_index(attrlist, num,
166*5051Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i],
167*5051Swyllys 			    sizeof (KMF_DATA));
168*5051Swyllys 			num++;
169*5051Swyllys 
170*5051Swyllys 			kmf_set_attr_at_index(attrlist, num,
171*5051Swyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
172*5051Swyllys 			    sizeof (KMF_RAW_KEY_DATA));
173*5051Swyllys 			num++;
174*5051Swyllys 
175*5051Swyllys 			rv = kmf_store_key(kmfhandle, num, attrlist);
1763089Swyllys 		}
1773089Swyllys 	}
1783089Swyllys 	/*
1793089Swyllys 	 * Cleanup memory.
1803089Swyllys 	 */
1813089Swyllys 	if (certs) {
1823089Swyllys 		for (i = 0; i < ncerts; i++)
183*5051Swyllys 			kmf_free_data(&certs[i]);
1843089Swyllys 		free(certs);
1853089Swyllys 	}
1863089Swyllys 	if (keys) {
1873089Swyllys 		for (i = 0; i < nkeys; i++)
188*5051Swyllys 			kmf_free_raw_key(&keys[i]);
1893089Swyllys 		free(keys);
19017Sdinak 	}
19117Sdinak 
19217Sdinak 
1933089Swyllys 	return (rv);
19417Sdinak }
19517Sdinak 
1963089Swyllys 
1973089Swyllys static KMF_RETURN
1983089Swyllys pk_import_pk12_nss(
1993089Swyllys 	KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *kmfcred,
2003089Swyllys 	KMF_CREDENTIAL *tokencred,
2013089Swyllys 	char *token_spec, char *dir, char *prefix,
2023089Swyllys 	char *nickname, char *trustflags, char *filename)
20317Sdinak {
2043089Swyllys 	KMF_RETURN rv = KMF_OK;
2053089Swyllys 	KMF_DATA *certs = NULL;
2063089Swyllys 	KMF_RAW_KEY_DATA *keys = NULL;
2073089Swyllys 	int ncerts = 0;
2083089Swyllys 	int nkeys = 0;
2093089Swyllys 	int i;
210*5051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
211*5051Swyllys 	KMF_ATTRIBUTE attrlist[16];
212*5051Swyllys 	int numattr = 0;
2133089Swyllys 
2143089Swyllys 	rv = configure_nss(kmfhandle, dir, prefix);
2153089Swyllys 	if (rv != KMF_OK)
2163089Swyllys 		return (rv);
2173089Swyllys 
218*5051Swyllys 	rv = kmf_import_objects(kmfhandle, filename, kmfcred,
219*5051Swyllys 	    &certs, &ncerts, &keys, &nkeys);
2203089Swyllys 
2213089Swyllys 	if (rv == KMF_OK)
2223089Swyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
223*5051Swyllys 		    "key(s) in %s\n"), ncerts, nkeys, filename);
22417Sdinak 
2253089Swyllys 	if (rv == KMF_OK) {
226*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
227*5051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
228*5051Swyllys 		numattr++;
22917Sdinak 
230*5051Swyllys 		if (token_spec != NULL) {
231*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
232*5051Swyllys 			    KMF_TOKEN_LABEL_ATTR, token_spec,
233*5051Swyllys 			    strlen(token_spec));
234*5051Swyllys 			numattr++;
235*5051Swyllys 		}
236*5051Swyllys 
237*5051Swyllys 		if (trustflags != NULL) {
238*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
239*5051Swyllys 			    KMF_TRUSTFLAG_ATTR, trustflags,
240*5051Swyllys 			    strlen(trustflags));
241*5051Swyllys 			numattr++;
242*5051Swyllys 		}
24317Sdinak 
2443089Swyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
245*5051Swyllys 			int num = numattr;
24617Sdinak 
247*5051Swyllys 			if (i == 0 && nickname != NULL) {
248*5051Swyllys 				kmf_set_attr_at_index(attrlist, num,
249*5051Swyllys 				    KMF_CERT_LABEL_ATTR, nickname,
250*5051Swyllys 				    strlen(nickname));
251*5051Swyllys 				num++;
252*5051Swyllys 			}
253*5051Swyllys 
254*5051Swyllys 			kmf_set_attr_at_index(attrlist, num,
255*5051Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i], sizeof (KMF_DATA));
256*5051Swyllys 			num++;
257*5051Swyllys 			rv = kmf_store_cert(kmfhandle, num, attrlist);
2583089Swyllys 		}
2593089Swyllys 		if (rv != KMF_OK) {
2603089Swyllys 			display_error(kmfhandle, rv,
261*5051Swyllys 			    gettext("Error storing certificate in NSS token"));
2623089Swyllys 		}
26317Sdinak 	}
26417Sdinak 
2653089Swyllys 	if (rv == KMF_OK) {
266*5051Swyllys 		numattr = 0;
267*5051Swyllys 
268*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
269*5051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
270*5051Swyllys 		    sizeof (kstype));
271*5051Swyllys 		numattr++;
272*5051Swyllys 
273*5051Swyllys 		if (token_spec != NULL) {
274*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
275*5051Swyllys 			    KMF_TOKEN_LABEL_ATTR, token_spec,
276*5051Swyllys 			    strlen(token_spec));
277*5051Swyllys 			numattr++;
278*5051Swyllys 		}
279*5051Swyllys 
280*5051Swyllys 		if (nickname != NULL) {
281*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
282*5051Swyllys 			    KMF_KEYLABEL_ATTR, nickname,
283*5051Swyllys 			    strlen(nickname));
284*5051Swyllys 			numattr++;
285*5051Swyllys 		}
286*5051Swyllys 
287*5051Swyllys 		if (tokencred->credlen > 0) {
288*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
289*5051Swyllys 			    KMF_CREDENTIAL_ATTR, tokencred,
290*5051Swyllys 			    sizeof (KMF_CREDENTIAL));
291*5051Swyllys 			numattr++;
292*5051Swyllys 		}
2933089Swyllys 
2943089Swyllys 		/* The order of certificates and keys should match */
2953089Swyllys 		for (i = 0; i < nkeys; i++) {
296*5051Swyllys 			int num = numattr;
297*5051Swyllys 
298*5051Swyllys 			kmf_set_attr_at_index(attrlist, num,
299*5051Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i],
300*5051Swyllys 			    sizeof (KMF_DATA));
301*5051Swyllys 			num++;
3023089Swyllys 
303*5051Swyllys 			kmf_set_attr_at_index(attrlist, num,
304*5051Swyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
305*5051Swyllys 			    sizeof (KMF_RAW_KEY_DATA));
306*5051Swyllys 			num++;
307*5051Swyllys 
308*5051Swyllys 			rv = kmf_store_key(kmfhandle, num, attrlist);
3093089Swyllys 		}
3103089Swyllys 	}
3113089Swyllys 
3123089Swyllys 	/*
3133089Swyllys 	 * Cleanup memory.
3143089Swyllys 	 */
3153089Swyllys 	if (certs) {
3163089Swyllys 		for (i = 0; i < ncerts; i++)
317*5051Swyllys 			kmf_free_data(&certs[i]);
3183089Swyllys 		free(certs);
3193089Swyllys 	}
3203089Swyllys 	if (keys) {
3213089Swyllys 		for (i = 0; i < nkeys; i++)
322*5051Swyllys 			kmf_free_raw_key(&keys[i]);
3233089Swyllys 		free(keys);
32417Sdinak 	}
32517Sdinak 
3263089Swyllys 	return (rv);
3273089Swyllys }
32817Sdinak 
3293089Swyllys static KMF_RETURN
3303089Swyllys pk_import_cert(
3313089Swyllys 	KMF_HANDLE_T kmfhandle,
3323089Swyllys 	KMF_KEYSTORE_TYPE kstype,
3333089Swyllys 	char *label, char *token_spec, char *filename,
3343089Swyllys 	char *dir, char *prefix, char *trustflags)
3353089Swyllys {
3363089Swyllys 	KMF_RETURN rv = KMF_OK;
337*5051Swyllys 	KMF_ATTRIBUTE attrlist[32];
338*5051Swyllys 	int i = 0;
33917Sdinak 
3403089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
3413089Swyllys 		rv = select_token(kmfhandle, token_spec, FALSE);
342*5051Swyllys 	} else if (kstype == KMF_KEYSTORE_NSS) {
343*5051Swyllys 		rv = configure_nss(kmfhandle, dir, prefix);
344*5051Swyllys 	}
345*5051Swyllys 	if (rv != KMF_OK)
346*5051Swyllys 		return (rv);
34717Sdinak 
348*5051Swyllys 	kmf_set_attr_at_index(attrlist, i,
349*5051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (KMF_KEYSTORE_TYPE));
350*5051Swyllys 	i++;
351*5051Swyllys 
352*5051Swyllys 	kmf_set_attr_at_index(attrlist, i, KMF_CERT_FILENAME_ATTR,
353*5051Swyllys 	    filename, strlen(filename));
354*5051Swyllys 	i++;
355*5051Swyllys 
356*5051Swyllys 	if (label != NULL) {
357*5051Swyllys 		kmf_set_attr_at_index(attrlist, i, KMF_CERT_LABEL_ATTR,
358*5051Swyllys 		    label, strlen(label));
359*5051Swyllys 		i++;
360*5051Swyllys 	}
361*5051Swyllys 
362*5051Swyllys 	if (kstype == KMF_KEYSTORE_NSS) {
363*5051Swyllys 		if (trustflags != NULL) {
364*5051Swyllys 			kmf_set_attr_at_index(attrlist, i, KMF_TRUSTFLAG_ATTR,
365*5051Swyllys 			    trustflags, strlen(trustflags));
366*5051Swyllys 			i++;
367*5051Swyllys 		}
368*5051Swyllys 
369*5051Swyllys 		if (token_spec != NULL) {
370*5051Swyllys 			kmf_set_attr_at_index(attrlist, i,
371*5051Swyllys 			    KMF_TOKEN_LABEL_ATTR,
372*5051Swyllys 			    token_spec, strlen(token_spec));
373*5051Swyllys 			i++;
37417Sdinak 		}
3753089Swyllys 	}
37617Sdinak 
377*5051Swyllys 	rv = kmf_import_cert(kmfhandle, i, attrlist);
3783089Swyllys 	return (rv);
3793089Swyllys }
3803089Swyllys 
3813089Swyllys static KMF_RETURN
3823089Swyllys pk_import_file_crl(void *kmfhandle,
3833089Swyllys 	char *infile,
3843089Swyllys 	char *outfile,
3853089Swyllys 	char *outdir,
3863089Swyllys 	KMF_ENCODE_FORMAT outfmt)
3873089Swyllys {
388*5051Swyllys 	int numattr = 0;
389*5051Swyllys 	KMF_ATTRIBUTE attrlist[8];
390*5051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
3913089Swyllys 
392*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
393*5051Swyllys 	    &kstype, sizeof (kstype));
394*5051Swyllys 	numattr++;
395*5051Swyllys 	if (infile) {
396*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
397*5051Swyllys 		    KMF_CRL_FILENAME_ATTR, infile, strlen(infile));
398*5051Swyllys 		numattr++;
399*5051Swyllys 	}
400*5051Swyllys 	if (outdir) {
401*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
402*5051Swyllys 		    KMF_DIRPATH_ATTR, outdir, strlen(outdir));
403*5051Swyllys 		numattr++;
404*5051Swyllys 	}
405*5051Swyllys 	if (outfile) {
406*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
407*5051Swyllys 		    KMF_CRL_OUTFILE_ATTR, outfile, strlen(outfile));
408*5051Swyllys 		numattr++;
409*5051Swyllys 	}
410*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
411*5051Swyllys 	    KMF_ENCODE_FORMAT_ATTR, &outfmt, sizeof (outfmt));
412*5051Swyllys 	numattr++;
4133089Swyllys 
414*5051Swyllys 	return (kmf_import_crl(kmfhandle, numattr, attrlist));
4153089Swyllys }
4163089Swyllys 
4173089Swyllys static KMF_RETURN
4183089Swyllys pk_import_nss_crl(void *kmfhandle,
4193089Swyllys 	boolean_t verify_crl_flag,
4203089Swyllys 	char *infile,
4213089Swyllys 	char *outdir,
4223089Swyllys 	char *prefix)
4233089Swyllys {
4243089Swyllys 	KMF_RETURN rv;
425*5051Swyllys 	int numattr = 0;
426*5051Swyllys 	KMF_ATTRIBUTE attrlist[4];
427*5051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
4283089Swyllys 
4293089Swyllys 	rv = configure_nss(kmfhandle, outdir, prefix);
4303089Swyllys 	if (rv != KMF_OK)
4313089Swyllys 		return (rv);
4323089Swyllys 
433*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
434*5051Swyllys 	    &kstype, sizeof (kstype));
435*5051Swyllys 	numattr++;
436*5051Swyllys 	if (infile) {
437*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR,
438*5051Swyllys 		    infile, strlen(infile));
439*5051Swyllys 		numattr++;
440*5051Swyllys 	}
441*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_CHECK_ATTR,
442*5051Swyllys 	    &verify_crl_flag, sizeof (verify_crl_flag));
443*5051Swyllys 	numattr++;
4443089Swyllys 
445*5051Swyllys 	return (kmf_import_crl(kmfhandle, numattr, attrlist));
4463089Swyllys 
4473089Swyllys }
4483089Swyllys 
4493089Swyllys static KMF_RETURN
4503089Swyllys pk_import_pk12_pk11(
4513089Swyllys 	KMF_HANDLE_T kmfhandle,
4523089Swyllys 	KMF_CREDENTIAL *p12cred,
4533089Swyllys 	KMF_CREDENTIAL *tokencred,
4543089Swyllys 	char *label, char *token_spec,
4553089Swyllys 	char *filename)
4563089Swyllys {
4573089Swyllys 	KMF_RETURN rv = KMF_OK;
4583089Swyllys 	KMF_DATA *certs = NULL;
4593089Swyllys 	KMF_RAW_KEY_DATA *keys = NULL;
4603089Swyllys 	int ncerts = 0;
4613089Swyllys 	int nkeys = 0;
4623089Swyllys 	int i;
463*5051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
464*5051Swyllys 	KMF_ATTRIBUTE attrlist[16];
465*5051Swyllys 	int numattr = 0;
4663089Swyllys 
4673089Swyllys 	rv = select_token(kmfhandle, token_spec, FALSE);
4683089Swyllys 
4693089Swyllys 	if (rv != KMF_OK) {
47017Sdinak 		return (rv);
47117Sdinak 	}
47217Sdinak 
473*5051Swyllys 	rv = kmf_import_objects(kmfhandle, filename, p12cred,
474*5051Swyllys 	    &certs, &ncerts, &keys, &nkeys);
4753089Swyllys 
4763089Swyllys 	if (rv == KMF_OK) {
477*5051Swyllys 
478*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
479*5051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
480*5051Swyllys 		    sizeof (kstype));
481*5051Swyllys 		numattr++;
482*5051Swyllys 
483*5051Swyllys 		if (label != NULL) {
484*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
485*5051Swyllys 			    KMF_KEYLABEL_ATTR, label,
486*5051Swyllys 			    strlen(label));
487*5051Swyllys 			numattr++;
488*5051Swyllys 		}
489*5051Swyllys 
490*5051Swyllys 		if (tokencred != NULL && tokencred->credlen > 0) {
491*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
492*5051Swyllys 			    KMF_CREDENTIAL_ATTR, tokencred,
493*5051Swyllys 			    sizeof (KMF_CREDENTIAL));
494*5051Swyllys 			numattr++;
495*5051Swyllys 		}
4963089Swyllys 
4973089Swyllys 		/* The order of certificates and keys should match */
4983089Swyllys 		for (i = 0; i < nkeys; i++) {
499*5051Swyllys 			int num = numattr;
500*5051Swyllys 
501*5051Swyllys 			kmf_set_attr_at_index(attrlist, num,
502*5051Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i],
503*5051Swyllys 			    sizeof (KMF_DATA));
504*5051Swyllys 			num++;
5053089Swyllys 
506*5051Swyllys 			kmf_set_attr_at_index(attrlist, num,
507*5051Swyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
508*5051Swyllys 			    sizeof (KMF_RAW_KEY_DATA));
509*5051Swyllys 			num++;
510*5051Swyllys 
511*5051Swyllys 			rv = kmf_store_key(kmfhandle, num, attrlist);
512*5051Swyllys 
5133089Swyllys 		}
5143089Swyllys 	}
5153089Swyllys 
5163089Swyllys 	if (rv == KMF_OK) {
5173089Swyllys 
5183089Swyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
519*5051Swyllys 		    "key(s) in %s\n"), ncerts, nkeys, filename);
520*5051Swyllys 		numattr = 0;
521*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
522*5051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
523*5051Swyllys 		numattr++;
5243089Swyllys 
5253089Swyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
526*5051Swyllys 			int num = numattr;
5273089Swyllys 
528*5051Swyllys 			if (i == 0 && label != NULL) {
529*5051Swyllys 				kmf_set_attr_at_index(attrlist, num,
530*5051Swyllys 				    KMF_CERT_LABEL_ATTR, label, strlen(label));
531*5051Swyllys 				num++;
532*5051Swyllys 			}
533*5051Swyllys 
534*5051Swyllys 			kmf_set_attr_at_index(attrlist, num,
535*5051Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i], sizeof (KMF_DATA));
536*5051Swyllys 			num++;
537*5051Swyllys 
538*5051Swyllys 			rv = kmf_store_cert(kmfhandle, num, attrlist);
5393089Swyllys 		}
5403089Swyllys 	}
5413089Swyllys 
5423089Swyllys 	/*
5433089Swyllys 	 * Cleanup memory.
5443089Swyllys 	 */
5453089Swyllys 	if (certs) {
5463089Swyllys 		for (i = 0; i < ncerts; i++)
547*5051Swyllys 			kmf_free_data(&certs[i]);
5483089Swyllys 		free(certs);
5493089Swyllys 	}
5503089Swyllys 	if (keys) {
5513089Swyllys 		for (i = 0; i < nkeys; i++)
552*5051Swyllys 			kmf_free_raw_key(&keys[i]);
5533089Swyllys 		free(keys);
5543089Swyllys 	}
5553089Swyllys 
5563089Swyllys 	return (rv);
55717Sdinak }
55817Sdinak 
559*5051Swyllys static KMF_RETURN
560*5051Swyllys pk_import_keys(KMF_HANDLE_T kmfhandle,
561*5051Swyllys 	KMF_KEYSTORE_TYPE kstype, char *token_spec,
562*5051Swyllys 	KMF_CREDENTIAL *cred, char *filename,
563*5051Swyllys 	char *label, char *senstr, char *extstr)
564*5051Swyllys {
565*5051Swyllys 	KMF_RETURN rv = KMF_OK;
566*5051Swyllys 	KMF_ATTRIBUTE attrlist[16];
567*5051Swyllys 	KMF_KEYSTORE_TYPE fileks = KMF_KEYSTORE_OPENSSL;
568*5051Swyllys 	int numattr = 0;
569*5051Swyllys 	KMF_KEY_HANDLE key;
570*5051Swyllys 	KMF_RAW_KEY_DATA rawkey;
571*5051Swyllys 	KMF_KEY_CLASS class = KMF_ASYM_PRI;
572*5051Swyllys 	int numkeys = 1;
573*5051Swyllys 
574*5051Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
575*5051Swyllys 		rv = select_token(kmfhandle, token_spec, FALSE);
576*5051Swyllys 	}
577*5051Swyllys 	if (rv != KMF_OK)
578*5051Swyllys 		return (rv);
579*5051Swyllys 	/*
580*5051Swyllys 	 * First, set up to read the keyfile using the FILE plugin
581*5051Swyllys 	 * mechanisms.
582*5051Swyllys 	 */
583*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
584*5051Swyllys 	    &fileks, sizeof (fileks));
585*5051Swyllys 	numattr++;
586*5051Swyllys 
587*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
588*5051Swyllys 	    &numkeys, sizeof (numkeys));
589*5051Swyllys 	numattr++;
590*5051Swyllys 
591*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
592*5051Swyllys 	    &key, sizeof (key));
593*5051Swyllys 	numattr++;
594*5051Swyllys 
595*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR,
596*5051Swyllys 	    &rawkey, sizeof (rawkey));
597*5051Swyllys 	numattr++;
598*5051Swyllys 
599*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
600*5051Swyllys 	    &class, sizeof (class));
601*5051Swyllys 	numattr++;
602*5051Swyllys 
603*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
604*5051Swyllys 	    filename, strlen(filename));
605*5051Swyllys 	numattr++;
606*5051Swyllys 
607*5051Swyllys 	rv = kmf_find_key(kmfhandle, numattr, attrlist);
608*5051Swyllys 	if (rv == KMF_OK) {
609*5051Swyllys 		numattr = 0;
610*5051Swyllys 
611*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
612*5051Swyllys 		    &kstype, sizeof (kstype));
613*5051Swyllys 		numattr++;
614*5051Swyllys 
615*5051Swyllys 		if (cred != NULL && cred->credlen > 0) {
616*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
617*5051Swyllys 			    KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
618*5051Swyllys 			numattr++;
619*5051Swyllys 		}
620*5051Swyllys 
621*5051Swyllys 		if (label != NULL) {
622*5051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
623*5051Swyllys 			    KMF_KEYLABEL_ATTR, label, strlen(label));
624*5051Swyllys 			numattr++;
625*5051Swyllys 		}
626*5051Swyllys 
627*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
628*5051Swyllys 		    KMF_RAW_KEY_ATTR, &rawkey, sizeof (rawkey));
629*5051Swyllys 		numattr++;
630*5051Swyllys 
631*5051Swyllys 		rv = kmf_store_key(kmfhandle, numattr, attrlist);
632*5051Swyllys 		if (rv == KMF_OK) {
633*5051Swyllys 			printf(gettext("Importing %d keys\n"), numkeys);
634*5051Swyllys 		}
635*5051Swyllys 
636*5051Swyllys 		kmf_free_kmf_key(kmfhandle, &key);
637*5051Swyllys 		kmf_free_raw_key(&rawkey);
638*5051Swyllys 	} else {
639*5051Swyllys 		cryptoerror(LOG_STDERR,
640*5051Swyllys 		    gettext("Failed to load key from file (%s)\n"),
641*5051Swyllys 		    filename);
642*5051Swyllys 	}
643*5051Swyllys 	return (rv);
644*5051Swyllys }
645*5051Swyllys 
646*5051Swyllys static KMF_RETURN
647*5051Swyllys pk_import_rawkey(KMF_HANDLE_T kmfhandle,
648*5051Swyllys 	KMF_KEYSTORE_TYPE kstype, char *token,
649*5051Swyllys 	KMF_CREDENTIAL *cred,
650*5051Swyllys 	char *filename, char *label, KMF_KEY_ALG keyAlg,
651*5051Swyllys 	char *senstr, char *extstr)
652*5051Swyllys {
653*5051Swyllys 	KMF_RETURN rv = KMF_OK;
654*5051Swyllys 	KMF_ATTRIBUTE attrlist[16];
655*5051Swyllys 	int numattr = 0;
656*5051Swyllys 	uint32_t keylen;
657*5051Swyllys 	boolean_t sensitive = B_FALSE;
658*5051Swyllys 	boolean_t not_extractable = B_FALSE;
659*5051Swyllys 	KMF_DATA keydata = {NULL, 0};
660*5051Swyllys 	KMF_KEY_HANDLE rawkey;
661*5051Swyllys 
662*5051Swyllys 	rv = kmf_read_input_file(kmfhandle, filename, &keydata);
663*5051Swyllys 	if (rv != KMF_OK)
664*5051Swyllys 		return (rv);
665*5051Swyllys 
666*5051Swyllys 	rv = select_token(kmfhandle, token, FALSE);
667*5051Swyllys 
668*5051Swyllys 	if (rv != KMF_OK) {
669*5051Swyllys 		return (rv);
670*5051Swyllys 	}
671*5051Swyllys 	if (senstr != NULL) {
672*5051Swyllys 		if (tolower(senstr[0]) == 'y')
673*5051Swyllys 			sensitive = B_TRUE;
674*5051Swyllys 		else if (tolower(senstr[0]) == 'n')
675*5051Swyllys 			sensitive = B_FALSE;
676*5051Swyllys 		else {
677*5051Swyllys 			cryptoerror(LOG_STDERR,
678*5051Swyllys 			    gettext("Incorrect sensitive option value.\n"));
679*5051Swyllys 			return (KMF_ERR_BAD_PARAMETER);
680*5051Swyllys 		}
681*5051Swyllys 	}
682*5051Swyllys 
683*5051Swyllys 	if (extstr != NULL) {
684*5051Swyllys 		if (tolower(extstr[0]) == 'y')
685*5051Swyllys 			not_extractable = B_FALSE;
686*5051Swyllys 		else if (tolower(extstr[0]) == 'n')
687*5051Swyllys 			not_extractable = B_TRUE;
688*5051Swyllys 		else {
689*5051Swyllys 			cryptoerror(LOG_STDERR,
690*5051Swyllys 			    gettext("Incorrect extractable option value.\n"));
691*5051Swyllys 			return (KMF_ERR_BAD_PARAMETER);
692*5051Swyllys 		}
693*5051Swyllys 	}
694*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
695*5051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
696*5051Swyllys 	numattr++;
697*5051Swyllys 
698*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
699*5051Swyllys 	    KMF_KEY_HANDLE_ATTR, &rawkey, sizeof (rawkey));
700*5051Swyllys 	numattr++;
701*5051Swyllys 
702*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
703*5051Swyllys 	    KMF_KEYALG_ATTR, &keyAlg, sizeof (KMF_KEY_ALG));
704*5051Swyllys 	numattr++;
705*5051Swyllys 
706*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
707*5051Swyllys 	    KMF_KEY_DATA_ATTR, keydata.Data, keydata.Length);
708*5051Swyllys 	numattr++;
709*5051Swyllys 
710*5051Swyllys 	/* Key length is given in bits not bytes */
711*5051Swyllys 	keylen = keydata.Length * 8;
712*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
713*5051Swyllys 	    KMF_KEYLENGTH_ATTR, &keylen, sizeof (keydata.Length));
714*5051Swyllys 	numattr++;
715*5051Swyllys 
716*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
717*5051Swyllys 	    KMF_SENSITIVE_BOOL_ATTR, &sensitive, sizeof (sensitive));
718*5051Swyllys 	numattr++;
719*5051Swyllys 
720*5051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
721*5051Swyllys 	    KMF_NON_EXTRACTABLE_BOOL_ATTR, &not_extractable,
722*5051Swyllys 	    sizeof (not_extractable));
723*5051Swyllys 	numattr++;
724*5051Swyllys 
725*5051Swyllys 	if (label != NULL) {
726*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
727*5051Swyllys 		    KMF_KEYLABEL_ATTR, label, strlen(label));
728*5051Swyllys 		numattr++;
729*5051Swyllys 	}
730*5051Swyllys 	if (cred != NULL && cred->credlen > 0) {
731*5051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
732*5051Swyllys 		    KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
733*5051Swyllys 		numattr++;
734*5051Swyllys 	}
735*5051Swyllys 	rv = kmf_create_sym_key(kmfhandle, numattr, attrlist);
736*5051Swyllys 
737*5051Swyllys 	return (rv);
738*5051Swyllys }
739*5051Swyllys 
74017Sdinak /*
7413089Swyllys  * Import objects from into KMF repositories.
74217Sdinak  */
74317Sdinak int
74417Sdinak pk_import(int argc, char *argv[])
74517Sdinak {
746864Sdinak 	int		opt;
747864Sdinak 	extern int	optind_av;
748864Sdinak 	extern char	*optarg_av;
749864Sdinak 	char		*token_spec = NULL;
75017Sdinak 	char		*filename = NULL;
7513089Swyllys 	char		*keyfile = NULL;
7523089Swyllys 	char		*certfile = NULL;
7533089Swyllys 	char		*crlfile = NULL;
754*5051Swyllys 	char		*label = NULL;
7553089Swyllys 	char		*dir = NULL;
7563089Swyllys 	char		*keydir = NULL;
7573089Swyllys 	char		*prefix = NULL;
7583089Swyllys 	char		*trustflags = NULL;
7593089Swyllys 	char		*verify_crl = NULL;
760*5051Swyllys 	char		*keytype = "generic";
761*5051Swyllys 	char		*senstr = NULL;
762*5051Swyllys 	char		*extstr = NULL;
7633089Swyllys 	boolean_t	verify_crl_flag = B_FALSE;
7643089Swyllys 	int		oclass = 0;
7653089Swyllys 	KMF_KEYSTORE_TYPE	kstype = 0;
7663089Swyllys 	KMF_ENCODE_FORMAT	kfmt = 0;
7673089Swyllys 	KMF_ENCODE_FORMAT	okfmt = KMF_FORMAT_ASN1;
7683089Swyllys 	KMF_RETURN		rv = KMF_OK;
7693089Swyllys 	KMF_CREDENTIAL	pk12cred = { NULL, 0 };
7703089Swyllys 	KMF_CREDENTIAL	tokencred = { NULL, 0 };
7713089Swyllys 	KMF_HANDLE_T	kmfhandle = NULL;
772*5051Swyllys 	KMF_KEY_ALG	keyAlg = KMF_GENERIC_SECRET;
77317Sdinak 
774864Sdinak 	/* Parse command line options.  Do NOT i18n/l10n. */
7753089Swyllys 	while ((opt = getopt_av(argc, argv,
776*5051Swyllys 	    "T:(token)i:(infile)"
777*5051Swyllys 	    "k:(keystore)y:(objtype)"
778*5051Swyllys 	    "d:(dir)p:(prefix)"
779*5051Swyllys 	    "n:(certlabel)N:(label)"
780*5051Swyllys 	    "K:(outkey)c:(outcert)"
781*5051Swyllys 	    "v:(verifycrl)l:(outcrl)"
782*5051Swyllys 	    "E:(keytype)s:(sensitive)x:(extractable)"
783*5051Swyllys 	    "t:(trust)D:(keydir)F:(outformat)")) != EOF) {
7843089Swyllys 		if (EMPTYSTRING(optarg_av))
7853089Swyllys 			return (PK_ERR_USAGE);
786864Sdinak 		switch (opt) {
787864Sdinak 		case 'T':	/* token specifier */
788864Sdinak 			if (token_spec)
789864Sdinak 				return (PK_ERR_USAGE);
790864Sdinak 			token_spec = optarg_av;
791864Sdinak 			break;
7923089Swyllys 		case 'c':	/* output cert file name */
7933089Swyllys 			if (certfile)
7943089Swyllys 				return (PK_ERR_USAGE);
7953089Swyllys 			certfile = optarg_av;
7963089Swyllys 			break;
7973089Swyllys 		case 'l':	/* output CRL file name */
7983089Swyllys 			if (crlfile)
7993089Swyllys 				return (PK_ERR_USAGE);
8003089Swyllys 			crlfile = optarg_av;
8013089Swyllys 			break;
8023089Swyllys 		case 'K':	/* output key file name */
8033089Swyllys 			if (keyfile)
8043089Swyllys 				return (PK_ERR_USAGE);
8053089Swyllys 			keyfile = optarg_av;
8063089Swyllys 			break;
807864Sdinak 		case 'i':	/* input file name */
808864Sdinak 			if (filename)
809864Sdinak 				return (PK_ERR_USAGE);
810864Sdinak 			filename = optarg_av;
811864Sdinak 			break;
8123089Swyllys 		case 'k':
8133089Swyllys 			kstype = KS2Int(optarg_av);
8143089Swyllys 			if (kstype == 0)
8153089Swyllys 				return (PK_ERR_USAGE);
8163089Swyllys 			break;
8173089Swyllys 		case 'y':
8183089Swyllys 			oclass = OT2Int(optarg_av);
8193089Swyllys 			if (oclass == -1)
8203089Swyllys 				return (PK_ERR_USAGE);
8213089Swyllys 			break;
8223089Swyllys 		case 'd':
8233089Swyllys 			dir = optarg_av;
8243089Swyllys 			break;
8253089Swyllys 		case 'D':
8263089Swyllys 			keydir = optarg_av;
8273089Swyllys 			break;
8283089Swyllys 		case 'p':
8293089Swyllys 			if (prefix)
8303089Swyllys 				return (PK_ERR_USAGE);
8313089Swyllys 			prefix = optarg_av;
8323089Swyllys 			break;
8333089Swyllys 		case 'n':
8343089Swyllys 		case 'N':
835*5051Swyllys 			if (label)
8363089Swyllys 				return (PK_ERR_USAGE);
837*5051Swyllys 			label = optarg_av;
8383089Swyllys 			break;
8393089Swyllys 		case 'F':
8403089Swyllys 			okfmt = Str2Format(optarg_av);
8413089Swyllys 			if (okfmt == KMF_FORMAT_UNDEF)
8423089Swyllys 				return (PK_ERR_USAGE);
8433089Swyllys 			break;
8443089Swyllys 		case 't':
8453089Swyllys 			if (trustflags)
8463089Swyllys 				return (PK_ERR_USAGE);
8473089Swyllys 			trustflags = optarg_av;
8483089Swyllys 			break;
8493089Swyllys 		case 'v':
8503089Swyllys 			verify_crl = optarg_av;
8513089Swyllys 			if (tolower(verify_crl[0]) == 'y')
8523089Swyllys 				verify_crl_flag = B_TRUE;
8533089Swyllys 			else if (tolower(verify_crl[0]) == 'n')
8543089Swyllys 				verify_crl_flag = B_FALSE;
8553089Swyllys 			else
8563089Swyllys 				return (PK_ERR_USAGE);
8573089Swyllys 			break;
858*5051Swyllys 		case 'E':
859*5051Swyllys 			keytype = optarg_av;
860*5051Swyllys 			break;
861*5051Swyllys 		case 's':
862*5051Swyllys 			if (senstr)
863*5051Swyllys 				return (PK_ERR_USAGE);
864*5051Swyllys 			senstr = optarg_av;
865*5051Swyllys 			break;
866*5051Swyllys 		case 'x':
867*5051Swyllys 			if (extstr)
868*5051Swyllys 				return (PK_ERR_USAGE);
869*5051Swyllys 			extstr = optarg_av;
870*5051Swyllys 			break;
871864Sdinak 		default:
872864Sdinak 			return (PK_ERR_USAGE);
873864Sdinak 			break;
874864Sdinak 		}
875864Sdinak 	}
87617Sdinak 
8773089Swyllys 	/* Assume keystore = PKCS#11 if not specified */
8783089Swyllys 	if (kstype == 0)
8793089Swyllys 		kstype = KMF_KEYSTORE_PK11TOKEN;
880864Sdinak 
881864Sdinak 	/* Filename arg is required. */
8823089Swyllys 	if (EMPTYSTRING(filename)) {
8833089Swyllys 		cryptoerror(LOG_STDERR, gettext("The 'infile' parameter"
884*5051Swyllys 		    "is required for the import operation.\n"));
88517Sdinak 		return (PK_ERR_USAGE);
8863089Swyllys 	}
88717Sdinak 
888864Sdinak 	/* No additional args allowed. */
889864Sdinak 	argc -= optind_av;
890864Sdinak 	argv += optind_av;
891864Sdinak 	if (argc)
892864Sdinak 		return (PK_ERR_USAGE);
89317Sdinak 
8943089Swyllys 	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
8953089Swyllys 	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
896*5051Swyllys 	    kstype != KMF_KEYSTORE_PK11TOKEN) {
8973089Swyllys 
8983089Swyllys 		(void) fprintf(stderr, gettext("The objtype parameter "
899*5051Swyllys 		    "is only relevant if keystore=pkcs11\n"));
9003089Swyllys 		return (PK_ERR_USAGE);
90117Sdinak 	}
90217Sdinak 
9033089Swyllys 	/*
9043089Swyllys 	 * You must specify a certlabel (cert label) when importing
9053089Swyllys 	 * into NSS or PKCS#11.
9063089Swyllys 	 */
9073089Swyllys 	if (kstype == KMF_KEYSTORE_NSS &&
908*5051Swyllys 	    (oclass != PK_CRL_OBJ) && EMPTYSTRING(label)) {
9093089Swyllys 		cryptoerror(LOG_STDERR, gettext("The 'label' argument "
910*5051Swyllys 		    "is required for this operation\n"));
9113089Swyllys 		return (PK_ERR_USAGE);
91217Sdinak 	}
91317Sdinak 
914*5051Swyllys 	if ((rv = kmf_get_file_format(filename, &kfmt)) != KMF_OK) {
915*5051Swyllys 		/*
916*5051Swyllys 		 * Allow for raw key data to be imported.
917*5051Swyllys 		 */
918*5051Swyllys 		if (rv == KMF_ERR_ENCODING) {
919*5051Swyllys 			rv = KMF_OK;
920*5051Swyllys 			kfmt = KMF_FORMAT_RAWKEY;
921*5051Swyllys 			/*
922*5051Swyllys 			 * Set the object class only if it was not
923*5051Swyllys 			 * given on the command line or if it was
924*5051Swyllys 			 * specified as a symmetric key object.
925*5051Swyllys 			 */
926*5051Swyllys 			if (oclass == 0 || (oclass & PK_SYMKEY_OBJ)) {
927*5051Swyllys 				oclass = PK_SYMKEY_OBJ;
928*5051Swyllys 			} else {
929*5051Swyllys 				cryptoerror(LOG_STDERR, gettext(
930*5051Swyllys 				    "The input file does not contain the "
931*5051Swyllys 				    "object type indicated on command "
932*5051Swyllys 				    "line."));
933*5051Swyllys 				return (KMF_ERR_BAD_PARAMETER);
934*5051Swyllys 			}
935*5051Swyllys 		} else {
936*5051Swyllys 			cryptoerror(LOG_STDERR,
937*5051Swyllys 			    gettext("File format not recognized."));
938*5051Swyllys 			return (rv);
939*5051Swyllys 		}
940*5051Swyllys 	}
941*5051Swyllys 
942*5051Swyllys 	/* Check parameters for raw key import operation */
943*5051Swyllys 	if (kfmt == KMF_FORMAT_RAWKEY) {
944*5051Swyllys 		if (keytype != NULL &&
945*5051Swyllys 		    Str2SymKeyType(keytype, &keyAlg) != 0) {
946*5051Swyllys 			cryptoerror(LOG_STDERR,
947*5051Swyllys 			    gettext("Unrecognized keytype(%s).\n"), keytype);
948*5051Swyllys 			return (PK_ERR_USAGE);
949*5051Swyllys 		}
950*5051Swyllys 		if (senstr != NULL && extstr != NULL &&
951*5051Swyllys 		    kstype != KMF_KEYSTORE_PK11TOKEN) {
952*5051Swyllys 			cryptoerror(LOG_STDERR,
953*5051Swyllys 			    gettext("The sensitive or extractable option "
954*5051Swyllys 			    "applies only when importing a key from a file "
955*5051Swyllys 			    "into a PKCS#11 keystore.\n"));
9563089Swyllys 			return (PK_ERR_USAGE);
9573089Swyllys 		}
95817Sdinak 	}
95917Sdinak 
960*5051Swyllys 	/* If no objtype was given, treat it as a certificate */
9613089Swyllys 	if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 ||
962*5051Swyllys 	    kfmt == KMF_FORMAT_PEM))
9633089Swyllys 		oclass = PK_CERT_OBJ;
96417Sdinak 
9653089Swyllys 	if (kstype == KMF_KEYSTORE_NSS) {
9663089Swyllys 		if (oclass == PK_CRL_OBJ &&
967*5051Swyllys 		    (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
9683089Swyllys 			cryptoerror(LOG_STDERR, gettext(
969*5051Swyllys 			    "CRL data can only be imported as DER or "
970*5051Swyllys 			    "PEM format"));
9713089Swyllys 			return (PK_ERR_USAGE);
9723089Swyllys 		}
9733089Swyllys 
9743089Swyllys 		if (oclass == PK_CERT_OBJ &&
975*5051Swyllys 		    (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
9763089Swyllys 			cryptoerror(LOG_STDERR, gettext(
977*5051Swyllys 			    "Certificates can only be imported as DER or "
978*5051Swyllys 			    "PEM format"));
9793089Swyllys 			return (PK_ERR_USAGE);
9803089Swyllys 		}
9813089Swyllys 
9823089Swyllys 		/* we do not import private keys except in PKCS12 bundles */
9833089Swyllys 		if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) {
9843089Swyllys 			cryptoerror(LOG_STDERR, gettext(
985*5051Swyllys 			    "Private key data can only be imported as part "
986*5051Swyllys 			    "of a PKCS12 file.\n"));
9873089Swyllys 			return (PK_ERR_USAGE);
9883089Swyllys 		}
98917Sdinak 	}
99017Sdinak 
9913089Swyllys 	if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) {
9923089Swyllys 		if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) {
99317Sdinak 			cryptoerror(LOG_STDERR, gettext(
994*5051Swyllys 			    "The 'outkey' and 'outcert' parameters "
995*5051Swyllys 			    "are required for the import operation "
996*5051Swyllys 			    "when the 'file' keystore is used.\n"));
9973089Swyllys 			return (PK_ERR_USAGE);
99817Sdinak 		}
99917Sdinak 	}
100017Sdinak 
10013089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec))
10023089Swyllys 		token_spec = PK_DEFAULT_PK11TOKEN;
10033089Swyllys 	else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec))
10043089Swyllys 		token_spec = DEFAULT_NSS_TOKEN;
10053089Swyllys 
10063089Swyllys 	if (kfmt == KMF_FORMAT_PKCS12) {
10073089Swyllys 		(void) get_pk12_password(&pk12cred);
10083089Swyllys 	}
10093089Swyllys 
1010*5051Swyllys 	if ((kfmt == KMF_FORMAT_PKCS12 || kfmt == KMF_FORMAT_RAWKEY ||
1011*5051Swyllys 	    (kfmt == KMF_FORMAT_PEM && (oclass & PK_KEY_OBJ))) &&
1012*5051Swyllys 	    (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)) {
1013*5051Swyllys 		(void) get_token_password(kstype, token_spec, &tokencred);
1014*5051Swyllys 	}
1015*5051Swyllys 
1016*5051Swyllys 	if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
10173089Swyllys 		cryptoerror(LOG_STDERR, gettext("Error initializing "
1018*5051Swyllys 		    "KMF: 0x%02x\n"), rv);
10193089Swyllys 		goto end;
10203089Swyllys 	}
102117Sdinak 
10223089Swyllys 	switch (kstype) {
10233089Swyllys 		case KMF_KEYSTORE_PK11TOKEN:
10243089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
10253089Swyllys 				rv = pk_import_pk12_pk11(
1026*5051Swyllys 				    kmfhandle, &pk12cred,
1027*5051Swyllys 				    &tokencred, label,
1028*5051Swyllys 				    token_spec, filename);
10293089Swyllys 			else if (oclass == PK_CERT_OBJ)
10303089Swyllys 				rv = pk_import_cert(
1031*5051Swyllys 				    kmfhandle, kstype,
1032*5051Swyllys 				    label, token_spec,
1033*5051Swyllys 				    filename,
1034*5051Swyllys 				    NULL, NULL, NULL);
10353089Swyllys 			else if (oclass == PK_CRL_OBJ)
10363089Swyllys 				rv = pk_import_file_crl(
1037*5051Swyllys 				    kmfhandle, filename,
1038*5051Swyllys 				    crlfile, dir, okfmt);
1039*5051Swyllys 			else if (kfmt == KMF_FORMAT_RAWKEY &&
1040*5051Swyllys 			    oclass == PK_SYMKEY_OBJ) {
1041*5051Swyllys 				rv = pk_import_rawkey(kmfhandle,
1042*5051Swyllys 				    kstype, token_spec, &tokencred,
1043*5051Swyllys 				    filename, label,
1044*5051Swyllys 				    keyAlg, senstr, extstr);
1045*5051Swyllys 			} else if (kfmt == KMF_FORMAT_PEM ||
1046*5051Swyllys 			    kfmt == KMF_FORMAT_PEM_KEYPAIR) {
1047*5051Swyllys 				rv = pk_import_keys(kmfhandle,
1048*5051Swyllys 				    kstype, token_spec, &tokencred,
1049*5051Swyllys 				    filename, label, senstr, extstr);
1050*5051Swyllys 			} else {
1051*5051Swyllys 				rv = PK_ERR_USAGE;
1052*5051Swyllys 			}
10533089Swyllys 			break;
10543089Swyllys 		case KMF_KEYSTORE_NSS:
10553089Swyllys 			if (dir == NULL)
10563089Swyllys 				dir = PK_DEFAULT_DIRECTORY;
10573089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
10583089Swyllys 				rv = pk_import_pk12_nss(
1059*5051Swyllys 				    kmfhandle, &pk12cred,
1060*5051Swyllys 				    &tokencred,
1061*5051Swyllys 				    token_spec, dir, prefix,
1062*5051Swyllys 				    label, trustflags, filename);
10633089Swyllys 			else if (oclass == PK_CERT_OBJ) {
10643089Swyllys 				rv = pk_import_cert(
1065*5051Swyllys 				    kmfhandle, kstype,
1066*5051Swyllys 				    label, token_spec,
1067*5051Swyllys 				    filename, dir, prefix, trustflags);
10683089Swyllys 			} else if (oclass == PK_CRL_OBJ) {
10693089Swyllys 				rv = pk_import_nss_crl(
1070*5051Swyllys 				    kmfhandle, verify_crl_flag,
1071*5051Swyllys 				    filename, dir, prefix);
10723089Swyllys 			}
10733089Swyllys 			break;
10743089Swyllys 		case KMF_KEYSTORE_OPENSSL:
10753089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
10763089Swyllys 				rv = pk_import_pk12_files(
1077*5051Swyllys 				    kmfhandle, &pk12cred,
1078*5051Swyllys 				    filename, certfile, keyfile,
1079*5051Swyllys 				    dir, keydir, okfmt);
10803089Swyllys 			else if (oclass == PK_CRL_OBJ) {
10813089Swyllys 				rv = pk_import_file_crl(
1082*5051Swyllys 				    kmfhandle, filename,
1083*5051Swyllys 				    crlfile, dir, okfmt);
10843089Swyllys 			} else
10853089Swyllys 				/*
10863089Swyllys 				 * It doesn't make sense to import anything
10873089Swyllys 				 * else for the files plugin.
10883089Swyllys 				 */
10893089Swyllys 				return (PK_ERR_USAGE);
10903089Swyllys 			break;
10913089Swyllys 		default:
10923089Swyllys 			rv = PK_ERR_USAGE;
10933089Swyllys 			break;
10943089Swyllys 	}
109517Sdinak 
10963089Swyllys end:
10973089Swyllys 	if (rv != KMF_OK)
10983089Swyllys 		display_error(kmfhandle, rv,
1099*5051Swyllys 		    gettext("Error importing objects"));
11003089Swyllys 
11013089Swyllys 	if (tokencred.cred != NULL)
11023089Swyllys 		free(tokencred.cred);
11033089Swyllys 
11043089Swyllys 	if (pk12cred.cred != NULL)
11053089Swyllys 		free(pk12cred.cred);
11063089Swyllys 
1107*5051Swyllys 	(void) kmf_finalize(kmfhandle);
11083089Swyllys 
11093089Swyllys 	if (rv != KMF_OK)
11103089Swyllys 		return (PK_ERR_USAGE);
11113089Swyllys 
111217Sdinak 	return (0);
111317Sdinak }
1114