xref: /onnv-gate/usr/src/cmd/cmd-crypto/pktool/import.c (revision 5069:a114332ed71c)
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 /*
225051Swyllys  * 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;
595051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
605051Swyllys 	KMF_ATTRIBUTE attrlist[16];
615051Swyllys 	int numattr = 0;
6217Sdinak 
635051Swyllys 	rv = kmf_import_objects(kmfhandle, outfile, cred,
645051Swyllys 	    &certs, &ncerts, &keys, &nkeys);
6517Sdinak 
663089Swyllys 	if (rv == KMF_OK) {
673089Swyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
685051Swyllys 		    "key(s) in %s\n"), ncerts, nkeys, outfile);
6917Sdinak 	}
7017Sdinak 
713089Swyllys 	if (rv == KMF_OK && ncerts > 0) {
723089Swyllys 		char newcertfile[MAXPATHLEN];
733089Swyllys 
745051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
755051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
765051Swyllys 		numattr++;
775051Swyllys 
785051Swyllys 		if (dir != NULL) {
795051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
805051Swyllys 			    KMF_DIRPATH_ATTR, dir, strlen(dir));
815051Swyllys 			numattr++;
825051Swyllys 		}
835051Swyllys 
845051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
855051Swyllys 		    KMF_ENCODE_FORMAT_ATTR, &outformat, sizeof (outformat));
865051Swyllys 		numattr++;
873089Swyllys 
883089Swyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
895051Swyllys 			int num = numattr;
905051Swyllys 
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,
985051Swyllys 				    sizeof (newcertfile), "%s_%d", certfile, i);
995051Swyllys 
1005051Swyllys 				kmf_set_attr_at_index(attrlist, num,
1015051Swyllys 				    KMF_CERT_FILENAME_ATTR, newcertfile,
1025051Swyllys 				    strlen(newcertfile));
1035051Swyllys 				num++;
1043089Swyllys 			} else {
1055051Swyllys 				kmf_set_attr_at_index(attrlist, num,
1065051Swyllys 				    KMF_CERT_FILENAME_ATTR, certfile,
1075051Swyllys 				    strlen(certfile));
1085051Swyllys 				num++;
1093089Swyllys 			}
1105051Swyllys 
1115051Swyllys 			kmf_set_attr_at_index(attrlist, num,
1125051Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i], sizeof (KMF_DATA));
1135051Swyllys 			num++;
1145051Swyllys 			rv = kmf_store_cert(kmfhandle, num, attrlist);
1153089Swyllys 		}
1163089Swyllys 	}
1173089Swyllys 	if (rv == KMF_OK && nkeys > 0) {
1183089Swyllys 		char newkeyfile[MAXPATHLEN];
1193089Swyllys 
1205051Swyllys 		numattr = 0;
1215051Swyllys 
1225051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
1235051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
1245051Swyllys 		    sizeof (kstype));
1255051Swyllys 		numattr++;
1265051Swyllys 
1275051Swyllys 		if (keydir != NULL) {
1285051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1295051Swyllys 			    KMF_DIRPATH_ATTR, keydir,
1305051Swyllys 			    strlen(keydir));
1315051Swyllys 			numattr++;
1325051Swyllys 		}
1335051Swyllys 
1345051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
1355051Swyllys 		    KMF_ENCODE_FORMAT_ATTR, &outformat,
1365051Swyllys 		    sizeof (outformat));
1375051Swyllys 		numattr++;
1385051Swyllys 
1395051Swyllys 		if (cred != NULL && cred->credlen > 0) {
1405051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1415051Swyllys 			    KMF_CREDENTIAL_ATTR, cred,
1425051Swyllys 			    sizeof (KMF_CREDENTIAL));
1435051Swyllys 			numattr++;
1445051Swyllys 		}
14517Sdinak 
1463089Swyllys 		/* The order of certificates and keys should match */
1473089Swyllys 		for (i = 0; rv == KMF_OK && i < nkeys; i++) {
1485051Swyllys 			int num = numattr;
1493089Swyllys 
1503089Swyllys 			if (i > 0) {
1513089Swyllys 				(void) snprintf(newkeyfile,
1525051Swyllys 				    sizeof (newkeyfile), "%s_%d", keyfile, i);
1535051Swyllys 
1545051Swyllys 				kmf_set_attr_at_index(attrlist, num,
1555051Swyllys 				    KMF_KEY_FILENAME_ATTR, newkeyfile,
1565051Swyllys 				    strlen(newkeyfile));
1575051Swyllys 				num++;
1583089Swyllys 			} else {
1595051Swyllys 				kmf_set_attr_at_index(attrlist, num,
1605051Swyllys 				    KMF_KEY_FILENAME_ATTR, keyfile,
1615051Swyllys 				    strlen(keyfile));
1625051Swyllys 				num++;
1633089Swyllys 			}
16417Sdinak 
1655051Swyllys 			kmf_set_attr_at_index(attrlist, num,
1665051Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i],
1675051Swyllys 			    sizeof (KMF_DATA));
1685051Swyllys 			num++;
1695051Swyllys 
1705051Swyllys 			kmf_set_attr_at_index(attrlist, num,
1715051Swyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
1725051Swyllys 			    sizeof (KMF_RAW_KEY_DATA));
1735051Swyllys 			num++;
1745051Swyllys 
1755051Swyllys 			rv = kmf_store_key(kmfhandle, num, attrlist);
1763089Swyllys 		}
1773089Swyllys 	}
1783089Swyllys 	/*
1793089Swyllys 	 * Cleanup memory.
1803089Swyllys 	 */
1813089Swyllys 	if (certs) {
1823089Swyllys 		for (i = 0; i < ncerts; i++)
1835051Swyllys 			kmf_free_data(&certs[i]);
1843089Swyllys 		free(certs);
1853089Swyllys 	}
1863089Swyllys 	if (keys) {
1873089Swyllys 		for (i = 0; i < nkeys; i++)
1885051Swyllys 			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;
2105051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
2115051Swyllys 	KMF_ATTRIBUTE attrlist[16];
2125051Swyllys 	int numattr = 0;
2133089Swyllys 
2143089Swyllys 	rv = configure_nss(kmfhandle, dir, prefix);
2153089Swyllys 	if (rv != KMF_OK)
2163089Swyllys 		return (rv);
2173089Swyllys 
2185051Swyllys 	rv = kmf_import_objects(kmfhandle, filename, kmfcred,
2195051Swyllys 	    &certs, &ncerts, &keys, &nkeys);
2203089Swyllys 
2213089Swyllys 	if (rv == KMF_OK)
2223089Swyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
2235051Swyllys 		    "key(s) in %s\n"), ncerts, nkeys, filename);
22417Sdinak 
2253089Swyllys 	if (rv == KMF_OK) {
2265051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
2275051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
2285051Swyllys 		numattr++;
22917Sdinak 
2305051Swyllys 		if (token_spec != NULL) {
2315051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
2325051Swyllys 			    KMF_TOKEN_LABEL_ATTR, token_spec,
2335051Swyllys 			    strlen(token_spec));
2345051Swyllys 			numattr++;
2355051Swyllys 		}
2365051Swyllys 
2375051Swyllys 		if (trustflags != NULL) {
2385051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
2395051Swyllys 			    KMF_TRUSTFLAG_ATTR, trustflags,
2405051Swyllys 			    strlen(trustflags));
2415051Swyllys 			numattr++;
2425051Swyllys 		}
24317Sdinak 
2443089Swyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
2455051Swyllys 			int num = numattr;
24617Sdinak 
2475051Swyllys 			if (i == 0 && nickname != NULL) {
2485051Swyllys 				kmf_set_attr_at_index(attrlist, num,
2495051Swyllys 				    KMF_CERT_LABEL_ATTR, nickname,
2505051Swyllys 				    strlen(nickname));
2515051Swyllys 				num++;
2525051Swyllys 			}
2535051Swyllys 
2545051Swyllys 			kmf_set_attr_at_index(attrlist, num,
2555051Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i], sizeof (KMF_DATA));
2565051Swyllys 			num++;
2575051Swyllys 			rv = kmf_store_cert(kmfhandle, num, attrlist);
2583089Swyllys 		}
2593089Swyllys 		if (rv != KMF_OK) {
2603089Swyllys 			display_error(kmfhandle, rv,
2615051Swyllys 			    gettext("Error storing certificate in NSS token"));
2623089Swyllys 		}
26317Sdinak 	}
26417Sdinak 
2653089Swyllys 	if (rv == KMF_OK) {
2665051Swyllys 		numattr = 0;
2675051Swyllys 
2685051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
2695051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
2705051Swyllys 		    sizeof (kstype));
2715051Swyllys 		numattr++;
2725051Swyllys 
2735051Swyllys 		if (token_spec != NULL) {
2745051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
2755051Swyllys 			    KMF_TOKEN_LABEL_ATTR, token_spec,
2765051Swyllys 			    strlen(token_spec));
2775051Swyllys 			numattr++;
2785051Swyllys 		}
2795051Swyllys 
2805051Swyllys 		if (nickname != NULL) {
2815051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
2825051Swyllys 			    KMF_KEYLABEL_ATTR, nickname,
2835051Swyllys 			    strlen(nickname));
2845051Swyllys 			numattr++;
2855051Swyllys 		}
2865051Swyllys 
2875051Swyllys 		if (tokencred->credlen > 0) {
2885051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
2895051Swyllys 			    KMF_CREDENTIAL_ATTR, tokencred,
2905051Swyllys 			    sizeof (KMF_CREDENTIAL));
2915051Swyllys 			numattr++;
2925051Swyllys 		}
2933089Swyllys 
2943089Swyllys 		/* The order of certificates and keys should match */
2953089Swyllys 		for (i = 0; i < nkeys; i++) {
2965051Swyllys 			int num = numattr;
2975051Swyllys 
2985051Swyllys 			kmf_set_attr_at_index(attrlist, num,
2995051Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i],
3005051Swyllys 			    sizeof (KMF_DATA));
3015051Swyllys 			num++;
3023089Swyllys 
3035051Swyllys 			kmf_set_attr_at_index(attrlist, num,
3045051Swyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
3055051Swyllys 			    sizeof (KMF_RAW_KEY_DATA));
3065051Swyllys 			num++;
3075051Swyllys 
3085051Swyllys 			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++)
3175051Swyllys 			kmf_free_data(&certs[i]);
3183089Swyllys 		free(certs);
3193089Swyllys 	}
3203089Swyllys 	if (keys) {
3213089Swyllys 		for (i = 0; i < nkeys; i++)
3225051Swyllys 			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;
3375051Swyllys 	KMF_ATTRIBUTE attrlist[32];
3385051Swyllys 	int i = 0;
33917Sdinak 
3403089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
3413089Swyllys 		rv = select_token(kmfhandle, token_spec, FALSE);
3425051Swyllys 	} else if (kstype == KMF_KEYSTORE_NSS) {
3435051Swyllys 		rv = configure_nss(kmfhandle, dir, prefix);
3445051Swyllys 	}
3455051Swyllys 	if (rv != KMF_OK)
3465051Swyllys 		return (rv);
34717Sdinak 
3485051Swyllys 	kmf_set_attr_at_index(attrlist, i,
3495051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (KMF_KEYSTORE_TYPE));
3505051Swyllys 	i++;
3515051Swyllys 
3525051Swyllys 	kmf_set_attr_at_index(attrlist, i, KMF_CERT_FILENAME_ATTR,
3535051Swyllys 	    filename, strlen(filename));
3545051Swyllys 	i++;
3555051Swyllys 
3565051Swyllys 	if (label != NULL) {
3575051Swyllys 		kmf_set_attr_at_index(attrlist, i, KMF_CERT_LABEL_ATTR,
3585051Swyllys 		    label, strlen(label));
3595051Swyllys 		i++;
3605051Swyllys 	}
3615051Swyllys 
3625051Swyllys 	if (kstype == KMF_KEYSTORE_NSS) {
3635051Swyllys 		if (trustflags != NULL) {
3645051Swyllys 			kmf_set_attr_at_index(attrlist, i, KMF_TRUSTFLAG_ATTR,
3655051Swyllys 			    trustflags, strlen(trustflags));
3665051Swyllys 			i++;
3675051Swyllys 		}
3685051Swyllys 
3695051Swyllys 		if (token_spec != NULL) {
3705051Swyllys 			kmf_set_attr_at_index(attrlist, i,
3715051Swyllys 			    KMF_TOKEN_LABEL_ATTR,
3725051Swyllys 			    token_spec, strlen(token_spec));
3735051Swyllys 			i++;
37417Sdinak 		}
3753089Swyllys 	}
37617Sdinak 
3775051Swyllys 	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 {
3885051Swyllys 	int numattr = 0;
3895051Swyllys 	KMF_ATTRIBUTE attrlist[8];
3905051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
3913089Swyllys 
3925051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
3935051Swyllys 	    &kstype, sizeof (kstype));
3945051Swyllys 	numattr++;
3955051Swyllys 	if (infile) {
3965051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
3975051Swyllys 		    KMF_CRL_FILENAME_ATTR, infile, strlen(infile));
3985051Swyllys 		numattr++;
3995051Swyllys 	}
4005051Swyllys 	if (outdir) {
4015051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
4025051Swyllys 		    KMF_DIRPATH_ATTR, outdir, strlen(outdir));
4035051Swyllys 		numattr++;
4045051Swyllys 	}
4055051Swyllys 	if (outfile) {
4065051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
4075051Swyllys 		    KMF_CRL_OUTFILE_ATTR, outfile, strlen(outfile));
4085051Swyllys 		numattr++;
4095051Swyllys 	}
4105051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
4115051Swyllys 	    KMF_ENCODE_FORMAT_ATTR, &outfmt, sizeof (outfmt));
4125051Swyllys 	numattr++;
4133089Swyllys 
4145051Swyllys 	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;
4255051Swyllys 	int numattr = 0;
4265051Swyllys 	KMF_ATTRIBUTE attrlist[4];
4275051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
4283089Swyllys 
4293089Swyllys 	rv = configure_nss(kmfhandle, outdir, prefix);
4303089Swyllys 	if (rv != KMF_OK)
4313089Swyllys 		return (rv);
4323089Swyllys 
4335051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
4345051Swyllys 	    &kstype, sizeof (kstype));
4355051Swyllys 	numattr++;
4365051Swyllys 	if (infile) {
4375051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR,
4385051Swyllys 		    infile, strlen(infile));
4395051Swyllys 		numattr++;
4405051Swyllys 	}
4415051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_CHECK_ATTR,
4425051Swyllys 	    &verify_crl_flag, sizeof (verify_crl_flag));
4435051Swyllys 	numattr++;
4443089Swyllys 
4455051Swyllys 	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;
4635051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
4645051Swyllys 	KMF_ATTRIBUTE attrlist[16];
4655051Swyllys 	int numattr = 0;
4663089Swyllys 
4673089Swyllys 	rv = select_token(kmfhandle, token_spec, FALSE);
4683089Swyllys 
4693089Swyllys 	if (rv != KMF_OK) {
47017Sdinak 		return (rv);
47117Sdinak 	}
47217Sdinak 
4735051Swyllys 	rv = kmf_import_objects(kmfhandle, filename, p12cred,
4745051Swyllys 	    &certs, &ncerts, &keys, &nkeys);
4753089Swyllys 
4763089Swyllys 	if (rv == KMF_OK) {
4775051Swyllys 
4785051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
4795051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
4805051Swyllys 		    sizeof (kstype));
4815051Swyllys 		numattr++;
4825051Swyllys 
4835051Swyllys 		if (label != NULL) {
4845051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
4855051Swyllys 			    KMF_KEYLABEL_ATTR, label,
4865051Swyllys 			    strlen(label));
4875051Swyllys 			numattr++;
4885051Swyllys 		}
4895051Swyllys 
4905051Swyllys 		if (tokencred != NULL && tokencred->credlen > 0) {
4915051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
4925051Swyllys 			    KMF_CREDENTIAL_ATTR, tokencred,
4935051Swyllys 			    sizeof (KMF_CREDENTIAL));
4945051Swyllys 			numattr++;
4955051Swyllys 		}
4963089Swyllys 
4973089Swyllys 		/* The order of certificates and keys should match */
4983089Swyllys 		for (i = 0; i < nkeys; i++) {
4995051Swyllys 			int num = numattr;
5005051Swyllys 
5015051Swyllys 			kmf_set_attr_at_index(attrlist, num,
5025051Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i],
5035051Swyllys 			    sizeof (KMF_DATA));
5045051Swyllys 			num++;
5053089Swyllys 
5065051Swyllys 			kmf_set_attr_at_index(attrlist, num,
5075051Swyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
5085051Swyllys 			    sizeof (KMF_RAW_KEY_DATA));
5095051Swyllys 			num++;
5105051Swyllys 
5115051Swyllys 			rv = kmf_store_key(kmfhandle, num, attrlist);
5125051Swyllys 
5133089Swyllys 		}
5143089Swyllys 	}
5153089Swyllys 
5163089Swyllys 	if (rv == KMF_OK) {
5173089Swyllys 
5183089Swyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
5195051Swyllys 		    "key(s) in %s\n"), ncerts, nkeys, filename);
5205051Swyllys 		numattr = 0;
5215051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
5225051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
5235051Swyllys 		numattr++;
5243089Swyllys 
5253089Swyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
5265051Swyllys 			int num = numattr;
5273089Swyllys 
5285051Swyllys 			if (i == 0 && label != NULL) {
5295051Swyllys 				kmf_set_attr_at_index(attrlist, num,
5305051Swyllys 				    KMF_CERT_LABEL_ATTR, label, strlen(label));
5315051Swyllys 				num++;
5325051Swyllys 			}
5335051Swyllys 
5345051Swyllys 			kmf_set_attr_at_index(attrlist, num,
5355051Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i], sizeof (KMF_DATA));
5365051Swyllys 			num++;
5375051Swyllys 
5385051Swyllys 			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++)
5475051Swyllys 			kmf_free_data(&certs[i]);
5483089Swyllys 		free(certs);
5493089Swyllys 	}
5503089Swyllys 	if (keys) {
5513089Swyllys 		for (i = 0; i < nkeys; i++)
5525051Swyllys 			kmf_free_raw_key(&keys[i]);
5533089Swyllys 		free(keys);
5543089Swyllys 	}
5553089Swyllys 
5563089Swyllys 	return (rv);
55717Sdinak }
55817Sdinak 
559*5069Swyllys /*ARGSUSED*/
5605051Swyllys static KMF_RETURN
5615051Swyllys pk_import_keys(KMF_HANDLE_T kmfhandle,
5625051Swyllys 	KMF_KEYSTORE_TYPE kstype, char *token_spec,
5635051Swyllys 	KMF_CREDENTIAL *cred, char *filename,
5645051Swyllys 	char *label, char *senstr, char *extstr)
5655051Swyllys {
5665051Swyllys 	KMF_RETURN rv = KMF_OK;
5675051Swyllys 	KMF_ATTRIBUTE attrlist[16];
5685051Swyllys 	KMF_KEYSTORE_TYPE fileks = KMF_KEYSTORE_OPENSSL;
5695051Swyllys 	int numattr = 0;
5705051Swyllys 	KMF_KEY_HANDLE key;
5715051Swyllys 	KMF_RAW_KEY_DATA rawkey;
5725051Swyllys 	KMF_KEY_CLASS class = KMF_ASYM_PRI;
5735051Swyllys 	int numkeys = 1;
5745051Swyllys 
5755051Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
5765051Swyllys 		rv = select_token(kmfhandle, token_spec, FALSE);
5775051Swyllys 	}
5785051Swyllys 	if (rv != KMF_OK)
5795051Swyllys 		return (rv);
5805051Swyllys 	/*
5815051Swyllys 	 * First, set up to read the keyfile using the FILE plugin
5825051Swyllys 	 * mechanisms.
5835051Swyllys 	 */
5845051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
5855051Swyllys 	    &fileks, sizeof (fileks));
5865051Swyllys 	numattr++;
5875051Swyllys 
5885051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
5895051Swyllys 	    &numkeys, sizeof (numkeys));
5905051Swyllys 	numattr++;
5915051Swyllys 
5925051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
5935051Swyllys 	    &key, sizeof (key));
5945051Swyllys 	numattr++;
5955051Swyllys 
5965051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR,
5975051Swyllys 	    &rawkey, sizeof (rawkey));
5985051Swyllys 	numattr++;
5995051Swyllys 
6005051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
6015051Swyllys 	    &class, sizeof (class));
6025051Swyllys 	numattr++;
6035051Swyllys 
6045051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
6055051Swyllys 	    filename, strlen(filename));
6065051Swyllys 	numattr++;
6075051Swyllys 
6085051Swyllys 	rv = kmf_find_key(kmfhandle, numattr, attrlist);
6095051Swyllys 	if (rv == KMF_OK) {
6105051Swyllys 		numattr = 0;
6115051Swyllys 
6125051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
6135051Swyllys 		    &kstype, sizeof (kstype));
6145051Swyllys 		numattr++;
6155051Swyllys 
6165051Swyllys 		if (cred != NULL && cred->credlen > 0) {
6175051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
6185051Swyllys 			    KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
6195051Swyllys 			numattr++;
6205051Swyllys 		}
6215051Swyllys 
6225051Swyllys 		if (label != NULL) {
6235051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
6245051Swyllys 			    KMF_KEYLABEL_ATTR, label, strlen(label));
6255051Swyllys 			numattr++;
6265051Swyllys 		}
6275051Swyllys 
6285051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
6295051Swyllys 		    KMF_RAW_KEY_ATTR, &rawkey, sizeof (rawkey));
6305051Swyllys 		numattr++;
6315051Swyllys 
6325051Swyllys 		rv = kmf_store_key(kmfhandle, numattr, attrlist);
6335051Swyllys 		if (rv == KMF_OK) {
634*5069Swyllys 			(void) printf(gettext("Importing %d keys\n"), numkeys);
6355051Swyllys 		}
6365051Swyllys 
6375051Swyllys 		kmf_free_kmf_key(kmfhandle, &key);
6385051Swyllys 		kmf_free_raw_key(&rawkey);
6395051Swyllys 	} else {
6405051Swyllys 		cryptoerror(LOG_STDERR,
6415051Swyllys 		    gettext("Failed to load key from file (%s)\n"),
6425051Swyllys 		    filename);
6435051Swyllys 	}
6445051Swyllys 	return (rv);
6455051Swyllys }
6465051Swyllys 
6475051Swyllys static KMF_RETURN
6485051Swyllys pk_import_rawkey(KMF_HANDLE_T kmfhandle,
6495051Swyllys 	KMF_KEYSTORE_TYPE kstype, char *token,
6505051Swyllys 	KMF_CREDENTIAL *cred,
6515051Swyllys 	char *filename, char *label, KMF_KEY_ALG keyAlg,
6525051Swyllys 	char *senstr, char *extstr)
6535051Swyllys {
6545051Swyllys 	KMF_RETURN rv = KMF_OK;
6555051Swyllys 	KMF_ATTRIBUTE attrlist[16];
6565051Swyllys 	int numattr = 0;
6575051Swyllys 	uint32_t keylen;
6585051Swyllys 	boolean_t sensitive = B_FALSE;
6595051Swyllys 	boolean_t not_extractable = B_FALSE;
6605051Swyllys 	KMF_DATA keydata = {NULL, 0};
6615051Swyllys 	KMF_KEY_HANDLE rawkey;
6625051Swyllys 
6635051Swyllys 	rv = kmf_read_input_file(kmfhandle, filename, &keydata);
6645051Swyllys 	if (rv != KMF_OK)
6655051Swyllys 		return (rv);
6665051Swyllys 
6675051Swyllys 	rv = select_token(kmfhandle, token, FALSE);
6685051Swyllys 
6695051Swyllys 	if (rv != KMF_OK) {
6705051Swyllys 		return (rv);
6715051Swyllys 	}
6725051Swyllys 	if (senstr != NULL) {
6735051Swyllys 		if (tolower(senstr[0]) == 'y')
6745051Swyllys 			sensitive = B_TRUE;
6755051Swyllys 		else if (tolower(senstr[0]) == 'n')
6765051Swyllys 			sensitive = B_FALSE;
6775051Swyllys 		else {
6785051Swyllys 			cryptoerror(LOG_STDERR,
6795051Swyllys 			    gettext("Incorrect sensitive option value.\n"));
6805051Swyllys 			return (KMF_ERR_BAD_PARAMETER);
6815051Swyllys 		}
6825051Swyllys 	}
6835051Swyllys 
6845051Swyllys 	if (extstr != NULL) {
6855051Swyllys 		if (tolower(extstr[0]) == 'y')
6865051Swyllys 			not_extractable = B_FALSE;
6875051Swyllys 		else if (tolower(extstr[0]) == 'n')
6885051Swyllys 			not_extractable = B_TRUE;
6895051Swyllys 		else {
6905051Swyllys 			cryptoerror(LOG_STDERR,
6915051Swyllys 			    gettext("Incorrect extractable option value.\n"));
6925051Swyllys 			return (KMF_ERR_BAD_PARAMETER);
6935051Swyllys 		}
6945051Swyllys 	}
6955051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
6965051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
6975051Swyllys 	numattr++;
6985051Swyllys 
6995051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7005051Swyllys 	    KMF_KEY_HANDLE_ATTR, &rawkey, sizeof (rawkey));
7015051Swyllys 	numattr++;
7025051Swyllys 
7035051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7045051Swyllys 	    KMF_KEYALG_ATTR, &keyAlg, sizeof (KMF_KEY_ALG));
7055051Swyllys 	numattr++;
7065051Swyllys 
7075051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7085051Swyllys 	    KMF_KEY_DATA_ATTR, keydata.Data, keydata.Length);
7095051Swyllys 	numattr++;
7105051Swyllys 
7115051Swyllys 	/* Key length is given in bits not bytes */
7125051Swyllys 	keylen = keydata.Length * 8;
7135051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7145051Swyllys 	    KMF_KEYLENGTH_ATTR, &keylen, sizeof (keydata.Length));
7155051Swyllys 	numattr++;
7165051Swyllys 
7175051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7185051Swyllys 	    KMF_SENSITIVE_BOOL_ATTR, &sensitive, sizeof (sensitive));
7195051Swyllys 	numattr++;
7205051Swyllys 
7215051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7225051Swyllys 	    KMF_NON_EXTRACTABLE_BOOL_ATTR, &not_extractable,
7235051Swyllys 	    sizeof (not_extractable));
7245051Swyllys 	numattr++;
7255051Swyllys 
7265051Swyllys 	if (label != NULL) {
7275051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
7285051Swyllys 		    KMF_KEYLABEL_ATTR, label, strlen(label));
7295051Swyllys 		numattr++;
7305051Swyllys 	}
7315051Swyllys 	if (cred != NULL && cred->credlen > 0) {
7325051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
7335051Swyllys 		    KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
7345051Swyllys 		numattr++;
7355051Swyllys 	}
7365051Swyllys 	rv = kmf_create_sym_key(kmfhandle, numattr, attrlist);
7375051Swyllys 
7385051Swyllys 	return (rv);
7395051Swyllys }
7405051Swyllys 
74117Sdinak /*
7423089Swyllys  * Import objects from into KMF repositories.
74317Sdinak  */
74417Sdinak int
74517Sdinak pk_import(int argc, char *argv[])
74617Sdinak {
747864Sdinak 	int		opt;
748864Sdinak 	extern int	optind_av;
749864Sdinak 	extern char	*optarg_av;
750864Sdinak 	char		*token_spec = NULL;
75117Sdinak 	char		*filename = NULL;
7523089Swyllys 	char		*keyfile = NULL;
7533089Swyllys 	char		*certfile = NULL;
7543089Swyllys 	char		*crlfile = NULL;
7555051Swyllys 	char		*label = NULL;
7563089Swyllys 	char		*dir = NULL;
7573089Swyllys 	char		*keydir = NULL;
7583089Swyllys 	char		*prefix = NULL;
7593089Swyllys 	char		*trustflags = NULL;
7603089Swyllys 	char		*verify_crl = NULL;
7615051Swyllys 	char		*keytype = "generic";
7625051Swyllys 	char		*senstr = NULL;
7635051Swyllys 	char		*extstr = NULL;
7643089Swyllys 	boolean_t	verify_crl_flag = B_FALSE;
7653089Swyllys 	int		oclass = 0;
7663089Swyllys 	KMF_KEYSTORE_TYPE	kstype = 0;
7673089Swyllys 	KMF_ENCODE_FORMAT	kfmt = 0;
7683089Swyllys 	KMF_ENCODE_FORMAT	okfmt = KMF_FORMAT_ASN1;
7693089Swyllys 	KMF_RETURN		rv = KMF_OK;
7703089Swyllys 	KMF_CREDENTIAL	pk12cred = { NULL, 0 };
7713089Swyllys 	KMF_CREDENTIAL	tokencred = { NULL, 0 };
7723089Swyllys 	KMF_HANDLE_T	kmfhandle = NULL;
7735051Swyllys 	KMF_KEY_ALG	keyAlg = KMF_GENERIC_SECRET;
77417Sdinak 
775864Sdinak 	/* Parse command line options.  Do NOT i18n/l10n. */
7763089Swyllys 	while ((opt = getopt_av(argc, argv,
7775051Swyllys 	    "T:(token)i:(infile)"
7785051Swyllys 	    "k:(keystore)y:(objtype)"
7795051Swyllys 	    "d:(dir)p:(prefix)"
7805051Swyllys 	    "n:(certlabel)N:(label)"
7815051Swyllys 	    "K:(outkey)c:(outcert)"
7825051Swyllys 	    "v:(verifycrl)l:(outcrl)"
7835051Swyllys 	    "E:(keytype)s:(sensitive)x:(extractable)"
7845051Swyllys 	    "t:(trust)D:(keydir)F:(outformat)")) != EOF) {
7853089Swyllys 		if (EMPTYSTRING(optarg_av))
7863089Swyllys 			return (PK_ERR_USAGE);
787864Sdinak 		switch (opt) {
788864Sdinak 		case 'T':	/* token specifier */
789864Sdinak 			if (token_spec)
790864Sdinak 				return (PK_ERR_USAGE);
791864Sdinak 			token_spec = optarg_av;
792864Sdinak 			break;
7933089Swyllys 		case 'c':	/* output cert file name */
7943089Swyllys 			if (certfile)
7953089Swyllys 				return (PK_ERR_USAGE);
7963089Swyllys 			certfile = optarg_av;
7973089Swyllys 			break;
7983089Swyllys 		case 'l':	/* output CRL file name */
7993089Swyllys 			if (crlfile)
8003089Swyllys 				return (PK_ERR_USAGE);
8013089Swyllys 			crlfile = optarg_av;
8023089Swyllys 			break;
8033089Swyllys 		case 'K':	/* output key file name */
8043089Swyllys 			if (keyfile)
8053089Swyllys 				return (PK_ERR_USAGE);
8063089Swyllys 			keyfile = optarg_av;
8073089Swyllys 			break;
808864Sdinak 		case 'i':	/* input file name */
809864Sdinak 			if (filename)
810864Sdinak 				return (PK_ERR_USAGE);
811864Sdinak 			filename = optarg_av;
812864Sdinak 			break;
8133089Swyllys 		case 'k':
8143089Swyllys 			kstype = KS2Int(optarg_av);
8153089Swyllys 			if (kstype == 0)
8163089Swyllys 				return (PK_ERR_USAGE);
8173089Swyllys 			break;
8183089Swyllys 		case 'y':
8193089Swyllys 			oclass = OT2Int(optarg_av);
8203089Swyllys 			if (oclass == -1)
8213089Swyllys 				return (PK_ERR_USAGE);
8223089Swyllys 			break;
8233089Swyllys 		case 'd':
8243089Swyllys 			dir = optarg_av;
8253089Swyllys 			break;
8263089Swyllys 		case 'D':
8273089Swyllys 			keydir = optarg_av;
8283089Swyllys 			break;
8293089Swyllys 		case 'p':
8303089Swyllys 			if (prefix)
8313089Swyllys 				return (PK_ERR_USAGE);
8323089Swyllys 			prefix = optarg_av;
8333089Swyllys 			break;
8343089Swyllys 		case 'n':
8353089Swyllys 		case 'N':
8365051Swyllys 			if (label)
8373089Swyllys 				return (PK_ERR_USAGE);
8385051Swyllys 			label = optarg_av;
8393089Swyllys 			break;
8403089Swyllys 		case 'F':
8413089Swyllys 			okfmt = Str2Format(optarg_av);
8423089Swyllys 			if (okfmt == KMF_FORMAT_UNDEF)
8433089Swyllys 				return (PK_ERR_USAGE);
8443089Swyllys 			break;
8453089Swyllys 		case 't':
8463089Swyllys 			if (trustflags)
8473089Swyllys 				return (PK_ERR_USAGE);
8483089Swyllys 			trustflags = optarg_av;
8493089Swyllys 			break;
8503089Swyllys 		case 'v':
8513089Swyllys 			verify_crl = optarg_av;
8523089Swyllys 			if (tolower(verify_crl[0]) == 'y')
8533089Swyllys 				verify_crl_flag = B_TRUE;
8543089Swyllys 			else if (tolower(verify_crl[0]) == 'n')
8553089Swyllys 				verify_crl_flag = B_FALSE;
8563089Swyllys 			else
8573089Swyllys 				return (PK_ERR_USAGE);
8583089Swyllys 			break;
8595051Swyllys 		case 'E':
8605051Swyllys 			keytype = optarg_av;
8615051Swyllys 			break;
8625051Swyllys 		case 's':
8635051Swyllys 			if (senstr)
8645051Swyllys 				return (PK_ERR_USAGE);
8655051Swyllys 			senstr = optarg_av;
8665051Swyllys 			break;
8675051Swyllys 		case 'x':
8685051Swyllys 			if (extstr)
8695051Swyllys 				return (PK_ERR_USAGE);
8705051Swyllys 			extstr = optarg_av;
8715051Swyllys 			break;
872864Sdinak 		default:
873864Sdinak 			return (PK_ERR_USAGE);
874864Sdinak 			break;
875864Sdinak 		}
876864Sdinak 	}
87717Sdinak 
8783089Swyllys 	/* Assume keystore = PKCS#11 if not specified */
8793089Swyllys 	if (kstype == 0)
8803089Swyllys 		kstype = KMF_KEYSTORE_PK11TOKEN;
881864Sdinak 
882864Sdinak 	/* Filename arg is required. */
8833089Swyllys 	if (EMPTYSTRING(filename)) {
8843089Swyllys 		cryptoerror(LOG_STDERR, gettext("The 'infile' parameter"
8855051Swyllys 		    "is required for the import operation.\n"));
88617Sdinak 		return (PK_ERR_USAGE);
8873089Swyllys 	}
88817Sdinak 
889864Sdinak 	/* No additional args allowed. */
890864Sdinak 	argc -= optind_av;
891864Sdinak 	argv += optind_av;
892864Sdinak 	if (argc)
893864Sdinak 		return (PK_ERR_USAGE);
89417Sdinak 
8953089Swyllys 	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
8963089Swyllys 	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
8975051Swyllys 	    kstype != KMF_KEYSTORE_PK11TOKEN) {
8983089Swyllys 
8993089Swyllys 		(void) fprintf(stderr, gettext("The objtype parameter "
9005051Swyllys 		    "is only relevant if keystore=pkcs11\n"));
9013089Swyllys 		return (PK_ERR_USAGE);
90217Sdinak 	}
90317Sdinak 
9043089Swyllys 	/*
9053089Swyllys 	 * You must specify a certlabel (cert label) when importing
9063089Swyllys 	 * into NSS or PKCS#11.
9073089Swyllys 	 */
9083089Swyllys 	if (kstype == KMF_KEYSTORE_NSS &&
9095051Swyllys 	    (oclass != PK_CRL_OBJ) && EMPTYSTRING(label)) {
9103089Swyllys 		cryptoerror(LOG_STDERR, gettext("The 'label' argument "
9115051Swyllys 		    "is required for this operation\n"));
9123089Swyllys 		return (PK_ERR_USAGE);
91317Sdinak 	}
91417Sdinak 
9155051Swyllys 	if ((rv = kmf_get_file_format(filename, &kfmt)) != KMF_OK) {
9165051Swyllys 		/*
9175051Swyllys 		 * Allow for raw key data to be imported.
9185051Swyllys 		 */
9195051Swyllys 		if (rv == KMF_ERR_ENCODING) {
9205051Swyllys 			rv = KMF_OK;
9215051Swyllys 			kfmt = KMF_FORMAT_RAWKEY;
9225051Swyllys 			/*
9235051Swyllys 			 * Set the object class only if it was not
9245051Swyllys 			 * given on the command line or if it was
9255051Swyllys 			 * specified as a symmetric key object.
9265051Swyllys 			 */
9275051Swyllys 			if (oclass == 0 || (oclass & PK_SYMKEY_OBJ)) {
9285051Swyllys 				oclass = PK_SYMKEY_OBJ;
9295051Swyllys 			} else {
9305051Swyllys 				cryptoerror(LOG_STDERR, gettext(
9315051Swyllys 				    "The input file does not contain the "
9325051Swyllys 				    "object type indicated on command "
9335051Swyllys 				    "line."));
9345051Swyllys 				return (KMF_ERR_BAD_PARAMETER);
9355051Swyllys 			}
9365051Swyllys 		} else {
9375051Swyllys 			cryptoerror(LOG_STDERR,
9385051Swyllys 			    gettext("File format not recognized."));
9395051Swyllys 			return (rv);
9405051Swyllys 		}
9415051Swyllys 	}
9425051Swyllys 
9435051Swyllys 	/* Check parameters for raw key import operation */
9445051Swyllys 	if (kfmt == KMF_FORMAT_RAWKEY) {
9455051Swyllys 		if (keytype != NULL &&
9465051Swyllys 		    Str2SymKeyType(keytype, &keyAlg) != 0) {
9475051Swyllys 			cryptoerror(LOG_STDERR,
9485051Swyllys 			    gettext("Unrecognized keytype(%s).\n"), keytype);
9495051Swyllys 			return (PK_ERR_USAGE);
9505051Swyllys 		}
9515051Swyllys 		if (senstr != NULL && extstr != NULL &&
9525051Swyllys 		    kstype != KMF_KEYSTORE_PK11TOKEN) {
9535051Swyllys 			cryptoerror(LOG_STDERR,
9545051Swyllys 			    gettext("The sensitive or extractable option "
9555051Swyllys 			    "applies only when importing a key from a file "
9565051Swyllys 			    "into a PKCS#11 keystore.\n"));
9573089Swyllys 			return (PK_ERR_USAGE);
9583089Swyllys 		}
95917Sdinak 	}
96017Sdinak 
9615051Swyllys 	/* If no objtype was given, treat it as a certificate */
9623089Swyllys 	if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 ||
9635051Swyllys 	    kfmt == KMF_FORMAT_PEM))
9643089Swyllys 		oclass = PK_CERT_OBJ;
96517Sdinak 
9663089Swyllys 	if (kstype == KMF_KEYSTORE_NSS) {
9673089Swyllys 		if (oclass == PK_CRL_OBJ &&
9685051Swyllys 		    (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
9693089Swyllys 			cryptoerror(LOG_STDERR, gettext(
9705051Swyllys 			    "CRL data can only be imported as DER or "
9715051Swyllys 			    "PEM format"));
9723089Swyllys 			return (PK_ERR_USAGE);
9733089Swyllys 		}
9743089Swyllys 
9753089Swyllys 		if (oclass == PK_CERT_OBJ &&
9765051Swyllys 		    (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
9773089Swyllys 			cryptoerror(LOG_STDERR, gettext(
9785051Swyllys 			    "Certificates can only be imported as DER or "
9795051Swyllys 			    "PEM format"));
9803089Swyllys 			return (PK_ERR_USAGE);
9813089Swyllys 		}
9823089Swyllys 
9833089Swyllys 		/* we do not import private keys except in PKCS12 bundles */
9843089Swyllys 		if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) {
9853089Swyllys 			cryptoerror(LOG_STDERR, gettext(
9865051Swyllys 			    "Private key data can only be imported as part "
9875051Swyllys 			    "of a PKCS12 file.\n"));
9883089Swyllys 			return (PK_ERR_USAGE);
9893089Swyllys 		}
99017Sdinak 	}
99117Sdinak 
9923089Swyllys 	if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) {
9933089Swyllys 		if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) {
99417Sdinak 			cryptoerror(LOG_STDERR, gettext(
9955051Swyllys 			    "The 'outkey' and 'outcert' parameters "
9965051Swyllys 			    "are required for the import operation "
9975051Swyllys 			    "when the 'file' keystore is used.\n"));
9983089Swyllys 			return (PK_ERR_USAGE);
99917Sdinak 		}
100017Sdinak 	}
100117Sdinak 
10023089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec))
10033089Swyllys 		token_spec = PK_DEFAULT_PK11TOKEN;
10043089Swyllys 	else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec))
10053089Swyllys 		token_spec = DEFAULT_NSS_TOKEN;
10063089Swyllys 
10073089Swyllys 	if (kfmt == KMF_FORMAT_PKCS12) {
10083089Swyllys 		(void) get_pk12_password(&pk12cred);
10093089Swyllys 	}
10103089Swyllys 
10115051Swyllys 	if ((kfmt == KMF_FORMAT_PKCS12 || kfmt == KMF_FORMAT_RAWKEY ||
10125051Swyllys 	    (kfmt == KMF_FORMAT_PEM && (oclass & PK_KEY_OBJ))) &&
10135051Swyllys 	    (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)) {
10145051Swyllys 		(void) get_token_password(kstype, token_spec, &tokencred);
10155051Swyllys 	}
10165051Swyllys 
10175051Swyllys 	if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
10183089Swyllys 		cryptoerror(LOG_STDERR, gettext("Error initializing "
10195051Swyllys 		    "KMF: 0x%02x\n"), rv);
10203089Swyllys 		goto end;
10213089Swyllys 	}
102217Sdinak 
10233089Swyllys 	switch (kstype) {
10243089Swyllys 		case KMF_KEYSTORE_PK11TOKEN:
10253089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
10263089Swyllys 				rv = pk_import_pk12_pk11(
10275051Swyllys 				    kmfhandle, &pk12cred,
10285051Swyllys 				    &tokencred, label,
10295051Swyllys 				    token_spec, filename);
10303089Swyllys 			else if (oclass == PK_CERT_OBJ)
10313089Swyllys 				rv = pk_import_cert(
10325051Swyllys 				    kmfhandle, kstype,
10335051Swyllys 				    label, token_spec,
10345051Swyllys 				    filename,
10355051Swyllys 				    NULL, NULL, NULL);
10363089Swyllys 			else if (oclass == PK_CRL_OBJ)
10373089Swyllys 				rv = pk_import_file_crl(
10385051Swyllys 				    kmfhandle, filename,
10395051Swyllys 				    crlfile, dir, okfmt);
10405051Swyllys 			else if (kfmt == KMF_FORMAT_RAWKEY &&
10415051Swyllys 			    oclass == PK_SYMKEY_OBJ) {
10425051Swyllys 				rv = pk_import_rawkey(kmfhandle,
10435051Swyllys 				    kstype, token_spec, &tokencred,
10445051Swyllys 				    filename, label,
10455051Swyllys 				    keyAlg, senstr, extstr);
10465051Swyllys 			} else if (kfmt == KMF_FORMAT_PEM ||
10475051Swyllys 			    kfmt == KMF_FORMAT_PEM_KEYPAIR) {
10485051Swyllys 				rv = pk_import_keys(kmfhandle,
10495051Swyllys 				    kstype, token_spec, &tokencred,
10505051Swyllys 				    filename, label, senstr, extstr);
10515051Swyllys 			} else {
10525051Swyllys 				rv = PK_ERR_USAGE;
10535051Swyllys 			}
10543089Swyllys 			break;
10553089Swyllys 		case KMF_KEYSTORE_NSS:
10563089Swyllys 			if (dir == NULL)
10573089Swyllys 				dir = PK_DEFAULT_DIRECTORY;
10583089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
10593089Swyllys 				rv = pk_import_pk12_nss(
10605051Swyllys 				    kmfhandle, &pk12cred,
10615051Swyllys 				    &tokencred,
10625051Swyllys 				    token_spec, dir, prefix,
10635051Swyllys 				    label, trustflags, filename);
10643089Swyllys 			else if (oclass == PK_CERT_OBJ) {
10653089Swyllys 				rv = pk_import_cert(
10665051Swyllys 				    kmfhandle, kstype,
10675051Swyllys 				    label, token_spec,
10685051Swyllys 				    filename, dir, prefix, trustflags);
10693089Swyllys 			} else if (oclass == PK_CRL_OBJ) {
10703089Swyllys 				rv = pk_import_nss_crl(
10715051Swyllys 				    kmfhandle, verify_crl_flag,
10725051Swyllys 				    filename, dir, prefix);
10733089Swyllys 			}
10743089Swyllys 			break;
10753089Swyllys 		case KMF_KEYSTORE_OPENSSL:
10763089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
10773089Swyllys 				rv = pk_import_pk12_files(
10785051Swyllys 				    kmfhandle, &pk12cred,
10795051Swyllys 				    filename, certfile, keyfile,
10805051Swyllys 				    dir, keydir, okfmt);
10813089Swyllys 			else if (oclass == PK_CRL_OBJ) {
10823089Swyllys 				rv = pk_import_file_crl(
10835051Swyllys 				    kmfhandle, filename,
10845051Swyllys 				    crlfile, dir, okfmt);
10853089Swyllys 			} else
10863089Swyllys 				/*
10873089Swyllys 				 * It doesn't make sense to import anything
10883089Swyllys 				 * else for the files plugin.
10893089Swyllys 				 */
10903089Swyllys 				return (PK_ERR_USAGE);
10913089Swyllys 			break;
10923089Swyllys 		default:
10933089Swyllys 			rv = PK_ERR_USAGE;
10943089Swyllys 			break;
10953089Swyllys 	}
109617Sdinak 
10973089Swyllys end:
10983089Swyllys 	if (rv != KMF_OK)
10993089Swyllys 		display_error(kmfhandle, rv,
11005051Swyllys 		    gettext("Error importing objects"));
11013089Swyllys 
11023089Swyllys 	if (tokencred.cred != NULL)
11033089Swyllys 		free(tokencred.cred);
11043089Swyllys 
11053089Swyllys 	if (pk12cred.cred != NULL)
11063089Swyllys 		free(pk12cred.cred);
11073089Swyllys 
11085051Swyllys 	(void) kmf_finalize(kmfhandle);
11093089Swyllys 
11103089Swyllys 	if (rv != KMF_OK)
11113089Swyllys 		return (PK_ERR_USAGE);
11123089Swyllys 
111317Sdinak 	return (0);
111417Sdinak }
1115