delete.c revision 6b35cb3cf158584a9408d44b9b6796564e8e1882
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
* Copyright 2012 Milan Jurik. All rights reserved.
*/
/*
* This file implements the token object delete operation for this tool.
* It loads the PKCS#11 modules, finds the object to delete, deletes it,
* and cleans up. User must be R/W logged into the token.
*/
#include <stdio.h>
#include <string.h>
#include <cryptoutil.h>
#include <security/cryptoki.h>
#include "common.h"
#include <kmfapi.h>
static KMF_RETURN
pk_destroy_keys(void *handle, KMF_ATTRIBUTE *attrlist, int numattr)
{
int i;
KMF_RETURN rv = KMF_OK;
uint32_t *numkeys;
KMF_KEY_HANDLE *keys = NULL;
int del_num = 0;
KMF_ATTRIBUTE delete_attlist[16];
KMF_KEYSTORE_TYPE kstype;
uint32_t len;
boolean_t destroy = B_TRUE;
KMF_CREDENTIAL cred;
char *slotlabel = NULL;
len = sizeof (kstype);
rv = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
&kstype, &len);
if (rv != KMF_OK)
return (rv);
kmf_set_attr_at_index(delete_attlist, del_num,
KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
del_num++;
/* "destroy" is optional. Default is TRUE */
(void) kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
(void *)&destroy, NULL);
kmf_set_attr_at_index(delete_attlist, del_num,
KMF_DESTROY_BOOL_ATTR, &destroy, sizeof (boolean_t));
del_num++;
switch (kstype) {
case KMF_KEYSTORE_NSS:
rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
(void *)&cred, NULL);
if (rv == KMF_OK) {
if (cred.credlen > 0) {
kmf_set_attr_at_index(delete_attlist, del_num,
KMF_CREDENTIAL_ATTR, &cred,
sizeof (KMF_CREDENTIAL));
del_num++;
}
}
slotlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist,
numattr);
if (slotlabel != NULL) {
kmf_set_attr_at_index(delete_attlist, del_num,
KMF_TOKEN_LABEL_ATTR, slotlabel,
strlen(slotlabel));
del_num++;
}
break;
case KMF_KEYSTORE_OPENSSL:
break;
case KMF_KEYSTORE_PK11TOKEN:
rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
(void *)&cred, NULL);
if (rv == KMF_OK) {
if (cred.credlen > 0) {
kmf_set_attr_at_index(delete_attlist, del_num,
KMF_CREDENTIAL_ATTR, &cred,
sizeof (KMF_CREDENTIAL));
del_num++;
}
}
break;
default:
return (PK_ERR_USAGE);
}
numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
if (numkeys == NULL)
return (PK_ERR_USAGE);
keys = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
if (keys == NULL)
return (PK_ERR_USAGE);
for (i = 0; rv == KMF_OK && i < *numkeys; i++) {
int num = del_num;
kmf_set_attr_at_index(delete_attlist, num,
KMF_KEY_HANDLE_ATTR, &keys[i], sizeof (KMF_KEY_HANDLE));
num++;
rv = kmf_delete_key_from_keystore(handle, num, delete_attlist);
}
return (rv);
}
static KMF_RETURN
pk_delete_keys(KMF_HANDLE_T kmfhandle, KMF_ATTRIBUTE *attlist, int numattr,
char *desc, int *keysdeleted)
{
KMF_RETURN rv = KMF_OK;
uint32_t numkeys = 0;
int num = numattr;
*keysdeleted = 0;
numkeys = 0;
kmf_set_attr_at_index(attlist, num,
KMF_COUNT_ATTR, &numkeys, sizeof (uint32_t));
num++;
rv = kmf_find_key(kmfhandle, num, attlist);
if (rv == KMF_OK && numkeys > 0) {
KMF_KEY_HANDLE *keys = NULL;
char prompt[1024];
(void) snprintf(prompt, sizeof (prompt),
gettext("%d %s key(s) found, do you want "
"to delete them (y/N) ?"), numkeys,
(desc != NULL ? desc : ""));
if (!yesno(prompt,
gettext("Respond with yes or no.\n"),
B_FALSE)) {
*keysdeleted = numkeys;
return (KMF_OK);
}
keys = (KMF_KEY_HANDLE *)malloc(numkeys *
sizeof (KMF_KEY_HANDLE));
if (keys == NULL)
return (KMF_ERR_MEMORY);
(void) memset(keys, 0, numkeys *
sizeof (KMF_KEY_HANDLE));
kmf_set_attr_at_index(attlist, num,
KMF_KEY_HANDLE_ATTR, keys, sizeof (KMF_KEY_HANDLE));
num++;
rv = kmf_find_key(kmfhandle, num, attlist);
if (rv == KMF_OK) {
rv = pk_destroy_keys(kmfhandle, attlist, num);
}
free(keys);
}
*keysdeleted = numkeys;
return (rv);
}
static KMF_RETURN
pk_delete_certs(KMF_HANDLE_T kmfhandle, KMF_ATTRIBUTE *attlist, int numattr)
{
KMF_RETURN rv = KMF_OK;
uint32_t numcerts = 0;
int num = numattr;
kmf_set_attr_at_index(attlist, num,
KMF_COUNT_ATTR, &numcerts, sizeof (uint32_t));
num++;
rv = kmf_find_cert(kmfhandle, num, attlist);
if (rv == KMF_OK && numcerts > 0) {
char prompt[1024];
(void) snprintf(prompt, sizeof (prompt),
gettext("%d certificate(s) found, do you want "
"to delete them (y/N) ?"), numcerts);
if (!yesno(prompt,
gettext("Respond with yes or no.\n"),
B_FALSE)) {
return (KMF_OK);
}
/*
* Use numattr because delete cert does not require
* KMF_COUNT_ATTR attribute.
*/
rv = kmf_delete_cert_from_keystore(kmfhandle, numattr, attlist);
}
return (rv);
}
static KMF_RETURN
delete_nss_keys(KMF_HANDLE_T kmfhandle, char *dir, char *prefix,
char *token, int oclass, char *objlabel,
KMF_CREDENTIAL *tokencred)
{
KMF_RETURN rv = KMF_OK;
char *keytype = NULL;
int nk, numkeys = 0;
KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
int numattr = 0;
KMF_ATTRIBUTE attrlist[16];
KMF_KEY_CLASS keyclass;
rv = configure_nss(kmfhandle, dir, prefix);
if (rv != KMF_OK)
return (rv);
kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
&kstype, sizeof (kstype));
numattr++;
if (objlabel != NULL) {
kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR,
objlabel, strlen(objlabel));
numattr++;
}
if (tokencred->credlen > 0) {
kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
tokencred, sizeof (KMF_CREDENTIAL));
numattr++;
}
if (token && strlen(token)) {
kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
token, strlen(token));
numattr++;
}
if (oclass & PK_PRIKEY_OBJ) {
int num = numattr;
keyclass = KMF_ASYM_PRI;
kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
&keyclass, sizeof (keyclass));
num++;
keytype = "private";
rv = pk_delete_keys(kmfhandle, attrlist, num, keytype, &nk);
numkeys += nk;
if (rv == KMF_ERR_KEY_NOT_FOUND &&
oclass != PK_PRIKEY_OBJ)
rv = KMF_OK;
}
if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
int num = numattr;
keyclass = KMF_SYMMETRIC;
kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
&keyclass, sizeof (keyclass));
num++;
keytype = "symmetric";
rv = pk_delete_keys(kmfhandle, attrlist, num, keytype, &nk);
numkeys += nk;
if (rv == KMF_ERR_KEY_NOT_FOUND &&
oclass != PK_SYMKEY_OBJ)
rv = KMF_OK;
}
if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) {
int num = numattr;
keyclass = KMF_ASYM_PUB;
kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
&keyclass, sizeof (keyclass));
num++;
keytype = "public";
rv = pk_delete_keys(kmfhandle, attrlist, num, keytype, &nk);
numkeys += nk;
if (rv == KMF_ERR_KEY_NOT_FOUND &&
oclass != PK_PUBKEY_OBJ)
rv = KMF_OK;
}
if (rv == KMF_OK && numkeys == 0)
rv = KMF_ERR_KEY_NOT_FOUND;
return (rv);
}
static KMF_RETURN
delete_nss_certs(KMF_HANDLE_T kmfhandle,
char *dir, char *prefix,
char *token, char *objlabel,
KMF_BIGINT *serno, char *issuer, char *subject,
KMF_CERT_VALIDITY find_criteria_flag)
{
KMF_RETURN rv = KMF_OK;
KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
int numattr = 0;
KMF_ATTRIBUTE attrlist[16];
rv = configure_nss(kmfhandle, dir, prefix);
if (rv != KMF_OK)
return (rv);
kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
&kstype, sizeof (kstype));
numattr++;
if (objlabel != NULL) {
kmf_set_attr_at_index(attrlist, numattr,
KMF_CERT_LABEL_ATTR, objlabel,
strlen(objlabel));
numattr++;
}
if (issuer != NULL) {
kmf_set_attr_at_index(attrlist, numattr,
KMF_ISSUER_NAME_ATTR, issuer,
strlen(issuer));
numattr++;
}
if (subject != NULL) {
kmf_set_attr_at_index(attrlist, numattr,
KMF_SUBJECT_NAME_ATTR, subject,
strlen(subject));
numattr++;
}
if (serno != NULL) {
kmf_set_attr_at_index(attrlist, numattr,
KMF_BIGINT_ATTR, serno,
sizeof (KMF_BIGINT));
numattr++;
}
kmf_set_attr_at_index(attrlist, numattr,
KMF_CERT_VALIDITY_ATTR, &find_criteria_flag,
sizeof (KMF_CERT_VALIDITY));
numattr++;
if (token != NULL) {
kmf_set_attr_at_index(attrlist, numattr,
KMF_TOKEN_LABEL_ATTR, token,
strlen(token));
numattr++;
}
rv = pk_delete_certs(kmfhandle, attrlist, numattr);
return (rv);
}
static KMF_RETURN
delete_nss_crl(void *kmfhandle,
char *dir, char *prefix, char *token,
char *issuer, char *subject)
{
KMF_RETURN rv = KMF_OK;
int numattr = 0;
KMF_ATTRIBUTE attrlist[8];
KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
rv = configure_nss(kmfhandle, dir, prefix);
if (rv != KMF_OK)
return (rv);
kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
&kstype, sizeof (kstype));
numattr++;
if (token != NULL) {
kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
token, strlen(token));
numattr++;
}
if (issuer != NULL) {
kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_NAME_ATTR,
issuer, strlen(issuer));
numattr++;
}
if (subject != NULL) {
kmf_set_attr_at_index(attrlist, numattr, KMF_SUBJECT_NAME_ATTR,
subject, strlen(subject));
numattr++;
}
rv = kmf_delete_crl(kmfhandle, numattr, attrlist);
return (rv);
}
static KMF_RETURN
delete_pk11_keys(KMF_HANDLE_T kmfhandle,
char *token, int oclass, char *objlabel,
KMF_CREDENTIAL *tokencred)
{
KMF_RETURN rv = KMF_OK;
int nk, numkeys = 0;
KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
int numattr = 0;
KMF_ATTRIBUTE attrlist[16];
KMF_KEY_CLASS keyclass;
boolean_t token_bool = B_TRUE;
boolean_t private;
/*
* Symmetric keys and RSA/DSA private keys are always
* created with the "CKA_PRIVATE" field == TRUE, so
* make sure we search for them with it also set.
*/
if (oclass & (PK_SYMKEY_OBJ | PK_PRIKEY_OBJ))
oclass |= PK_PRIVATE_OBJ;
rv = select_token(kmfhandle, token, FALSE);
if (rv != KMF_OK) {
return (rv);
}
kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
&kstype, sizeof (kstype));
numattr++;
if (objlabel != NULL) {
kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR,
objlabel, strlen(objlabel));
numattr++;
}
if (tokencred != NULL && tokencred->credlen > 0) {
kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
tokencred, sizeof (KMF_CREDENTIAL));
numattr++;
}
private = ((oclass & PK_PRIVATE_OBJ) > 0);
kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVATE_BOOL_ATTR,
&private, sizeof (private));
numattr++;
kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR,
&token_bool, sizeof (token_bool));
numattr++;
if (oclass & PK_PRIKEY_OBJ) {
int num = numattr;
keyclass = KMF_ASYM_PRI;
kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
&keyclass, sizeof (keyclass));
num++;
rv = pk_delete_keys(kmfhandle, attrlist, num, "private", &nk);
numkeys += nk;
if (rv == KMF_ERR_KEY_NOT_FOUND &&
oclass != PK_PRIKEY_OBJ)
rv = KMF_OK;
}
if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
int num = numattr;
keyclass = KMF_SYMMETRIC;
kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
&keyclass, sizeof (keyclass));
num++;
rv = pk_delete_keys(kmfhandle, attrlist, num, "symmetric", &nk);
numkeys += nk;
if (rv == KMF_ERR_KEY_NOT_FOUND &&
oclass != PK_SYMKEY_OBJ)
rv = KMF_OK;
}
if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) {
int num = numattr;
private = B_FALSE;
keyclass = KMF_ASYM_PUB;
kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
&keyclass, sizeof (keyclass));
num++;
rv = pk_delete_keys(kmfhandle, attrlist, num, "public", &nk);
numkeys += nk;
if (rv == KMF_ERR_KEY_NOT_FOUND &&
oclass != PK_PUBKEY_OBJ)
rv = KMF_OK;
}
if (rv == KMF_OK && numkeys == 0)
rv = KMF_ERR_KEY_NOT_FOUND;
return (rv);
}
static KMF_RETURN
delete_pk11_certs(KMF_HANDLE_T kmfhandle,
char *token, char *objlabel,
KMF_BIGINT *serno, char *issuer, char *subject,
KMF_CERT_VALIDITY find_criteria_flag)
{
KMF_RETURN kmfrv;
KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
int numattr = 0;
KMF_ATTRIBUTE attrlist[16];
kmfrv = select_token(kmfhandle, token, FALSE);
if (kmfrv != KMF_OK) {
return (kmfrv);
}
kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
&kstype, sizeof (kstype));
numattr++;
if (objlabel != NULL) {
kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR,
objlabel, strlen(objlabel));
numattr++;
}
if (issuer != NULL) {
kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_NAME_ATTR,
issuer, strlen(issuer));
numattr++;
}
if (subject != NULL) {
kmf_set_attr_at_index(attrlist, numattr, KMF_SUBJECT_NAME_ATTR,
subject, strlen(subject));
numattr++;
}
if (serno != NULL) {
kmf_set_attr_at_index(attrlist, numattr, KMF_BIGINT_ATTR,
serno, sizeof (KMF_BIGINT));
numattr++;
}
kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_VALIDITY_ATTR,
&find_criteria_flag, sizeof (KMF_CERT_VALIDITY));
numattr++;
kmfrv = pk_delete_certs(kmfhandle, attrlist, numattr);
return (kmfrv);
}
static KMF_RETURN
delete_file_certs(KMF_HANDLE_T kmfhandle,
char *dir, char *filename, KMF_BIGINT *serial, char *issuer,
char *subject, KMF_CERT_VALIDITY find_criteria_flag)
{
KMF_RETURN rv;
KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
int numattr = 0;
KMF_ATTRIBUTE attrlist[16];
kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
&kstype, sizeof (kstype));
numattr++;
if (issuer != NULL) {
kmf_set_attr_at_index(attrlist, numattr, KMF_ISSUER_NAME_ATTR,
issuer, strlen(issuer));
numattr++;
}
if (subject != NULL) {
kmf_set_attr_at_index(attrlist, numattr, KMF_SUBJECT_NAME_ATTR,
subject, strlen(subject));
numattr++;
}
if (serial != NULL) {
kmf_set_attr_at_index(attrlist, numattr, KMF_BIGINT_ATTR,
serial, sizeof (KMF_BIGINT));
numattr++;
}
if (dir != NULL) {
kmf_set_attr_at_index(attrlist, numattr, KMF_DIRPATH_ATTR,
dir, strlen(dir));
numattr++;
}
if (filename != NULL) {
kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR,
filename, strlen(filename));
numattr++;
}
kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_VALIDITY_ATTR,
&find_criteria_flag, sizeof (KMF_CERT_VALIDITY));
numattr++;
rv = pk_delete_certs(kmfhandle, attrlist, numattr);
return (rv);
}
static KMF_RETURN
delete_file_keys(KMF_HANDLE_T kmfhandle, int oclass,
char *dir, char *infile)
{
KMF_RETURN rv = KMF_OK;
char *keytype = "";
int nk, numkeys = 0;
KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
int numattr = 0;
KMF_ATTRIBUTE attrlist[16];
KMF_KEY_CLASS keyclass;
kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
&kstype, sizeof (kstype));
numattr++;
if (dir != NULL) {
kmf_set_attr_at_index(attrlist, numattr, KMF_DIRPATH_ATTR,
dir, strlen(dir));
numattr++;
}
if (infile != NULL) {
kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
infile, strlen(infile));
numattr++;
}
if (oclass & (PK_PUBKEY_OBJ | PK_PRIKEY_OBJ)) {
int num = numattr;
keyclass = KMF_ASYM_PRI;
kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
&keyclass, sizeof (keyclass));
num++;
keytype = "Asymmetric";
rv = pk_delete_keys(kmfhandle, attrlist, num, keytype, &nk);
numkeys += nk;
}
if (oclass & PK_SYMKEY_OBJ) {
int num = numattr;
keyclass = KMF_SYMMETRIC;
kmf_set_attr_at_index(attrlist, num, KMF_KEYCLASS_ATTR,
&keyclass, sizeof (keyclass));
num++;
keytype = "symmetric";
rv = pk_delete_keys(kmfhandle, attrlist, num, keytype, &nk);
numkeys += nk;
if (rv == KMF_ERR_KEY_NOT_FOUND && numkeys > 0)
rv = KMF_OK;
}
if (rv == KMF_OK && numkeys == 0)
rv = KMF_ERR_KEY_NOT_FOUND;
return (rv);
}
static KMF_RETURN
delete_file_crl(void *kmfhandle, char *filename)
{
KMF_RETURN rv;
int numattr = 0;
KMF_ATTRIBUTE attrlist[4];
KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
if (filename == NULL || strlen(filename) == 0)
return (KMF_ERR_BAD_PARAMETER);
kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
&kstype, sizeof (kstype));
numattr++;
if (filename) {
kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_FILENAME_ATTR,
filename, strlen(filename));
numattr++;
}
rv = kmf_delete_crl(kmfhandle, numattr, attrlist);
return (rv);
}
/*
* Delete token objects.
*/
int
pk_delete(int argc, char *argv[])
{
int opt;
extern int optind_av;
extern char *optarg_av;
char *token_spec = NULL;
char *subject = NULL;
char *issuer = NULL;
char *dir = NULL;
char *prefix = NULL;
char *infile = NULL;
char *object_label = NULL;
char *serstr = NULL;
int oclass = 0;
KMF_BIGINT serial = { NULL, 0 };
KMF_HANDLE_T kmfhandle = NULL;
KMF_KEYSTORE_TYPE kstype = 0;
KMF_RETURN kmfrv, keyrv, certrv, crlrv;
int rv = 0;
char *find_criteria = NULL;
KMF_CERT_VALIDITY find_criteria_flag = KMF_ALL_CERTS;
KMF_CREDENTIAL tokencred = { NULL, 0 };
/* Parse command line options. Do NOT i18n/l10n. */
while ((opt = getopt_av(argc, argv,
"T:(token)y:(objtype)l:(label)"
"k:(keystore)s:(subject)n:(nickname)"
"d:(dir)p:(prefix)S:(serial)i:(issuer)"
"c:(criteria)"
"f:(infile)")) != EOF) {
if (EMPTYSTRING(optarg_av))
return (PK_ERR_USAGE);
switch (opt) {
case 'T': /* token specifier */
if (token_spec)
return (PK_ERR_USAGE);
token_spec = optarg_av;
break;
case 'y': /* object type: public, private, both */
if (oclass)
return (PK_ERR_USAGE);
oclass = OT2Int(optarg_av);
if (oclass == -1)
return (PK_ERR_USAGE);
break;
case 'l': /* objects with specific label */
case 'n':
if (object_label)
return (PK_ERR_USAGE);
object_label = (char *)optarg_av;
break;
case 'k':
kstype = KS2Int(optarg_av);
if (kstype == 0)
return (PK_ERR_USAGE);
break;
case 's':
subject = optarg_av;
break;
case 'i':
issuer = optarg_av;
break;
case 'd':
dir = optarg_av;
break;
case 'p':
prefix = optarg_av;
break;
case 'S':
serstr = optarg_av;
break;
case 'f':
infile = optarg_av;
break;
case 'c':
find_criteria = optarg_av;
if (!strcasecmp(find_criteria, "valid"))
find_criteria_flag =
KMF_NONEXPIRED_CERTS;
else if (!strcasecmp(find_criteria, "expired"))
find_criteria_flag = KMF_EXPIRED_CERTS;
else if (!strcasecmp(find_criteria, "both"))
find_criteria_flag = KMF_ALL_CERTS;
else
return (PK_ERR_USAGE);
break;
default:
return (PK_ERR_USAGE);
}
}
/* Assume keystore = PKCS#11 if not specified */
if (kstype == 0)
kstype = KMF_KEYSTORE_PK11TOKEN;
/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
kstype != KMF_KEYSTORE_PK11TOKEN) {
(void) fprintf(stderr, gettext("The objtype parameter "
"is only relevant if keystore=pkcs11\n"));
return (PK_ERR_USAGE);
}
/* No additional args allowed. */
argc -= optind_av;
argv += optind_av;
if (argc)
return (PK_ERR_USAGE);
/* Done parsing command line options. */
DIR_OPTION_CHECK(kstype, dir);
if (kstype == KMF_KEYSTORE_PK11TOKEN && token_spec == NULL) {
token_spec = PK_DEFAULT_PK11TOKEN;
} else if (kstype == KMF_KEYSTORE_NSS && token_spec == NULL) {
token_spec = DEFAULT_NSS_TOKEN;
}
if (serstr != NULL) {
uchar_t *bytes = NULL;
size_t bytelen;
rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen);
if (rv != KMF_OK || bytes == NULL) {
(void) fprintf(stderr, gettext("serial number "
"must be specified as a hex number "
"(ex: 0x0102030405ffeeddee)\n"));
return (PK_ERR_USAGE);
}
serial.val = bytes;
serial.len = bytelen;
/* If serial number was given, it must be a cert search */
if (oclass == 0)
oclass = PK_CERT_OBJ;
}
/*
* If no object type was given but subject or issuer was,
* it must be a certificate we are looking to delete.
*/
if ((issuer != NULL || subject != NULL) && oclass == 0)
oclass = PK_CERT_OBJ;
/* If no object class specified, delete everything but CRLs */
if (oclass == 0)
oclass = PK_CERT_OBJ | PK_KEY_OBJ;
if ((kstype == KMF_KEYSTORE_PK11TOKEN ||
kstype == KMF_KEYSTORE_NSS) &&
(oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ))) {
(void) get_token_password(kstype, token_spec,
&tokencred);
}
if ((kmfrv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK)
return (kmfrv);
keyrv = certrv = crlrv = KMF_OK;
switch (kstype) {
case KMF_KEYSTORE_PK11TOKEN:
if (oclass & PK_KEY_OBJ) {
keyrv = delete_pk11_keys(kmfhandle,
token_spec, oclass,
object_label, &tokencred);
/*
* If deleting groups of objects, it is OK
* to ignore the "key not found" case so that
* we can continue to find other objects.
*/
if (keyrv != KMF_OK &&
keyrv != KMF_ERR_KEY_NOT_FOUND)
break;
}
if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
certrv = delete_pk11_certs(kmfhandle,
token_spec, object_label,
&serial, issuer,
subject, find_criteria_flag);
/*
* If cert delete failed, but we are looking at
* other objects, then it is OK.
*/
if (certrv != KMF_OK &&
certrv != KMF_ERR_CERT_NOT_FOUND)
break;
}
if (oclass & PK_CRL_OBJ)
crlrv = delete_file_crl(kmfhandle,
infile);
break;
case KMF_KEYSTORE_NSS:
keyrv = certrv = crlrv = KMF_OK;
if (oclass & PK_KEY_OBJ) {
keyrv = delete_nss_keys(kmfhandle,
dir, prefix, token_spec,
oclass, (char *)object_label,
&tokencred);
if (keyrv != KMF_OK &&
keyrv != KMF_ERR_KEY_NOT_FOUND)
break;
}
if (oclass & PK_CERT_OBJ) {
certrv = delete_nss_certs(kmfhandle,
dir, prefix, token_spec,
(char *)object_label,
&serial, issuer, subject,
find_criteria_flag);
if (certrv != KMF_OK &&
certrv != KMF_ERR_CERT_NOT_FOUND)
break;
}
if (oclass & PK_CRL_OBJ)
crlrv = delete_nss_crl(kmfhandle,
dir, prefix, token_spec,
(char *)object_label, subject);
break;
case KMF_KEYSTORE_OPENSSL:
if (oclass & PK_KEY_OBJ) {
keyrv = delete_file_keys(kmfhandle, oclass,
dir, infile);
if (keyrv != KMF_OK)
break;
}
if (oclass & (PK_CERT_OBJ)) {
certrv = delete_file_certs(kmfhandle,
dir, infile, &serial, issuer,
subject, find_criteria_flag);
if (certrv != KMF_OK)
break;
}
if (oclass & PK_CRL_OBJ)
crlrv = delete_file_crl(kmfhandle,
infile);
break;
default:
rv = PK_ERR_USAGE;
break;
}
/*
* Logic here:
* If searching for more than just one class of object (key or cert)
* and only 1 of the classes was not found, it is not an error.
* If searching for just one class of object, that failure should
* be reported.
*
* Any error other than "KMF_ERR_[key/cert]_NOT_FOUND" should
* be reported either way.
*/
if (keyrv != KMF_ERR_KEY_NOT_FOUND && keyrv != KMF_OK)
kmfrv = keyrv;
else if (certrv != KMF_OK && certrv != KMF_ERR_CERT_NOT_FOUND)
kmfrv = certrv;
else if (crlrv != KMF_OK && crlrv != KMF_ERR_CRL_NOT_FOUND)
kmfrv = crlrv;
/*
* If nothing was found, return error.
*/
if ((keyrv == KMF_ERR_KEY_NOT_FOUND && (oclass & PK_KEY_OBJ)) &&
(certrv == KMF_ERR_CERT_NOT_FOUND && (oclass & PK_CERT_OBJ)))
kmfrv = KMF_ERR_KEY_NOT_FOUND;
if (kmfrv != KMF_OK)
goto out;
if (keyrv != KMF_OK && (oclass == PK_KEY_OBJ))
kmfrv = keyrv;
else if (certrv != KMF_OK && (oclass == PK_CERT_OBJ))
kmfrv = certrv;
else if (crlrv != KMF_OK && (oclass == PK_CRL_OBJ))
kmfrv = crlrv;
out:
if (kmfrv != KMF_OK) {
display_error(kmfhandle, kmfrv,
gettext("Error deleting objects"));
}
if (serial.val != NULL)
free(serial.val);
(void) kmf_finalize(kmfhandle);
return (kmfrv);
}