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 2008 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     27 
     28 /*
     29  * This file implements the token object delete operation for this tool.
     30  * It loads the PKCS#11 modules, finds the object to delete, deletes it,
     31  * and cleans up.  User must be R/W logged into the token.
     32  */
     33 
     34 #include <stdio.h>
     35 #include <string.h>
     36 #include <cryptoutil.h>
     37 #include <security/cryptoki.h>
     38 #include "common.h"
     39 #include <kmfapi.h>
     40 
     41 static KMF_RETURN
     42 pk_destroy_keys(void *handle, KMF_ATTRIBUTE *attrlist, int numattr)
     43 {
     44 	int i;
     45 	KMF_RETURN rv = KMF_OK;
     46 	uint32_t *numkeys;
     47 	KMF_KEY_HANDLE *keys = NULL;
     48 	int del_num = 0;
     49 	KMF_ATTRIBUTE delete_attlist[16];
     50 	KMF_KEYSTORE_TYPE kstype;
     51 	uint32_t len;
     52 	boolean_t destroy = B_TRUE;
     53 	KMF_CREDENTIAL cred;
     54 	char *slotlabel = NULL;
     55 
     56 	len = sizeof (kstype);
     57 	rv = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
     58 	    &kstype, &len);
     59 	if (rv != KMF_OK)
     60 		return (rv);
     61 
     62 	kmf_set_attr_at_index(delete_attlist, del_num,
     63 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
     64 	del_num++;
     65 
     66 	/* "destroy" is optional. Default is TRUE */
     67 	(void) kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
     68 	    (void *)&destroy, NULL);
     69 
     70 	kmf_set_attr_at_index(delete_attlist, del_num,
     71 	    KMF_DESTROY_BOOL_ATTR, &destroy, sizeof (boolean_t));
     72 	del_num++;
     73 
     74 	switch (kstype) {
     75 	case KMF_KEYSTORE_NSS:
     76 		rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
     77 		    (void *)&cred, NULL);
     78 		if (rv == KMF_OK) {
     79 			if (cred.credlen > 0) {
     80 				kmf_set_attr_at_index(delete_attlist, del_num,
     81 				    KMF_CREDENTIAL_ATTR, &cred,
     82 				    sizeof (KMF_CREDENTIAL));
     83 				del_num++;
     84 			}
     85 		}
     86 
     87 		slotlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist,
     88 		    numattr);
     89 		if (slotlabel != NULL) {
     90 			kmf_set_attr_at_index(delete_attlist, del_num,
     91 			    KMF_TOKEN_LABEL_ATTR, slotlabel,
     92 			    strlen(slotlabel));
     93 			del_num++;
     94 		}
     95 		break;
     96 	case KMF_KEYSTORE_OPENSSL:
     97 		break;
     98 	case KMF_KEYSTORE_PK11TOKEN:
     99 		rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
    100 		    (void *)&cred, NULL);
    101 		if (rv == KMF_OK) {
    102 			if (cred.credlen > 0) {
    103 				kmf_set_attr_at_index(delete_attlist, del_num,
    104 				    KMF_CREDENTIAL_ATTR, &cred,
    105 				    sizeof (KMF_CREDENTIAL));
    106 				del_num++;
    107 			}
    108 		}
    109 		break;
    110 	default:
    111 		return (PK_ERR_USAGE);
    112 	}
    113 
    114 	numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
    115 	if (numkeys == NULL)
    116 		return (PK_ERR_USAGE);
    117 
    118 	keys = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
    119 	if (keys == NULL)
    120 		return (PK_ERR_USAGE);
    121 
    122 	for (i = 0; rv == KMF_OK && i < *numkeys; i++) {
    123 		int num = del_num;
    124 
    125 		kmf_set_attr_at_index(delete_attlist, num,
    126 		    KMF_KEY_HANDLE_ATTR, &keys[i], sizeof (KMF_KEY_HANDLE));
    127 		num++;
    128 
    129 		rv = kmf_delete_key_from_keystore(handle, num, delete_attlist);
    130 	}
    131 	return (rv);
    132 }
    133 
    134 static KMF_RETURN
    135 pk_delete_keys(KMF_HANDLE_T kmfhandle, KMF_ATTRIBUTE *attlist, int numattr,
    136 	char *desc, int *keysdeleted)
    137 {
    138 	KMF_RETURN rv = KMF_OK;
    139 	uint32_t numkeys = 0;
    140 	int num = numattr;
    141 
    142 	*keysdeleted = 0;
    143 	numkeys = 0;
    144 
    145 	kmf_set_attr_at_index(attlist, num,
    146 	    KMF_COUNT_ATTR, &numkeys, sizeof (uint32_t));
    147 	num++;
    148 
    149 	rv = kmf_find_key(kmfhandle, num, attlist);
    150 
    151 	if (rv == KMF_OK && numkeys > 0) {
    152 		KMF_KEY_HANDLE *keys = NULL;
    153 		char prompt[1024];
    154 
    155 		(void) snprintf(prompt, sizeof (prompt),
    156 		    gettext("%d %s key(s) found, do you want "
    157 		    "to delete them (y/N) ?"), numkeys,
    158 		    (desc != NULL ? desc : ""));
    159 
    160 		if (!yesno(prompt,
    161 		    gettext("Respond with yes or no.\n"),
    162 		    B_FALSE)) {
    163 			*keysdeleted = numkeys;
    164 			return (KMF_OK);
    165 		}
    166 		keys = (KMF_KEY_HANDLE *)malloc(numkeys *
    167 		    sizeof (KMF_KEY_HANDLE));
    168 		if (keys == NULL)
    169 			return (KMF_ERR_MEMORY);
    170 		(void) memset(keys, 0, numkeys *
    171 		    sizeof (KMF_KEY_HANDLE));
    172 
    173 		kmf_set_attr_at_index(attlist, num,
    174 		    KMF_KEY_HANDLE_ATTR, keys, sizeof (KMF_KEY_HANDLE));
    175 		num++;
    176 
    177 		rv = kmf_find_key(kmfhandle, num, attlist);
    178 		if (rv == KMF_OK) {
    179 			rv = pk_destroy_keys(kmfhandle, attlist, num);
    180 		}
    181 
    182 		free(keys);
    183 	}
    184 
    185 	*keysdeleted = numkeys;
    186 	return (rv);
    187 }
    188 
    189 static KMF_RETURN
    190 pk_delete_certs(KMF_HANDLE_T kmfhandle, KMF_ATTRIBUTE *attlist, int numattr)
    191 {
    192 	KMF_RETURN rv = KMF_OK;
    193 	uint32_t numcerts = 0;
    194 	int num = numattr;
    195 
    196 	kmf_set_attr_at_index(attlist, num,
    197 	    KMF_COUNT_ATTR, &numcerts, sizeof (uint32_t));
    198 	num++;
    199 
    200 	rv = kmf_find_cert(kmfhandle, num, attlist);
    201 	if (rv == KMF_OK && numcerts > 0) {
    202 		char prompt[1024];
    203 		(void) snprintf(prompt, sizeof (prompt),
    204 		    gettext("%d certificate(s) found, do you want "
    205 		    "to delete them (y/N) ?"), numcerts);
    206 
    207 		if (!yesno(prompt,
    208 		    gettext("Respond with yes or no.\n"),
    209 		    B_FALSE)) {
    210 			return (KMF_OK);
    211 		}
    212 
    213 		/*
    214 		 * Use numattr because delete cert does not require
    215 		 * KMF_COUNT_ATTR attribute.
    216 		 */
    217 		rv = kmf_delete_cert_from_keystore(kmfhandle, numattr, attlist);
    218 
    219 	}
    220 
    221 	return (rv);
    222 }
    223 
    224 static KMF_RETURN
    225 delete_nss_keys(KMF_HANDLE_T kmfhandle, char *dir, char *prefix,
    226 	char *token, int oclass, char *objlabel,
    227 	KMF_CREDENTIAL *tokencred)
    228 {
    229 	KMF_RETURN rv = KMF_OK;
    230 	char *keytype = NULL;
    231 	int nk, numkeys = 0;
    232 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
    233 	int numattr = 0;
    234 	KMF_ATTRIBUTE attrlist[16];
    235 	KMF_KEY_CLASS keyclass;
    236 
    237 	rv = configure_nss(kmfhandle, dir, prefix);
    238 	if (rv != KMF_OK)
    239 		return (rv);
    240 
    241 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    242 	    &kstype, sizeof (kstype));
    243 	numattr++;
    244 
    245 	if (objlabel != NULL) {
    246 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR,
    247 		    objlabel, strlen(objlabel));
    248 		numattr++;
    249 	}
    250 
    251 	if (tokencred->credlen > 0) {
    252 		kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
    253 		    tokencred, sizeof (KMF_CREDENTIAL));
    254 		numattr++;
    255 	}
    256 
    257 	if (token && strlen(token)) {
    258 		kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
    259 		    token, strlen(token));
    260 		numattr++;
    261 	}
    262 
    263 	if (oclass & PK_PRIKEY_OBJ) {
    264 		int num = numattr;
    265 
    266 		keyclass = KMF_ASYM_PRI;
    267 		kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
    268 		    &keyclass, sizeof (keyclass));
    269 		num++;
    270 
    271 		keytype = "private";
    272 		rv = pk_delete_keys(kmfhandle, attrlist, num, keytype, &nk);
    273 		numkeys += nk;
    274 		if (rv == KMF_ERR_KEY_NOT_FOUND &&
    275 		    oclass != PK_PRIKEY_OBJ)
    276 			rv = KMF_OK;
    277 	}
    278 	if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
    279 		int num = numattr;
    280 
    281 		keyclass = KMF_SYMMETRIC;
    282 		kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
    283 		    &keyclass, sizeof (keyclass));
    284 		num++;
    285 
    286 		keytype = "symmetric";
    287 		rv = pk_delete_keys(kmfhandle, attrlist, num, keytype, &nk);
    288 		numkeys += nk;
    289 		if (rv == KMF_ERR_KEY_NOT_FOUND &&
    290 		    oclass != PK_SYMKEY_OBJ)
    291 			rv = KMF_OK;
    292 	}
    293 	if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) {
    294 		int num = numattr;
    295 
    296 		keyclass = KMF_ASYM_PUB;
    297 		kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
    298 		    &keyclass, sizeof (keyclass));
    299 		num++;
    300 
    301 		keytype = "public";
    302 		rv = pk_delete_keys(kmfhandle, attrlist, num, keytype, &nk);
    303 		numkeys += nk;
    304 		if (rv == KMF_ERR_KEY_NOT_FOUND &&
    305 		    oclass != PK_PUBKEY_OBJ)
    306 			rv = KMF_OK;
    307 	}
    308 	if (rv == KMF_OK && numkeys == 0)
    309 		rv = KMF_ERR_KEY_NOT_FOUND;
    310 
    311 	return (rv);
    312 }
    313 
    314 static KMF_RETURN
    315 delete_nss_certs(KMF_HANDLE_T kmfhandle,
    316 	char *dir, char *prefix,
    317 	char *token, char *objlabel,
    318 	KMF_BIGINT *serno, char *issuer, char *subject,
    319 	KMF_CERT_VALIDITY find_criteria_flag)
    320 {
    321 	KMF_RETURN rv = KMF_OK;
    322 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
    323 	int numattr = 0;
    324 	KMF_ATTRIBUTE attrlist[16];
    325 
    326 	rv = configure_nss(kmfhandle, dir, prefix);
    327 	if (rv != KMF_OK)
    328 		return (rv);
    329 
    330 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    331 		    &kstype, sizeof (kstype));
    332 		numattr++;
    333 
    334 		if (objlabel != NULL) {
    335 			kmf_set_attr_at_index(attrlist, numattr,
    336 			    KMF_CERT_LABEL_ATTR, objlabel,
    337 			    strlen(objlabel));
    338 			numattr++;
    339 		}
    340 
    341 		if (issuer != NULL) {
    342 			kmf_set_attr_at_index(attrlist, numattr,
    343 			    KMF_ISSUER_NAME_ATTR, issuer,
    344 			    strlen(issuer));
    345 			numattr++;
    346 		}
    347 
    348 		if (subject != NULL) {
    349 			kmf_set_attr_at_index(attrlist, numattr,
    350 			    KMF_SUBJECT_NAME_ATTR, subject,
    351 			    strlen(subject));
    352 			numattr++;
    353 		}
    354 
    355 		if (serno != NULL) {
    356 			kmf_set_attr_at_index(attrlist, numattr,
    357 			    KMF_BIGINT_ATTR, serno,
    358 			    sizeof (KMF_BIGINT));
    359 			numattr++;
    360 		}
    361 
    362 		kmf_set_attr_at_index(attrlist, numattr,
    363 		    KMF_CERT_VALIDITY_ATTR, &find_criteria_flag,
    364 		    sizeof (KMF_CERT_VALIDITY));
    365 		numattr++;
    366 
    367 		if (token != NULL) {
    368 			kmf_set_attr_at_index(attrlist, numattr,
    369 			    KMF_TOKEN_LABEL_ATTR, token,
    370 			    strlen(token));
    371 			numattr++;
    372 		}
    373 
    374 	rv = pk_delete_certs(kmfhandle, attrlist, numattr);
    375 
    376 	return (rv);
    377 }
    378 
    379 static KMF_RETURN
    380 delete_nss_crl(void *kmfhandle,
    381 	char *dir, char *prefix, char *token,
    382 	char *issuer, char *subject)
    383 {
    384 	KMF_RETURN rv = KMF_OK;
    385 	int numattr = 0;
    386 	KMF_ATTRIBUTE attrlist[8];
    387 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
    388 
    389 	rv = configure_nss(kmfhandle, dir, prefix);
    390 	if (rv != KMF_OK)
    391 		return (rv);
    392 
    393 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    394 	    &kstype, sizeof (kstype));
    395 	numattr++;
    396 
    397 	if (token != NULL) {
    398 		kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
    399 		    token, strlen(token));
    400 		numattr++;
    401 	}
    402 	if (issuer != NULL) {
    403 		kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_NAME_ATTR,
    404 		    issuer, strlen(issuer));
    405 		numattr++;
    406 	}
    407 	if (subject != NULL) {
    408 		kmf_set_attr_at_index(attrlist, numattr, KMF_SUBJECT_NAME_ATTR,
    409 		    subject, strlen(subject));
    410 		numattr++;
    411 	}
    412 
    413 	rv = kmf_delete_crl(kmfhandle, numattr, attrlist);
    414 
    415 	return (rv);
    416 }
    417 
    418 static KMF_RETURN
    419 delete_pk11_keys(KMF_HANDLE_T kmfhandle,
    420 	char *token, int oclass, char *objlabel,
    421 	KMF_CREDENTIAL *tokencred)
    422 {
    423 	KMF_RETURN rv = KMF_OK;
    424 	int nk, numkeys = 0;
    425 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
    426 	int numattr = 0;
    427 	KMF_ATTRIBUTE attrlist[16];
    428 	KMF_KEY_CLASS keyclass;
    429 	boolean_t token_bool = B_TRUE;
    430 	boolean_t private;
    431 	/*
    432 	 * Symmetric keys and RSA/DSA private keys are always
    433 	 * created with the "CKA_PRIVATE" field == TRUE, so
    434 	 * make sure we search for them with it also set.
    435 	 */
    436 	if (oclass & (PK_SYMKEY_OBJ | PK_PRIKEY_OBJ))
    437 		oclass |= PK_PRIVATE_OBJ;
    438 
    439 	rv = select_token(kmfhandle, token, FALSE);
    440 	if (rv != KMF_OK) {
    441 		return (rv);
    442 	}
    443 
    444 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    445 	    &kstype, sizeof (kstype));
    446 	numattr++;
    447 
    448 	if (objlabel != NULL) {
    449 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR,
    450 		    objlabel, strlen(objlabel));
    451 		numattr++;
    452 	}
    453 
    454 	if (tokencred != NULL && tokencred->credlen > 0) {
    455 		kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
    456 		    tokencred, sizeof (KMF_CREDENTIAL));
    457 		numattr++;
    458 	}
    459 
    460 	private = ((oclass & PK_PRIVATE_OBJ) > 0);
    461 
    462 	kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVATE_BOOL_ATTR,
    463 	    &private, sizeof (private));
    464 	numattr++;
    465 
    466 	kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR,
    467 	    &token_bool, sizeof (token_bool));
    468 	numattr++;
    469 
    470 	if (oclass & PK_PRIKEY_OBJ) {
    471 		int num = numattr;
    472 
    473 		keyclass = KMF_ASYM_PRI;
    474 		kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
    475 		    &keyclass, sizeof (keyclass));
    476 		num++;
    477 
    478 		rv = pk_delete_keys(kmfhandle, attrlist, num, "private", &nk);
    479 		numkeys += nk;
    480 		if (rv == KMF_ERR_KEY_NOT_FOUND &&
    481 		    oclass != PK_PRIKEY_OBJ)
    482 			rv = KMF_OK;
    483 	}
    484 
    485 	if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
    486 		int num = numattr;
    487 
    488 		keyclass = KMF_SYMMETRIC;
    489 		kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
    490 		    &keyclass, sizeof (keyclass));
    491 		num++;
    492 
    493 		rv = pk_delete_keys(kmfhandle, attrlist, num, "symmetric", &nk);
    494 		numkeys += nk;
    495 		if (rv == KMF_ERR_KEY_NOT_FOUND &&
    496 		    oclass != PK_SYMKEY_OBJ)
    497 			rv = KMF_OK;
    498 	}
    499 
    500 	if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) {
    501 		int num = numattr;
    502 
    503 		private = B_FALSE;
    504 		keyclass = KMF_ASYM_PUB;
    505 		kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
    506 		    &keyclass, sizeof (keyclass));
    507 		num++;
    508 
    509 		rv = pk_delete_keys(kmfhandle, attrlist, num, "public", &nk);
    510 		numkeys += nk;
    511 		if (rv == KMF_ERR_KEY_NOT_FOUND &&
    512 		    oclass != PK_PUBKEY_OBJ)
    513 			rv = KMF_OK;
    514 	}
    515 	if (rv == KMF_OK && numkeys == 0)
    516 		rv = KMF_ERR_KEY_NOT_FOUND;
    517 
    518 	return (rv);
    519 }
    520 
    521 static KMF_RETURN
    522 delete_pk11_certs(KMF_HANDLE_T kmfhandle,
    523 	char *token, char *objlabel,
    524 	KMF_BIGINT *serno, char *issuer, char *subject,
    525 	KMF_CERT_VALIDITY find_criteria_flag)
    526 {
    527 	KMF_RETURN kmfrv;
    528 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
    529 	int numattr = 0;
    530 	KMF_ATTRIBUTE attrlist[16];
    531 
    532 	kmfrv = select_token(kmfhandle, token, FALSE);
    533 
    534 	if (kmfrv != KMF_OK) {
    535 		return (kmfrv);
    536 	}
    537 
    538 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    539 	    &kstype, sizeof (kstype));
    540 	numattr++;
    541 
    542 	if (objlabel != NULL) {
    543 		kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR,
    544 		    objlabel, strlen(objlabel));
    545 		numattr++;
    546 	}
    547 
    548 	if (issuer != NULL) {
    549 		kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_NAME_ATTR,
    550 		    issuer, strlen(issuer));
    551 		numattr++;
    552 	}
    553 
    554 	if (subject != NULL) {
    555 		kmf_set_attr_at_index(attrlist, numattr, KMF_SUBJECT_NAME_ATTR,
    556 		    subject, strlen(subject));
    557 		numattr++;
    558 	}
    559 
    560 	if (serno != NULL) {
    561 		kmf_set_attr_at_index(attrlist, numattr, KMF_BIGINT_ATTR,
    562 		    serno, sizeof (KMF_BIGINT));
    563 		numattr++;
    564 	}
    565 
    566 	kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_VALIDITY_ATTR,
    567 	    &find_criteria_flag, sizeof (KMF_CERT_VALIDITY));
    568 	numattr++;
    569 
    570 	kmfrv = pk_delete_certs(kmfhandle, attrlist, numattr);
    571 
    572 	return (kmfrv);
    573 }
    574 
    575 static KMF_RETURN
    576 delete_file_certs(KMF_HANDLE_T kmfhandle,
    577 	char *dir, char *filename, KMF_BIGINT *serial, char *issuer,
    578 	char *subject, KMF_CERT_VALIDITY find_criteria_flag)
    579 {
    580 	KMF_RETURN rv;
    581 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
    582 	int numattr = 0;
    583 	KMF_ATTRIBUTE attrlist[16];
    584 
    585 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    586 	    &kstype, sizeof (kstype));
    587 	numattr++;
    588 
    589 	if (issuer != NULL) {
    590 		kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_NAME_ATTR,
    591 		    issuer, strlen(issuer));
    592 		numattr++;
    593 	}
    594 
    595 	if (subject != NULL) {
    596 		kmf_set_attr_at_index(attrlist, numattr, KMF_SUBJECT_NAME_ATTR,
    597 		    subject, strlen(subject));
    598 		numattr++;
    599 	}
    600 
    601 	if (serial != NULL) {
    602 		kmf_set_attr_at_index(attrlist, numattr, KMF_BIGINT_ATTR,
    603 		    serial, sizeof (KMF_BIGINT));
    604 		numattr++;
    605 	}
    606 
    607 	if (dir != NULL) {
    608 		kmf_set_attr_at_index(attrlist, numattr, KMF_DIRPATH_ATTR,
    609 		    dir, strlen(dir));
    610 		numattr++;
    611 	}
    612 
    613 	if (filename != NULL) {
    614 		kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR,
    615 		    filename, strlen(filename));
    616 		numattr++;
    617 	}
    618 
    619 	kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_VALIDITY_ATTR,
    620 	    &find_criteria_flag, sizeof (KMF_CERT_VALIDITY));
    621 	numattr++;
    622 
    623 	rv = pk_delete_certs(kmfhandle, attrlist, numattr);
    624 
    625 	return (rv);
    626 }
    627 
    628 static KMF_RETURN
    629 delete_file_keys(KMF_HANDLE_T kmfhandle, int oclass,
    630 	char *dir, char *infile)
    631 {
    632 	KMF_RETURN rv = KMF_OK;
    633 	char *keytype = "";
    634 	int nk, numkeys = 0;
    635 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
    636 	int numattr = 0;
    637 	KMF_ATTRIBUTE attrlist[16];
    638 	KMF_KEY_CLASS keyclass;
    639 
    640 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    641 	    &kstype, sizeof (kstype));
    642 	numattr++;
    643 
    644 	if (dir != NULL) {
    645 		kmf_set_attr_at_index(attrlist, numattr, KMF_DIRPATH_ATTR,
    646 		    dir, strlen(dir));
    647 		numattr++;
    648 	}
    649 
    650 	if (infile != NULL) {
    651 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
    652 		    infile, strlen(infile));
    653 		numattr++;
    654 	}
    655 
    656 	if (oclass & (PK_PUBKEY_OBJ | PK_PRIKEY_OBJ)) {
    657 		int num = numattr;
    658 
    659 		keyclass = KMF_ASYM_PRI;
    660 		kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
    661 		    &keyclass, sizeof (keyclass));
    662 		num++;
    663 
    664 		keytype = "Asymmetric";
    665 		rv = pk_delete_keys(kmfhandle, attrlist, num, keytype, &nk);
    666 		numkeys += nk;
    667 	}
    668 	if (oclass & PK_SYMKEY_OBJ) {
    669 		int num = numattr;
    670 
    671 		keyclass = KMF_SYMMETRIC;
    672 		kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
    673 		    &keyclass, sizeof (keyclass));
    674 		num++;
    675 
    676 		keytype = "symmetric";
    677 		rv = pk_delete_keys(kmfhandle, attrlist, num, keytype, &nk);
    678 		numkeys += nk;
    679 		if (rv == KMF_ERR_KEY_NOT_FOUND && numkeys > 0)
    680 			rv = KMF_OK;
    681 	}
    682 	if (rv == KMF_OK && numkeys == 0)
    683 		rv = KMF_ERR_KEY_NOT_FOUND;
    684 
    685 	return (rv);
    686 }
    687 
    688 static KMF_RETURN
    689 delete_file_crl(void *kmfhandle, char *filename)
    690 {
    691 	KMF_RETURN rv;
    692 	int numattr = 0;
    693 	KMF_ATTRIBUTE attrlist[4];
    694 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
    695 
    696 	if (filename == NULL || strlen(filename) == 0)
    697 		return (KMF_ERR_BAD_PARAMETER);
    698 
    699 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    700 	    &kstype, sizeof (kstype));
    701 	numattr++;
    702 
    703 	if (filename) {
    704 		kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR,
    705 		    filename, strlen(filename));
    706 		numattr++;
    707 	}
    708 
    709 	rv = kmf_delete_crl(kmfhandle, numattr, attrlist);
    710 
    711 	return (rv);
    712 }
    713 
    714 /*
    715  * Delete token objects.
    716  */
    717 int
    718 pk_delete(int argc, char *argv[])
    719 {
    720 	int		opt;
    721 	extern int	optind_av;
    722 	extern char	*optarg_av;
    723 	char		*token_spec = NULL;
    724 	char		*subject = NULL;
    725 	char		*issuer = NULL;
    726 	char		*dir = NULL;
    727 	char		*prefix = NULL;
    728 	char		*infile = NULL;
    729 	char		*object_label = NULL;
    730 	char		*serstr = NULL;
    731 
    732 	int		oclass = 0;
    733 	KMF_BIGINT	serial = { NULL, 0 };
    734 	KMF_HANDLE_T	kmfhandle = NULL;
    735 	KMF_KEYSTORE_TYPE	kstype = 0;
    736 	KMF_RETURN	kmfrv, keyrv, certrv, crlrv;
    737 	int		rv = 0;
    738 	char			*find_criteria = NULL;
    739 	KMF_CERT_VALIDITY	find_criteria_flag = KMF_ALL_CERTS;
    740 	KMF_CREDENTIAL	tokencred = {NULL, 0};
    741 
    742 	/* Parse command line options.  Do NOT i18n/l10n. */
    743 	while ((opt = getopt_av(argc, argv,
    744 	    "T:(token)y:(objtype)l:(label)"
    745 	    "k:(keystore)s:(subject)n:(nickname)"
    746 	    "d:(dir)p:(prefix)S:(serial)i:(issuer)"
    747 	    "c:(criteria)"
    748 	    "f:(infile)")) != EOF) {
    749 
    750 		if (EMPTYSTRING(optarg_av))
    751 			return (PK_ERR_USAGE);
    752 		switch (opt) {
    753 		case 'T':	/* token specifier */
    754 			if (token_spec)
    755 				return (PK_ERR_USAGE);
    756 			token_spec = optarg_av;
    757 			break;
    758 		case 'y':	/* object type:  public, private, both */
    759 			if (oclass)
    760 				return (PK_ERR_USAGE);
    761 			oclass = OT2Int(optarg_av);
    762 			if (oclass == -1)
    763 				return (PK_ERR_USAGE);
    764 			break;
    765 		case 'l':	/* objects with specific label */
    766 		case 'n':
    767 			if (object_label)
    768 				return (PK_ERR_USAGE);
    769 			object_label = (char *)optarg_av;
    770 			break;
    771 		case 'k':
    772 			kstype = KS2Int(optarg_av);
    773 			if (kstype == 0)
    774 				return (PK_ERR_USAGE);
    775 			break;
    776 		case 's':
    777 			subject = optarg_av;
    778 			break;
    779 		case 'i':
    780 			issuer = optarg_av;
    781 			break;
    782 		case 'd':
    783 			dir = optarg_av;
    784 			break;
    785 		case 'p':
    786 			prefix = optarg_av;
    787 			break;
    788 		case 'S':
    789 			serstr = optarg_av;
    790 			break;
    791 		case 'f':
    792 			infile = optarg_av;
    793 			break;
    794 		case 'c':
    795 			find_criteria = optarg_av;
    796 			if (!strcasecmp(find_criteria, "valid"))
    797 				find_criteria_flag =
    798 				    KMF_NONEXPIRED_CERTS;
    799 			else if (!strcasecmp(find_criteria, "expired"))
    800 				find_criteria_flag = KMF_EXPIRED_CERTS;
    801 			else if (!strcasecmp(find_criteria, "both"))
    802 				find_criteria_flag = KMF_ALL_CERTS;
    803 			else
    804 				return (PK_ERR_USAGE);
    805 			break;
    806 		default:
    807 			return (PK_ERR_USAGE);
    808 			break;
    809 		}
    810 	}
    811 
    812 	/* Assume keystore = PKCS#11 if not specified */
    813 	if (kstype == 0)
    814 		kstype = KMF_KEYSTORE_PK11TOKEN;
    815 
    816 	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
    817 	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
    818 	    kstype != KMF_KEYSTORE_PK11TOKEN) {
    819 
    820 		(void) fprintf(stderr, gettext("The objtype parameter "
    821 		    "is only relevant if keystore=pkcs11\n"));
    822 		return (PK_ERR_USAGE);
    823 	}
    824 
    825 
    826 	/* No additional args allowed. */
    827 	argc -= optind_av;
    828 	argv += optind_av;
    829 	if (argc)
    830 		return (PK_ERR_USAGE);
    831 	/* Done parsing command line options. */
    832 
    833 	DIR_OPTION_CHECK(kstype, dir);
    834 
    835 	if (kstype == KMF_KEYSTORE_PK11TOKEN && token_spec == NULL) {
    836 		token_spec = PK_DEFAULT_PK11TOKEN;
    837 	} else if (kstype == KMF_KEYSTORE_NSS && token_spec == NULL) {
    838 		token_spec = DEFAULT_NSS_TOKEN;
    839 	}
    840 
    841 	if (serstr != NULL) {
    842 		uchar_t *bytes = NULL;
    843 		size_t bytelen;
    844 
    845 		rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen);
    846 		if (rv != KMF_OK || bytes == NULL) {
    847 			(void) fprintf(stderr, gettext("serial number "
    848 			    "must be specified as a hex number "
    849 			    "(ex: 0x0102030405ffeeddee)\n"));
    850 			return (PK_ERR_USAGE);
    851 		}
    852 		serial.val = bytes;
    853 		serial.len = bytelen;
    854 		/* If serial number was given, it must be a cert search */
    855 		if (oclass == 0)
    856 			oclass = PK_CERT_OBJ;
    857 	}
    858 	/*
    859 	 * If no object type was given but subject or issuer was,
    860 	 * it must be a certificate we are looking to delete.
    861 	 */
    862 	if ((issuer != NULL || subject != NULL) && oclass == 0)
    863 		oclass = PK_CERT_OBJ;
    864 	/* If no object class specified, delete everything but CRLs */
    865 	if (oclass == 0)
    866 		oclass = PK_CERT_OBJ | PK_KEY_OBJ;
    867 
    868 	if ((kstype == KMF_KEYSTORE_PK11TOKEN ||
    869 	    kstype == KMF_KEYSTORE_NSS) &&
    870 	    (oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ))) {
    871 
    872 		(void) get_token_password(kstype, token_spec,
    873 		    &tokencred);
    874 	}
    875 
    876 	if ((kmfrv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK)
    877 		return (kmfrv);
    878 
    879 	keyrv = certrv = crlrv = KMF_OK;
    880 	switch (kstype) {
    881 		case KMF_KEYSTORE_PK11TOKEN:
    882 			if (oclass & PK_KEY_OBJ) {
    883 				keyrv = delete_pk11_keys(kmfhandle,
    884 				    token_spec, oclass,
    885 				    object_label, &tokencred);
    886 				/*
    887 				 * If deleting groups of objects, it is OK
    888 				 * to ignore the "key not found" case so that
    889 				 * we can continue to find other objects.
    890 				 */
    891 				if (keyrv != KMF_OK &&
    892 				    keyrv != KMF_ERR_KEY_NOT_FOUND)
    893 					break;
    894 			}
    895 			if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
    896 				certrv = delete_pk11_certs(kmfhandle,
    897 				    token_spec, object_label,
    898 				    &serial, issuer,
    899 				    subject, find_criteria_flag);
    900 				/*
    901 				 * If cert delete failed, but we are looking at
    902 				 * other objects, then it is OK.
    903 				 */
    904 				if (certrv != KMF_OK &&
    905 				    certrv != KMF_ERR_CERT_NOT_FOUND)
    906 					break;
    907 			}
    908 			if (oclass & PK_CRL_OBJ)
    909 				crlrv = delete_file_crl(kmfhandle,
    910 				    infile);
    911 			break;
    912 		case KMF_KEYSTORE_NSS:
    913 			keyrv = certrv = crlrv = KMF_OK;
    914 			if (oclass & PK_KEY_OBJ) {
    915 				keyrv = delete_nss_keys(kmfhandle,
    916 				    dir, prefix, token_spec,
    917 				    oclass, (char  *)object_label,
    918 				    &tokencred);
    919 				if (keyrv != KMF_OK &&
    920 				    keyrv != KMF_ERR_KEY_NOT_FOUND)
    921 					break;
    922 			}
    923 			if (oclass & PK_CERT_OBJ) {
    924 				certrv = delete_nss_certs(kmfhandle,
    925 				    dir, prefix, token_spec,
    926 				    (char  *)object_label,
    927 				    &serial, issuer, subject,
    928 				    find_criteria_flag);
    929 				if (certrv != KMF_OK &&
    930 				    certrv != KMF_ERR_CERT_NOT_FOUND)
    931 					break;
    932 			}
    933 			if (oclass & PK_CRL_OBJ)
    934 				crlrv = delete_nss_crl(kmfhandle,
    935 				    dir, prefix, token_spec,
    936 				    (char  *)object_label, subject);
    937 			break;
    938 		case KMF_KEYSTORE_OPENSSL:
    939 			if (oclass & PK_KEY_OBJ) {
    940 				keyrv = delete_file_keys(kmfhandle, oclass,
    941 				    dir, infile);
    942 				if (keyrv != KMF_OK)
    943 					break;
    944 			}
    945 			if (oclass & (PK_CERT_OBJ)) {
    946 				certrv = delete_file_certs(kmfhandle,
    947 				    dir, infile, &serial, issuer,
    948 				    subject, find_criteria_flag);
    949 				if (certrv != KMF_OK)
    950 					break;
    951 			}
    952 			if (oclass & PK_CRL_OBJ)
    953 				crlrv = delete_file_crl(kmfhandle,
    954 				    infile);
    955 			break;
    956 		default:
    957 			rv = PK_ERR_USAGE;
    958 			break;
    959 	}
    960 
    961 	/*
    962 	 * Logic here:
    963 	 *    If searching for more than just one class of object (key or cert)
    964 	 *    and only 1 of the classes was not found, it is not an error.
    965 	 *    If searching for just one class of object, that failure should
    966 	 *    be reported.
    967 	 *
    968 	 *    Any error other than "KMF_ERR_[key/cert]_NOT_FOUND" should
    969 	 *    be reported either way.
    970 	 */
    971 	if (keyrv != KMF_ERR_KEY_NOT_FOUND && keyrv != KMF_OK)
    972 		kmfrv = keyrv;
    973 	else if (certrv != KMF_OK && certrv != KMF_ERR_CERT_NOT_FOUND)
    974 		kmfrv = certrv;
    975 	else if (crlrv != KMF_OK && crlrv != KMF_ERR_CRL_NOT_FOUND)
    976 		kmfrv = crlrv;
    977 
    978 	/*
    979 	 * If nothing was found, return error.
    980 	 */
    981 	if ((keyrv == KMF_ERR_KEY_NOT_FOUND && (oclass & PK_KEY_OBJ)) &&
    982 	    (certrv == KMF_ERR_CERT_NOT_FOUND && (oclass & PK_CERT_OBJ)))
    983 		kmfrv = KMF_ERR_KEY_NOT_FOUND;
    984 
    985 	if (kmfrv != KMF_OK)
    986 		goto out;
    987 
    988 	if (keyrv != KMF_OK && (oclass == PK_KEY_OBJ))
    989 		kmfrv = keyrv;
    990 	else if (certrv != KMF_OK && (oclass == PK_CERT_OBJ))
    991 		kmfrv = certrv;
    992 	else if (crlrv != KMF_OK && (oclass == PK_CRL_OBJ))
    993 		kmfrv = crlrv;
    994 
    995 out:
    996 	if (kmfrv != KMF_OK) {
    997 		display_error(kmfhandle, kmfrv,
    998 		    gettext("Error deleting objects"));
    999 	}
   1000 
   1001 	if (serial.val != NULL)
   1002 		free(serial.val);
   1003 	(void) kmf_finalize(kmfhandle);
   1004 	return (kmfrv);
   1005 }
   1006