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