xref: /onnv-gate/usr/src/cmd/cmd-crypto/pktool/import.c (revision 7108:3b59b8bbdcdd)
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 /*
226354Swyllys  * Copyright 2008 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 
485536Swyllys #define	NEW_ATTRLIST(a, n) \
495536Swyllys { \
505536Swyllys 	a = (KMF_ATTRIBUTE *)malloc(n * sizeof (KMF_ATTRIBUTE)); \
515536Swyllys 	if (a == NULL) { \
525536Swyllys 		rv = KMF_ERR_MEMORY; \
535536Swyllys 		goto end; \
545536Swyllys 	} \
555536Swyllys 	(void) memset(a, 0, n * sizeof (KMF_ATTRIBUTE));  \
565536Swyllys }
575536Swyllys 
583089Swyllys static KMF_RETURN
593089Swyllys pk_import_pk12_files(KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *cred,
603089Swyllys 	char *outfile, char *certfile, char *keyfile,
616669Swyllys 	KMF_ENCODE_FORMAT outformat)
6217Sdinak {
633089Swyllys 	KMF_RETURN rv = KMF_OK;
645536Swyllys 	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;
705536Swyllys 	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 
845536Swyllys 		NEW_ATTRLIST(attrlist,  (3 + (3 * ncerts)));
855536Swyllys 
865051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
875051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
885051Swyllys 		numattr++;
895051Swyllys 
905051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
915051Swyllys 		    KMF_ENCODE_FORMAT_ATTR, &outformat, sizeof (outformat));
925051Swyllys 		numattr++;
933089Swyllys 
943089Swyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
955051Swyllys 			int num = numattr;
965051Swyllys 
973089Swyllys 			/*
983089Swyllys 			 * If storing more than 1 cert, gotta change
993089Swyllys 			 * the name so we don't overwrite the previous one.
1003089Swyllys 			 * Just append a _# to the name.
1013089Swyllys 			 */
1023089Swyllys 			if (i > 0) {
1033089Swyllys 				(void) snprintf(newcertfile,
1045051Swyllys 				    sizeof (newcertfile), "%s_%d", certfile, i);
1055051Swyllys 
1065051Swyllys 				kmf_set_attr_at_index(attrlist, num,
1075051Swyllys 				    KMF_CERT_FILENAME_ATTR, newcertfile,
1085051Swyllys 				    strlen(newcertfile));
1095051Swyllys 				num++;
1103089Swyllys 			} else {
1115051Swyllys 				kmf_set_attr_at_index(attrlist, num,
1125051Swyllys 				    KMF_CERT_FILENAME_ATTR, certfile,
1135051Swyllys 				    strlen(certfile));
1145051Swyllys 				num++;
1153089Swyllys 			}
1165051Swyllys 
1175536Swyllys 			if (certs[i].kmf_private.label != NULL) {
1185536Swyllys 				kmf_set_attr_at_index(attrlist, num,
1195536Swyllys 				    KMF_CERT_LABEL_ATTR,
1205536Swyllys 				    certs[i].kmf_private.label,
1215536Swyllys 				    strlen(certs[i].kmf_private.label));
1225536Swyllys 				num++;
1235536Swyllys 			}
1245051Swyllys 			kmf_set_attr_at_index(attrlist, num,
1255536Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i].certificate,
1265536Swyllys 			    sizeof (KMF_DATA));
1275051Swyllys 			num++;
1285051Swyllys 			rv = kmf_store_cert(kmfhandle, num, attrlist);
1293089Swyllys 		}
1305536Swyllys 		free(attrlist);
1313089Swyllys 	}
1323089Swyllys 	if (rv == KMF_OK && nkeys > 0) {
1333089Swyllys 		char newkeyfile[MAXPATHLEN];
1345051Swyllys 		numattr = 0;
1355536Swyllys 		NEW_ATTRLIST(attrlist, (4 + (4 * nkeys)));
1365051Swyllys 
1375051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
1385051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
1395051Swyllys 		    sizeof (kstype));
1405051Swyllys 		numattr++;
1415051Swyllys 
1425051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
1435051Swyllys 		    KMF_ENCODE_FORMAT_ATTR, &outformat,
1445051Swyllys 		    sizeof (outformat));
1455051Swyllys 		numattr++;
1465051Swyllys 
1475051Swyllys 		if (cred != NULL && cred->credlen > 0) {
1485051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1495051Swyllys 			    KMF_CREDENTIAL_ATTR, cred,
1505051Swyllys 			    sizeof (KMF_CREDENTIAL));
1515051Swyllys 			numattr++;
1525051Swyllys 		}
15317Sdinak 
1543089Swyllys 		/* The order of certificates and keys should match */
1553089Swyllys 		for (i = 0; rv == KMF_OK && i < nkeys; i++) {
1565051Swyllys 			int num = numattr;
1573089Swyllys 
1583089Swyllys 			if (i > 0) {
1593089Swyllys 				(void) snprintf(newkeyfile,
1605051Swyllys 				    sizeof (newkeyfile), "%s_%d", keyfile, i);
1615051Swyllys 
1625051Swyllys 				kmf_set_attr_at_index(attrlist, num,
1635051Swyllys 				    KMF_KEY_FILENAME_ATTR, newkeyfile,
1645051Swyllys 				    strlen(newkeyfile));
1655051Swyllys 				num++;
1663089Swyllys 			} else {
1675051Swyllys 				kmf_set_attr_at_index(attrlist, num,
1685051Swyllys 				    KMF_KEY_FILENAME_ATTR, keyfile,
1695051Swyllys 				    strlen(keyfile));
1705051Swyllys 				num++;
1713089Swyllys 			}
17217Sdinak 
1735536Swyllys 			if (i < ncerts) {
1745536Swyllys 				kmf_set_attr_at_index(attrlist, num,
1755536Swyllys 				    KMF_CERT_DATA_ATTR, &certs[i],
1765536Swyllys 				    sizeof (KMF_CERT_DATA_ATTR));
1775536Swyllys 				num++;
1785536Swyllys 			}
1795051Swyllys 
1805051Swyllys 			kmf_set_attr_at_index(attrlist, num,
1815051Swyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
1825051Swyllys 			    sizeof (KMF_RAW_KEY_DATA));
1835051Swyllys 			num++;
1845051Swyllys 
1855051Swyllys 			rv = kmf_store_key(kmfhandle, num, attrlist);
1863089Swyllys 		}
1875536Swyllys 		free(attrlist);
1883089Swyllys 	}
1895536Swyllys end:
1903089Swyllys 	/*
1913089Swyllys 	 * Cleanup memory.
1923089Swyllys 	 */
1933089Swyllys 	if (certs) {
1943089Swyllys 		for (i = 0; i < ncerts; i++)
1955536Swyllys 			kmf_free_kmf_cert(kmfhandle, &certs[i]);
1963089Swyllys 		free(certs);
1973089Swyllys 	}
1983089Swyllys 	if (keys) {
1993089Swyllys 		for (i = 0; i < nkeys; i++)
2005051Swyllys 			kmf_free_raw_key(&keys[i]);
2013089Swyllys 		free(keys);
20217Sdinak 	}
20317Sdinak 
20417Sdinak 
2053089Swyllys 	return (rv);
20617Sdinak }
20717Sdinak 
2083089Swyllys 
2093089Swyllys static KMF_RETURN
2103089Swyllys pk_import_pk12_nss(
2113089Swyllys 	KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *kmfcred,
2123089Swyllys 	KMF_CREDENTIAL *tokencred,
2133089Swyllys 	char *token_spec, char *dir, char *prefix,
2143089Swyllys 	char *nickname, char *trustflags, char *filename)
21517Sdinak {
2163089Swyllys 	KMF_RETURN rv = KMF_OK;
2175536Swyllys 	KMF_X509_DER_CERT *certs = NULL;
2183089Swyllys 	KMF_RAW_KEY_DATA *keys = NULL;
2193089Swyllys 	int ncerts = 0;
2203089Swyllys 	int nkeys = 0;
2213089Swyllys 	int i;
2225051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
2235536Swyllys 	KMF_ATTRIBUTE *attrlist = NULL;
2245051Swyllys 	int numattr = 0;
2253089Swyllys 
2263089Swyllys 	rv = configure_nss(kmfhandle, dir, prefix);
2273089Swyllys 	if (rv != KMF_OK)
2283089Swyllys 		return (rv);
2293089Swyllys 
2305051Swyllys 	rv = kmf_import_objects(kmfhandle, filename, kmfcred,
2315051Swyllys 	    &certs, &ncerts, &keys, &nkeys);
2323089Swyllys 
2333089Swyllys 	if (rv == KMF_OK)
2343089Swyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
2355051Swyllys 		    "key(s) in %s\n"), ncerts, nkeys, filename);
23617Sdinak 
2373089Swyllys 	if (rv == KMF_OK) {
238*7108Swyllys 		numattr = 0;
239*7108Swyllys 		NEW_ATTRLIST(attrlist, (4 + (2 * nkeys)));
240*7108Swyllys 
241*7108Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
242*7108Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
243*7108Swyllys 		    sizeof (kstype));
244*7108Swyllys 		numattr++;
245*7108Swyllys 
246*7108Swyllys 		if (token_spec != NULL) {
247*7108Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
248*7108Swyllys 			    KMF_TOKEN_LABEL_ATTR, token_spec,
249*7108Swyllys 			    strlen(token_spec));
250*7108Swyllys 			numattr++;
251*7108Swyllys 		}
252*7108Swyllys 
253*7108Swyllys 		if (nickname != NULL) {
254*7108Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
255*7108Swyllys 			    KMF_KEYLABEL_ATTR, nickname,
256*7108Swyllys 			    strlen(nickname));
257*7108Swyllys 			numattr++;
258*7108Swyllys 		}
259*7108Swyllys 
260*7108Swyllys 		if (tokencred->credlen > 0) {
261*7108Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
262*7108Swyllys 			    KMF_CREDENTIAL_ATTR, tokencred,
263*7108Swyllys 			    sizeof (KMF_CREDENTIAL));
264*7108Swyllys 			numattr++;
265*7108Swyllys 		}
266*7108Swyllys 
267*7108Swyllys 		/* The order of certificates and keys should match */
268*7108Swyllys 		for (i = 0; i < nkeys; i++) {
269*7108Swyllys 			int num = numattr;
270*7108Swyllys 
271*7108Swyllys 			if (i < ncerts) {
272*7108Swyllys 				kmf_set_attr_at_index(attrlist, num,
273*7108Swyllys 				    KMF_CERT_DATA_ATTR, &certs[i],
274*7108Swyllys 				    sizeof (KMF_DATA));
275*7108Swyllys 				num++;
276*7108Swyllys 			}
277*7108Swyllys 
278*7108Swyllys 			kmf_set_attr_at_index(attrlist, num,
279*7108Swyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
280*7108Swyllys 			    sizeof (KMF_RAW_KEY_DATA));
281*7108Swyllys 			num++;
282*7108Swyllys 
283*7108Swyllys 			rv = kmf_store_key(kmfhandle, num, attrlist);
284*7108Swyllys 		}
285*7108Swyllys 		free(attrlist);
286*7108Swyllys 		attrlist = NULL;
287*7108Swyllys 	}
288*7108Swyllys 
289*7108Swyllys 	if (rv == KMF_OK) {
2905536Swyllys 		NEW_ATTRLIST(attrlist, (3 + (2 * ncerts)));
2915536Swyllys 
2925051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
2935051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
2945051Swyllys 		numattr++;
29517Sdinak 
2965051Swyllys 		if (token_spec != NULL) {
2975051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
2985051Swyllys 			    KMF_TOKEN_LABEL_ATTR, token_spec,
2995051Swyllys 			    strlen(token_spec));
3005051Swyllys 			numattr++;
3015051Swyllys 		}
3025051Swyllys 
3035051Swyllys 		if (trustflags != NULL) {
3045051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3055051Swyllys 			    KMF_TRUSTFLAG_ATTR, trustflags,
3065051Swyllys 			    strlen(trustflags));
3075051Swyllys 			numattr++;
3085051Swyllys 		}
30917Sdinak 
3103089Swyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
3115051Swyllys 			int num = numattr;
31217Sdinak 
3135536Swyllys 			if (certs[i].kmf_private.label != NULL) {
3145536Swyllys 				kmf_set_attr_at_index(attrlist, num,
3155536Swyllys 				    KMF_CERT_LABEL_ATTR,
3165536Swyllys 				    certs[i].kmf_private.label,
3175536Swyllys 				    strlen(certs[i].kmf_private.label));
3185536Swyllys 				num++;
3195536Swyllys 			} else if (i == 0 && nickname != NULL) {
3205051Swyllys 				kmf_set_attr_at_index(attrlist, num,
3215051Swyllys 				    KMF_CERT_LABEL_ATTR, nickname,
3225051Swyllys 				    strlen(nickname));
3235051Swyllys 				num++;
3245051Swyllys 			}
3255051Swyllys 
3265051Swyllys 			kmf_set_attr_at_index(attrlist, num,
3275536Swyllys 			    KMF_CERT_DATA_ATTR,
3285536Swyllys 			    &certs[i].certificate, sizeof (KMF_DATA));
3295051Swyllys 			num++;
3305051Swyllys 			rv = kmf_store_cert(kmfhandle, num, attrlist);
3313089Swyllys 		}
3325536Swyllys 		free(attrlist);
3335536Swyllys 		attrlist = NULL;
3343089Swyllys 		if (rv != KMF_OK) {
3353089Swyllys 			display_error(kmfhandle, rv,
3365051Swyllys 			    gettext("Error storing certificate in NSS token"));
3373089Swyllys 		}
33817Sdinak 	}
33917Sdinak 
3405536Swyllys end:
3413089Swyllys 	/*
3423089Swyllys 	 * Cleanup memory.
3433089Swyllys 	 */
3443089Swyllys 	if (certs) {
3453089Swyllys 		for (i = 0; i < ncerts; i++)
3465536Swyllys 			kmf_free_kmf_cert(kmfhandle, &certs[i]);
3473089Swyllys 		free(certs);
3483089Swyllys 	}
3493089Swyllys 	if (keys) {
3503089Swyllys 		for (i = 0; i < nkeys; i++)
3515051Swyllys 			kmf_free_raw_key(&keys[i]);
3523089Swyllys 		free(keys);
35317Sdinak 	}
35417Sdinak 
3553089Swyllys 	return (rv);
3563089Swyllys }
35717Sdinak 
3583089Swyllys static KMF_RETURN
3593089Swyllys pk_import_cert(
3603089Swyllys 	KMF_HANDLE_T kmfhandle,
3613089Swyllys 	KMF_KEYSTORE_TYPE kstype,
3623089Swyllys 	char *label, char *token_spec, char *filename,
3633089Swyllys 	char *dir, char *prefix, char *trustflags)
3643089Swyllys {
3653089Swyllys 	KMF_RETURN rv = KMF_OK;
3665051Swyllys 	KMF_ATTRIBUTE attrlist[32];
3676354Swyllys 	KMF_CREDENTIAL tokencred;
3685051Swyllys 	int i = 0;
36917Sdinak 
3703089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
3713089Swyllys 		rv = select_token(kmfhandle, token_spec, FALSE);
3725051Swyllys 	} else if (kstype == KMF_KEYSTORE_NSS) {
3735051Swyllys 		rv = configure_nss(kmfhandle, dir, prefix);
3745051Swyllys 	}
3755051Swyllys 	if (rv != KMF_OK)
3765051Swyllys 		return (rv);
37717Sdinak 
3785051Swyllys 	kmf_set_attr_at_index(attrlist, i,
3795051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (KMF_KEYSTORE_TYPE));
3805051Swyllys 	i++;
3815051Swyllys 
3825051Swyllys 	kmf_set_attr_at_index(attrlist, i, KMF_CERT_FILENAME_ATTR,
3835051Swyllys 	    filename, strlen(filename));
3845051Swyllys 	i++;
3855051Swyllys 
3865051Swyllys 	if (label != NULL) {
3875051Swyllys 		kmf_set_attr_at_index(attrlist, i, KMF_CERT_LABEL_ATTR,
3885051Swyllys 		    label, strlen(label));
3895051Swyllys 		i++;
3905051Swyllys 	}
3915051Swyllys 
3925051Swyllys 	if (kstype == KMF_KEYSTORE_NSS) {
3935051Swyllys 		if (trustflags != NULL) {
3945051Swyllys 			kmf_set_attr_at_index(attrlist, i, KMF_TRUSTFLAG_ATTR,
3955051Swyllys 			    trustflags, strlen(trustflags));
3965051Swyllys 			i++;
3975051Swyllys 		}
3985051Swyllys 
3995051Swyllys 		if (token_spec != NULL) {
4005051Swyllys 			kmf_set_attr_at_index(attrlist, i,
4015051Swyllys 			    KMF_TOKEN_LABEL_ATTR,
4025051Swyllys 			    token_spec, strlen(token_spec));
4035051Swyllys 			i++;
40417Sdinak 		}
4053089Swyllys 	}
40617Sdinak 
4075051Swyllys 	rv = kmf_import_cert(kmfhandle, i, attrlist);
4086354Swyllys 	if (rv == KMF_ERR_AUTH_FAILED) {
4096354Swyllys 		/*
4106354Swyllys 		 * The token requires a credential, prompt and try again.
4116354Swyllys 		 */
4126354Swyllys 		(void) get_token_password(kstype, token_spec, &tokencred);
4136354Swyllys 		kmf_set_attr_at_index(attrlist, i, KMF_CREDENTIAL_ATTR,
4146354Swyllys 		    &tokencred, sizeof (KMF_CREDENTIAL));
4156354Swyllys 		i++;
4166354Swyllys 
4176354Swyllys 		rv = kmf_import_cert(kmfhandle, i, attrlist);
4186354Swyllys 
4196354Swyllys 	}
4203089Swyllys 	return (rv);
4213089Swyllys }
4223089Swyllys 
4233089Swyllys static KMF_RETURN
4243089Swyllys pk_import_file_crl(void *kmfhandle,
4253089Swyllys 	char *infile,
4263089Swyllys 	char *outfile,
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 (outfile) {
4425051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
4435051Swyllys 		    KMF_CRL_OUTFILE_ATTR, outfile, strlen(outfile));
4445051Swyllys 		numattr++;
4455051Swyllys 	}
4465051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
4475051Swyllys 	    KMF_ENCODE_FORMAT_ATTR, &outfmt, sizeof (outfmt));
4485051Swyllys 	numattr++;
4493089Swyllys 
4505051Swyllys 	return (kmf_import_crl(kmfhandle, numattr, attrlist));
4513089Swyllys }
4523089Swyllys 
4533089Swyllys static KMF_RETURN
4543089Swyllys pk_import_nss_crl(void *kmfhandle,
4553089Swyllys 	boolean_t verify_crl_flag,
4563089Swyllys 	char *infile,
4573089Swyllys 	char *outdir,
4583089Swyllys 	char *prefix)
4593089Swyllys {
4603089Swyllys 	KMF_RETURN rv;
4615051Swyllys 	int numattr = 0;
4625051Swyllys 	KMF_ATTRIBUTE attrlist[4];
4635051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
4643089Swyllys 
4653089Swyllys 	rv = configure_nss(kmfhandle, outdir, prefix);
4663089Swyllys 	if (rv != KMF_OK)
4673089Swyllys 		return (rv);
4683089Swyllys 
4695051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
4705051Swyllys 	    &kstype, sizeof (kstype));
4715051Swyllys 	numattr++;
4725051Swyllys 	if (infile) {
4735051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR,
4745051Swyllys 		    infile, strlen(infile));
4755051Swyllys 		numattr++;
4765051Swyllys 	}
4775051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_CHECK_ATTR,
4785051Swyllys 	    &verify_crl_flag, sizeof (verify_crl_flag));
4795051Swyllys 	numattr++;
4803089Swyllys 
4815051Swyllys 	return (kmf_import_crl(kmfhandle, numattr, attrlist));
4823089Swyllys 
4833089Swyllys }
4843089Swyllys 
4853089Swyllys static KMF_RETURN
4863089Swyllys pk_import_pk12_pk11(
4873089Swyllys 	KMF_HANDLE_T kmfhandle,
4883089Swyllys 	KMF_CREDENTIAL *p12cred,
4893089Swyllys 	KMF_CREDENTIAL *tokencred,
4903089Swyllys 	char *label, char *token_spec,
4913089Swyllys 	char *filename)
4923089Swyllys {
4933089Swyllys 	KMF_RETURN rv = KMF_OK;
4945536Swyllys 	KMF_X509_DER_CERT *certs = NULL;
4953089Swyllys 	KMF_RAW_KEY_DATA *keys = NULL;
4963089Swyllys 	int ncerts = 0;
4973089Swyllys 	int nkeys = 0;
4983089Swyllys 	int i;
4995051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
5005536Swyllys 	KMF_ATTRIBUTE *attrlist = NULL;
5015051Swyllys 	int numattr = 0;
5023089Swyllys 
5033089Swyllys 	rv = select_token(kmfhandle, token_spec, FALSE);
5043089Swyllys 
5053089Swyllys 	if (rv != KMF_OK) {
50617Sdinak 		return (rv);
50717Sdinak 	}
50817Sdinak 
5095051Swyllys 	rv = kmf_import_objects(kmfhandle, filename, p12cred,
5105051Swyllys 	    &certs, &ncerts, &keys, &nkeys);
5113089Swyllys 
5123089Swyllys 	if (rv == KMF_OK) {
5135536Swyllys 		NEW_ATTRLIST(attrlist, (3 + (2 * nkeys)));
5145051Swyllys 
5155051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
5165051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
5175051Swyllys 		    sizeof (kstype));
5185051Swyllys 		numattr++;
5195051Swyllys 
5205051Swyllys 		if (label != NULL) {
5215051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
5225051Swyllys 			    KMF_KEYLABEL_ATTR, label,
5235051Swyllys 			    strlen(label));
5245051Swyllys 			numattr++;
5255051Swyllys 		}
5265051Swyllys 
5275051Swyllys 		if (tokencred != NULL && tokencred->credlen > 0) {
5285051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
5295051Swyllys 			    KMF_CREDENTIAL_ATTR, tokencred,
5305051Swyllys 			    sizeof (KMF_CREDENTIAL));
5315051Swyllys 			numattr++;
5325051Swyllys 		}
5333089Swyllys 
5343089Swyllys 		/* The order of certificates and keys should match */
5353089Swyllys 		for (i = 0; i < nkeys; i++) {
5365051Swyllys 			int num = numattr;
5375051Swyllys 
5385536Swyllys 			if (i < ncerts) {
5395536Swyllys 				kmf_set_attr_at_index(attrlist, num,
5405536Swyllys 				    KMF_CERT_DATA_ATTR, &certs[i].certificate,
5415536Swyllys 				    sizeof (KMF_DATA));
5425536Swyllys 				num++;
5435536Swyllys 			}
5443089Swyllys 
5455051Swyllys 			kmf_set_attr_at_index(attrlist, num,
5465051Swyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
5475051Swyllys 			    sizeof (KMF_RAW_KEY_DATA));
5485051Swyllys 			num++;
5495051Swyllys 
5505051Swyllys 			rv = kmf_store_key(kmfhandle, num, attrlist);
5515051Swyllys 
5523089Swyllys 		}
5535536Swyllys 		free(attrlist);
5543089Swyllys 	}
5553089Swyllys 
5563089Swyllys 	if (rv == KMF_OK) {
5575536Swyllys 		numattr = 0;
5585536Swyllys 		NEW_ATTRLIST(attrlist, (1 + (2 * ncerts)));
5593089Swyllys 
5603089Swyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
5615051Swyllys 		    "key(s) in %s\n"), ncerts, nkeys, filename);
5625536Swyllys 
5635051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
5645051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
5655051Swyllys 		numattr++;
5663089Swyllys 
5673089Swyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
5685051Swyllys 			int num = numattr;
5695536Swyllys 			if (certs[i].kmf_private.label != NULL) {
5705536Swyllys 				kmf_set_attr_at_index(attrlist, num,
5715536Swyllys 				    KMF_CERT_LABEL_ATTR,
5725536Swyllys 				    certs[i].kmf_private.label,
5735536Swyllys 				    strlen(certs[i].kmf_private.label));
5745536Swyllys 				num++;
5755536Swyllys 			} else if (i == 0 && label != NULL) {
5765051Swyllys 				kmf_set_attr_at_index(attrlist, num,
5775051Swyllys 				    KMF_CERT_LABEL_ATTR, label, strlen(label));
5785051Swyllys 				num++;
5795051Swyllys 			}
5805051Swyllys 
5815051Swyllys 			kmf_set_attr_at_index(attrlist, num,
5825536Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i].certificate,
5835536Swyllys 			    sizeof (KMF_DATA));
5845051Swyllys 			num++;
5855051Swyllys 
5865051Swyllys 			rv = kmf_store_cert(kmfhandle, num, attrlist);
5873089Swyllys 		}
5885536Swyllys 		free(attrlist);
5893089Swyllys 	}
5903089Swyllys 
5915536Swyllys end:
5923089Swyllys 	/*
5933089Swyllys 	 * Cleanup memory.
5943089Swyllys 	 */
5953089Swyllys 	if (certs) {
5963089Swyllys 		for (i = 0; i < ncerts; i++)
5975536Swyllys 			kmf_free_kmf_cert(kmfhandle, &certs[i]);
5983089Swyllys 		free(certs);
5993089Swyllys 	}
6003089Swyllys 	if (keys) {
6013089Swyllys 		for (i = 0; i < nkeys; i++)
6025051Swyllys 			kmf_free_raw_key(&keys[i]);
6033089Swyllys 		free(keys);
6043089Swyllys 	}
6053089Swyllys 
6063089Swyllys 	return (rv);
60717Sdinak }
60817Sdinak 
6095069Swyllys /*ARGSUSED*/
6105051Swyllys static KMF_RETURN
6115051Swyllys pk_import_keys(KMF_HANDLE_T kmfhandle,
6125051Swyllys 	KMF_KEYSTORE_TYPE kstype, char *token_spec,
6135051Swyllys 	KMF_CREDENTIAL *cred, char *filename,
6145051Swyllys 	char *label, char *senstr, char *extstr)
6155051Swyllys {
6165051Swyllys 	KMF_RETURN rv = KMF_OK;
6175051Swyllys 	KMF_ATTRIBUTE attrlist[16];
6185051Swyllys 	KMF_KEYSTORE_TYPE fileks = KMF_KEYSTORE_OPENSSL;
6195051Swyllys 	int numattr = 0;
6205051Swyllys 	KMF_KEY_HANDLE key;
6215051Swyllys 	KMF_RAW_KEY_DATA rawkey;
6225051Swyllys 	KMF_KEY_CLASS class = KMF_ASYM_PRI;
6235051Swyllys 	int numkeys = 1;
6245051Swyllys 
6255051Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
6265051Swyllys 		rv = select_token(kmfhandle, token_spec, FALSE);
6275051Swyllys 	}
6285051Swyllys 	if (rv != KMF_OK)
6295051Swyllys 		return (rv);
6305051Swyllys 	/*
6315051Swyllys 	 * First, set up to read the keyfile using the FILE plugin
6325051Swyllys 	 * mechanisms.
6335051Swyllys 	 */
6345051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
6355051Swyllys 	    &fileks, sizeof (fileks));
6365051Swyllys 	numattr++;
6375051Swyllys 
6385051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
6395051Swyllys 	    &numkeys, sizeof (numkeys));
6405051Swyllys 	numattr++;
6415051Swyllys 
6425051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
6435051Swyllys 	    &key, sizeof (key));
6445051Swyllys 	numattr++;
6455051Swyllys 
6465051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR,
6475051Swyllys 	    &rawkey, sizeof (rawkey));
6485051Swyllys 	numattr++;
6495051Swyllys 
6505051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
6515051Swyllys 	    &class, sizeof (class));
6525051Swyllys 	numattr++;
6535051Swyllys 
6545051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
6555051Swyllys 	    filename, strlen(filename));
6565051Swyllys 	numattr++;
6575051Swyllys 
6585051Swyllys 	rv = kmf_find_key(kmfhandle, numattr, attrlist);
6595051Swyllys 	if (rv == KMF_OK) {
6605051Swyllys 		numattr = 0;
6615051Swyllys 
6625051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
6635051Swyllys 		    &kstype, sizeof (kstype));
6645051Swyllys 		numattr++;
6655051Swyllys 
6665051Swyllys 		if (cred != NULL && cred->credlen > 0) {
6675051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
6685051Swyllys 			    KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
6695051Swyllys 			numattr++;
6705051Swyllys 		}
6715051Swyllys 
6725051Swyllys 		if (label != NULL) {
6735051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
6745051Swyllys 			    KMF_KEYLABEL_ATTR, label, strlen(label));
6755051Swyllys 			numattr++;
6765051Swyllys 		}
6775051Swyllys 
6785051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
6795051Swyllys 		    KMF_RAW_KEY_ATTR, &rawkey, sizeof (rawkey));
6805051Swyllys 		numattr++;
6815051Swyllys 
6825051Swyllys 		rv = kmf_store_key(kmfhandle, numattr, attrlist);
6835051Swyllys 		if (rv == KMF_OK) {
6845069Swyllys 			(void) printf(gettext("Importing %d keys\n"), numkeys);
6855051Swyllys 		}
6865051Swyllys 
6875051Swyllys 		kmf_free_kmf_key(kmfhandle, &key);
6885051Swyllys 		kmf_free_raw_key(&rawkey);
6895051Swyllys 	} else {
6905051Swyllys 		cryptoerror(LOG_STDERR,
6915051Swyllys 		    gettext("Failed to load key from file (%s)\n"),
6925051Swyllys 		    filename);
6935051Swyllys 	}
6945051Swyllys 	return (rv);
6955051Swyllys }
6965051Swyllys 
6975051Swyllys static KMF_RETURN
6985051Swyllys pk_import_rawkey(KMF_HANDLE_T kmfhandle,
6995051Swyllys 	KMF_KEYSTORE_TYPE kstype, char *token,
7005051Swyllys 	KMF_CREDENTIAL *cred,
7015051Swyllys 	char *filename, char *label, KMF_KEY_ALG keyAlg,
7025051Swyllys 	char *senstr, char *extstr)
7035051Swyllys {
7045051Swyllys 	KMF_RETURN rv = KMF_OK;
7055051Swyllys 	KMF_ATTRIBUTE attrlist[16];
7065051Swyllys 	int numattr = 0;
7075051Swyllys 	uint32_t keylen;
7085051Swyllys 	boolean_t sensitive = B_FALSE;
7095051Swyllys 	boolean_t not_extractable = B_FALSE;
7105051Swyllys 	KMF_DATA keydata = {NULL, 0};
7115051Swyllys 	KMF_KEY_HANDLE rawkey;
7125051Swyllys 
7135051Swyllys 	rv = kmf_read_input_file(kmfhandle, filename, &keydata);
7145051Swyllys 	if (rv != KMF_OK)
7155051Swyllys 		return (rv);
7165051Swyllys 
7175051Swyllys 	rv = select_token(kmfhandle, token, FALSE);
7185051Swyllys 
7195051Swyllys 	if (rv != KMF_OK) {
7205051Swyllys 		return (rv);
7215051Swyllys 	}
7225051Swyllys 	if (senstr != NULL) {
7235051Swyllys 		if (tolower(senstr[0]) == 'y')
7245051Swyllys 			sensitive = B_TRUE;
7255051Swyllys 		else if (tolower(senstr[0]) == 'n')
7265051Swyllys 			sensitive = B_FALSE;
7275051Swyllys 		else {
7285051Swyllys 			cryptoerror(LOG_STDERR,
7295051Swyllys 			    gettext("Incorrect sensitive option value.\n"));
7305051Swyllys 			return (KMF_ERR_BAD_PARAMETER);
7315051Swyllys 		}
7325051Swyllys 	}
7335051Swyllys 
7345051Swyllys 	if (extstr != NULL) {
7355051Swyllys 		if (tolower(extstr[0]) == 'y')
7365051Swyllys 			not_extractable = B_FALSE;
7375051Swyllys 		else if (tolower(extstr[0]) == 'n')
7385051Swyllys 			not_extractable = B_TRUE;
7395051Swyllys 		else {
7405051Swyllys 			cryptoerror(LOG_STDERR,
7415051Swyllys 			    gettext("Incorrect extractable option value.\n"));
7425051Swyllys 			return (KMF_ERR_BAD_PARAMETER);
7435051Swyllys 		}
7445051Swyllys 	}
7455051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7465051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
7475051Swyllys 	numattr++;
7485051Swyllys 
7495051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7505051Swyllys 	    KMF_KEY_HANDLE_ATTR, &rawkey, sizeof (rawkey));
7515051Swyllys 	numattr++;
7525051Swyllys 
7535051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7545051Swyllys 	    KMF_KEYALG_ATTR, &keyAlg, sizeof (KMF_KEY_ALG));
7555051Swyllys 	numattr++;
7565051Swyllys 
7575051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7585051Swyllys 	    KMF_KEY_DATA_ATTR, keydata.Data, keydata.Length);
7595051Swyllys 	numattr++;
7605051Swyllys 
7615051Swyllys 	/* Key length is given in bits not bytes */
7625051Swyllys 	keylen = keydata.Length * 8;
7635051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7645051Swyllys 	    KMF_KEYLENGTH_ATTR, &keylen, sizeof (keydata.Length));
7655051Swyllys 	numattr++;
7665051Swyllys 
7675051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7685051Swyllys 	    KMF_SENSITIVE_BOOL_ATTR, &sensitive, sizeof (sensitive));
7695051Swyllys 	numattr++;
7705051Swyllys 
7715051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7725051Swyllys 	    KMF_NON_EXTRACTABLE_BOOL_ATTR, &not_extractable,
7735051Swyllys 	    sizeof (not_extractable));
7745051Swyllys 	numattr++;
7755051Swyllys 
7765051Swyllys 	if (label != NULL) {
7775051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
7785051Swyllys 		    KMF_KEYLABEL_ATTR, label, strlen(label));
7795051Swyllys 		numattr++;
7805051Swyllys 	}
7815051Swyllys 	if (cred != NULL && cred->credlen > 0) {
7825051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
7835051Swyllys 		    KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
7845051Swyllys 		numattr++;
7855051Swyllys 	}
7865051Swyllys 	rv = kmf_create_sym_key(kmfhandle, numattr, attrlist);
7875051Swyllys 
7885051Swyllys 	return (rv);
7895051Swyllys }
7905051Swyllys 
79117Sdinak /*
7923089Swyllys  * Import objects from into KMF repositories.
79317Sdinak  */
79417Sdinak int
79517Sdinak pk_import(int argc, char *argv[])
79617Sdinak {
797864Sdinak 	int		opt;
798864Sdinak 	extern int	optind_av;
799864Sdinak 	extern char	*optarg_av;
800864Sdinak 	char		*token_spec = NULL;
80117Sdinak 	char		*filename = NULL;
8023089Swyllys 	char		*keyfile = NULL;
8033089Swyllys 	char		*certfile = NULL;
8043089Swyllys 	char		*crlfile = NULL;
8055051Swyllys 	char		*label = NULL;
8063089Swyllys 	char		*dir = NULL;
8073089Swyllys 	char		*prefix = NULL;
8083089Swyllys 	char		*trustflags = NULL;
8093089Swyllys 	char		*verify_crl = NULL;
8105051Swyllys 	char		*keytype = "generic";
8115051Swyllys 	char		*senstr = NULL;
8125051Swyllys 	char		*extstr = NULL;
8133089Swyllys 	boolean_t	verify_crl_flag = B_FALSE;
8143089Swyllys 	int		oclass = 0;
8153089Swyllys 	KMF_KEYSTORE_TYPE	kstype = 0;
8163089Swyllys 	KMF_ENCODE_FORMAT	kfmt = 0;
8173089Swyllys 	KMF_ENCODE_FORMAT	okfmt = KMF_FORMAT_ASN1;
8183089Swyllys 	KMF_RETURN		rv = KMF_OK;
8193089Swyllys 	KMF_CREDENTIAL	pk12cred = { NULL, 0 };
8203089Swyllys 	KMF_CREDENTIAL	tokencred = { NULL, 0 };
8213089Swyllys 	KMF_HANDLE_T	kmfhandle = NULL;
8225051Swyllys 	KMF_KEY_ALG	keyAlg = KMF_GENERIC_SECRET;
82317Sdinak 
824864Sdinak 	/* Parse command line options.  Do NOT i18n/l10n. */
8253089Swyllys 	while ((opt = getopt_av(argc, argv,
8265051Swyllys 	    "T:(token)i:(infile)"
8275051Swyllys 	    "k:(keystore)y:(objtype)"
8285051Swyllys 	    "d:(dir)p:(prefix)"
8295051Swyllys 	    "n:(certlabel)N:(label)"
8305051Swyllys 	    "K:(outkey)c:(outcert)"
8315051Swyllys 	    "v:(verifycrl)l:(outcrl)"
8325051Swyllys 	    "E:(keytype)s:(sensitive)x:(extractable)"
8336669Swyllys 	    "t:(trust)F:(outformat)")) != EOF) {
8343089Swyllys 		if (EMPTYSTRING(optarg_av))
8353089Swyllys 			return (PK_ERR_USAGE);
836864Sdinak 		switch (opt) {
837864Sdinak 		case 'T':	/* token specifier */
838864Sdinak 			if (token_spec)
839864Sdinak 				return (PK_ERR_USAGE);
840864Sdinak 			token_spec = optarg_av;
841864Sdinak 			break;
8423089Swyllys 		case 'c':	/* output cert file name */
8433089Swyllys 			if (certfile)
8443089Swyllys 				return (PK_ERR_USAGE);
8453089Swyllys 			certfile = optarg_av;
8463089Swyllys 			break;
8473089Swyllys 		case 'l':	/* output CRL file name */
8483089Swyllys 			if (crlfile)
8493089Swyllys 				return (PK_ERR_USAGE);
8503089Swyllys 			crlfile = optarg_av;
8513089Swyllys 			break;
8523089Swyllys 		case 'K':	/* output key file name */
8533089Swyllys 			if (keyfile)
8543089Swyllys 				return (PK_ERR_USAGE);
8553089Swyllys 			keyfile = optarg_av;
8563089Swyllys 			break;
857864Sdinak 		case 'i':	/* input file name */
858864Sdinak 			if (filename)
859864Sdinak 				return (PK_ERR_USAGE);
860864Sdinak 			filename = optarg_av;
861864Sdinak 			break;
8623089Swyllys 		case 'k':
8633089Swyllys 			kstype = KS2Int(optarg_av);
8643089Swyllys 			if (kstype == 0)
8653089Swyllys 				return (PK_ERR_USAGE);
8663089Swyllys 			break;
8673089Swyllys 		case 'y':
8683089Swyllys 			oclass = OT2Int(optarg_av);
8693089Swyllys 			if (oclass == -1)
8703089Swyllys 				return (PK_ERR_USAGE);
8713089Swyllys 			break;
8723089Swyllys 		case 'd':
8733089Swyllys 			dir = optarg_av;
8743089Swyllys 			break;
8753089Swyllys 		case 'p':
8763089Swyllys 			if (prefix)
8773089Swyllys 				return (PK_ERR_USAGE);
8783089Swyllys 			prefix = optarg_av;
8793089Swyllys 			break;
8803089Swyllys 		case 'n':
8813089Swyllys 		case 'N':
8825051Swyllys 			if (label)
8833089Swyllys 				return (PK_ERR_USAGE);
8845051Swyllys 			label = optarg_av;
8853089Swyllys 			break;
8863089Swyllys 		case 'F':
8873089Swyllys 			okfmt = Str2Format(optarg_av);
8883089Swyllys 			if (okfmt == KMF_FORMAT_UNDEF)
8893089Swyllys 				return (PK_ERR_USAGE);
8903089Swyllys 			break;
8913089Swyllys 		case 't':
8923089Swyllys 			if (trustflags)
8933089Swyllys 				return (PK_ERR_USAGE);
8943089Swyllys 			trustflags = optarg_av;
8953089Swyllys 			break;
8963089Swyllys 		case 'v':
8973089Swyllys 			verify_crl = optarg_av;
8983089Swyllys 			if (tolower(verify_crl[0]) == 'y')
8993089Swyllys 				verify_crl_flag = B_TRUE;
9003089Swyllys 			else if (tolower(verify_crl[0]) == 'n')
9013089Swyllys 				verify_crl_flag = B_FALSE;
9023089Swyllys 			else
9033089Swyllys 				return (PK_ERR_USAGE);
9043089Swyllys 			break;
9055051Swyllys 		case 'E':
9065051Swyllys 			keytype = optarg_av;
9075051Swyllys 			break;
9085051Swyllys 		case 's':
9095051Swyllys 			if (senstr)
9105051Swyllys 				return (PK_ERR_USAGE);
9115051Swyllys 			senstr = optarg_av;
9125051Swyllys 			break;
9135051Swyllys 		case 'x':
9145051Swyllys 			if (extstr)
9155051Swyllys 				return (PK_ERR_USAGE);
9165051Swyllys 			extstr = optarg_av;
9175051Swyllys 			break;
918864Sdinak 		default:
919864Sdinak 			return (PK_ERR_USAGE);
920864Sdinak 			break;
921864Sdinak 		}
922864Sdinak 	}
92317Sdinak 
9243089Swyllys 	/* Assume keystore = PKCS#11 if not specified */
9253089Swyllys 	if (kstype == 0)
9263089Swyllys 		kstype = KMF_KEYSTORE_PK11TOKEN;
927864Sdinak 
928864Sdinak 	/* Filename arg is required. */
9293089Swyllys 	if (EMPTYSTRING(filename)) {
9303089Swyllys 		cryptoerror(LOG_STDERR, gettext("The 'infile' parameter"
9315051Swyllys 		    "is required for the import operation.\n"));
93217Sdinak 		return (PK_ERR_USAGE);
9333089Swyllys 	}
93417Sdinak 
935864Sdinak 	/* No additional args allowed. */
936864Sdinak 	argc -= optind_av;
937864Sdinak 	argv += optind_av;
938864Sdinak 	if (argc)
939864Sdinak 		return (PK_ERR_USAGE);
94017Sdinak 
9416884Swyllys 	DIR_OPTION_CHECK(kstype, dir);
9426884Swyllys 
9433089Swyllys 	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
9443089Swyllys 	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
9455051Swyllys 	    kstype != KMF_KEYSTORE_PK11TOKEN) {
9463089Swyllys 
9473089Swyllys 		(void) fprintf(stderr, gettext("The objtype parameter "
9485051Swyllys 		    "is only relevant if keystore=pkcs11\n"));
9493089Swyllys 		return (PK_ERR_USAGE);
95017Sdinak 	}
95117Sdinak 
9523089Swyllys 	/*
9533089Swyllys 	 * You must specify a certlabel (cert label) when importing
9543089Swyllys 	 * into NSS or PKCS#11.
9553089Swyllys 	 */
9563089Swyllys 	if (kstype == KMF_KEYSTORE_NSS &&
9575051Swyllys 	    (oclass != PK_CRL_OBJ) && EMPTYSTRING(label)) {
9583089Swyllys 		cryptoerror(LOG_STDERR, gettext("The 'label' argument "
9595051Swyllys 		    "is required for this operation\n"));
9603089Swyllys 		return (PK_ERR_USAGE);
96117Sdinak 	}
96217Sdinak 
9635051Swyllys 	if ((rv = kmf_get_file_format(filename, &kfmt)) != KMF_OK) {
9645051Swyllys 		/*
9655051Swyllys 		 * Allow for raw key data to be imported.
9665051Swyllys 		 */
9675051Swyllys 		if (rv == KMF_ERR_ENCODING) {
9685051Swyllys 			rv = KMF_OK;
9695051Swyllys 			kfmt = KMF_FORMAT_RAWKEY;
9705051Swyllys 			/*
9715051Swyllys 			 * Set the object class only if it was not
9725051Swyllys 			 * given on the command line or if it was
9735051Swyllys 			 * specified as a symmetric key object.
9745051Swyllys 			 */
9755051Swyllys 			if (oclass == 0 || (oclass & PK_SYMKEY_OBJ)) {
9765051Swyllys 				oclass = PK_SYMKEY_OBJ;
9775051Swyllys 			} else {
9785051Swyllys 				cryptoerror(LOG_STDERR, gettext(
9795051Swyllys 				    "The input file does not contain the "
9805051Swyllys 				    "object type indicated on command "
9815051Swyllys 				    "line."));
9825051Swyllys 				return (KMF_ERR_BAD_PARAMETER);
9835051Swyllys 			}
9845051Swyllys 		} else {
9855051Swyllys 			cryptoerror(LOG_STDERR,
9865051Swyllys 			    gettext("File format not recognized."));
9875051Swyllys 			return (rv);
9885051Swyllys 		}
9895051Swyllys 	}
9905051Swyllys 
9915051Swyllys 	/* Check parameters for raw key import operation */
9925051Swyllys 	if (kfmt == KMF_FORMAT_RAWKEY) {
9935051Swyllys 		if (keytype != NULL &&
9945051Swyllys 		    Str2SymKeyType(keytype, &keyAlg) != 0) {
9955051Swyllys 			cryptoerror(LOG_STDERR,
9965051Swyllys 			    gettext("Unrecognized keytype(%s).\n"), keytype);
9975051Swyllys 			return (PK_ERR_USAGE);
9985051Swyllys 		}
9995051Swyllys 		if (senstr != NULL && extstr != NULL &&
10005051Swyllys 		    kstype != KMF_KEYSTORE_PK11TOKEN) {
10015051Swyllys 			cryptoerror(LOG_STDERR,
10025051Swyllys 			    gettext("The sensitive or extractable option "
10035051Swyllys 			    "applies only when importing a key from a file "
10045051Swyllys 			    "into a PKCS#11 keystore.\n"));
10053089Swyllys 			return (PK_ERR_USAGE);
10063089Swyllys 		}
100717Sdinak 	}
100817Sdinak 
10095051Swyllys 	/* If no objtype was given, treat it as a certificate */
10103089Swyllys 	if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 ||
10115051Swyllys 	    kfmt == KMF_FORMAT_PEM))
10123089Swyllys 		oclass = PK_CERT_OBJ;
101317Sdinak 
10143089Swyllys 	if (kstype == KMF_KEYSTORE_NSS) {
10153089Swyllys 		if (oclass == PK_CRL_OBJ &&
10165051Swyllys 		    (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
10173089Swyllys 			cryptoerror(LOG_STDERR, gettext(
10185051Swyllys 			    "CRL data can only be imported as DER or "
10195051Swyllys 			    "PEM format"));
10203089Swyllys 			return (PK_ERR_USAGE);
10213089Swyllys 		}
10223089Swyllys 
10233089Swyllys 		if (oclass == PK_CERT_OBJ &&
10245051Swyllys 		    (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
10253089Swyllys 			cryptoerror(LOG_STDERR, gettext(
10265051Swyllys 			    "Certificates can only be imported as DER or "
10275051Swyllys 			    "PEM format"));
10283089Swyllys 			return (PK_ERR_USAGE);
10293089Swyllys 		}
10303089Swyllys 
10313089Swyllys 		/* we do not import private keys except in PKCS12 bundles */
10323089Swyllys 		if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) {
10333089Swyllys 			cryptoerror(LOG_STDERR, gettext(
10345051Swyllys 			    "Private key data can only be imported as part "
10355051Swyllys 			    "of a PKCS12 file.\n"));
10363089Swyllys 			return (PK_ERR_USAGE);
10373089Swyllys 		}
103817Sdinak 	}
103917Sdinak 
10403089Swyllys 	if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) {
10413089Swyllys 		if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) {
104217Sdinak 			cryptoerror(LOG_STDERR, gettext(
10435051Swyllys 			    "The 'outkey' and 'outcert' parameters "
10445051Swyllys 			    "are required for the import operation "
10455051Swyllys 			    "when the 'file' keystore is used.\n"));
10463089Swyllys 			return (PK_ERR_USAGE);
104717Sdinak 		}
104817Sdinak 	}
104917Sdinak 
10503089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec))
10513089Swyllys 		token_spec = PK_DEFAULT_PK11TOKEN;
10523089Swyllys 	else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec))
10533089Swyllys 		token_spec = DEFAULT_NSS_TOKEN;
10543089Swyllys 
10553089Swyllys 	if (kfmt == KMF_FORMAT_PKCS12) {
10563089Swyllys 		(void) get_pk12_password(&pk12cred);
10573089Swyllys 	}
10583089Swyllys 
10595051Swyllys 	if ((kfmt == KMF_FORMAT_PKCS12 || kfmt == KMF_FORMAT_RAWKEY ||
10605051Swyllys 	    (kfmt == KMF_FORMAT_PEM && (oclass & PK_KEY_OBJ))) &&
10615051Swyllys 	    (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)) {
10625051Swyllys 		(void) get_token_password(kstype, token_spec, &tokencred);
10635051Swyllys 	}
10645051Swyllys 
10655051Swyllys 	if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
10663089Swyllys 		cryptoerror(LOG_STDERR, gettext("Error initializing "
10675051Swyllys 		    "KMF: 0x%02x\n"), rv);
10683089Swyllys 		goto end;
10693089Swyllys 	}
107017Sdinak 
10713089Swyllys 	switch (kstype) {
10723089Swyllys 		case KMF_KEYSTORE_PK11TOKEN:
10733089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
10743089Swyllys 				rv = pk_import_pk12_pk11(
10755051Swyllys 				    kmfhandle, &pk12cred,
10765051Swyllys 				    &tokencred, label,
10775051Swyllys 				    token_spec, filename);
10783089Swyllys 			else if (oclass == PK_CERT_OBJ)
10793089Swyllys 				rv = pk_import_cert(
10805051Swyllys 				    kmfhandle, kstype,
10815051Swyllys 				    label, token_spec,
10825051Swyllys 				    filename,
10835051Swyllys 				    NULL, NULL, NULL);
10843089Swyllys 			else if (oclass == PK_CRL_OBJ)
10853089Swyllys 				rv = pk_import_file_crl(
10865051Swyllys 				    kmfhandle, filename,
10876669Swyllys 				    crlfile, okfmt);
10885051Swyllys 			else if (kfmt == KMF_FORMAT_RAWKEY &&
10895051Swyllys 			    oclass == PK_SYMKEY_OBJ) {
10905051Swyllys 				rv = pk_import_rawkey(kmfhandle,
10915051Swyllys 				    kstype, token_spec, &tokencred,
10925051Swyllys 				    filename, label,
10935051Swyllys 				    keyAlg, senstr, extstr);
10945051Swyllys 			} else if (kfmt == KMF_FORMAT_PEM ||
10955051Swyllys 			    kfmt == KMF_FORMAT_PEM_KEYPAIR) {
10965051Swyllys 				rv = pk_import_keys(kmfhandle,
10975051Swyllys 				    kstype, token_spec, &tokencred,
10985051Swyllys 				    filename, label, senstr, extstr);
10995051Swyllys 			} else {
11005051Swyllys 				rv = PK_ERR_USAGE;
11015051Swyllys 			}
11023089Swyllys 			break;
11033089Swyllys 		case KMF_KEYSTORE_NSS:
11043089Swyllys 			if (dir == NULL)
11053089Swyllys 				dir = PK_DEFAULT_DIRECTORY;
11063089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
11073089Swyllys 				rv = pk_import_pk12_nss(
11085051Swyllys 				    kmfhandle, &pk12cred,
11095051Swyllys 				    &tokencred,
11105051Swyllys 				    token_spec, dir, prefix,
11115051Swyllys 				    label, trustflags, filename);
11123089Swyllys 			else if (oclass == PK_CERT_OBJ) {
11133089Swyllys 				rv = pk_import_cert(
11145051Swyllys 				    kmfhandle, kstype,
11155051Swyllys 				    label, token_spec,
11165051Swyllys 				    filename, dir, prefix, trustflags);
11173089Swyllys 			} else if (oclass == PK_CRL_OBJ) {
11183089Swyllys 				rv = pk_import_nss_crl(
11195051Swyllys 				    kmfhandle, verify_crl_flag,
11205051Swyllys 				    filename, dir, prefix);
11213089Swyllys 			}
11223089Swyllys 			break;
11233089Swyllys 		case KMF_KEYSTORE_OPENSSL:
11243089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
11253089Swyllys 				rv = pk_import_pk12_files(
11265051Swyllys 				    kmfhandle, &pk12cred,
11275051Swyllys 				    filename, certfile, keyfile,
11286669Swyllys 				    okfmt);
11293089Swyllys 			else if (oclass == PK_CRL_OBJ) {
11303089Swyllys 				rv = pk_import_file_crl(
11315051Swyllys 				    kmfhandle, filename,
11326669Swyllys 				    crlfile, okfmt);
11333089Swyllys 			} else
11343089Swyllys 				/*
11353089Swyllys 				 * It doesn't make sense to import anything
11363089Swyllys 				 * else for the files plugin.
11373089Swyllys 				 */
11383089Swyllys 				return (PK_ERR_USAGE);
11393089Swyllys 			break;
11403089Swyllys 		default:
11413089Swyllys 			rv = PK_ERR_USAGE;
11423089Swyllys 			break;
11433089Swyllys 	}
114417Sdinak 
11453089Swyllys end:
11463089Swyllys 	if (rv != KMF_OK)
11473089Swyllys 		display_error(kmfhandle, rv,
11485051Swyllys 		    gettext("Error importing objects"));
11493089Swyllys 
11503089Swyllys 	if (tokencred.cred != NULL)
11513089Swyllys 		free(tokencred.cred);
11523089Swyllys 
11533089Swyllys 	if (pk12cred.cred != NULL)
11543089Swyllys 		free(pk12cred.cred);
11553089Swyllys 
11565051Swyllys 	(void) kmf_finalize(kmfhandle);
11573089Swyllys 
11583089Swyllys 	if (rv != KMF_OK)
11593089Swyllys 		return (PK_ERR_USAGE);
11603089Swyllys 
116117Sdinak 	return (0);
116217Sdinak }
1163