xref: /onnv-gate/usr/src/cmd/cmd-crypto/pktool/import.c (revision 5536:865d075cefb7)
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 
48*5536Swyllys #define	NEW_ATTRLIST(a, n) \
49*5536Swyllys { \
50*5536Swyllys 	a = (KMF_ATTRIBUTE *)malloc(n * sizeof (KMF_ATTRIBUTE)); \
51*5536Swyllys 	if (a == NULL) { \
52*5536Swyllys 		rv = KMF_ERR_MEMORY; \
53*5536Swyllys 		goto end; \
54*5536Swyllys 	} \
55*5536Swyllys 	(void) memset(a, 0, n * sizeof (KMF_ATTRIBUTE));  \
56*5536Swyllys }
57*5536Swyllys 
583089Swyllys static KMF_RETURN
593089Swyllys pk_import_pk12_files(KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *cred,
603089Swyllys 	char *outfile, char *certfile, char *keyfile,
613089Swyllys 	char *dir, char *keydir, KMF_ENCODE_FORMAT outformat)
6217Sdinak {
633089Swyllys 	KMF_RETURN rv = KMF_OK;
64*5536Swyllys 	KMF_X509_DER_CERT *certs = NULL;
653089Swyllys 	KMF_RAW_KEY_DATA *keys = NULL;
663089Swyllys 	int ncerts = 0;
673089Swyllys 	int nkeys = 0;
683089Swyllys 	int i;
695051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
70*5536Swyllys 	KMF_ATTRIBUTE *attrlist = NULL;
715051Swyllys 	int numattr = 0;
7217Sdinak 
735051Swyllys 	rv = kmf_import_objects(kmfhandle, outfile, cred,
745051Swyllys 	    &certs, &ncerts, &keys, &nkeys);
7517Sdinak 
763089Swyllys 	if (rv == KMF_OK) {
773089Swyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
785051Swyllys 		    "key(s) in %s\n"), ncerts, nkeys, outfile);
7917Sdinak 	}
8017Sdinak 
813089Swyllys 	if (rv == KMF_OK && ncerts > 0) {
823089Swyllys 		char newcertfile[MAXPATHLEN];
833089Swyllys 
84*5536Swyllys 		NEW_ATTRLIST(attrlist,  (3 + (3 * ncerts)));
85*5536Swyllys 
865051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
875051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
885051Swyllys 		numattr++;
895051Swyllys 
905051Swyllys 		if (dir != NULL) {
915051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
925051Swyllys 			    KMF_DIRPATH_ATTR, dir, strlen(dir));
935051Swyllys 			numattr++;
945051Swyllys 		}
955051Swyllys 
965051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
975051Swyllys 		    KMF_ENCODE_FORMAT_ATTR, &outformat, sizeof (outformat));
985051Swyllys 		numattr++;
993089Swyllys 
1003089Swyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
1015051Swyllys 			int num = numattr;
1025051Swyllys 
1033089Swyllys 			/*
1043089Swyllys 			 * If storing more than 1 cert, gotta change
1053089Swyllys 			 * the name so we don't overwrite the previous one.
1063089Swyllys 			 * Just append a _# to the name.
1073089Swyllys 			 */
1083089Swyllys 			if (i > 0) {
1093089Swyllys 				(void) snprintf(newcertfile,
1105051Swyllys 				    sizeof (newcertfile), "%s_%d", certfile, i);
1115051Swyllys 
1125051Swyllys 				kmf_set_attr_at_index(attrlist, num,
1135051Swyllys 				    KMF_CERT_FILENAME_ATTR, newcertfile,
1145051Swyllys 				    strlen(newcertfile));
1155051Swyllys 				num++;
1163089Swyllys 			} else {
1175051Swyllys 				kmf_set_attr_at_index(attrlist, num,
1185051Swyllys 				    KMF_CERT_FILENAME_ATTR, certfile,
1195051Swyllys 				    strlen(certfile));
1205051Swyllys 				num++;
1213089Swyllys 			}
1225051Swyllys 
123*5536Swyllys 			if (certs[i].kmf_private.label != NULL) {
124*5536Swyllys 				kmf_set_attr_at_index(attrlist, num,
125*5536Swyllys 				    KMF_CERT_LABEL_ATTR,
126*5536Swyllys 				    certs[i].kmf_private.label,
127*5536Swyllys 				    strlen(certs[i].kmf_private.label));
128*5536Swyllys 				num++;
129*5536Swyllys 			}
1305051Swyllys 			kmf_set_attr_at_index(attrlist, num,
131*5536Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i].certificate,
132*5536Swyllys 			    sizeof (KMF_DATA));
1335051Swyllys 			num++;
1345051Swyllys 			rv = kmf_store_cert(kmfhandle, num, attrlist);
1353089Swyllys 		}
136*5536Swyllys 		free(attrlist);
1373089Swyllys 	}
1383089Swyllys 	if (rv == KMF_OK && nkeys > 0) {
1393089Swyllys 		char newkeyfile[MAXPATHLEN];
1405051Swyllys 		numattr = 0;
141*5536Swyllys 		NEW_ATTRLIST(attrlist, (4 + (4 * nkeys)));
1425051Swyllys 
1435051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
1445051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
1455051Swyllys 		    sizeof (kstype));
1465051Swyllys 		numattr++;
1475051Swyllys 
1485051Swyllys 		if (keydir != NULL) {
1495051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1505051Swyllys 			    KMF_DIRPATH_ATTR, keydir,
1515051Swyllys 			    strlen(keydir));
1525051Swyllys 			numattr++;
1535051Swyllys 		}
1545051Swyllys 
1555051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
1565051Swyllys 		    KMF_ENCODE_FORMAT_ATTR, &outformat,
1575051Swyllys 		    sizeof (outformat));
1585051Swyllys 		numattr++;
1595051Swyllys 
1605051Swyllys 		if (cred != NULL && cred->credlen > 0) {
1615051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1625051Swyllys 			    KMF_CREDENTIAL_ATTR, cred,
1635051Swyllys 			    sizeof (KMF_CREDENTIAL));
1645051Swyllys 			numattr++;
1655051Swyllys 		}
16617Sdinak 
1673089Swyllys 		/* The order of certificates and keys should match */
1683089Swyllys 		for (i = 0; rv == KMF_OK && i < nkeys; i++) {
1695051Swyllys 			int num = numattr;
1703089Swyllys 
1713089Swyllys 			if (i > 0) {
1723089Swyllys 				(void) snprintf(newkeyfile,
1735051Swyllys 				    sizeof (newkeyfile), "%s_%d", keyfile, i);
1745051Swyllys 
1755051Swyllys 				kmf_set_attr_at_index(attrlist, num,
1765051Swyllys 				    KMF_KEY_FILENAME_ATTR, newkeyfile,
1775051Swyllys 				    strlen(newkeyfile));
1785051Swyllys 				num++;
1793089Swyllys 			} else {
1805051Swyllys 				kmf_set_attr_at_index(attrlist, num,
1815051Swyllys 				    KMF_KEY_FILENAME_ATTR, keyfile,
1825051Swyllys 				    strlen(keyfile));
1835051Swyllys 				num++;
1843089Swyllys 			}
18517Sdinak 
186*5536Swyllys 			if (i < ncerts) {
187*5536Swyllys 				kmf_set_attr_at_index(attrlist, num,
188*5536Swyllys 				    KMF_CERT_DATA_ATTR, &certs[i],
189*5536Swyllys 				    sizeof (KMF_CERT_DATA_ATTR));
190*5536Swyllys 				num++;
191*5536Swyllys 			}
1925051Swyllys 
1935051Swyllys 			kmf_set_attr_at_index(attrlist, num,
1945051Swyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
1955051Swyllys 			    sizeof (KMF_RAW_KEY_DATA));
1965051Swyllys 			num++;
1975051Swyllys 
1985051Swyllys 			rv = kmf_store_key(kmfhandle, num, attrlist);
1993089Swyllys 		}
200*5536Swyllys 		free(attrlist);
2013089Swyllys 	}
202*5536Swyllys end:
2033089Swyllys 	/*
2043089Swyllys 	 * Cleanup memory.
2053089Swyllys 	 */
2063089Swyllys 	if (certs) {
2073089Swyllys 		for (i = 0; i < ncerts; i++)
208*5536Swyllys 			kmf_free_kmf_cert(kmfhandle, &certs[i]);
2093089Swyllys 		free(certs);
2103089Swyllys 	}
2113089Swyllys 	if (keys) {
2123089Swyllys 		for (i = 0; i < nkeys; i++)
2135051Swyllys 			kmf_free_raw_key(&keys[i]);
2143089Swyllys 		free(keys);
21517Sdinak 	}
21617Sdinak 
21717Sdinak 
2183089Swyllys 	return (rv);
21917Sdinak }
22017Sdinak 
2213089Swyllys 
2223089Swyllys static KMF_RETURN
2233089Swyllys pk_import_pk12_nss(
2243089Swyllys 	KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *kmfcred,
2253089Swyllys 	KMF_CREDENTIAL *tokencred,
2263089Swyllys 	char *token_spec, char *dir, char *prefix,
2273089Swyllys 	char *nickname, char *trustflags, char *filename)
22817Sdinak {
2293089Swyllys 	KMF_RETURN rv = KMF_OK;
230*5536Swyllys 	KMF_X509_DER_CERT *certs = NULL;
2313089Swyllys 	KMF_RAW_KEY_DATA *keys = NULL;
2323089Swyllys 	int ncerts = 0;
2333089Swyllys 	int nkeys = 0;
2343089Swyllys 	int i;
2355051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
236*5536Swyllys 	KMF_ATTRIBUTE *attrlist = NULL;
2375051Swyllys 	int numattr = 0;
2383089Swyllys 
2393089Swyllys 	rv = configure_nss(kmfhandle, dir, prefix);
2403089Swyllys 	if (rv != KMF_OK)
2413089Swyllys 		return (rv);
2423089Swyllys 
2435051Swyllys 	rv = kmf_import_objects(kmfhandle, filename, kmfcred,
2445051Swyllys 	    &certs, &ncerts, &keys, &nkeys);
2453089Swyllys 
2463089Swyllys 	if (rv == KMF_OK)
2473089Swyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
2485051Swyllys 		    "key(s) in %s\n"), ncerts, nkeys, filename);
24917Sdinak 
2503089Swyllys 	if (rv == KMF_OK) {
251*5536Swyllys 		NEW_ATTRLIST(attrlist, (3 + (2 * ncerts)));
252*5536Swyllys 
2535051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
2545051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
2555051Swyllys 		numattr++;
25617Sdinak 
2575051Swyllys 		if (token_spec != NULL) {
2585051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
2595051Swyllys 			    KMF_TOKEN_LABEL_ATTR, token_spec,
2605051Swyllys 			    strlen(token_spec));
2615051Swyllys 			numattr++;
2625051Swyllys 		}
2635051Swyllys 
2645051Swyllys 		if (trustflags != NULL) {
2655051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
2665051Swyllys 			    KMF_TRUSTFLAG_ATTR, trustflags,
2675051Swyllys 			    strlen(trustflags));
2685051Swyllys 			numattr++;
2695051Swyllys 		}
27017Sdinak 
2713089Swyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
2725051Swyllys 			int num = numattr;
27317Sdinak 
274*5536Swyllys 			if (certs[i].kmf_private.label != NULL) {
275*5536Swyllys 				kmf_set_attr_at_index(attrlist, num,
276*5536Swyllys 				    KMF_CERT_LABEL_ATTR,
277*5536Swyllys 				    certs[i].kmf_private.label,
278*5536Swyllys 				    strlen(certs[i].kmf_private.label));
279*5536Swyllys 				num++;
280*5536Swyllys 			} else if (i == 0 && nickname != NULL) {
2815051Swyllys 				kmf_set_attr_at_index(attrlist, num,
2825051Swyllys 				    KMF_CERT_LABEL_ATTR, nickname,
2835051Swyllys 				    strlen(nickname));
2845051Swyllys 				num++;
2855051Swyllys 			}
2865051Swyllys 
2875051Swyllys 			kmf_set_attr_at_index(attrlist, num,
288*5536Swyllys 			    KMF_CERT_DATA_ATTR,
289*5536Swyllys 			    &certs[i].certificate, sizeof (KMF_DATA));
2905051Swyllys 			num++;
2915051Swyllys 			rv = kmf_store_cert(kmfhandle, num, attrlist);
2923089Swyllys 		}
293*5536Swyllys 		free(attrlist);
294*5536Swyllys 		attrlist = NULL;
2953089Swyllys 		if (rv != KMF_OK) {
2963089Swyllys 			display_error(kmfhandle, rv,
2975051Swyllys 			    gettext("Error storing certificate in NSS token"));
2983089Swyllys 		}
29917Sdinak 	}
30017Sdinak 
3013089Swyllys 	if (rv == KMF_OK) {
3025051Swyllys 		numattr = 0;
303*5536Swyllys 		NEW_ATTRLIST(attrlist, (4 + (2 * nkeys)));
3045051Swyllys 
3055051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
3065051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
3075051Swyllys 		    sizeof (kstype));
3085051Swyllys 		numattr++;
3095051Swyllys 
3105051Swyllys 		if (token_spec != NULL) {
3115051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3125051Swyllys 			    KMF_TOKEN_LABEL_ATTR, token_spec,
3135051Swyllys 			    strlen(token_spec));
3145051Swyllys 			numattr++;
3155051Swyllys 		}
3165051Swyllys 
3175051Swyllys 		if (nickname != NULL) {
3185051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3195051Swyllys 			    KMF_KEYLABEL_ATTR, nickname,
3205051Swyllys 			    strlen(nickname));
3215051Swyllys 			numattr++;
3225051Swyllys 		}
3235051Swyllys 
3245051Swyllys 		if (tokencred->credlen > 0) {
3255051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3265051Swyllys 			    KMF_CREDENTIAL_ATTR, tokencred,
3275051Swyllys 			    sizeof (KMF_CREDENTIAL));
3285051Swyllys 			numattr++;
3295051Swyllys 		}
3303089Swyllys 
3313089Swyllys 		/* The order of certificates and keys should match */
3323089Swyllys 		for (i = 0; i < nkeys; i++) {
3335051Swyllys 			int num = numattr;
3345051Swyllys 
335*5536Swyllys 			if (i < ncerts) {
336*5536Swyllys 				kmf_set_attr_at_index(attrlist, num,
337*5536Swyllys 				    KMF_CERT_DATA_ATTR, &certs[i],
338*5536Swyllys 				    sizeof (KMF_DATA));
339*5536Swyllys 				num++;
340*5536Swyllys 			}
3413089Swyllys 
3425051Swyllys 			kmf_set_attr_at_index(attrlist, num,
3435051Swyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
3445051Swyllys 			    sizeof (KMF_RAW_KEY_DATA));
3455051Swyllys 			num++;
3465051Swyllys 
3475051Swyllys 			rv = kmf_store_key(kmfhandle, num, attrlist);
3483089Swyllys 		}
349*5536Swyllys 		free(attrlist);
3503089Swyllys 	}
3513089Swyllys 
352*5536Swyllys end:
3533089Swyllys 	/*
3543089Swyllys 	 * Cleanup memory.
3553089Swyllys 	 */
3563089Swyllys 	if (certs) {
3573089Swyllys 		for (i = 0; i < ncerts; i++)
358*5536Swyllys 			kmf_free_kmf_cert(kmfhandle, &certs[i]);
3593089Swyllys 		free(certs);
3603089Swyllys 	}
3613089Swyllys 	if (keys) {
3623089Swyllys 		for (i = 0; i < nkeys; i++)
3635051Swyllys 			kmf_free_raw_key(&keys[i]);
3643089Swyllys 		free(keys);
36517Sdinak 	}
36617Sdinak 
3673089Swyllys 	return (rv);
3683089Swyllys }
36917Sdinak 
3703089Swyllys static KMF_RETURN
3713089Swyllys pk_import_cert(
3723089Swyllys 	KMF_HANDLE_T kmfhandle,
3733089Swyllys 	KMF_KEYSTORE_TYPE kstype,
3743089Swyllys 	char *label, char *token_spec, char *filename,
3753089Swyllys 	char *dir, char *prefix, char *trustflags)
3763089Swyllys {
3773089Swyllys 	KMF_RETURN rv = KMF_OK;
3785051Swyllys 	KMF_ATTRIBUTE attrlist[32];
3795051Swyllys 	int i = 0;
38017Sdinak 
3813089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
3823089Swyllys 		rv = select_token(kmfhandle, token_spec, FALSE);
3835051Swyllys 	} else if (kstype == KMF_KEYSTORE_NSS) {
3845051Swyllys 		rv = configure_nss(kmfhandle, dir, prefix);
3855051Swyllys 	}
3865051Swyllys 	if (rv != KMF_OK)
3875051Swyllys 		return (rv);
38817Sdinak 
3895051Swyllys 	kmf_set_attr_at_index(attrlist, i,
3905051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (KMF_KEYSTORE_TYPE));
3915051Swyllys 	i++;
3925051Swyllys 
3935051Swyllys 	kmf_set_attr_at_index(attrlist, i, KMF_CERT_FILENAME_ATTR,
3945051Swyllys 	    filename, strlen(filename));
3955051Swyllys 	i++;
3965051Swyllys 
3975051Swyllys 	if (label != NULL) {
3985051Swyllys 		kmf_set_attr_at_index(attrlist, i, KMF_CERT_LABEL_ATTR,
3995051Swyllys 		    label, strlen(label));
4005051Swyllys 		i++;
4015051Swyllys 	}
4025051Swyllys 
4035051Swyllys 	if (kstype == KMF_KEYSTORE_NSS) {
4045051Swyllys 		if (trustflags != NULL) {
4055051Swyllys 			kmf_set_attr_at_index(attrlist, i, KMF_TRUSTFLAG_ATTR,
4065051Swyllys 			    trustflags, strlen(trustflags));
4075051Swyllys 			i++;
4085051Swyllys 		}
4095051Swyllys 
4105051Swyllys 		if (token_spec != NULL) {
4115051Swyllys 			kmf_set_attr_at_index(attrlist, i,
4125051Swyllys 			    KMF_TOKEN_LABEL_ATTR,
4135051Swyllys 			    token_spec, strlen(token_spec));
4145051Swyllys 			i++;
41517Sdinak 		}
4163089Swyllys 	}
41717Sdinak 
4185051Swyllys 	rv = kmf_import_cert(kmfhandle, i, attrlist);
4193089Swyllys 	return (rv);
4203089Swyllys }
4213089Swyllys 
4223089Swyllys static KMF_RETURN
4233089Swyllys pk_import_file_crl(void *kmfhandle,
4243089Swyllys 	char *infile,
4253089Swyllys 	char *outfile,
4263089Swyllys 	char *outdir,
4273089Swyllys 	KMF_ENCODE_FORMAT outfmt)
4283089Swyllys {
4295051Swyllys 	int numattr = 0;
4305051Swyllys 	KMF_ATTRIBUTE attrlist[8];
4315051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
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,
4385051Swyllys 		    KMF_CRL_FILENAME_ATTR, infile, strlen(infile));
4395051Swyllys 		numattr++;
4405051Swyllys 	}
4415051Swyllys 	if (outdir) {
4425051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
4435051Swyllys 		    KMF_DIRPATH_ATTR, outdir, strlen(outdir));
4445051Swyllys 		numattr++;
4455051Swyllys 	}
4465051Swyllys 	if (outfile) {
4475051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
4485051Swyllys 		    KMF_CRL_OUTFILE_ATTR, outfile, strlen(outfile));
4495051Swyllys 		numattr++;
4505051Swyllys 	}
4515051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
4525051Swyllys 	    KMF_ENCODE_FORMAT_ATTR, &outfmt, sizeof (outfmt));
4535051Swyllys 	numattr++;
4543089Swyllys 
4555051Swyllys 	return (kmf_import_crl(kmfhandle, numattr, attrlist));
4563089Swyllys }
4573089Swyllys 
4583089Swyllys static KMF_RETURN
4593089Swyllys pk_import_nss_crl(void *kmfhandle,
4603089Swyllys 	boolean_t verify_crl_flag,
4613089Swyllys 	char *infile,
4623089Swyllys 	char *outdir,
4633089Swyllys 	char *prefix)
4643089Swyllys {
4653089Swyllys 	KMF_RETURN rv;
4665051Swyllys 	int numattr = 0;
4675051Swyllys 	KMF_ATTRIBUTE attrlist[4];
4685051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
4693089Swyllys 
4703089Swyllys 	rv = configure_nss(kmfhandle, outdir, prefix);
4713089Swyllys 	if (rv != KMF_OK)
4723089Swyllys 		return (rv);
4733089Swyllys 
4745051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
4755051Swyllys 	    &kstype, sizeof (kstype));
4765051Swyllys 	numattr++;
4775051Swyllys 	if (infile) {
4785051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR,
4795051Swyllys 		    infile, strlen(infile));
4805051Swyllys 		numattr++;
4815051Swyllys 	}
4825051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_CHECK_ATTR,
4835051Swyllys 	    &verify_crl_flag, sizeof (verify_crl_flag));
4845051Swyllys 	numattr++;
4853089Swyllys 
4865051Swyllys 	return (kmf_import_crl(kmfhandle, numattr, attrlist));
4873089Swyllys 
4883089Swyllys }
4893089Swyllys 
4903089Swyllys static KMF_RETURN
4913089Swyllys pk_import_pk12_pk11(
4923089Swyllys 	KMF_HANDLE_T kmfhandle,
4933089Swyllys 	KMF_CREDENTIAL *p12cred,
4943089Swyllys 	KMF_CREDENTIAL *tokencred,
4953089Swyllys 	char *label, char *token_spec,
4963089Swyllys 	char *filename)
4973089Swyllys {
4983089Swyllys 	KMF_RETURN rv = KMF_OK;
499*5536Swyllys 	KMF_X509_DER_CERT *certs = NULL;
5003089Swyllys 	KMF_RAW_KEY_DATA *keys = NULL;
5013089Swyllys 	int ncerts = 0;
5023089Swyllys 	int nkeys = 0;
5033089Swyllys 	int i;
5045051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
505*5536Swyllys 	KMF_ATTRIBUTE *attrlist = NULL;
5065051Swyllys 	int numattr = 0;
5073089Swyllys 
5083089Swyllys 	rv = select_token(kmfhandle, token_spec, FALSE);
5093089Swyllys 
5103089Swyllys 	if (rv != KMF_OK) {
51117Sdinak 		return (rv);
51217Sdinak 	}
51317Sdinak 
5145051Swyllys 	rv = kmf_import_objects(kmfhandle, filename, p12cred,
5155051Swyllys 	    &certs, &ncerts, &keys, &nkeys);
5163089Swyllys 
5173089Swyllys 	if (rv == KMF_OK) {
518*5536Swyllys 		NEW_ATTRLIST(attrlist, (3 + (2 * nkeys)));
5195051Swyllys 
5205051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
5215051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
5225051Swyllys 		    sizeof (kstype));
5235051Swyllys 		numattr++;
5245051Swyllys 
5255051Swyllys 		if (label != NULL) {
5265051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
5275051Swyllys 			    KMF_KEYLABEL_ATTR, label,
5285051Swyllys 			    strlen(label));
5295051Swyllys 			numattr++;
5305051Swyllys 		}
5315051Swyllys 
5325051Swyllys 		if (tokencred != NULL && tokencred->credlen > 0) {
5335051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
5345051Swyllys 			    KMF_CREDENTIAL_ATTR, tokencred,
5355051Swyllys 			    sizeof (KMF_CREDENTIAL));
5365051Swyllys 			numattr++;
5375051Swyllys 		}
5383089Swyllys 
5393089Swyllys 		/* The order of certificates and keys should match */
5403089Swyllys 		for (i = 0; i < nkeys; i++) {
5415051Swyllys 			int num = numattr;
5425051Swyllys 
543*5536Swyllys 			if (i < ncerts) {
544*5536Swyllys 				kmf_set_attr_at_index(attrlist, num,
545*5536Swyllys 				    KMF_CERT_DATA_ATTR, &certs[i].certificate,
546*5536Swyllys 				    sizeof (KMF_DATA));
547*5536Swyllys 				num++;
548*5536Swyllys 			}
5493089Swyllys 
5505051Swyllys 			kmf_set_attr_at_index(attrlist, num,
5515051Swyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
5525051Swyllys 			    sizeof (KMF_RAW_KEY_DATA));
5535051Swyllys 			num++;
5545051Swyllys 
5555051Swyllys 			rv = kmf_store_key(kmfhandle, num, attrlist);
5565051Swyllys 
5573089Swyllys 		}
558*5536Swyllys 		free(attrlist);
5593089Swyllys 	}
5603089Swyllys 
5613089Swyllys 	if (rv == KMF_OK) {
562*5536Swyllys 		numattr = 0;
563*5536Swyllys 		NEW_ATTRLIST(attrlist, (1 + (2 * ncerts)));
5643089Swyllys 
5653089Swyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
5665051Swyllys 		    "key(s) in %s\n"), ncerts, nkeys, filename);
567*5536Swyllys 
5685051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
5695051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
5705051Swyllys 		numattr++;
5713089Swyllys 
5723089Swyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
5735051Swyllys 			int num = numattr;
574*5536Swyllys 			if (certs[i].kmf_private.label != NULL) {
575*5536Swyllys 				kmf_set_attr_at_index(attrlist, num,
576*5536Swyllys 				    KMF_CERT_LABEL_ATTR,
577*5536Swyllys 				    certs[i].kmf_private.label,
578*5536Swyllys 				    strlen(certs[i].kmf_private.label));
579*5536Swyllys 				num++;
580*5536Swyllys 			} else if (i == 0 && label != NULL) {
5815051Swyllys 				kmf_set_attr_at_index(attrlist, num,
5825051Swyllys 				    KMF_CERT_LABEL_ATTR, label, strlen(label));
5835051Swyllys 				num++;
5845051Swyllys 			}
5855051Swyllys 
5865051Swyllys 			kmf_set_attr_at_index(attrlist, num,
587*5536Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i].certificate,
588*5536Swyllys 			    sizeof (KMF_DATA));
5895051Swyllys 			num++;
5905051Swyllys 
5915051Swyllys 			rv = kmf_store_cert(kmfhandle, num, attrlist);
5923089Swyllys 		}
593*5536Swyllys 		free(attrlist);
5943089Swyllys 	}
5953089Swyllys 
596*5536Swyllys end:
5973089Swyllys 	/*
5983089Swyllys 	 * Cleanup memory.
5993089Swyllys 	 */
6003089Swyllys 	if (certs) {
6013089Swyllys 		for (i = 0; i < ncerts; i++)
602*5536Swyllys 			kmf_free_kmf_cert(kmfhandle, &certs[i]);
6033089Swyllys 		free(certs);
6043089Swyllys 	}
6053089Swyllys 	if (keys) {
6063089Swyllys 		for (i = 0; i < nkeys; i++)
6075051Swyllys 			kmf_free_raw_key(&keys[i]);
6083089Swyllys 		free(keys);
6093089Swyllys 	}
6103089Swyllys 
6113089Swyllys 	return (rv);
61217Sdinak }
61317Sdinak 
6145069Swyllys /*ARGSUSED*/
6155051Swyllys static KMF_RETURN
6165051Swyllys pk_import_keys(KMF_HANDLE_T kmfhandle,
6175051Swyllys 	KMF_KEYSTORE_TYPE kstype, char *token_spec,
6185051Swyllys 	KMF_CREDENTIAL *cred, char *filename,
6195051Swyllys 	char *label, char *senstr, char *extstr)
6205051Swyllys {
6215051Swyllys 	KMF_RETURN rv = KMF_OK;
6225051Swyllys 	KMF_ATTRIBUTE attrlist[16];
6235051Swyllys 	KMF_KEYSTORE_TYPE fileks = KMF_KEYSTORE_OPENSSL;
6245051Swyllys 	int numattr = 0;
6255051Swyllys 	KMF_KEY_HANDLE key;
6265051Swyllys 	KMF_RAW_KEY_DATA rawkey;
6275051Swyllys 	KMF_KEY_CLASS class = KMF_ASYM_PRI;
6285051Swyllys 	int numkeys = 1;
6295051Swyllys 
6305051Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
6315051Swyllys 		rv = select_token(kmfhandle, token_spec, FALSE);
6325051Swyllys 	}
6335051Swyllys 	if (rv != KMF_OK)
6345051Swyllys 		return (rv);
6355051Swyllys 	/*
6365051Swyllys 	 * First, set up to read the keyfile using the FILE plugin
6375051Swyllys 	 * mechanisms.
6385051Swyllys 	 */
6395051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
6405051Swyllys 	    &fileks, sizeof (fileks));
6415051Swyllys 	numattr++;
6425051Swyllys 
6435051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
6445051Swyllys 	    &numkeys, sizeof (numkeys));
6455051Swyllys 	numattr++;
6465051Swyllys 
6475051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
6485051Swyllys 	    &key, sizeof (key));
6495051Swyllys 	numattr++;
6505051Swyllys 
6515051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR,
6525051Swyllys 	    &rawkey, sizeof (rawkey));
6535051Swyllys 	numattr++;
6545051Swyllys 
6555051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
6565051Swyllys 	    &class, sizeof (class));
6575051Swyllys 	numattr++;
6585051Swyllys 
6595051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
6605051Swyllys 	    filename, strlen(filename));
6615051Swyllys 	numattr++;
6625051Swyllys 
6635051Swyllys 	rv = kmf_find_key(kmfhandle, numattr, attrlist);
6645051Swyllys 	if (rv == KMF_OK) {
6655051Swyllys 		numattr = 0;
6665051Swyllys 
6675051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
6685051Swyllys 		    &kstype, sizeof (kstype));
6695051Swyllys 		numattr++;
6705051Swyllys 
6715051Swyllys 		if (cred != NULL && cred->credlen > 0) {
6725051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
6735051Swyllys 			    KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
6745051Swyllys 			numattr++;
6755051Swyllys 		}
6765051Swyllys 
6775051Swyllys 		if (label != NULL) {
6785051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
6795051Swyllys 			    KMF_KEYLABEL_ATTR, label, strlen(label));
6805051Swyllys 			numattr++;
6815051Swyllys 		}
6825051Swyllys 
6835051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
6845051Swyllys 		    KMF_RAW_KEY_ATTR, &rawkey, sizeof (rawkey));
6855051Swyllys 		numattr++;
6865051Swyllys 
6875051Swyllys 		rv = kmf_store_key(kmfhandle, numattr, attrlist);
6885051Swyllys 		if (rv == KMF_OK) {
6895069Swyllys 			(void) printf(gettext("Importing %d keys\n"), numkeys);
6905051Swyllys 		}
6915051Swyllys 
6925051Swyllys 		kmf_free_kmf_key(kmfhandle, &key);
6935051Swyllys 		kmf_free_raw_key(&rawkey);
6945051Swyllys 	} else {
6955051Swyllys 		cryptoerror(LOG_STDERR,
6965051Swyllys 		    gettext("Failed to load key from file (%s)\n"),
6975051Swyllys 		    filename);
6985051Swyllys 	}
6995051Swyllys 	return (rv);
7005051Swyllys }
7015051Swyllys 
7025051Swyllys static KMF_RETURN
7035051Swyllys pk_import_rawkey(KMF_HANDLE_T kmfhandle,
7045051Swyllys 	KMF_KEYSTORE_TYPE kstype, char *token,
7055051Swyllys 	KMF_CREDENTIAL *cred,
7065051Swyllys 	char *filename, char *label, KMF_KEY_ALG keyAlg,
7075051Swyllys 	char *senstr, char *extstr)
7085051Swyllys {
7095051Swyllys 	KMF_RETURN rv = KMF_OK;
7105051Swyllys 	KMF_ATTRIBUTE attrlist[16];
7115051Swyllys 	int numattr = 0;
7125051Swyllys 	uint32_t keylen;
7135051Swyllys 	boolean_t sensitive = B_FALSE;
7145051Swyllys 	boolean_t not_extractable = B_FALSE;
7155051Swyllys 	KMF_DATA keydata = {NULL, 0};
7165051Swyllys 	KMF_KEY_HANDLE rawkey;
7175051Swyllys 
7185051Swyllys 	rv = kmf_read_input_file(kmfhandle, filename, &keydata);
7195051Swyllys 	if (rv != KMF_OK)
7205051Swyllys 		return (rv);
7215051Swyllys 
7225051Swyllys 	rv = select_token(kmfhandle, token, FALSE);
7235051Swyllys 
7245051Swyllys 	if (rv != KMF_OK) {
7255051Swyllys 		return (rv);
7265051Swyllys 	}
7275051Swyllys 	if (senstr != NULL) {
7285051Swyllys 		if (tolower(senstr[0]) == 'y')
7295051Swyllys 			sensitive = B_TRUE;
7305051Swyllys 		else if (tolower(senstr[0]) == 'n')
7315051Swyllys 			sensitive = B_FALSE;
7325051Swyllys 		else {
7335051Swyllys 			cryptoerror(LOG_STDERR,
7345051Swyllys 			    gettext("Incorrect sensitive option value.\n"));
7355051Swyllys 			return (KMF_ERR_BAD_PARAMETER);
7365051Swyllys 		}
7375051Swyllys 	}
7385051Swyllys 
7395051Swyllys 	if (extstr != NULL) {
7405051Swyllys 		if (tolower(extstr[0]) == 'y')
7415051Swyllys 			not_extractable = B_FALSE;
7425051Swyllys 		else if (tolower(extstr[0]) == 'n')
7435051Swyllys 			not_extractable = B_TRUE;
7445051Swyllys 		else {
7455051Swyllys 			cryptoerror(LOG_STDERR,
7465051Swyllys 			    gettext("Incorrect extractable option value.\n"));
7475051Swyllys 			return (KMF_ERR_BAD_PARAMETER);
7485051Swyllys 		}
7495051Swyllys 	}
7505051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7515051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
7525051Swyllys 	numattr++;
7535051Swyllys 
7545051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7555051Swyllys 	    KMF_KEY_HANDLE_ATTR, &rawkey, sizeof (rawkey));
7565051Swyllys 	numattr++;
7575051Swyllys 
7585051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7595051Swyllys 	    KMF_KEYALG_ATTR, &keyAlg, sizeof (KMF_KEY_ALG));
7605051Swyllys 	numattr++;
7615051Swyllys 
7625051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7635051Swyllys 	    KMF_KEY_DATA_ATTR, keydata.Data, keydata.Length);
7645051Swyllys 	numattr++;
7655051Swyllys 
7665051Swyllys 	/* Key length is given in bits not bytes */
7675051Swyllys 	keylen = keydata.Length * 8;
7685051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7695051Swyllys 	    KMF_KEYLENGTH_ATTR, &keylen, sizeof (keydata.Length));
7705051Swyllys 	numattr++;
7715051Swyllys 
7725051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7735051Swyllys 	    KMF_SENSITIVE_BOOL_ATTR, &sensitive, sizeof (sensitive));
7745051Swyllys 	numattr++;
7755051Swyllys 
7765051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7775051Swyllys 	    KMF_NON_EXTRACTABLE_BOOL_ATTR, &not_extractable,
7785051Swyllys 	    sizeof (not_extractable));
7795051Swyllys 	numattr++;
7805051Swyllys 
7815051Swyllys 	if (label != NULL) {
7825051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
7835051Swyllys 		    KMF_KEYLABEL_ATTR, label, strlen(label));
7845051Swyllys 		numattr++;
7855051Swyllys 	}
7865051Swyllys 	if (cred != NULL && cred->credlen > 0) {
7875051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
7885051Swyllys 		    KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
7895051Swyllys 		numattr++;
7905051Swyllys 	}
7915051Swyllys 	rv = kmf_create_sym_key(kmfhandle, numattr, attrlist);
7925051Swyllys 
7935051Swyllys 	return (rv);
7945051Swyllys }
7955051Swyllys 
79617Sdinak /*
7973089Swyllys  * Import objects from into KMF repositories.
79817Sdinak  */
79917Sdinak int
80017Sdinak pk_import(int argc, char *argv[])
80117Sdinak {
802864Sdinak 	int		opt;
803864Sdinak 	extern int	optind_av;
804864Sdinak 	extern char	*optarg_av;
805864Sdinak 	char		*token_spec = NULL;
80617Sdinak 	char		*filename = NULL;
8073089Swyllys 	char		*keyfile = NULL;
8083089Swyllys 	char		*certfile = NULL;
8093089Swyllys 	char		*crlfile = NULL;
8105051Swyllys 	char		*label = NULL;
8113089Swyllys 	char		*dir = NULL;
8123089Swyllys 	char		*keydir = NULL;
8133089Swyllys 	char		*prefix = NULL;
8143089Swyllys 	char		*trustflags = NULL;
8153089Swyllys 	char		*verify_crl = NULL;
8165051Swyllys 	char		*keytype = "generic";
8175051Swyllys 	char		*senstr = NULL;
8185051Swyllys 	char		*extstr = NULL;
8193089Swyllys 	boolean_t	verify_crl_flag = B_FALSE;
8203089Swyllys 	int		oclass = 0;
8213089Swyllys 	KMF_KEYSTORE_TYPE	kstype = 0;
8223089Swyllys 	KMF_ENCODE_FORMAT	kfmt = 0;
8233089Swyllys 	KMF_ENCODE_FORMAT	okfmt = KMF_FORMAT_ASN1;
8243089Swyllys 	KMF_RETURN		rv = KMF_OK;
8253089Swyllys 	KMF_CREDENTIAL	pk12cred = { NULL, 0 };
8263089Swyllys 	KMF_CREDENTIAL	tokencred = { NULL, 0 };
8273089Swyllys 	KMF_HANDLE_T	kmfhandle = NULL;
8285051Swyllys 	KMF_KEY_ALG	keyAlg = KMF_GENERIC_SECRET;
82917Sdinak 
830864Sdinak 	/* Parse command line options.  Do NOT i18n/l10n. */
8313089Swyllys 	while ((opt = getopt_av(argc, argv,
8325051Swyllys 	    "T:(token)i:(infile)"
8335051Swyllys 	    "k:(keystore)y:(objtype)"
8345051Swyllys 	    "d:(dir)p:(prefix)"
8355051Swyllys 	    "n:(certlabel)N:(label)"
8365051Swyllys 	    "K:(outkey)c:(outcert)"
8375051Swyllys 	    "v:(verifycrl)l:(outcrl)"
8385051Swyllys 	    "E:(keytype)s:(sensitive)x:(extractable)"
8395051Swyllys 	    "t:(trust)D:(keydir)F:(outformat)")) != EOF) {
8403089Swyllys 		if (EMPTYSTRING(optarg_av))
8413089Swyllys 			return (PK_ERR_USAGE);
842864Sdinak 		switch (opt) {
843864Sdinak 		case 'T':	/* token specifier */
844864Sdinak 			if (token_spec)
845864Sdinak 				return (PK_ERR_USAGE);
846864Sdinak 			token_spec = optarg_av;
847864Sdinak 			break;
8483089Swyllys 		case 'c':	/* output cert file name */
8493089Swyllys 			if (certfile)
8503089Swyllys 				return (PK_ERR_USAGE);
8513089Swyllys 			certfile = optarg_av;
8523089Swyllys 			break;
8533089Swyllys 		case 'l':	/* output CRL file name */
8543089Swyllys 			if (crlfile)
8553089Swyllys 				return (PK_ERR_USAGE);
8563089Swyllys 			crlfile = optarg_av;
8573089Swyllys 			break;
8583089Swyllys 		case 'K':	/* output key file name */
8593089Swyllys 			if (keyfile)
8603089Swyllys 				return (PK_ERR_USAGE);
8613089Swyllys 			keyfile = optarg_av;
8623089Swyllys 			break;
863864Sdinak 		case 'i':	/* input file name */
864864Sdinak 			if (filename)
865864Sdinak 				return (PK_ERR_USAGE);
866864Sdinak 			filename = optarg_av;
867864Sdinak 			break;
8683089Swyllys 		case 'k':
8693089Swyllys 			kstype = KS2Int(optarg_av);
8703089Swyllys 			if (kstype == 0)
8713089Swyllys 				return (PK_ERR_USAGE);
8723089Swyllys 			break;
8733089Swyllys 		case 'y':
8743089Swyllys 			oclass = OT2Int(optarg_av);
8753089Swyllys 			if (oclass == -1)
8763089Swyllys 				return (PK_ERR_USAGE);
8773089Swyllys 			break;
8783089Swyllys 		case 'd':
8793089Swyllys 			dir = optarg_av;
8803089Swyllys 			break;
8813089Swyllys 		case 'D':
8823089Swyllys 			keydir = optarg_av;
8833089Swyllys 			break;
8843089Swyllys 		case 'p':
8853089Swyllys 			if (prefix)
8863089Swyllys 				return (PK_ERR_USAGE);
8873089Swyllys 			prefix = optarg_av;
8883089Swyllys 			break;
8893089Swyllys 		case 'n':
8903089Swyllys 		case 'N':
8915051Swyllys 			if (label)
8923089Swyllys 				return (PK_ERR_USAGE);
8935051Swyllys 			label = optarg_av;
8943089Swyllys 			break;
8953089Swyllys 		case 'F':
8963089Swyllys 			okfmt = Str2Format(optarg_av);
8973089Swyllys 			if (okfmt == KMF_FORMAT_UNDEF)
8983089Swyllys 				return (PK_ERR_USAGE);
8993089Swyllys 			break;
9003089Swyllys 		case 't':
9013089Swyllys 			if (trustflags)
9023089Swyllys 				return (PK_ERR_USAGE);
9033089Swyllys 			trustflags = optarg_av;
9043089Swyllys 			break;
9053089Swyllys 		case 'v':
9063089Swyllys 			verify_crl = optarg_av;
9073089Swyllys 			if (tolower(verify_crl[0]) == 'y')
9083089Swyllys 				verify_crl_flag = B_TRUE;
9093089Swyllys 			else if (tolower(verify_crl[0]) == 'n')
9103089Swyllys 				verify_crl_flag = B_FALSE;
9113089Swyllys 			else
9123089Swyllys 				return (PK_ERR_USAGE);
9133089Swyllys 			break;
9145051Swyllys 		case 'E':
9155051Swyllys 			keytype = optarg_av;
9165051Swyllys 			break;
9175051Swyllys 		case 's':
9185051Swyllys 			if (senstr)
9195051Swyllys 				return (PK_ERR_USAGE);
9205051Swyllys 			senstr = optarg_av;
9215051Swyllys 			break;
9225051Swyllys 		case 'x':
9235051Swyllys 			if (extstr)
9245051Swyllys 				return (PK_ERR_USAGE);
9255051Swyllys 			extstr = optarg_av;
9265051Swyllys 			break;
927864Sdinak 		default:
928864Sdinak 			return (PK_ERR_USAGE);
929864Sdinak 			break;
930864Sdinak 		}
931864Sdinak 	}
93217Sdinak 
9333089Swyllys 	/* Assume keystore = PKCS#11 if not specified */
9343089Swyllys 	if (kstype == 0)
9353089Swyllys 		kstype = KMF_KEYSTORE_PK11TOKEN;
936864Sdinak 
937864Sdinak 	/* Filename arg is required. */
9383089Swyllys 	if (EMPTYSTRING(filename)) {
9393089Swyllys 		cryptoerror(LOG_STDERR, gettext("The 'infile' parameter"
9405051Swyllys 		    "is required for the import operation.\n"));
94117Sdinak 		return (PK_ERR_USAGE);
9423089Swyllys 	}
94317Sdinak 
944864Sdinak 	/* No additional args allowed. */
945864Sdinak 	argc -= optind_av;
946864Sdinak 	argv += optind_av;
947864Sdinak 	if (argc)
948864Sdinak 		return (PK_ERR_USAGE);
94917Sdinak 
9503089Swyllys 	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
9513089Swyllys 	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
9525051Swyllys 	    kstype != KMF_KEYSTORE_PK11TOKEN) {
9533089Swyllys 
9543089Swyllys 		(void) fprintf(stderr, gettext("The objtype parameter "
9555051Swyllys 		    "is only relevant if keystore=pkcs11\n"));
9563089Swyllys 		return (PK_ERR_USAGE);
95717Sdinak 	}
95817Sdinak 
9593089Swyllys 	/*
9603089Swyllys 	 * You must specify a certlabel (cert label) when importing
9613089Swyllys 	 * into NSS or PKCS#11.
9623089Swyllys 	 */
9633089Swyllys 	if (kstype == KMF_KEYSTORE_NSS &&
9645051Swyllys 	    (oclass != PK_CRL_OBJ) && EMPTYSTRING(label)) {
9653089Swyllys 		cryptoerror(LOG_STDERR, gettext("The 'label' argument "
9665051Swyllys 		    "is required for this operation\n"));
9673089Swyllys 		return (PK_ERR_USAGE);
96817Sdinak 	}
96917Sdinak 
9705051Swyllys 	if ((rv = kmf_get_file_format(filename, &kfmt)) != KMF_OK) {
9715051Swyllys 		/*
9725051Swyllys 		 * Allow for raw key data to be imported.
9735051Swyllys 		 */
9745051Swyllys 		if (rv == KMF_ERR_ENCODING) {
9755051Swyllys 			rv = KMF_OK;
9765051Swyllys 			kfmt = KMF_FORMAT_RAWKEY;
9775051Swyllys 			/*
9785051Swyllys 			 * Set the object class only if it was not
9795051Swyllys 			 * given on the command line or if it was
9805051Swyllys 			 * specified as a symmetric key object.
9815051Swyllys 			 */
9825051Swyllys 			if (oclass == 0 || (oclass & PK_SYMKEY_OBJ)) {
9835051Swyllys 				oclass = PK_SYMKEY_OBJ;
9845051Swyllys 			} else {
9855051Swyllys 				cryptoerror(LOG_STDERR, gettext(
9865051Swyllys 				    "The input file does not contain the "
9875051Swyllys 				    "object type indicated on command "
9885051Swyllys 				    "line."));
9895051Swyllys 				return (KMF_ERR_BAD_PARAMETER);
9905051Swyllys 			}
9915051Swyllys 		} else {
9925051Swyllys 			cryptoerror(LOG_STDERR,
9935051Swyllys 			    gettext("File format not recognized."));
9945051Swyllys 			return (rv);
9955051Swyllys 		}
9965051Swyllys 	}
9975051Swyllys 
9985051Swyllys 	/* Check parameters for raw key import operation */
9995051Swyllys 	if (kfmt == KMF_FORMAT_RAWKEY) {
10005051Swyllys 		if (keytype != NULL &&
10015051Swyllys 		    Str2SymKeyType(keytype, &keyAlg) != 0) {
10025051Swyllys 			cryptoerror(LOG_STDERR,
10035051Swyllys 			    gettext("Unrecognized keytype(%s).\n"), keytype);
10045051Swyllys 			return (PK_ERR_USAGE);
10055051Swyllys 		}
10065051Swyllys 		if (senstr != NULL && extstr != NULL &&
10075051Swyllys 		    kstype != KMF_KEYSTORE_PK11TOKEN) {
10085051Swyllys 			cryptoerror(LOG_STDERR,
10095051Swyllys 			    gettext("The sensitive or extractable option "
10105051Swyllys 			    "applies only when importing a key from a file "
10115051Swyllys 			    "into a PKCS#11 keystore.\n"));
10123089Swyllys 			return (PK_ERR_USAGE);
10133089Swyllys 		}
101417Sdinak 	}
101517Sdinak 
10165051Swyllys 	/* If no objtype was given, treat it as a certificate */
10173089Swyllys 	if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 ||
10185051Swyllys 	    kfmt == KMF_FORMAT_PEM))
10193089Swyllys 		oclass = PK_CERT_OBJ;
102017Sdinak 
10213089Swyllys 	if (kstype == KMF_KEYSTORE_NSS) {
10223089Swyllys 		if (oclass == PK_CRL_OBJ &&
10235051Swyllys 		    (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
10243089Swyllys 			cryptoerror(LOG_STDERR, gettext(
10255051Swyllys 			    "CRL data can only be imported as DER or "
10265051Swyllys 			    "PEM format"));
10273089Swyllys 			return (PK_ERR_USAGE);
10283089Swyllys 		}
10293089Swyllys 
10303089Swyllys 		if (oclass == PK_CERT_OBJ &&
10315051Swyllys 		    (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
10323089Swyllys 			cryptoerror(LOG_STDERR, gettext(
10335051Swyllys 			    "Certificates can only be imported as DER or "
10345051Swyllys 			    "PEM format"));
10353089Swyllys 			return (PK_ERR_USAGE);
10363089Swyllys 		}
10373089Swyllys 
10383089Swyllys 		/* we do not import private keys except in PKCS12 bundles */
10393089Swyllys 		if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) {
10403089Swyllys 			cryptoerror(LOG_STDERR, gettext(
10415051Swyllys 			    "Private key data can only be imported as part "
10425051Swyllys 			    "of a PKCS12 file.\n"));
10433089Swyllys 			return (PK_ERR_USAGE);
10443089Swyllys 		}
104517Sdinak 	}
104617Sdinak 
10473089Swyllys 	if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) {
10483089Swyllys 		if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) {
104917Sdinak 			cryptoerror(LOG_STDERR, gettext(
10505051Swyllys 			    "The 'outkey' and 'outcert' parameters "
10515051Swyllys 			    "are required for the import operation "
10525051Swyllys 			    "when the 'file' keystore is used.\n"));
10533089Swyllys 			return (PK_ERR_USAGE);
105417Sdinak 		}
105517Sdinak 	}
105617Sdinak 
10573089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec))
10583089Swyllys 		token_spec = PK_DEFAULT_PK11TOKEN;
10593089Swyllys 	else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec))
10603089Swyllys 		token_spec = DEFAULT_NSS_TOKEN;
10613089Swyllys 
10623089Swyllys 	if (kfmt == KMF_FORMAT_PKCS12) {
10633089Swyllys 		(void) get_pk12_password(&pk12cred);
10643089Swyllys 	}
10653089Swyllys 
10665051Swyllys 	if ((kfmt == KMF_FORMAT_PKCS12 || kfmt == KMF_FORMAT_RAWKEY ||
10675051Swyllys 	    (kfmt == KMF_FORMAT_PEM && (oclass & PK_KEY_OBJ))) &&
10685051Swyllys 	    (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)) {
10695051Swyllys 		(void) get_token_password(kstype, token_spec, &tokencred);
10705051Swyllys 	}
10715051Swyllys 
10725051Swyllys 	if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
10733089Swyllys 		cryptoerror(LOG_STDERR, gettext("Error initializing "
10745051Swyllys 		    "KMF: 0x%02x\n"), rv);
10753089Swyllys 		goto end;
10763089Swyllys 	}
107717Sdinak 
10783089Swyllys 	switch (kstype) {
10793089Swyllys 		case KMF_KEYSTORE_PK11TOKEN:
10803089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
10813089Swyllys 				rv = pk_import_pk12_pk11(
10825051Swyllys 				    kmfhandle, &pk12cred,
10835051Swyllys 				    &tokencred, label,
10845051Swyllys 				    token_spec, filename);
10853089Swyllys 			else if (oclass == PK_CERT_OBJ)
10863089Swyllys 				rv = pk_import_cert(
10875051Swyllys 				    kmfhandle, kstype,
10885051Swyllys 				    label, token_spec,
10895051Swyllys 				    filename,
10905051Swyllys 				    NULL, NULL, NULL);
10913089Swyllys 			else if (oclass == PK_CRL_OBJ)
10923089Swyllys 				rv = pk_import_file_crl(
10935051Swyllys 				    kmfhandle, filename,
10945051Swyllys 				    crlfile, dir, okfmt);
10955051Swyllys 			else if (kfmt == KMF_FORMAT_RAWKEY &&
10965051Swyllys 			    oclass == PK_SYMKEY_OBJ) {
10975051Swyllys 				rv = pk_import_rawkey(kmfhandle,
10985051Swyllys 				    kstype, token_spec, &tokencred,
10995051Swyllys 				    filename, label,
11005051Swyllys 				    keyAlg, senstr, extstr);
11015051Swyllys 			} else if (kfmt == KMF_FORMAT_PEM ||
11025051Swyllys 			    kfmt == KMF_FORMAT_PEM_KEYPAIR) {
11035051Swyllys 				rv = pk_import_keys(kmfhandle,
11045051Swyllys 				    kstype, token_spec, &tokencred,
11055051Swyllys 				    filename, label, senstr, extstr);
11065051Swyllys 			} else {
11075051Swyllys 				rv = PK_ERR_USAGE;
11085051Swyllys 			}
11093089Swyllys 			break;
11103089Swyllys 		case KMF_KEYSTORE_NSS:
11113089Swyllys 			if (dir == NULL)
11123089Swyllys 				dir = PK_DEFAULT_DIRECTORY;
11133089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
11143089Swyllys 				rv = pk_import_pk12_nss(
11155051Swyllys 				    kmfhandle, &pk12cred,
11165051Swyllys 				    &tokencred,
11175051Swyllys 				    token_spec, dir, prefix,
11185051Swyllys 				    label, trustflags, filename);
11193089Swyllys 			else if (oclass == PK_CERT_OBJ) {
11203089Swyllys 				rv = pk_import_cert(
11215051Swyllys 				    kmfhandle, kstype,
11225051Swyllys 				    label, token_spec,
11235051Swyllys 				    filename, dir, prefix, trustflags);
11243089Swyllys 			} else if (oclass == PK_CRL_OBJ) {
11253089Swyllys 				rv = pk_import_nss_crl(
11265051Swyllys 				    kmfhandle, verify_crl_flag,
11275051Swyllys 				    filename, dir, prefix);
11283089Swyllys 			}
11293089Swyllys 			break;
11303089Swyllys 		case KMF_KEYSTORE_OPENSSL:
11313089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
11323089Swyllys 				rv = pk_import_pk12_files(
11335051Swyllys 				    kmfhandle, &pk12cred,
11345051Swyllys 				    filename, certfile, keyfile,
11355051Swyllys 				    dir, keydir, okfmt);
11363089Swyllys 			else if (oclass == PK_CRL_OBJ) {
11373089Swyllys 				rv = pk_import_file_crl(
11385051Swyllys 				    kmfhandle, filename,
11395051Swyllys 				    crlfile, dir, okfmt);
11403089Swyllys 			} else
11413089Swyllys 				/*
11423089Swyllys 				 * It doesn't make sense to import anything
11433089Swyllys 				 * else for the files plugin.
11443089Swyllys 				 */
11453089Swyllys 				return (PK_ERR_USAGE);
11463089Swyllys 			break;
11473089Swyllys 		default:
11483089Swyllys 			rv = PK_ERR_USAGE;
11493089Swyllys 			break;
11503089Swyllys 	}
115117Sdinak 
11523089Swyllys end:
11533089Swyllys 	if (rv != KMF_OK)
11543089Swyllys 		display_error(kmfhandle, rv,
11555051Swyllys 		    gettext("Error importing objects"));
11563089Swyllys 
11573089Swyllys 	if (tokencred.cred != NULL)
11583089Swyllys 		free(tokencred.cred);
11593089Swyllys 
11603089Swyllys 	if (pk12cred.cred != NULL)
11613089Swyllys 		free(pk12cred.cred);
11623089Swyllys 
11635051Swyllys 	(void) kmf_finalize(kmfhandle);
11643089Swyllys 
11653089Swyllys 	if (rv != KMF_OK)
11663089Swyllys 		return (PK_ERR_USAGE);
11673089Swyllys 
116817Sdinak 	return (0);
116917Sdinak }
1170