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 BerElement *asn1 = NULL; 1703 BerValue *extdata = NULL; 1704 1705 at = strchr(name, '@'); 1706 if (at == NULL) 1707 return (KMF_ERR_ENCODING); 1708 1709 realm = at+1; 1710 *at = 0; 1711 1712 if ((asn1 = kmfder_alloc()) == NULL) 1713 return (KMF_ERR_MEMORY); 1714 1715 if (kmfber_printf(asn1, "{D{", &KMFOID_PKINIT_san) == -1) 1716 goto cleanup; 1717 1718 if (kmfber_printf(asn1, "l", strlen(realm)) == -1) 1719 goto cleanup; 1720 if (kmfber_write(asn1, realm, strlen(realm), 0) != strlen(realm)) 1721 goto cleanup; 1722 if (kmfber_printf(asn1, "l", strlen(name)) == -1) 1723 goto cleanup; 1724 if (kmfber_write(asn1, name, strlen(name), 0) != strlen(name)) 1725 goto cleanup; 1726 if (kmfber_printf(asn1, "}}") == -1) 1727 goto cleanup; 1728 1729 if (kmfber_flatten(asn1, &extdata) == -1) { 1730 rv = KMF_ERR_ENCODING; 1731 goto cleanup; 1732 } 1733 1734 derdata->Data = (uchar_t *)extdata->bv_val; 1735 derdata->Length = extdata->bv_len; 1736 1737 free(extdata); 1738 cleanup: 1739 if (asn1 != NULL) 1740 kmfber_free(asn1, 1); 1741 1742 if (*at == 0) 1743 *at = '@'; 1744 1745 return (rv); 1746 } 1747 1748 static KMF_RETURN 1749 encode_sclogon(char *name, KMF_DATA *derdata) 1750 { 1751 KMF_RETURN rv = KMF_OK; 1752 BerElement *asn1 = NULL; 1753 BerValue *extdata = NULL; 1754 1755 if ((asn1 = kmfder_alloc()) == NULL) 1756 return (KMF_ERR_MEMORY); 1757 1758 /* The name is encoded as a KerberosString (IA5STRING) */ 1759 if (kmfber_printf(asn1, "{Ds}", 1760 &KMFOID_MS_KP_SCLogon, name) == -1) 1761 goto cleanup; 1762 1763 if (kmfber_flatten(asn1, &extdata) == -1) { 1764 rv = KMF_ERR_ENCODING; 1765 goto cleanup; 1766 } 1767 1768 derdata->Data = (uchar_t *)extdata->bv_val; 1769 derdata->Length = extdata->bv_len; 1770 1771 free(extdata); 1772 cleanup: 1773 if (asn1 != NULL) 1774 kmfber_free(asn1, 1); 1775 1776 return (rv); 1777 } 1778 1779 static KMF_RETURN 1780 verify_uri_format(char *uristring) 1781 { 1782 KMF_RETURN ret = KMF_OK; 1783 xmlURIPtr uriptr = NULL; 1784 1785 /* Parse the URI string; get the hostname and port */ 1786 uriptr = xmlParseURI(uristring); 1787 if (uriptr == NULL) { 1788 ret = KMF_ERR_BAD_URI; 1789 goto out; 1790 } 1791 1792 if (uriptr->scheme == NULL || !strlen(uriptr->scheme)) { 1793 ret = KMF_ERR_BAD_URI; 1794 goto out; 1795 } 1796 1797 if (uriptr->server == NULL || !strlen(uriptr->server)) { 1798 ret = KMF_ERR_BAD_URI; 1799 goto out; 1800 } 1801 out: 1802 if (uriptr != NULL) 1803 xmlFreeURI(uriptr); 1804 return (ret); 1805 } 1806 1807 static KMF_RETURN 1808 encode_altname(char *namedata, 1809 KMF_GENERALNAMECHOICES nametype, KMF_DATA *encodedname) 1810 { 1811 KMF_RETURN ret = KMF_OK; 1812 KMF_X509_NAME dnname; 1813 uchar_t tagval; 1814 BerElement *asn1 = NULL; 1815 BerValue *extdata; 1816 1817 if (namedata == NULL || encodedname == NULL) 1818 return (KMF_ERR_BAD_PARAMETER); 1819 1820 /* 1821 * Encode the namedata according to rules in RFC 3280 for GeneralName. 1822 * The input "namedata" is assumed to be an ASCII string representation 1823 * of the AltName, we need to convert it to correct ASN.1 here before 1824 * adding it to the cert. 1825 */ 1826 switch (nametype) { 1827 case GENNAME_RFC822NAME: /* rfc 822 */ 1828 /* IA5String, no encoding needed */ 1829 encodedname->Data = (uchar_t *)strdup(namedata); 1830 if (encodedname->Data == NULL) 1831 return (KMF_ERR_MEMORY); 1832 encodedname->Length = strlen(namedata); 1833 tagval = (0x80 | nametype); 1834 break; 1835 case GENNAME_DNSNAME: /* rfc 1034 */ 1836 encodedname->Data = (uchar_t *)strdup(namedata); 1837 if (encodedname->Data == NULL) 1838 return (KMF_ERR_MEMORY); 1839 encodedname->Length = strlen(namedata); 1840 tagval = (0x80 | nametype); 1841 break; 1842 case GENNAME_URI: /* rfc 1738 */ 1843 ret = verify_uri_format(namedata); 1844 if (ret != KMF_OK) 1845 return (ret); 1846 /* IA5String, no encoding needed */ 1847 encodedname->Data = (uchar_t *)strdup(namedata); 1848 if (encodedname->Data == NULL) 1849 return (KMF_ERR_MEMORY); 1850 encodedname->Length = strlen(namedata); 1851 tagval = (0x80 | nametype); 1852 break; 1853 case GENNAME_IPADDRESS: 1854 ret = encode_ipaddr(namedata, encodedname); 1855 tagval = (0x80 | nametype); 1856 break; 1857 case GENNAME_REGISTEREDID: 1858 ret = encode_rid(namedata, encodedname); 1859 tagval = (0x80 | nametype); 1860 break; 1861 case GENNAME_DIRECTORYNAME: 1862 ret = kmf_dn_parser(namedata, &dnname); 1863 if (ret == KMF_OK) { 1864 ret = DerEncodeName(&dnname, encodedname); 1865 } 1866 (void) kmf_free_dn(&dnname); 1867 tagval = (0xA0 | nametype); 1868 break; 1869 case GENNAME_KRB5PRINC: 1870 tagval = (0x80 | GENNAME_OTHERNAME); 1871 ret = encode_krb5(namedata, encodedname); 1872 break; 1873 case GENNAME_SCLOGON_UPN: 1874 tagval = (0x80 | GENNAME_OTHERNAME); 1875 ret = encode_sclogon(namedata, encodedname); 1876 break; 1877 default: 1878 /* unsupported */ 1879 return (KMF_ERR_BAD_PARAMETER); 1880 1881 } 1882 if (ret != KMF_OK) { 1883 kmf_free_data(encodedname); 1884 return (ret); 1885 } 1886 1887 if ((asn1 = kmfder_alloc()) == NULL) 1888 return (KMF_ERR_MEMORY); 1889 1890 if (kmfber_printf(asn1, "Tl", tagval, encodedname->Length) == -1) 1891 goto cleanup; 1892 1893 if (kmfber_write(asn1, (char *)encodedname->Data, 1894 encodedname->Length, 0) == -1) { 1895 ret = KMF_ERR_ENCODING; 1896 goto cleanup; 1897 } 1898 if (kmfber_flatten(asn1, &extdata) == -1) { 1899 ret = KMF_ERR_ENCODING; 1900 goto cleanup; 1901 } 1902 1903 kmf_free_data(encodedname); 1904 encodedname->Data = (uchar_t *)extdata->bv_val; 1905 encodedname->Length = extdata->bv_len; 1906 1907 free(extdata); 1908 1909 cleanup: 1910 if (asn1) 1911 kmfber_free(asn1, 1); 1912 1913 if (ret != KMF_OK) 1914 kmf_free_data(encodedname); 1915 1916 return (ret); 1917 } 1918 1919 KMF_X509_EXTENSION * 1920 FindExtn(KMF_X509_EXTENSIONS *exts, KMF_OID *oid) 1921 { 1922 KMF_X509_EXTENSION *foundextn = NULL; 1923 int i; 1924 1925 if (exts == NULL || oid == NULL) 1926 return (NULL); 1927 1928 for (i = 0; i < exts->numberOfExtensions; i++) { 1929 if (IsEqualOid(oid, &exts->extensions[i].extnId)) { 1930 foundextn = &exts->extensions[i]; 1931 break; 1932 } 1933 } 1934 return (foundextn); 1935 } 1936 1937 KMF_RETURN 1938 GetSequenceContents(char *data, size_t len, 1939 char **contents, size_t *outlen) 1940 { 1941 KMF_RETURN ret = KMF_OK; 1942 BerElement *exasn1 = NULL; 1943 BerValue oldextn; 1944 int tag; 1945 size_t oldsize; 1946 char *olddata = NULL; 1947 1948 if (data == NULL || contents == NULL || outlen == NULL) 1949 return (KMF_ERR_BAD_PARAMETER); 1950 1951 /* 1952 * Decode the sequence of general names 1953 */ 1954 oldextn.bv_val = data; 1955 oldextn.bv_len = len; 1956 1957 if ((exasn1 = kmfder_init(&oldextn)) == NULL) { 1958 ret = KMF_ERR_MEMORY; 1959 goto out; 1960 } 1961 1962 /* 1963 * Unwrap the sequence to find the size of the block 1964 * of GeneralName items in the set. 1965 * 1966 * Peek at the tag and length ("tl"), 1967 * then consume them ("{"). 1968 */ 1969 if (kmfber_scanf(exasn1, "tl{", &tag, &oldsize) == KMFBER_DEFAULT || 1970 oldsize == 0) { 1971 ret = KMF_ERR_ENCODING; 1972 goto out; 1973 } 1974 1975 olddata = malloc(oldsize); 1976 if (olddata == NULL) { 1977 ret = KMF_ERR_MEMORY; 1978 goto out; 1979 } 1980 (void) memset(olddata, 0, oldsize); 1981 /* 1982 * Read the entire blob of GeneralNames, we don't 1983 * need to interpret them now. 1984 */ 1985 if (kmfber_read(exasn1, olddata, oldsize) != oldsize) { 1986 ret = KMF_ERR_ENCODING; 1987 goto out; 1988 } 1989 out: 1990 if (exasn1 != NULL) 1991 kmfber_free(exasn1, 1); 1992 1993 if (ret != KMF_OK) { 1994 *contents = NULL; 1995 *outlen = 0; 1996 if (olddata != NULL) 1997 free(olddata); 1998 } else { 1999 *contents = olddata; 2000 *outlen = oldsize; 2001 } 2002 return (ret); 2003 } 2004 2005 KMF_RETURN 2006 add_an_extension(KMF_X509_EXTENSIONS *exts, KMF_X509_EXTENSION *newextn) 2007 { 2008 KMF_RETURN ret = KMF_OK; 2009 KMF_X509_EXTENSION *extlist; 2010 2011 if (exts == NULL || newextn == NULL) 2012 return (KMF_ERR_BAD_PARAMETER); 2013 2014 extlist = malloc(sizeof (KMF_X509_EXTENSION) * 2015 (exts->numberOfExtensions + 1)); 2016 if (extlist == NULL) 2017 return (KMF_ERR_MEMORY); 2018 2019 (void) memcpy(extlist, exts->extensions, 2020 exts->numberOfExtensions * sizeof (KMF_X509_EXTENSION)); 2021 2022 (void) memcpy(&extlist[exts->numberOfExtensions], newextn, 2023 sizeof (KMF_X509_EXTENSION)); 2024 2025 free(exts->extensions); 2026 exts->numberOfExtensions++; 2027 exts->extensions = extlist; 2028 2029 return (ret); 2030 } 2031 2032 KMF_RETURN 2033 kmf_set_altname(KMF_X509_EXTENSIONS *extensions, 2034 KMF_OID *oid, 2035 int critical, 2036 KMF_GENERALNAMECHOICES nametype, 2037 char *namedata) 2038 { 2039 KMF_RETURN ret = KMF_OK; 2040 KMF_X509_EXTENSION subjAltName; 2041 KMF_DATA dername = { NULL, 0 }; 2042 BerElement *asn1 = NULL; 2043 BerValue *extdata; 2044 char *olddata = NULL; 2045 KMF_X509_EXTENSION *foundextn = NULL; 2046 size_t oldsize = 0; 2047 2048 if (extensions == NULL || oid == NULL || namedata == NULL) 2049 return (KMF_ERR_BAD_PARAMETER); 2050 2051 ret = encode_altname(namedata, nametype, &dername); 2052 2053 if (ret != KMF_OK) 2054 return (ret); 2055 2056 (void) memset(&subjAltName, 0, sizeof (subjAltName)); 2057 2058 ret = copy_data(&subjAltName.extnId, oid); 2059 if (ret != KMF_OK) 2060 goto out; 2061 /* 2062 * Check to see if this cert already has a subjectAltName. 2063 */ 2064 foundextn = FindExtn(extensions, oid); 2065 2066 if (foundextn != NULL) { 2067 ret = GetSequenceContents( 2068 (char *)foundextn->BERvalue.Data, 2069 foundextn->BERvalue.Length, 2070 &olddata, &oldsize); 2071 if (ret != KMF_OK) 2072 goto out; 2073 } 2074 2075 /* 2076 * Assume (!!) that the namedata given is already properly encoded. 2077 */ 2078 if ((asn1 = kmfder_alloc()) == NULL) 2079 return (KMF_ERR_MEMORY); 2080 2081 if (kmfber_printf(asn1, "{") == -1) { 2082 ret = KMF_ERR_ENCODING; 2083 goto out; 2084 } 2085 2086 /* Write the old extension data first */ 2087 if (olddata != NULL && oldsize > 0) { 2088 if (kmfber_write(asn1, olddata, oldsize, 0) == -1) { 2089 ret = KMF_ERR_ENCODING; 2090 goto out; 2091 } 2092 } 2093 2094 /* Now add the new name to the list */ 2095 if (kmfber_write(asn1, (char *)dername.Data, dername.Length, 0) == -1) { 2096 ret = KMF_ERR_ENCODING; 2097 goto out; 2098 } 2099 2100 /* Now close the sequence */ 2101 if (kmfber_printf(asn1, "}") == -1) { 2102 ret = KMF_ERR_ENCODING; 2103 goto out; 2104 } 2105 if (kmfber_flatten(asn1, &extdata) == -1) { 2106 ret = KMF_ERR_ENCODING; 2107 goto out; 2108 } 2109 2110 /* 2111 * If we are just adding to an existing list of altNames, 2112 * just replace the BER data associated with the found extension. 2113 */ 2114 if (foundextn != NULL) { 2115 free(foundextn->BERvalue.Data); 2116 foundextn->critical = critical; 2117 foundextn->BERvalue.Data = (uchar_t *)extdata->bv_val; 2118 foundextn->BERvalue.Length = extdata->bv_len; 2119 } else { 2120 subjAltName.critical = critical; 2121 subjAltName.format = KMF_X509_DATAFORMAT_ENCODED; 2122 subjAltName.BERvalue.Data = (uchar_t *)extdata->bv_val; 2123 subjAltName.BERvalue.Length = extdata->bv_len; 2124 ret = add_an_extension(extensions, &subjAltName); 2125 if (ret != KMF_OK) 2126 free(subjAltName.BERvalue.Data); 2127 } 2128 2129 free(extdata); 2130 out: 2131 if (olddata != NULL) 2132 free(olddata); 2133 2134 kmf_free_data(&dername); 2135 if (ret != KMF_OK) 2136 kmf_free_data(&subjAltName.extnId); 2137 if (asn1 != NULL) 2138 kmfber_free(asn1, 1); 2139 return (ret); 2140 } 2141 2142 /* 2143 * Search a list of attributes for one that matches the given type. 2144 * Return a pointer into the attribute list. This does not 2145 * return a copy of the value, it returns a reference into the 2146 * given list. 2147 */ 2148 int 2149 kmf_find_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, int numattrs) 2150 { 2151 int i; 2152 for (i = 0; i < numattrs; i++) { 2153 if (attlist[i].type == type) 2154 return (i); 2155 } 2156 return (-1); 2157 } 2158 2159 /* 2160 * Verify that a given attribute is consistent with the 2161 * "test" attribute. 2162 */ 2163 static KMF_RETURN 2164 verify_attribute(KMF_ATTRIBUTE *givenattr, 2165 KMF_ATTRIBUTE_TESTER *testattr) 2166 { 2167 /* A NULL pValue was found where one is required */ 2168 if (testattr->null_value_ok == FALSE && 2169 givenattr->pValue == NULL) 2170 return (KMF_ERR_BAD_PARAMETER); 2171 2172 /* If the given valueLen is too small, return error */ 2173 if (givenattr->pValue != NULL && 2174 testattr->minlen > 0 && 2175 (givenattr->valueLen < testattr->minlen)) 2176 return (KMF_ERR_BAD_PARAMETER); 2177 2178 /* If the given valueLen is too big, return error */ 2179 if (givenattr->pValue != NULL && 2180 testattr->maxlen > 0 && 2181 (givenattr->valueLen > testattr->maxlen)) 2182 return (KMF_ERR_BAD_PARAMETER); 2183 2184 return (KMF_OK); 2185 } 2186 2187 /* 2188 * Given a set of required attribute tests and optional 2189 * attributes, make sure that the actual attributes 2190 * being tested (attrlist below) are allowed and are 2191 * properly specified. 2192 */ 2193 KMF_RETURN 2194 test_attributes(int reqnum, KMF_ATTRIBUTE_TESTER *reqattrs, 2195 int optnum, KMF_ATTRIBUTE_TESTER *optattrs, 2196 int numattrs, KMF_ATTRIBUTE *attrlist) 2197 { 2198 KMF_RETURN ret = KMF_OK; 2199 int i, idx; 2200 2201 /* 2202 * If the caller didn't supply enough attributes, 2203 * return an error. 2204 */ 2205 if (numattrs < reqnum || attrlist == NULL) 2206 return (KMF_ERR_BAD_PARAMETER); 2207 2208 /* 2209 * Make sure all required attrs are present and 2210 * correct. 2211 */ 2212 for (i = 0; i < reqnum && ret == KMF_OK; i++) { 2213 idx = kmf_find_attr(reqattrs[i].type, attrlist, numattrs); 2214 /* If a required attr is not found, return error */ 2215 if (idx == -1) { 2216 return (KMF_ERR_BAD_PARAMETER); 2217 } 2218 2219 ret = verify_attribute(&attrlist[idx], &reqattrs[i]); 2220 } 2221 /* 2222 * Now test the optional parameters. 2223 */ 2224 for (i = 0; i < optnum && ret == KMF_OK; i++) { 2225 idx = kmf_find_attr(optattrs[i].type, attrlist, numattrs); 2226 /* If a optional attr is not found, continue. */ 2227 if (idx == -1) { 2228 continue; 2229 } 2230 2231 ret = verify_attribute(&attrlist[idx], &optattrs[i]); 2232 } 2233 2234 return (ret); 2235 } 2236 2237 /* 2238 * Given an already allocated attribute list, insert 2239 * the given attribute information at a specific index 2240 * in the list. 2241 */ 2242 void 2243 kmf_set_attr_at_index(KMF_ATTRIBUTE *attlist, int index, 2244 KMF_ATTR_TYPE type, void *pValue, uint32_t len) 2245 { 2246 if (attlist == NULL) 2247 return; 2248 2249 attlist[index].type = type; 2250 attlist[index].pValue = pValue; 2251 attlist[index].valueLen = len; 2252 } 2253 2254 /* 2255 * Find an attribute matching a particular type and set 2256 * the pValue and length fields to the given values. 2257 */ 2258 KMF_RETURN 2259 kmf_set_attr(KMF_ATTRIBUTE *attlist, int numattr, 2260 KMF_ATTR_TYPE type, void *pValue, uint32_t len) 2261 { 2262 int idx; 2263 if (attlist == NULL) 2264 return (KMF_ERR_BAD_PARAMETER); 2265 2266 idx = kmf_find_attr(type, attlist, numattr); 2267 if (idx == -1) 2268 return (KMF_ERR_ATTR_NOT_FOUND); 2269 2270 attlist[idx].type = type; 2271 /* Assumes the attribute pValue can hold the result */ 2272 if (attlist[idx].pValue != NULL) { 2273 if (attlist[idx].valueLen >= len) 2274 (void) memcpy(attlist[idx].pValue, pValue, len); 2275 else 2276 return (KMF_ERR_BUFFER_SIZE); 2277 } 2278 attlist[idx].valueLen = len; 2279 return (KMF_OK); 2280 } 2281 2282 /* 2283 * Find a particular attribute in a list and return 2284 * a pointer to its value. 2285 */ 2286 void * 2287 kmf_get_attr_ptr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, 2288 int numattrs) 2289 { 2290 int i; 2291 2292 i = kmf_find_attr(type, attlist, numattrs); 2293 if (i == -1) 2294 return (NULL); 2295 2296 return (attlist[i].pValue); 2297 } 2298 2299 /* 2300 * Find a particular attribute in a list and return 2301 * the value and length values. Value and length 2302 * may be NULL if the caller doesn't want their values 2303 * to be filled in. 2304 */ 2305 KMF_RETURN 2306 kmf_get_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, 2307 int numattrs, void *outValue, uint32_t *outlen) 2308 { 2309 int i; 2310 uint32_t len = 0; 2311 uint32_t *lenptr = outlen; 2312 2313 if (lenptr == NULL) 2314 lenptr = &len; 2315 2316 i = kmf_find_attr(type, attlist, numattrs); 2317 if (i == -1) 2318 return (KMF_ERR_ATTR_NOT_FOUND); 2319 2320 /* This assumes that the ptr passed in is pre-allocated space */ 2321 if (attlist[i].pValue != NULL && outValue != NULL) { 2322 /* 2323 * If the caller did not specify a length, 2324 * assume "outValue" is big enough. 2325 */ 2326 if (outlen != NULL) { 2327 if (*outlen >= attlist[i].valueLen) 2328 (void) memcpy(outValue, attlist[i].pValue, 2329 attlist[i].valueLen); 2330 else 2331 return (KMF_ERR_BUFFER_SIZE); 2332 } else { 2333 (void) memcpy(outValue, attlist[i].pValue, 2334 attlist[i].valueLen); 2335 } 2336 } 2337 2338 if (outlen != NULL) 2339 *outlen = attlist[i].valueLen; 2340 return (KMF_OK); 2341 } 2342 2343 /* 2344 * Utility routine to find a string type attribute, allocate it 2345 * and return the value to the caller. This simplifies the 2346 * operation by doing both "kmf_get_attr" calls and avoids 2347 * duplicating this block of code in lots of places. 2348 */ 2349 KMF_RETURN 2350 kmf_get_string_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attrlist, 2351 int numattrs, char **outstr) 2352 { 2353 KMF_RETURN rv; 2354 uint32_t len; 2355 2356 if (outstr == NULL) 2357 return (KMF_ERR_BAD_PARAMETER); 2358 2359 if ((rv = kmf_get_attr(type, attrlist, numattrs, NULL, &len)) == 2360 KMF_OK) { 2361 *outstr = malloc(len + 1); 2362 if ((*outstr) == NULL) 2363 return (KMF_ERR_MEMORY); 2364 (void) memset((*outstr), 0, len + 1); 2365 rv = kmf_get_attr(type, attrlist, numattrs, (*outstr), &len); 2366 if (rv != KMF_OK) { 2367 free(*outstr); 2368 *outstr = NULL; 2369 } 2370 } 2371 2372 return (rv); 2373 } 2374 2375 2376 void 2377 free_entry(conf_entry_t *entry) 2378 { 2379 if (entry == NULL) 2380 return; 2381 free(entry->keystore); 2382 free(entry->modulepath); 2383 free(entry->option); 2384 } 2385 2386 void 2387 free_entrylist(conf_entrylist_t *list) 2388 { 2389 conf_entrylist_t *next; 2390 2391 while (list != NULL) { 2392 next = list->next; 2393 free_entry(list->entry); 2394 free(list); 2395 list = next; 2396 } 2397 } 2398 2399 static KMF_RETURN 2400 parse_entry(char *buf, conf_entry_t **entry) 2401 { 2402 KMF_RETURN ret = KMF_OK; 2403 conf_entry_t *tmp = NULL; 2404 char *token1; 2405 char *token2; 2406 char *token3; 2407 char *lasts; 2408 char *value; 2409 2410 if ((token1 = strtok_r(buf, SEP_COLON, &lasts)) == NULL) 2411 return (KMF_ERR_KMF_CONF); 2412 2413 if ((tmp = calloc(sizeof (conf_entry_t), 1)) == NULL) 2414 return (KMF_ERR_MEMORY); 2415 2416 if ((tmp->keystore = strdup(token1)) == NULL) { 2417 ret = KMF_ERR_MEMORY; 2418 goto end; 2419 } 2420 2421 if ((token2 = strtok_r(NULL, SEP_SEMICOLON, &lasts)) == NULL) { 2422 ret = KMF_ERR_KMF_CONF; 2423 goto end; 2424 } 2425 2426 /* need to get token3 first to satisfy nested strtok invocations */ 2427 token3 = strtok_r(NULL, SEP_SEMICOLON, &lasts); 2428 2429 /* parse token2 */ 2430 if (strncmp(token2, CONF_MODULEPATH, strlen(CONF_MODULEPATH)) != 0) { 2431 ret = KMF_ERR_KMF_CONF; 2432 goto end; 2433 } 2434 2435 if (value = strpbrk(token2, SEP_EQUAL)) { 2436 value++; /* get rid of = */ 2437 } else { 2438 ret = KMF_ERR_KMF_CONF; 2439 goto end; 2440 } 2441 2442 if ((tmp->modulepath = strdup(value)) == NULL) { 2443 ret = KMF_ERR_MEMORY; 2444 goto end; 2445 } 2446 2447 /* parse token3, if it exists */ 2448 if (token3 != NULL) { 2449 if (strncmp(token3, CONF_OPTION, strlen(CONF_OPTION)) 2450 != 0) { 2451 ret = KMF_ERR_KMF_CONF; 2452 goto end; 2453 } 2454 2455 if (value = strpbrk(token3, SEP_EQUAL)) { 2456 value++; /* get rid of = */ 2457 } else { 2458 ret = KMF_ERR_KMF_CONF; 2459 goto end; 2460 } 2461 2462 if ((tmp->option = strdup(value)) == NULL) { 2463 ret = KMF_ERR_MEMORY; 2464 goto end; 2465 } 2466 } 2467 2468 *entry = tmp; 2469 2470 end: 2471 if (ret != KMF_OK) { 2472 free_entry(tmp); 2473 free(tmp); 2474 } 2475 return (ret); 2476 } 2477 2478 2479 conf_entry_t * 2480 dup_entry(conf_entry_t *entry) 2481 { 2482 conf_entry_t *rtn_entry; 2483 2484 if (entry == NULL) 2485 return (NULL); 2486 2487 rtn_entry = malloc(sizeof (conf_entry_t)); 2488 if (rtn_entry == NULL) 2489 return (NULL); 2490 2491 if ((rtn_entry->keystore = strdup(entry->keystore)) == NULL) 2492 goto out; 2493 2494 if ((rtn_entry->modulepath = strdup(entry->modulepath)) == NULL) 2495 goto out; 2496 2497 if (entry->option != NULL && 2498 (rtn_entry->option = strdup(entry->modulepath)) == NULL) 2499 goto out; 2500 2501 return (rtn_entry); 2502 2503 out: 2504 free_entry(rtn_entry); 2505 return (NULL); 2506 } 2507 2508 2509 /* 2510 * This function takes a keystore_name as input and returns 2511 * the KMF_KEYSTORE_TYPE value assigned to it. If the "option" 2512 * argument is not NULL, this function also returns the option string 2513 * if there is an option string for the plugin module. 2514 */ 2515 KMF_RETURN 2516 kmf_get_plugin_info(KMF_HANDLE_T handle, char *keystore_name, 2517 KMF_KEYSTORE_TYPE *kstype, char **option) 2518 { 2519 KMF_RETURN ret = KMF_OK; 2520 conf_entrylist_t *phead = extra_plugin_list; 2521 boolean_t is_default = B_TRUE; 2522 2523 /* 2524 * Although handle is not really used in the function, we will 2525 * check the handle to make sure that kmf_intialize() is called 2526 * before this function. 2527 */ 2528 if (handle == NULL || keystore_name == NULL || kstype == NULL) 2529 return (KMF_ERR_BAD_PARAMETER); 2530 2531 if (strcmp(keystore_name, "pkcs11") == 0) { 2532 *kstype = KMF_KEYSTORE_PK11TOKEN; 2533 } else if (strcmp(keystore_name, "file") == 0) { 2534 *kstype = KMF_KEYSTORE_OPENSSL; 2535 } else if (strcmp(keystore_name, "nss") == 0) { 2536 *kstype = KMF_KEYSTORE_NSS; 2537 } else { 2538 is_default = B_FALSE; 2539 } 2540 2541 if (is_default) { 2542 if (option != NULL) 2543 *option = NULL; 2544 goto out; 2545 } 2546 2547 /* Not a built-in plugin; check if it is in extra_plugin_list. */ 2548 while (phead != NULL) { 2549 if (strcmp(phead->entry->keystore, keystore_name) == 0) 2550 break; 2551 phead = phead->next; 2552 } 2553 2554 if (phead == NULL) { 2555 ret = KMF_ERR_PLUGIN_NOTFOUND; 2556 goto out; 2557 } 2558 2559 /* found it */ 2560 *kstype = phead->entry->kstype; 2561 if (option != NULL) { 2562 if (phead->entry->option == NULL) 2563 *option = NULL; 2564 else { 2565 *option = strdup(phead->entry->option); 2566 if (*option == NULL) { 2567 ret = KMF_ERR_MEMORY; 2568 goto out; 2569 } 2570 } 2571 } 2572 2573 out: 2574 return (ret); 2575 } 2576 2577 /* 2578 * Retrieve the non-default plugin list from the kmf.conf file. 2579 */ 2580 KMF_RETURN 2581 get_entrylist(conf_entrylist_t **entlist) 2582 { 2583 KMF_RETURN rv = KMF_OK; 2584 FILE *pfile; 2585 conf_entry_t *entry; 2586 conf_entrylist_t *rtnlist = NULL; 2587 conf_entrylist_t *ptmp; 2588 conf_entrylist_t *pcur; 2589 char buffer[MAXPATHLEN]; 2590 size_t len; 2591 2592 if ((pfile = fopen(_PATH_KMF_CONF, "rF")) == NULL) { 2593 cryptoerror(LOG_ERR, "failed to open %s.\n", _PATH_KMF_CONF); 2594 return (KMF_ERR_KMF_CONF); 2595 } 2596 2597 while (fgets(buffer, MAXPATHLEN, pfile) != NULL) { 2598 if (buffer[0] == '#' || buffer[0] == ' ' || 2599 buffer[0] == '\n'|| buffer[0] == '\t') { 2600 continue; /* ignore comment lines */ 2601 } 2602 2603 len = strlen(buffer); 2604 if (buffer[len-1] == '\n') { /* get rid of trailing '\n' */ 2605 len--; 2606 } 2607 buffer[len] = '\0'; 2608 2609 rv = parse_entry(buffer, &entry); 2610 if (rv != KMF_OK) { 2611 goto end; 2612 } 2613 2614 if ((ptmp = malloc(sizeof (conf_entrylist_t))) == NULL) { 2615 rv = KMF_ERR_MEMORY; 2616 goto end; 2617 } 2618 ptmp->entry = entry; 2619 ptmp->next = NULL; 2620 2621 if (rtnlist == NULL) { 2622 rtnlist = pcur = ptmp; 2623 } else { 2624 pcur->next = ptmp; 2625 pcur = ptmp; 2626 } 2627 } 2628 2629 end: 2630 (void) fclose(pfile); 2631 2632 if (rv == KMF_OK) { 2633 *entlist = rtnlist; 2634 } else if (rtnlist != NULL) { 2635 free_entrylist(rtnlist); 2636 *entlist = NULL; 2637 kstore_num = DEFAULT_KEYSTORE_NUM; 2638 } 2639 2640 return (rv); 2641 } 2642 2643 2644 boolean_t 2645 is_valid_keystore_type(KMF_KEYSTORE_TYPE kstype) 2646 { 2647 2648 if (kstype > 0 && kstype <= kstore_num) 2649 return (B_TRUE); 2650 else 2651 return (B_FALSE); 2652 } 2653 2654 2655 /* 2656 * This API is used by elfsign. We must keep it in old API form. 2657 */ 2658 KMF_RETURN 2659 KMF_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) 2660 { 2661 2662 KMF_ATTRIBUTE attlist[32]; 2663 int i = 0; 2664 2665 if (params == NULL) 2666 return (KMF_ERR_BAD_PARAMETER); 2667 2668 kmf_set_attr_at_index(attlist, i, 2669 KMF_KEYSTORE_TYPE_ATTR, ¶ms->kstype, sizeof (params->kstype)); 2670 i++; 2671 2672 if (params->kstype == KMF_KEYSTORE_NSS) { 2673 if (params->nssconfig.configdir != NULL) { 2674 kmf_set_attr_at_index(attlist, i, 2675 KMF_DIRPATH_ATTR, 2676 params->nssconfig.configdir, 2677 strlen(params->nssconfig.configdir)); 2678 i++; 2679 } 2680 if (params->nssconfig.certPrefix != NULL) { 2681 kmf_set_attr_at_index(attlist, i, 2682 KMF_CERTPREFIX_ATTR, 2683 params->nssconfig.certPrefix, 2684 strlen(params->nssconfig.certPrefix)); 2685 i++; 2686 } 2687 if (params->nssconfig.keyPrefix != NULL) { 2688 kmf_set_attr_at_index(attlist, i, 2689 KMF_KEYPREFIX_ATTR, 2690 params->nssconfig.keyPrefix, 2691 strlen(params->nssconfig.keyPrefix)); 2692 i++; 2693 } 2694 if (params->nssconfig.secModName != NULL) { 2695 kmf_set_attr_at_index(attlist, i, 2696 KMF_SECMODNAME_ATTR, 2697 params->nssconfig.secModName, 2698 strlen(params->nssconfig.secModName)); 2699 i++; 2700 } 2701 } else if (params->kstype == KMF_KEYSTORE_PK11TOKEN) { 2702 if (params->pkcs11config.label != NULL) { 2703 kmf_set_attr_at_index(attlist, i, 2704 KMF_TOKEN_LABEL_ATTR, 2705 params->pkcs11config.label, 2706 strlen(params->pkcs11config.label)); 2707 i++; 2708 } 2709 kmf_set_attr_at_index(attlist, i, 2710 KMF_READONLY_ATTR, 2711 ¶ms->pkcs11config.readonly, 2712 sizeof (params->pkcs11config.readonly)); 2713 i++; 2714 } 2715 2716 return (kmf_configure_keystore(handle, i, attlist)); 2717 } 2718 2719 /* 2720 * This API is used by elfsign. We must keep it in old API form. 2721 */ 2722 KMF_RETURN 2723 KMF_Initialize(KMF_HANDLE_T *outhandle, char *policyfile, char *policyname) 2724 { 2725 return (kmf_initialize(outhandle, policyfile, policyname)); 2726 } 2727 2728 /* 2729 * This API is used by elfsign. We must keep it in old API form. 2730 */ 2731 KMF_RETURN 2732 KMF_Finalize(KMF_HANDLE_T handle) 2733 { 2734 return (kmf_finalize(handle)); 2735 } 2736 2737 /* 2738 * This API is used by elfsign. We must keep it in old API form. 2739 */ 2740 KMF_RETURN 2741 KMF_GetKMFErrorString(KMF_RETURN errcode, char **errmsg) 2742 { 2743 return (kmf_get_kmf_error_str(errcode, errmsg)); 2744 } 2745 2746 /* 2747 * This API is used by elfsign. We must keep it in old API form. 2748 */ 2749 KMF_RETURN 2750 KMF_ReadInputFile(KMF_HANDLE_T handle, char *filename, KMF_DATA *pdata) 2751 { 2752 return (kmf_read_input_file(handle, filename, pdata)); 2753 } 2754 2755 2756 /* 2757 * This API is used by elfsign. We must keep it in old API form. 2758 */ 2759 void 2760 KMF_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert) 2761 { 2762 kmf_free_kmf_cert(handle, kmf_cert); 2763 } 2764 2765 /* 2766 * This API is used by elfsign. We must keep it in old API form. 2767 */ 2768 void 2769 KMF_FreeData(KMF_DATA *datablock) 2770 { 2771 kmf_free_data(datablock); 2772 } 2773 2774 /* 2775 * This API is used by elfsign. We must keep it in old API form. 2776 */ 2777 void 2778 KMF_FreeKMFKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key) 2779 { 2780 kmf_free_kmf_key(handle, key); 2781 } 2782 2783 /* 2784 * This API is used by elfsign. We must keep it in old API form. 2785 */ 2786 void 2787 KMF_FreeSignedCSR(KMF_CSR_DATA *csr) 2788 { 2789 kmf_free_signed_csr(csr); 2790 } 2791