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