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