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