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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * This file implements the setpin operation for this tool. 31 * The basic flow of the process is to load the PKCS#11 module, 32 * finds the soft token, prompt the user for the old PIN (if 33 * any) and the new PIN, change the token's PIN, and clean up. 34 */ 35 36 #include <stdio.h> 37 #include <stdlib.h> 38 #include <errno.h> 39 #include <string.h> 40 #include <cryptoutil.h> 41 #include <security/cryptoki.h> 42 #include "common.h" 43 44 /* 45 * Changes the token's PIN. 46 */ 47 int 48 pk_setpin(int argc, char *argv[]) 49 /* ARGSUSED */ 50 { 51 char *token_name = NULL; 52 char *manuf_id = NULL; 53 char *serial_no = NULL; 54 CK_SLOT_ID slot_id; 55 CK_FLAGS pin_state; 56 CK_SESSION_HANDLE sess; 57 CK_UTF8CHAR_PTR old_pin = NULL, new_pin = NULL; 58 CK_ULONG old_pinlen = 0, new_pinlen = 0; 59 CK_RV rv = CKR_OK; 60 char full_name[FULL_NAME_LEN]; 61 62 cryptodebug("inside pk_setpin"); 63 64 /* Get rid of subcommand word "setpin". */ 65 argc--; 66 argv++; 67 68 /* No additional args allowed. */ 69 if (argc != 0) 70 return (PK_ERR_USAGE); 71 /* Done parsing command line options. */ 72 73 /* 74 * Token_name, manuf_id, and serial_no are all optional. 75 * If unspecified, token_name must have a default value 76 * at least, so set it to the default softtoken value. 77 */ 78 if (token_name == NULL) 79 token_name = SOFT_TOKEN_LABEL; 80 if (manuf_id == NULL) 81 manuf_id = SOFT_MANUFACTURER_ID; 82 if (serial_no == NULL) 83 serial_no = SOFT_TOKEN_SERIAL; 84 full_token_name(token_name, manuf_id, serial_no, full_name); 85 86 /* Find the slot with token. */ 87 if ((rv = find_token_slot(token_name, manuf_id, serial_no, &slot_id, 88 &pin_state)) != CKR_OK) { 89 cryptoerror(LOG_STDERR, 90 gettext("Unable to find token %s (%s)."), full_name, 91 pkcs11_strerror(rv)); 92 final_pk11(NULL); 93 return (PK_ERR_PK11); 94 } 95 96 /* 97 * If the token is the softtoken, check if the token flags show the 98 * PIN has not been set yet. If not then set the old PIN to the 99 * default "changeme". Otherwise, let user type in the correct old 100 * PIN to unlock token. 101 */ 102 if (pin_state == CKF_USER_PIN_TO_BE_CHANGED && 103 strcmp(token_name, SOFT_TOKEN_LABEL) == 0) { 104 cryptodebug("pin_state: first time passphrase is being set"); 105 if ((old_pin = (CK_UTF8CHAR_PTR) strdup(SOFT_DEFAULT_PIN)) == 106 NULL) { 107 cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 108 final_pk11(NULL); 109 return (PK_ERR_PK11); 110 } 111 old_pinlen = strlen(SOFT_DEFAULT_PIN); 112 } else { 113 cryptodebug("pin_state: changing an existing pin "); 114 if ((rv = get_pin(gettext("Enter token passphrase:"), NULL, 115 &old_pin, &old_pinlen)) != CKR_OK) { 116 cryptoerror(LOG_STDERR, 117 gettext("Unable to get token passphrase (%s)."), 118 pkcs11_strerror(rv)); 119 final_pk11(NULL); 120 return (PK_ERR_PK11); 121 } 122 } 123 124 /* Get the user's new PIN. */ 125 if ((rv = get_pin(gettext("Create new passphrase:"), gettext( 126 "Re-enter new passphrase:"), &new_pin, &new_pinlen)) != CKR_OK) { 127 if (rv == CKR_PIN_INCORRECT) 128 cryptoerror(LOG_STDERR, gettext( 129 "Passphrases do not match.")); 130 else 131 cryptoerror(LOG_STDERR, gettext( 132 "Unable to get and confirm new passphrase (%s)."), 133 pkcs11_strerror(rv)); 134 free(old_pin); 135 final_pk11(NULL); 136 return (PK_ERR_PK11); 137 } 138 139 /* Open a R/W session to the token to change the PIN. */ 140 if ((rv = open_sess(slot_id, CKF_RW_SESSION, &sess)) != CKR_OK) { 141 cryptoerror(LOG_STDERR, 142 gettext("Unable to open token session (%s)."), 143 pkcs11_strerror(rv)); 144 free(old_pin); 145 final_pk11(NULL); 146 return (PK_ERR_PK11); 147 } 148 149 /* Change the PIN if possible. */ 150 cryptodebug("calling C_SetPIN"); 151 rv = C_SetPIN(sess, old_pin, old_pinlen, new_pin, new_pinlen); 152 153 /* Clean up. */ 154 free(old_pin); 155 free(new_pin); 156 quick_finish(sess); 157 158 if (rv != CKR_OK) { 159 if (rv == CKR_PIN_INCORRECT) 160 cryptoerror(LOG_STDERR, 161 gettext("Incorrect passphrase.")); 162 else 163 cryptoerror(LOG_STDERR, 164 gettext("Unable to change passphrase (%s)."), 165 pkcs11_strerror(rv)); 166 return (PK_ERR_PK11); 167 } 168 169 (void) fprintf(stdout, gettext("Passphrase changed.\n")); 170 return (0); 171 } 172