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 } 1229 1230 void 1231 kmf_free_raw_sym_key(KMF_RAW_SYM_KEY *key) 1232 { 1233 if (key == NULL) 1234 return; 1235 kmf_free_bigint(&key->keydata); 1236 free(key); 1237 } 1238 1239 /* 1240 * This function frees the space allocated for the name portion of a 1241 * KMF_CRL_DIST_POINT. 1242 */ 1243 void 1244 free_dp_name(KMF_CRL_DIST_POINT *dp) 1245 { 1246 KMF_GENERALNAMES *fullname; 1247 KMF_DATA *urldata; 1248 int i; 1249 1250 if (dp == NULL) 1251 return; 1252 1253 /* For phase 1, we only need to free the fullname space. */ 1254 fullname = &(dp->name.full_name); 1255 if (fullname->number == 0) 1256 return; 1257 1258 for (i = 0; i < fullname->number; i++) { 1259 urldata = &(fullname->namelist[fullname->number - 1].name); 1260 kmf_free_data(urldata); 1261 } 1262 1263 free(fullname->namelist); 1264 } 1265 1266 /* 1267 * This function frees the space allocated for a KMF_CRL_DIST_POINT. 1268 */ 1269 void 1270 free_dp(KMF_CRL_DIST_POINT *dp) 1271 { 1272 if (dp == NULL) 1273 return; 1274 1275 free_dp_name(dp); 1276 kmf_free_data(&(dp->reasons)); 1277 /* Need not to free crl_issuer space at phase 1 */ 1278 } 1279 1280 /* 1281 * This function frees space for a KMF_X509EXT_CRLDISTPOINTS internally. 1282 */ 1283 void 1284 kmf_free_crl_dist_pts(KMF_X509EXT_CRLDISTPOINTS *crl_dps) 1285 { 1286 int i; 1287 1288 if (crl_dps == NULL) 1289 return; 1290 1291 for (i = 0; i < crl_dps->number; i++) 1292 free_dp(&(crl_dps->dplist[i])); 1293 1294 free(crl_dps->dplist); 1295 } 1296 1297 KMF_RETURN 1298 kmf_create_ocsp_request(KMF_HANDLE_T handle, 1299 int num_args, 1300 KMF_ATTRIBUTE *attrlist) 1301 { 1302 KMF_RETURN ret = KMF_OK; 1303 KMF_PLUGIN *plugin; 1304 KMF_RETURN (*createReqFn)(void *, int num_args, 1305 KMF_ATTRIBUTE *attrlist); 1306 1307 KMF_ATTRIBUTE_TESTER required_attrs[] = { 1308 {KMF_OCSP_REQUEST_FILENAME_ATTR, FALSE, 1, 0}, 1309 {KMF_USER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 1310 sizeof (KMF_DATA)}, 1311 {KMF_ISSUER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 1312 sizeof (KMF_DATA)}, 1313 }; 1314 1315 int num_req_attrs = sizeof (required_attrs) / 1316 sizeof (KMF_ATTRIBUTE_TESTER); 1317 1318 if (handle == NULL) 1319 return (KMF_ERR_BAD_PARAMETER); 1320 1321 CLEAR_ERROR(handle, ret); 1322 1323 ret = test_attributes(num_req_attrs, required_attrs, 1324 0, NULL, num_args, attrlist); 1325 1326 if (ret != KMF_OK) 1327 return (ret); 1328 1329 /* 1330 * This framework function is actually implemented in the openssl 1331 * plugin library, so we find the function address and call it. 1332 */ 1333 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 1334 if (plugin == NULL || plugin->dldesc == NULL) { 1335 return (KMF_ERR_PLUGIN_NOTFOUND); 1336 } 1337 1338 createReqFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, 1339 "OpenSSL_CreateOCSPRequest"); 1340 if (createReqFn == NULL) { 1341 return (KMF_ERR_FUNCTION_NOT_FOUND); 1342 } 1343 1344 return (createReqFn(handle, num_args, attrlist)); 1345 1346 } 1347 1348 KMF_RETURN 1349 kmf_get_ocsp_status_for_cert(KMF_HANDLE_T handle, 1350 int num_args, 1351 KMF_ATTRIBUTE *attrlist) 1352 { 1353 KMF_RETURN ret = KMF_OK; 1354 KMF_PLUGIN *plugin; 1355 KMF_RETURN (*getCertStatusFn)(void *, int num_args, 1356 KMF_ATTRIBUTE *attrlist); 1357 1358 KMF_ATTRIBUTE_TESTER required_attrs[] = { 1359 {KMF_USER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 1360 sizeof (KMF_DATA)}, 1361 {KMF_ISSUER_CERT_DATA_ATTR, FALSE, sizeof (KMF_DATA), 1362 sizeof (KMF_DATA)}, 1363 {KMF_OCSP_RESPONSE_DATA_ATTR, FALSE, sizeof (KMF_DATA), 1364 sizeof (KMF_DATA)}, 1365 {KMF_OCSP_RESPONSE_STATUS_ATTR, FALSE, sizeof (int), 1366 sizeof (uint32_t)}, 1367 {KMF_OCSP_RESPONSE_REASON_ATTR, FALSE, sizeof (int), 1368 sizeof (uint32_t)}, 1369 {KMF_OCSP_RESPONSE_CERT_STATUS_ATTR, FALSE, sizeof (int), 1370 sizeof (uint32_t)}, 1371 }; 1372 1373 int num_req_attrs = sizeof (required_attrs) / 1374 sizeof (KMF_ATTRIBUTE_TESTER); 1375 1376 if (handle == NULL) 1377 return (KMF_ERR_BAD_PARAMETER); 1378 1379 CLEAR_ERROR(handle, ret); 1380 1381 ret = test_attributes(num_req_attrs, required_attrs, 1382 0, NULL, num_args, attrlist); 1383 1384 if (ret != KMF_OK) 1385 return (ret); 1386 1387 /* 1388 * This framework function is actually implemented in the openssl 1389 * plugin library, so we find the function address and call it. 1390 */ 1391 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 1392 if (plugin == NULL || plugin->dldesc == NULL) { 1393 return (KMF_ERR_INTERNAL); 1394 } 1395 1396 getCertStatusFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, 1397 "OpenSSL_GetOCSPStatusForCert"); 1398 if (getCertStatusFn == NULL) { 1399 return (KMF_ERR_INTERNAL); 1400 } 1401 1402 return (getCertStatusFn(handle, num_args, attrlist)); 1403 1404 } 1405 1406 KMF_RETURN 1407 kmf_string_to_oid(char *oidstring, KMF_OID *oid) 1408 { 1409 KMF_RETURN rv = KMF_OK; 1410 char *cp, *bp, *startp; 1411 int numbuf; 1412 int onumbuf; 1413 int nbytes, index; 1414 int len; 1415 unsigned char *op; 1416 1417 if (oidstring == NULL || oid == NULL) 1418 return (KMF_ERR_BAD_PARAMETER); 1419 1420 len = strlen(oidstring); 1421 1422 bp = oidstring; 1423 cp = bp; 1424 /* Skip over leading space */ 1425 while ((bp < &cp[len]) && isspace(*bp)) 1426 bp++; 1427 1428 startp = bp; 1429 nbytes = 0; 1430 1431 /* 1432 * The first two numbers are chewed up by the first octet. 1433 */ 1434 if (sscanf(bp, "%d", &numbuf) != 1) 1435 return (KMF_ERR_BAD_PARAMETER); 1436 while ((bp < &cp[len]) && isdigit(*bp)) 1437 bp++; 1438 while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 1439 bp++; 1440 if (sscanf(bp, "%d", &numbuf) != 1) 1441 return (KMF_ERR_BAD_PARAMETER); 1442 while ((bp < &cp[len]) && isdigit(*bp)) 1443 bp++; 1444 while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 1445 bp++; 1446 nbytes++; 1447 1448 while (isdigit(*bp)) { 1449 if (sscanf(bp, "%d", &numbuf) != 1) 1450 return (KMF_ERR_BAD_PARAMETER); 1451 while (numbuf) { 1452 nbytes++; 1453 numbuf >>= 7; 1454 } 1455 while ((bp < &cp[len]) && isdigit(*bp)) 1456 bp++; 1457 while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 1458 bp++; 1459 } 1460 1461 oid->Length = nbytes; 1462 oid->Data = malloc(oid->Length); 1463 if (oid->Data == NULL) { 1464 return (KMF_ERR_MEMORY); 1465 } 1466 (void) memset(oid->Data, 0, oid->Length); 1467 1468 op = oid->Data; 1469 1470 bp = startp; 1471 (void) sscanf(bp, "%d", &numbuf); 1472 1473 while (isdigit(*bp)) bp++; 1474 while (isspace(*bp) || *bp == '.') bp++; 1475 1476 onumbuf = 40 * numbuf; 1477 (void) sscanf(bp, "%d", &numbuf); 1478 onumbuf += numbuf; 1479 *op = (unsigned char) onumbuf; 1480 op++; 1481 1482 while (isdigit(*bp)) bp++; 1483 while (isspace(*bp) || *bp == '.') bp++; 1484 while (isdigit(*bp)) { 1485 (void) sscanf(bp, "%d", &numbuf); 1486 nbytes = 0; 1487 /* Have to fill in the bytes msb-first */ 1488 onumbuf = numbuf; 1489 while (numbuf) { 1490 nbytes++; 1491 numbuf >>= 7; 1492 } 1493 numbuf = onumbuf; 1494 op += nbytes; 1495 index = -1; 1496 while (numbuf) { 1497 op[index] = (unsigned char)numbuf & 0x7f; 1498 if (index != -1) 1499 op[index] |= 0x80; 1500 index--; 1501 numbuf >>= 7; 1502 } 1503 while (isdigit(*bp)) bp++; 1504 while (isspace(*bp) || *bp == '.') bp++; 1505 } 1506 1507 return (rv); 1508 } 1509 1510 static KMF_RETURN 1511 encode_rid(char *name, KMF_DATA *derdata) 1512 { 1513 KMF_RETURN rv = KMF_OK; 1514 1515 if (name == NULL || derdata == NULL) 1516 return (KMF_ERR_BAD_PARAMETER); 1517 1518 rv = kmf_string_to_oid(name, (KMF_OID *)derdata); 1519 1520 return (rv); 1521 } 1522 1523 static KMF_RETURN 1524 encode_ipaddr(char *name, KMF_DATA *derdata) 1525 { 1526 KMF_RETURN rv = KMF_OK; 1527 size_t len; 1528 in_addr_t v4; 1529 in6_addr_t v6; 1530 uint8_t *ptr; 1531 1532 if (name == NULL || derdata == NULL) 1533 return (KMF_ERR_BAD_PARAMETER); 1534 1535 v4 = inet_addr(name); 1536 if (v4 == (in_addr_t)-1) { 1537 ptr = (uint8_t *)&v6; 1538 if (inet_pton(AF_INET6, name, ptr) != 1) 1539 return (KMF_ERR_ENCODING); 1540 len = sizeof (v6); 1541 } else { 1542 ptr = (uint8_t *)&v4; 1543 len = sizeof (v4); 1544 } 1545 1546 derdata->Data = malloc(len); 1547 if (derdata->Data == NULL) 1548 return (KMF_ERR_MEMORY); 1549 (void) memcpy(derdata->Data, ptr, len); 1550 derdata->Length = len; 1551 1552 return (rv); 1553 } 1554 1555 static KMF_RETURN 1556 verify_uri_format(char *uristring) 1557 { 1558 KMF_RETURN ret = KMF_OK; 1559 xmlURIPtr uriptr = NULL; 1560 1561 /* Parse the URI string; get the hostname and port */ 1562 uriptr = xmlParseURI(uristring); 1563 if (uriptr == NULL) { 1564 ret = KMF_ERR_BAD_URI; 1565 goto out; 1566 } 1567 1568 if (uriptr->scheme == NULL || !strlen(uriptr->scheme)) { 1569 ret = KMF_ERR_BAD_URI; 1570 goto out; 1571 } 1572 1573 if (uriptr->server == NULL || !strlen(uriptr->server)) { 1574 ret = KMF_ERR_BAD_URI; 1575 goto out; 1576 } 1577 out: 1578 if (uriptr != NULL) 1579 xmlFreeURI(uriptr); 1580 return (ret); 1581 } 1582 1583 static KMF_RETURN 1584 encode_altname(char *namedata, 1585 KMF_GENERALNAMECHOICES nametype, KMF_DATA *encodedname) 1586 { 1587 KMF_RETURN ret = KMF_OK; 1588 KMF_X509_NAME dnname; 1589 uchar_t tagval; 1590 BerElement *asn1 = NULL; 1591 BerValue *extdata; 1592 1593 if (namedata == NULL || encodedname == NULL) 1594 return (KMF_ERR_BAD_PARAMETER); 1595 1596 /* 1597 * Encode the namedata according to rules in RFC 3280 for GeneralName. 1598 * The input "namedata" is assumed to be an ASCII string representation 1599 * of the AltName, we need to convert it to correct ASN.1 here before 1600 * adding it to the cert. 1601 */ 1602 switch (nametype) { 1603 case GENNAME_RFC822NAME: /* rfc 822 */ 1604 /* IA5String, no encoding needed */ 1605 encodedname->Data = (uchar_t *)strdup(namedata); 1606 if (encodedname->Data == NULL) 1607 return (KMF_ERR_MEMORY); 1608 encodedname->Length = strlen(namedata); 1609 tagval = (0x80 | nametype); 1610 break; 1611 case GENNAME_DNSNAME: /* rfc 1034 */ 1612 encodedname->Data = (uchar_t *)strdup(namedata); 1613 if (encodedname->Data == NULL) 1614 return (KMF_ERR_MEMORY); 1615 encodedname->Length = strlen(namedata); 1616 tagval = (0x80 | nametype); 1617 break; 1618 case GENNAME_URI: /* rfc 1738 */ 1619 ret = verify_uri_format(namedata); 1620 if (ret != KMF_OK) 1621 return (ret); 1622 /* IA5String, no encoding needed */ 1623 encodedname->Data = (uchar_t *)strdup(namedata); 1624 if (encodedname->Data == NULL) 1625 return (KMF_ERR_MEMORY); 1626 encodedname->Length = strlen(namedata); 1627 tagval = (0x80 | nametype); 1628 break; 1629 case GENNAME_IPADDRESS: 1630 ret = encode_ipaddr(namedata, encodedname); 1631 tagval = (0x80 | nametype); 1632 break; 1633 case GENNAME_REGISTEREDID: 1634 ret = encode_rid(namedata, encodedname); 1635 tagval = (0x80 | nametype); 1636 break; 1637 case GENNAME_DIRECTORYNAME: 1638 ret = kmf_dn_parser(namedata, &dnname); 1639 if (ret == KMF_OK) { 1640 ret = DerEncodeName(&dnname, encodedname); 1641 } 1642 (void) kmf_free_dn(&dnname); 1643 tagval = (0xA0 | nametype); 1644 break; 1645 default: 1646 /* unsupported */ 1647 return (KMF_ERR_BAD_PARAMETER); 1648 1649 } 1650 if (ret != KMF_OK) { 1651 kmf_free_data(encodedname); 1652 return (ret); 1653 } 1654 1655 if ((asn1 = kmfder_alloc()) == NULL) 1656 return (KMF_ERR_MEMORY); 1657 1658 if (kmfber_printf(asn1, "Tl", tagval, encodedname->Length) == -1) 1659 goto cleanup; 1660 1661 if (kmfber_write(asn1, (char *)encodedname->Data, 1662 encodedname->Length, 0) == -1) { 1663 ret = KMF_ERR_ENCODING; 1664 goto cleanup; 1665 } 1666 if (kmfber_flatten(asn1, &extdata) == -1) { 1667 ret = KMF_ERR_ENCODING; 1668 goto cleanup; 1669 } 1670 1671 kmf_free_data(encodedname); 1672 encodedname->Data = (uchar_t *)extdata->bv_val; 1673 encodedname->Length = extdata->bv_len; 1674 1675 free(extdata); 1676 1677 cleanup: 1678 if (asn1) 1679 kmfber_free(asn1, 1); 1680 1681 if (ret != KMF_OK) 1682 kmf_free_data(encodedname); 1683 1684 return (ret); 1685 } 1686 1687 KMF_X509_EXTENSION * 1688 FindExtn(KMF_X509_EXTENSIONS *exts, KMF_OID *oid) 1689 { 1690 KMF_X509_EXTENSION *foundextn = NULL; 1691 int i; 1692 1693 if (exts == NULL || oid == NULL) 1694 return (NULL); 1695 1696 for (i = 0; i < exts->numberOfExtensions; i++) { 1697 if (IsEqualOid(oid, &exts->extensions[i].extnId)) { 1698 foundextn = &exts->extensions[i]; 1699 break; 1700 } 1701 } 1702 return (foundextn); 1703 } 1704 1705 KMF_RETURN 1706 GetSequenceContents(char *data, size_t len, 1707 char **contents, size_t *outlen) 1708 { 1709 KMF_RETURN ret = KMF_OK; 1710 BerElement *exasn1 = NULL; 1711 BerValue oldextn; 1712 int tag; 1713 size_t oldsize; 1714 char *olddata = NULL; 1715 1716 if (data == NULL || contents == NULL || outlen == NULL) 1717 return (KMF_ERR_BAD_PARAMETER); 1718 1719 /* 1720 * Decode the sequence of general names 1721 */ 1722 oldextn.bv_val = data; 1723 oldextn.bv_len = len; 1724 1725 if ((exasn1 = kmfder_init(&oldextn)) == NULL) { 1726 ret = KMF_ERR_MEMORY; 1727 goto out; 1728 } 1729 1730 /* 1731 * Unwrap the sequence to find the size of the block 1732 * of GeneralName items in the set. 1733 * 1734 * Peek at the tag and length ("tl"), 1735 * then consume them ("{"). 1736 */ 1737 if (kmfber_scanf(exasn1, "tl{", &tag, &oldsize) == KMFBER_DEFAULT || 1738 oldsize == 0) { 1739 ret = KMF_ERR_ENCODING; 1740 goto out; 1741 } 1742 1743 olddata = malloc(oldsize); 1744 if (olddata == NULL) { 1745 ret = KMF_ERR_MEMORY; 1746 goto out; 1747 } 1748 (void) memset(olddata, 0, oldsize); 1749 /* 1750 * Read the entire blob of GeneralNames, we don't 1751 * need to interpret them now. 1752 */ 1753 if (kmfber_read(exasn1, olddata, oldsize) != oldsize) { 1754 ret = KMF_ERR_ENCODING; 1755 goto out; 1756 } 1757 out: 1758 if (exasn1 != NULL) 1759 kmfber_free(exasn1, 1); 1760 1761 if (ret != KMF_OK) { 1762 *contents = NULL; 1763 *outlen = 0; 1764 if (olddata != NULL) 1765 free(olddata); 1766 } else { 1767 *contents = olddata; 1768 *outlen = oldsize; 1769 } 1770 return (ret); 1771 } 1772 1773 KMF_RETURN 1774 add_an_extension(KMF_X509_EXTENSIONS *exts, KMF_X509_EXTENSION *newextn) 1775 { 1776 KMF_RETURN ret = KMF_OK; 1777 KMF_X509_EXTENSION *extlist; 1778 1779 if (exts == NULL || newextn == NULL) 1780 return (KMF_ERR_BAD_PARAMETER); 1781 1782 extlist = malloc(sizeof (KMF_X509_EXTENSION) * 1783 (exts->numberOfExtensions + 1)); 1784 if (extlist == NULL) 1785 return (KMF_ERR_MEMORY); 1786 1787 (void) memcpy(extlist, exts->extensions, 1788 exts->numberOfExtensions * sizeof (KMF_X509_EXTENSION)); 1789 1790 (void) memcpy(&extlist[exts->numberOfExtensions], newextn, 1791 sizeof (KMF_X509_EXTENSION)); 1792 1793 free(exts->extensions); 1794 exts->numberOfExtensions++; 1795 exts->extensions = extlist; 1796 1797 return (ret); 1798 } 1799 1800 KMF_RETURN 1801 kmf_set_altname(KMF_X509_EXTENSIONS *extensions, 1802 KMF_OID *oid, 1803 int critical, 1804 KMF_GENERALNAMECHOICES nametype, 1805 char *namedata) 1806 { 1807 KMF_RETURN ret = KMF_OK; 1808 KMF_X509_EXTENSION subjAltName; 1809 KMF_DATA dername = { NULL, 0 }; 1810 BerElement *asn1 = NULL; 1811 BerValue *extdata; 1812 char *olddata = NULL; 1813 KMF_X509_EXTENSION *foundextn = NULL; 1814 size_t oldsize = 0; 1815 1816 if (extensions == NULL || oid == NULL || namedata == NULL) 1817 return (KMF_ERR_BAD_PARAMETER); 1818 1819 ret = encode_altname(namedata, nametype, &dername); 1820 1821 if (ret != KMF_OK) 1822 return (ret); 1823 1824 (void) memset(&subjAltName, 0, sizeof (subjAltName)); 1825 1826 ret = copy_data(&subjAltName.extnId, oid); 1827 if (ret != KMF_OK) 1828 goto out; 1829 /* 1830 * Check to see if this cert already has a subjectAltName. 1831 */ 1832 foundextn = FindExtn(extensions, oid); 1833 1834 if (foundextn != NULL) { 1835 ret = GetSequenceContents( 1836 (char *)foundextn->BERvalue.Data, 1837 foundextn->BERvalue.Length, 1838 &olddata, &oldsize); 1839 if (ret != KMF_OK) 1840 goto out; 1841 } 1842 1843 /* 1844 * Assume (!!) that the namedata given is already properly encoded. 1845 */ 1846 if ((asn1 = kmfder_alloc()) == NULL) 1847 return (KMF_ERR_MEMORY); 1848 1849 if (kmfber_printf(asn1, "{") == -1) { 1850 ret = KMF_ERR_ENCODING; 1851 goto out; 1852 } 1853 1854 /* Write the old extension data first */ 1855 if (olddata != NULL && oldsize > 0) { 1856 if (kmfber_write(asn1, olddata, oldsize, 0) == -1) { 1857 ret = KMF_ERR_ENCODING; 1858 goto out; 1859 } 1860 } 1861 1862 /* Now add the new name to the list */ 1863 if (kmfber_write(asn1, (char *)dername.Data, dername.Length, 0) == -1) { 1864 ret = KMF_ERR_ENCODING; 1865 goto out; 1866 } 1867 1868 /* Now close the sequence */ 1869 if (kmfber_printf(asn1, "}") == -1) { 1870 ret = KMF_ERR_ENCODING; 1871 goto out; 1872 } 1873 if (kmfber_flatten(asn1, &extdata) == -1) { 1874 ret = KMF_ERR_ENCODING; 1875 goto out; 1876 } 1877 1878 /* 1879 * If we are just adding to an existing list of altNames, 1880 * just replace the BER data associated with the found extension. 1881 */ 1882 if (foundextn != NULL) { 1883 free(foundextn->BERvalue.Data); 1884 foundextn->critical = critical; 1885 foundextn->BERvalue.Data = (uchar_t *)extdata->bv_val; 1886 foundextn->BERvalue.Length = extdata->bv_len; 1887 } else { 1888 subjAltName.critical = critical; 1889 subjAltName.format = KMF_X509_DATAFORMAT_ENCODED; 1890 subjAltName.BERvalue.Data = (uchar_t *)extdata->bv_val; 1891 subjAltName.BERvalue.Length = extdata->bv_len; 1892 ret = add_an_extension(extensions, &subjAltName); 1893 if (ret != KMF_OK) 1894 free(subjAltName.BERvalue.Data); 1895 } 1896 1897 free(extdata); 1898 out: 1899 if (olddata != NULL) 1900 free(olddata); 1901 1902 kmf_free_data(&dername); 1903 if (ret != KMF_OK) 1904 kmf_free_data(&subjAltName.extnId); 1905 if (asn1 != NULL) 1906 kmfber_free(asn1, 1); 1907 return (ret); 1908 } 1909 1910 /* 1911 * Search a list of attributes for one that matches the given type. 1912 * Return a pointer into the attribute list. This does not 1913 * return a copy of the value, it returns a reference into the 1914 * given list. 1915 */ 1916 int 1917 kmf_find_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, int numattrs) 1918 { 1919 int i; 1920 for (i = 0; i < numattrs; i++) { 1921 if (attlist[i].type == type) 1922 return (i); 1923 } 1924 return (-1); 1925 } 1926 1927 /* 1928 * Verify that a given attribute is consistent with the 1929 * "test" attribute. 1930 */ 1931 static KMF_RETURN 1932 verify_attribute(KMF_ATTRIBUTE *givenattr, 1933 KMF_ATTRIBUTE_TESTER *testattr) 1934 { 1935 /* A NULL pValue was found where one is required */ 1936 if (testattr->null_value_ok == FALSE && 1937 givenattr->pValue == NULL) 1938 return (KMF_ERR_BAD_PARAMETER); 1939 1940 /* If the given valueLen is too small, return error */ 1941 if (givenattr->pValue != NULL && 1942 testattr->minlen > 0 && 1943 (givenattr->valueLen < testattr->minlen)) 1944 return (KMF_ERR_BAD_PARAMETER); 1945 1946 /* If the given valueLen is too big, return error */ 1947 if (givenattr->pValue != NULL && 1948 testattr->maxlen > 0 && 1949 (givenattr->valueLen > testattr->maxlen)) 1950 return (KMF_ERR_BAD_PARAMETER); 1951 1952 return (KMF_OK); 1953 } 1954 1955 /* 1956 * Given a set of required attribute tests and optional 1957 * attributes, make sure that the actual attributes 1958 * being tested (attrlist below) are allowed and are 1959 * properly specified. 1960 */ 1961 KMF_RETURN 1962 test_attributes(int reqnum, KMF_ATTRIBUTE_TESTER *reqattrs, 1963 int optnum, KMF_ATTRIBUTE_TESTER *optattrs, 1964 int numattrs, KMF_ATTRIBUTE *attrlist) 1965 { 1966 KMF_RETURN ret = KMF_OK; 1967 int i, idx; 1968 1969 /* 1970 * If the caller didn't supply enough attributes, 1971 * return an error. 1972 */ 1973 if (numattrs < reqnum || attrlist == NULL) 1974 return (KMF_ERR_BAD_PARAMETER); 1975 1976 /* 1977 * Make sure all required attrs are present and 1978 * correct. 1979 */ 1980 for (i = 0; i < reqnum && ret == KMF_OK; i++) { 1981 idx = kmf_find_attr(reqattrs[i].type, attrlist, numattrs); 1982 /* If a required attr is not found, return error */ 1983 if (idx == -1) { 1984 return (KMF_ERR_BAD_PARAMETER); 1985 } 1986 1987 ret = verify_attribute(&attrlist[idx], &reqattrs[i]); 1988 } 1989 /* 1990 * Now test the optional parameters. 1991 */ 1992 for (i = 0; i < optnum && ret == KMF_OK; i++) { 1993 idx = kmf_find_attr(optattrs[i].type, attrlist, numattrs); 1994 /* If a optional attr is not found, continue. */ 1995 if (idx == -1) { 1996 continue; 1997 } 1998 1999 ret = verify_attribute(&attrlist[idx], &optattrs[i]); 2000 } 2001 2002 return (ret); 2003 } 2004 2005 /* 2006 * Given an already allocated attribute list, insert 2007 * the given attribute information at a specific index 2008 * in the list. 2009 */ 2010 void 2011 kmf_set_attr_at_index(KMF_ATTRIBUTE *attlist, int index, 2012 KMF_ATTR_TYPE type, void *pValue, uint32_t len) 2013 { 2014 if (attlist == NULL) 2015 return; 2016 2017 attlist[index].type = type; 2018 attlist[index].pValue = pValue; 2019 attlist[index].valueLen = len; 2020 } 2021 2022 /* 2023 * Find an attribute matching a particular type and set 2024 * the pValue and length fields to the given values. 2025 */ 2026 KMF_RETURN 2027 kmf_set_attr(KMF_ATTRIBUTE *attlist, int numattr, 2028 KMF_ATTR_TYPE type, void *pValue, uint32_t len) 2029 { 2030 int idx; 2031 if (attlist == NULL) 2032 return (KMF_ERR_BAD_PARAMETER); 2033 2034 idx = kmf_find_attr(type, attlist, numattr); 2035 if (idx == -1) 2036 return (KMF_ERR_ATTR_NOT_FOUND); 2037 2038 attlist[idx].type = type; 2039 /* Assumes the attribute pValue can hold the result */ 2040 if (attlist[idx].pValue != NULL) { 2041 if (attlist[idx].valueLen >= len) 2042 (void) memcpy(attlist[idx].pValue, pValue, len); 2043 else 2044 return (KMF_ERR_BUFFER_SIZE); 2045 } 2046 attlist[idx].valueLen = len; 2047 return (KMF_OK); 2048 } 2049 2050 /* 2051 * Find a particular attribute in a list and return 2052 * a pointer to its value. 2053 */ 2054 void * 2055 kmf_get_attr_ptr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, 2056 int numattrs) 2057 { 2058 int i; 2059 2060 i = kmf_find_attr(type, attlist, numattrs); 2061 if (i == -1) 2062 return (NULL); 2063 2064 return (attlist[i].pValue); 2065 } 2066 2067 /* 2068 * Find a particular attribute in a list and return 2069 * the value and length values. Value and length 2070 * may be NULL if the caller doesn't want their values 2071 * to be filled in. 2072 */ 2073 KMF_RETURN 2074 kmf_get_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attlist, 2075 int numattrs, void *outValue, uint32_t *outlen) 2076 { 2077 int i; 2078 uint32_t len = 0; 2079 uint32_t *lenptr = outlen; 2080 2081 if (lenptr == NULL) 2082 lenptr = &len; 2083 2084 i = kmf_find_attr(type, attlist, numattrs); 2085 if (i == -1) 2086 return (KMF_ERR_ATTR_NOT_FOUND); 2087 2088 /* This assumes that the ptr passed in is pre-allocated space */ 2089 if (attlist[i].pValue != NULL && outValue != NULL) { 2090 /* 2091 * If the caller did not specify a length, 2092 * assume "outValue" is big enough. 2093 */ 2094 if (outlen != NULL) { 2095 if (*outlen >= attlist[i].valueLen) 2096 (void) memcpy(outValue, attlist[i].pValue, 2097 attlist[i].valueLen); 2098 else 2099 return (KMF_ERR_BUFFER_SIZE); 2100 } else { 2101 (void) memcpy(outValue, attlist[i].pValue, 2102 attlist[i].valueLen); 2103 } 2104 } 2105 2106 if (outlen != NULL) 2107 *outlen = attlist[i].valueLen; 2108 return (KMF_OK); 2109 } 2110 2111 /* 2112 * Utility routine to find a string type attribute, allocate it 2113 * and return the value to the caller. This simplifies the 2114 * operation by doing both "kmf_get_attr" calls and avoids 2115 * duplicating this block of code in lots of places. 2116 */ 2117 KMF_RETURN 2118 kmf_get_string_attr(KMF_ATTR_TYPE type, KMF_ATTRIBUTE *attrlist, 2119 int numattrs, char **outstr) 2120 { 2121 KMF_RETURN rv; 2122 uint32_t len; 2123 2124 if (outstr == NULL) 2125 return (KMF_ERR_BAD_PARAMETER); 2126 2127 if ((rv = kmf_get_attr(type, attrlist, numattrs, NULL, &len)) == 2128 KMF_OK) { 2129 *outstr = malloc(len + 1); 2130 if ((*outstr) == NULL) 2131 return (KMF_ERR_MEMORY); 2132 (void) memset((*outstr), 0, len + 1); 2133 rv = kmf_get_attr(type, attrlist, numattrs, (*outstr), &len); 2134 if (rv != KMF_OK) { 2135 free(*outstr); 2136 *outstr = NULL; 2137 } 2138 } 2139 2140 return (rv); 2141 } 2142 2143 /* 2144 * This API is used by elfsign. We must keep it in old API form. 2145 */ 2146 KMF_RETURN 2147 KMF_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) 2148 { 2149 2150 KMF_ATTRIBUTE attlist[32]; 2151 int i = 0; 2152 2153 if (params == NULL) 2154 return (KMF_ERR_BAD_PARAMETER); 2155 2156 kmf_set_attr_at_index(attlist, i, 2157 KMF_KEYSTORE_TYPE_ATTR, ¶ms->kstype, sizeof (params->kstype)); 2158 i++; 2159 2160 if (params->kstype == KMF_KEYSTORE_NSS) { 2161 if (params->nssconfig.configdir != NULL) { 2162 kmf_set_attr_at_index(attlist, i, 2163 KMF_DIRPATH_ATTR, 2164 params->nssconfig.configdir, 2165 strlen(params->nssconfig.configdir)); 2166 i++; 2167 } 2168 if (params->nssconfig.certPrefix != NULL) { 2169 kmf_set_attr_at_index(attlist, i, 2170 KMF_CERTPREFIX_ATTR, 2171 params->nssconfig.certPrefix, 2172 strlen(params->nssconfig.certPrefix)); 2173 i++; 2174 } 2175 if (params->nssconfig.keyPrefix != NULL) { 2176 kmf_set_attr_at_index(attlist, i, 2177 KMF_KEYPREFIX_ATTR, 2178 params->nssconfig.keyPrefix, 2179 strlen(params->nssconfig.keyPrefix)); 2180 i++; 2181 } 2182 if (params->nssconfig.secModName != NULL) { 2183 kmf_set_attr_at_index(attlist, i, 2184 KMF_SECMODNAME_ATTR, 2185 params->nssconfig.secModName, 2186 strlen(params->nssconfig.secModName)); 2187 i++; 2188 } 2189 } else if (params->kstype == KMF_KEYSTORE_PK11TOKEN) { 2190 if (params->pkcs11config.label != NULL) { 2191 kmf_set_attr_at_index(attlist, i, 2192 KMF_TOKEN_LABEL_ATTR, 2193 params->pkcs11config.label, 2194 strlen(params->pkcs11config.label)); 2195 i++; 2196 } 2197 kmf_set_attr_at_index(attlist, i, 2198 KMF_READONLY_ATTR, 2199 ¶ms->pkcs11config.readonly, 2200 sizeof (params->pkcs11config.readonly)); 2201 i++; 2202 } 2203 2204 return (kmf_configure_keystore(handle, i, attlist)); 2205 } 2206 2207 /* 2208 * This API is used by elfsign. We must keep it in old API form. 2209 */ 2210 KMF_RETURN 2211 KMF_Initialize(KMF_HANDLE_T *outhandle, char *policyfile, char *policyname) 2212 { 2213 return (kmf_initialize(outhandle, policyfile, policyname)); 2214 } 2215 2216 /* 2217 * This API is used by elfsign. We must keep it in old API form. 2218 */ 2219 KMF_RETURN 2220 KMF_Finalize(KMF_HANDLE_T handle) 2221 { 2222 return (kmf_finalize(handle)); 2223 } 2224 2225 /* 2226 * This API is used by elfsign. We must keep it in old API form. 2227 */ 2228 KMF_RETURN 2229 KMF_GetKMFErrorString(KMF_RETURN errcode, char **errmsg) 2230 { 2231 return (kmf_get_kmf_error_str(errcode, errmsg)); 2232 } 2233 2234 /* 2235 * This API is used by elfsign. We must keep it in old API form. 2236 */ 2237 KMF_RETURN 2238 KMF_ReadInputFile(KMF_HANDLE_T handle, char *filename, KMF_DATA *pdata) 2239 { 2240 return (kmf_read_input_file(handle, filename, pdata)); 2241 } 2242 2243 2244 /* 2245 * This API is used by elfsign. We must keep it in old API form. 2246 */ 2247 void 2248 KMF_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert) 2249 { 2250 kmf_free_kmf_cert(handle, kmf_cert); 2251 } 2252 2253 /* 2254 * This API is used by elfsign. We must keep it in old API form. 2255 */ 2256 void 2257 KMF_FreeData(KMF_DATA *datablock) 2258 { 2259 kmf_free_data(datablock); 2260 } 2261 2262 /* 2263 * This API is used by elfsign. We must keep it in old API form. 2264 */ 2265 void 2266 KMF_FreeKMFKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key) 2267 { 2268 kmf_free_kmf_key(handle, key); 2269 } 2270 2271 /* 2272 * This API is used by elfsign. We must keep it in old API form. 2273 */ 2274 void 2275 KMF_FreeSignedCSR(KMF_CSR_DATA *csr) 2276 { 2277 kmf_free_signed_csr(csr); 2278 } 2279