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