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 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 22 */ 23 24 #include <stdio.h> 25 #include <dlfcn.h> 26 #include <link.h> 27 #include <fcntl.h> 28 #include <ctype.h> 29 #include <sys/param.h> 30 #include <sys/types.h> 31 #include <sys/stat.h> 32 #include <errno.h> 33 #include <sys/socket.h> 34 #include <netinet/in.h> 35 #include <arpa/inet.h> 36 #include <thread.h> 37 38 #include <ber_der.h> 39 #include <kmfapiP.h> 40 41 #include <pem_encode.h> 42 #include <rdn_parser.h> 43 #include <libxml2/libxml/uri.h> 44 #include <libgen.h> 45 #include <cryptoutil.h> 46 47 static uchar_t pkcs11_initialized = 0; 48 mutex_t init_lock = DEFAULTMUTEX; 49 extern int errno; 50 51 typedef struct { 52 KMF_RETURN code; 53 char *message; 54 } kmf_error_map; 55 56 static kmf_error_map kmf_errcodes[] = { 57 {KMF_OK, "KMF_OK"}, 58 {KMF_ERR_BAD_PARAMETER, "KMF_ERR_BAD_PARAMETER"}, 59 {KMF_ERR_BAD_KEY_FORMAT, "KMF_ERR_BAD_KEY_FORMAT"}, 60 {KMF_ERR_BAD_ALGORITHM, "KMF_ERR_BAD_ALGORITHM"}, 61 {KMF_ERR_MEMORY, "KMF_ERR_MEMORY"}, 62 {KMF_ERR_ENCODING, "KMF_ERR_ENCODING"}, 63 {KMF_ERR_PLUGIN_INIT, "KMF_ERR_PLUGIN_INIT"}, 64 {KMF_ERR_PLUGIN_NOTFOUND, "KMF_ERR_PLUGIN_NOTFOUND"}, 65 {KMF_ERR_INTERNAL, "KMF_ERR_INTERNAL"}, 66 {KMF_ERR_BAD_CERT_FORMAT, "KMF_ERR_BAD_CERT_FORMAT"}, 67 {KMF_ERR_KEYGEN_FAILED, "KMF_ERR_KEYGEN_FAILED"}, 68 {KMF_ERR_UNINITIALIZED, "KMF_ERR_UNINITIALIZED"}, 69 {KMF_ERR_ISSUER, "KMF_ERR_ISSUER"}, 70 {KMF_ERR_NOT_REVOKED, "KMF_ERR_NOT_REVOKED"}, 71 {KMF_ERR_CERT_NOT_FOUND, "KMF_ERR_CERT_NOT_FOUND"}, 72 {KMF_ERR_CRL_NOT_FOUND, "KMF_ERR_CRL_NOT_FOUND"}, 73 {KMF_ERR_RDN_PARSER, "KMF_ERR_RDN_PARSER"}, 74 {KMF_ERR_RDN_ATTR, "KMF_ERR_RDN_ATTR"}, 75 {KMF_ERR_SLOTNAME, "KMF_ERR_SLOTNAME"}, 76 {KMF_ERR_EMPTY_CRL, "KMF_ERR_EMPTY_CRL"}, 77 {KMF_ERR_BUFFER_SIZE, "KMF_ERR_BUFFER_SIZE"}, 78 {KMF_ERR_AUTH_FAILED, "KMF_ERR_AUTH_FAILED"}, 79 {KMF_ERR_TOKEN_SELECTED, "KMF_ERR_TOKEN_SELECTED"}, 80 {KMF_ERR_NO_TOKEN_SELECTED, "KMF_ERR_NO_TOKEN_SELECTED"}, 81 {KMF_ERR_TOKEN_NOT_PRESENT, "KMF_ERR_TOKEN_NOT_PRESENT"}, 82 {KMF_ERR_EXTENSION_NOT_FOUND, "KMF_ERR_EXTENSION_NOT_FOUND"}, 83 {KMF_ERR_POLICY_ENGINE, "KMF_ERR_POLICY_ENGINE"}, 84 {KMF_ERR_POLICY_DB_FORMAT, "KMF_ERR_POLICY_DB_FORMAT"}, 85 {KMF_ERR_POLICY_NOT_FOUND, "KMF_ERR_POLICY_NOT_FOUND"}, 86 {KMF_ERR_POLICY_DB_FILE, "KMF_ERR_POLICY_DB_FILE"}, 87 {KMF_ERR_POLICY_NAME, "KMF_ERR_POLICY_NAME"}, 88 {KMF_ERR_OCSP_POLICY, "KMF_ERR_OCSP_POLICY"}, 89 {KMF_ERR_TA_POLICY, "KMF_ERR_TA_POLICY"}, 90 {KMF_ERR_KEY_NOT_FOUND, "KMF_ERR_KEY_NOT_FOUND"}, 91 {KMF_ERR_OPEN_FILE, "KMF_ERR_OPEN_FILE"}, 92 {KMF_ERR_OCSP_BAD_ISSUER, "KMF_ERR_OCSP_BAD_ISSUER"}, 93 {KMF_ERR_OCSP_BAD_CERT, "KMF_ERR_OCSP_BAD_CERT"}, 94 {KMF_ERR_OCSP_CREATE_REQUEST, "KMF_ERR_OCSP_CREATE_REQUEST"}, 95 {KMF_ERR_CONNECT_SERVER, "KMF_ERR_CONNECT_SERVER"}, 96 {KMF_ERR_SEND_REQUEST, "KMF_ERR_SEND_REQUEST"}, 97 {KMF_ERR_OCSP_CERTID, "KMF_ERR_OCSP_CERTID"}, 98 {KMF_ERR_OCSP_MALFORMED_RESPONSE, "KMF_ERR_OCSP_MALFORMED_RESPONSE"}, 99 {KMF_ERR_OCSP_RESPONSE_STATUS, "KMF_ERR_OCSP_RESPONSE_STATUS"}, 100 {KMF_ERR_OCSP_NO_BASIC_RESPONSE, "KMF_ERR_OCSP_NO_BASIC_RESPONSE"}, 101 {KMF_ERR_OCSP_BAD_SIGNER, "KMF_ERR_OCSP_BAD_SIGNER"}, 102 {KMF_ERR_OCSP_RESPONSE_SIGNATURE, "KMF_ERR_OCSP_RESPONSE_SIGNATURE"}, 103 {KMF_ERR_OCSP_UNKNOWN_CERT, "KMF_ERR_OCSP_UNKNOWN_CERT"}, 104 {KMF_ERR_OCSP_STATUS_TIME_INVALID, "KMF_ERR_OCSP_STATUS_TIME_INVALID"}, 105 {KMF_ERR_BAD_HTTP_RESPONSE, "KMF_ERR_BAD_HTTP_RESPONSE"}, 106 {KMF_ERR_RECV_RESPONSE, "KMF_ERR_RECV_RESPONSE"}, 107 {KMF_ERR_RECV_TIMEOUT, "KMF_ERR_RECV_TIMEOUT"}, 108 {KMF_ERR_DUPLICATE_KEYFILE, "KMF_ERR_DUPLICATE_KEYFILE"}, 109 {KMF_ERR_AMBIGUOUS_PATHNAME, "KMF_ERR_AMBIGUOUS_PATHNAME"}, 110 {KMF_ERR_FUNCTION_NOT_FOUND, "KMF_ERR_FUNCTION_NOT_FOUND"}, 111 {KMF_ERR_PKCS12_FORMAT, "KMF_ERR_PKCS12_FORMAT"}, 112 {KMF_ERR_BAD_KEY_TYPE, "KMF_ERR_BAD_KEY_TYPE"}, 113 {KMF_ERR_BAD_KEY_CLASS, "KMF_ERR_BAD_KEY_CLASS"}, 114 {KMF_ERR_BAD_KEY_SIZE, "KMF_ERR_BAD_KEY_SIZE"}, 115 {KMF_ERR_BAD_HEX_STRING, "KMF_ERR_BAD_HEX_STRING"}, 116 {KMF_ERR_KEYUSAGE, "KMF_ERR_KEYUSAGE"}, 117 {KMF_ERR_VALIDITY_PERIOD, "KMF_ERR_VALIDITY_PERIOD"}, 118 {KMF_ERR_OCSP_REVOKED, "KMF_ERR_OCSP_REVOKED"}, 119 {KMF_ERR_CERT_MULTIPLE_FOUND, "KMF_ERR_CERT_MULTIPLE_FOUND"}, 120 {KMF_ERR_WRITE_FILE, "KMF_ERR_WRITE_FILE"}, 121 {KMF_ERR_BAD_URI, "KMF_ERR_BAD_URI"}, 122 {KMF_ERR_BAD_CRLFILE, "KMF_ERR_BAD_CRLFILE"}, 123 {KMF_ERR_BAD_CERTFILE, "KMF_ERR_BAD_CERTFILE"}, 124 {KMF_ERR_GETKEYVALUE_FAILED, "KMF_ERR_GETKEYVALUE_FAILED"}, 125 {KMF_ERR_BAD_KEYHANDLE, "KMF_ERR_BAD_KEYHANDLE"}, 126 {KMF_ERR_BAD_OBJECT_TYPE, "KMF_ERR_BAD_OBJECT_TYPE"}, 127 {KMF_ERR_OCSP_RESPONSE_LIFETIME, "KMF_ERR_OCSP_RESPONSE_LIFETIME"}, 128 {KMF_ERR_UNKNOWN_CSR_ATTRIBUTE, "KMF_ERR_UNKNOWN_CSR_ATTRIBUTE"}, 129 {KMF_ERR_UNINITIALIZED_TOKEN, "KMF_ERR_UNINITIALIZED_TOKEN"}, 130 {KMF_ERR_INCOMPLETE_TBS_CERT, "KMF_ERR_INCOMPLETE_TBS_CERT"}, 131 {KMF_ERR_MISSING_ERRCODE, "KMF_ERR_MISSING_ERRCODE"}, 132 {KMF_KEYSTORE_ALREADY_INITIALIZED, "KMF_KEYSTORE_ALREADY_INITIALIZED"}, 133 {KMF_ERR_SENSITIVE_KEY, "KMF_ERR_SENSITIVE_KEY"}, 134 {KMF_ERR_UNEXTRACTABLE_KEY, "KMF_ERR_UNEXTRACTABLE_KEY"}, 135 {KMF_ERR_KEY_MISMATCH, "KMF_ERR_KEY_MISMATCH"}, 136 {KMF_ERR_ATTR_NOT_FOUND, "KMF_ERR_ATTR_NOT_FOUND"}, 137 {KMF_ERR_KMF_CONF, "KMF_ERR_KMF_CONF"}, 138 {KMF_ERR_NAME_NOT_MATCHED, "KMF_ERR_NAME_NOT_MATCHED"}, 139 {KMF_ERR_MAPPER_OPEN, "KMF_ERR_MAPPER_OPEN"}, 140 {KMF_ERR_MAPPER_NOT_FOUND, "KMF_ERR_MAPPER_NOT_FOUND"}, 141 {KMF_ERR_MAPPING_FAILED, "KMF_ERR_MAPPING_FAILED"}, 142 {KMF_ERR_CERT_VALIDATION, "KMF_ERR_CERT_VALIDATION"} 143 }; 144 145 typedef struct { 146 KMF_KEYSTORE_TYPE kstype; 147 char *path; 148 boolean_t critical; 149 } KMF_PLUGIN_ITEM; 150 151 KMF_PLUGIN_ITEM plugin_list[] = { 152 {KMF_KEYSTORE_OPENSSL, KMF_PLUGIN_PATH "kmf_openssl.so.1", TRUE}, 153 {KMF_KEYSTORE_PK11TOKEN, KMF_PLUGIN_PATH "kmf_pkcs11.so.1", TRUE}, 154 {KMF_KEYSTORE_NSS, KMF_PLUGIN_PATH "kmf_nss.so.1", FALSE} 155 }; 156 157 158 159 static KMF_RETURN InitializePlugin(KMF_KEYSTORE_TYPE, char *, KMF_PLUGIN **); 160 static KMF_RETURN AddPlugin(KMF_HANDLE_T, KMF_PLUGIN *); 161 static void free_extensions(KMF_X509_EXTENSIONS *extns); 162 static void DestroyPlugin(KMF_PLUGIN *); 163 164 #if defined(__sparcv9) 165 #define ISA_PATH "/sparcv9" 166 #elif defined(__sparc) 167 #define ISA_PATH "/" 168 #elif defined(__i386) 169 #define ISA_PATH "/" 170 #elif defined(__amd64) 171 #define ISA_PATH "/amd64" 172 #endif 173 174 #define DEFAULT_KEYSTORE_NUM 3 175 static int kstore_num = DEFAULT_KEYSTORE_NUM; 176 conf_entrylist_t *extra_plugin_list = NULL; 177 static boolean_t check_extra_plugin = B_FALSE; 178 mutex_t extra_plugin_lock = DEFAULTMUTEX; 179 180 KMF_RETURN 181 init_pk11() 182 { 183 (void) mutex_lock(&init_lock); 184 if (!pkcs11_initialized) { 185 CK_RV rv = C_Initialize(NULL); 186 if ((rv != CKR_OK) && 187 (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { 188 (void) mutex_unlock(&init_lock); 189 return (KMF_ERR_UNINITIALIZED); 190 } else { 191 pkcs11_initialized = 1; 192 } 193 } 194 (void) mutex_unlock(&init_lock); 195 return (KMF_OK); 196 } 197 198 /* 199 * Private method for searching the plugin list for the correct 200 * Plugin to use. 201 */ 202 KMF_PLUGIN * 203 FindPlugin(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE kstype) 204 { 205 KMF_PLUGIN_LIST *node; 206 KMF_RETURN ret = KMF_OK; 207 KMF_PLUGIN *pluginrec = NULL; 208 209 if (handle == NULL) 210 return (NULL); 211 212 node = handle->plugins; 213 214 /* See if the desired plugin was already initialized. */ 215 while (node != NULL && node->plugin->type != kstype) 216 node = node->next; 217 218 if (node != NULL) 219 return (node->plugin); 220 221 /* The plugin was not found, try to initialize it here. */ 222 if (VALID_DEFAULT_KEYSTORE_TYPE(kstype)) { 223 int i; 224 int numitems = sizeof (plugin_list)/sizeof (KMF_PLUGIN_ITEM); 225 for (i = 0; i < numitems; i++) { 226 if (plugin_list[i].kstype == kstype) { 227 ret = InitializePlugin(plugin_list[i].kstype, 228 plugin_list[i].path, &pluginrec); 229 break; 230 } 231 } 232 233 goto out; 234 235 } else { 236 /* 237 * Not a built-in plugin. Check if it is in the 238 * extra_plugin_list. If it is, try to initialize it here. 239 */ 240 conf_entrylist_t *phead = extra_plugin_list; 241 char realpath[MAXPATHLEN]; 242 243 while (phead != NULL) { 244 if (phead->entry->kstype == kstype) 245 break; 246 else 247 phead = phead->next; 248 } 249 250 if (phead == NULL) 251 return (NULL); 252 253 /* 254 * Get the absolute path of the module. 255 * - If modulepath is not a full path, then prepend it 256 * with KMF_PLUGIN_PATH. 257 * - If modulepath is a full path and contain $ISA, then 258 * subsitute the architecture dependent path. 259 */ 260 (void) memset(realpath, 0, sizeof (realpath)); 261 if (strncmp(phead->entry->modulepath, "/", 1) != 0) { 262 (void) snprintf(realpath, MAXPATHLEN, "%s%s", 263 KMF_PLUGIN_PATH, phead->entry->modulepath); 264 } else { 265 char *buf = phead->entry->modulepath; 266 char *isa; 267 268 if ((isa = strstr(buf, PKCS11_ISA)) != NULL) { 269 char *isa_str; 270 271 (void) strncpy(realpath, buf, isa - buf); 272 isa_str = strdup(ISA_PATH); 273 if (isa_str == NULL) /* not enough memory */ 274 return (NULL); 275 276 (void) strncat(realpath, isa_str, 277 strlen(isa_str)); 278 free(isa_str); 279 280 isa += strlen(PKCS11_ISA); 281 (void) strlcat(realpath, isa, MAXPATHLEN); 282 } else { 283 (void) snprintf(realpath, MAXPATHLEN, "%s", 284 phead->entry->modulepath); 285 } 286 } 287 288 ret = InitializePlugin(phead->entry->kstype, realpath, 289 &pluginrec); 290 goto out; 291 } 292 293 out: 294 if (ret != KMF_OK || pluginrec == NULL) 295 /* No matching plugins found in the built-in list */ 296 return (NULL); 297 298 ret = AddPlugin(handle, pluginrec); 299 if (ret != KMF_OK) { 300 DestroyPlugin(pluginrec); 301 pluginrec = NULL; 302 } 303 return (pluginrec); 304 } 305 306 307 static KMF_RETURN 308 InitializePlugin(KMF_KEYSTORE_TYPE kstype, char *path, KMF_PLUGIN **plugin) 309 { 310 KMF_PLUGIN *p = NULL; 311 KMF_PLUGIN_FUNCLIST *(*sym)(); 312 313 if (path == NULL || plugin == NULL) 314 return (KMF_ERR_BAD_PARAMETER); 315 316 *plugin = NULL; 317 318 p = (KMF_PLUGIN *)malloc(sizeof (KMF_PLUGIN)); 319 if (p == NULL) 320 return (KMF_ERR_MEMORY); 321 322 p->type = kstype; 323 p->path = strdup(path); 324 if (p->path == NULL) { 325 free(p); 326 return (KMF_ERR_MEMORY); 327 } 328 /* 329 * Do not use RTLD_GROUP here, or this will cause a circular 330 * dependency when kmf_pkcs11.so.1 gets its PKCS#11 functions 331 * from libpkcs11.so.1 when kmf is used via libelfsign.so.1 332 * called from kcfd. 333 */ 334 p->dldesc = dlopen(path, RTLD_LAZY | RTLD_PARENT); 335 if (p->dldesc == NULL) { 336 free(p->path); 337 free(p); 338 return (KMF_ERR_PLUGIN_INIT); 339 } 340 341 sym = (KMF_PLUGIN_FUNCLIST *(*)())dlsym(p->dldesc, 342 KMF_PLUGIN_INIT_SYMBOL); 343 if (sym == NULL) { 344 (void) dlclose(p->dldesc); 345 free(p->path); 346 free(p); 347 return (KMF_ERR_PLUGIN_INIT); 348 } 349 350 /* Get the function list */ 351 if ((p->funclist = (*sym)()) == NULL) { 352 (void) dlclose(p->dldesc); 353 free(p->path); 354 free(p); 355 return (KMF_ERR_PLUGIN_INIT); 356 } 357 358 *plugin = p; 359 360 return (KMF_OK); 361 } 362 363 static KMF_RETURN 364 AddPlugin(KMF_HANDLE_T handle, KMF_PLUGIN *plugin) 365 { 366 KMF_PLUGIN_LIST *n; 367 368 if (handle == NULL || plugin == NULL) 369 return (KMF_ERR_BAD_PARAMETER); 370 371 /* If the head is NULL, create it */ 372 if (handle->plugins == NULL) { 373 handle->plugins = (KMF_PLUGIN_LIST *)malloc( 374 sizeof (KMF_PLUGIN_LIST)); 375 if (handle->plugins == NULL) 376 return (KMF_ERR_MEMORY); 377 handle->plugins->plugin = plugin; 378 handle->plugins->next = NULL; 379 } else { 380 /* walk the list to find the tail */ 381 n = handle->plugins; 382 while (n->next != NULL) 383 n = n->next; 384 n->next = (KMF_PLUGIN_LIST *)malloc(sizeof (KMF_PLUGIN_LIST)); 385 if (n->next == NULL) 386 return (KMF_ERR_MEMORY); 387 388 n->next->plugin = plugin; 389 n->next->next = NULL; 390 } 391 return (0); 392 } 393 394 static void 395 DestroyPlugin(KMF_PLUGIN *plugin) 396 { 397 if (plugin) { 398 if (plugin->path) 399 free(plugin->path); 400 free(plugin); 401 } 402 } 403 404 static void 405 Cleanup_KMF_Handle(KMF_HANDLE_T handle) 406 { 407 if (handle != NULL) { 408 while (handle->plugins != NULL) { 409 KMF_PLUGIN_LIST *next = handle->plugins->next; 410 411 DestroyPlugin(handle->plugins->plugin); 412 free(handle->plugins); 413 handle->plugins = next; 414 } 415 kmf_free_policy_record(handle->policy); 416 free(handle->policy); 417 } 418 free(handle); 419 } 420 421 void 422 Cleanup_PK11_Session(KMF_HANDLE_T handle) 423 { 424 if (handle != NULL) { 425 /* Close active session on a pkcs11 token */ 426 if (handle->pk11handle != NULL) { 427 (void) C_CloseSession(handle->pk11handle); 428 handle->pk11handle = NULL; 429 } 430 } 431 } 432 433 KMF_RETURN 434 kmf_initialize(KMF_HANDLE_T *outhandle, char *policyfile, char *policyname) 435 { 436 KMF_RETURN ret = KMF_OK; 437 KMF_HANDLE *handle = NULL; 438 439 if (outhandle == NULL) 440 return (KMF_ERR_BAD_PARAMETER); 441 442 *outhandle = NULL; 443 handle = (KMF_HANDLE *)malloc(sizeof (KMF_HANDLE)); 444 if (handle == NULL) 445 return (KMF_ERR_MEMORY); 446 447 (void) memset(handle, 0, sizeof (KMF_HANDLE)); 448 handle->plugins = NULL; 449 450 /* 451 * When this function is called the first time, get the additional 452 * plugins from the config file. 453 */ 454 (void) mutex_lock(&extra_plugin_lock); 455 if (!check_extra_plugin) { 456 457 ret = get_entrylist(&extra_plugin_list); 458 check_extra_plugin = B_TRUE; 459 460 /* 461 * Assign the kstype number to the additional plugins here. 462 * The global kstore_num will be protected by the mutex lock. 463 */ 464 if (ret == KMF_OK) { 465 conf_entrylist_t *phead = extra_plugin_list; 466 while (phead != NULL) { 467 phead->entry->kstype = ++kstore_num; 468 phead = phead->next; 469 } 470 } 471 472 /* 473 * If the KMF configuration file does not exist or cannot be 474 * parsed correctly, we will give a warning in syslog and 475 * continue on as there is no extra plugins in the system. 476 */ 477 if (ret == KMF_ERR_KMF_CONF) { 478 cryptoerror(LOG_WARNING, "KMF was unable to parse " 479 "the private KMF config file.\n"); 480 ret = KMF_OK; 481 } 482 483 if (ret != KMF_OK) { 484 (void) mutex_unlock(&extra_plugin_lock); 485 goto errout; 486 } 487 } 488 (void) mutex_unlock(&extra_plugin_lock); 489 490 /* Initialize the handle with the policy */ 491 ret = kmf_set_policy((void *)handle, 492 policyfile == NULL ? KMF_DEFAULT_POLICY_FILE : policyfile, 493 policyname == NULL ? KMF_DEFAULT_POLICY_NAME : policyname); 494 if (ret != KMF_OK) 495 goto errout; 496 497 /* 498 * Let's have the mapper status structure even if no cert-to-name 499 * mapping is initialized. It's better not to coredump in the 500 * kmf_get_mapper_lasterror function, for example, when there is no 501 * mapping initialized. 502 */ 503 handle->mapstate = malloc(sizeof (KMF_MAPPER_STATE)); 504 if (handle->mapstate == NULL) { 505 ret = KMF_ERR_MEMORY; 506 goto errout; 507 } 508 handle->mapstate->lastmappererr = KMF_OK; 509 handle->mapstate->options = NULL; 510 511 /* 512 * Initialize the mapping scheme according to the policy. If no mapping 513 * is set in the policy database we silently ignore the error. 514 */ 515 (void) kmf_cert_to_name_mapping_initialize(handle, 0, NULL); 516 517 CLEAR_ERROR(handle, ret); 518 errout: 519 if (ret != KMF_OK) { 520 Cleanup_KMF_Handle(handle); 521 handle = NULL; 522 } 523 524 *outhandle = (KMF_HANDLE_T)handle; 525 return (ret); 526 } 527 528 KMF_RETURN 529 kmf_configure_keystore(KMF_HANDLE_T handle, 530 int num_args, 531 KMF_ATTRIBUTE *attrlist) 532 { 533 KMF_RETURN ret = KMF_OK; 534 KMF_PLUGIN *plugin; 535 KMF_KEYSTORE_TYPE kstype; 536 uint32_t len; 537 538 KMF_ATTRIBUTE_TESTER required_attrs[] = { 539 {KMF_KEYSTORE_TYPE_ATTR, FALSE, 1, sizeof (KMF_KEYSTORE_TYPE)}, 540 }; 541 542 int num_req_attrs = sizeof (required_attrs) / 543 sizeof (KMF_ATTRIBUTE_TESTER); 544 545 if (handle == NULL) 546 return (KMF_ERR_BAD_PARAMETER); 547 548 CLEAR_ERROR(handle, ret); 549 550 ret = test_attributes(num_req_attrs, required_attrs, 551 0, NULL, num_args, attrlist); 552 553 if (ret != KMF_OK) 554 return (ret); 555 556 len = sizeof (kstype); 557 ret = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, num_args, 558 &kstype, &len); 559 if (ret != KMF_OK) 560 return (ret); 561 562 plugin = FindPlugin(handle, kstype); 563 if (plugin != NULL && plugin->funclist->ConfigureKeystore != NULL) { 564 return (plugin->funclist->ConfigureKeystore(handle, num_args, 565 attrlist)); 566 } else { 567 /* return KMF_OK, if the plugin does not have an entry */ 568 return (KMF_OK); 569 } 570 } 571 572 KMF_RETURN 573 kmf_finalize(KMF_HANDLE_T handle) 574 { 575 KMF_RETURN ret = KMF_OK; 576 577 CLEAR_ERROR(handle, ret); 578 if (ret != KMF_OK) 579 return (ret); 580 581 if (pkcs11_initialized) { 582 Cleanup_PK11_Session(handle); 583 } 584 Cleanup_KMF_Handle(handle); 585 586 return (ret); 587 } 588 589 KMF_RETURN 590 kmf_get_kmf_error_str(KMF_RETURN errcode, char **errmsg) 591 { 592 KMF_RETURN ret = KMF_OK; 593 int i, maxerr; 594 595 if (errmsg == NULL) 596 return (KMF_ERR_BAD_PARAMETER); 597 598 *errmsg = NULL; 599 maxerr = sizeof (kmf_errcodes) / sizeof (kmf_error_map); 600 601 for (i = 0; i < maxerr && errcode != kmf_errcodes[i].code; i++) 602 /* empty body */ 603 ; 604 605 if (i == maxerr) 606 return (KMF_ERR_MISSING_ERRCODE); 607 else { 608 *errmsg = strdup(kmf_errcodes[i].message); 609 if ((*errmsg) == NULL) 610 return (KMF_ERR_MEMORY); 611 } 612 return (ret); 613 } 614 615 KMF_RETURN 616 kmf_get_plugin_error_str(KMF_HANDLE_T handle, char **msgstr) 617 { 618 KMF_RETURN ret = KMF_OK; 619 KMF_PLUGIN *plugin; 620 621 if (handle == NULL || msgstr == NULL) 622 return (KMF_ERR_BAD_PARAMETER); 623 624 *msgstr = NULL; 625 626 if (handle->lasterr.errcode == 0) { 627 return (KMF_ERR_MISSING_ERRCODE); 628 } 629 630 if (handle->lasterr.kstype == -1) { /* System error */ 631 char *str = strerror(handle->lasterr.errcode); 632 if (str != NULL) { 633 *msgstr = strdup(str); 634 if ((*msgstr) == NULL) 635 return (KMF_ERR_MEMORY); 636 } 637 return (KMF_OK); 638 } 639 640 plugin = FindPlugin(handle, handle->lasterr.kstype); 641 if (plugin == NULL) 642 return (KMF_ERR_PLUGIN_NOTFOUND); 643 644 if (plugin->funclist->GetErrorString != NULL) { 645 ret = plugin->funclist->GetErrorString(handle, msgstr); 646 } else { 647 return (KMF_ERR_FUNCTION_NOT_FOUND); 648 } 649 650 return (ret); 651 } 652 653 654 #define SET_SYS_ERROR(h, c) if (h) {\ 655 h->lasterr.kstype = -1;\ 656 h->lasterr.errcode = c;\ 657 } 658 659 KMF_RETURN 660 kmf_read_input_file(KMF_HANDLE_T handle, char *filename, KMF_DATA *pdata) 661 { 662 struct stat s; 663 long nread, total = 0; 664 int fd; 665 unsigned char *buf = NULL; 666 KMF_RETURN ret; 667 668 if (handle) { 669 CLEAR_ERROR(handle, ret); 670 if (ret != KMF_OK) 671 return (ret); 672 } 673 674 if (filename == NULL || pdata == NULL) { 675 return (KMF_ERR_BAD_PARAMETER); 676 } 677 678 if ((fd = open(filename, O_RDONLY)) < 0) { 679 SET_SYS_ERROR(handle, errno); 680 return (KMF_ERR_OPEN_FILE); 681 } 682 683 if (fstat(fd, &s) < 0) { 684 SET_SYS_ERROR(handle, errno); 685 (void) close(fd); 686 return (KMF_ERR_OPEN_FILE); 687 } 688 689 if ((buf = (unsigned char *) malloc(s.st_size)) == NULL) { 690 (void) close(fd); 691 return (KMF_ERR_MEMORY); 692 } 693 694 do { 695 nread = read(fd, buf+total, s.st_size-total); 696 if (nread < 0) { 697 SET_SYS_ERROR(handle, errno); 698 (void) close(fd); 699 free(buf); 700 return (KMF_ERR_INTERNAL); 701 } 702 total += nread; 703 } while (total < s.st_size); 704 705 pdata->Data = buf; 706 pdata->Length = s.st_size; 707 (void) close(fd); 708 return (KMF_OK); 709 } 710 711 /* 712 * 713 * Name: kmf_der_to_pem 714 * 715 * Description: 716 * Function for converting DER encoded format to PEM encoded format 717 * 718 * Parameters: 719 * type(input) - CERTIFICATE or CSR 720 * data(input) - pointer to the DER encoded data 721 * len(input) - length of input data 722 * out(output) - contains the output buffer address to be returned 723 * outlen(output) - pointer to the returned output length 724 * 725 * Returns: 726 * A KMF_RETURN value indicating success or specifying a particular 727 * error condition. 728 * The value KMF_OK indicates success. All other values represent 729 * an error condition. 730 * 731 */ 732 KMF_RETURN 733 kmf_der_to_pem(KMF_OBJECT_TYPE type, unsigned char *data, 734 int len, unsigned char **out, int *outlen) 735 { 736 737 KMF_RETURN err; 738 if (data == NULL || out == NULL || outlen == NULL) 739 return (KMF_ERR_BAD_PARAMETER); 740 741 err = Der2Pem(type, data, len, out, outlen); 742 return (err); 743 744 } 745 746 /* 747 * 748 * Name: kmf_pem_to_der 749 * 750 * Description: 751 * Function for converting PEM encoded format to DER encoded format 752 * 753 * Parameters: 754 * in(input) - pointer to the PEM encoded data 755 * inlen(input) - length of input data 756 * out(output) - contains the output buffer address to be returned 757 * outlen(output) - pointer to the returned output length 758 * 759 * Returns: 760 * A KMF_RETURN value indicating success or specifying a particular 761 * error condition. 762 * The value KMF_OK indicates success. All other values represent 763 * an error condition. 764 * 765 */ 766 KMF_RETURN 767 kmf_pem_to_der(unsigned char *in, int inlen, 768 unsigned char **out, int *outlen) 769 { 770 KMF_RETURN err; 771 if (in == NULL || out == NULL || outlen == NULL) 772 return (KMF_ERR_BAD_PARAMETER); 773 774 err = Pem2Der(in, inlen, out, outlen); 775 return (err); 776 } 777 778 char * 779 kmf_oid_to_string(KMF_OID *oid) 780 { 781 char numstr[128]; 782 uint32_t number; 783 int numshift; 784 uint32_t i, string_length; 785 uchar_t *cp; 786 char *bp; 787 788 /* First determine the size of the string */ 789 string_length = 0; 790 number = 0; 791 numshift = 0; 792 cp = (unsigned char *)oid->Data; 793 794 number = (uint32_t)cp[0]; 795 (void) sprintf(numstr, "%d ", number/40); 796 797 string_length += strlen(numstr); 798 (void) sprintf(numstr, "%d ", number%40); 799 800 string_length += strlen(numstr); 801 802 for (i = 1; i < oid->Length; i++) { 803 if ((uint32_t)(numshift+7) < (sizeof (uint32_t)*8)) { 804 number = (number << 7) | (cp[i] & 0x7f); 805 numshift += 7; 806 } else { 807 return (NULL); 808 } 809 810 if ((cp[i] & 0x80) == 0) { 811 (void) sprintf(numstr, "%d ", number); 812 string_length += strlen(numstr); 813 number = 0; 814 numshift = 0; 815 } 816 } 817 /* 818 * If we get here, we've calculated the length of "n n n ... n ". Add 4 819 * here for "{ " and "}\0". 820 */ 821 string_length += 4; 822 if ((bp = (char *)malloc(string_length))) { 823 number = (uint32_t)cp[0]; 824 825 (void) sprintf(numstr, "%d.", number/40); 826 (void) strcpy(bp, numstr); 827 828 (void) sprintf(numstr, "%d.", number%40); 829 (void) strcat(bp, numstr); 830 831 number = 0; 832 cp = (unsigned char *) oid->Data; 833 for (i = 1; i < oid->Length; i++) { 834 number = (number << 7) | (cp[i] & 0x7f); 835 if ((cp[i] & 0x80) == 0) { 836 (void) sprintf(numstr, "%d", number); 837 (void) strcat(bp, numstr); 838 number = 0; 839 if (i+1 < oid->Length) 840 (void) strcat(bp, "."); 841 } 842 } 843 } 844 return (bp); 845 } 846 847 static boolean_t 848 check_for_pem(uchar_t *buf, KMF_ENCODE_FORMAT *fmt) 849 { 850 char *p; 851 int i; 852 853 if (buf == NULL) 854 return (FALSE); 855 856 for (i = 0; i < 8 && isascii(buf[i]); i++) 857 /* loop to make sure this is ascii */; 858 if (i != 8) 859 return (FALSE); 860 861 if (memcmp(buf, "Bag Attr", 8) == 0) { 862 *fmt = KMF_FORMAT_PEM_KEYPAIR; 863 return (TRUE); 864 } 865 866 /* Look for "-----BEGIN" right after a newline */ 867 p = strtok((char *)buf, "\n"); 868 while (p != NULL) { 869 if (strstr(p, "-----BEGIN") != NULL) { 870 *fmt = KMF_FORMAT_PEM; 871 /* Restore the buffer */ 872 buf[strlen(p)] = '\n'; 873 return (TRUE); 874 } 875 buf[strlen(p)] = '\n'; 876 p = strtok(NULL, "\n"); 877 } 878 return (FALSE); 879 } 880 881 882 static unsigned char pkcs12_version[3] = {0x02, 0x01, 0x03}; 883 static unsigned char pkcs12_oid[11] = 884 {0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01}; 885 886 /* 887 * This function takes a BER encoded string as input and checks the version 888 * and the oid in the the top-level ASN.1 structure to see if it complies to 889 * the PKCS#12 Syntax. 890 */ 891 static boolean_t 892 check_for_pkcs12(uchar_t *buf, int buf_len) 893 { 894 int index = 0; 895 int length_octets; 896 897 if (buf == NULL || buf_len <= 0) 898 return (FALSE); 899 900 /* 901 * The top level structure for a PKCS12 string: 902 * 903 * PFX ::= SEQUENCE { 904 * version INTEGER {v3(3)}(v3,...) 905 * authSafe ContentInfo 906 * macData MacData OPTIONAL 907 * } 908 * 909 * ContentInfo 910 * FROM PKCS-7 {iso(1) member-body(2) us(840) rsadsi(113549) 911 * pkcs(1) pkcs-7(7) modules(0) pkcs-7(1)} 912 * 913 * Therefore, the BER/DER dump of a PKCS#12 file for the first 2 914 * sequences up to the oid part is as following: 915 * 916 * SEQUENCE { 917 * INTEGER 3 918 * SEQUENCE { 919 * OBJECT IDENTIFIER data (1 2 840 113549 1 7 1) 920 */ 921 922 /* 923 * Check the first sequence and calculate the number of bytes used 924 * to store the length. 925 */ 926 if (buf[index++] != 0x30) 927 return (FALSE); 928 929 if (buf[index] & 0x80) { 930 length_octets = buf[index++] & 0x0F; /* long form */ 931 } else { 932 length_octets = 1; /* short form */ 933 } 934 935 index += length_octets; 936 if (index >= buf_len) 937 return (FALSE); 938 939 /* Skip the length octets and check the pkcs12 version */ 940 if (memcmp(buf + index, pkcs12_version, sizeof (pkcs12_version)) != 0) 941 return (FALSE); 942 943 index += sizeof (pkcs12_version); 944 if (index >= buf_len) 945 return (FALSE); 946 947 /* 948 * Check the 2nd sequence and calculate the number of bytes used 949 * to store the length. 950 */ 951 if ((buf[index++] & 0xFF) != 0x30) 952 return (FALSE); 953 954 if (buf[index] & 0x80) { 955 length_octets = buf[index++] & 0x0F; 956 } else { 957 length_octets = 1; 958 } 959 960 index += length_octets; 961 if (index + sizeof (pkcs12_oid) >= buf_len) 962 return (FALSE); 963 964 /* Skip the length octets and check the oid */ 965 if (memcmp(buf + index, pkcs12_oid, sizeof (pkcs12_oid)) != 0) 966 return (FALSE); 967 else 968 return (TRUE); 969 } 970 971 KMF_RETURN 972 kmf_get_data_format(KMF_DATA *data, KMF_ENCODE_FORMAT *fmt) 973 { 974 uchar_t *buf = data->Data; 975 976 if (check_for_pkcs12(buf, data->Length) == TRUE) { 977 *fmt = KMF_FORMAT_PKCS12; 978 } else if (buf[0] == 0x30 && (buf[1] & 0x80)) { 979 /* It is most likely a generic ASN.1 encoded file */ 980 *fmt = KMF_FORMAT_ASN1; 981 } else if (check_for_pem(buf, fmt) != TRUE) { 982 /* Cannot determine this file format */ 983 *fmt = KMF_FORMAT_UNDEF; 984 return (KMF_ERR_ENCODING); 985 } 986 return (KMF_OK); 987 } 988 989 KMF_RETURN 990 kmf_get_file_format(char *filename, KMF_ENCODE_FORMAT *fmt) 991 { 992 KMF_RETURN ret = KMF_OK; 993 KMF_DATA filebuf = {NULL, 0}; 994 995 if (filename == NULL || !strlen(filename) || fmt == NULL) 996 return (KMF_ERR_BAD_PARAMETER); 997 998 *fmt = 0; 999 ret = kmf_read_input_file(NULL, filename, &filebuf); 1000 if (ret != KMF_OK) 1001 return (ret); 1002 1003 if (filebuf.Length < 8) { 1004 ret = KMF_ERR_ENCODING; /* too small */ 1005 goto end; 1006 } 1007 1008 ret = kmf_get_data_format(&filebuf, fmt); 1009 end: 1010 kmf_free_data(&filebuf); 1011 return (ret); 1012 } 1013 1014 KMF_RETURN 1015 kmf_hexstr_to_bytes(unsigned char *hexstr, unsigned char **bytes, 1016 size_t *outlen) 1017 { 1018 KMF_RETURN ret = KMF_OK; 1019 unsigned char *buf = NULL; 1020 int len, stringlen; 1021 int i; 1022 unsigned char ch; 1023 1024 if (hexstr == NULL) { 1025 return (KMF_ERR_BAD_PARAMETER); 1026 } 1027 1028 if (hexstr[0] == '0' && ((hexstr[1] == 'x') || (hexstr[1] == 'X'))) 1029 hexstr += 2; 1030 1031 for (i = 0; i < strlen((char *)hexstr) && isxdigit(hexstr[i]); i++) 1032 /* empty body */ 1033 ; 1034 /* 1035 * If all the characters are not legitimate hex chars, 1036 * return an error. 1037 */ 1038 if (i != strlen((char *)hexstr)) 1039 return (KMF_ERR_BAD_HEX_STRING); 1040 stringlen = i; 1041 len = (i / 2) + (i % 2); 1042 1043 buf = malloc(len); 1044 if (buf == NULL) { 1045 return (KMF_ERR_MEMORY); 1046 } 1047 (void) memset(buf, 0, len); 1048 1049 for (i = 0; i < stringlen; i++) { 1050 ch = (unsigned char) *hexstr; 1051 hexstr++; 1052 if ((ch >= '0') && (ch <= '9')) 1053 ch -= '0'; 1054 else if ((ch >= 'A') && (ch <= 'F')) 1055 ch = ch - 'A' + 10; 1056 else if ((ch >= 'a') && (ch <= 'f')) 1057 ch = ch - 'a' + 10; 1058 else { 1059 ret = KMF_ERR_BAD_HEX_STRING; 1060 goto out; 1061 } 1062 1063 if (i & 1) { 1064 buf[i/2] |= ch; 1065 } else { 1066 buf[i/2] = (ch << 4); 1067 } 1068 } 1069 1070 *bytes = buf; 1071 *outlen = len; 1072 out: 1073 if (buf != NULL && ret != KMF_OK) { 1074 free(buf); 1075 } 1076 return (ret); 1077 } 1078 1079 void 1080 kmf_free_dn(KMF_X509_NAME *name) 1081 { 1082 KMF_X509_RDN *newrdn = NULL; 1083 KMF_X509_TYPE_VALUE_PAIR *av = NULL; 1084 int i, j; 1085 1086 if (name && name->numberOfRDNs) { 1087 for (i = 0; i < name->numberOfRDNs; i++) { 1088 newrdn = &name->RelativeDistinguishedName[i]; 1089 for (j = 0; j < newrdn->numberOfPairs; j++) { 1090 av = &newrdn->AttributeTypeAndValue[j]; 1091 kmf_free_data(&av->type); 1092 kmf_free_data(&av->value); 1093 } 1094 free(newrdn->AttributeTypeAndValue); 1095 newrdn->numberOfPairs = 0; 1096 newrdn->AttributeTypeAndValue = NULL; 1097 } 1098 free(name->RelativeDistinguishedName); 1099 name->numberOfRDNs = 0; 1100 name->RelativeDistinguishedName = NULL; 1101 } 1102 } 1103 1104 void 1105 kmf_free_kmf_cert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert) 1106 { 1107 KMF_PLUGIN *plugin; 1108 KMF_RETURN ret; 1109 1110 CLEAR_ERROR(handle, ret); 1111 if (ret != KMF_OK) 1112 return; 1113 1114 if (kmf_cert == NULL) 1115 return; 1116 1117 plugin = FindPlugin(handle, kmf_cert->kmf_private.keystore_type); 1118 1119 if (plugin != NULL && plugin->funclist->FreeKMFCert != NULL) { 1120 plugin->funclist->FreeKMFCert(handle, kmf_cert); 1121 } 1122 } 1123 1124 void 1125 kmf_free_data(KMF_DATA *datablock) 1126 { 1127 if (datablock != NULL && datablock->Data != NULL) { 1128 free(datablock->Data); 1129 datablock->Data = NULL; 1130 datablock->Length = 0; 1131 } 1132 } 1133 1134 void 1135 kmf_free_algoid(KMF_X509_ALGORITHM_IDENTIFIER *algoid) 1136 { 1137 if (algoid == NULL) 1138 return; 1139 kmf_free_data(&algoid->algorithm); 1140 kmf_free_data(&algoid->parameters); 1141 } 1142 1143 void 1144 kmf_free_extn(KMF_X509_EXTENSION *exptr) 1145 { 1146 if (exptr == NULL) 1147 return; 1148 1149 kmf_free_data((KMF_DATA *)&exptr->extnId); 1150 kmf_free_data(&exptr->BERvalue); 1151 1152 if (exptr->value.tagAndValue) { 1153 kmf_free_data(&exptr->value.tagAndValue->value); 1154 free(exptr->value.tagAndValue); 1155 } 1156 } 1157 1158 void 1159 kmf_free_tbs_csr(KMF_TBS_CSR *tbscsr) 1160 { 1161 if (tbscsr) { 1162 kmf_free_data(&tbscsr->version); 1163 1164 kmf_free_dn(&tbscsr->subject); 1165 1166 kmf_free_algoid(&tbscsr->subjectPublicKeyInfo.algorithm); 1167 kmf_free_data(&tbscsr->subjectPublicKeyInfo.subjectPublicKey); 1168 1169 free_extensions(&tbscsr->extensions); 1170 } 1171 } 1172 1173 void 1174 kmf_free_signed_csr(KMF_CSR_DATA *csr) 1175 { 1176 if (csr) { 1177 kmf_free_tbs_csr(&csr->csr); 1178 1179 kmf_free_algoid(&csr->signature.algorithmIdentifier); 1180 kmf_free_data(&csr->signature.encrypted); 1181 } 1182 } 1183 1184 static void 1185 free_validity(KMF_X509_VALIDITY *validity) 1186 { 1187 if (validity == NULL) 1188 return; 1189 kmf_free_data(&validity->notBefore.time); 1190 kmf_free_data(&validity->notAfter.time); 1191 } 1192 1193 static void 1194 free_extensions(KMF_X509_EXTENSIONS *extns) 1195 { 1196 int i; 1197 KMF_X509_EXTENSION *exptr; 1198 1199 if (extns && extns->numberOfExtensions > 0) { 1200 for (i = 0; i < extns->numberOfExtensions; i++) { 1201 exptr = &extns->extensions[i]; 1202 kmf_free_extn(exptr); 1203 } 1204 free(extns->extensions); 1205 extns->numberOfExtensions = 0; 1206 extns->extensions = NULL; 1207 } 1208 } 1209 1210 void 1211 kmf_free_tbs_cert(KMF_X509_TBS_CERT *tbscert) 1212 { 1213 if (tbscert) { 1214 kmf_free_data(&tbscert->version); 1215 kmf_free_bigint(&tbscert->serialNumber); 1216 kmf_free_algoid(&tbscert->signature); 1217 1218 kmf_free_dn(&tbscert->issuer); 1219 kmf_free_dn(&tbscert->subject); 1220 1221 free_validity(&tbscert->validity); 1222 1223 kmf_free_data(&tbscert->issuerUniqueIdentifier); 1224 kmf_free_data(&tbscert->subjectUniqueIdentifier); 1225 1226 kmf_free_algoid(&tbscert->subjectPublicKeyInfo.algorithm); 1227 kmf_free_data(&tbscert->subjectPublicKeyInfo.subjectPublicKey); 1228 1229 free_extensions(&tbscert->extensions); 1230 1231 kmf_free_data(&tbscert->issuerUniqueIdentifier); 1232 kmf_free_data(&tbscert->subjectUniqueIdentifier); 1233 } 1234 } 1235 1236 void 1237 kmf_free_signed_cert(KMF_X509_CERTIFICATE *certptr) 1238 { 1239 if (!certptr) 1240 return; 1241 1242 kmf_free_tbs_cert(&certptr->certificate); 1243 1244 kmf_free_algoid(&certptr->signature.algorithmIdentifier); 1245 kmf_free_data(&certptr->signature.encrypted); 1246 } 1247 1248 void 1249 kmf_free_str(char *pstr) 1250 { 1251 if (pstr != NULL) 1252 free(pstr); 1253 } 1254 1255 void 1256 free_keyidlist(KMF_OID *oidlist, int len) 1257 { 1258 int i; 1259 for (i = 0; i < len; i++) { 1260 kmf_free_data((KMF_DATA *)&oidlist[i]); 1261 } 1262 free(oidlist); 1263 } 1264 1265 void 1266 kmf_free_eku(KMF_X509EXT_EKU *eptr) 1267 { 1268 if (eptr && eptr->nEKUs > 0 && eptr->keyPurposeIdList != NULL) 1269 free_keyidlist(eptr->keyPurposeIdList, eptr->nEKUs); 1270 } 1271 1272 void 1273 kmf_free_spki(KMF_X509_SPKI *spki) 1274 { 1275 if (spki != NULL) { 1276 kmf_free_algoid(&spki->algorithm); 1277 kmf_free_data(&spki->subjectPublicKey); 1278 } 1279 } 1280 1281 void 1282 kmf_free_kmf_key(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key) 1283 { 1284 KMF_PLUGIN *plugin; 1285 KMF_RETURN ret; 1286 KMF_ATTRIBUTE attlist[2]; /* only 2 attributes for DeleteKey op */ 1287 int i = 0; 1288 boolean_t token_destroy = B_FALSE; 1289 1290 if (key == NULL) 1291 return; 1292 1293 CLEAR_ERROR(handle, ret); 1294 if (ret != KMF_OK) 1295 return; 1296 1297 kmf_set_attr_at_index(attlist, i, 1298 KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE)); 1299 i++; 1300 1301 kmf_set_attr_at_index(attlist, i, 1302 KMF_DESTROY_BOOL_ATTR, &token_destroy, sizeof (boolean_t)); 1303 i++; 1304 1305 plugin = FindPlugin(handle, key->kstype); 1306 if (plugin != NULL && plugin->funclist->DeleteKey != NULL) { 1307 (void) plugin->funclist->DeleteKey(handle, i, attlist); 1308 } 1309 1310 if (key->keylabel) 1311 free(key->keylabel); 1312 1313 if (key->israw) { 1314 kmf_free_raw_key(key->keyp); 1315 free(key->keyp); 1316 } 1317 1318 (void) memset(key, 0, sizeof (KMF_KEY_HANDLE)); 1319 } 1320 1321 void 1322 kmf_free_bigint(KMF_BIGINT *big) 1323 { 1324 if (big != NULL && big->val != NULL) { 1325 /* Clear it out before returning it to the pool */ 1326 (void) memset(big->val, 0x00, big->len); 1327 free(big->val); 1328 big->val = NULL; 1329 big->len = 0; 1330 } 1331 } 1332 1333 static void 1334 free_raw_rsa(KMF_RAW_RSA_KEY *key) 1335 { 1336 if (key == NULL) 1337 return; 1338 kmf_free_bigint(&key->mod); 1339 kmf_free_bigint(&key->pubexp); 1340 kmf_free_bigint(&key->priexp); 1341 kmf_free_bigint(&key->prime1); 1342 kmf_free_bigint(&key->prime2); 1343 kmf_free_bigint(&key->exp1); 1344 kmf_free_bigint(&key->exp2); 1345 kmf_free_bigint(&key->coef); 1346 } 1347 1348 static void 1349 free_raw_dsa(KMF_RAW_DSA_KEY *key) 1350 { 1351 if (key == NULL) 1352 return; 1353 kmf_free_bigint(&key->prime); 1354 kmf_free_bigint(&key->subprime); 1355 kmf_free_bigint(&key->base); 1356 kmf_free_bigint(&key->value); 1357 } 1358 1359 static void 1360 free_raw_sym(KMF_RAW_SYM_KEY *key) 1361 { 1362 if (key == NULL) 1363 return; 1364 kmf_free_bigint(&key->keydata); 1365 } 1366 1367 void 1368 kmf_free_raw_key(KMF_RAW_KEY_DATA *key) 1369 { 1370 if (key == NULL) 1371 return; 1372 1373 switch (key->keytype) { 1374 case KMF_RSA: 1375 free_raw_rsa(&key->rawdata.rsa); 1376 break; 1377 case KMF_DSA: 1378 free_raw_dsa(&key->rawdata.dsa); 1379 break; 1380 case KMF_AES: 1381 case KMF_RC4: 1382 case KMF_DES: 1383 case KMF_DES3: 1384 free_raw_sym(&key->rawdata.sym); 1385 break; 1386 } 1387 if (key->label) { 1388 free(key->label); 1389 key->label = NULL; 1390 } 1391 kmf_free_data(&key->id); 1392 } 1393 1394 void 1395 kmf_free_raw_sym_key(KMF_RAW_SYM_KEY *key) 1396 { 1397 if (key == NULL) 1398 return; 1399 kmf_free_bigint(&key->keydata); 1400 free(key); 1401 } 1402 1403 /* 1404 * This function frees the space allocated for the name portion of a 1405 * KMF_CRL_DIST_POINT. 1406 */ 1407 void 1408 free_dp_name(KMF_CRL_DIST_POINT *dp) 1409 { 1410 KMF_GENERALNAMES *fullname; 1411 KMF_DATA *urldata; 1412 int i; 1413 1414 if (dp == NULL) 1415 return; 1416 1417 /* For phase 1, we only need to free the fullname space. */ 1418 fullname = &(dp->name.full_name); 1419 if (fullname->number == 0) 1420 return; 1421 1422 for (i = 0; i < fullname->number; i++) { 1423 urldata = &(fullname->namelist[fullname->number - 1].name); 1424 kmf_free_data(urldata); 1425 } 1426 1427 free(fullname->namelist); 1428 } 1429 1430 /* 1431 * This function frees the space allocated for a KMF_CRL_DIST_POINT. 1432 */ 1433 void 1434 free_dp(KMF_CRL_DIST_POINT *dp) 1435 { 1436 if (dp == NULL) 1437 return; 1438 1439 free_dp_name(dp); 1440 kmf_free_data(&(dp->reasons)); 1441 /* Need not to free crl_issuer space at phase 1 */ 1442 } 1443 1444 /* 1445 * This function frees space for a KMF_X509EXT_CRLDISTPOINTS internally. 1446 */ 1447 void 1448 kmf_free_crl_dist_pts(KMF_X509EXT_CRLDISTPOINTS *crl_dps) 1449 { 1450 int i; 1451 1452 if (crl_dps == NULL) 1453 return; 1454 1455 for (i = 0; i < crl_dps->number; i++) 1456 free_dp(&(crl_dps->dplist[i])); 1457 1458 free(crl_dps->dplist); 1459 } 1460 1461 KMF_RETURN 1462 kmf_create_ocsp_request(KMF_HANDLE_T handle, 1463 int num_args, 1464 KMF_ATTRIBUTE *attrlist) 1465 { 1466 KMF_RETURN ret = KMF_OK; 1467 KMF_PLUGIN *plugin; 1468 KMF_RETURN (*createReqFn)(void *, int num_args, 1469 KMF_ATTRIBUTE *attrlist); 1470 1471 KMF_ATTRIBUTE_TESTER required_attrs[] = { 1472 {KMF_OCSP_REQUEST_FILENAME_ATTR, FALSE, 1, 0}, 1473 {KMF_USER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 1474 sizeof (KMF_DATA)}, 1475 {KMF_ISSUER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 1476 sizeof (KMF_DATA)}, 1477 }; 1478 1479 int num_req_attrs = sizeof (required_attrs) / 1480 sizeof (KMF_ATTRIBUTE_TESTER); 1481 1482 if (handle == NULL) 1483 return (KMF_ERR_BAD_PARAMETER); 1484 1485 CLEAR_ERROR(handle, ret); 1486 1487 ret = test_attributes(num_req_attrs, required_attrs, 1488 0, NULL, num_args, attrlist); 1489 1490 if (ret != KMF_OK) 1491 return (ret); 1492 1493 /* 1494 * This framework function is actually implemented in the openssl 1495 * plugin library, so we find the function address and call it. 1496 */ 1497 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 1498 if (plugin == NULL || plugin->dldesc == NULL) { 1499 return (KMF_ERR_PLUGIN_NOTFOUND); 1500 } 1501 1502 createReqFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, 1503 "OpenSSL_CreateOCSPRequest"); 1504 if (createReqFn == NULL) { 1505 return (KMF_ERR_FUNCTION_NOT_FOUND); 1506 } 1507 1508 return (createReqFn(handle, num_args, attrlist)); 1509 1510 } 1511 1512 KMF_RETURN 1513 kmf_get_ocsp_status_for_cert(KMF_HANDLE_T handle, 1514 int num_args, 1515 KMF_ATTRIBUTE *attrlist) 1516 { 1517 KMF_RETURN ret = KMF_OK; 1518 KMF_PLUGIN *plugin; 1519 KMF_RETURN (*getCertStatusFn)(void *, int num_args, 1520 KMF_ATTRIBUTE *attrlist); 1521 1522 KMF_ATTRIBUTE_TESTER required_attrs[] = { 1523 {KMF_USER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 1524 sizeof (KMF_DATA)}, 1525 {KMF_ISSUER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 1526 sizeof (KMF_DATA)}, 1527 {KMF_OCSP_RESPONSE_DATA_ATTR, FALSE, sizeof (KMF_DATA), 1528 sizeof (KMF_DATA)}, 1529 {KMF_OCSP_RESPONSE_STATUS_ATTR, FALSE, sizeof (int), 1530 sizeof (uint32_t)}, 1531 {KMF_OCSP_RESPONSE_REASON_ATTR, FALSE, sizeof (int), 1532 sizeof (uint32_t)}, 1533 {KMF_OCSP_RESPONSE_CERT_STATUS_ATTR, FALSE, sizeof (int), 1534 sizeof (uint32_t)}, 1535 }; 1536 1537 int num_req_attrs = sizeof (required_attrs) / 1538 sizeof (KMF_ATTRIBUTE_TESTER); 1539 1540 if (handle == NULL) 1541 return (KMF_ERR_BAD_PARAMETER); 1542 1543 CLEAR_ERROR(handle, ret); 1544 1545 ret = test_attributes(num_req_attrs, required_attrs, 1546 0, NULL, num_args, attrlist); 1547 1548 if (ret != KMF_OK) 1549 return (ret); 1550 1551 /* 1552 * This framework function is actually implemented in the openssl 1553 * plugin library, so we find the function address and call it. 1554 */ 1555 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 1556 if (plugin == NULL || plugin->dldesc == NULL) { 1557 return (KMF_ERR_INTERNAL); 1558 } 1559 1560 getCertStatusFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, 1561 "OpenSSL_GetOCSPStatusForCert"); 1562 if (getCertStatusFn == NULL) { 1563 return (KMF_ERR_INTERNAL); 1564 } 1565 1566 return (getCertStatusFn(handle, num_args, attrlist)); 1567 1568 } 1569 1570 KMF_RETURN 1571 kmf_string_to_oid(char *oidstring, KMF_OID *oid) 1572 { 1573 KMF_RETURN rv = KMF_OK; 1574 char *cp, *bp, *startp; 1575 int numbuf; 1576 int onumbuf; 1577 int nbytes, index; 1578 int len; 1579 unsigned char *op; 1580 1581 if (oidstring == NULL || oid == NULL) 1582 return (KMF_ERR_BAD_PARAMETER); 1583 1584 len = strlen(oidstring); 1585 1586 bp = oidstring; 1587 cp = bp; 1588 /* Skip over leading space */ 1589 while ((bp < &cp[len]) && isspace(*bp)) 1590 bp++; 1591 1592 startp = bp; 1593 nbytes = 0; 1594 1595 /* 1596 * The first two numbers are chewed up by the first octet. 1597 */ 1598 if (sscanf(bp, "%d", &numbuf) != 1) 1599 return (KMF_ERR_BAD_PARAMETER); 1600 while ((bp < &cp[len]) && isdigit(*bp)) 1601 bp++; 1602 while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 1603 bp++; 1604 if (sscanf(bp, "%d", &numbuf) != 1) 1605 return (KMF_ERR_BAD_PARAMETER); 1606 while ((bp < &cp[len]) && isdigit(*bp)) 1607 bp++; 1608 while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 1609 bp++; 1610 nbytes++; 1611 1612 while (isdigit(*bp)) { 1613 if (sscanf(bp, "%d", &numbuf) != 1) 1614 return (KMF_ERR_BAD_PARAMETER); 1615 while (numbuf) { 1616 nbytes++; 1617 numbuf >>= 7; 1618 } 1619 while ((bp < &cp[len]) && isdigit(*bp)) 1620 bp++; 1621 while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 1622 bp++; 1623 } 1624 1625 oid->Length = nbytes; 1626 oid->Data = malloc(oid->Length); 1627 if (oid->Data == NULL) { 1628 return (KMF_ERR_MEMORY); 1629 } 1630 (void) memset(oid->Data, 0, oid->Length); 1631 1632 op = oid->Data; 1633 1634 bp = startp; 1635 (void) sscanf(bp, "%d", &numbuf); 1636 1637 while (isdigit(*bp)) bp++; 1638 while (isspace(*bp) || *bp == '.') bp++; 1639 1640 onumbuf = 40 * numbuf; 1641 (void) sscanf(bp, "%d", &numbuf); 1642 onumbuf += numbuf; 1643 *op = (unsigned char) onumbuf; 1644 op++; 1645 1646 while (isdigit(*bp)) bp++; 1647 while (isspace(*bp) || *bp == '.') bp++; 1648 while (isdigit(*bp)) { 1649 (void) sscanf(bp, "%d", &numbuf); 1650 nbytes = 0; 1651 /* Have to fill in the bytes msb-first */ 1652 onumbuf = numbuf; 1653 while (numbuf) { 1654 nbytes++; 1655 numbuf >>= 7; 1656 } 1657 numbuf = onumbuf; 1658 op += nbytes; 1659 index = -1; 1660 while (numbuf) { 1661 op[index] = (unsigned char)numbuf & 0x7f; 1662 if (index != -1) 1663 op[index] |= 0x80; 1664 index--; 1665 numbuf >>= 7; 1666 } 1667 while (isdigit(*bp)) bp++; 1668 while (isspace(*bp) || *bp == '.') bp++; 1669 } 1670 1671 return (rv); 1672 } 1673 1674 static KMF_RETURN 1675 encode_rid(char *name, KMF_DATA *derdata) 1676 { 1677 KMF_RETURN rv = KMF_OK; 1678 1679 if (name == NULL || derdata == NULL) 1680 return (KMF_ERR_BAD_PARAMETER); 1681 1682 rv = kmf_string_to_oid(name, (KMF_OID *)derdata); 1683 1684 return (rv); 1685 } 1686 1687 static KMF_RETURN 1688 encode_ipaddr(char *name, KMF_DATA *derdata) 1689 { 1690 KMF_RETURN rv = KMF_OK; 1691 size_t len; 1692 in_addr_t v4; 1693 in6_addr_t v6; 1694 uint8_t *ptr; 1695 1696 if (name == NULL || derdata == NULL) 1697 return (KMF_ERR_BAD_PARAMETER); 1698 1699 v4 = inet_addr(name); 1700 if (v4 == (in_addr_t)-1) { 1701 ptr = (uint8_t *)&v6; 1702 if (inet_pton(AF_INET6, name, ptr) != 1) 1703 return (KMF_ERR_ENCODING); 1704 len = sizeof (v6); 1705 } else { 1706 ptr = (uint8_t *)&v4; 1707 len = sizeof (v4); 1708 } 1709 1710 derdata->Data = malloc(len); 1711 if (derdata->Data == NULL) 1712 return (KMF_ERR_MEMORY); 1713 (void) memcpy(derdata->Data, ptr, len); 1714 derdata->Length = len; 1715 1716 return (rv); 1717 } 1718 1719 static KMF_RETURN 1720 encode_krb5(char *name, KMF_DATA *derdata) 1721 { 1722 KMF_RETURN rv = KMF_OK; 1723 char *at, *realm; 1724 char *slash, *inst = NULL; 1725 BerElement *asn1 = NULL; 1726 BerValue *extdata = NULL; 1727 1728 at = strchr(name, '@'); 1729 if (at == NULL) 1730 return (KMF_ERR_ENCODING); 1731 1732 realm = at + 1; 1733 *at = 0; 1734 1735 /* 1736 * KRB5PrincipalName ::= SEQUENCE { 1737 * realm [0] Realm, 1738 * principalName [1] PrincipalName 1739 * } 1740 * 1741 * KerberosString ::= GeneralString (IA5String) 1742 * Realm ::= KerberosString 1743 * PrincipalName ::= SEQUENCE { 1744 * name-type [0] Int32, 1745 * name-string [1] SEQUENCE OF KerberosString 1746 * } 1747 */ 1748 1749 /* 1750 * Construct the "principalName" first. 1751 * 1752 * The name may be split with a "/" to indicate a new instance. 1753 * This must be separated in the ASN.1 1754 */ 1755 slash = strchr(name, '/'); 1756 if (slash != NULL) { 1757 inst = name; 1758 name = slash + 1; 1759 *slash = 0; 1760 } 1761 if ((asn1 = kmfder_alloc()) == NULL) { 1762 rv = KMF_ERR_MEMORY; 1763 goto cleanup; 1764 } 1765 if (kmfber_printf(asn1, "{Tli", 0xa0, 3, 0x01) == -1) 1766 goto cleanup; 1767 1768 if (inst != NULL) { 1769 if (kmfber_printf(asn1, "Tl{Tl", 0xA1, 1770 strlen(inst) + strlen(name) + 6, 1771 BER_GENERALSTRING, strlen(inst)) == -1) 1772 goto cleanup; 1773 if (kmfber_write(asn1, inst, strlen(inst), 0) != strlen(inst)) 1774 goto cleanup; 1775 if (kmfber_printf(asn1, "Tl", BER_GENERALSTRING, 1776 strlen(name)) == -1) 1777 goto cleanup; 1778 if (kmfber_write(asn1, name, strlen(name), 0) != strlen(name)) 1779 goto cleanup; 1780 } else { 1781 if (kmfber_printf(asn1, "Tl{Tl", 0xA1, 1782 strlen(name) + 4, BER_GENERALSTRING, strlen(name)) == -1) 1783 goto cleanup; 1784 if (kmfber_write(asn1, name, strlen(name), 0) != strlen(name)) 1785 goto cleanup; 1786 } 1787 1788 if (kmfber_printf(asn1, "}}") == -1) 1789 goto cleanup; 1790 if (kmfber_flatten(asn1, &extdata) == -1) { 1791 rv = KMF_ERR_ENCODING; 1792 goto cleanup; 1793 } 1794 kmfber_free(asn1, 1); 1795 asn1 = NULL; 1796 1797 /* Next construct the KRB5PrincipalNameSeq */ 1798 if ((asn1 = kmfder_alloc()) == NULL) { 1799 kmfber_bvfree(extdata); 1800 rv = KMF_ERR_MEMORY; 1801 goto cleanup; 1802 } 1803 if (kmfber_printf(asn1, "{TlTl", 0xA0, strlen(realm) + 2, 1804 BER_GENERALSTRING, strlen(realm)) == -1) 1805 goto cleanup; 1806 if (kmfber_write(asn1, realm, strlen(realm), 0) != strlen(realm)) 1807 goto cleanup; 1808 if (kmfber_printf(asn1, "Tl", 0xA1, extdata->bv_len) == -1) 1809 goto cleanup; 1810 if (kmfber_write(asn1, extdata->bv_val, 1811 extdata->bv_len, 0) != extdata->bv_len) 1812 goto cleanup; 1813 if (kmfber_printf(asn1, "}") == -1) 1814 goto cleanup; 1815 kmfber_bvfree(extdata); 1816 extdata = NULL; 1817 if (kmfber_flatten(asn1, &extdata) == -1) { 1818 rv = KMF_ERR_ENCODING; 1819 goto cleanup; 1820 } 1821 kmfber_free(asn1, 1); 1822 asn1 = NULL; 1823 1824 /* 1825 * GeneralName ::= CHOICE { 1826 * otherName [0] OtherName, 1827 * ... 1828 * } 1829 * 1830 * OtherName ::= SEQUENCE { 1831 * type-id OBJECT IDENTIFIER, 1832 * value [0] EXPLICIT ANY DEFINED BY type-id 1833 * } 1834 */ 1835 1836 /* Now construct the SAN: OID + typed data. */ 1837 if ((asn1 = kmfder_alloc()) == NULL) { 1838 kmfber_bvfree(extdata); 1839 rv = KMF_ERR_MEMORY; 1840 goto cleanup; 1841 } 1842 if (kmfber_printf(asn1, "D", &KMFOID_PKINIT_san) == -1) 1843 goto cleanup; 1844 if (kmfber_printf(asn1, "Tl", 0xA0, extdata->bv_len) == -1) 1845 goto cleanup; 1846 if (kmfber_write(asn1, extdata->bv_val, 1847 extdata->bv_len, 0) != extdata->bv_len) 1848 goto cleanup; 1849 kmfber_bvfree(extdata); 1850 extdata = NULL; 1851 if (kmfber_flatten(asn1, &extdata) == -1) { 1852 rv = KMF_ERR_ENCODING; 1853 goto cleanup; 1854 } 1855 kmfber_free(asn1, 1); 1856 asn1 = NULL; 1857 1858 derdata->Data = (uchar_t *)extdata->bv_val; 1859 extdata->bv_val = NULL; /* clear it so it is not freed later */ 1860 derdata->Length = extdata->bv_len; 1861 1862 cleanup: 1863 if (asn1 != NULL) 1864 kmfber_free(asn1, 1); 1865 1866 if (extdata != NULL) 1867 kmfber_bvfree(extdata); 1868 1869 if (*at == 0) 1870 *at = '@'; 1871 1872 if (inst != NULL) 1873 *slash = '/'; 1874 1875 return (rv); 1876 } 1877 1878 static KMF_RETURN 1879 encode_sclogon(char *name, KMF_DATA *derdata) 1880 { 1881 KMF_RETURN rv = KMF_OK; 1882 BerElement *asn1 = NULL; 1883 BerValue *extdata = NULL; 1884 1885 if ((asn1 = kmfder_alloc()) == NULL) 1886 return (KMF_ERR_MEMORY); 1887 1888 /* The name is encoded as a KerberosString (IA5STRING) */ 1889 if (kmfber_printf(asn1, "{Ds}", 1890 &KMFOID_MS_KP_SCLogon, name) == -1) 1891 goto cleanup; 1892 1893 if (kmfber_flatten(asn1, &extdata) == -1) { 1894 rv = KMF_ERR_ENCODING; 1895 goto cleanup; 1896 } 1897 1898 derdata->Data = (uchar_t *)extdata->bv_val; 1899 derdata->Length = extdata->bv_len; 1900 1901 free(extdata); 1902 cleanup: 1903 if (asn1 != NULL) 1904 kmfber_free(asn1, 1); 1905 1906 return (rv); 1907 } 1908 1909 static KMF_RETURN 1910 verify_uri_format(char *uristring) 1911 { 1912 KMF_RETURN ret = KMF_OK; 1913 xmlURIPtr uriptr = NULL; 1914 1915 /* Parse the URI string; get the hostname and port */ 1916 uriptr = xmlParseURI(uristring); 1917 if (uriptr == NULL) { 1918 ret = KMF_ERR_BAD_URI; 1919 goto out; 1920 } 1921 1922 if (uriptr->scheme == NULL || !strlen(uriptr->scheme)) { 1923 ret = KMF_ERR_BAD_URI; 1924 goto out; 1925 } 1926 1927 if (uriptr->server == NULL || !strlen(uriptr->server)) { 1928 ret = KMF_ERR_BAD_URI; 1929 goto out; 1930 } 1931 out: 1932 if (uriptr != NULL) 1933 xmlFreeURI(uriptr); 1934 return (ret); 1935 } 1936 1937 static KMF_RETURN 1938 encode_altname(char *namedata, 1939 KMF_GENERALNAMECHOICES nametype, KMF_DATA *encodedname) 1940 { 1941 KMF_RETURN ret = KMF_OK; 1942 KMF_X509_NAME dnname; 1943 uchar_t tagval; 1944 BerElement *asn1 = NULL; 1945 BerValue *extdata; 1946 1947 if (namedata == NULL || encodedname == NULL) 1948 return (KMF_ERR_BAD_PARAMETER); 1949 1950 /* 1951 * Encode the namedata according to rules in RFC 3280 for GeneralName. 1952 * The input "namedata" is assumed to be an ASCII string representation 1953 * of the AltName, we need to convert it to correct ASN.1 here before 1954 * adding it to the cert. 1955 */ 1956 switch (nametype) { 1957 case GENNAME_RFC822NAME: /* rfc 822 */ 1958 /* IA5String, no encoding needed */ 1959 encodedname->Data = (uchar_t *)strdup(namedata); 1960 if (encodedname->Data == NULL) 1961 return (KMF_ERR_MEMORY); 1962 encodedname->Length = strlen(namedata); 1963 tagval = (0x80 | nametype); 1964 break; 1965 case GENNAME_DNSNAME: /* rfc 1034 */ 1966 encodedname->Data = (uchar_t *)strdup(namedata); 1967 if (encodedname->Data == NULL) 1968 return (KMF_ERR_MEMORY); 1969 encodedname->Length = strlen(namedata); 1970 tagval = (0x80 | nametype); 1971 break; 1972 case GENNAME_URI: /* rfc 1738 */ 1973 ret = verify_uri_format(namedata); 1974 if (ret != KMF_OK) 1975 return (ret); 1976 /* IA5String, no encoding needed */ 1977 encodedname->Data = (uchar_t *)strdup(namedata); 1978 if (encodedname->Data == NULL) 1979 return (KMF_ERR_MEMORY); 1980 encodedname->Length = strlen(namedata); 1981 tagval = (0x80 | nametype); 1982 break; 1983 case GENNAME_IPADDRESS: 1984 ret = encode_ipaddr(namedata, encodedname); 1985 tagval = (0x80 | nametype); 1986 break; 1987 case GENNAME_REGISTEREDID: 1988 ret = encode_rid(namedata, encodedname); 1989 tagval = (0x80 | nametype); 1990 break; 1991 case GENNAME_DIRECTORYNAME: 1992 ret = kmf_dn_parser(namedata, &dnname); 1993 if (ret == KMF_OK) { 1994 ret = DerEncodeName(&dnname, encodedname); 1995 } 1996 (void) kmf_free_dn(&dnname); 1997 tagval = (0x80 | nametype); 1998 break; 1999 case GENNAME_KRB5PRINC: 2000 tagval = (0xA0 | GENNAME_OTHERNAME); 2001 ret = encode_krb5(namedata, encodedname); 2002 break; 2003 case GENNAME_SCLOGON_UPN: 2004 tagval = (0xA0 | GENNAME_OTHERNAME); 2005 ret = encode_sclogon(namedata, encodedname); 2006 break; 2007 default: 2008 /* unsupported */ 2009 return (KMF_ERR_BAD_PARAMETER); 2010 2011 } 2012 if (ret != KMF_OK) { 2013 kmf_free_data(encodedname); 2014 return (ret); 2015 } 2016 2017 if ((asn1 = kmfder_alloc()) == NULL) 2018 return (KMF_ERR_MEMORY); 2019 2020 if (kmfber_printf(asn1, "Tl", tagval, encodedname->Length) == -1) 2021 goto cleanup; 2022 2023 if (kmfber_write(asn1, (char *)encodedname->Data, 2024 encodedname->Length, 0) == -1) { 2025 ret = KMF_ERR_ENCODING; 2026 goto cleanup; 2027 } 2028 if (kmfber_flatten(asn1, &extdata) == -1) { 2029 ret = KMF_ERR_ENCODING; 2030 goto cleanup; 2031 } 2032 2033 kmf_free_data(encodedname); 2034 encodedname->Data = (uchar_t *)extdata->bv_val; 2035 encodedname->Length = extdata->bv_len; 2036 2037 free(extdata); 2038 2039 cleanup: 2040 if (asn1) 2041 kmfber_free(asn1, 1); 2042 2043 if (ret != KMF_OK) 2044 kmf_free_data(encodedname); 2045 2046 return (ret); 2047 } 2048 2049 KMF_X509_EXTENSION * 2050 FindExtn(KMF_X509_EXTENSIONS *exts, KMF_OID *oid) 2051 { 2052 KMF_X509_EXTENSION *foundextn = NULL; 2053 int i; 2054 2055 if (exts == NULL || oid == NULL) 2056 return (NULL); 2057 2058 for (i = 0; i < exts->numberOfExtensions; i++) { 2059 if (IsEqualOid(oid, &exts->extensions[i].extnId)) { 2060 foundextn = &exts->extensions[i]; 2061 break; 2062 } 2063 } 2064 return (foundextn); 2065 } 2066 2067 KMF_RETURN 2068 GetSequenceContents(char *data, size_t len, 2069 char **contents, size_t *outlen) 2070 { 2071 KMF_RETURN ret = KMF_OK; 2072 BerElement *exasn1 = NULL; 2073 BerValue oldextn; 2074 int tag; 2075 size_t oldsize; 2076 char *olddata = NULL; 2077 2078 if (data == NULL || contents == NULL || outlen == NULL) 2079 return (KMF_ERR_BAD_PARAMETER); 2080 2081 /* 2082 * Decode the sequence of general names 2083 */ 2084 oldextn.bv_val = data; 2085 oldextn.bv_len = len; 2086 2087 if ((exasn1 = kmfder_init(&oldextn)) == NULL) { 2088 ret = KMF_ERR_MEMORY; 2089 goto out; 2090 } 2091 2092 /* 2093 * Unwrap the sequence to find the size of the block 2094 * of GeneralName items in the set. 2095 * 2096 * Peek at the tag and length ("tl"), 2097 * then consume them ("{"). 2098 */ 2099 if (kmfber_scanf(exasn1, "tl{", &tag, &oldsize) == KMFBER_DEFAULT || 2100 oldsize == 0) { 2101 ret = KMF_ERR_ENCODING; 2102 goto out; 2103 } 2104 2105 olddata = malloc(oldsize); 2106 if (olddata == NULL) { 2107 ret = KMF_ERR_MEMORY; 2108 goto out; 2109 } 2110 (void) memset(olddata, 0, oldsize); 2111 /* 2112 * Read the entire blob of GeneralNames, we don't 2113 * need to interpret them now. 2114 */ 2115 if (kmfber_read(exasn1, olddata, oldsize) != oldsize) { 2116 ret = KMF_ERR_ENCODING; 2117 goto out; 2118 } 2119 out: 2120 if (exasn1 != NULL) 2121 kmfber_free(exasn1, 1); 2122 2123 if (ret != KMF_OK) { 2124 *contents = NULL; 2125 *outlen = 0; 2126 if (olddata != NULL) 2127 free(olddata); 2128 } else { 2129 *contents = olddata; 2130 *outlen = oldsize; 2131 } 2132 return (ret); 2133 } 2134 2135 KMF_RETURN 2136 add_an_extension(KMF_X509_EXTENSIONS *exts, KMF_X509_EXTENSION *newextn) 2137 { 2138 KMF_RETURN ret = KMF_OK; 2139 KMF_X509_EXTENSION *extlist; 2140 2141 if (exts == NULL || newextn == NULL) 2142 return (KMF_ERR_BAD_PARAMETER); 2143 2144 extlist = malloc(sizeof (KMF_X509_EXTENSION) * 2145 (exts->numberOfExtensions + 1)); 2146 if (extlist == NULL) 2147 return (KMF_ERR_MEMORY); 2148 2149 (void) memcpy(extlist, exts->extensions, 2150 exts->numberOfExtensions * sizeof (KMF_X509_EXTENSION)); 2151 2152 (void) memcpy(&extlist[exts->numberOfExtensions], newextn, 2153 sizeof (KMF_X509_EXTENSION)); 2154 2155 free(exts->extensions); 2156 exts->numberOfExtensions++; 2157 exts->extensions = extlist; 2158 2159 return (ret); 2160 } 2161 2162 KMF_RETURN 2163 kmf_set_altname(KMF_X509_EXTENSIONS *extensions, 2164 KMF_OID *oid, 2165 int critical, 2166 KMF_GENERALNAMECHOICES nametype, 2167 char *namedata) 2168 { 2169 KMF_RETURN ret = KMF_OK; 2170 KMF_X509_EXTENSION subjAltName; 2171 KMF_DATA dername = { NULL, 0 }; 2172 BerElement *asn1 = NULL; 2173 BerValue *extdata; 2174 char *olddata = NULL; 2175 KMF_X509_EXTENSION *foundextn = NULL; 2176 size_t oldsize = 0; 2177 2178 if (extensions == NULL || oid == NULL || namedata == NULL) 2179 return (KMF_ERR_BAD_PARAMETER); 2180 2181 ret = encode_altname(namedata, nametype, &dername); 2182 2183 if (ret != KMF_OK) 2184 return (ret); 2185 2186 (void) memset(&subjAltName, 0, sizeof (subjAltName)); 2187 2188 ret = copy_data(&subjAltName.extnId, oid); 2189 if (ret != KMF_OK) 2190 goto out; 2191 /* 2192 * Check to see if this cert already has a subjectAltName. 2193 */ 2194 foundextn = FindExtn(extensions, oid); 2195 2196 if (foundextn != NULL) { 2197 ret = GetSequenceContents( 2198 (char *)foundextn->BERvalue.Data, 2199 foundextn->BERvalue.Length, 2200 &olddata, &oldsize); 2201 if (ret != KMF_OK) 2202 goto out; 2203 } 2204 2205 /* 2206 * Assume (!!) that the namedata given is already properly encoded. 2207 */ 2208 if ((asn1 = kmfder_alloc()) == NULL) 2209 return (KMF_ERR_MEMORY); 2210 2211 if (kmfber_printf(asn1, "{") == -1) { 2212 ret = KMF_ERR_ENCODING; 2213 goto out; 2214 } 2215 2216 /* Write the old extension data first */ 2217 if (olddata != NULL && oldsize > 0) { 2218 if (kmfber_write(asn1, olddata, oldsize, 0) == -1) { 2219 ret = KMF_ERR_ENCODING; 2220 goto out; 2221 } 2222 } 2223 2224 /* Now add the new name to the list */ 2225 if (kmfber_write(asn1, (char *)dername.Data, dername.Length, 0) == -1) { 2226 ret = KMF_ERR_ENCODING; 2227 goto out; 2228 } 2229 2230 /* Now close the sequence */ 2231 if (kmfber_printf(asn1, "}") == -1) { 2232 ret = KMF_ERR_ENCODING; 2233 goto out; 2234 } 2235 if (kmfber_flatten(asn1, &extdata) == -1) { 2236 ret = KMF_ERR_ENCODING; 2237 goto out; 2238 } 2239 2240 /* 2241 * If we are just adding to an existing list of altNames, 2242 * just replace the BER data associated with the found extension. 2243 */ 2244 if (foundextn != NULL) { 2245 free(foundextn->BERvalue.Data); 2246 foundextn->critical = critical; 2247 foundextn->BERvalue.Data = (uchar_t *)extdata->bv_val; 2248 foundextn->BERvalue.Length = extdata->bv_len; 2249 } else { 2250 subjAltName.critical = critical; 2251 subjAltName.format = KMF_X509_DATAFORMAT_ENCODED; 2252 subjAltName.BERvalue.Data = (uchar_t *)extdata->bv_val; 2253 subjAltName.BERvalue.Length = extdata->bv_len; 2254 ret = add_an_extension(extensions, &subjAltName); 2255 if (ret != KMF_OK) 2256 free(subjAltName.BERvalue.Data); 2257 } 2258 2259 free(extdata); 2260 out: 2261 if (olddata != NULL) 2262 free(olddata); 2263 2264 kmf_free_data(&dername); 2265 if (ret != KMF_OK) 2266 kmf_free_data(&subjAltName.extnId); 2267 if (asn1 != NULL) 2268 kmfber_free(asn1, 1); 2269 return (ret); 2270 } 2271 2272 /* 2273 * Search a list of attributes for one that matches the given type. 2274 * Return a pointer into the attribute list. This does not 2275 * return a copy of the value, it returns a reference into the 2276 * given list. 2277 */ 2278 int 2279 kmf_find_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, int numattrs) 2280 { 2281 int i; 2282 for (i = 0; i < numattrs; i++) { 2283 if (attlist[i].type == type) 2284 return (i); 2285 } 2286 return (-1); 2287 } 2288 2289 /* 2290 * Verify that a given attribute is consistent with the 2291 * "test" attribute. 2292 */ 2293 static KMF_RETURN 2294 verify_attribute(KMF_ATTRIBUTE *givenattr, 2295 KMF_ATTRIBUTE_TESTER *testattr) 2296 { 2297 /* A NULL pValue was found where one is required */ 2298 if (testattr->null_value_ok == FALSE && 2299 givenattr->pValue == NULL) 2300 return (KMF_ERR_BAD_PARAMETER); 2301 2302 /* If the given valueLen is too small, return error */ 2303 if (givenattr->pValue != NULL && 2304 testattr->minlen > 0 && 2305 (givenattr->valueLen < testattr->minlen)) 2306 return (KMF_ERR_BAD_PARAMETER); 2307 2308 /* If the given valueLen is too big, return error */ 2309 if (givenattr->pValue != NULL && 2310 testattr->maxlen > 0 && 2311 (givenattr->valueLen > testattr->maxlen)) 2312 return (KMF_ERR_BAD_PARAMETER); 2313 2314 return (KMF_OK); 2315 } 2316 2317 /* 2318 * Given a set of required attribute tests and optional 2319 * attributes, make sure that the actual attributes 2320 * being tested (attrlist below) are allowed and are 2321 * properly specified. 2322 */ 2323 KMF_RETURN 2324 test_attributes(int reqnum, KMF_ATTRIBUTE_TESTER *reqattrs, 2325 int optnum, KMF_ATTRIBUTE_TESTER *optattrs, 2326 int numattrs, KMF_ATTRIBUTE *attrlist) 2327 { 2328 KMF_RETURN ret = KMF_OK; 2329 int i, idx; 2330 2331 /* 2332 * If the caller didn't supply enough attributes, 2333 * return an error. 2334 */ 2335 if (numattrs < reqnum || attrlist == NULL) 2336 return (KMF_ERR_BAD_PARAMETER); 2337 2338 /* 2339 * Make sure all required attrs are present and 2340 * correct. 2341 */ 2342 for (i = 0; i < reqnum && ret == KMF_OK; i++) { 2343 idx = kmf_find_attr(reqattrs[i].type, attrlist, numattrs); 2344 /* If a required attr is not found, return error */ 2345 if (idx == -1) { 2346 return (KMF_ERR_BAD_PARAMETER); 2347 } 2348 2349 ret = verify_attribute(&attrlist[idx], &reqattrs[i]); 2350 } 2351 /* 2352 * Now test the optional parameters. 2353 */ 2354 for (i = 0; i < optnum && ret == KMF_OK; i++) { 2355 idx = kmf_find_attr(optattrs[i].type, attrlist, numattrs); 2356 /* If a optional attr is not found, continue. */ 2357 if (idx == -1) { 2358 continue; 2359 } 2360 2361 ret = verify_attribute(&attrlist[idx], &optattrs[i]); 2362 } 2363 2364 return (ret); 2365 } 2366 2367 /* 2368 * Given an already allocated attribute list, insert 2369 * the given attribute information at a specific index 2370 * in the list. 2371 */ 2372 void 2373 kmf_set_attr_at_index(KMF_ATTRIBUTE *attlist, int index, 2374 KMF_ATTR_TYPE type, void *pValue, uint32_t len) 2375 { 2376 if (attlist == NULL) 2377 return; 2378 2379 attlist[index].type = type; 2380 attlist[index].pValue = pValue; 2381 attlist[index].valueLen = len; 2382 } 2383 2384 /* 2385 * Find an attribute matching a particular type and set 2386 * the pValue and length fields to the given values. 2387 */ 2388 KMF_RETURN 2389 kmf_set_attr(KMF_ATTRIBUTE *attlist, int numattr, 2390 KMF_ATTR_TYPE type, void *pValue, uint32_t len) 2391 { 2392 int idx; 2393 if (attlist == NULL) 2394 return (KMF_ERR_BAD_PARAMETER); 2395 2396 idx = kmf_find_attr(type, attlist, numattr); 2397 if (idx == -1) 2398 return (KMF_ERR_ATTR_NOT_FOUND); 2399 2400 attlist[idx].type = type; 2401 /* Assumes the attribute pValue can hold the result */ 2402 if (attlist[idx].pValue != NULL) { 2403 if (attlist[idx].valueLen >= len) 2404 (void) memcpy(attlist[idx].pValue, pValue, len); 2405 else 2406 return (KMF_ERR_BUFFER_SIZE); 2407 } 2408 attlist[idx].valueLen = len; 2409 return (KMF_OK); 2410 } 2411 2412 /* 2413 * Find a particular attribute in a list and return 2414 * a pointer to its value. 2415 */ 2416 void * 2417 kmf_get_attr_ptr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, 2418 int numattrs) 2419 { 2420 int i; 2421 2422 i = kmf_find_attr(type, attlist, numattrs); 2423 if (i == -1) 2424 return (NULL); 2425 2426 return (attlist[i].pValue); 2427 } 2428 2429 /* 2430 * Find a particular attribute in a list and return 2431 * the value and length values. Value and length 2432 * may be NULL if the caller doesn't want their values 2433 * to be filled in. 2434 */ 2435 KMF_RETURN 2436 kmf_get_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, 2437 int numattrs, void *outValue, uint32_t *outlen) 2438 { 2439 int i; 2440 uint32_t len = 0; 2441 uint32_t *lenptr = outlen; 2442 2443 if (lenptr == NULL) 2444 lenptr = &len; 2445 2446 i = kmf_find_attr(type, attlist, numattrs); 2447 if (i == -1) 2448 return (KMF_ERR_ATTR_NOT_FOUND); 2449 2450 /* This assumes that the ptr passed in is pre-allocated space */ 2451 if (attlist[i].pValue != NULL && outValue != NULL) { 2452 /* 2453 * If the caller did not specify a length, 2454 * assume "outValue" is big enough. 2455 */ 2456 if (outlen != NULL) { 2457 if (*outlen >= attlist[i].valueLen) 2458 (void) memcpy(outValue, attlist[i].pValue, 2459 attlist[i].valueLen); 2460 else 2461 return (KMF_ERR_BUFFER_SIZE); 2462 } else { 2463 (void) memcpy(outValue, attlist[i].pValue, 2464 attlist[i].valueLen); 2465 } 2466 } 2467 2468 if (outlen != NULL) 2469 *outlen = attlist[i].valueLen; 2470 return (KMF_OK); 2471 } 2472 2473 /* 2474 * Utility routine to find a string type attribute, allocate it 2475 * and return the value to the caller. This simplifies the 2476 * operation by doing both "kmf_get_attr" calls and avoids 2477 * duplicating this block of code in lots of places. 2478 */ 2479 KMF_RETURN 2480 kmf_get_string_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attrlist, 2481 int numattrs, char **outstr) 2482 { 2483 KMF_RETURN rv; 2484 uint32_t len; 2485 2486 if (outstr == NULL) 2487 return (KMF_ERR_BAD_PARAMETER); 2488 2489 if ((rv = kmf_get_attr(type, attrlist, numattrs, NULL, &len)) == 2490 KMF_OK) { 2491 *outstr = malloc(len + 1); 2492 if ((*outstr) == NULL) 2493 return (KMF_ERR_MEMORY); 2494 (void) memset((*outstr), 0, len + 1); 2495 rv = kmf_get_attr(type, attrlist, numattrs, (*outstr), &len); 2496 if (rv != KMF_OK) { 2497 free(*outstr); 2498 *outstr = NULL; 2499 } 2500 } 2501 2502 return (rv); 2503 } 2504 2505 2506 void 2507 free_entry(conf_entry_t *entry) 2508 { 2509 if (entry == NULL) 2510 return; 2511 free(entry->keystore); 2512 free(entry->modulepath); 2513 free(entry->option); 2514 } 2515 2516 void 2517 free_entrylist(conf_entrylist_t *list) 2518 { 2519 conf_entrylist_t *next; 2520 2521 while (list != NULL) { 2522 next = list->next; 2523 free_entry(list->entry); 2524 free(list); 2525 list = next; 2526 } 2527 } 2528 2529 static KMF_RETURN 2530 parse_entry(char *buf, conf_entry_t **entry) 2531 { 2532 KMF_RETURN ret = KMF_OK; 2533 conf_entry_t *tmp = NULL; 2534 char *token1; 2535 char *token2; 2536 char *token3; 2537 char *lasts; 2538 char *value; 2539 2540 if ((token1 = strtok_r(buf, SEP_COLON, &lasts)) == NULL) 2541 return (KMF_ERR_KMF_CONF); 2542 2543 if ((tmp = calloc(sizeof (conf_entry_t), 1)) == NULL) 2544 return (KMF_ERR_MEMORY); 2545 2546 if ((tmp->keystore = strdup(token1)) == NULL) { 2547 ret = KMF_ERR_MEMORY; 2548 goto end; 2549 } 2550 2551 if ((token2 = strtok_r(NULL, SEP_SEMICOLON, &lasts)) == NULL) { 2552 ret = KMF_ERR_KMF_CONF; 2553 goto end; 2554 } 2555 2556 /* need to get token3 first to satisfy nested strtok invocations */ 2557 token3 = strtok_r(NULL, SEP_SEMICOLON, &lasts); 2558 2559 /* parse token2 */ 2560 if (strncmp(token2, CONF_MODULEPATH, strlen(CONF_MODULEPATH)) != 0) { 2561 ret = KMF_ERR_KMF_CONF; 2562 goto end; 2563 } 2564 2565 if (value = strpbrk(token2, SEP_EQUAL)) { 2566 value++; /* get rid of = */ 2567 } else { 2568 ret = KMF_ERR_KMF_CONF; 2569 goto end; 2570 } 2571 2572 if ((tmp->modulepath = strdup(value)) == NULL) { 2573 ret = KMF_ERR_MEMORY; 2574 goto end; 2575 } 2576 2577 /* parse token3, if it exists */ 2578 if (token3 != NULL) { 2579 if (strncmp(token3, CONF_OPTION, strlen(CONF_OPTION)) 2580 != 0) { 2581 ret = KMF_ERR_KMF_CONF; 2582 goto end; 2583 } 2584 2585 if (value = strpbrk(token3, SEP_EQUAL)) { 2586 value++; /* get rid of = */ 2587 } else { 2588 ret = KMF_ERR_KMF_CONF; 2589 goto end; 2590 } 2591 2592 if ((tmp->option = strdup(value)) == NULL) { 2593 ret = KMF_ERR_MEMORY; 2594 goto end; 2595 } 2596 } 2597 2598 *entry = tmp; 2599 2600 end: 2601 if (ret != KMF_OK) { 2602 free_entry(tmp); 2603 free(tmp); 2604 } 2605 return (ret); 2606 } 2607 2608 2609 conf_entry_t * 2610 dup_entry(conf_entry_t *entry) 2611 { 2612 conf_entry_t *rtn_entry; 2613 2614 if (entry == NULL) 2615 return (NULL); 2616 2617 rtn_entry = malloc(sizeof (conf_entry_t)); 2618 if (rtn_entry == NULL) 2619 return (NULL); 2620 2621 if ((rtn_entry->keystore = strdup(entry->keystore)) == NULL) 2622 goto out; 2623 2624 if ((rtn_entry->modulepath = strdup(entry->modulepath)) == NULL) 2625 goto out; 2626 2627 if (entry->option != NULL && 2628 (rtn_entry->option = strdup(entry->modulepath)) == NULL) 2629 goto out; 2630 2631 return (rtn_entry); 2632 2633 out: 2634 free_entry(rtn_entry); 2635 return (NULL); 2636 } 2637 2638 2639 /* 2640 * This function takes a keystore_name as input and returns 2641 * the KMF_KEYSTORE_TYPE value assigned to it. If the "option" 2642 * argument is not NULL, this function also returns the option string 2643 * if there is an option string for the plugin module. 2644 */ 2645 KMF_RETURN 2646 kmf_get_plugin_info(KMF_HANDLE_T handle, char *keystore_name, 2647 KMF_KEYSTORE_TYPE *kstype, char **option) 2648 { 2649 KMF_RETURN ret = KMF_OK; 2650 conf_entrylist_t *phead = extra_plugin_list; 2651 boolean_t is_default = B_TRUE; 2652 2653 /* 2654 * Although handle is not really used in the function, we will 2655 * check the handle to make sure that kmf_intialize() is called 2656 * before this function. 2657 */ 2658 if (handle == NULL || keystore_name == NULL || kstype == NULL) 2659 return (KMF_ERR_BAD_PARAMETER); 2660 2661 if (strcmp(keystore_name, "pkcs11") == 0) { 2662 *kstype = KMF_KEYSTORE_PK11TOKEN; 2663 } else if (strcmp(keystore_name, "file") == 0) { 2664 *kstype = KMF_KEYSTORE_OPENSSL; 2665 } else if (strcmp(keystore_name, "nss") == 0) { 2666 *kstype = KMF_KEYSTORE_NSS; 2667 } else { 2668 is_default = B_FALSE; 2669 } 2670 2671 if (is_default) { 2672 if (option != NULL) 2673 *option = NULL; 2674 goto out; 2675 } 2676 2677 /* Not a built-in plugin; check if it is in extra_plugin_list. */ 2678 while (phead != NULL) { 2679 if (strcmp(phead->entry->keystore, keystore_name) == 0) 2680 break; 2681 phead = phead->next; 2682 } 2683 2684 if (phead == NULL) { 2685 ret = KMF_ERR_PLUGIN_NOTFOUND; 2686 goto out; 2687 } 2688 2689 /* found it */ 2690 *kstype = phead->entry->kstype; 2691 if (option != NULL) { 2692 if (phead->entry->option == NULL) 2693 *option = NULL; 2694 else { 2695 *option = strdup(phead->entry->option); 2696 if (*option == NULL) { 2697 ret = KMF_ERR_MEMORY; 2698 goto out; 2699 } 2700 } 2701 } 2702 2703 out: 2704 return (ret); 2705 } 2706 2707 /* 2708 * Retrieve the non-default plugin list from the kmf.conf file. 2709 */ 2710 KMF_RETURN 2711 get_entrylist(conf_entrylist_t **entlist) 2712 { 2713 KMF_RETURN rv = KMF_OK; 2714 FILE *pfile; 2715 conf_entry_t *entry; 2716 conf_entrylist_t *rtnlist = NULL; 2717 conf_entrylist_t *ptmp; 2718 conf_entrylist_t *pcur; 2719 char buffer[MAXPATHLEN]; 2720 size_t len; 2721 2722 if ((pfile = fopen(_PATH_KMF_CONF, "rF")) == NULL) { 2723 cryptoerror(LOG_ERR, "failed to open %s.\n", _PATH_KMF_CONF); 2724 return (KMF_ERR_KMF_CONF); 2725 } 2726 2727 while (fgets(buffer, MAXPATHLEN, pfile) != NULL) { 2728 if (buffer[0] == '#' || buffer[0] == ' ' || 2729 buffer[0] == '\n'|| buffer[0] == '\t') { 2730 continue; /* ignore comment lines */ 2731 } 2732 2733 len = strlen(buffer); 2734 if (buffer[len-1] == '\n') { /* get rid of trailing '\n' */ 2735 len--; 2736 } 2737 buffer[len] = '\0'; 2738 2739 rv = parse_entry(buffer, &entry); 2740 if (rv != KMF_OK) { 2741 goto end; 2742 } 2743 2744 if ((ptmp = malloc(sizeof (conf_entrylist_t))) == NULL) { 2745 rv = KMF_ERR_MEMORY; 2746 goto end; 2747 } 2748 ptmp->entry = entry; 2749 ptmp->next = NULL; 2750 2751 if (rtnlist == NULL) { 2752 rtnlist = pcur = ptmp; 2753 } else { 2754 pcur->next = ptmp; 2755 pcur = ptmp; 2756 } 2757 } 2758 2759 end: 2760 (void) fclose(pfile); 2761 2762 if (rv == KMF_OK) { 2763 *entlist = rtnlist; 2764 } else if (rtnlist != NULL) { 2765 free_entrylist(rtnlist); 2766 *entlist = NULL; 2767 kstore_num = DEFAULT_KEYSTORE_NUM; 2768 } 2769 2770 return (rv); 2771 } 2772 2773 2774 boolean_t 2775 is_valid_keystore_type(KMF_KEYSTORE_TYPE kstype) 2776 { 2777 2778 if (kstype > 0 && kstype <= kstore_num) 2779 return (B_TRUE); 2780 else 2781 return (B_FALSE); 2782 } 2783