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