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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * Copyright 2018, Joyent, Inc. 25 */ 26 27 #include <cryptoutil.h> 28 #include <strings.h> 29 #include <stdio.h> 30 #include <tzfile.h> 31 #include <sys/crypto/common.h> 32 33 /* 34 * In order to fit everything on one line, the 'CRYPTO_' prefix 35 * has been dropped from the KCF #defines, e.g. 36 * CRYPTO_SUCCESS becomes SUCCESS. 37 */ 38 39 static CK_RV error_number_table[CRYPTO_LAST_ERROR + 1] = { 40 CKR_OK, /* SUCCESS */ 41 CKR_CANCEL, /* CANCEL */ 42 CKR_HOST_MEMORY, /* HOST_MEMORY */ 43 CKR_GENERAL_ERROR, /* GENERAL_ERROR */ 44 CKR_FUNCTION_FAILED, /* FAILED */ 45 CKR_ARGUMENTS_BAD, /* ARGUMENTS_BAD */ 46 CKR_ATTRIBUTE_READ_ONLY, /* ATTRIBUTE_READ_ONLY */ 47 CKR_ATTRIBUTE_SENSITIVE, /* ATTRIBUTE_SENSITIVE */ 48 CKR_ATTRIBUTE_TYPE_INVALID, /* ATTRIBUTE_TYPE_INVALID */ 49 CKR_ATTRIBUTE_VALUE_INVALID, /* ATTRIBUTE_VALUE_INVALID */ 50 CKR_FUNCTION_FAILED, /* CANCELED */ 51 CKR_DATA_INVALID, /* DATA_INVALID */ 52 CKR_DATA_LEN_RANGE, /* DATA_LEN_RANGE */ 53 CKR_DEVICE_ERROR, /* DEVICE_ERROR */ 54 CKR_DEVICE_MEMORY, /* DEVICE_MEMORY */ 55 CKR_DEVICE_REMOVED, /* DEVICE_REMOVED */ 56 CKR_ENCRYPTED_DATA_INVALID, /* ENCRYPTED_DATA_INVALID */ 57 CKR_ENCRYPTED_DATA_LEN_RANGE, /* ENCRYPTED_DATA_LEN_RANGE */ 58 CKR_KEY_HANDLE_INVALID, /* KEY_HANDLE_INVALID */ 59 CKR_KEY_SIZE_RANGE, /* KEY_SIZE_RANGE */ 60 CKR_KEY_TYPE_INCONSISTENT, /* KEY_TYPE_INCONSISTENT */ 61 CKR_KEY_NOT_NEEDED, /* KEY_NOT_NEEDED */ 62 CKR_KEY_CHANGED, /* KEY_CHANGED */ 63 CKR_KEY_NEEDED, /* KEY_NEEDED */ 64 CKR_KEY_INDIGESTIBLE, /* KEY_INDIGESTIBLE */ 65 CKR_KEY_FUNCTION_NOT_PERMITTED, /* KEY_FUNCTION_NOT_PERMITTED */ 66 CKR_KEY_NOT_WRAPPABLE, /* KEY_NOT_WRAPPABLE */ 67 CKR_KEY_UNEXTRACTABLE, /* KEY_UNEXTRACTABLE */ 68 CKR_MECHANISM_INVALID, /* MECHANISM_INVALID */ 69 CKR_MECHANISM_PARAM_INVALID, /* MECHANISM_PARAM_INVALID */ 70 CKR_OBJECT_HANDLE_INVALID, /* OBJECT_HANDLE_INVALID */ 71 CKR_OPERATION_ACTIVE, /* OPERATION_ACTIVE */ 72 CKR_OPERATION_NOT_INITIALIZED, /* OPERATION_NOT_INITIALIZED */ 73 CKR_PIN_INCORRECT, /* PIN_INCORRECT */ 74 CKR_PIN_INVALID, /* PIN_INVALID */ 75 CKR_PIN_LEN_RANGE, /* PIN_LEN_RANGE */ 76 CKR_PIN_EXPIRED, /* PIN_EXPIRED */ 77 CKR_PIN_LOCKED, /* PIN_LOCKED */ 78 CKR_SESSION_CLOSED, /* SESSION_CLOSED */ 79 CKR_SESSION_COUNT, /* SESSION_COUNT */ 80 CKR_SESSION_HANDLE_INVALID, /* SESSION_HANDLE_INVALID */ 81 CKR_SESSION_READ_ONLY, /* SESSION_READ_ONLY */ 82 CKR_SESSION_EXISTS, /* SESSION_EXISTS */ 83 CKR_SESSION_READ_ONLY_EXISTS, /* SESSION_READ_ONLY_EXISTS */ 84 CKR_SESSION_READ_WRITE_SO_EXISTS, /* SESSION_READ_WRITE_SO_EXISTS */ 85 CKR_SIGNATURE_INVALID, /* SIGNATURE_INVALID */ 86 CKR_SIGNATURE_LEN_RANGE, /* SIGNATURE_LEN_RANGE */ 87 CKR_TEMPLATE_INCOMPLETE, /* TEMPLATE_INCOMPLETE */ 88 CKR_TEMPLATE_INCONSISTENT, /* TEMPLATE_INCONSISTENT */ 89 CKR_UNWRAPPING_KEY_HANDLE_INVALID, /* UNWRAPPING_KEY_HANDLE_INVALID */ 90 CKR_UNWRAPPING_KEY_SIZE_RANGE, /* UNWRAPPING_KEY_SIZE_RANGE */ 91 CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, /* UNWRAPPING_KEY_TYPE_INCONSISTENT */ 92 CKR_USER_ALREADY_LOGGED_IN, /* USER_ALREADY_LOGGED_IN */ 93 CKR_USER_NOT_LOGGED_IN, /* USER_NOT_LOGGED_IN */ 94 CKR_USER_PIN_NOT_INITIALIZED, /* USER_PIN_NOT_INITIALIZED */ 95 CKR_USER_TYPE_INVALID, /* USER_TYPE_INVALID */ 96 CKR_USER_ANOTHER_ALREADY_LOGGED_IN, /* USER_ANOTHER_ALREADY_LOGGED_IN */ 97 CKR_USER_TOO_MANY_TYPES, /* USER_TOO_MANY_TYPES */ 98 CKR_WRAPPED_KEY_INVALID, /* WRAPPED_KEY_INVALID */ 99 CKR_WRAPPED_KEY_LEN_RANGE, /* WRAPPED_KEY_LEN_RANGE */ 100 CKR_WRAPPING_KEY_HANDLE_INVALID, /* WRAPPING_KEY_HANDLE_INVALID */ 101 CKR_WRAPPING_KEY_SIZE_RANGE, /* WRAPPING_KEY_SIZE_RANGE */ 102 CKR_WRAPPING_KEY_TYPE_INCONSISTENT, /* WRAPPING_KEY_TYPE_INCONSISTENT */ 103 CKR_RANDOM_SEED_NOT_SUPPORTED, /* RANDOM_SEED_NOT_SUPPORTED */ 104 CKR_RANDOM_NO_RNG, /* RANDOM_NO_RNG */ 105 CKR_DOMAIN_PARAMS_INVALID, /* DOMAIN_PARAMS_INVALID */ 106 CKR_BUFFER_TOO_SMALL, /* BUFFER_TOO_SMALL */ 107 CKR_INFORMATION_SENSITIVE, /* INFORMATION_SENSITIVE */ 108 CKR_FUNCTION_NOT_SUPPORTED, /* NOT_SUPPORTED */ 109 CKR_GENERAL_ERROR, /* QUEUED */ 110 CKR_GENERAL_ERROR, /* BUFFER_TOO_BIG */ 111 CKR_OPERATION_NOT_INITIALIZED, /* INVALID_CONTEXT */ 112 CKR_GENERAL_ERROR, /* INVALID_MAC */ 113 CKR_GENERAL_ERROR, /* MECH_NOT_SUPPORTED */ 114 CKR_GENERAL_ERROR, /* INCONSISTENT_ATTRIBUTE */ 115 CKR_GENERAL_ERROR, /* NO_PERMISSION */ 116 CKR_SLOT_ID_INVALID, /* INVALID_PROVIDER_ID */ 117 CKR_GENERAL_ERROR, /* VERSION_MISMATCH */ 118 CKR_GENERAL_ERROR, /* BUSY */ 119 CKR_GENERAL_ERROR, /* UNKNOWN_PROVIDER */ 120 CKR_GENERAL_ERROR, /* MODVERIFICATION_FAILED */ 121 CKR_GENERAL_ERROR, /* OLD_CTX_TEMPLATE */ 122 CKR_GENERAL_ERROR, /* WEAK_KEY */ 123 CKR_GENERAL_ERROR /* FIPS140_ERROR */ 124 }; 125 126 #if CRYPTO_LAST_ERROR != CRYPTO_FIPS140_ERROR 127 #error "Crypto to PKCS11 error mapping table needs to be updated!" 128 #endif 129 130 /* 131 * This function returns a fullpath based on the "dir" and "filepath" input 132 * arugments. 133 * - If the filepath specified does not start with a "/" and the directory 134 * is also given, prepend the directory to the filename. 135 * - If only dir or filepath is given, this function returns a copy of the 136 * given argument. 137 * - If the filepath is fully qualified already and the "dir" is also 138 * given, return NULL to indicate an error. 139 */ 140 char * 141 get_fullpath(char *dir, char *filepath) 142 { 143 char *fullpath = NULL; 144 int pathlen = 0; 145 int dirlen = 0; 146 147 if (filepath != NULL) 148 pathlen = strlen(filepath); 149 150 if (dir != NULL) 151 dirlen = strlen(dir); 152 153 if (pathlen > 0 && dirlen > 0) { 154 if (filepath[0] != '/') { 155 int len = pathlen + dirlen + 2; 156 fullpath = (char *)malloc(len); 157 if (fullpath != NULL) 158 (void) snprintf(fullpath, len, "%s/%s", 159 dir, filepath); 160 } else { 161 return (NULL); 162 } 163 } else if (pathlen > 0) { 164 fullpath = (char *)strdup(filepath); 165 } else if (dirlen > 0) { 166 fullpath = (char *)strdup(dir); 167 } 168 169 return (fullpath); 170 } 171 172 /* 173 * This function converts the input string to the value of time 174 * in seconds. 175 * - If the input string is NULL, return zero second. 176 * - The input string needs to be in the form of: 177 * number-second(s), number-minute(s), number-hour(s) or 178 * number-day(s). 179 */ 180 int 181 str2lifetime(char *ltimestr, uint32_t *ltime) 182 { 183 int num; 184 char timetok[10]; 185 186 if (ltimestr == NULL || !strlen(ltimestr)) { 187 *ltime = 0; 188 return (0); 189 } 190 191 (void) memset(timetok, 0, sizeof (timetok)); 192 if (sscanf(ltimestr, "%d-%08s", &num, timetok) != 2) 193 return (-1); 194 195 if (!strcasecmp(timetok, "second") || 196 !strcasecmp(timetok, "seconds")) { 197 *ltime = num; 198 } else if (!strcasecmp(timetok, "minute") || 199 !strcasecmp(timetok, "minutes")) { 200 *ltime = num * SECSPERMIN; 201 } else if (!strcasecmp(timetok, "day") || 202 !strcasecmp(timetok, "days")) { 203 *ltime = num * SECSPERDAY; 204 } else if (!strcasecmp(timetok, "hour") || 205 !strcasecmp(timetok, "hours")) { 206 *ltime = num * SECSPERHOUR; 207 } else { 208 *ltime = 0; 209 return (-1); 210 } 211 212 return (0); 213 } 214 215 /* 216 * Map KCF error codes into PKCS11 error codes. 217 */ 218 CK_RV 219 crypto2pkcs11_error_number(uint_t n) 220 { 221 if (n >= sizeof (error_number_table) / sizeof (error_number_table[0])) 222 return (CKR_GENERAL_ERROR); 223 224 return (error_number_table[n]); 225 } 226