11c9bd843Sdinak /* 21c9bd843Sdinak * CDDL HEADER START 31c9bd843Sdinak * 41c9bd843Sdinak * The contents of this file are subject to the terms of the 51c9bd843Sdinak * Common Development and Distribution License (the "License"). 61c9bd843Sdinak * You may not use this file except in compliance with the License. 71c9bd843Sdinak * 81c9bd843Sdinak * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 91c9bd843Sdinak * or http://www.opensolaris.org/os/licensing. 101c9bd843Sdinak * See the License for the specific language governing permissions 111c9bd843Sdinak * and limitations under the License. 121c9bd843Sdinak * 131c9bd843Sdinak * When distributing Covered Code, include this CDDL HEADER in each 141c9bd843Sdinak * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 151c9bd843Sdinak * If applicable, add the following below this CDDL HEADER, with the 161c9bd843Sdinak * fields enclosed by brackets "[]" replaced with your own identifying 171c9bd843Sdinak * information: Portions Copyright [yyyy] [name of copyright owner] 181c9bd843Sdinak * 191c9bd843Sdinak * CDDL HEADER END 201c9bd843Sdinak */ 211c9bd843Sdinak /* 22*c545f712SDina K Nimeh * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 231c9bd843Sdinak * Use is subject to license terms. 241c9bd843Sdinak */ 251c9bd843Sdinak 261c9bd843Sdinak #include <stdio.h> 271c9bd843Sdinak #include <string.h> 281c9bd843Sdinak #include <fcntl.h> 291c9bd843Sdinak #include <locale.h> 301c9bd843Sdinak #include <cryptoutil.h> 311c9bd843Sdinak 321c9bd843Sdinak #define MAX_PASS_TRIES 5 /* maximum tries to get passphrase */ 331c9bd843Sdinak 341c9bd843Sdinak #define DEFAULT_TOKEN_PROMPT gettext("Enter PIN for %s: ") 351c9bd843Sdinak #define DEFAULT_TOKEN_REPROMPT gettext("Re-enter PIN for %s: ") 361c9bd843Sdinak #define DEFAULT_TOKEN_MINSIZE gettext("PIN must be at least %d characters.\n") 371c9bd843Sdinak 38*c545f712SDina K Nimeh #define DEFAULT_USER_PROMPT gettext("Enter passphrase: ") 39*c545f712SDina K Nimeh #define DEFAULT_USER_REPROMPT gettext("Re-enter passphrase: ") 40*c545f712SDina K Nimeh #define DEFAULT_USER_MINSIZE \ 41*c545f712SDina K Nimeh gettext("Passphrase must be at least %d characters.\n") 421c9bd843Sdinak 431c9bd843Sdinak #define DEFAULT_PK11TOKEN SOFT_TOKEN_LABEL 441c9bd843Sdinak 451c9bd843Sdinak /* 461c9bd843Sdinak * Default token name 471c9bd843Sdinak */ 481c9bd843Sdinak char * 491c9bd843Sdinak pkcs11_default_token(void) 501c9bd843Sdinak { 511c9bd843Sdinak return (DEFAULT_PK11TOKEN); 521c9bd843Sdinak } 531c9bd843Sdinak 541c9bd843Sdinak /* 551c9bd843Sdinak * Prompt user for a passphrase or the PIN for a token. 561c9bd843Sdinak * 571c9bd843Sdinak * An optional minimum length can be enforced. Caller can optionally also 581c9bd843Sdinak * reprompt for the passphrase/PIN to confirm it was entered correctly. 591c9bd843Sdinak * The caller must free the buffer containing the passphrase/PIN with free(). 601c9bd843Sdinak * 0 returned for success, -1 for failure with the first passphrase/PIN, 611c9bd843Sdinak * -2 for failure with the optional second passphrase/PIN used to confirm. 621c9bd843Sdinak */ 631c9bd843Sdinak int 641c9bd843Sdinak pkcs11_get_pass(char *token_name, char **pdata, size_t *psize, size_t min_psize, 651c9bd843Sdinak boolean_t with_confirmation) 661c9bd843Sdinak { 671c9bd843Sdinak char prompt[1024]; 681c9bd843Sdinak char *tmpbuf = NULL; 691c9bd843Sdinak char *databuf = NULL; 701c9bd843Sdinak int tries; 711c9bd843Sdinak 721c9bd843Sdinak if (token_name != NULL) 731c9bd843Sdinak (void) snprintf(prompt, sizeof (prompt), DEFAULT_TOKEN_PROMPT, 741c9bd843Sdinak token_name); 751c9bd843Sdinak else 761c9bd843Sdinak (void) snprintf(prompt, sizeof (prompt), DEFAULT_USER_PROMPT); 771c9bd843Sdinak 781c9bd843Sdinak for (tries = MAX_PASS_TRIES; tries > 0; tries--) { 791c9bd843Sdinak tmpbuf = getpassphrase(prompt); 801c9bd843Sdinak if (tmpbuf == NULL) 811c9bd843Sdinak return (-1); 821c9bd843Sdinak 831c9bd843Sdinak if (strnlen(tmpbuf, min_psize) >= min_psize) 841c9bd843Sdinak break; 851c9bd843Sdinak 861c9bd843Sdinak if (token_name != NULL) 871c9bd843Sdinak (void) printf(DEFAULT_TOKEN_MINSIZE, min_psize); 881c9bd843Sdinak else 891c9bd843Sdinak (void) printf(DEFAULT_USER_MINSIZE, min_psize); 901c9bd843Sdinak } 911c9bd843Sdinak if (tries == 0) { 921c9bd843Sdinak (void) printf(gettext("Exceeded number of attempts.\n")); 931c9bd843Sdinak return (-1); 941c9bd843Sdinak } 951c9bd843Sdinak 961c9bd843Sdinak databuf = strdup(tmpbuf); 971c9bd843Sdinak (void) memset(tmpbuf, 0, strlen(tmpbuf)); /* clean up */ 981c9bd843Sdinak if (databuf == NULL) 991c9bd843Sdinak return (-1); 1001c9bd843Sdinak 1011c9bd843Sdinak if (with_confirmation) { 1021c9bd843Sdinak if (token_name != NULL) 1031c9bd843Sdinak (void) snprintf(prompt, sizeof (prompt), 1041c9bd843Sdinak DEFAULT_TOKEN_REPROMPT, token_name); 1051c9bd843Sdinak else 1061c9bd843Sdinak (void) snprintf(prompt, sizeof (prompt), 1071c9bd843Sdinak DEFAULT_USER_REPROMPT); 1081c9bd843Sdinak tmpbuf = getpassphrase(prompt); 1091c9bd843Sdinak if (tmpbuf == NULL) { 1101c9bd843Sdinak /* clean up */ 1111c9bd843Sdinak (void) memset(databuf, 0, strlen(databuf)); 1121c9bd843Sdinak free(databuf); 1131c9bd843Sdinak return (-2); 1141c9bd843Sdinak } 1151c9bd843Sdinak 1161c9bd843Sdinak if (strcmp(databuf, tmpbuf) != 0) { 1171c9bd843Sdinak /* clean up */ 1181c9bd843Sdinak (void) memset(tmpbuf, 0, strlen(tmpbuf)); 1191c9bd843Sdinak (void) memset(databuf, 0, strlen(databuf)); 1201c9bd843Sdinak free(databuf); 1211c9bd843Sdinak return (-2); 1221c9bd843Sdinak } 1231c9bd843Sdinak } 1241c9bd843Sdinak 1251c9bd843Sdinak *pdata = databuf; 1261c9bd843Sdinak *psize = strlen(databuf); 1271c9bd843Sdinak 1281c9bd843Sdinak return (0); 1291c9bd843Sdinak } 130