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 static void free_extensions(KMF_X509_EXTENSIONS *extns); 156 157 KMF_RETURN 158 init_pk11() 159 { 160 (void) mutex_lock(&init_lock); 161 if (!pkcs11_initialized) { 162 CK_RV rv = C_Initialize(NULL); 163 if ((rv != CKR_OK) && 164 (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { 165 (void) mutex_unlock(&init_lock); 166 return (KMF_ERR_UNINITIALIZED); 167 } else { 168 pkcs11_initialized = 1; 169 } 170 } 171 (void) mutex_unlock(&init_lock); 172 return (KMF_OK); 173 } 174 175 /* 176 * Private method for searching the plugin list for the correct 177 * Plugin to use. 178 */ 179 KMF_PLUGIN * 180 FindPlugin(KMF_HANDLE_T handle, KMF_KEYSTORE_TYPE kstype) 181 { 182 KMF_PLUGIN_LIST *node; 183 184 if (handle == NULL) 185 return (NULL); 186 187 node = handle->plugins; 188 189 while (node != NULL && node->plugin->type != kstype) 190 node = node->next; 191 192 /* If it is NULL, that is indication enough of an error */ 193 return (node ? node->plugin : NULL); 194 } 195 196 static KMF_RETURN 197 InitializePlugin(KMF_KEYSTORE_TYPE kstype, char *path, KMF_PLUGIN **plugin) 198 { 199 KMF_PLUGIN *p = NULL; 200 KMF_PLUGIN_FUNCLIST *(*sym)(); 201 202 if (path == NULL || plugin == NULL) 203 return (KMF_ERR_BAD_PARAMETER); 204 205 *plugin = NULL; 206 207 p = (KMF_PLUGIN *)malloc(sizeof (KMF_PLUGIN)); 208 if (p == NULL) 209 return (KMF_ERR_MEMORY); 210 211 p->type = kstype; 212 p->path = strdup(path); 213 if (p->path == NULL) { 214 free(p); 215 return (KMF_ERR_MEMORY); 216 } 217 p->dldesc = dlopen(path, RTLD_NOW | RTLD_GROUP | RTLD_PARENT); 218 if (p->dldesc == NULL) { 219 free(p->path); 220 free(p); 221 return (KMF_ERR_PLUGIN_INIT); 222 } 223 224 sym = (KMF_PLUGIN_FUNCLIST *(*)())dlsym(p->dldesc, 225 KMF_PLUGIN_INIT_SYMBOL); 226 if (sym == NULL) { 227 (void) dlclose(p->dldesc); 228 free(p->path); 229 free(p); 230 return (KMF_ERR_PLUGIN_INIT); 231 } 232 233 /* Get the function list */ 234 if ((p->funclist = (*sym)()) == NULL) { 235 (void) dlclose(p->dldesc); 236 free(p->path); 237 free(p); 238 return (KMF_ERR_PLUGIN_INIT); 239 } 240 241 *plugin = p; 242 243 return (KMF_OK); 244 } 245 246 static KMF_RETURN 247 AddPlugin(KMF_HANDLE_T handle, KMF_PLUGIN *plugin) 248 { 249 KMF_PLUGIN_LIST *n; 250 251 if (handle == NULL || plugin == NULL) 252 return (KMF_ERR_BAD_PARAMETER); 253 254 /* If the head is NULL, create it */ 255 if (handle->plugins == NULL) { 256 handle->plugins = (KMF_PLUGIN_LIST *)malloc( 257 sizeof (KMF_PLUGIN_LIST)); 258 if (handle->plugins == NULL) 259 return (KMF_ERR_MEMORY); 260 handle->plugins->plugin = plugin; 261 handle->plugins->next = NULL; 262 } else { 263 /* walk the list to find the tail */ 264 n = handle->plugins; 265 while (n->next != NULL) 266 n = n->next; 267 n->next = (KMF_PLUGIN_LIST *)malloc(sizeof (KMF_PLUGIN_LIST)); 268 if (n->next == NULL) 269 return (KMF_ERR_MEMORY); 270 271 n->next->plugin = plugin; 272 n->next->next = NULL; 273 } 274 return (0); 275 } 276 277 static void 278 DestroyPlugin(KMF_PLUGIN *plugin) 279 { 280 if (plugin) { 281 if (plugin->path) 282 free(plugin->path); 283 free(plugin); 284 } 285 } 286 287 static void 288 Cleanup_KMF_Handle(KMF_HANDLE_T handle) 289 { 290 if (handle != NULL) { 291 while (handle->plugins != NULL) { 292 KMF_PLUGIN_LIST *next = handle->plugins->next; 293 294 DestroyPlugin(handle->plugins->plugin); 295 296 free(handle->plugins); 297 298 handle->plugins = next; 299 } 300 301 KMF_FreePolicyRecord(handle->policy); 302 free(handle->policy); 303 } 304 free(handle); 305 } 306 307 void 308 Cleanup_PK11_Session(KMF_HANDLE_T handle) 309 { 310 if (handle != NULL) { 311 /* Close active session on a pkcs11 token */ 312 if (handle->pk11handle != NULL) { 313 (void) C_CloseSession(handle->pk11handle); 314 handle->pk11handle = NULL; 315 } 316 } 317 } 318 319 KMF_RETURN 320 KMF_Initialize(KMF_HANDLE_T *outhandle, char *policyfile, char *policyname) 321 { 322 KMF_RETURN ret = KMF_OK; 323 KMF_HANDLE *handle = NULL; 324 KMF_PLUGIN *pluginrec = NULL; 325 int i, numitems; 326 327 if (outhandle == NULL) 328 return (KMF_ERR_BAD_PARAMETER); 329 330 *outhandle = NULL; 331 handle = (KMF_HANDLE *)malloc(sizeof (KMF_HANDLE)); 332 if (handle == NULL) 333 return (KMF_ERR_MEMORY); 334 335 (void) memset(handle, 0, sizeof (KMF_HANDLE)); 336 handle->plugins = NULL; 337 338 /* Initialize the handle with the policy */ 339 ret = KMF_SetPolicy((void *)handle, 340 policyfile == NULL ? KMF_DEFAULT_POLICY_FILE : policyfile, 341 policyname == NULL ? KMF_DEFAULT_POLICY_NAME : policyname); 342 if (ret != KMF_OK) 343 goto errout; 344 345 numitems = sizeof (plugin_list)/sizeof (KMF_PLUGIN_ITEM); 346 for (i = 0; i < numitems; i++) { 347 ret = InitializePlugin(plugin_list[i].kstype, 348 plugin_list[i].path, &pluginrec); 349 if (ret != KMF_OK) { 350 cryptoerror( 351 plugin_list[i].critical ? LOG_WARNING : LOG_DEBUG, 352 "KMF was unable to load %s plugin module %s\n", 353 plugin_list[i].critical ? "critical" : "optional", 354 plugin_list[i].path); 355 356 if (plugin_list[i].critical == FALSE) 357 ret = KMF_OK; 358 else 359 goto errout; 360 } 361 if (pluginrec != NULL) { 362 if ((ret = AddPlugin(handle, pluginrec))) 363 goto errout; 364 } 365 } 366 367 CLEAR_ERROR(handle, ret); 368 errout: 369 if (ret != KMF_OK) { 370 Cleanup_KMF_Handle(handle); 371 handle = NULL; 372 } 373 374 *outhandle = (KMF_HANDLE_T)handle; 375 return (ret); 376 } 377 378 KMF_RETURN 379 KMF_ConfigureKeystore(KMF_HANDLE_T handle, KMF_CONFIG_PARAMS *params) 380 { 381 KMF_PLUGIN *plugin; 382 KMF_RETURN ret; 383 384 CLEAR_ERROR(handle, ret); 385 if (ret != KMF_OK) 386 return (ret); 387 388 if (params == NULL) 389 return (KMF_ERR_BAD_PARAMETER); 390 391 plugin = FindPlugin(handle, params->kstype); 392 if (plugin == NULL) 393 return (KMF_ERR_PLUGIN_NOTFOUND); 394 395 if (plugin->funclist->ConfigureKeystore != NULL) 396 return (plugin->funclist->ConfigureKeystore(handle, params)); 397 else 398 /* return KMF_OK, if the plugin does not have an entry */ 399 return (KMF_OK); 400 } 401 402 KMF_RETURN 403 KMF_Finalize(KMF_HANDLE_T handle) 404 { 405 KMF_RETURN ret = KMF_OK; 406 407 CLEAR_ERROR(handle, ret); 408 if (ret != KMF_OK) 409 return (ret); 410 411 if (pkcs11_initialized) { 412 Cleanup_PK11_Session(handle); 413 } 414 Cleanup_KMF_Handle(handle); 415 416 return (ret); 417 } 418 419 KMF_RETURN 420 KMF_GetKMFErrorString(KMF_RETURN errcode, char **errmsg) 421 { 422 KMF_RETURN ret = KMF_OK; 423 int i, maxerr; 424 425 if (errmsg == NULL) 426 return (KMF_ERR_BAD_PARAMETER); 427 428 *errmsg = NULL; 429 maxerr = sizeof (kmf_errcodes) / sizeof (kmf_error_map); 430 431 for (i = 0; i < maxerr && errcode != kmf_errcodes[i].code; i++); 432 433 if (i == maxerr) 434 return (KMF_ERR_MISSING_ERRCODE); 435 else { 436 *errmsg = strdup(kmf_errcodes[i].message); 437 if ((*errmsg) == NULL) 438 return (KMF_ERR_MEMORY); 439 } 440 return (ret); 441 } 442 443 KMF_RETURN 444 KMF_GetPluginErrorString(KMF_HANDLE_T handle, char **msgstr) 445 { 446 KMF_RETURN ret = KMF_OK; 447 KMF_PLUGIN *plugin; 448 449 if (handle == NULL || msgstr == NULL) 450 return (KMF_ERR_BAD_PARAMETER); 451 452 *msgstr = NULL; 453 454 if (handle->lasterr.errcode == 0) { 455 return (KMF_ERR_MISSING_ERRCODE); 456 } 457 458 if (handle->lasterr.kstype == -1) { /* System error */ 459 char *str = strerror(handle->lasterr.errcode); 460 if (str != NULL) { 461 *msgstr = strdup(str); 462 if ((*msgstr) == NULL) 463 return (KMF_ERR_MEMORY); 464 } 465 return (KMF_OK); 466 } 467 468 plugin = FindPlugin(handle, handle->lasterr.kstype); 469 if (plugin == NULL) 470 return (KMF_ERR_PLUGIN_NOTFOUND); 471 472 if (plugin->funclist->GetErrorString != NULL) { 473 ret = plugin->funclist->GetErrorString(handle, msgstr); 474 } else { 475 return (KMF_ERR_FUNCTION_NOT_FOUND); 476 } 477 478 return (ret); 479 } 480 481 KMF_RETURN 482 KMF_DNParser(char *string, KMF_X509_NAME *name) 483 { 484 KMF_RETURN err; 485 486 if (string == NULL || name == NULL) 487 return (KMF_ERR_BAD_PARAMETER); 488 489 err = ParseDistinguishedName(string, (int)strlen(string), name); 490 return (err); 491 } 492 493 KMF_RETURN 494 KMF_DN2Der(KMF_X509_NAME *dn, KMF_DATA *der) 495 { 496 KMF_RETURN rv; 497 498 if (dn == NULL || der == NULL) 499 return (KMF_ERR_BAD_PARAMETER); 500 501 rv = DerEncodeName(dn, der); 502 return (rv); 503 } 504 505 #define SET_SYS_ERROR(h, c) if (h) {\ 506 h->lasterr.kstype = -1;\ 507 h->lasterr.errcode = c;\ 508 } 509 510 KMF_RETURN 511 KMF_ReadInputFile(KMF_HANDLE_T handle, char *filename, KMF_DATA *pdata) 512 { 513 struct stat s; 514 long nread, total = 0; 515 int fd; 516 unsigned char *buf = NULL; 517 KMF_RETURN ret; 518 519 if (handle) { 520 CLEAR_ERROR(handle, ret); 521 if (ret != KMF_OK) 522 return (ret); 523 } 524 525 if (filename == NULL || pdata == NULL) { 526 return (KMF_ERR_BAD_PARAMETER); 527 } 528 529 if ((fd = open(filename, O_RDONLY)) < 0) { 530 SET_SYS_ERROR(handle, errno); 531 return (KMF_ERR_OPEN_FILE); 532 } 533 534 if (fstat(fd, &s) < 0) { 535 SET_SYS_ERROR(handle, errno); 536 (void) close(fd); 537 return (KMF_ERR_OPEN_FILE); 538 } 539 540 if ((buf = (unsigned char *) malloc(s.st_size)) == NULL) { 541 (void) close(fd); 542 return (KMF_ERR_MEMORY); 543 } 544 545 do { 546 nread = read(fd, buf+total, s.st_size-total); 547 if (nread < 0) { 548 SET_SYS_ERROR(handle, errno); 549 (void) close(fd); 550 free(buf); 551 return (KMF_ERR_INTERNAL); 552 } 553 total += nread; 554 } while (total < s.st_size); 555 556 pdata->Data = buf; 557 pdata->Length = s.st_size; 558 (void) close(fd); 559 return (KMF_OK); 560 } 561 562 /* 563 * 564 * Name: KMF_Der2Pem 565 * 566 * Description: 567 * Function for converting DER encoded format to PEM encoded format 568 * 569 * Parameters: 570 * type(input) - CERTIFICATE or CSR 571 * data(input) - pointer to the DER encoded data 572 * len(input) - length of input data 573 * out(output) - contains the output buffer address to be returned 574 * outlen(output) - pointer to the returned output length 575 * 576 * Returns: 577 * A KMF_RETURN value indicating success or specifying a particular 578 * error condition. 579 * The value KMF_OK indicates success. All other values represent 580 * an error condition. 581 * 582 */ 583 KMF_RETURN 584 KMF_Der2Pem(KMF_OBJECT_TYPE type, unsigned char *data, 585 int len, unsigned char **out, int *outlen) 586 { 587 588 KMF_RETURN err; 589 if (data == NULL || out == NULL || outlen == NULL) 590 return (KMF_ERR_BAD_PARAMETER); 591 592 err = Der2Pem(type, data, len, out, outlen); 593 return (err); 594 595 } 596 597 /* 598 * 599 * Name: KMF_Pem2Der 600 * 601 * Description: 602 * Function for converting PEM encoded format to DER encoded format 603 * 604 * Parameters: 605 * in(input) - pointer to the PEM encoded data 606 * inlen(input) - length of input data 607 * out(output) - contains the output buffer address to be returned 608 * outlen(output) - pointer to the returned output length 609 * 610 * Returns: 611 * A KMF_RETURN value indicating success or specifying a particular 612 * error condition. 613 * The value KMF_OK indicates success. All other values represent 614 * an error condition. 615 * 616 */ 617 KMF_RETURN 618 KMF_Pem2Der(unsigned char *in, int inlen, 619 unsigned char **out, int *outlen) 620 { 621 KMF_RETURN err; 622 if (in == NULL || out == NULL || outlen == NULL) 623 return (KMF_ERR_BAD_PARAMETER); 624 625 err = Pem2Der(in, inlen, out, outlen); 626 return (err); 627 } 628 629 char * 630 KMF_OID2String(KMF_OID *oid) 631 { 632 char numstr[128]; 633 uint32_t number; 634 int numshift; 635 uint32_t i, string_length; 636 uchar_t *cp; 637 char *bp; 638 639 /* First determine the size of the string */ 640 string_length = 0; 641 number = 0; 642 numshift = 0; 643 cp = (unsigned char *)oid->Data; 644 645 number = (uint32_t)cp[0]; 646 (void) sprintf(numstr, "%d ", number/40); 647 648 string_length += strlen(numstr); 649 (void) sprintf(numstr, "%d ", number%40); 650 651 string_length += strlen(numstr); 652 653 for (i = 1; i < oid->Length; i++) { 654 if ((uint32_t)(numshift+7) < (sizeof (uint32_t)*8)) { 655 number = (number << 7) | (cp[i] & 0x7f); 656 numshift += 7; 657 } else { 658 return (NULL); 659 } 660 661 if ((cp[i] & 0x80) == 0) { 662 (void) sprintf(numstr, "%d ", number); 663 string_length += strlen(numstr); 664 number = 0; 665 numshift = 0; 666 } 667 } 668 /* 669 * If we get here, we've calculated the length of "n n n ... n ". Add 4 670 * here for "{ " and "}\0". 671 */ 672 string_length += 4; 673 if ((bp = (char *)malloc(string_length))) { 674 number = (uint32_t)cp[0]; 675 676 (void) sprintf(numstr, "%d.", number/40); 677 (void) strcpy(bp, numstr); 678 679 (void) sprintf(numstr, "%d.", number%40); 680 (void) strcat(bp, numstr); 681 682 number = 0; 683 cp = (unsigned char *) oid->Data; 684 for (i = 1; i < oid->Length; i++) { 685 number = (number << 7) | (cp[i] & 0x7f); 686 if ((cp[i] & 0x80) == 0) { 687 (void) sprintf(numstr, "%d", number); 688 (void) strcat(bp, numstr); 689 number = 0; 690 if (i+1 < oid->Length) 691 (void) strcat(bp, "."); 692 } 693 } 694 } 695 return (bp); 696 } 697 698 static boolean_t 699 check_for_pem(uchar_t *buf, KMF_ENCODE_FORMAT *fmt) 700 { 701 char *p; 702 703 if (buf == NULL) 704 return (FALSE); 705 706 if (memcmp(buf, "Bag Attr", 8) == 0) { 707 *fmt = KMF_FORMAT_PEM_KEYPAIR; 708 return (TRUE); 709 } 710 711 /* Look for "-----BEGIN" right after a newline */ 712 p = strtok((char *)buf, "\n"); 713 while (p != NULL) { 714 if (strstr(p, "-----BEGIN") != NULL) { 715 *fmt = KMF_FORMAT_PEM; 716 return (TRUE); 717 } 718 p = strtok(NULL, "\n"); 719 } 720 return (FALSE); 721 } 722 723 724 static unsigned char pkcs12_version[3] = {0x02, 0x01, 0x03}; 725 static unsigned char pkcs12_oid[11] = 726 {0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01}; 727 728 /* 729 * This function takes a BER encoded string as input and checks the version 730 * and the oid in the the top-level ASN.1 structure to see if it complies to 731 * the PKCS#12 Syntax. 732 */ 733 static boolean_t 734 check_for_pkcs12(uchar_t *buf, int buf_len) 735 { 736 int index = 0; 737 int length_octets; 738 739 if (buf == NULL || buf_len <= 0) 740 return (FALSE); 741 742 /* 743 * The top level structure for a PKCS12 string: 744 * 745 * PFX ::= SEQUENCE { 746 * version INTEGER {v3(3)}(v3,...) 747 * authSafe ContentInfo 748 * macData MacData OPTIONAL 749 * } 750 * 751 * ContentInfo 752 * FROM PKCS-7 {iso(1) member-body(2) us(840) rsadsi(113549) 753 * pkcs(1) pkcs-7(7) modules(0) pkcs-7(1)} 754 * 755 * Therefore, the BER/DER dump of a PKCS#12 file for the first 2 756 * sequences up to the oid part is as following: 757 * 758 * SEQUENCE { 759 * INTEGER 3 760 * SEQUENCE { 761 * OBJECT IDENTIFIER data (1 2 840 113549 1 7 1) 762 */ 763 764 /* 765 * Check the first sequence and calculate the number of bytes used 766 * to store the length. 767 */ 768 if (buf[index++] != 0x30) 769 return (FALSE); 770 771 if (buf[index] & 0x80) { 772 length_octets = buf[index++] & 0x0F; /* long form */ 773 } else { 774 length_octets = 1; /* short form */ 775 } 776 777 index += length_octets; 778 if (index >= buf_len) 779 return (FALSE); 780 781 /* Skip the length octets and check the pkcs12 version */ 782 if (memcmp(buf + index, pkcs12_version, sizeof (pkcs12_version)) != 0) 783 return (FALSE); 784 785 index += sizeof (pkcs12_version); 786 if (index >= buf_len) 787 return (FALSE); 788 789 /* 790 * Check the 2nd sequence and calculate the number of bytes used 791 * to store the length. 792 */ 793 if ((buf[index++] & 0xFF) != 0x30) 794 return (FALSE); 795 796 if (buf[index] & 0x80) { 797 length_octets = buf[index++] & 0x0F; 798 } else { 799 length_octets = 1; 800 } 801 802 index += length_octets; 803 if (index + sizeof (pkcs12_oid) >= buf_len) 804 return (FALSE); 805 806 /* Skip the length octets and check the oid */ 807 if (memcmp(buf + index, pkcs12_oid, sizeof (pkcs12_oid)) != 0) 808 return (FALSE); 809 else 810 return (TRUE); 811 } 812 813 KMF_RETURN 814 KMF_GetFileFormat(char *filename, KMF_ENCODE_FORMAT *fmt) 815 { 816 KMF_RETURN ret = KMF_OK; 817 KMF_DATA filebuf = {NULL, 0}; 818 uchar_t *buf; 819 820 if (filename == NULL || !strlen(filename) || fmt == NULL) 821 return (KMF_ERR_BAD_PARAMETER); 822 823 *fmt = 0; 824 ret = KMF_ReadInputFile(NULL, filename, &filebuf); 825 if (ret != KMF_OK) 826 return (ret); 827 828 if (filebuf.Length < 8) { 829 ret = KMF_ERR_ENCODING; /* too small */ 830 goto end; 831 } 832 833 buf = filebuf.Data; 834 if (check_for_pkcs12(buf, filebuf.Length) == TRUE) { 835 *fmt = KMF_FORMAT_PKCS12; 836 } else if (buf[0] == 0x30 && (buf[1] & 0x80)) { 837 /* It is most likely a generic ASN.1 encoded file */ 838 *fmt = KMF_FORMAT_ASN1; 839 } else if (check_for_pem(buf, fmt) == TRUE) { 840 goto end; 841 } else { 842 /* Cannot determine this file format */ 843 *fmt = 0; 844 ret = KMF_ERR_ENCODING; 845 } 846 847 end: 848 KMF_FreeData(&filebuf); 849 return (ret); 850 } 851 852 KMF_RETURN 853 KMF_HexString2Bytes(unsigned char *hexstr, unsigned char **bytes, 854 size_t *outlen) 855 { 856 KMF_RETURN ret = KMF_OK; 857 unsigned char *buf = NULL; 858 int len, stringlen; 859 int i; 860 unsigned char ch; 861 862 if (hexstr == NULL) { 863 return (KMF_ERR_BAD_PARAMETER); 864 } 865 866 if (hexstr[0] == '0' && 867 ((hexstr[1] == 'x') || (hexstr[1] == 'X'))) 868 hexstr += 2; 869 870 for (i = 0; i < strlen((char *)hexstr) && isxdigit(hexstr[i]); i++); 871 /* 872 * If all the characters are not legitimate hex chars, 873 * return an error. 874 */ 875 if (i != strlen((char *)hexstr)) 876 return (KMF_ERR_BAD_HEX_STRING); 877 stringlen = i; 878 len = (i / 2) + (i % 2); 879 880 buf = malloc(len); 881 if (buf == NULL) { 882 return (KMF_ERR_MEMORY); 883 } 884 (void) memset(buf, 0, len); 885 886 for (i = 0; i < stringlen; i++) { 887 ch = (unsigned char) *hexstr; 888 hexstr++; 889 if ((ch >= '0') && (ch <= '9')) 890 ch -= '0'; 891 else if ((ch >= 'A') && (ch <= 'F')) 892 ch = ch - 'A' + 10; 893 else if ((ch >= 'a') && (ch <= 'f')) 894 ch = ch - 'a' + 10; 895 else { 896 ret = KMF_ERR_BAD_HEX_STRING; 897 goto out; 898 } 899 900 if (i & 1) { 901 buf[i/2] |= ch; 902 } else { 903 buf[i/2] = (ch << 4); 904 } 905 } 906 907 *bytes = buf; 908 *outlen = len; 909 out: 910 if (buf != NULL && ret != KMF_OK) { 911 free(buf); 912 } 913 return (ret); 914 } 915 916 void 917 KMF_FreeDN(KMF_X509_NAME *name) 918 { 919 KMF_X509_RDN *newrdn = NULL; 920 KMF_X509_TYPE_VALUE_PAIR *av = NULL; 921 int i, j; 922 923 if (name && name->numberOfRDNs) { 924 for (i = 0; i < name->numberOfRDNs; i++) { 925 newrdn = &name->RelativeDistinguishedName[i]; 926 for (j = 0; j < newrdn->numberOfPairs; j++) { 927 av = &newrdn->AttributeTypeAndValue[j]; 928 KMF_FreeData(&av->type); 929 KMF_FreeData(&av->value); 930 } 931 free(newrdn->AttributeTypeAndValue); 932 newrdn->numberOfPairs = 0; 933 newrdn->AttributeTypeAndValue = NULL; 934 } 935 free(name->RelativeDistinguishedName); 936 name->numberOfRDNs = 0; 937 name->RelativeDistinguishedName = NULL; 938 } 939 } 940 941 void 942 KMF_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert) 943 { 944 KMF_PLUGIN *plugin; 945 KMF_RETURN ret; 946 947 CLEAR_ERROR(handle, ret); 948 if (ret != KMF_OK) 949 return; 950 951 if (kmf_cert == NULL) 952 return; 953 954 plugin = FindPlugin(handle, kmf_cert->kmf_private.keystore_type); 955 956 if (plugin != NULL && plugin->funclist->FreeKMFCert != NULL) { 957 plugin->funclist->FreeKMFCert(handle, kmf_cert); 958 } 959 } 960 961 void 962 KMF_FreeData(KMF_DATA *datablock) 963 { 964 if (datablock != NULL && datablock->Data != NULL) { 965 free(datablock->Data); 966 datablock->Data = NULL; 967 datablock->Length = 0; 968 } 969 } 970 971 void 972 KMF_FreeAlgOID(KMF_X509_ALGORITHM_IDENTIFIER *algoid) 973 { 974 if (algoid == NULL) 975 return; 976 KMF_FreeData(&algoid->algorithm); 977 KMF_FreeData(&algoid->parameters); 978 } 979 980 void 981 KMF_FreeExtension(KMF_X509_EXTENSION *exptr) 982 { 983 if (exptr == NULL) 984 return; 985 986 KMF_FreeData((KMF_DATA *)&exptr->extnId); 987 KMF_FreeData(&exptr->BERvalue); 988 989 if (exptr->value.tagAndValue) { 990 KMF_FreeData(&exptr->value.tagAndValue->value); 991 free(exptr->value.tagAndValue); 992 } 993 } 994 995 void 996 KMF_FreeTBSCSR(KMF_TBS_CSR *tbscsr) 997 { 998 if (tbscsr) { 999 KMF_FreeData(&tbscsr->version); 1000 1001 KMF_FreeDN(&tbscsr->subject); 1002 1003 KMF_FreeAlgOID(&tbscsr->subjectPublicKeyInfo.algorithm); 1004 KMF_FreeData(&tbscsr->subjectPublicKeyInfo.subjectPublicKey); 1005 1006 free_extensions(&tbscsr->extensions); 1007 } 1008 } 1009 1010 void 1011 KMF_FreeSignedCSR(KMF_CSR_DATA *csr) 1012 { 1013 if (csr) { 1014 KMF_FreeTBSCSR(&csr->csr); 1015 1016 KMF_FreeAlgOID(&csr->signature.algorithmIdentifier); 1017 KMF_FreeData(&csr->signature.encrypted); 1018 } 1019 } 1020 1021 static void 1022 free_validity(KMF_X509_VALIDITY *validity) 1023 { 1024 if (validity == NULL) 1025 return; 1026 KMF_FreeData(&validity->notBefore.time); 1027 KMF_FreeData(&validity->notAfter.time); 1028 } 1029 1030 static void 1031 free_extensions(KMF_X509_EXTENSIONS *extns) 1032 { 1033 int i; 1034 KMF_X509_EXTENSION *exptr; 1035 1036 if (extns && extns->numberOfExtensions > 0) { 1037 for (i = 0; i < extns->numberOfExtensions; i++) { 1038 exptr = &extns->extensions[i]; 1039 KMF_FreeExtension(exptr); 1040 } 1041 free(extns->extensions); 1042 extns->numberOfExtensions = 0; 1043 extns->extensions = NULL; 1044 } 1045 } 1046 1047 void 1048 KMF_FreeTBSCert(KMF_X509_TBS_CERT *tbscert) 1049 { 1050 if (tbscert) { 1051 KMF_FreeData(&tbscert->version); 1052 KMF_FreeBigint(&tbscert->serialNumber); 1053 KMF_FreeAlgOID(&tbscert->signature); 1054 1055 KMF_FreeDN(&tbscert->issuer); 1056 KMF_FreeDN(&tbscert->subject); 1057 1058 free_validity(&tbscert->validity); 1059 1060 KMF_FreeData(&tbscert->issuerUniqueIdentifier); 1061 KMF_FreeData(&tbscert->subjectUniqueIdentifier); 1062 1063 KMF_FreeAlgOID(&tbscert->subjectPublicKeyInfo.algorithm); 1064 KMF_FreeData(&tbscert->subjectPublicKeyInfo.subjectPublicKey); 1065 1066 free_extensions(&tbscert->extensions); 1067 1068 KMF_FreeData(&tbscert->issuerUniqueIdentifier); 1069 KMF_FreeData(&tbscert->subjectUniqueIdentifier); 1070 } 1071 } 1072 1073 void 1074 KMF_FreeSignedCert(KMF_X509_CERTIFICATE *certptr) 1075 { 1076 if (!certptr) 1077 return; 1078 1079 KMF_FreeTBSCert(&certptr->certificate); 1080 1081 KMF_FreeAlgOID(&certptr->signature.algorithmIdentifier); 1082 KMF_FreeData(&certptr->signature.encrypted); 1083 } 1084 1085 void 1086 KMF_FreeString(char *pstr) 1087 { 1088 if (pstr != NULL) 1089 free(pstr); 1090 } 1091 1092 void 1093 free_keyidlist(KMF_OID *oidlist, int len) 1094 { 1095 int i; 1096 for (i = 0; i < len; i++) { 1097 KMF_FreeData((KMF_DATA *)&oidlist[i]); 1098 } 1099 free(oidlist); 1100 } 1101 1102 void 1103 KMF_FreeEKU(KMF_X509EXT_EKU *eptr) 1104 { 1105 if (eptr && eptr->nEKUs > 0 && 1106 eptr->keyPurposeIdList != NULL) 1107 free_keyidlist(eptr->keyPurposeIdList, eptr->nEKUs); 1108 } 1109 1110 void 1111 KMF_FreeSPKI(KMF_X509_SPKI *spki) 1112 { 1113 if (spki != NULL) { 1114 KMF_FreeAlgOID(&spki->algorithm); 1115 KMF_FreeData(&spki->subjectPublicKey); 1116 } 1117 } 1118 1119 void 1120 KMF_FreeKMFKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key) 1121 { 1122 KMF_PLUGIN *plugin; 1123 KMF_RETURN ret; 1124 1125 CLEAR_ERROR(handle, ret); 1126 if (ret != KMF_OK) 1127 return; 1128 1129 if (key == NULL) 1130 return; 1131 1132 plugin = FindPlugin(handle, key->kstype); 1133 if (plugin != NULL && plugin->funclist->DeleteKey != NULL) { 1134 (void) plugin->funclist->DeleteKey(handle, NULL, key, FALSE); 1135 } 1136 1137 if (key == NULL) 1138 return; 1139 1140 if (key->keylabel) 1141 free(key->keylabel); 1142 1143 if (key->israw) { 1144 KMF_FreeRawKey(key->keyp); 1145 free(key->keyp); 1146 } 1147 1148 (void) memset(key, 0, sizeof (KMF_KEY_HANDLE)); 1149 } 1150 1151 void 1152 KMF_FreeBigint(KMF_BIGINT *big) 1153 { 1154 if (big != NULL && big->val != NULL) { 1155 /* Clear it out before returning it to the pool */ 1156 (void) memset(big->val, 0x00, big->len); 1157 free(big->val); 1158 big->val = NULL; 1159 big->len = 0; 1160 } 1161 } 1162 1163 static void 1164 free_raw_rsa(KMF_RAW_RSA_KEY *key) 1165 { 1166 if (key == NULL) 1167 return; 1168 KMF_FreeBigint(&key->mod); 1169 KMF_FreeBigint(&key->pubexp); 1170 KMF_FreeBigint(&key->priexp); 1171 KMF_FreeBigint(&key->prime1); 1172 KMF_FreeBigint(&key->prime2); 1173 KMF_FreeBigint(&key->exp1); 1174 KMF_FreeBigint(&key->exp2); 1175 KMF_FreeBigint(&key->coef); 1176 } 1177 1178 static void 1179 free_raw_dsa(KMF_RAW_DSA_KEY *key) 1180 { 1181 if (key == NULL) 1182 return; 1183 KMF_FreeBigint(&key->prime); 1184 KMF_FreeBigint(&key->subprime); 1185 KMF_FreeBigint(&key->base); 1186 KMF_FreeBigint(&key->value); 1187 } 1188 1189 static void 1190 free_raw_sym(KMF_RAW_SYM_KEY *key) 1191 { 1192 if (key == NULL) 1193 return; 1194 KMF_FreeBigint(&key->keydata); 1195 } 1196 1197 void 1198 KMF_FreeRawKey(KMF_RAW_KEY_DATA *key) 1199 { 1200 if (key == NULL) 1201 return; 1202 1203 switch (key->keytype) { 1204 case KMF_RSA: 1205 free_raw_rsa(&key->rawdata.rsa); 1206 break; 1207 case KMF_DSA: 1208 free_raw_dsa(&key->rawdata.dsa); 1209 break; 1210 case KMF_AES: 1211 case KMF_RC4: 1212 case KMF_DES: 1213 case KMF_DES3: 1214 free_raw_sym(&key->rawdata.sym); 1215 break; 1216 } 1217 } 1218 1219 void 1220 KMF_FreeRawSymKey(KMF_RAW_SYM_KEY *key) 1221 { 1222 if (key == NULL) 1223 return; 1224 KMF_FreeBigint(&key->keydata); 1225 free(key); 1226 } 1227 1228 /* 1229 * This function frees the space allocated for the name portion of a 1230 * KMF_CRL_DIST_POINT. 1231 */ 1232 void 1233 free_dp_name(KMF_CRL_DIST_POINT *dp) 1234 { 1235 KMF_GENERALNAMES *fullname; 1236 KMF_DATA *urldata; 1237 int i; 1238 1239 if (dp == NULL) 1240 return; 1241 1242 /* For phase 1, we only need to free the fullname space. */ 1243 fullname = &(dp->name.full_name); 1244 if (fullname->number == 0) 1245 return; 1246 1247 for (i = 0; i < fullname->number; i++) { 1248 urldata = &(fullname->namelist[fullname->number - 1].name); 1249 KMF_FreeData(urldata); 1250 } 1251 1252 free(fullname->namelist); 1253 } 1254 1255 /* 1256 * This function frees the space allocated for a KMF_CRL_DIST_POINT. 1257 */ 1258 void 1259 free_dp(KMF_CRL_DIST_POINT *dp) 1260 { 1261 if (dp == NULL) 1262 return; 1263 1264 free_dp_name(dp); 1265 KMF_FreeData(&(dp->reasons)); 1266 /* Need not to free crl_issuer space at phase 1 */ 1267 } 1268 1269 /* 1270 * This function frees space for a KMF_X509EXT_CRLDISTPOINTS internally. 1271 */ 1272 void 1273 KMF_FreeCRLDistributionPoints(KMF_X509EXT_CRLDISTPOINTS *crl_dps) 1274 { 1275 int i; 1276 1277 if (crl_dps == NULL) 1278 return; 1279 1280 for (i = 0; i < crl_dps->number; i++) 1281 free_dp(&(crl_dps->dplist[i])); 1282 1283 free(crl_dps->dplist); 1284 } 1285 1286 KMF_RETURN 1287 KMF_CreateOCSPRequest(KMF_HANDLE_T handle, KMF_OCSPREQUEST_PARAMS *params, 1288 char *reqfile) 1289 { 1290 KMF_PLUGIN *plugin; 1291 KMF_RETURN (*createReqFn)(void *, KMF_OCSPREQUEST_PARAMS *params, 1292 char *reqfile); 1293 KMF_RETURN ret; 1294 1295 CLEAR_ERROR(handle, ret); 1296 if (ret != KMF_OK) 1297 return (ret); 1298 1299 1300 if (params == NULL || 1301 reqfile == NULL) 1302 return (KMF_ERR_BAD_PARAMETER); 1303 1304 /* 1305 * This framework function is actually implemented in the openssl 1306 * plugin library, so we find the function address and call it. 1307 */ 1308 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 1309 if (plugin == NULL || plugin->dldesc == NULL) { 1310 return (KMF_ERR_PLUGIN_NOTFOUND); 1311 } 1312 1313 createReqFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, 1314 "OpenSSL_CreateOCSPRequest"); 1315 if (createReqFn == NULL) { 1316 return (KMF_ERR_FUNCTION_NOT_FOUND); 1317 } 1318 1319 return (createReqFn(handle, params, reqfile)); 1320 } 1321 1322 KMF_RETURN 1323 KMF_GetOCSPStatusForCert(KMF_HANDLE_T handle, 1324 KMF_OCSPRESPONSE_PARAMS_INPUT *params_in, 1325 KMF_OCSPRESPONSE_PARAMS_OUTPUT *params_out) 1326 { 1327 KMF_PLUGIN *plugin; 1328 KMF_RETURN (*getCertStatusFn)(void *, 1329 KMF_OCSPRESPONSE_PARAMS_INPUT *params_in, 1330 KMF_OCSPRESPONSE_PARAMS_OUTPUT *params_out); 1331 KMF_RETURN ret; 1332 1333 CLEAR_ERROR(handle, ret); 1334 if (ret != KMF_OK) 1335 return (ret); 1336 1337 1338 if (params_in == NULL || 1339 params_out == NULL) 1340 return (KMF_ERR_BAD_PARAMETER); 1341 1342 /* 1343 * This framework function is actually implemented in the openssl 1344 * plugin library, so we find the function address and call it. 1345 */ 1346 plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL); 1347 if (plugin == NULL || plugin->dldesc == NULL) { 1348 return (KMF_ERR_INTERNAL); 1349 } 1350 1351 getCertStatusFn = (KMF_RETURN(*)())dlsym(plugin->dldesc, 1352 "OpenSSL_GetOCSPStatusForCert"); 1353 if (getCertStatusFn == NULL) { 1354 return (KMF_ERR_INTERNAL); 1355 } 1356 1357 return (getCertStatusFn(handle, params_in, params_out)); 1358 } 1359 1360 KMF_RETURN 1361 KMF_String2OID(char *oidstring, KMF_OID *oid) 1362 { 1363 KMF_RETURN rv = KMF_OK; 1364 char *cp, *bp, *startp; 1365 int numbuf; 1366 int onumbuf; 1367 int nbytes, index; 1368 int len; 1369 unsigned char *op; 1370 1371 if (oidstring == NULL || oid == NULL) 1372 return (KMF_ERR_BAD_PARAMETER); 1373 1374 len = strlen(oidstring); 1375 1376 bp = oidstring; 1377 cp = bp; 1378 /* Skip over leading space */ 1379 while ((bp < &cp[len]) && isspace(*bp)) 1380 bp++; 1381 1382 startp = bp; 1383 nbytes = 0; 1384 1385 /* 1386 * The first two numbers are chewed up by the first octet. 1387 */ 1388 if (sscanf(bp, "%d", &numbuf) != 1) 1389 return (KMF_ERR_BAD_PARAMETER); 1390 while ((bp < &cp[len]) && isdigit(*bp)) 1391 bp++; 1392 while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 1393 bp++; 1394 if (sscanf(bp, "%d", &numbuf) != 1) 1395 return (KMF_ERR_BAD_PARAMETER); 1396 while ((bp < &cp[len]) && isdigit(*bp)) 1397 bp++; 1398 while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 1399 bp++; 1400 nbytes++; 1401 1402 while (isdigit(*bp)) { 1403 if (sscanf(bp, "%d", &numbuf) != 1) 1404 return (KMF_ERR_BAD_PARAMETER); 1405 while (numbuf) { 1406 nbytes++; 1407 numbuf >>= 7; 1408 } 1409 while ((bp < &cp[len]) && isdigit(*bp)) 1410 bp++; 1411 while ((bp < &cp[len]) && (isspace(*bp) || *bp == '.')) 1412 bp++; 1413 } 1414 1415 oid->Length = nbytes; 1416 oid->Data = malloc(oid->Length); 1417 if (oid->Data == NULL) { 1418 return (KMF_ERR_MEMORY); 1419 } 1420 (void) memset(oid->Data, 0, oid->Length); 1421 1422 op = oid->Data; 1423 1424 bp = startp; 1425 (void) sscanf(bp, "%d", &numbuf); 1426 1427 while (isdigit(*bp)) bp++; 1428 while (isspace(*bp) || *bp == '.') bp++; 1429 1430 onumbuf = 40 * numbuf; 1431 (void) sscanf(bp, "%d", &numbuf); 1432 onumbuf += numbuf; 1433 *op = (unsigned char) onumbuf; 1434 op++; 1435 1436 while (isdigit(*bp)) bp++; 1437 while (isspace(*bp) || *bp == '.') bp++; 1438 while (isdigit(*bp)) { 1439 (void) sscanf(bp, "%d", &numbuf); 1440 nbytes = 0; 1441 /* Have to fill in the bytes msb-first */ 1442 onumbuf = numbuf; 1443 while (numbuf) { 1444 nbytes++; 1445 numbuf >>= 7; 1446 } 1447 numbuf = onumbuf; 1448 op += nbytes; 1449 index = -1; 1450 while (numbuf) { 1451 op[index] = (unsigned char)numbuf & 0x7f; 1452 if (index != -1) 1453 op[index] |= 0x80; 1454 index--; 1455 numbuf >>= 7; 1456 } 1457 while (isdigit(*bp)) bp++; 1458 while (isspace(*bp) || *bp == '.') bp++; 1459 } 1460 1461 return (rv); 1462 } 1463 1464 static KMF_RETURN 1465 encode_rid(char *name, KMF_DATA *derdata) 1466 { 1467 KMF_RETURN rv = KMF_OK; 1468 1469 if (name == NULL || derdata == NULL) 1470 return (KMF_ERR_BAD_PARAMETER); 1471 1472 rv = KMF_String2OID(name, (KMF_OID *)derdata); 1473 1474 return (rv); 1475 } 1476 1477 static KMF_RETURN 1478 encode_ipaddr(char *name, KMF_DATA *derdata) 1479 { 1480 KMF_RETURN rv = KMF_OK; 1481 size_t len; 1482 in_addr_t v4; 1483 in6_addr_t v6; 1484 uint8_t *ptr; 1485 1486 if (name == NULL || derdata == NULL) 1487 return (KMF_ERR_BAD_PARAMETER); 1488 1489 v4 = inet_addr(name); 1490 if (v4 == (in_addr_t)-1) { 1491 ptr = (uint8_t *)&v6; 1492 if (inet_pton(AF_INET6, name, ptr) != 1) 1493 return (KMF_ERR_ENCODING); 1494 len = sizeof (v6); 1495 } else { 1496 ptr = (uint8_t *)&v4; 1497 len = sizeof (v4); 1498 } 1499 1500 derdata->Data = malloc(len); 1501 if (derdata->Data == NULL) 1502 return (KMF_ERR_MEMORY); 1503 (void) memcpy(derdata->Data, ptr, len); 1504 derdata->Length = len; 1505 1506 return (rv); 1507 } 1508 1509 static KMF_RETURN 1510 verify_uri_format(char *uristring) 1511 { 1512 KMF_RETURN ret = KMF_OK; 1513 xmlURIPtr uriptr = NULL; 1514 1515 /* Parse the URI string; get the hostname and port */ 1516 uriptr = xmlParseURI(uristring); 1517 if (uriptr == NULL) { 1518 ret = KMF_ERR_BAD_URI; 1519 goto out; 1520 } 1521 1522 if (uriptr->scheme == NULL || !strlen(uriptr->scheme)) { 1523 ret = KMF_ERR_BAD_URI; 1524 goto out; 1525 } 1526 1527 if (uriptr->server == NULL || !strlen(uriptr->server)) { 1528 ret = KMF_ERR_BAD_URI; 1529 goto out; 1530 } 1531 out: 1532 if (uriptr != NULL) 1533 xmlFreeURI(uriptr); 1534 return (ret); 1535 } 1536 1537 static KMF_RETURN 1538 encode_altname(char *namedata, 1539 KMF_GENERALNAMECHOICES nametype, KMF_DATA *encodedname) 1540 { 1541 KMF_RETURN ret = KMF_OK; 1542 KMF_X509_NAME dnname; 1543 uchar_t tagval; 1544 BerElement *asn1 = NULL; 1545 BerValue *extdata; 1546 1547 if (namedata == NULL || encodedname == NULL) 1548 return (KMF_ERR_BAD_PARAMETER); 1549 1550 /* 1551 * Encode the namedata according to rules in RFC 3280 for GeneralName. 1552 * The input "namedata" is assumed to be an ASCII string representation 1553 * of the AltName, we need to convert it to correct ASN.1 here before 1554 * adding it to the cert. 1555 */ 1556 switch (nametype) { 1557 case GENNAME_RFC822NAME: /* rfc 822 */ 1558 /* IA5String, no encoding needed */ 1559 encodedname->Data = (uchar_t *)strdup(namedata); 1560 if (encodedname->Data == NULL) 1561 return (KMF_ERR_MEMORY); 1562 encodedname->Length = strlen(namedata); 1563 tagval = (0x80 | nametype); 1564 break; 1565 case GENNAME_DNSNAME: /* rfc 1034 */ 1566 encodedname->Data = (uchar_t *)strdup(namedata); 1567 if (encodedname->Data == NULL) 1568 return (KMF_ERR_MEMORY); 1569 encodedname->Length = strlen(namedata); 1570 tagval = (0x80 | nametype); 1571 break; 1572 case GENNAME_URI: /* rfc 1738 */ 1573 ret = verify_uri_format(namedata); 1574 if (ret != KMF_OK) 1575 return (ret); 1576 /* IA5String, no encoding needed */ 1577 encodedname->Data = (uchar_t *)strdup(namedata); 1578 if (encodedname->Data == NULL) 1579 return (KMF_ERR_MEMORY); 1580 encodedname->Length = strlen(namedata); 1581 tagval = (0x80 | nametype); 1582 break; 1583 case GENNAME_IPADDRESS: 1584 ret = encode_ipaddr(namedata, encodedname); 1585 tagval = (0x80 | nametype); 1586 break; 1587 case GENNAME_REGISTEREDID: 1588 ret = encode_rid(namedata, encodedname); 1589 tagval = (0x80 | nametype); 1590 break; 1591 case GENNAME_DIRECTORYNAME: 1592 ret = KMF_DNParser(namedata, &dnname); 1593 if (ret == KMF_OK) { 1594 ret = KMF_DN2Der(&dnname, encodedname); 1595 } 1596 (void) KMF_FreeDN(&dnname); 1597 tagval = (0xA0 | nametype); 1598 break; 1599 default: 1600 /* unsupported */ 1601 return (KMF_ERR_BAD_PARAMETER); 1602 1603 } 1604 if (ret != KMF_OK) { 1605 KMF_FreeData(encodedname); 1606 return (ret); 1607 } 1608 1609 if ((asn1 = kmfder_alloc()) == NULL) 1610 return (KMF_ERR_MEMORY); 1611 1612 if (kmfber_printf(asn1, "Tl", 1613 tagval, encodedname->Length) == -1) 1614 goto cleanup; 1615 1616 if (kmfber_write(asn1, (char *)encodedname->Data, 1617 encodedname->Length, 0) == -1) { 1618 ret = KMF_ERR_ENCODING; 1619 goto cleanup; 1620 } 1621 if (kmfber_flatten(asn1, &extdata) == -1) { 1622 ret = KMF_ERR_ENCODING; 1623 goto cleanup; 1624 } 1625 1626 KMF_FreeData(encodedname); 1627 encodedname->Data = (uchar_t *)extdata->bv_val; 1628 encodedname->Length = extdata->bv_len; 1629 1630 free(extdata); 1631 1632 cleanup: 1633 if (asn1) 1634 kmfber_free(asn1, 1); 1635 1636 if (ret != KMF_OK) 1637 KMF_FreeData(encodedname); 1638 1639 return (ret); 1640 } 1641 1642 KMF_X509_EXTENSION * 1643 FindExtn(KMF_X509_EXTENSIONS *exts, KMF_OID *oid) 1644 { 1645 KMF_X509_EXTENSION *foundextn = NULL; 1646 int i; 1647 1648 if (exts == NULL || oid == NULL) 1649 return (NULL); 1650 1651 for (i = 0; i < exts->numberOfExtensions; i++) { 1652 if (IsEqualOid(oid, &exts->extensions[i].extnId)) { 1653 foundextn = &exts->extensions[i]; 1654 break; 1655 } 1656 } 1657 return (foundextn); 1658 } 1659 1660 KMF_RETURN 1661 GetSequenceContents(char *data, size_t len, 1662 char **contents, size_t *outlen) 1663 { 1664 KMF_RETURN ret = KMF_OK; 1665 BerElement *exasn1 = NULL; 1666 BerValue oldextn; 1667 int tag; 1668 size_t oldsize; 1669 char *olddata = NULL; 1670 1671 if (data == NULL || contents == NULL || outlen == NULL) 1672 return (KMF_ERR_BAD_PARAMETER); 1673 1674 /* 1675 * Decode the sequence of general names 1676 */ 1677 oldextn.bv_val = data; 1678 oldextn.bv_len = len; 1679 1680 if ((exasn1 = kmfder_init(&oldextn)) == NULL) { 1681 ret = KMF_ERR_MEMORY; 1682 goto out; 1683 } 1684 1685 /* 1686 * Unwrap the sequence to find the size of the block 1687 * of GeneralName items in the set. 1688 * 1689 * Peek at the tag and length ("tl"), 1690 * then consume them ("{"). 1691 */ 1692 if (kmfber_scanf(exasn1, "tl{", &tag, &oldsize) == KMFBER_DEFAULT || 1693 oldsize == 0) { 1694 ret = KMF_ERR_ENCODING; 1695 goto out; 1696 } 1697 1698 olddata = malloc(oldsize); 1699 if (olddata == NULL) { 1700 ret = KMF_ERR_MEMORY; 1701 goto out; 1702 } 1703 (void) memset(olddata, 0, oldsize); 1704 /* 1705 * Read the entire blob of GeneralNames, we don't 1706 * need to interpret them now. 1707 */ 1708 if (kmfber_read(exasn1, olddata, oldsize) != oldsize) { 1709 ret = KMF_ERR_ENCODING; 1710 goto out; 1711 } 1712 out: 1713 if (exasn1 != NULL) 1714 kmfber_free(exasn1, 1); 1715 1716 if (ret != KMF_OK) { 1717 *contents = NULL; 1718 *outlen = 0; 1719 if (olddata != NULL) 1720 free(olddata); 1721 } else { 1722 *contents = olddata; 1723 *outlen = oldsize; 1724 } 1725 return (ret); 1726 } 1727 1728 KMF_RETURN 1729 add_an_extension(KMF_X509_EXTENSIONS *exts, KMF_X509_EXTENSION *newextn) 1730 { 1731 KMF_RETURN ret = KMF_OK; 1732 KMF_X509_EXTENSION *extlist; 1733 1734 if (exts == NULL || newextn == NULL) 1735 return (KMF_ERR_BAD_PARAMETER); 1736 1737 extlist = malloc(sizeof (KMF_X509_EXTENSION) * 1738 (exts->numberOfExtensions + 1)); 1739 if (extlist == NULL) 1740 return (KMF_ERR_MEMORY); 1741 1742 (void) memcpy(extlist, exts->extensions, 1743 exts->numberOfExtensions * sizeof (KMF_X509_EXTENSION)); 1744 1745 (void) memcpy(&extlist[exts->numberOfExtensions], newextn, 1746 sizeof (KMF_X509_EXTENSION)); 1747 1748 free(exts->extensions); 1749 exts->numberOfExtensions++; 1750 exts->extensions = extlist; 1751 1752 return (ret); 1753 } 1754 1755 KMF_RETURN 1756 KMF_SetAltName(KMF_X509_EXTENSIONS *extensions, 1757 KMF_OID *oid, 1758 int critical, 1759 KMF_GENERALNAMECHOICES nametype, 1760 char *namedata) 1761 { 1762 KMF_RETURN ret = KMF_OK; 1763 KMF_X509_EXTENSION subjAltName; 1764 KMF_DATA dername = { NULL, 0 }; 1765 BerElement *asn1 = NULL; 1766 BerValue *extdata; 1767 char *olddata = NULL; 1768 KMF_X509_EXTENSION *foundextn = NULL; 1769 size_t oldsize = 0; 1770 1771 if (extensions == NULL || oid == NULL || namedata == NULL) 1772 return (KMF_ERR_BAD_PARAMETER); 1773 1774 ret = encode_altname(namedata, nametype, &dername); 1775 1776 if (ret != KMF_OK) 1777 return (ret); 1778 1779 (void) memset(&subjAltName, 0, sizeof (subjAltName)); 1780 1781 ret = copy_data(&subjAltName.extnId, oid); 1782 if (ret != KMF_OK) 1783 goto out; 1784 /* 1785 * Check to see if this cert already has a subjectAltName. 1786 */ 1787 foundextn = FindExtn(extensions, oid); 1788 1789 if (foundextn != NULL) { 1790 ret = GetSequenceContents( 1791 (char *)foundextn->BERvalue.Data, 1792 foundextn->BERvalue.Length, 1793 &olddata, &oldsize); 1794 if (ret != KMF_OK) 1795 goto out; 1796 } 1797 1798 /* 1799 * Assume (!!) that the namedata given is already properly encoded. 1800 */ 1801 if ((asn1 = kmfder_alloc()) == NULL) 1802 return (KMF_ERR_MEMORY); 1803 1804 if (kmfber_printf(asn1, "{") == -1) { 1805 ret = KMF_ERR_ENCODING; 1806 goto out; 1807 } 1808 1809 /* Write the old extension data first */ 1810 if (olddata != NULL && oldsize > 0) { 1811 if (kmfber_write(asn1, olddata, oldsize, 0) == -1) { 1812 ret = KMF_ERR_ENCODING; 1813 goto out; 1814 } 1815 } 1816 1817 /* Now add the new name to the list */ 1818 if (kmfber_write(asn1, (char *)dername.Data, dername.Length, 0) == -1) { 1819 ret = KMF_ERR_ENCODING; 1820 goto out; 1821 } 1822 1823 /* Now close the sequence */ 1824 if (kmfber_printf(asn1, "}") == -1) { 1825 ret = KMF_ERR_ENCODING; 1826 goto out; 1827 } 1828 if (kmfber_flatten(asn1, &extdata) == -1) { 1829 ret = KMF_ERR_ENCODING; 1830 goto out; 1831 } 1832 1833 /* 1834 * If we are just adding to an existing list of altNames, 1835 * just replace the BER data associated with the found extension. 1836 */ 1837 if (foundextn != NULL) { 1838 free(foundextn->BERvalue.Data); 1839 foundextn->critical = critical; 1840 foundextn->BERvalue.Data = (uchar_t *)extdata->bv_val; 1841 foundextn->BERvalue.Length = extdata->bv_len; 1842 } else { 1843 subjAltName.critical = critical; 1844 subjAltName.format = KMF_X509_DATAFORMAT_ENCODED; 1845 subjAltName.BERvalue.Data = (uchar_t *)extdata->bv_val; 1846 subjAltName.BERvalue.Length = extdata->bv_len; 1847 ret = add_an_extension(extensions, &subjAltName); 1848 if (ret != KMF_OK) 1849 free(subjAltName.BERvalue.Data); 1850 } 1851 1852 free(extdata); 1853 out: 1854 if (olddata != NULL) 1855 free(olddata); 1856 1857 KMF_FreeData(&dername); 1858 if (ret != KMF_OK) 1859 KMF_FreeData(&subjAltName.extnId); 1860 if (asn1 != NULL) 1861 kmfber_free(asn1, 1); 1862 return (ret); 1863 } 1864