xref: /onnv-gate/usr/src/cmd/cmd-crypto/pktool/import.c (revision 10241:356a64b58ebc)
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 /*
2210179SHuie-Ying.Lee@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
2317Sdinak  * Use is subject to license terms.
2417Sdinak  */
2517Sdinak 
2617Sdinak /*
2717Sdinak  * This file implements the import operation for this tool.
2817Sdinak  * The basic flow of the process is to decrypt the PKCS#12
2917Sdinak  * input file if it has a password, parse the elements in
3017Sdinak  * the file, find the soft token, log into it, import the
3117Sdinak  * PKCS#11 objects into the soft token, and log out.
3217Sdinak  */
3317Sdinak 
3417Sdinak #include <stdio.h>
3517Sdinak #include <stdlib.h>
3617Sdinak #include <string.h>
373089Swyllys #include <ctype.h>
3817Sdinak #include <errno.h>
3917Sdinak #include <fcntl.h>
4017Sdinak #include <sys/types.h>
4117Sdinak #include <sys/stat.h>
4217Sdinak #include "common.h"
433089Swyllys 
443089Swyllys #include <kmfapi.h>
4517Sdinak 
465536Swyllys #define	NEW_ATTRLIST(a, n) \
475536Swyllys { \
485536Swyllys 	a = (KMF_ATTRIBUTE *)malloc(n * sizeof (KMF_ATTRIBUTE)); \
495536Swyllys 	if (a == NULL) { \
505536Swyllys 		rv = KMF_ERR_MEMORY; \
515536Swyllys 		goto end; \
525536Swyllys 	} \
535536Swyllys 	(void) memset(a, 0, n * sizeof (KMF_ATTRIBUTE));  \
545536Swyllys }
555536Swyllys 
563089Swyllys static KMF_RETURN
pk_import_pk12_files(KMF_HANDLE_T kmfhandle,KMF_CREDENTIAL * cred,char * outfile,char * certfile,char * keyfile,KMF_ENCODE_FORMAT outformat)573089Swyllys pk_import_pk12_files(KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *cred,
583089Swyllys 	char *outfile, char *certfile, char *keyfile,
596669Swyllys 	KMF_ENCODE_FORMAT outformat)
6017Sdinak {
613089Swyllys 	KMF_RETURN rv = KMF_OK;
625536Swyllys 	KMF_X509_DER_CERT *certs = NULL;
633089Swyllys 	KMF_RAW_KEY_DATA *keys = NULL;
643089Swyllys 	int ncerts = 0;
653089Swyllys 	int nkeys = 0;
663089Swyllys 	int i;
675051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
685536Swyllys 	KMF_ATTRIBUTE *attrlist = NULL;
695051Swyllys 	int numattr = 0;
7017Sdinak 
715051Swyllys 	rv = kmf_import_objects(kmfhandle, outfile, cred,
725051Swyllys 	    &certs, &ncerts, &keys, &nkeys);
7317Sdinak 
743089Swyllys 	if (rv == KMF_OK) {
753089Swyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
765051Swyllys 		    "key(s) in %s\n"), ncerts, nkeys, outfile);
7717Sdinak 	}
7817Sdinak 
793089Swyllys 	if (rv == KMF_OK && ncerts > 0) {
803089Swyllys 		char newcertfile[MAXPATHLEN];
813089Swyllys 
825536Swyllys 		NEW_ATTRLIST(attrlist,  (3 + (3 * ncerts)));
835536Swyllys 
845051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
855051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
865051Swyllys 		numattr++;
875051Swyllys 
885051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
895051Swyllys 		    KMF_ENCODE_FORMAT_ATTR, &outformat, sizeof (outformat));
905051Swyllys 		numattr++;
913089Swyllys 
923089Swyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
935051Swyllys 			int num = numattr;
945051Swyllys 
953089Swyllys 			/*
963089Swyllys 			 * If storing more than 1 cert, gotta change
973089Swyllys 			 * the name so we don't overwrite the previous one.
983089Swyllys 			 * Just append a _# to the name.
993089Swyllys 			 */
1003089Swyllys 			if (i > 0) {
1013089Swyllys 				(void) snprintf(newcertfile,
1025051Swyllys 				    sizeof (newcertfile), "%s_%d", certfile, i);
1035051Swyllys 
1045051Swyllys 				kmf_set_attr_at_index(attrlist, num,
1055051Swyllys 				    KMF_CERT_FILENAME_ATTR, newcertfile,
1065051Swyllys 				    strlen(newcertfile));
1075051Swyllys 				num++;
1083089Swyllys 			} else {
1095051Swyllys 				kmf_set_attr_at_index(attrlist, num,
1105051Swyllys 				    KMF_CERT_FILENAME_ATTR, certfile,
1115051Swyllys 				    strlen(certfile));
1125051Swyllys 				num++;
1133089Swyllys 			}
1145051Swyllys 
1155536Swyllys 			if (certs[i].kmf_private.label != NULL) {
1165536Swyllys 				kmf_set_attr_at_index(attrlist, num,
1175536Swyllys 				    KMF_CERT_LABEL_ATTR,
1185536Swyllys 				    certs[i].kmf_private.label,
1195536Swyllys 				    strlen(certs[i].kmf_private.label));
1205536Swyllys 				num++;
1215536Swyllys 			}
1225051Swyllys 			kmf_set_attr_at_index(attrlist, num,
1235536Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i].certificate,
1245536Swyllys 			    sizeof (KMF_DATA));
1255051Swyllys 			num++;
1265051Swyllys 			rv = kmf_store_cert(kmfhandle, num, attrlist);
1273089Swyllys 		}
1285536Swyllys 		free(attrlist);
1293089Swyllys 	}
1303089Swyllys 	if (rv == KMF_OK && nkeys > 0) {
1313089Swyllys 		char newkeyfile[MAXPATHLEN];
1325051Swyllys 		numattr = 0;
1335536Swyllys 		NEW_ATTRLIST(attrlist, (4 + (4 * nkeys)));
1345051Swyllys 
1355051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
1365051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
1375051Swyllys 		    sizeof (kstype));
1385051Swyllys 		numattr++;
1395051Swyllys 
1405051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
1415051Swyllys 		    KMF_ENCODE_FORMAT_ATTR, &outformat,
1425051Swyllys 		    sizeof (outformat));
1435051Swyllys 		numattr++;
1445051Swyllys 
1455051Swyllys 		if (cred != NULL && cred->credlen > 0) {
1465051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
1475051Swyllys 			    KMF_CREDENTIAL_ATTR, cred,
1485051Swyllys 			    sizeof (KMF_CREDENTIAL));
1495051Swyllys 			numattr++;
1505051Swyllys 		}
15117Sdinak 
1523089Swyllys 		/* The order of certificates and keys should match */
1533089Swyllys 		for (i = 0; rv == KMF_OK && i < nkeys; i++) {
1545051Swyllys 			int num = numattr;
1553089Swyllys 
1563089Swyllys 			if (i > 0) {
1573089Swyllys 				(void) snprintf(newkeyfile,
1585051Swyllys 				    sizeof (newkeyfile), "%s_%d", keyfile, i);
1595051Swyllys 
1605051Swyllys 				kmf_set_attr_at_index(attrlist, num,
1615051Swyllys 				    KMF_KEY_FILENAME_ATTR, newkeyfile,
1625051Swyllys 				    strlen(newkeyfile));
1635051Swyllys 				num++;
1643089Swyllys 			} else {
1655051Swyllys 				kmf_set_attr_at_index(attrlist, num,
1665051Swyllys 				    KMF_KEY_FILENAME_ATTR, keyfile,
1675051Swyllys 				    strlen(keyfile));
1685051Swyllys 				num++;
1693089Swyllys 			}
17017Sdinak 
1715536Swyllys 			if (i < ncerts) {
1725536Swyllys 				kmf_set_attr_at_index(attrlist, num,
1735536Swyllys 				    KMF_CERT_DATA_ATTR, &certs[i],
1745536Swyllys 				    sizeof (KMF_CERT_DATA_ATTR));
1755536Swyllys 				num++;
1765536Swyllys 			}
1775051Swyllys 
1785051Swyllys 			kmf_set_attr_at_index(attrlist, num,
1795051Swyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
1805051Swyllys 			    sizeof (KMF_RAW_KEY_DATA));
1815051Swyllys 			num++;
1825051Swyllys 
1835051Swyllys 			rv = kmf_store_key(kmfhandle, num, attrlist);
1843089Swyllys 		}
1855536Swyllys 		free(attrlist);
1863089Swyllys 	}
1875536Swyllys end:
1883089Swyllys 	/*
1893089Swyllys 	 * Cleanup memory.
1903089Swyllys 	 */
1913089Swyllys 	if (certs) {
1923089Swyllys 		for (i = 0; i < ncerts; i++)
1935536Swyllys 			kmf_free_kmf_cert(kmfhandle, &certs[i]);
1943089Swyllys 		free(certs);
1953089Swyllys 	}
1963089Swyllys 	if (keys) {
1973089Swyllys 		for (i = 0; i < nkeys; i++)
1985051Swyllys 			kmf_free_raw_key(&keys[i]);
1993089Swyllys 		free(keys);
20017Sdinak 	}
20117Sdinak 
20217Sdinak 
2033089Swyllys 	return (rv);
20417Sdinak }
20517Sdinak 
2063089Swyllys 
2073089Swyllys static KMF_RETURN
pk_import_pk12_nss(KMF_HANDLE_T kmfhandle,KMF_CREDENTIAL * kmfcred,KMF_CREDENTIAL * tokencred,char * token_spec,char * dir,char * prefix,char * nickname,char * trustflags,char * filename)2083089Swyllys pk_import_pk12_nss(
2093089Swyllys 	KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *kmfcred,
2103089Swyllys 	KMF_CREDENTIAL *tokencred,
2113089Swyllys 	char *token_spec, char *dir, char *prefix,
2123089Swyllys 	char *nickname, char *trustflags, char *filename)
21317Sdinak {
2143089Swyllys 	KMF_RETURN rv = KMF_OK;
2155536Swyllys 	KMF_X509_DER_CERT *certs = NULL;
2163089Swyllys 	KMF_RAW_KEY_DATA *keys = NULL;
2173089Swyllys 	int ncerts = 0;
2183089Swyllys 	int nkeys = 0;
2193089Swyllys 	int i;
2205051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
2215536Swyllys 	KMF_ATTRIBUTE *attrlist = NULL;
2225051Swyllys 	int numattr = 0;
2233089Swyllys 
2243089Swyllys 	rv = configure_nss(kmfhandle, dir, prefix);
2253089Swyllys 	if (rv != KMF_OK)
2263089Swyllys 		return (rv);
2273089Swyllys 
2285051Swyllys 	rv = kmf_import_objects(kmfhandle, filename, kmfcred,
2295051Swyllys 	    &certs, &ncerts, &keys, &nkeys);
2303089Swyllys 
2313089Swyllys 	if (rv == KMF_OK)
2323089Swyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
2335051Swyllys 		    "key(s) in %s\n"), ncerts, nkeys, filename);
23417Sdinak 
2353089Swyllys 	if (rv == KMF_OK) {
2367108Swyllys 		numattr = 0;
2377108Swyllys 		NEW_ATTRLIST(attrlist, (4 + (2 * nkeys)));
2387108Swyllys 
2397108Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
2407108Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
2417108Swyllys 		    sizeof (kstype));
2427108Swyllys 		numattr++;
2437108Swyllys 
2447108Swyllys 		if (token_spec != NULL) {
2457108Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
2467108Swyllys 			    KMF_TOKEN_LABEL_ATTR, token_spec,
2477108Swyllys 			    strlen(token_spec));
2487108Swyllys 			numattr++;
2497108Swyllys 		}
2507108Swyllys 
2517108Swyllys 		if (nickname != NULL) {
2527108Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
2537108Swyllys 			    KMF_KEYLABEL_ATTR, nickname,
2547108Swyllys 			    strlen(nickname));
2557108Swyllys 			numattr++;
2567108Swyllys 		}
2577108Swyllys 
2587108Swyllys 		if (tokencred->credlen > 0) {
2597108Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
2607108Swyllys 			    KMF_CREDENTIAL_ATTR, tokencred,
2617108Swyllys 			    sizeof (KMF_CREDENTIAL));
2627108Swyllys 			numattr++;
2637108Swyllys 		}
2647108Swyllys 
2657108Swyllys 		/* The order of certificates and keys should match */
2667108Swyllys 		for (i = 0; i < nkeys; i++) {
2677108Swyllys 			int num = numattr;
2687108Swyllys 
2697108Swyllys 			if (i < ncerts) {
2707108Swyllys 				kmf_set_attr_at_index(attrlist, num,
2717108Swyllys 				    KMF_CERT_DATA_ATTR, &certs[i],
2727108Swyllys 				    sizeof (KMF_DATA));
2737108Swyllys 				num++;
2747108Swyllys 			}
2757108Swyllys 
2767108Swyllys 			kmf_set_attr_at_index(attrlist, num,
2777108Swyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
2787108Swyllys 			    sizeof (KMF_RAW_KEY_DATA));
2797108Swyllys 			num++;
2807108Swyllys 
2817108Swyllys 			rv = kmf_store_key(kmfhandle, num, attrlist);
2827108Swyllys 		}
2837108Swyllys 		free(attrlist);
2847108Swyllys 		attrlist = NULL;
2857108Swyllys 	}
2867108Swyllys 
2877108Swyllys 	if (rv == KMF_OK) {
28810179SHuie-Ying.Lee@Sun.COM 		numattr = 0;
2895536Swyllys 		NEW_ATTRLIST(attrlist, (3 + (2 * ncerts)));
2905536Swyllys 
2915051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
2925051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
2935051Swyllys 		numattr++;
29417Sdinak 
2955051Swyllys 		if (token_spec != NULL) {
2965051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
2975051Swyllys 			    KMF_TOKEN_LABEL_ATTR, token_spec,
2985051Swyllys 			    strlen(token_spec));
2995051Swyllys 			numattr++;
3005051Swyllys 		}
3015051Swyllys 
3025051Swyllys 		if (trustflags != NULL) {
3035051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
3045051Swyllys 			    KMF_TRUSTFLAG_ATTR, trustflags,
3055051Swyllys 			    strlen(trustflags));
3065051Swyllys 			numattr++;
3075051Swyllys 		}
30817Sdinak 
3093089Swyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
3105051Swyllys 			int num = numattr;
31117Sdinak 
3125536Swyllys 			if (certs[i].kmf_private.label != NULL) {
3135536Swyllys 				kmf_set_attr_at_index(attrlist, num,
3145536Swyllys 				    KMF_CERT_LABEL_ATTR,
3155536Swyllys 				    certs[i].kmf_private.label,
3165536Swyllys 				    strlen(certs[i].kmf_private.label));
3175536Swyllys 				num++;
3185536Swyllys 			} else if (i == 0 && nickname != NULL) {
3195051Swyllys 				kmf_set_attr_at_index(attrlist, num,
3205051Swyllys 				    KMF_CERT_LABEL_ATTR, nickname,
3215051Swyllys 				    strlen(nickname));
3225051Swyllys 				num++;
3235051Swyllys 			}
3245051Swyllys 
3255051Swyllys 			kmf_set_attr_at_index(attrlist, num,
3265536Swyllys 			    KMF_CERT_DATA_ATTR,
3275536Swyllys 			    &certs[i].certificate, sizeof (KMF_DATA));
3285051Swyllys 			num++;
3295051Swyllys 			rv = kmf_store_cert(kmfhandle, num, attrlist);
3303089Swyllys 		}
3315536Swyllys 		free(attrlist);
3325536Swyllys 		attrlist = NULL;
3333089Swyllys 		if (rv != KMF_OK) {
3343089Swyllys 			display_error(kmfhandle, rv,
3355051Swyllys 			    gettext("Error storing certificate in NSS token"));
3363089Swyllys 		}
33717Sdinak 	}
33817Sdinak 
3395536Swyllys end:
3403089Swyllys 	/*
3413089Swyllys 	 * Cleanup memory.
3423089Swyllys 	 */
3433089Swyllys 	if (certs) {
3443089Swyllys 		for (i = 0; i < ncerts; i++)
3455536Swyllys 			kmf_free_kmf_cert(kmfhandle, &certs[i]);
3463089Swyllys 		free(certs);
3473089Swyllys 	}
3483089Swyllys 	if (keys) {
3493089Swyllys 		for (i = 0; i < nkeys; i++)
3505051Swyllys 			kmf_free_raw_key(&keys[i]);
3513089Swyllys 		free(keys);
35217Sdinak 	}
35317Sdinak 
3543089Swyllys 	return (rv);
3553089Swyllys }
35617Sdinak 
3573089Swyllys static KMF_RETURN
pk_import_cert(KMF_HANDLE_T kmfhandle,KMF_KEYSTORE_TYPE kstype,char * label,char * token_spec,char * filename,char * dir,char * prefix,char * trustflags)3583089Swyllys pk_import_cert(
3593089Swyllys 	KMF_HANDLE_T kmfhandle,
3603089Swyllys 	KMF_KEYSTORE_TYPE kstype,
3613089Swyllys 	char *label, char *token_spec, char *filename,
3623089Swyllys 	char *dir, char *prefix, char *trustflags)
3633089Swyllys {
3643089Swyllys 	KMF_RETURN rv = KMF_OK;
3655051Swyllys 	KMF_ATTRIBUTE attrlist[32];
3666354Swyllys 	KMF_CREDENTIAL tokencred;
3675051Swyllys 	int i = 0;
36817Sdinak 
3693089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
3703089Swyllys 		rv = select_token(kmfhandle, token_spec, FALSE);
3715051Swyllys 	} else if (kstype == KMF_KEYSTORE_NSS) {
3725051Swyllys 		rv = configure_nss(kmfhandle, dir, prefix);
3735051Swyllys 	}
3745051Swyllys 	if (rv != KMF_OK)
3755051Swyllys 		return (rv);
37617Sdinak 
3775051Swyllys 	kmf_set_attr_at_index(attrlist, i,
3785051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (KMF_KEYSTORE_TYPE));
3795051Swyllys 	i++;
3805051Swyllys 
3815051Swyllys 	kmf_set_attr_at_index(attrlist, i, KMF_CERT_FILENAME_ATTR,
3825051Swyllys 	    filename, strlen(filename));
3835051Swyllys 	i++;
3845051Swyllys 
3855051Swyllys 	if (label != NULL) {
3865051Swyllys 		kmf_set_attr_at_index(attrlist, i, KMF_CERT_LABEL_ATTR,
3875051Swyllys 		    label, strlen(label));
3885051Swyllys 		i++;
3895051Swyllys 	}
3905051Swyllys 
3915051Swyllys 	if (kstype == KMF_KEYSTORE_NSS) {
3925051Swyllys 		if (trustflags != NULL) {
3935051Swyllys 			kmf_set_attr_at_index(attrlist, i, KMF_TRUSTFLAG_ATTR,
3945051Swyllys 			    trustflags, strlen(trustflags));
3955051Swyllys 			i++;
3965051Swyllys 		}
3975051Swyllys 
3985051Swyllys 		if (token_spec != NULL) {
3995051Swyllys 			kmf_set_attr_at_index(attrlist, i,
4005051Swyllys 			    KMF_TOKEN_LABEL_ATTR,
4015051Swyllys 			    token_spec, strlen(token_spec));
4025051Swyllys 			i++;
40317Sdinak 		}
4043089Swyllys 	}
40517Sdinak 
4065051Swyllys 	rv = kmf_import_cert(kmfhandle, i, attrlist);
4076354Swyllys 	if (rv == KMF_ERR_AUTH_FAILED) {
4086354Swyllys 		/*
4096354Swyllys 		 * The token requires a credential, prompt and try again.
4106354Swyllys 		 */
4116354Swyllys 		(void) get_token_password(kstype, token_spec, &tokencred);
4126354Swyllys 		kmf_set_attr_at_index(attrlist, i, KMF_CREDENTIAL_ATTR,
4136354Swyllys 		    &tokencred, sizeof (KMF_CREDENTIAL));
4146354Swyllys 		i++;
4156354Swyllys 
4166354Swyllys 		rv = kmf_import_cert(kmfhandle, i, attrlist);
4176354Swyllys 
4186354Swyllys 	}
4193089Swyllys 	return (rv);
4203089Swyllys }
4213089Swyllys 
4223089Swyllys static KMF_RETURN
pk_import_file_crl(void * kmfhandle,char * infile,char * outfile,KMF_ENCODE_FORMAT outfmt)4233089Swyllys pk_import_file_crl(void *kmfhandle,
4243089Swyllys 	char *infile,
4253089Swyllys 	char *outfile,
4263089Swyllys 	KMF_ENCODE_FORMAT outfmt)
4273089Swyllys {
4285051Swyllys 	int numattr = 0;
4295051Swyllys 	KMF_ATTRIBUTE attrlist[8];
4305051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
4313089Swyllys 
4325051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
4335051Swyllys 	    &kstype, sizeof (kstype));
4345051Swyllys 	numattr++;
4355051Swyllys 	if (infile) {
4365051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
4375051Swyllys 		    KMF_CRL_FILENAME_ATTR, infile, strlen(infile));
4385051Swyllys 		numattr++;
4395051Swyllys 	}
4405051Swyllys 	if (outfile) {
4415051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
4425051Swyllys 		    KMF_CRL_OUTFILE_ATTR, outfile, strlen(outfile));
4435051Swyllys 		numattr++;
4445051Swyllys 	}
4455051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
4465051Swyllys 	    KMF_ENCODE_FORMAT_ATTR, &outfmt, sizeof (outfmt));
4475051Swyllys 	numattr++;
4483089Swyllys 
4495051Swyllys 	return (kmf_import_crl(kmfhandle, numattr, attrlist));
4503089Swyllys }
4513089Swyllys 
4523089Swyllys static KMF_RETURN
pk_import_nss_crl(void * kmfhandle,boolean_t verify_crl_flag,char * infile,char * outdir,char * prefix)4533089Swyllys pk_import_nss_crl(void *kmfhandle,
4543089Swyllys 	boolean_t verify_crl_flag,
4553089Swyllys 	char *infile,
4563089Swyllys 	char *outdir,
4573089Swyllys 	char *prefix)
4583089Swyllys {
4593089Swyllys 	KMF_RETURN rv;
4605051Swyllys 	int numattr = 0;
4615051Swyllys 	KMF_ATTRIBUTE attrlist[4];
4625051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
4633089Swyllys 
4643089Swyllys 	rv = configure_nss(kmfhandle, outdir, prefix);
4653089Swyllys 	if (rv != KMF_OK)
4663089Swyllys 		return (rv);
4673089Swyllys 
4685051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
4695051Swyllys 	    &kstype, sizeof (kstype));
4705051Swyllys 	numattr++;
4715051Swyllys 	if (infile) {
4725051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR,
4735051Swyllys 		    infile, strlen(infile));
4745051Swyllys 		numattr++;
4755051Swyllys 	}
4765051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_CHECK_ATTR,
4775051Swyllys 	    &verify_crl_flag, sizeof (verify_crl_flag));
4785051Swyllys 	numattr++;
4793089Swyllys 
4805051Swyllys 	return (kmf_import_crl(kmfhandle, numattr, attrlist));
4813089Swyllys 
4823089Swyllys }
4833089Swyllys 
4843089Swyllys static KMF_RETURN
pk_import_pk12_pk11(KMF_HANDLE_T kmfhandle,KMF_CREDENTIAL * p12cred,KMF_CREDENTIAL * tokencred,char * label,char * token_spec,char * filename)4853089Swyllys pk_import_pk12_pk11(
4863089Swyllys 	KMF_HANDLE_T kmfhandle,
4873089Swyllys 	KMF_CREDENTIAL *p12cred,
4883089Swyllys 	KMF_CREDENTIAL *tokencred,
4893089Swyllys 	char *label, char *token_spec,
4903089Swyllys 	char *filename)
4913089Swyllys {
4923089Swyllys 	KMF_RETURN rv = KMF_OK;
4935536Swyllys 	KMF_X509_DER_CERT *certs = NULL;
4943089Swyllys 	KMF_RAW_KEY_DATA *keys = NULL;
4953089Swyllys 	int ncerts = 0;
4963089Swyllys 	int nkeys = 0;
4973089Swyllys 	int i;
4985051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
4995536Swyllys 	KMF_ATTRIBUTE *attrlist = NULL;
5005051Swyllys 	int numattr = 0;
5013089Swyllys 
5023089Swyllys 	rv = select_token(kmfhandle, token_spec, FALSE);
5033089Swyllys 
5043089Swyllys 	if (rv != KMF_OK) {
50517Sdinak 		return (rv);
50617Sdinak 	}
50717Sdinak 
5085051Swyllys 	rv = kmf_import_objects(kmfhandle, filename, p12cred,
5095051Swyllys 	    &certs, &ncerts, &keys, &nkeys);
5103089Swyllys 
5113089Swyllys 	if (rv == KMF_OK) {
5125536Swyllys 		NEW_ATTRLIST(attrlist, (3 + (2 * nkeys)));
5135051Swyllys 
5145051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
5155051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
5165051Swyllys 		    sizeof (kstype));
5175051Swyllys 		numattr++;
5185051Swyllys 
5195051Swyllys 		if (label != NULL) {
5205051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
5215051Swyllys 			    KMF_KEYLABEL_ATTR, label,
5225051Swyllys 			    strlen(label));
5235051Swyllys 			numattr++;
5245051Swyllys 		}
5255051Swyllys 
5265051Swyllys 		if (tokencred != NULL && tokencred->credlen > 0) {
5275051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
5285051Swyllys 			    KMF_CREDENTIAL_ATTR, tokencred,
5295051Swyllys 			    sizeof (KMF_CREDENTIAL));
5305051Swyllys 			numattr++;
5315051Swyllys 		}
5323089Swyllys 
5333089Swyllys 		/* The order of certificates and keys should match */
5343089Swyllys 		for (i = 0; i < nkeys; i++) {
5355051Swyllys 			int num = numattr;
5365051Swyllys 
5375536Swyllys 			if (i < ncerts) {
5385536Swyllys 				kmf_set_attr_at_index(attrlist, num,
5395536Swyllys 				    KMF_CERT_DATA_ATTR, &certs[i].certificate,
5405536Swyllys 				    sizeof (KMF_DATA));
5415536Swyllys 				num++;
5425536Swyllys 			}
5433089Swyllys 
5445051Swyllys 			kmf_set_attr_at_index(attrlist, num,
5455051Swyllys 			    KMF_RAW_KEY_ATTR, &keys[i],
5465051Swyllys 			    sizeof (KMF_RAW_KEY_DATA));
5475051Swyllys 			num++;
5485051Swyllys 
5495051Swyllys 			rv = kmf_store_key(kmfhandle, num, attrlist);
5505051Swyllys 
5513089Swyllys 		}
5525536Swyllys 		free(attrlist);
5533089Swyllys 	}
5543089Swyllys 
5553089Swyllys 	if (rv == KMF_OK) {
5565536Swyllys 		numattr = 0;
5575536Swyllys 		NEW_ATTRLIST(attrlist, (1 + (2 * ncerts)));
5583089Swyllys 
5593089Swyllys 		(void) printf(gettext("Found %d certificate(s) and %d "
5605051Swyllys 		    "key(s) in %s\n"), ncerts, nkeys, filename);
5615536Swyllys 
5625051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
5635051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
5645051Swyllys 		numattr++;
5653089Swyllys 
5663089Swyllys 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
5675051Swyllys 			int num = numattr;
5685536Swyllys 			if (certs[i].kmf_private.label != NULL) {
5695536Swyllys 				kmf_set_attr_at_index(attrlist, num,
5705536Swyllys 				    KMF_CERT_LABEL_ATTR,
5715536Swyllys 				    certs[i].kmf_private.label,
5725536Swyllys 				    strlen(certs[i].kmf_private.label));
5735536Swyllys 				num++;
5745536Swyllys 			} else if (i == 0 && label != NULL) {
5755051Swyllys 				kmf_set_attr_at_index(attrlist, num,
5765051Swyllys 				    KMF_CERT_LABEL_ATTR, label, strlen(label));
5775051Swyllys 				num++;
5785051Swyllys 			}
5795051Swyllys 
5805051Swyllys 			kmf_set_attr_at_index(attrlist, num,
5815536Swyllys 			    KMF_CERT_DATA_ATTR, &certs[i].certificate,
5825536Swyllys 			    sizeof (KMF_DATA));
5835051Swyllys 			num++;
5845051Swyllys 
5855051Swyllys 			rv = kmf_store_cert(kmfhandle, num, attrlist);
5863089Swyllys 		}
5875536Swyllys 		free(attrlist);
5883089Swyllys 	}
5893089Swyllys 
5905536Swyllys end:
5913089Swyllys 	/*
5923089Swyllys 	 * Cleanup memory.
5933089Swyllys 	 */
5943089Swyllys 	if (certs) {
5953089Swyllys 		for (i = 0; i < ncerts; i++)
5965536Swyllys 			kmf_free_kmf_cert(kmfhandle, &certs[i]);
5973089Swyllys 		free(certs);
5983089Swyllys 	}
5993089Swyllys 	if (keys) {
6003089Swyllys 		for (i = 0; i < nkeys; i++)
6015051Swyllys 			kmf_free_raw_key(&keys[i]);
6023089Swyllys 		free(keys);
6033089Swyllys 	}
6043089Swyllys 
6053089Swyllys 	return (rv);
60617Sdinak }
60717Sdinak 
6085069Swyllys /*ARGSUSED*/
6095051Swyllys static KMF_RETURN
pk_import_keys(KMF_HANDLE_T kmfhandle,KMF_KEYSTORE_TYPE kstype,char * token_spec,KMF_CREDENTIAL * cred,char * filename,char * label,char * senstr,char * extstr)6105051Swyllys pk_import_keys(KMF_HANDLE_T kmfhandle,
6115051Swyllys 	KMF_KEYSTORE_TYPE kstype, char *token_spec,
6125051Swyllys 	KMF_CREDENTIAL *cred, char *filename,
6135051Swyllys 	char *label, char *senstr, char *extstr)
6145051Swyllys {
6155051Swyllys 	KMF_RETURN rv = KMF_OK;
6165051Swyllys 	KMF_ATTRIBUTE attrlist[16];
6175051Swyllys 	KMF_KEYSTORE_TYPE fileks = KMF_KEYSTORE_OPENSSL;
6185051Swyllys 	int numattr = 0;
6195051Swyllys 	KMF_KEY_HANDLE key;
6205051Swyllys 	KMF_RAW_KEY_DATA rawkey;
6215051Swyllys 	KMF_KEY_CLASS class = KMF_ASYM_PRI;
6225051Swyllys 	int numkeys = 1;
6235051Swyllys 
6245051Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
6255051Swyllys 		rv = select_token(kmfhandle, token_spec, FALSE);
6265051Swyllys 	}
6275051Swyllys 	if (rv != KMF_OK)
6285051Swyllys 		return (rv);
6295051Swyllys 	/*
6305051Swyllys 	 * First, set up to read the keyfile using the FILE plugin
6315051Swyllys 	 * mechanisms.
6325051Swyllys 	 */
6335051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
6345051Swyllys 	    &fileks, sizeof (fileks));
6355051Swyllys 	numattr++;
6365051Swyllys 
6375051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
6385051Swyllys 	    &numkeys, sizeof (numkeys));
6395051Swyllys 	numattr++;
6405051Swyllys 
6415051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
6425051Swyllys 	    &key, sizeof (key));
6435051Swyllys 	numattr++;
6445051Swyllys 
6455051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR,
6465051Swyllys 	    &rawkey, sizeof (rawkey));
6475051Swyllys 	numattr++;
6485051Swyllys 
6495051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
6505051Swyllys 	    &class, sizeof (class));
6515051Swyllys 	numattr++;
6525051Swyllys 
6535051Swyllys 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
6545051Swyllys 	    filename, strlen(filename));
6555051Swyllys 	numattr++;
6565051Swyllys 
6575051Swyllys 	rv = kmf_find_key(kmfhandle, numattr, attrlist);
6585051Swyllys 	if (rv == KMF_OK) {
6595051Swyllys 		numattr = 0;
6605051Swyllys 
6615051Swyllys 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
6625051Swyllys 		    &kstype, sizeof (kstype));
6635051Swyllys 		numattr++;
6645051Swyllys 
6655051Swyllys 		if (cred != NULL && cred->credlen > 0) {
6665051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
6675051Swyllys 			    KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
6685051Swyllys 			numattr++;
6695051Swyllys 		}
6705051Swyllys 
6715051Swyllys 		if (label != NULL) {
6725051Swyllys 			kmf_set_attr_at_index(attrlist, numattr,
6735051Swyllys 			    KMF_KEYLABEL_ATTR, label, strlen(label));
6745051Swyllys 			numattr++;
6755051Swyllys 		}
6765051Swyllys 
6775051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
6785051Swyllys 		    KMF_RAW_KEY_ATTR, &rawkey, sizeof (rawkey));
6795051Swyllys 		numattr++;
6805051Swyllys 
6815051Swyllys 		rv = kmf_store_key(kmfhandle, numattr, attrlist);
6825051Swyllys 		if (rv == KMF_OK) {
6835069Swyllys 			(void) printf(gettext("Importing %d keys\n"), numkeys);
6845051Swyllys 		}
6855051Swyllys 
6865051Swyllys 		kmf_free_kmf_key(kmfhandle, &key);
6875051Swyllys 		kmf_free_raw_key(&rawkey);
6885051Swyllys 	} else {
6895051Swyllys 		cryptoerror(LOG_STDERR,
6905051Swyllys 		    gettext("Failed to load key from file (%s)\n"),
6915051Swyllys 		    filename);
6925051Swyllys 	}
6935051Swyllys 	return (rv);
6945051Swyllys }
6955051Swyllys 
6965051Swyllys static KMF_RETURN
pk_import_rawkey(KMF_HANDLE_T kmfhandle,KMF_KEYSTORE_TYPE kstype,char * token,KMF_CREDENTIAL * cred,char * filename,char * label,KMF_KEY_ALG keyAlg,char * senstr,char * extstr)6975051Swyllys pk_import_rawkey(KMF_HANDLE_T kmfhandle,
6985051Swyllys 	KMF_KEYSTORE_TYPE kstype, char *token,
6995051Swyllys 	KMF_CREDENTIAL *cred,
7005051Swyllys 	char *filename, char *label, KMF_KEY_ALG keyAlg,
7015051Swyllys 	char *senstr, char *extstr)
7025051Swyllys {
7035051Swyllys 	KMF_RETURN rv = KMF_OK;
7045051Swyllys 	KMF_ATTRIBUTE attrlist[16];
7055051Swyllys 	int numattr = 0;
7065051Swyllys 	uint32_t keylen;
7075051Swyllys 	boolean_t sensitive = B_FALSE;
7085051Swyllys 	boolean_t not_extractable = B_FALSE;
7095051Swyllys 	KMF_DATA keydata = {NULL, 0};
7105051Swyllys 	KMF_KEY_HANDLE rawkey;
7115051Swyllys 
7125051Swyllys 	rv = kmf_read_input_file(kmfhandle, filename, &keydata);
7135051Swyllys 	if (rv != KMF_OK)
7145051Swyllys 		return (rv);
7155051Swyllys 
7165051Swyllys 	rv = select_token(kmfhandle, token, FALSE);
7175051Swyllys 
7185051Swyllys 	if (rv != KMF_OK) {
7195051Swyllys 		return (rv);
7205051Swyllys 	}
7215051Swyllys 	if (senstr != NULL) {
7225051Swyllys 		if (tolower(senstr[0]) == 'y')
7235051Swyllys 			sensitive = B_TRUE;
7245051Swyllys 		else if (tolower(senstr[0]) == 'n')
7255051Swyllys 			sensitive = B_FALSE;
7265051Swyllys 		else {
7275051Swyllys 			cryptoerror(LOG_STDERR,
7285051Swyllys 			    gettext("Incorrect sensitive option value.\n"));
7295051Swyllys 			return (KMF_ERR_BAD_PARAMETER);
7305051Swyllys 		}
7315051Swyllys 	}
7325051Swyllys 
7335051Swyllys 	if (extstr != NULL) {
7345051Swyllys 		if (tolower(extstr[0]) == 'y')
7355051Swyllys 			not_extractable = B_FALSE;
7365051Swyllys 		else if (tolower(extstr[0]) == 'n')
7375051Swyllys 			not_extractable = B_TRUE;
7385051Swyllys 		else {
7395051Swyllys 			cryptoerror(LOG_STDERR,
7405051Swyllys 			    gettext("Incorrect extractable option value.\n"));
7415051Swyllys 			return (KMF_ERR_BAD_PARAMETER);
7425051Swyllys 		}
7435051Swyllys 	}
7445051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7455051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
7465051Swyllys 	numattr++;
7475051Swyllys 
7485051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7495051Swyllys 	    KMF_KEY_HANDLE_ATTR, &rawkey, sizeof (rawkey));
7505051Swyllys 	numattr++;
7515051Swyllys 
7525051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7535051Swyllys 	    KMF_KEYALG_ATTR, &keyAlg, sizeof (KMF_KEY_ALG));
7545051Swyllys 	numattr++;
7555051Swyllys 
7565051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7575051Swyllys 	    KMF_KEY_DATA_ATTR, keydata.Data, keydata.Length);
7585051Swyllys 	numattr++;
7595051Swyllys 
7605051Swyllys 	/* Key length is given in bits not bytes */
7615051Swyllys 	keylen = keydata.Length * 8;
7625051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7635051Swyllys 	    KMF_KEYLENGTH_ATTR, &keylen, sizeof (keydata.Length));
7645051Swyllys 	numattr++;
7655051Swyllys 
7665051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7675051Swyllys 	    KMF_SENSITIVE_BOOL_ATTR, &sensitive, sizeof (sensitive));
7685051Swyllys 	numattr++;
7695051Swyllys 
7705051Swyllys 	kmf_set_attr_at_index(attrlist, numattr,
7715051Swyllys 	    KMF_NON_EXTRACTABLE_BOOL_ATTR, &not_extractable,
7725051Swyllys 	    sizeof (not_extractable));
7735051Swyllys 	numattr++;
7745051Swyllys 
7755051Swyllys 	if (label != NULL) {
7765051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
7775051Swyllys 		    KMF_KEYLABEL_ATTR, label, strlen(label));
7785051Swyllys 		numattr++;
7795051Swyllys 	}
7805051Swyllys 	if (cred != NULL && cred->credlen > 0) {
7815051Swyllys 		kmf_set_attr_at_index(attrlist, numattr,
7825051Swyllys 		    KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
7835051Swyllys 		numattr++;
7845051Swyllys 	}
7855051Swyllys 	rv = kmf_create_sym_key(kmfhandle, numattr, attrlist);
7865051Swyllys 
7875051Swyllys 	return (rv);
7885051Swyllys }
7895051Swyllys 
79017Sdinak /*
7913089Swyllys  * Import objects from into KMF repositories.
79217Sdinak  */
79317Sdinak int
pk_import(int argc,char * argv[])79417Sdinak pk_import(int argc, char *argv[])
79517Sdinak {
796864Sdinak 	int		opt;
797864Sdinak 	extern int	optind_av;
798864Sdinak 	extern char	*optarg_av;
799864Sdinak 	char		*token_spec = NULL;
80017Sdinak 	char		*filename = NULL;
8013089Swyllys 	char		*keyfile = NULL;
8023089Swyllys 	char		*certfile = NULL;
8033089Swyllys 	char		*crlfile = NULL;
8045051Swyllys 	char		*label = NULL;
8053089Swyllys 	char		*dir = NULL;
8063089Swyllys 	char		*prefix = NULL;
8073089Swyllys 	char		*trustflags = NULL;
8083089Swyllys 	char		*verify_crl = NULL;
8095051Swyllys 	char		*keytype = "generic";
8105051Swyllys 	char		*senstr = NULL;
8115051Swyllys 	char		*extstr = NULL;
8123089Swyllys 	boolean_t	verify_crl_flag = B_FALSE;
8133089Swyllys 	int		oclass = 0;
8143089Swyllys 	KMF_KEYSTORE_TYPE	kstype = 0;
8153089Swyllys 	KMF_ENCODE_FORMAT	kfmt = 0;
8163089Swyllys 	KMF_ENCODE_FORMAT	okfmt = KMF_FORMAT_ASN1;
8173089Swyllys 	KMF_RETURN		rv = KMF_OK;
8183089Swyllys 	KMF_CREDENTIAL	pk12cred = { NULL, 0 };
8193089Swyllys 	KMF_CREDENTIAL	tokencred = { NULL, 0 };
8203089Swyllys 	KMF_HANDLE_T	kmfhandle = NULL;
8215051Swyllys 	KMF_KEY_ALG	keyAlg = KMF_GENERIC_SECRET;
82217Sdinak 
823864Sdinak 	/* Parse command line options.  Do NOT i18n/l10n. */
8243089Swyllys 	while ((opt = getopt_av(argc, argv,
8255051Swyllys 	    "T:(token)i:(infile)"
8265051Swyllys 	    "k:(keystore)y:(objtype)"
8275051Swyllys 	    "d:(dir)p:(prefix)"
8285051Swyllys 	    "n:(certlabel)N:(label)"
8295051Swyllys 	    "K:(outkey)c:(outcert)"
8305051Swyllys 	    "v:(verifycrl)l:(outcrl)"
8315051Swyllys 	    "E:(keytype)s:(sensitive)x:(extractable)"
8326669Swyllys 	    "t:(trust)F:(outformat)")) != EOF) {
8333089Swyllys 		if (EMPTYSTRING(optarg_av))
8343089Swyllys 			return (PK_ERR_USAGE);
835864Sdinak 		switch (opt) {
836864Sdinak 		case 'T':	/* token specifier */
837864Sdinak 			if (token_spec)
838864Sdinak 				return (PK_ERR_USAGE);
839864Sdinak 			token_spec = optarg_av;
840864Sdinak 			break;
8413089Swyllys 		case 'c':	/* output cert file name */
8423089Swyllys 			if (certfile)
8433089Swyllys 				return (PK_ERR_USAGE);
8443089Swyllys 			certfile = optarg_av;
8453089Swyllys 			break;
8463089Swyllys 		case 'l':	/* output CRL file name */
8473089Swyllys 			if (crlfile)
8483089Swyllys 				return (PK_ERR_USAGE);
8493089Swyllys 			crlfile = optarg_av;
8503089Swyllys 			break;
8513089Swyllys 		case 'K':	/* output key file name */
8523089Swyllys 			if (keyfile)
8533089Swyllys 				return (PK_ERR_USAGE);
8543089Swyllys 			keyfile = optarg_av;
8553089Swyllys 			break;
856864Sdinak 		case 'i':	/* input file name */
857864Sdinak 			if (filename)
858864Sdinak 				return (PK_ERR_USAGE);
859864Sdinak 			filename = optarg_av;
860864Sdinak 			break;
8613089Swyllys 		case 'k':
8623089Swyllys 			kstype = KS2Int(optarg_av);
8633089Swyllys 			if (kstype == 0)
8643089Swyllys 				return (PK_ERR_USAGE);
8653089Swyllys 			break;
8663089Swyllys 		case 'y':
8673089Swyllys 			oclass = OT2Int(optarg_av);
8683089Swyllys 			if (oclass == -1)
8693089Swyllys 				return (PK_ERR_USAGE);
8703089Swyllys 			break;
8713089Swyllys 		case 'd':
8723089Swyllys 			dir = optarg_av;
8733089Swyllys 			break;
8743089Swyllys 		case 'p':
8753089Swyllys 			if (prefix)
8763089Swyllys 				return (PK_ERR_USAGE);
8773089Swyllys 			prefix = optarg_av;
8783089Swyllys 			break;
8793089Swyllys 		case 'n':
8803089Swyllys 		case 'N':
8815051Swyllys 			if (label)
8823089Swyllys 				return (PK_ERR_USAGE);
8835051Swyllys 			label = optarg_av;
8843089Swyllys 			break;
8853089Swyllys 		case 'F':
8863089Swyllys 			okfmt = Str2Format(optarg_av);
8873089Swyllys 			if (okfmt == KMF_FORMAT_UNDEF)
8883089Swyllys 				return (PK_ERR_USAGE);
8893089Swyllys 			break;
8903089Swyllys 		case 't':
8913089Swyllys 			if (trustflags)
8923089Swyllys 				return (PK_ERR_USAGE);
8933089Swyllys 			trustflags = optarg_av;
8943089Swyllys 			break;
8953089Swyllys 		case 'v':
8963089Swyllys 			verify_crl = optarg_av;
8973089Swyllys 			if (tolower(verify_crl[0]) == 'y')
8983089Swyllys 				verify_crl_flag = B_TRUE;
8993089Swyllys 			else if (tolower(verify_crl[0]) == 'n')
9003089Swyllys 				verify_crl_flag = B_FALSE;
9013089Swyllys 			else
9023089Swyllys 				return (PK_ERR_USAGE);
9033089Swyllys 			break;
9045051Swyllys 		case 'E':
9055051Swyllys 			keytype = optarg_av;
9065051Swyllys 			break;
9075051Swyllys 		case 's':
9085051Swyllys 			if (senstr)
9095051Swyllys 				return (PK_ERR_USAGE);
9105051Swyllys 			senstr = optarg_av;
9115051Swyllys 			break;
9125051Swyllys 		case 'x':
9135051Swyllys 			if (extstr)
9145051Swyllys 				return (PK_ERR_USAGE);
9155051Swyllys 			extstr = optarg_av;
9165051Swyllys 			break;
917864Sdinak 		default:
918864Sdinak 			return (PK_ERR_USAGE);
919864Sdinak 			break;
920864Sdinak 		}
921864Sdinak 	}
92217Sdinak 
9233089Swyllys 	/* Assume keystore = PKCS#11 if not specified */
9243089Swyllys 	if (kstype == 0)
9253089Swyllys 		kstype = KMF_KEYSTORE_PK11TOKEN;
926864Sdinak 
927864Sdinak 	/* Filename arg is required. */
9283089Swyllys 	if (EMPTYSTRING(filename)) {
9293089Swyllys 		cryptoerror(LOG_STDERR, gettext("The 'infile' parameter"
9305051Swyllys 		    "is required for the import operation.\n"));
93117Sdinak 		return (PK_ERR_USAGE);
9323089Swyllys 	}
93317Sdinak 
934864Sdinak 	/* No additional args allowed. */
935864Sdinak 	argc -= optind_av;
936864Sdinak 	argv += optind_av;
937864Sdinak 	if (argc)
938864Sdinak 		return (PK_ERR_USAGE);
93917Sdinak 
9406884Swyllys 	DIR_OPTION_CHECK(kstype, dir);
9416884Swyllys 
9423089Swyllys 	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
9433089Swyllys 	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
9445051Swyllys 	    kstype != KMF_KEYSTORE_PK11TOKEN) {
9453089Swyllys 
9463089Swyllys 		(void) fprintf(stderr, gettext("The objtype parameter "
9475051Swyllys 		    "is only relevant if keystore=pkcs11\n"));
9483089Swyllys 		return (PK_ERR_USAGE);
94917Sdinak 	}
95017Sdinak 
9513089Swyllys 	/*
9523089Swyllys 	 * You must specify a certlabel (cert label) when importing
9533089Swyllys 	 * into NSS or PKCS#11.
9543089Swyllys 	 */
9553089Swyllys 	if (kstype == KMF_KEYSTORE_NSS &&
9565051Swyllys 	    (oclass != PK_CRL_OBJ) && EMPTYSTRING(label)) {
9573089Swyllys 		cryptoerror(LOG_STDERR, gettext("The 'label' argument "
9585051Swyllys 		    "is required for this operation\n"));
9593089Swyllys 		return (PK_ERR_USAGE);
96017Sdinak 	}
96117Sdinak 
9625051Swyllys 	if ((rv = kmf_get_file_format(filename, &kfmt)) != KMF_OK) {
963*10241Swyllys.ingersoll@sun.com 		char *kmferrstr = NULL;
964*10241Swyllys.ingersoll@sun.com 		KMF_RETURN rv2;
9655051Swyllys 		/*
9665051Swyllys 		 * Allow for raw key data to be imported.
9675051Swyllys 		 */
9685051Swyllys 		if (rv == KMF_ERR_ENCODING) {
9695051Swyllys 			rv = KMF_OK;
9705051Swyllys 			kfmt = KMF_FORMAT_RAWKEY;
9715051Swyllys 			/*
9725051Swyllys 			 * Set the object class only if it was not
9735051Swyllys 			 * given on the command line or if it was
9745051Swyllys 			 * specified as a symmetric key object.
9755051Swyllys 			 */
9765051Swyllys 			if (oclass == 0 || (oclass & PK_SYMKEY_OBJ)) {
9775051Swyllys 				oclass = PK_SYMKEY_OBJ;
9785051Swyllys 			} else {
9795051Swyllys 				cryptoerror(LOG_STDERR, gettext(
9805051Swyllys 				    "The input file does not contain the "
9815051Swyllys 				    "object type indicated on command "
9825051Swyllys 				    "line."));
9835051Swyllys 				return (KMF_ERR_BAD_PARAMETER);
9845051Swyllys 			}
9855051Swyllys 		} else {
986*10241Swyllys.ingersoll@sun.com 			if (rv == KMF_ERR_OPEN_FILE) {
987*10241Swyllys.ingersoll@sun.com 				cryptoerror(LOG_STDERR,
988*10241Swyllys.ingersoll@sun.com 				    gettext("Cannot open file (%s)\n."),
989*10241Swyllys.ingersoll@sun.com 				    filename);
990*10241Swyllys.ingersoll@sun.com 			} else {
991*10241Swyllys.ingersoll@sun.com 				rv2 = kmf_get_kmf_error_str(rv, &kmferrstr);
992*10241Swyllys.ingersoll@sun.com 				if (rv2 == KMF_OK && kmferrstr) {
993*10241Swyllys.ingersoll@sun.com 					cryptoerror(LOG_STDERR,
994*10241Swyllys.ingersoll@sun.com 					    gettext("libkmf error: %s"),
995*10241Swyllys.ingersoll@sun.com 					    kmferrstr);
996*10241Swyllys.ingersoll@sun.com 					kmf_free_str(kmferrstr);
997*10241Swyllys.ingersoll@sun.com 				}
998*10241Swyllys.ingersoll@sun.com 			}
9995051Swyllys 			return (rv);
10005051Swyllys 		}
10015051Swyllys 	}
10025051Swyllys 
10035051Swyllys 	/* Check parameters for raw key import operation */
10045051Swyllys 	if (kfmt == KMF_FORMAT_RAWKEY) {
10055051Swyllys 		if (keytype != NULL &&
10065051Swyllys 		    Str2SymKeyType(keytype, &keyAlg) != 0) {
10075051Swyllys 			cryptoerror(LOG_STDERR,
10085051Swyllys 			    gettext("Unrecognized keytype(%s).\n"), keytype);
10095051Swyllys 			return (PK_ERR_USAGE);
10105051Swyllys 		}
10115051Swyllys 		if (senstr != NULL && extstr != NULL &&
10125051Swyllys 		    kstype != KMF_KEYSTORE_PK11TOKEN) {
10135051Swyllys 			cryptoerror(LOG_STDERR,
10145051Swyllys 			    gettext("The sensitive or extractable option "
10155051Swyllys 			    "applies only when importing a key from a file "
10165051Swyllys 			    "into a PKCS#11 keystore.\n"));
10173089Swyllys 			return (PK_ERR_USAGE);
10183089Swyllys 		}
101917Sdinak 	}
102017Sdinak 
10215051Swyllys 	/* If no objtype was given, treat it as a certificate */
10223089Swyllys 	if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 ||
10235051Swyllys 	    kfmt == KMF_FORMAT_PEM))
10243089Swyllys 		oclass = PK_CERT_OBJ;
102517Sdinak 
10263089Swyllys 	if (kstype == KMF_KEYSTORE_NSS) {
10273089Swyllys 		if (oclass == PK_CRL_OBJ &&
10285051Swyllys 		    (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
10293089Swyllys 			cryptoerror(LOG_STDERR, gettext(
10305051Swyllys 			    "CRL data can only be imported as DER or "
10315051Swyllys 			    "PEM format"));
10323089Swyllys 			return (PK_ERR_USAGE);
10333089Swyllys 		}
10343089Swyllys 
10353089Swyllys 		if (oclass == PK_CERT_OBJ &&
10365051Swyllys 		    (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
10373089Swyllys 			cryptoerror(LOG_STDERR, gettext(
10385051Swyllys 			    "Certificates can only be imported as DER or "
10395051Swyllys 			    "PEM format"));
10403089Swyllys 			return (PK_ERR_USAGE);
10413089Swyllys 		}
10423089Swyllys 
10433089Swyllys 		/* we do not import private keys except in PKCS12 bundles */
10443089Swyllys 		if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) {
10453089Swyllys 			cryptoerror(LOG_STDERR, gettext(
10465051Swyllys 			    "Private key data can only be imported as part "
10475051Swyllys 			    "of a PKCS12 file.\n"));
10483089Swyllys 			return (PK_ERR_USAGE);
10493089Swyllys 		}
105017Sdinak 	}
105117Sdinak 
10523089Swyllys 	if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) {
10533089Swyllys 		if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) {
105417Sdinak 			cryptoerror(LOG_STDERR, gettext(
10555051Swyllys 			    "The 'outkey' and 'outcert' parameters "
10565051Swyllys 			    "are required for the import operation "
10575051Swyllys 			    "when the 'file' keystore is used.\n"));
10583089Swyllys 			return (PK_ERR_USAGE);
105917Sdinak 		}
106017Sdinak 	}
106117Sdinak 
10623089Swyllys 	if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec))
10633089Swyllys 		token_spec = PK_DEFAULT_PK11TOKEN;
10643089Swyllys 	else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec))
10653089Swyllys 		token_spec = DEFAULT_NSS_TOKEN;
10663089Swyllys 
10673089Swyllys 	if (kfmt == KMF_FORMAT_PKCS12) {
10683089Swyllys 		(void) get_pk12_password(&pk12cred);
10693089Swyllys 	}
10703089Swyllys 
10715051Swyllys 	if ((kfmt == KMF_FORMAT_PKCS12 || kfmt == KMF_FORMAT_RAWKEY ||
10725051Swyllys 	    (kfmt == KMF_FORMAT_PEM && (oclass & PK_KEY_OBJ))) &&
10735051Swyllys 	    (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)) {
10745051Swyllys 		(void) get_token_password(kstype, token_spec, &tokencred);
10755051Swyllys 	}
10765051Swyllys 
10775051Swyllys 	if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
10783089Swyllys 		cryptoerror(LOG_STDERR, gettext("Error initializing "
10795051Swyllys 		    "KMF: 0x%02x\n"), rv);
10803089Swyllys 		goto end;
10813089Swyllys 	}
108217Sdinak 
10833089Swyllys 	switch (kstype) {
10843089Swyllys 		case KMF_KEYSTORE_PK11TOKEN:
10853089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
10863089Swyllys 				rv = pk_import_pk12_pk11(
10875051Swyllys 				    kmfhandle, &pk12cred,
10885051Swyllys 				    &tokencred, label,
10895051Swyllys 				    token_spec, filename);
10903089Swyllys 			else if (oclass == PK_CERT_OBJ)
10913089Swyllys 				rv = pk_import_cert(
10925051Swyllys 				    kmfhandle, kstype,
10935051Swyllys 				    label, token_spec,
10945051Swyllys 				    filename,
10955051Swyllys 				    NULL, NULL, NULL);
10963089Swyllys 			else if (oclass == PK_CRL_OBJ)
10973089Swyllys 				rv = pk_import_file_crl(
10985051Swyllys 				    kmfhandle, filename,
10996669Swyllys 				    crlfile, okfmt);
11005051Swyllys 			else if (kfmt == KMF_FORMAT_RAWKEY &&
11015051Swyllys 			    oclass == PK_SYMKEY_OBJ) {
11025051Swyllys 				rv = pk_import_rawkey(kmfhandle,
11035051Swyllys 				    kstype, token_spec, &tokencred,
11045051Swyllys 				    filename, label,
11055051Swyllys 				    keyAlg, senstr, extstr);
11065051Swyllys 			} else if (kfmt == KMF_FORMAT_PEM ||
11075051Swyllys 			    kfmt == KMF_FORMAT_PEM_KEYPAIR) {
11085051Swyllys 				rv = pk_import_keys(kmfhandle,
11095051Swyllys 				    kstype, token_spec, &tokencred,
11105051Swyllys 				    filename, label, senstr, extstr);
11115051Swyllys 			} else {
11125051Swyllys 				rv = PK_ERR_USAGE;
11135051Swyllys 			}
11143089Swyllys 			break;
11153089Swyllys 		case KMF_KEYSTORE_NSS:
11163089Swyllys 			if (dir == NULL)
11173089Swyllys 				dir = PK_DEFAULT_DIRECTORY;
11183089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
11193089Swyllys 				rv = pk_import_pk12_nss(
11205051Swyllys 				    kmfhandle, &pk12cred,
11215051Swyllys 				    &tokencred,
11225051Swyllys 				    token_spec, dir, prefix,
11235051Swyllys 				    label, trustflags, filename);
11243089Swyllys 			else if (oclass == PK_CERT_OBJ) {
11253089Swyllys 				rv = pk_import_cert(
11265051Swyllys 				    kmfhandle, kstype,
11275051Swyllys 				    label, token_spec,
11285051Swyllys 				    filename, dir, prefix, trustflags);
11293089Swyllys 			} else if (oclass == PK_CRL_OBJ) {
11303089Swyllys 				rv = pk_import_nss_crl(
11315051Swyllys 				    kmfhandle, verify_crl_flag,
11325051Swyllys 				    filename, dir, prefix);
11333089Swyllys 			}
11343089Swyllys 			break;
11353089Swyllys 		case KMF_KEYSTORE_OPENSSL:
11363089Swyllys 			if (kfmt == KMF_FORMAT_PKCS12)
11373089Swyllys 				rv = pk_import_pk12_files(
11385051Swyllys 				    kmfhandle, &pk12cred,
11395051Swyllys 				    filename, certfile, keyfile,
11406669Swyllys 				    okfmt);
11413089Swyllys 			else if (oclass == PK_CRL_OBJ) {
11423089Swyllys 				rv = pk_import_file_crl(
11435051Swyllys 				    kmfhandle, filename,
11446669Swyllys 				    crlfile, okfmt);
11453089Swyllys 			} else
11463089Swyllys 				/*
11473089Swyllys 				 * It doesn't make sense to import anything
11483089Swyllys 				 * else for the files plugin.
11493089Swyllys 				 */
11503089Swyllys 				return (PK_ERR_USAGE);
11513089Swyllys 			break;
11523089Swyllys 		default:
11533089Swyllys 			rv = PK_ERR_USAGE;
11543089Swyllys 			break;
11553089Swyllys 	}
115617Sdinak 
11573089Swyllys end:
11583089Swyllys 	if (rv != KMF_OK)
11593089Swyllys 		display_error(kmfhandle, rv,
11605051Swyllys 		    gettext("Error importing objects"));
11613089Swyllys 
11623089Swyllys 	if (tokencred.cred != NULL)
11633089Swyllys 		free(tokencred.cred);
11643089Swyllys 
11653089Swyllys 	if (pk12cred.cred != NULL)
11663089Swyllys 		free(pk12cred.cred);
11673089Swyllys 
11685051Swyllys 	(void) kmf_finalize(kmfhandle);
11693089Swyllys 
11703089Swyllys 	if (rv != KMF_OK)
11713089Swyllys 		return (PK_ERR_USAGE);
11723089Swyllys 
117317Sdinak 	return (0);
117417Sdinak }
1175