1*7711facfSdinak /* 2*7711facfSdinak * CDDL HEADER START 3*7711facfSdinak * 4*7711facfSdinak * The contents of this file are subject to the terms of the 5*7711facfSdinak * Common Development and Distribution License, Version 1.0 only 6*7711facfSdinak * (the "License"). You may not use this file except in compliance 7*7711facfSdinak * with the License. 8*7711facfSdinak * 9*7711facfSdinak * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7711facfSdinak * or http://www.opensolaris.org/os/licensing. 11*7711facfSdinak * See the License for the specific language governing permissions 12*7711facfSdinak * and limitations under the License. 13*7711facfSdinak * 14*7711facfSdinak * When distributing Covered Code, include this CDDL HEADER in each 15*7711facfSdinak * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7711facfSdinak * If applicable, add the following below this CDDL HEADER, with the 17*7711facfSdinak * fields enclosed by brackets "[]" replaced with your own identifying 18*7711facfSdinak * information: Portions Copyright [yyyy] [name of copyright owner] 19*7711facfSdinak * 20*7711facfSdinak * CDDL HEADER END 21*7711facfSdinak */ 22*7711facfSdinak /* 23*7711facfSdinak * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7711facfSdinak * Use is subject to license terms. 25*7711facfSdinak */ 26*7711facfSdinak 27*7711facfSdinak #pragma ident "%Z%%M% %I% %E% SMI" 28*7711facfSdinak 29*7711facfSdinak /* 30*7711facfSdinak * This file implements the token object delete operation for this tool. 31*7711facfSdinak * It loads the PKCS#11 modules, finds the object to delete, deletes it, 32*7711facfSdinak * and cleans up. User must be R/W logged into the token. 33*7711facfSdinak */ 34*7711facfSdinak 35*7711facfSdinak #include <stdio.h> 36*7711facfSdinak #include <string.h> 37*7711facfSdinak #include <cryptoutil.h> 38*7711facfSdinak #include <security/cryptoki.h> 39*7711facfSdinak #include "common.h" 40*7711facfSdinak 41*7711facfSdinak /* 42*7711facfSdinak * Delete token objects. 43*7711facfSdinak */ 44*7711facfSdinak int 45*7711facfSdinak pk_delete(int argc, char *argv[]) 46*7711facfSdinak { 47*7711facfSdinak int opt; 48*7711facfSdinak extern int optind; 49*7711facfSdinak extern char *optarg; 50*7711facfSdinak char *token_name = NULL; 51*7711facfSdinak char *manuf_id = NULL; 52*7711facfSdinak char *serial_no = NULL; 53*7711facfSdinak char full_name[FULL_NAME_LEN]; 54*7711facfSdinak boolean_t public_objs = B_FALSE; 55*7711facfSdinak boolean_t private_objs = B_FALSE; 56*7711facfSdinak CK_BYTE *object_label = NULL; 57*7711facfSdinak int obj_type = 0x00; 58*7711facfSdinak CK_SLOT_ID slot_id; 59*7711facfSdinak CK_FLAGS pin_state; 60*7711facfSdinak CK_UTF8CHAR_PTR pin = NULL; 61*7711facfSdinak CK_ULONG pinlen = 0; 62*7711facfSdinak CK_SESSION_HANDLE sess; 63*7711facfSdinak CK_OBJECT_HANDLE *objs; 64*7711facfSdinak CK_ULONG num_objs; 65*7711facfSdinak CK_ATTRIBUTE label = { CKA_LABEL, NULL, 0 }; 66*7711facfSdinak CK_RV rv = CKR_OK; 67*7711facfSdinak int i; 68*7711facfSdinak 69*7711facfSdinak cryptodebug("inside pk_delete"); 70*7711facfSdinak 71*7711facfSdinak /* Parse command line options. Do NOT i18n/l10n. */ 72*7711facfSdinak while ((opt = getopt(argc, argv, "p(private)P(public)l:(label)")) != 73*7711facfSdinak EOF) { 74*7711facfSdinak switch (opt) { 75*7711facfSdinak case 'p': /* private objects */ 76*7711facfSdinak private_objs = B_TRUE; 77*7711facfSdinak obj_type |= PK_PRIVATE_OBJ; 78*7711facfSdinak break; 79*7711facfSdinak case 'P': /* public objects */ 80*7711facfSdinak public_objs = B_TRUE; 81*7711facfSdinak obj_type |= PK_PUBLIC_OBJ; 82*7711facfSdinak break; 83*7711facfSdinak case 'l': /* objects with specific label */ 84*7711facfSdinak if (object_label) 85*7711facfSdinak return (PK_ERR_USAGE); 86*7711facfSdinak object_label = (CK_BYTE *)optarg; 87*7711facfSdinak break; 88*7711facfSdinak default: 89*7711facfSdinak return (PK_ERR_USAGE); 90*7711facfSdinak break; 91*7711facfSdinak } 92*7711facfSdinak } 93*7711facfSdinak 94*7711facfSdinak /* At least one of public, private, or object label is required. */ 95*7711facfSdinak if (!private_objs && !public_objs && object_label == NULL) 96*7711facfSdinak return (PK_ERR_USAGE); 97*7711facfSdinak 98*7711facfSdinak /* 99*7711facfSdinak * If object label is given but neither public/private is specified, 100*7711facfSdinak * delete all objects with that label. 101*7711facfSdinak */ 102*7711facfSdinak if (!private_objs && !public_objs && object_label != NULL) 103*7711facfSdinak obj_type = PK_ALL_OBJ; 104*7711facfSdinak 105*7711facfSdinak /* No additional args allowed. */ 106*7711facfSdinak argc -= optind; 107*7711facfSdinak argv += optind; 108*7711facfSdinak if (argc) 109*7711facfSdinak return (PK_ERR_USAGE); 110*7711facfSdinak /* Done parsing command line options. */ 111*7711facfSdinak 112*7711facfSdinak /* Delete operation only supported on softtoken. */ 113*7711facfSdinak if (token_name == NULL) 114*7711facfSdinak token_name = SOFT_TOKEN_LABEL; 115*7711facfSdinak if (manuf_id == NULL) 116*7711facfSdinak manuf_id = SOFT_MANUFACTURER_ID; 117*7711facfSdinak if (serial_no == NULL) 118*7711facfSdinak serial_no = SOFT_TOKEN_SERIAL; 119*7711facfSdinak full_token_name(token_name, manuf_id, serial_no, full_name); 120*7711facfSdinak 121*7711facfSdinak /* Find the slot with token. */ 122*7711facfSdinak if ((rv = find_token_slot(token_name, manuf_id, serial_no, &slot_id, 123*7711facfSdinak &pin_state)) != CKR_OK) { 124*7711facfSdinak cryptoerror(LOG_STDERR, gettext( 125*7711facfSdinak "Unable to find token %s (%s)."), full_name, 126*7711facfSdinak pkcs11_strerror(rv)); 127*7711facfSdinak return (PK_ERR_PK11); 128*7711facfSdinak } 129*7711facfSdinak 130*7711facfSdinak /* Always get the user's PIN for delete operations. */ 131*7711facfSdinak if ((rv = get_pin(gettext("Enter token passphrase:"), NULL, &pin, 132*7711facfSdinak &pinlen)) != CKR_OK) { 133*7711facfSdinak cryptoerror(LOG_STDERR, gettext( 134*7711facfSdinak "Unable to get token passphrase (%s)."), 135*7711facfSdinak pkcs11_strerror(rv)); 136*7711facfSdinak quick_finish(NULL); 137*7711facfSdinak return (PK_ERR_PK11); 138*7711facfSdinak } 139*7711facfSdinak 140*7711facfSdinak /* Log the user R/W into the token. */ 141*7711facfSdinak if ((rv = quick_start(slot_id, CKF_RW_SESSION, pin, pinlen, &sess)) != 142*7711facfSdinak CKR_OK) { 143*7711facfSdinak cryptoerror(LOG_STDERR, gettext( 144*7711facfSdinak "Unable to log into token (%s)."), pkcs11_strerror(rv)); 145*7711facfSdinak quick_finish(sess); 146*7711facfSdinak return (PK_ERR_PK11); 147*7711facfSdinak } 148*7711facfSdinak 149*7711facfSdinak /* Find the object(s) with the given label and/or type. */ 150*7711facfSdinak if ((rv = find_objs(sess, obj_type, object_label, &objs, &num_objs)) != 151*7711facfSdinak CKR_OK) { 152*7711facfSdinak cryptoerror(LOG_STDERR, gettext( 153*7711facfSdinak "Unable to find token objects (%s)."), pkcs11_strerror(rv)); 154*7711facfSdinak quick_finish(sess); 155*7711facfSdinak return (PK_ERR_PK11); 156*7711facfSdinak } 157*7711facfSdinak 158*7711facfSdinak if (num_objs == 0) { 159*7711facfSdinak (void) fprintf(stdout, gettext("No matching objects found.\n")); 160*7711facfSdinak quick_finish(sess); 161*7711facfSdinak return (0); 162*7711facfSdinak } 163*7711facfSdinak 164*7711facfSdinak if (num_objs != 1) { 165*7711facfSdinak (void) fprintf(stdout, gettext( 166*7711facfSdinak "Warning: %d matching objects found, deleting all.\n"), 167*7711facfSdinak num_objs); 168*7711facfSdinak if (yesno(gettext("Continue with delete? "), 169*7711facfSdinak gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) { 170*7711facfSdinak quick_finish(sess); 171*7711facfSdinak return (0); 172*7711facfSdinak } 173*7711facfSdinak } 174*7711facfSdinak 175*7711facfSdinak /* Destroy the objects if found. */ 176*7711facfSdinak for (i = 0; i < num_objs; i++) { 177*7711facfSdinak /* 178*7711facfSdinak * To give nice feedback to the user, get the object's 179*7711facfSdinak * label before deleting it. 180*7711facfSdinak */ 181*7711facfSdinak cryptodebug("calling C_GetAttributeValue for label"); 182*7711facfSdinak label.pValue = NULL; 183*7711facfSdinak label.ulValueLen = 0; 184*7711facfSdinak if (C_GetAttributeValue(sess, objs[i], &label, 1) == CKR_OK) { 185*7711facfSdinak if (label.ulValueLen != (CK_ULONG)-1 && 186*7711facfSdinak label.ulValueLen != 0 && 187*7711facfSdinak (label.pValue = malloc(label.ulValueLen)) != NULL) { 188*7711facfSdinak if (C_GetAttributeValue(sess, objs[i], &label, 189*7711facfSdinak 1) != CKR_OK) { 190*7711facfSdinak free(label.pValue); 191*7711facfSdinak label.pValue = NULL; 192*7711facfSdinak label.ulValueLen = 0; 193*7711facfSdinak } 194*7711facfSdinak } else { 195*7711facfSdinak label.ulValueLen = 0; 196*7711facfSdinak } 197*7711facfSdinak } 198*7711facfSdinak 199*7711facfSdinak cryptodebug("calling C_DestroyObject"); 200*7711facfSdinak if ((rv = C_DestroyObject(sess, objs[i])) != CKR_OK) { 201*7711facfSdinak if (label.pValue != NULL) 202*7711facfSdinak cryptoerror(LOG_STDERR, gettext( 203*7711facfSdinak "Unable to delete object #%d \"%.*s\" " 204*7711facfSdinak "(%s)."), i+1, label.ulValueLen, 205*7711facfSdinak label.pValue, pkcs11_strerror(rv)); 206*7711facfSdinak else 207*7711facfSdinak cryptoerror(LOG_STDERR, gettext( 208*7711facfSdinak "Unable to delete object #%d (%s)."), 209*7711facfSdinak i+1, pkcs11_strerror(rv)); 210*7711facfSdinak } else { 211*7711facfSdinak if (label.pValue != NULL) 212*7711facfSdinak (void) fprintf(stdout, gettext("Object #%d " 213*7711facfSdinak "\"%.*s\" successfully deleted.\n"), 214*7711facfSdinak i+1, label.ulValueLen, label.pValue); 215*7711facfSdinak else 216*7711facfSdinak (void) fprintf(stdout, gettext( 217*7711facfSdinak "Object #%d successfully deleted.\n"), i+1); 218*7711facfSdinak } 219*7711facfSdinak 220*7711facfSdinak if (label.pValue != NULL) 221*7711facfSdinak free(label.pValue); 222*7711facfSdinak } 223*7711facfSdinak 224*7711facfSdinak /* Clean up. */ 225*7711facfSdinak quick_finish(sess); 226*7711facfSdinak return (0); 227*7711facfSdinak } 228