Home | History | Annotate | Download | only in pktool
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 /*
     27  * This file implements the import operation for this tool.
     28  * The basic flow of the process is to decrypt the PKCS#12
     29  * input file if it has a password, parse the elements in
     30  * the file, find the soft token, log into it, import the
     31  * PKCS#11 objects into the soft token, and log out.
     32  */
     33 
     34 #include <stdio.h>
     35 #include <stdlib.h>
     36 #include <string.h>
     37 #include <ctype.h>
     38 #include <errno.h>
     39 #include <fcntl.h>
     40 #include <sys/types.h>
     41 #include <sys/stat.h>
     42 #include "common.h"
     43 
     44 #include <kmfapi.h>
     45 
     46 #define	NEW_ATTRLIST(a, n) \
     47 { \
     48 	a = (KMF_ATTRIBUTE *)malloc(n * sizeof (KMF_ATTRIBUTE)); \
     49 	if (a == NULL) { \
     50 		rv = KMF_ERR_MEMORY; \
     51 		goto end; \
     52 	} \
     53 	(void) memset(a, 0, n * sizeof (KMF_ATTRIBUTE));  \
     54 }
     55 
     56 static KMF_RETURN
     57 pk_import_pk12_files(KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *cred,
     58 	char *outfile, char *certfile, char *keyfile,
     59 	KMF_ENCODE_FORMAT outformat)
     60 {
     61 	KMF_RETURN rv = KMF_OK;
     62 	KMF_X509_DER_CERT *certs = NULL;
     63 	KMF_RAW_KEY_DATA *keys = NULL;
     64 	int ncerts = 0;
     65 	int nkeys = 0;
     66 	int i;
     67 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
     68 	KMF_ATTRIBUTE *attrlist = NULL;
     69 	int numattr = 0;
     70 
     71 	rv = kmf_import_objects(kmfhandle, outfile, cred,
     72 	    &certs, &ncerts, &keys, &nkeys);
     73 
     74 	if (rv == KMF_OK) {
     75 		(void) printf(gettext("Found %d certificate(s) and %d "
     76 		    "key(s) in %s\n"), ncerts, nkeys, outfile);
     77 	}
     78 
     79 	if (rv == KMF_OK && ncerts > 0) {
     80 		char newcertfile[MAXPATHLEN];
     81 
     82 		NEW_ATTRLIST(attrlist,  (3 + (3 * ncerts)));
     83 
     84 		kmf_set_attr_at_index(attrlist, numattr,
     85 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
     86 		numattr++;
     87 
     88 		kmf_set_attr_at_index(attrlist, numattr,
     89 		    KMF_ENCODE_FORMAT_ATTR, &outformat, sizeof (outformat));
     90 		numattr++;
     91 
     92 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
     93 			int num = numattr;
     94 
     95 			/*
     96 			 * If storing more than 1 cert, gotta change
     97 			 * the name so we don't overwrite the previous one.
     98 			 * Just append a _# to the name.
     99 			 */
    100 			if (i > 0) {
    101 				(void) snprintf(newcertfile,
    102 				    sizeof (newcertfile), "%s_%d", certfile, i);
    103 
    104 				kmf_set_attr_at_index(attrlist, num,
    105 				    KMF_CERT_FILENAME_ATTR, newcertfile,
    106 				    strlen(newcertfile));
    107 				num++;
    108 			} else {
    109 				kmf_set_attr_at_index(attrlist, num,
    110 				    KMF_CERT_FILENAME_ATTR, certfile,
    111 				    strlen(certfile));
    112 				num++;
    113 			}
    114 
    115 			if (certs[i].kmf_private.label != NULL) {
    116 				kmf_set_attr_at_index(attrlist, num,
    117 				    KMF_CERT_LABEL_ATTR,
    118 				    certs[i].kmf_private.label,
    119 				    strlen(certs[i].kmf_private.label));
    120 				num++;
    121 			}
    122 			kmf_set_attr_at_index(attrlist, num,
    123 			    KMF_CERT_DATA_ATTR, &certs[i].certificate,
    124 			    sizeof (KMF_DATA));
    125 			num++;
    126 			rv = kmf_store_cert(kmfhandle, num, attrlist);
    127 		}
    128 		free(attrlist);
    129 	}
    130 	if (rv == KMF_OK && nkeys > 0) {
    131 		char newkeyfile[MAXPATHLEN];
    132 		numattr = 0;
    133 		NEW_ATTRLIST(attrlist, (4 + (4 * nkeys)));
    134 
    135 		kmf_set_attr_at_index(attrlist, numattr,
    136 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
    137 		    sizeof (kstype));
    138 		numattr++;
    139 
    140 		kmf_set_attr_at_index(attrlist, numattr,
    141 		    KMF_ENCODE_FORMAT_ATTR, &outformat,
    142 		    sizeof (outformat));
    143 		numattr++;
    144 
    145 		if (cred != NULL && cred->credlen > 0) {
    146 			kmf_set_attr_at_index(attrlist, numattr,
    147 			    KMF_CREDENTIAL_ATTR, cred,
    148 			    sizeof (KMF_CREDENTIAL));
    149 			numattr++;
    150 		}
    151 
    152 		/* The order of certificates and keys should match */
    153 		for (i = 0; rv == KMF_OK && i < nkeys; i++) {
    154 			int num = numattr;
    155 
    156 			if (i > 0) {
    157 				(void) snprintf(newkeyfile,
    158 				    sizeof (newkeyfile), "%s_%d", keyfile, i);
    159 
    160 				kmf_set_attr_at_index(attrlist, num,
    161 				    KMF_KEY_FILENAME_ATTR, newkeyfile,
    162 				    strlen(newkeyfile));
    163 				num++;
    164 			} else {
    165 				kmf_set_attr_at_index(attrlist, num,
    166 				    KMF_KEY_FILENAME_ATTR, keyfile,
    167 				    strlen(keyfile));
    168 				num++;
    169 			}
    170 
    171 			if (i < ncerts) {
    172 				kmf_set_attr_at_index(attrlist, num,
    173 				    KMF_CERT_DATA_ATTR, &certs[i],
    174 				    sizeof (KMF_CERT_DATA_ATTR));
    175 				num++;
    176 			}
    177 
    178 			kmf_set_attr_at_index(attrlist, num,
    179 			    KMF_RAW_KEY_ATTR, &keys[i],
    180 			    sizeof (KMF_RAW_KEY_DATA));
    181 			num++;
    182 
    183 			rv = kmf_store_key(kmfhandle, num, attrlist);
    184 		}
    185 		free(attrlist);
    186 	}
    187 end:
    188 	/*
    189 	 * Cleanup memory.
    190 	 */
    191 	if (certs) {
    192 		for (i = 0; i < ncerts; i++)
    193 			kmf_free_kmf_cert(kmfhandle, &certs[i]);
    194 		free(certs);
    195 	}
    196 	if (keys) {
    197 		for (i = 0; i < nkeys; i++)
    198 			kmf_free_raw_key(&keys[i]);
    199 		free(keys);
    200 	}
    201 
    202 
    203 	return (rv);
    204 }
    205 
    206 
    207 static KMF_RETURN
    208 pk_import_pk12_nss(
    209 	KMF_HANDLE_T kmfhandle, KMF_CREDENTIAL *kmfcred,
    210 	KMF_CREDENTIAL *tokencred,
    211 	char *token_spec, char *dir, char *prefix,
    212 	char *nickname, char *trustflags, char *filename)
    213 {
    214 	KMF_RETURN rv = KMF_OK;
    215 	KMF_X509_DER_CERT *certs = NULL;
    216 	KMF_RAW_KEY_DATA *keys = NULL;
    217 	int ncerts = 0;
    218 	int nkeys = 0;
    219 	int i;
    220 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
    221 	KMF_ATTRIBUTE *attrlist = NULL;
    222 	int numattr = 0;
    223 
    224 	rv = configure_nss(kmfhandle, dir, prefix);
    225 	if (rv != KMF_OK)
    226 		return (rv);
    227 
    228 	rv = kmf_import_objects(kmfhandle, filename, kmfcred,
    229 	    &certs, &ncerts, &keys, &nkeys);
    230 
    231 	if (rv == KMF_OK)
    232 		(void) printf(gettext("Found %d certificate(s) and %d "
    233 		    "key(s) in %s\n"), ncerts, nkeys, filename);
    234 
    235 	if (rv == KMF_OK) {
    236 		numattr = 0;
    237 		NEW_ATTRLIST(attrlist, (4 + (2 * nkeys)));
    238 
    239 		kmf_set_attr_at_index(attrlist, numattr,
    240 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
    241 		    sizeof (kstype));
    242 		numattr++;
    243 
    244 		if (token_spec != NULL) {
    245 			kmf_set_attr_at_index(attrlist, numattr,
    246 			    KMF_TOKEN_LABEL_ATTR, token_spec,
    247 			    strlen(token_spec));
    248 			numattr++;
    249 		}
    250 
    251 		if (nickname != NULL) {
    252 			kmf_set_attr_at_index(attrlist, numattr,
    253 			    KMF_KEYLABEL_ATTR, nickname,
    254 			    strlen(nickname));
    255 			numattr++;
    256 		}
    257 
    258 		if (tokencred->credlen > 0) {
    259 			kmf_set_attr_at_index(attrlist, numattr,
    260 			    KMF_CREDENTIAL_ATTR, tokencred,
    261 			    sizeof (KMF_CREDENTIAL));
    262 			numattr++;
    263 		}
    264 
    265 		/* The order of certificates and keys should match */
    266 		for (i = 0; i < nkeys; i++) {
    267 			int num = numattr;
    268 
    269 			if (i < ncerts) {
    270 				kmf_set_attr_at_index(attrlist, num,
    271 				    KMF_CERT_DATA_ATTR, &certs[i],
    272 				    sizeof (KMF_DATA));
    273 				num++;
    274 			}
    275 
    276 			kmf_set_attr_at_index(attrlist, num,
    277 			    KMF_RAW_KEY_ATTR, &keys[i],
    278 			    sizeof (KMF_RAW_KEY_DATA));
    279 			num++;
    280 
    281 			rv = kmf_store_key(kmfhandle, num, attrlist);
    282 		}
    283 		free(attrlist);
    284 		attrlist = NULL;
    285 	}
    286 
    287 	if (rv == KMF_OK) {
    288 		numattr = 0;
    289 		NEW_ATTRLIST(attrlist, (3 + (2 * ncerts)));
    290 
    291 		kmf_set_attr_at_index(attrlist, numattr,
    292 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
    293 		numattr++;
    294 
    295 		if (token_spec != NULL) {
    296 			kmf_set_attr_at_index(attrlist, numattr,
    297 			    KMF_TOKEN_LABEL_ATTR, token_spec,
    298 			    strlen(token_spec));
    299 			numattr++;
    300 		}
    301 
    302 		if (trustflags != NULL) {
    303 			kmf_set_attr_at_index(attrlist, numattr,
    304 			    KMF_TRUSTFLAG_ATTR, trustflags,
    305 			    strlen(trustflags));
    306 			numattr++;
    307 		}
    308 
    309 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
    310 			int num = numattr;
    311 
    312 			if (certs[i].kmf_private.label != NULL) {
    313 				kmf_set_attr_at_index(attrlist, num,
    314 				    KMF_CERT_LABEL_ATTR,
    315 				    certs[i].kmf_private.label,
    316 				    strlen(certs[i].kmf_private.label));
    317 				num++;
    318 			} else if (i == 0 && nickname != NULL) {
    319 				kmf_set_attr_at_index(attrlist, num,
    320 				    KMF_CERT_LABEL_ATTR, nickname,
    321 				    strlen(nickname));
    322 				num++;
    323 			}
    324 
    325 			kmf_set_attr_at_index(attrlist, num,
    326 			    KMF_CERT_DATA_ATTR,
    327 			    &certs[i].certificate, sizeof (KMF_DATA));
    328 			num++;
    329 			rv = kmf_store_cert(kmfhandle, num, attrlist);
    330 		}
    331 		free(attrlist);
    332 		attrlist = NULL;
    333 		if (rv != KMF_OK) {
    334 			display_error(kmfhandle, rv,
    335 			    gettext("Error storing certificate in NSS token"));
    336 		}
    337 	}
    338 
    339 end:
    340 	/*
    341 	 * Cleanup memory.
    342 	 */
    343 	if (certs) {
    344 		for (i = 0; i < ncerts; i++)
    345 			kmf_free_kmf_cert(kmfhandle, &certs[i]);
    346 		free(certs);
    347 	}
    348 	if (keys) {
    349 		for (i = 0; i < nkeys; i++)
    350 			kmf_free_raw_key(&keys[i]);
    351 		free(keys);
    352 	}
    353 
    354 	return (rv);
    355 }
    356 
    357 static KMF_RETURN
    358 pk_import_cert(
    359 	KMF_HANDLE_T kmfhandle,
    360 	KMF_KEYSTORE_TYPE kstype,
    361 	char *label, char *token_spec, char *filename,
    362 	char *dir, char *prefix, char *trustflags)
    363 {
    364 	KMF_RETURN rv = KMF_OK;
    365 	KMF_ATTRIBUTE attrlist[32];
    366 	KMF_CREDENTIAL tokencred;
    367 	int i = 0;
    368 
    369 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
    370 		rv = select_token(kmfhandle, token_spec, FALSE);
    371 	} else if (kstype == KMF_KEYSTORE_NSS) {
    372 		rv = configure_nss(kmfhandle, dir, prefix);
    373 	}
    374 	if (rv != KMF_OK)
    375 		return (rv);
    376 
    377 	kmf_set_attr_at_index(attrlist, i,
    378 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (KMF_KEYSTORE_TYPE));
    379 	i++;
    380 
    381 	kmf_set_attr_at_index(attrlist, i, KMF_CERT_FILENAME_ATTR,
    382 	    filename, strlen(filename));
    383 	i++;
    384 
    385 	if (label != NULL) {
    386 		kmf_set_attr_at_index(attrlist, i, KMF_CERT_LABEL_ATTR,
    387 		    label, strlen(label));
    388 		i++;
    389 	}
    390 
    391 	if (kstype == KMF_KEYSTORE_NSS) {
    392 		if (trustflags != NULL) {
    393 			kmf_set_attr_at_index(attrlist, i, KMF_TRUSTFLAG_ATTR,
    394 			    trustflags, strlen(trustflags));
    395 			i++;
    396 		}
    397 
    398 		if (token_spec != NULL) {
    399 			kmf_set_attr_at_index(attrlist, i,
    400 			    KMF_TOKEN_LABEL_ATTR,
    401 			    token_spec, strlen(token_spec));
    402 			i++;
    403 		}
    404 	}
    405 
    406 	rv = kmf_import_cert(kmfhandle, i, attrlist);
    407 	if (rv == KMF_ERR_AUTH_FAILED) {
    408 		/*
    409 		 * The token requires a credential, prompt and try again.
    410 		 */
    411 		(void) get_token_password(kstype, token_spec, &tokencred);
    412 		kmf_set_attr_at_index(attrlist, i, KMF_CREDENTIAL_ATTR,
    413 		    &tokencred, sizeof (KMF_CREDENTIAL));
    414 		i++;
    415 
    416 		rv = kmf_import_cert(kmfhandle, i, attrlist);
    417 
    418 	}
    419 	return (rv);
    420 }
    421 
    422 static KMF_RETURN
    423 pk_import_file_crl(void *kmfhandle,
    424 	char *infile,
    425 	char *outfile,
    426 	KMF_ENCODE_FORMAT outfmt)
    427 {
    428 	int numattr = 0;
    429 	KMF_ATTRIBUTE attrlist[8];
    430 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
    431 
    432 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    433 	    &kstype, sizeof (kstype));
    434 	numattr++;
    435 	if (infile) {
    436 		kmf_set_attr_at_index(attrlist, numattr,
    437 		    KMF_CRL_FILENAME_ATTR, infile, strlen(infile));
    438 		numattr++;
    439 	}
    440 	if (outfile) {
    441 		kmf_set_attr_at_index(attrlist, numattr,
    442 		    KMF_CRL_OUTFILE_ATTR, outfile, strlen(outfile));
    443 		numattr++;
    444 	}
    445 	kmf_set_attr_at_index(attrlist, numattr,
    446 	    KMF_ENCODE_FORMAT_ATTR, &outfmt, sizeof (outfmt));
    447 	numattr++;
    448 
    449 	return (kmf_import_crl(kmfhandle, numattr, attrlist));
    450 }
    451 
    452 static KMF_RETURN
    453 pk_import_nss_crl(void *kmfhandle,
    454 	boolean_t verify_crl_flag,
    455 	char *infile,
    456 	char *outdir,
    457 	char *prefix)
    458 {
    459 	KMF_RETURN rv;
    460 	int numattr = 0;
    461 	KMF_ATTRIBUTE attrlist[4];
    462 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
    463 
    464 	rv = configure_nss(kmfhandle, outdir, prefix);
    465 	if (rv != KMF_OK)
    466 		return (rv);
    467 
    468 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    469 	    &kstype, sizeof (kstype));
    470 	numattr++;
    471 	if (infile) {
    472 		kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR,
    473 		    infile, strlen(infile));
    474 		numattr++;
    475 	}
    476 	kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_CHECK_ATTR,
    477 	    &verify_crl_flag, sizeof (verify_crl_flag));
    478 	numattr++;
    479 
    480 	return (kmf_import_crl(kmfhandle, numattr, attrlist));
    481 
    482 }
    483 
    484 static KMF_RETURN
    485 pk_import_pk12_pk11(
    486 	KMF_HANDLE_T kmfhandle,
    487 	KMF_CREDENTIAL *p12cred,
    488 	KMF_CREDENTIAL *tokencred,
    489 	char *label, char *token_spec,
    490 	char *filename)
    491 {
    492 	KMF_RETURN rv = KMF_OK;
    493 	KMF_X509_DER_CERT *certs = NULL;
    494 	KMF_RAW_KEY_DATA *keys = NULL;
    495 	int ncerts = 0;
    496 	int nkeys = 0;
    497 	int i;
    498 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
    499 	KMF_ATTRIBUTE *attrlist = NULL;
    500 	int numattr = 0;
    501 
    502 	rv = select_token(kmfhandle, token_spec, FALSE);
    503 
    504 	if (rv != KMF_OK) {
    505 		return (rv);
    506 	}
    507 
    508 	rv = kmf_import_objects(kmfhandle, filename, p12cred,
    509 	    &certs, &ncerts, &keys, &nkeys);
    510 
    511 	if (rv == KMF_OK) {
    512 		NEW_ATTRLIST(attrlist, (3 + (2 * nkeys)));
    513 
    514 		kmf_set_attr_at_index(attrlist, numattr,
    515 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
    516 		    sizeof (kstype));
    517 		numattr++;
    518 
    519 		if (label != NULL) {
    520 			kmf_set_attr_at_index(attrlist, numattr,
    521 			    KMF_KEYLABEL_ATTR, label,
    522 			    strlen(label));
    523 			numattr++;
    524 		}
    525 
    526 		if (tokencred != NULL && tokencred->credlen > 0) {
    527 			kmf_set_attr_at_index(attrlist, numattr,
    528 			    KMF_CREDENTIAL_ATTR, tokencred,
    529 			    sizeof (KMF_CREDENTIAL));
    530 			numattr++;
    531 		}
    532 
    533 		/* The order of certificates and keys should match */
    534 		for (i = 0; i < nkeys; i++) {
    535 			int num = numattr;
    536 
    537 			if (i < ncerts) {
    538 				kmf_set_attr_at_index(attrlist, num,
    539 				    KMF_CERT_DATA_ATTR, &certs[i].certificate,
    540 				    sizeof (KMF_DATA));
    541 				num++;
    542 			}
    543 
    544 			kmf_set_attr_at_index(attrlist, num,
    545 			    KMF_RAW_KEY_ATTR, &keys[i],
    546 			    sizeof (KMF_RAW_KEY_DATA));
    547 			num++;
    548 
    549 			rv = kmf_store_key(kmfhandle, num, attrlist);
    550 
    551 		}
    552 		free(attrlist);
    553 	}
    554 
    555 	if (rv == KMF_OK) {
    556 		numattr = 0;
    557 		NEW_ATTRLIST(attrlist, (1 + (2 * ncerts)));
    558 
    559 		(void) printf(gettext("Found %d certificate(s) and %d "
    560 		    "key(s) in %s\n"), ncerts, nkeys, filename);
    561 
    562 		kmf_set_attr_at_index(attrlist, numattr,
    563 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
    564 		numattr++;
    565 
    566 		for (i = 0; rv == KMF_OK && i < ncerts; i++) {
    567 			int num = numattr;
    568 			if (certs[i].kmf_private.label != NULL) {
    569 				kmf_set_attr_at_index(attrlist, num,
    570 				    KMF_CERT_LABEL_ATTR,
    571 				    certs[i].kmf_private.label,
    572 				    strlen(certs[i].kmf_private.label));
    573 				num++;
    574 			} else if (i == 0 && label != NULL) {
    575 				kmf_set_attr_at_index(attrlist, num,
    576 				    KMF_CERT_LABEL_ATTR, label, strlen(label));
    577 				num++;
    578 			}
    579 
    580 			kmf_set_attr_at_index(attrlist, num,
    581 			    KMF_CERT_DATA_ATTR, &certs[i].certificate,
    582 			    sizeof (KMF_DATA));
    583 			num++;
    584 
    585 			rv = kmf_store_cert(kmfhandle, num, attrlist);
    586 		}
    587 		free(attrlist);
    588 	}
    589 
    590 end:
    591 	/*
    592 	 * Cleanup memory.
    593 	 */
    594 	if (certs) {
    595 		for (i = 0; i < ncerts; i++)
    596 			kmf_free_kmf_cert(kmfhandle, &certs[i]);
    597 		free(certs);
    598 	}
    599 	if (keys) {
    600 		for (i = 0; i < nkeys; i++)
    601 			kmf_free_raw_key(&keys[i]);
    602 		free(keys);
    603 	}
    604 
    605 	return (rv);
    606 }
    607 
    608 /*ARGSUSED*/
    609 static KMF_RETURN
    610 pk_import_keys(KMF_HANDLE_T kmfhandle,
    611 	KMF_KEYSTORE_TYPE kstype, char *token_spec,
    612 	KMF_CREDENTIAL *cred, char *filename,
    613 	char *label, char *senstr, char *extstr)
    614 {
    615 	KMF_RETURN rv = KMF_OK;
    616 	KMF_ATTRIBUTE attrlist[16];
    617 	KMF_KEYSTORE_TYPE fileks = KMF_KEYSTORE_OPENSSL;
    618 	int numattr = 0;
    619 	KMF_KEY_HANDLE key;
    620 	KMF_RAW_KEY_DATA rawkey;
    621 	KMF_KEY_CLASS class = KMF_ASYM_PRI;
    622 	int numkeys = 1;
    623 
    624 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
    625 		rv = select_token(kmfhandle, token_spec, FALSE);
    626 	}
    627 	if (rv != KMF_OK)
    628 		return (rv);
    629 	/*
    630 	 * First, set up to read the keyfile using the FILE plugin
    631 	 * mechanisms.
    632 	 */
    633 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    634 	    &fileks, sizeof (fileks));
    635 	numattr++;
    636 
    637 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
    638 	    &numkeys, sizeof (numkeys));
    639 	numattr++;
    640 
    641 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
    642 	    &key, sizeof (key));
    643 	numattr++;
    644 
    645 	kmf_set_attr_at_index(attrlist, numattr, KMF_RAW_KEY_ATTR,
    646 	    &rawkey, sizeof (rawkey));
    647 	numattr++;
    648 
    649 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
    650 	    &class, sizeof (class));
    651 	numattr++;
    652 
    653 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
    654 	    filename, strlen(filename));
    655 	numattr++;
    656 
    657 	rv = kmf_find_key(kmfhandle, numattr, attrlist);
    658 	if (rv == KMF_OK) {
    659 		numattr = 0;
    660 
    661 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    662 		    &kstype, sizeof (kstype));
    663 		numattr++;
    664 
    665 		if (cred != NULL && cred->credlen > 0) {
    666 			kmf_set_attr_at_index(attrlist, numattr,
    667 			    KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
    668 			numattr++;
    669 		}
    670 
    671 		if (label != NULL) {
    672 			kmf_set_attr_at_index(attrlist, numattr,
    673 			    KMF_KEYLABEL_ATTR, label, strlen(label));
    674 			numattr++;
    675 		}
    676 
    677 		kmf_set_attr_at_index(attrlist, numattr,
    678 		    KMF_RAW_KEY_ATTR, &rawkey, sizeof (rawkey));
    679 		numattr++;
    680 
    681 		rv = kmf_store_key(kmfhandle, numattr, attrlist);
    682 		if (rv == KMF_OK) {
    683 			(void) printf(gettext("Importing %d keys\n"), numkeys);
    684 		}
    685 
    686 		kmf_free_kmf_key(kmfhandle, &key);
    687 		kmf_free_raw_key(&rawkey);
    688 	} else {
    689 		cryptoerror(LOG_STDERR,
    690 		    gettext("Failed to load key from file (%s)\n"),
    691 		    filename);
    692 	}
    693 	return (rv);
    694 }
    695 
    696 static KMF_RETURN
    697 pk_import_rawkey(KMF_HANDLE_T kmfhandle,
    698 	KMF_KEYSTORE_TYPE kstype, char *token,
    699 	KMF_CREDENTIAL *cred,
    700 	char *filename, char *label, KMF_KEY_ALG keyAlg,
    701 	char *senstr, char *extstr)
    702 {
    703 	KMF_RETURN rv = KMF_OK;
    704 	KMF_ATTRIBUTE attrlist[16];
    705 	int numattr = 0;
    706 	uint32_t keylen;
    707 	boolean_t sensitive = B_FALSE;
    708 	boolean_t not_extractable = B_FALSE;
    709 	KMF_DATA keydata = {NULL, 0};
    710 	KMF_KEY_HANDLE rawkey;
    711 
    712 	rv = kmf_read_input_file(kmfhandle, filename, &keydata);
    713 	if (rv != KMF_OK)
    714 		return (rv);
    715 
    716 	rv = select_token(kmfhandle, token, FALSE);
    717 
    718 	if (rv != KMF_OK) {
    719 		return (rv);
    720 	}
    721 	if (senstr != NULL) {
    722 		if (tolower(senstr[0]) == 'y')
    723 			sensitive = B_TRUE;
    724 		else if (tolower(senstr[0]) == 'n')
    725 			sensitive = B_FALSE;
    726 		else {
    727 			cryptoerror(LOG_STDERR,
    728 			    gettext("Incorrect sensitive option value.\n"));
    729 			return (KMF_ERR_BAD_PARAMETER);
    730 		}
    731 	}
    732 
    733 	if (extstr != NULL) {
    734 		if (tolower(extstr[0]) == 'y')
    735 			not_extractable = B_FALSE;
    736 		else if (tolower(extstr[0]) == 'n')
    737 			not_extractable = B_TRUE;
    738 		else {
    739 			cryptoerror(LOG_STDERR,
    740 			    gettext("Incorrect extractable option value.\n"));
    741 			return (KMF_ERR_BAD_PARAMETER);
    742 		}
    743 	}
    744 	kmf_set_attr_at_index(attrlist, numattr,
    745 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
    746 	numattr++;
    747 
    748 	kmf_set_attr_at_index(attrlist, numattr,
    749 	    KMF_KEY_HANDLE_ATTR, &rawkey, sizeof (rawkey));
    750 	numattr++;
    751 
    752 	kmf_set_attr_at_index(attrlist, numattr,
    753 	    KMF_KEYALG_ATTR, &keyAlg, sizeof (KMF_KEY_ALG));
    754 	numattr++;
    755 
    756 	kmf_set_attr_at_index(attrlist, numattr,
    757 	    KMF_KEY_DATA_ATTR, keydata.Data, keydata.Length);
    758 	numattr++;
    759 
    760 	/* Key length is given in bits not bytes */
    761 	keylen = keydata.Length * 8;
    762 	kmf_set_attr_at_index(attrlist, numattr,
    763 	    KMF_KEYLENGTH_ATTR, &keylen, sizeof (keydata.Length));
    764 	numattr++;
    765 
    766 	kmf_set_attr_at_index(attrlist, numattr,
    767 	    KMF_SENSITIVE_BOOL_ATTR, &sensitive, sizeof (sensitive));
    768 	numattr++;
    769 
    770 	kmf_set_attr_at_index(attrlist, numattr,
    771 	    KMF_NON_EXTRACTABLE_BOOL_ATTR, &not_extractable,
    772 	    sizeof (not_extractable));
    773 	numattr++;
    774 
    775 	if (label != NULL) {
    776 		kmf_set_attr_at_index(attrlist, numattr,
    777 		    KMF_KEYLABEL_ATTR, label, strlen(label));
    778 		numattr++;
    779 	}
    780 	if (cred != NULL && cred->credlen > 0) {
    781 		kmf_set_attr_at_index(attrlist, numattr,
    782 		    KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
    783 		numattr++;
    784 	}
    785 	rv = kmf_create_sym_key(kmfhandle, numattr, attrlist);
    786 
    787 	return (rv);
    788 }
    789 
    790 /*
    791  * Import objects from into KMF repositories.
    792  */
    793 int
    794 pk_import(int argc, char *argv[])
    795 {
    796 	int		opt;
    797 	extern int	optind_av;
    798 	extern char	*optarg_av;
    799 	char		*token_spec = NULL;
    800 	char		*filename = NULL;
    801 	char		*keyfile = NULL;
    802 	char		*certfile = NULL;
    803 	char		*crlfile = NULL;
    804 	char		*label = NULL;
    805 	char		*dir = NULL;
    806 	char		*prefix = NULL;
    807 	char		*trustflags = NULL;
    808 	char		*verify_crl = NULL;
    809 	char		*keytype = "generic";
    810 	char		*senstr = NULL;
    811 	char		*extstr = NULL;
    812 	boolean_t	verify_crl_flag = B_FALSE;
    813 	int		oclass = 0;
    814 	KMF_KEYSTORE_TYPE	kstype = 0;
    815 	KMF_ENCODE_FORMAT	kfmt = 0;
    816 	KMF_ENCODE_FORMAT	okfmt = KMF_FORMAT_ASN1;
    817 	KMF_RETURN		rv = KMF_OK;
    818 	KMF_CREDENTIAL	pk12cred = { NULL, 0 };
    819 	KMF_CREDENTIAL	tokencred = { NULL, 0 };
    820 	KMF_HANDLE_T	kmfhandle = NULL;
    821 	KMF_KEY_ALG	keyAlg = KMF_GENERIC_SECRET;
    822 
    823 	/* Parse command line options.  Do NOT i18n/l10n. */
    824 	while ((opt = getopt_av(argc, argv,
    825 	    "T:(token)i:(infile)"
    826 	    "k:(keystore)y:(objtype)"
    827 	    "d:(dir)p:(prefix)"
    828 	    "n:(certlabel)N:(label)"
    829 	    "K:(outkey)c:(outcert)"
    830 	    "v:(verifycrl)l:(outcrl)"
    831 	    "E:(keytype)s:(sensitive)x:(extractable)"
    832 	    "t:(trust)F:(outformat)")) != EOF) {
    833 		if (EMPTYSTRING(optarg_av))
    834 			return (PK_ERR_USAGE);
    835 		switch (opt) {
    836 		case 'T':	/* token specifier */
    837 			if (token_spec)
    838 				return (PK_ERR_USAGE);
    839 			token_spec = optarg_av;
    840 			break;
    841 		case 'c':	/* output cert file name */
    842 			if (certfile)
    843 				return (PK_ERR_USAGE);
    844 			certfile = optarg_av;
    845 			break;
    846 		case 'l':	/* output CRL file name */
    847 			if (crlfile)
    848 				return (PK_ERR_USAGE);
    849 			crlfile = optarg_av;
    850 			break;
    851 		case 'K':	/* output key file name */
    852 			if (keyfile)
    853 				return (PK_ERR_USAGE);
    854 			keyfile = optarg_av;
    855 			break;
    856 		case 'i':	/* input file name */
    857 			if (filename)
    858 				return (PK_ERR_USAGE);
    859 			filename = optarg_av;
    860 			break;
    861 		case 'k':
    862 			kstype = KS2Int(optarg_av);
    863 			if (kstype == 0)
    864 				return (PK_ERR_USAGE);
    865 			break;
    866 		case 'y':
    867 			oclass = OT2Int(optarg_av);
    868 			if (oclass == -1)
    869 				return (PK_ERR_USAGE);
    870 			break;
    871 		case 'd':
    872 			dir = optarg_av;
    873 			break;
    874 		case 'p':
    875 			if (prefix)
    876 				return (PK_ERR_USAGE);
    877 			prefix = optarg_av;
    878 			break;
    879 		case 'n':
    880 		case 'N':
    881 			if (label)
    882 				return (PK_ERR_USAGE);
    883 			label = optarg_av;
    884 			break;
    885 		case 'F':
    886 			okfmt = Str2Format(optarg_av);
    887 			if (okfmt == KMF_FORMAT_UNDEF)
    888 				return (PK_ERR_USAGE);
    889 			break;
    890 		case 't':
    891 			if (trustflags)
    892 				return (PK_ERR_USAGE);
    893 			trustflags = optarg_av;
    894 			break;
    895 		case 'v':
    896 			verify_crl = optarg_av;
    897 			if (tolower(verify_crl[0]) == 'y')
    898 				verify_crl_flag = B_TRUE;
    899 			else if (tolower(verify_crl[0]) == 'n')
    900 				verify_crl_flag = B_FALSE;
    901 			else
    902 				return (PK_ERR_USAGE);
    903 			break;
    904 		case 'E':
    905 			keytype = optarg_av;
    906 			break;
    907 		case 's':
    908 			if (senstr)
    909 				return (PK_ERR_USAGE);
    910 			senstr = optarg_av;
    911 			break;
    912 		case 'x':
    913 			if (extstr)
    914 				return (PK_ERR_USAGE);
    915 			extstr = optarg_av;
    916 			break;
    917 		default:
    918 			return (PK_ERR_USAGE);
    919 			break;
    920 		}
    921 	}
    922 
    923 	/* Assume keystore = PKCS#11 if not specified */
    924 	if (kstype == 0)
    925 		kstype = KMF_KEYSTORE_PK11TOKEN;
    926 
    927 	/* Filename arg is required. */
    928 	if (EMPTYSTRING(filename)) {
    929 		cryptoerror(LOG_STDERR, gettext("The 'infile' parameter"
    930 		    "is required for the import operation.\n"));
    931 		return (PK_ERR_USAGE);
    932 	}
    933 
    934 	/* No additional args allowed. */
    935 	argc -= optind_av;
    936 	argv += optind_av;
    937 	if (argc)
    938 		return (PK_ERR_USAGE);
    939 
    940 	DIR_OPTION_CHECK(kstype, dir);
    941 
    942 	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
    943 	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
    944 	    kstype != KMF_KEYSTORE_PK11TOKEN) {
    945 
    946 		(void) fprintf(stderr, gettext("The objtype parameter "
    947 		    "is only relevant if keystore=pkcs11\n"));
    948 		return (PK_ERR_USAGE);
    949 	}
    950 
    951 	/*
    952 	 * You must specify a certlabel (cert label) when importing
    953 	 * into NSS or PKCS#11.
    954 	 */
    955 	if (kstype == KMF_KEYSTORE_NSS &&
    956 	    (oclass != PK_CRL_OBJ) && EMPTYSTRING(label)) {
    957 		cryptoerror(LOG_STDERR, gettext("The 'label' argument "
    958 		    "is required for this operation\n"));
    959 		return (PK_ERR_USAGE);
    960 	}
    961 
    962 	if ((rv = kmf_get_file_format(filename, &kfmt)) != KMF_OK) {
    963 		char *kmferrstr = NULL;
    964 		KMF_RETURN rv2;
    965 		/*
    966 		 * Allow for raw key data to be imported.
    967 		 */
    968 		if (rv == KMF_ERR_ENCODING) {
    969 			rv = KMF_OK;
    970 			kfmt = KMF_FORMAT_RAWKEY;
    971 			/*
    972 			 * Set the object class only if it was not
    973 			 * given on the command line or if it was
    974 			 * specified as a symmetric key object.
    975 			 */
    976 			if (oclass == 0 || (oclass & PK_SYMKEY_OBJ)) {
    977 				oclass = PK_SYMKEY_OBJ;
    978 			} else {
    979 				cryptoerror(LOG_STDERR, gettext(
    980 				    "The input file does not contain the "
    981 				    "object type indicated on command "
    982 				    "line."));
    983 				return (KMF_ERR_BAD_PARAMETER);
    984 			}
    985 		} else {
    986 			if (rv == KMF_ERR_OPEN_FILE) {
    987 				cryptoerror(LOG_STDERR,
    988 				    gettext("Cannot open file (%s)\n."),
    989 				    filename);
    990 			} else {
    991 				rv2 = kmf_get_kmf_error_str(rv, &kmferrstr);
    992 				if (rv2 == KMF_OK && kmferrstr) {
    993 					cryptoerror(LOG_STDERR,
    994 					    gettext("libkmf error: %s"),
    995 					    kmferrstr);
    996 					kmf_free_str(kmferrstr);
    997 				}
    998 			}
    999 			return (rv);
   1000 		}
   1001 	}
   1002 
   1003 	/* Check parameters for raw key import operation */
   1004 	if (kfmt == KMF_FORMAT_RAWKEY) {
   1005 		if (keytype != NULL &&
   1006 		    Str2SymKeyType(keytype, &keyAlg) != 0) {
   1007 			cryptoerror(LOG_STDERR,
   1008 			    gettext("Unrecognized keytype(%s).\n"), keytype);
   1009 			return (PK_ERR_USAGE);
   1010 		}
   1011 		if (senstr != NULL && extstr != NULL &&
   1012 		    kstype != KMF_KEYSTORE_PK11TOKEN) {
   1013 			cryptoerror(LOG_STDERR,
   1014 			    gettext("The sensitive or extractable option "
   1015 			    "applies only when importing a key from a file "
   1016 			    "into a PKCS#11 keystore.\n"));
   1017 			return (PK_ERR_USAGE);
   1018 		}
   1019 	}
   1020 
   1021 	/* If no objtype was given, treat it as a certificate */
   1022 	if (oclass == 0 && (kfmt == KMF_FORMAT_ASN1 ||
   1023 	    kfmt == KMF_FORMAT_PEM))
   1024 		oclass = PK_CERT_OBJ;
   1025 
   1026 	if (kstype == KMF_KEYSTORE_NSS) {
   1027 		if (oclass == PK_CRL_OBJ &&
   1028 		    (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
   1029 			cryptoerror(LOG_STDERR, gettext(
   1030 			    "CRL data can only be imported as DER or "
   1031 			    "PEM format"));
   1032 			return (PK_ERR_USAGE);
   1033 		}
   1034 
   1035 		if (oclass == PK_CERT_OBJ &&
   1036 		    (kfmt != KMF_FORMAT_ASN1 && kfmt != KMF_FORMAT_PEM)) {
   1037 			cryptoerror(LOG_STDERR, gettext(
   1038 			    "Certificates can only be imported as DER or "
   1039 			    "PEM format"));
   1040 			return (PK_ERR_USAGE);
   1041 		}
   1042 
   1043 		/* we do not import private keys except in PKCS12 bundles */
   1044 		if (oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)) {
   1045 			cryptoerror(LOG_STDERR, gettext(
   1046 			    "Private key data can only be imported as part "
   1047 			    "of a PKCS12 file.\n"));
   1048 			return (PK_ERR_USAGE);
   1049 		}
   1050 	}
   1051 
   1052 	if (kstype == KMF_KEYSTORE_OPENSSL && oclass != PK_CRL_OBJ) {
   1053 		if (EMPTYSTRING(keyfile) || EMPTYSTRING(certfile)) {
   1054 			cryptoerror(LOG_STDERR, gettext(
   1055 			    "The 'outkey' and 'outcert' parameters "
   1056 			    "are required for the import operation "
   1057 			    "when the 'file' keystore is used.\n"));
   1058 			return (PK_ERR_USAGE);
   1059 		}
   1060 	}
   1061 
   1062 	if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec))
   1063 		token_spec = PK_DEFAULT_PK11TOKEN;
   1064 	else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec))
   1065 		token_spec = DEFAULT_NSS_TOKEN;
   1066 
   1067 	if (kfmt == KMF_FORMAT_PKCS12) {
   1068 		(void) get_pk12_password(&pk12cred);
   1069 	}
   1070 
   1071 	if ((kfmt == KMF_FORMAT_PKCS12 || kfmt == KMF_FORMAT_RAWKEY ||
   1072 	    (kfmt == KMF_FORMAT_PEM && (oclass & PK_KEY_OBJ))) &&
   1073 	    (kstype == KMF_KEYSTORE_PK11TOKEN || kstype == KMF_KEYSTORE_NSS)) {
   1074 		(void) get_token_password(kstype, token_spec, &tokencred);
   1075 	}
   1076 
   1077 	if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
   1078 		cryptoerror(LOG_STDERR, gettext("Error initializing "
   1079 		    "KMF: 0x%02x\n"), rv);
   1080 		goto end;
   1081 	}
   1082 
   1083 	switch (kstype) {
   1084 		case KMF_KEYSTORE_PK11TOKEN:
   1085 			if (kfmt == KMF_FORMAT_PKCS12)
   1086 				rv = pk_import_pk12_pk11(
   1087 				    kmfhandle, &pk12cred,
   1088 				    &tokencred, label,
   1089 				    token_spec, filename);
   1090 			else if (oclass == PK_CERT_OBJ)
   1091 				rv = pk_import_cert(
   1092 				    kmfhandle, kstype,
   1093 				    label, token_spec,
   1094 				    filename,
   1095 				    NULL, NULL, NULL);
   1096 			else if (oclass == PK_CRL_OBJ)
   1097 				rv = pk_import_file_crl(
   1098 				    kmfhandle, filename,
   1099 				    crlfile, okfmt);
   1100 			else if (kfmt == KMF_FORMAT_RAWKEY &&
   1101 			    oclass == PK_SYMKEY_OBJ) {
   1102 				rv = pk_import_rawkey(kmfhandle,
   1103 				    kstype, token_spec, &tokencred,
   1104 				    filename, label,
   1105 				    keyAlg, senstr, extstr);
   1106 			} else if (kfmt == KMF_FORMAT_PEM ||
   1107 			    kfmt == KMF_FORMAT_PEM_KEYPAIR) {
   1108 				rv = pk_import_keys(kmfhandle,
   1109 				    kstype, token_spec, &tokencred,
   1110 				    filename, label, senstr, extstr);
   1111 			} else {
   1112 				rv = PK_ERR_USAGE;
   1113 			}
   1114 			break;
   1115 		case KMF_KEYSTORE_NSS:
   1116 			if (dir == NULL)
   1117 				dir = PK_DEFAULT_DIRECTORY;
   1118 			if (kfmt == KMF_FORMAT_PKCS12)
   1119 				rv = pk_import_pk12_nss(
   1120 				    kmfhandle, &pk12cred,
   1121 				    &tokencred,
   1122 				    token_spec, dir, prefix,
   1123 				    label, trustflags, filename);
   1124 			else if (oclass == PK_CERT_OBJ) {
   1125 				rv = pk_import_cert(
   1126 				    kmfhandle, kstype,
   1127 				    label, token_spec,
   1128 				    filename, dir, prefix, trustflags);
   1129 			} else if (oclass == PK_CRL_OBJ) {
   1130 				rv = pk_import_nss_crl(
   1131 				    kmfhandle, verify_crl_flag,
   1132 				    filename, dir, prefix);
   1133 			}
   1134 			break;
   1135 		case KMF_KEYSTORE_OPENSSL:
   1136 			if (kfmt == KMF_FORMAT_PKCS12)
   1137 				rv = pk_import_pk12_files(
   1138 				    kmfhandle, &pk12cred,
   1139 				    filename, certfile, keyfile,
   1140 				    okfmt);
   1141 			else if (oclass == PK_CRL_OBJ) {
   1142 				rv = pk_import_file_crl(
   1143 				    kmfhandle, filename,
   1144 				    crlfile, okfmt);
   1145 			} else
   1146 				/*
   1147 				 * It doesn't make sense to import anything
   1148 				 * else for the files plugin.
   1149 				 */
   1150 				return (PK_ERR_USAGE);
   1151 			break;
   1152 		default:
   1153 			rv = PK_ERR_USAGE;
   1154 			break;
   1155 	}
   1156 
   1157 end:
   1158 	if (rv != KMF_OK)
   1159 		display_error(kmfhandle, rv,
   1160 		    gettext("Error importing objects"));
   1161 
   1162 	if (tokencred.cred != NULL)
   1163 		free(tokencred.cred);
   1164 
   1165 	if (pk12cred.cred != NULL)
   1166 		free(pk12cred.cred);
   1167 
   1168 	(void) kmf_finalize(kmfhandle);
   1169 
   1170 	if (rv != KMF_OK)
   1171 		return (PK_ERR_USAGE);
   1172 
   1173 	return (0);
   1174 }
   1175