17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 23*7711facfSdinak * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate /* 307c478bd9Sstevel@tonic-gate * This file implements the setpin operation for this tool. 317c478bd9Sstevel@tonic-gate * The basic flow of the process is to load the PKCS#11 module, 32*7711facfSdinak * finds the soft token, prompt the user for the old PIN (if 33*7711facfSdinak * any) and the new PIN, change the token's PIN, and clean up. 347c478bd9Sstevel@tonic-gate */ 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate #include <stdio.h> 377c478bd9Sstevel@tonic-gate #include <stdlib.h> 38*7711facfSdinak #include <errno.h> 397c478bd9Sstevel@tonic-gate #include <string.h> 407c478bd9Sstevel@tonic-gate #include <cryptoutil.h> 417c478bd9Sstevel@tonic-gate #include <security/cryptoki.h> 427c478bd9Sstevel@tonic-gate #include "common.h" 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate /* 45*7711facfSdinak * Changes the token's PIN. 467c478bd9Sstevel@tonic-gate */ 477c478bd9Sstevel@tonic-gate int 487c478bd9Sstevel@tonic-gate pk_setpin(int argc, char *argv[]) 497c478bd9Sstevel@tonic-gate /* ARGSUSED */ 507c478bd9Sstevel@tonic-gate { 517c478bd9Sstevel@tonic-gate char *token_name = NULL; 527c478bd9Sstevel@tonic-gate char *manuf_id = NULL; 537c478bd9Sstevel@tonic-gate char *serial_no = NULL; 547c478bd9Sstevel@tonic-gate CK_SLOT_ID slot_id; 557c478bd9Sstevel@tonic-gate CK_FLAGS pin_state; 56*7711facfSdinak CK_SESSION_HANDLE sess; 57*7711facfSdinak CK_UTF8CHAR_PTR old_pin = NULL, new_pin = NULL; 58*7711facfSdinak CK_ULONG old_pinlen = 0, new_pinlen = 0; 59*7711facfSdinak CK_RV rv = CKR_OK; 60*7711facfSdinak char full_name[FULL_NAME_LEN]; 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate cryptodebug("inside pk_setpin"); 637c478bd9Sstevel@tonic-gate 64*7711facfSdinak /* Get rid of subcommand word "setpin". */ 65*7711facfSdinak argc--; 66*7711facfSdinak argv++; 67*7711facfSdinak 68*7711facfSdinak /* No additional args allowed. */ 69*7711facfSdinak if (argc != 0) 70*7711facfSdinak return (PK_ERR_USAGE); 71*7711facfSdinak /* Done parsing command line options. */ 72*7711facfSdinak 737c478bd9Sstevel@tonic-gate /* 747c478bd9Sstevel@tonic-gate * Token_name, manuf_id, and serial_no are all optional. 757c478bd9Sstevel@tonic-gate * If unspecified, token_name must have a default value 76*7711facfSdinak * at least, so set it to the default softtoken value. 777c478bd9Sstevel@tonic-gate */ 78*7711facfSdinak if (token_name == NULL) 797c478bd9Sstevel@tonic-gate token_name = SOFT_TOKEN_LABEL; 80*7711facfSdinak if (manuf_id == NULL) 817c478bd9Sstevel@tonic-gate manuf_id = SOFT_MANUFACTURER_ID; 82*7711facfSdinak if (serial_no == NULL) 83*7711facfSdinak serial_no = SOFT_TOKEN_SERIAL; 84*7711facfSdinak full_token_name(token_name, manuf_id, serial_no, full_name); 857c478bd9Sstevel@tonic-gate 86*7711facfSdinak /* Find the slot with token. */ 87*7711facfSdinak if ((rv = find_token_slot(token_name, manuf_id, serial_no, &slot_id, 88*7711facfSdinak &pin_state)) != CKR_OK) { 89*7711facfSdinak cryptoerror(LOG_STDERR, 90*7711facfSdinak gettext("Unable to find token %s (%s)."), full_name, 91*7711facfSdinak pkcs11_strerror(rv)); 92*7711facfSdinak final_pk11(NULL); 93*7711facfSdinak return (PK_ERR_PK11); 947c478bd9Sstevel@tonic-gate } 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate /* 97*7711facfSdinak * If the token is the softtoken, check if the token flags show the 98*7711facfSdinak * PIN has not been set yet. If not then set the old PIN to the 99*7711facfSdinak * default "changeme". Otherwise, let user type in the correct old 100*7711facfSdinak * PIN to unlock token. 1017c478bd9Sstevel@tonic-gate */ 102*7711facfSdinak if (pin_state == CKF_USER_PIN_TO_BE_CHANGED && 103*7711facfSdinak strcmp(token_name, SOFT_TOKEN_LABEL) == 0) { 104*7711facfSdinak cryptodebug("pin_state: first time passphrase is being set"); 105*7711facfSdinak if ((old_pin = (CK_UTF8CHAR_PTR) strdup(SOFT_DEFAULT_PIN)) == 106*7711facfSdinak NULL) { 107*7711facfSdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 108*7711facfSdinak final_pk11(NULL); 109*7711facfSdinak return (PK_ERR_PK11); 110*7711facfSdinak } 111*7711facfSdinak old_pinlen = strlen(SOFT_DEFAULT_PIN); 112*7711facfSdinak } else { 113*7711facfSdinak cryptodebug("pin_state: changing an existing pin "); 114*7711facfSdinak if ((rv = get_pin(gettext("Enter token passphrase:"), NULL, 115*7711facfSdinak &old_pin, &old_pinlen)) != CKR_OK) { 116*7711facfSdinak cryptoerror(LOG_STDERR, 117*7711facfSdinak gettext("Unable to get token passphrase (%s)."), 118*7711facfSdinak pkcs11_strerror(rv)); 119*7711facfSdinak final_pk11(NULL); 120*7711facfSdinak return (PK_ERR_PK11); 121*7711facfSdinak } 1227c478bd9Sstevel@tonic-gate } 1237c478bd9Sstevel@tonic-gate 124*7711facfSdinak /* Get the user's new PIN. */ 125*7711facfSdinak if ((rv = get_pin(gettext("Create new passphrase:"), gettext( 126*7711facfSdinak "Re-enter new passphrase:"), &new_pin, &new_pinlen)) != CKR_OK) { 127*7711facfSdinak if (rv == CKR_PIN_INCORRECT) 128*7711facfSdinak cryptoerror(LOG_STDERR, gettext( 129*7711facfSdinak "Passphrases do not match.")); 130*7711facfSdinak else 131*7711facfSdinak cryptoerror(LOG_STDERR, gettext( 132*7711facfSdinak "Unable to get and confirm new passphrase (%s)."), 133*7711facfSdinak pkcs11_strerror(rv)); 134*7711facfSdinak free(old_pin); 135*7711facfSdinak final_pk11(NULL); 136*7711facfSdinak return (PK_ERR_PK11); 1377c478bd9Sstevel@tonic-gate } 1387c478bd9Sstevel@tonic-gate 139*7711facfSdinak /* Open a R/W session to the token to change the PIN. */ 140*7711facfSdinak if ((rv = open_sess(slot_id, CKF_RW_SESSION, &sess)) != CKR_OK) { 141*7711facfSdinak cryptoerror(LOG_STDERR, 142*7711facfSdinak gettext("Unable to open token session (%s)."), 143*7711facfSdinak pkcs11_strerror(rv)); 144*7711facfSdinak free(old_pin); 145*7711facfSdinak final_pk11(NULL); 146*7711facfSdinak return (PK_ERR_PK11); 147*7711facfSdinak } 148*7711facfSdinak 149*7711facfSdinak /* Change the PIN if possible. */ 150*7711facfSdinak cryptodebug("calling C_SetPIN"); 151*7711facfSdinak rv = C_SetPIN(sess, old_pin, old_pinlen, new_pin, new_pinlen); 152*7711facfSdinak 153*7711facfSdinak /* Clean up. */ 154*7711facfSdinak free(old_pin); 155*7711facfSdinak free(new_pin); 156*7711facfSdinak quick_finish(sess); 157*7711facfSdinak 158*7711facfSdinak if (rv != CKR_OK) { 159*7711facfSdinak if (rv == CKR_PIN_INCORRECT) 160*7711facfSdinak cryptoerror(LOG_STDERR, 161*7711facfSdinak gettext("Incorrect passphrase.")); 162*7711facfSdinak else 163*7711facfSdinak cryptoerror(LOG_STDERR, 164*7711facfSdinak gettext("Unable to change passphrase (%s)."), 165*7711facfSdinak pkcs11_strerror(rv)); 166*7711facfSdinak return (PK_ERR_PK11); 167*7711facfSdinak } 168*7711facfSdinak 169*7711facfSdinak (void) fprintf(stdout, gettext("Passphrase changed.\n")); 170*7711facfSdinak return (0); 1717c478bd9Sstevel@tonic-gate } 172