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