15252Sdinak /* 25252Sdinak * CDDL HEADER START 35252Sdinak * 45252Sdinak * The contents of this file are subject to the terms of the 55252Sdinak * Common Development and Distribution License (the "License"). 65252Sdinak * You may not use this file except in compliance with the License. 75252Sdinak * 85252Sdinak * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95252Sdinak * or http://www.opensolaris.org/os/licensing. 105252Sdinak * See the License for the specific language governing permissions 115252Sdinak * and limitations under the License. 125252Sdinak * 135252Sdinak * When distributing Covered Code, include this CDDL HEADER in each 145252Sdinak * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155252Sdinak * If applicable, add the following below this CDDL HEADER, with the 165252Sdinak * fields enclosed by brackets "[]" replaced with your own identifying 175252Sdinak * information: Portions Copyright [yyyy] [name of copyright owner] 185252Sdinak * 195252Sdinak * CDDL HEADER END 205252Sdinak */ 215252Sdinak /* 22*8407SDina.Nimeh@Sun.Com * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 235252Sdinak * Use is subject to license terms. 245252Sdinak */ 255252Sdinak 265252Sdinak #include <stdio.h> 275252Sdinak #include <string.h> 285252Sdinak #include <fcntl.h> 295252Sdinak #include <locale.h> 305252Sdinak #include <cryptoutil.h> 315252Sdinak 325252Sdinak #define MAX_PASS_TRIES 5 /* maximum tries to get passphrase */ 335252Sdinak 345252Sdinak #define DEFAULT_TOKEN_PROMPT gettext("Enter PIN for %s: ") 355252Sdinak #define DEFAULT_TOKEN_REPROMPT gettext("Re-enter PIN for %s: ") 365252Sdinak #define DEFAULT_TOKEN_MINSIZE gettext("PIN must be at least %d characters.\n") 375252Sdinak 38*8407SDina.Nimeh@Sun.Com #define DEFAULT_USER_PROMPT gettext("Enter passphrase: ") 39*8407SDina.Nimeh@Sun.Com #define DEFAULT_USER_REPROMPT gettext("Re-enter passphrase: ") 40*8407SDina.Nimeh@Sun.Com #define DEFAULT_USER_MINSIZE \ 41*8407SDina.Nimeh@Sun.Com gettext("Passphrase must be at least %d characters.\n") 425252Sdinak 435252Sdinak #define DEFAULT_PK11TOKEN SOFT_TOKEN_LABEL 445252Sdinak 455252Sdinak /* 465252Sdinak * Default token name 475252Sdinak */ 485252Sdinak char * 495252Sdinak pkcs11_default_token(void) 505252Sdinak { 515252Sdinak return (DEFAULT_PK11TOKEN); 525252Sdinak } 535252Sdinak 545252Sdinak /* 555252Sdinak * Prompt user for a passphrase or the PIN for a token. 565252Sdinak * 575252Sdinak * An optional minimum length can be enforced. Caller can optionally also 585252Sdinak * reprompt for the passphrase/PIN to confirm it was entered correctly. 595252Sdinak * The caller must free the buffer containing the passphrase/PIN with free(). 605252Sdinak * 0 returned for success, -1 for failure with the first passphrase/PIN, 615252Sdinak * -2 for failure with the optional second passphrase/PIN used to confirm. 625252Sdinak */ 635252Sdinak int 645252Sdinak pkcs11_get_pass(char *token_name, char **pdata, size_t *psize, size_t min_psize, 655252Sdinak boolean_t with_confirmation) 665252Sdinak { 675252Sdinak char prompt[1024]; 685252Sdinak char *tmpbuf = NULL; 695252Sdinak char *databuf = NULL; 705252Sdinak int tries; 715252Sdinak 725252Sdinak if (token_name != NULL) 735252Sdinak (void) snprintf(prompt, sizeof (prompt), DEFAULT_TOKEN_PROMPT, 745252Sdinak token_name); 755252Sdinak else 765252Sdinak (void) snprintf(prompt, sizeof (prompt), DEFAULT_USER_PROMPT); 775252Sdinak 785252Sdinak for (tries = MAX_PASS_TRIES; tries > 0; tries--) { 795252Sdinak tmpbuf = getpassphrase(prompt); 805252Sdinak if (tmpbuf == NULL) 815252Sdinak return (-1); 825252Sdinak 835252Sdinak if (strnlen(tmpbuf, min_psize) >= min_psize) 845252Sdinak break; 855252Sdinak 865252Sdinak if (token_name != NULL) 875252Sdinak (void) printf(DEFAULT_TOKEN_MINSIZE, min_psize); 885252Sdinak else 895252Sdinak (void) printf(DEFAULT_USER_MINSIZE, min_psize); 905252Sdinak } 915252Sdinak if (tries == 0) { 925252Sdinak (void) printf(gettext("Exceeded number of attempts.\n")); 935252Sdinak return (-1); 945252Sdinak } 955252Sdinak 965252Sdinak databuf = strdup(tmpbuf); 975252Sdinak (void) memset(tmpbuf, 0, strlen(tmpbuf)); /* clean up */ 985252Sdinak if (databuf == NULL) 995252Sdinak return (-1); 1005252Sdinak 1015252Sdinak if (with_confirmation) { 1025252Sdinak if (token_name != NULL) 1035252Sdinak (void) snprintf(prompt, sizeof (prompt), 1045252Sdinak DEFAULT_TOKEN_REPROMPT, token_name); 1055252Sdinak else 1065252Sdinak (void) snprintf(prompt, sizeof (prompt), 1075252Sdinak DEFAULT_USER_REPROMPT); 1085252Sdinak tmpbuf = getpassphrase(prompt); 1095252Sdinak if (tmpbuf == NULL) { 1105252Sdinak /* clean up */ 1115252Sdinak (void) memset(databuf, 0, strlen(databuf)); 1125252Sdinak free(databuf); 1135252Sdinak return (-2); 1145252Sdinak } 1155252Sdinak 1165252Sdinak if (strcmp(databuf, tmpbuf) != 0) { 1175252Sdinak /* clean up */ 1185252Sdinak (void) memset(tmpbuf, 0, strlen(tmpbuf)); 1195252Sdinak (void) memset(databuf, 0, strlen(databuf)); 1205252Sdinak free(databuf); 1215252Sdinak return (-2); 1225252Sdinak } 1235252Sdinak } 1245252Sdinak 1255252Sdinak *pdata = databuf; 1265252Sdinak *psize = strlen(databuf); 1275252Sdinak 1285252Sdinak return (0); 1295252Sdinak } 130