1 /* 2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 /* 6 * Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL 7 * project 2000. 8 */ 9 /* 10 * ==================================================================== 11 * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in 22 * the documentation and/or other materials provided with the 23 * distribution. 24 * 25 * 3. All advertising materials mentioning features or use of this 26 * software must display the following acknowledgment: 27 * "This product includes software developed by the OpenSSL Project 28 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 29 * 30 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 31 * endorse or promote products derived from this software without 32 * prior written permission. For written permission, please contact 33 * licensing@OpenSSL.org. 34 * 35 * 5. Products derived from this software may not be called "OpenSSL" 36 * nor may "OpenSSL" appear in their names without prior written 37 * permission of the OpenSSL Project. 38 * 39 * 6. Redistributions of any form whatsoever must retain the following 40 * acknowledgment: 41 * "This product includes software developed by the OpenSSL Project 42 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 43 * 44 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 45 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 47 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 48 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 49 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 50 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 51 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 53 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 54 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 55 * OF THE POSSIBILITY OF SUCH DAMAGE. 56 * ==================================================================== 57 * 58 * This product includes cryptographic software written by Eric Young 59 * (eay@cryptsoft.com). This product includes software written by Tim 60 * Hudson (tjh@cryptsoft.com). 61 * 62 */ 63 64 #pragma ident "%Z%%M% %I% %E% SMI" 65 66 #include <stdlib.h> 67 #include <kmfapiP.h> 68 #include <ber_der.h> 69 #include <fcntl.h> 70 #include <sys/stat.h> 71 #include <dirent.h> 72 #include <cryptoutil.h> 73 #include <synch.h> 74 #include <thread.h> 75 76 /* OPENSSL related headers */ 77 #include <openssl/bio.h> 78 #include <openssl/bn.h> 79 #include <openssl/asn1.h> 80 #include <openssl/err.h> 81 #include <openssl/bn.h> 82 #include <openssl/x509.h> 83 #include <openssl/rsa.h> 84 #include <openssl/dsa.h> 85 #include <openssl/x509v3.h> 86 #include <openssl/objects.h> 87 #include <openssl/pem.h> 88 #include <openssl/pkcs12.h> 89 #include <openssl/ocsp.h> 90 #include <openssl/des.h> 91 #include <openssl/rand.h> 92 93 #define PRINT_ANY_EXTENSION (\ 94 KMF_X509_EXT_KEY_USAGE |\ 95 KMF_X509_EXT_CERT_POLICIES |\ 96 KMF_X509_EXT_SUBJALTNAME |\ 97 KMF_X509_EXT_BASIC_CONSTRAINTS |\ 98 KMF_X509_EXT_NAME_CONSTRAINTS |\ 99 KMF_X509_EXT_POLICY_CONSTRAINTS |\ 100 KMF_X509_EXT_EXT_KEY_USAGE |\ 101 KMF_X509_EXT_INHIBIT_ANY_POLICY |\ 102 KMF_X509_EXT_AUTH_KEY_ID |\ 103 KMF_X509_EXT_SUBJ_KEY_ID |\ 104 KMF_X509_EXT_POLICY_MAPPING) 105 106 static uchar_t P[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 107 0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69, 108 0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c, 109 0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 110 0xe5, 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 111 0xaf, 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a, 112 0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24, 113 0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 114 0x91 }; 115 116 static uchar_t Q[] = { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 117 0xee, 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4, 118 0x8e, 0xda, 0xce, 0x91, 0x5f }; 119 120 static uchar_t G[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 121 0x13, 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5, 122 0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef, 123 0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 124 0x2e, 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 125 0xbf, 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c, 126 0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08, 127 0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 128 0x02 }; 129 130 #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_OPENSSL; \ 131 h->lasterr.errcode = c; 132 133 #define SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c; 134 135 mutex_t init_lock = DEFAULTMUTEX; 136 static int ssl_initialized = 0; 137 static BIO *bio_err = NULL; 138 139 static int 140 test_for_file(char *, mode_t); 141 142 static KMF_RETURN 143 extract_pem(KMF_HANDLE *, char *, char *, KMF_BIGINT *, char *, 144 CK_UTF8CHAR *, CK_ULONG, EVP_PKEY **, KMF_DATA **, int *); 145 146 static KMF_RETURN 147 kmf_load_cert(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY, 148 char *, KMF_DATA *); 149 150 static KMF_RETURN 151 load_certs(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY, 152 char *, KMF_DATA **, uint32_t *); 153 154 static KMF_RETURN 155 sslBN2KMFBN(BIGNUM *, KMF_BIGINT *); 156 157 static EVP_PKEY * 158 ImportRawRSAKey(KMF_RAW_RSA_KEY *); 159 160 static KMF_RETURN 161 convertToRawKey(EVP_PKEY *, KMF_RAW_KEY_DATA *); 162 163 KMF_RETURN 164 OpenSSL_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 165 166 void 167 OpenSSL_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *); 168 169 KMF_RETURN 170 OpenSSL_StoreCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *); 171 172 KMF_RETURN 173 OpenSSL_DeleteCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *); 174 175 KMF_RETURN 176 OpenSSL_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 177 178 KMF_RETURN 179 OpenSSL_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 180 181 KMF_RETURN 182 OpenSSL_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *); 183 184 KMF_RETURN 185 OpenSSL_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 186 KMF_DATA *, KMF_DATA *); 187 188 KMF_RETURN 189 OpenSSL_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 190 191 KMF_RETURN 192 OpenSSL_ImportCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 193 194 KMF_RETURN 195 OpenSSL_DeleteCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 196 197 KMF_RETURN 198 OpenSSL_ListCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 199 200 KMF_RETURN 201 OpenSSL_FindCertInCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 202 203 KMF_RETURN 204 OpenSSL_CertGetPrintable(KMF_HANDLE_T, const KMF_DATA *, 205 KMF_PRINTABLE_ITEM, char *); 206 207 KMF_RETURN 208 OpenSSL_GetErrorString(KMF_HANDLE_T, char **); 209 210 KMF_RETURN 211 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 212 213 KMF_RETURN 214 OpenSSL_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *, 215 KMF_DATA *, KMF_DATA *); 216 217 KMF_RETURN 218 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 219 220 KMF_RETURN 221 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 222 223 KMF_RETURN 224 OpenSSL_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 225 226 KMF_RETURN 227 OpenSSL_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 228 229 KMF_RETURN 230 OpenSSL_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *); 231 232 KMF_RETURN 233 OpenSSL_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *); 234 235 KMF_RETURN 236 OpenSSL_VerifyCRLFile(KMF_HANDLE_T, char *, KMF_DATA *); 237 238 KMF_RETURN 239 OpenSSL_CheckCRLDate(KMF_HANDLE_T, char *); 240 241 KMF_RETURN 242 OpenSSL_VerifyDataWithCert(KMF_HANDLE_T, KMF_ALGORITHM_INDEX, 243 KMF_DATA *, KMF_DATA *, KMF_DATA *); 244 245 static 246 KMF_PLUGIN_FUNCLIST openssl_plugin_table = 247 { 248 1, /* Version */ 249 NULL, /* ConfigureKeystore */ 250 OpenSSL_FindCert, 251 OpenSSL_FreeKMFCert, 252 OpenSSL_StoreCert, 253 NULL, /* ImportCert */ 254 OpenSSL_ImportCRL, 255 OpenSSL_DeleteCert, 256 OpenSSL_DeleteCRL, 257 OpenSSL_CreateKeypair, 258 OpenSSL_FindKey, 259 OpenSSL_EncodePubKeyData, 260 OpenSSL_SignData, 261 OpenSSL_DeleteKey, 262 OpenSSL_ListCRL, 263 NULL, /* FindCRL */ 264 OpenSSL_FindCertInCRL, 265 OpenSSL_GetErrorString, 266 OpenSSL_FindPrikeyByCert, 267 OpenSSL_DecryptData, 268 OpenSSL_ExportPK12, 269 OpenSSL_CreateSymKey, 270 OpenSSL_GetSymKeyValue, 271 NULL, /* SetTokenPin */ 272 OpenSSL_VerifyDataWithCert, 273 OpenSSL_StoreKey, 274 NULL /* Finalize */ 275 }; 276 277 static mutex_t *lock_cs; 278 static long *lock_count; 279 280 static void 281 /*ARGSUSED*/ 282 locking_cb(int mode, int type, char *file, int line) 283 { 284 if (mode & CRYPTO_LOCK) { 285 (void) mutex_lock(&(lock_cs[type])); 286 lock_count[type]++; 287 } else { 288 (void) mutex_unlock(&(lock_cs[type])); 289 } 290 } 291 292 static unsigned long 293 thread_id() 294 { 295 return ((unsigned long)thr_self()); 296 } 297 298 KMF_PLUGIN_FUNCLIST * 299 KMF_Plugin_Initialize() 300 { 301 int i; 302 303 (void) mutex_lock(&init_lock); 304 if (!ssl_initialized) { 305 OpenSSL_add_all_algorithms(); 306 307 /* Enable error strings for reporting */ 308 ERR_load_crypto_strings(); 309 310 /* 311 * Add support for extension OIDs that are not yet in the 312 * openssl default set. 313 */ 314 (void) OBJ_create("2.5.29.30", "nameConstraints", 315 "X509v3 Name Constraints"); 316 (void) OBJ_create("2.5.29.33", "policyMappings", 317 "X509v3 Policy Mappings"); 318 (void) OBJ_create("2.5.29.36", "policyConstraints", 319 "X509v3 Policy Constraints"); 320 (void) OBJ_create("2.5.29.46", "freshestCRL", 321 "X509v3 Freshest CRL"); 322 (void) OBJ_create("2.5.29.54", "inhibitAnyPolicy", 323 "X509v3 Inhibit Any-Policy"); 324 /* 325 * Set up for thread-safe operation. 326 */ 327 lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t)); 328 if (lock_cs == NULL) { 329 (void) mutex_unlock(&init_lock); 330 return (NULL); 331 } 332 333 lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long)); 334 if (lock_count == NULL) { 335 OPENSSL_free(lock_cs); 336 (void) mutex_unlock(&init_lock); 337 return (NULL); 338 } 339 340 for (i = 0; i < CRYPTO_num_locks(); i++) { 341 lock_count[i] = 0; 342 (void) mutex_init(&lock_cs[i], USYNC_THREAD, NULL); 343 } 344 345 CRYPTO_set_id_callback((unsigned long (*)())thread_id); 346 CRYPTO_set_locking_callback((void (*)())locking_cb); 347 ssl_initialized = 1; 348 } 349 (void) mutex_unlock(&init_lock); 350 351 return (&openssl_plugin_table); 352 } 353 /* 354 * Convert an SSL DN to a KMF DN. 355 */ 356 static KMF_RETURN 357 get_x509_dn(X509_NAME *sslDN, KMF_X509_NAME *kmfDN) 358 { 359 KMF_DATA derdata; 360 KMF_RETURN rv = KMF_OK; 361 uchar_t *tmp; 362 363 /* Convert to raw DER format */ 364 derdata.Length = i2d_X509_NAME(sslDN, NULL); 365 if ((tmp = derdata.Data = (uchar_t *)OPENSSL_malloc(derdata.Length)) 366 == NULL) { 367 return (KMF_ERR_MEMORY); 368 } 369 (void) i2d_X509_NAME(sslDN, &tmp); 370 371 /* Decode to KMF format */ 372 rv = DerDecodeName(&derdata, kmfDN); 373 if (rv != KMF_OK) { 374 rv = KMF_ERR_BAD_CERT_FORMAT; 375 } 376 OPENSSL_free(derdata.Data); 377 378 return (rv); 379 } 380 381 int 382 isdir(char *path) 383 { 384 struct stat s; 385 386 if (stat(path, &s) == -1) 387 return (0); 388 389 return ((s.st_mode & S_IFMT) == S_IFDIR); 390 } 391 392 static KMF_RETURN 393 ssl_cert2KMFDATA(KMF_HANDLE *kmfh, X509 *x509cert, KMF_DATA *cert) 394 { 395 KMF_RETURN rv = KMF_OK; 396 unsigned char *buf = NULL, *p; 397 int len; 398 399 /* 400 * Convert the X509 internal struct to DER encoded data 401 */ 402 if ((len = i2d_X509(x509cert, NULL)) < 0) { 403 SET_ERROR(kmfh, ERR_get_error()); 404 rv = KMF_ERR_BAD_CERT_FORMAT; 405 goto cleanup; 406 } 407 if ((buf = malloc(len)) == NULL) { 408 SET_SYS_ERROR(kmfh, errno); 409 rv = KMF_ERR_MEMORY; 410 goto cleanup; 411 } 412 413 /* 414 * i2d_X509 will increment the buf pointer so that we need to 415 * save it. 416 */ 417 p = buf; 418 if ((len = i2d_X509(x509cert, &p)) < 0) { 419 SET_ERROR(kmfh, ERR_get_error()); 420 free(buf); 421 rv = KMF_ERR_BAD_CERT_FORMAT; 422 goto cleanup; 423 } 424 425 /* caller's responsibility to free it */ 426 cert->Data = buf; 427 cert->Length = len; 428 429 cleanup: 430 if (rv != KMF_OK) { 431 if (buf) 432 free(buf); 433 cert->Data = NULL; 434 cert->Length = 0; 435 } 436 437 return (rv); 438 } 439 440 441 static KMF_RETURN 442 check_cert(X509 *xcert, char *issuer, char *subject, KMF_BIGINT *serial, 443 boolean_t *match) 444 { 445 KMF_RETURN rv = KMF_OK; 446 boolean_t findIssuer = FALSE; 447 boolean_t findSubject = FALSE; 448 boolean_t findSerial = FALSE; 449 KMF_X509_NAME issuerDN, subjectDN; 450 KMF_X509_NAME certIssuerDN, certSubjectDN; 451 452 *match = FALSE; 453 if (xcert == NULL) { 454 return (KMF_ERR_BAD_PARAMETER); 455 } 456 457 (void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME)); 458 (void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME)); 459 (void) memset(&certIssuerDN, 0, sizeof (KMF_X509_NAME)); 460 (void) memset(&certSubjectDN, 0, sizeof (KMF_X509_NAME)); 461 462 if (issuer != NULL && strlen(issuer)) { 463 rv = kmf_dn_parser(issuer, &issuerDN); 464 if (rv != KMF_OK) 465 return (KMF_ERR_BAD_PARAMETER); 466 467 rv = get_x509_dn(xcert->cert_info->issuer, &certIssuerDN); 468 if (rv != KMF_OK) { 469 kmf_free_dn(&issuerDN); 470 return (KMF_ERR_BAD_PARAMETER); 471 } 472 473 findIssuer = TRUE; 474 } 475 if (subject != NULL && strlen(subject)) { 476 rv = kmf_dn_parser(subject, &subjectDN); 477 if (rv != KMF_OK) { 478 rv = KMF_ERR_BAD_PARAMETER; 479 goto cleanup; 480 } 481 482 rv = get_x509_dn(xcert->cert_info->subject, &certSubjectDN); 483 if (rv != KMF_OK) { 484 rv = KMF_ERR_BAD_PARAMETER; 485 goto cleanup; 486 } 487 findSubject = TRUE; 488 } 489 if (serial != NULL && serial->val != NULL) 490 findSerial = TRUE; 491 492 if (findSerial) { 493 BIGNUM *bn; 494 495 /* Comparing BIGNUMs is a pain! */ 496 bn = ASN1_INTEGER_to_BN(xcert->cert_info->serialNumber, NULL); 497 if (bn != NULL) { 498 int bnlen = BN_num_bytes(bn); 499 500 if (bnlen == serial->len) { 501 uchar_t *a = malloc(bnlen); 502 if (a == NULL) { 503 rv = KMF_ERR_MEMORY; 504 BN_free(bn); 505 goto cleanup; 506 } 507 bnlen = BN_bn2bin(bn, a); 508 *match = (memcmp(a, serial->val, serial->len) == 509 0); 510 rv = KMF_OK; 511 free(a); 512 } 513 BN_free(bn); 514 if (!(*match)) 515 goto cleanup; 516 } else { 517 rv = KMF_OK; 518 goto cleanup; 519 } 520 } 521 if (findIssuer) { 522 *match = (kmf_compare_rdns(&issuerDN, &certIssuerDN) == 0); 523 if ((*match) == B_FALSE) { 524 /* stop checking and bail */ 525 rv = KMF_OK; 526 goto cleanup; 527 } 528 } 529 if (findSubject) { 530 *match = (kmf_compare_rdns(&subjectDN, &certSubjectDN) == 0); 531 if ((*match) == B_FALSE) { 532 /* stop checking and bail */ 533 rv = KMF_OK; 534 goto cleanup; 535 } 536 } 537 538 *match = TRUE; 539 cleanup: 540 if (findIssuer) { 541 kmf_free_dn(&issuerDN); 542 kmf_free_dn(&certIssuerDN); 543 } 544 if (findSubject) { 545 kmf_free_dn(&subjectDN); 546 kmf_free_dn(&certSubjectDN); 547 } 548 549 return (rv); 550 } 551 552 553 /* 554 * This function loads a certificate file into an X509 data structure, and 555 * checks if its issuer, subject or the serial number matches with those 556 * values. If it matches, then return the X509 data structure. 557 */ 558 static KMF_RETURN 559 load_X509cert(KMF_HANDLE *kmfh, 560 char *issuer, char *subject, KMF_BIGINT *serial, 561 char *pathname, X509 **outcert) 562 { 563 KMF_RETURN rv = KMF_OK; 564 X509 *xcert = NULL; 565 BIO *bcert = NULL; 566 boolean_t match = FALSE; 567 KMF_ENCODE_FORMAT format; 568 569 /* 570 * auto-detect the file format, regardless of what 571 * the 'format' parameters in the params say. 572 */ 573 rv = kmf_get_file_format(pathname, &format); 574 if (rv != KMF_OK) { 575 if (rv == KMF_ERR_OPEN_FILE) 576 rv = KMF_ERR_CERT_NOT_FOUND; 577 return (rv); 578 } 579 580 /* Not ASN1(DER) format */ 581 if ((bcert = BIO_new_file(pathname, "rb")) == NULL) { 582 SET_ERROR(kmfh, ERR_get_error()); 583 rv = KMF_ERR_OPEN_FILE; 584 goto cleanup; 585 } 586 587 if (format == KMF_FORMAT_PEM) 588 xcert = PEM_read_bio_X509_AUX(bcert, NULL, NULL, NULL); 589 else if (format == KMF_FORMAT_ASN1) 590 xcert = d2i_X509_bio(bcert, NULL); 591 else if (format == KMF_FORMAT_PKCS12) { 592 PKCS12 *p12 = d2i_PKCS12_bio(bcert, NULL); 593 if (p12 != NULL) { 594 (void) PKCS12_parse(p12, NULL, NULL, &xcert, NULL); 595 PKCS12_free(p12); 596 p12 = NULL; 597 } else { 598 SET_ERROR(kmfh, ERR_get_error()); 599 rv = KMF_ERR_BAD_CERT_FORMAT; 600 } 601 } else { 602 rv = KMF_ERR_BAD_PARAMETER; 603 goto cleanup; 604 } 605 606 if (xcert == NULL) { 607 SET_ERROR(kmfh, ERR_get_error()); 608 rv = KMF_ERR_BAD_CERT_FORMAT; 609 goto cleanup; 610 } 611 612 if (check_cert(xcert, issuer, subject, serial, &match) != KMF_OK || 613 match == FALSE) { 614 rv = KMF_ERR_CERT_NOT_FOUND; 615 goto cleanup; 616 } 617 618 if (outcert != NULL) { 619 *outcert = xcert; 620 } 621 622 cleanup: 623 if (bcert != NULL) (void) BIO_free(bcert); 624 if (rv != KMF_OK && xcert != NULL) 625 X509_free(xcert); 626 627 return (rv); 628 } 629 630 static int 631 datacmp(const void *a, const void *b) 632 { 633 KMF_DATA *adata = (KMF_DATA *)a; 634 KMF_DATA *bdata = (KMF_DATA *)b; 635 if (adata->Length > bdata->Length) 636 return (-1); 637 if (adata->Length < bdata->Length) 638 return (1); 639 return (0); 640 } 641 642 static KMF_RETURN 643 load_certs(KMF_HANDLE *kmfh, char *issuer, char *subject, KMF_BIGINT *serial, 644 KMF_CERT_VALIDITY validity, char *pathname, 645 KMF_DATA **certlist, uint32_t *numcerts) 646 { 647 KMF_RETURN rv = KMF_OK; 648 int i; 649 KMF_DATA *certs = NULL; 650 int nc = 0; 651 int hits = 0; 652 KMF_ENCODE_FORMAT format; 653 654 rv = kmf_get_file_format(pathname, &format); 655 if (rv != KMF_OK) { 656 if (rv == KMF_ERR_OPEN_FILE) 657 rv = KMF_ERR_CERT_NOT_FOUND; 658 return (rv); 659 } 660 if (format == KMF_FORMAT_ASN1) { 661 /* load a single certificate */ 662 certs = (KMF_DATA *)malloc(sizeof (KMF_DATA)); 663 if (certs == NULL) 664 return (KMF_ERR_MEMORY); 665 certs->Data = NULL; 666 certs->Length = 0; 667 rv = kmf_load_cert(kmfh, issuer, subject, serial, validity, 668 pathname, certs); 669 if (rv == KMF_OK) { 670 *certlist = certs; 671 *numcerts = 1; 672 } 673 return (rv); 674 } else if (format == KMF_FORMAT_PKCS12) { 675 /* We need a credential to access a PKCS#12 file */ 676 rv = KMF_ERR_BAD_CERT_FORMAT; 677 } else if (format == KMF_FORMAT_PEM || 678 format != KMF_FORMAT_PEM_KEYPAIR) { 679 680 /* This function only works on PEM files */ 681 rv = extract_pem(kmfh, issuer, subject, serial, pathname, 682 (uchar_t *)NULL, 0, NULL, &certs, &nc); 683 } else { 684 return (KMF_ERR_ENCODING); 685 } 686 687 if (rv != KMF_OK) 688 return (rv); 689 690 for (i = 0; i < nc; i++) { 691 if (validity == KMF_NONEXPIRED_CERTS) { 692 rv = kmf_check_cert_date(kmfh, &certs[i]); 693 } else if (validity == KMF_EXPIRED_CERTS) { 694 rv = kmf_check_cert_date(kmfh, &certs[i]); 695 if (rv == KMF_OK) 696 rv = KMF_ERR_CERT_NOT_FOUND; 697 if (rv == KMF_ERR_VALIDITY_PERIOD) 698 rv = KMF_OK; 699 } 700 if (rv != KMF_OK) { 701 /* Remove this cert from the list by clearing it. */ 702 kmf_free_data(&certs[i]); 703 } else { 704 hits++; /* count valid certs found */ 705 } 706 rv = KMF_OK; 707 } 708 if (rv == KMF_OK && hits == 0) { 709 rv = KMF_ERR_CERT_NOT_FOUND; 710 } else if (rv == KMF_OK && hits > 0) { 711 /* 712 * Sort the list of certs by length to put the cleared ones 713 * at the end so they don't get accessed by the caller. 714 */ 715 qsort((void *)certs, nc, sizeof (KMF_DATA), datacmp); 716 *certlist = certs; 717 718 /* since we sorted the list, just return the number of hits */ 719 *numcerts = hits; 720 } 721 return (rv); 722 } 723 724 725 static KMF_RETURN 726 kmf_load_cert(KMF_HANDLE *kmfh, 727 char *issuer, char *subject, KMF_BIGINT *serial, 728 KMF_CERT_VALIDITY validity, 729 char *pathname, 730 KMF_DATA *cert) 731 { 732 KMF_RETURN rv = KMF_OK; 733 X509 *x509cert = NULL; 734 735 rv = load_X509cert(kmfh, issuer, subject, serial, pathname, &x509cert); 736 if (rv == KMF_OK && x509cert != NULL && cert != NULL) { 737 rv = ssl_cert2KMFDATA(kmfh, x509cert, cert); 738 if (rv != KMF_OK) { 739 goto cleanup; 740 } 741 if (validity == KMF_NONEXPIRED_CERTS) { 742 rv = kmf_check_cert_date(kmfh, cert); 743 } else if (validity == KMF_EXPIRED_CERTS) { 744 rv = kmf_check_cert_date(kmfh, cert); 745 if (rv == KMF_OK) { 746 /* 747 * This is a valid cert so skip it. 748 */ 749 rv = KMF_ERR_CERT_NOT_FOUND; 750 } 751 if (rv == KMF_ERR_VALIDITY_PERIOD) { 752 /* 753 * We want to return success when we 754 * find an invalid cert. 755 */ 756 rv = KMF_OK; 757 goto cleanup; 758 } 759 } 760 } 761 cleanup: 762 if (x509cert != NULL) 763 X509_free(x509cert); 764 765 return (rv); 766 } 767 768 static KMF_RETURN 769 readAltFormatPrivateKey(KMF_DATA *filedata, EVP_PKEY **pkey) 770 { 771 KMF_RETURN ret = KMF_OK; 772 KMF_RAW_RSA_KEY rsa; 773 BerElement *asn1 = NULL; 774 BerValue filebuf; 775 BerValue OID = { NULL, 0 }; 776 BerValue *Mod = NULL, *PubExp = NULL; 777 BerValue *PriExp = NULL, *Prime1 = NULL, *Prime2 = NULL; 778 BerValue *Coef = NULL; 779 BIGNUM *D = NULL, *P = NULL, *Q = NULL, *COEF = NULL; 780 BIGNUM *Exp1 = NULL, *Exp2 = NULL, *pminus1 = NULL; 781 BIGNUM *qminus1 = NULL; 782 BN_CTX *ctx = NULL; 783 784 *pkey = NULL; 785 786 filebuf.bv_val = (char *)filedata->Data; 787 filebuf.bv_len = filedata->Length; 788 789 asn1 = kmfder_init(&filebuf); 790 if (asn1 == NULL) { 791 ret = KMF_ERR_MEMORY; 792 goto out; 793 } 794 795 if (kmfber_scanf(asn1, "{{Dn{IIIIII}}}", 796 &OID, &Mod, &PubExp, &PriExp, &Prime1, 797 &Prime2, &Coef) == -1) { 798 ret = KMF_ERR_ENCODING; 799 goto out; 800 } 801 802 /* 803 * We have to derive the 2 Exponents using Bignumber math. 804 * Exp1 = PriExp mod (Prime1 - 1) 805 * Exp2 = PriExp mod (Prime2 - 1) 806 */ 807 808 /* D = PrivateExponent */ 809 D = BN_bin2bn((const uchar_t *)PriExp->bv_val, PriExp->bv_len, D); 810 if (D == NULL) { 811 ret = KMF_ERR_MEMORY; 812 goto out; 813 } 814 815 /* P = Prime1 (first prime factor of Modulus) */ 816 P = BN_bin2bn((const uchar_t *)Prime1->bv_val, Prime1->bv_len, P); 817 if (D == NULL) { 818 ret = KMF_ERR_MEMORY; 819 goto out; 820 } 821 822 /* Q = Prime2 (second prime factor of Modulus) */ 823 Q = BN_bin2bn((const uchar_t *)Prime2->bv_val, Prime2->bv_len, Q); 824 825 if ((ctx = BN_CTX_new()) == NULL) { 826 ret = KMF_ERR_MEMORY; 827 goto out; 828 } 829 830 /* Compute (P - 1) */ 831 pminus1 = BN_new(); 832 (void) BN_sub(pminus1, P, BN_value_one()); 833 834 /* Exponent1 = D mod (P - 1) */ 835 Exp1 = BN_new(); 836 (void) BN_mod(Exp1, D, pminus1, ctx); 837 838 /* Compute (Q - 1) */ 839 qminus1 = BN_new(); 840 (void) BN_sub(qminus1, Q, BN_value_one()); 841 842 /* Exponent2 = D mod (Q - 1) */ 843 Exp2 = BN_new(); 844 (void) BN_mod(Exp2, D, qminus1, ctx); 845 846 /* Coef = (Inverse Q) mod P */ 847 COEF = BN_new(); 848 (void) BN_mod_inverse(COEF, Q, P, ctx); 849 850 /* Convert back to KMF format */ 851 (void) memset(&rsa, 0, sizeof (rsa)); 852 853 if ((ret = sslBN2KMFBN(Exp1, &rsa.exp1)) != KMF_OK) 854 goto out; 855 if ((ret = sslBN2KMFBN(Exp2, &rsa.exp2)) != KMF_OK) 856 goto out; 857 if ((ret = sslBN2KMFBN(COEF, &rsa.coef)) != KMF_OK) 858 goto out; 859 860 rsa.mod.val = (uchar_t *)Mod->bv_val; 861 rsa.mod.len = Mod->bv_len; 862 863 rsa.pubexp.val = (uchar_t *)PubExp->bv_val; 864 rsa.pubexp.len = PubExp->bv_len; 865 866 rsa.priexp.val = (uchar_t *)PriExp->bv_val; 867 rsa.priexp.len = PriExp->bv_len; 868 869 rsa.prime1.val = (uchar_t *)Prime1->bv_val; 870 rsa.prime1.len = Prime1->bv_len; 871 872 rsa.prime2.val = (uchar_t *)Prime2->bv_val; 873 rsa.prime2.len = Prime2->bv_len; 874 875 *pkey = ImportRawRSAKey(&rsa); 876 out: 877 if (asn1 != NULL) 878 kmfber_free(asn1, 1); 879 880 if (OID.bv_val) { 881 free(OID.bv_val); 882 } 883 if (PriExp) 884 free(PriExp); 885 886 if (Mod) 887 free(Mod); 888 889 if (PubExp) 890 free(PubExp); 891 892 if (Coef) { 893 (void) memset(Coef->bv_val, 0, Coef->bv_len); 894 free(Coef->bv_val); 895 free(Coef); 896 } 897 if (Prime1) 898 free(Prime1); 899 if (Prime2) 900 free(Prime2); 901 902 if (ctx != NULL) 903 BN_CTX_free(ctx); 904 905 if (D) 906 BN_clear_free(D); 907 if (P) 908 BN_clear_free(P); 909 if (Q) 910 BN_clear_free(Q); 911 if (pminus1) 912 BN_clear_free(pminus1); 913 if (qminus1) 914 BN_clear_free(qminus1); 915 if (Exp1) 916 BN_clear_free(Exp1); 917 if (Exp2) 918 BN_clear_free(Exp2); 919 920 return (ret); 921 922 } 923 924 static EVP_PKEY * 925 openssl_load_key(KMF_HANDLE_T handle, const char *file) 926 { 927 BIO *keyfile = NULL; 928 EVP_PKEY *pkey = NULL; 929 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 930 KMF_ENCODE_FORMAT format; 931 KMF_RETURN rv; 932 KMF_DATA filedata; 933 934 if (file == NULL) { 935 return (NULL); 936 } 937 938 if (kmf_get_file_format((char *)file, &format) != KMF_OK) 939 return (NULL); 940 941 keyfile = BIO_new_file(file, "rb"); 942 if (keyfile == NULL) { 943 goto end; 944 } 945 946 if (format == KMF_FORMAT_ASN1) { 947 pkey = d2i_PrivateKey_bio(keyfile, NULL); 948 if (pkey == NULL) { 949 950 (void) BIO_free(keyfile); 951 keyfile = NULL; 952 /* Try odd ASN.1 variations */ 953 rv = kmf_read_input_file(kmfh, (char *)file, 954 &filedata); 955 if (rv == KMF_OK) { 956 (void) readAltFormatPrivateKey(&filedata, 957 &pkey); 958 kmf_free_data(&filedata); 959 } 960 } 961 } else if (format == KMF_FORMAT_PEM || 962 format == KMF_FORMAT_PEM_KEYPAIR) { 963 pkey = PEM_read_bio_PrivateKey(keyfile, NULL, NULL, NULL); 964 if (pkey == NULL) { 965 KMF_DATA derdata; 966 /* 967 * Check if this is the alt. format 968 * RSA private key file. 969 */ 970 rv = kmf_read_input_file(kmfh, (char *)file, 971 &filedata); 972 if (rv == KMF_OK) { 973 uchar_t *d = NULL; 974 int len; 975 rv = kmf_pem_to_der(filedata.Data, 976 filedata.Length, &d, &len); 977 if (rv == KMF_OK && d != NULL) { 978 derdata.Data = d; 979 derdata.Length = (size_t)len; 980 (void) readAltFormatPrivateKey( 981 &derdata, &pkey); 982 free(d); 983 } 984 kmf_free_data(&filedata); 985 } 986 } 987 } 988 989 end: 990 if (pkey == NULL) 991 SET_ERROR(kmfh, ERR_get_error()); 992 993 if (keyfile != NULL) 994 (void) BIO_free(keyfile); 995 996 return (pkey); 997 } 998 999 KMF_RETURN 1000 OpenSSL_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 1001 { 1002 KMF_RETURN rv = KMF_OK; 1003 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1004 int i, n; 1005 uint32_t maxcerts = 0; 1006 uint32_t *num_certs; 1007 KMF_X509_DER_CERT *kmf_cert = NULL; 1008 char *dirpath = NULL; 1009 char *filename = NULL; 1010 char *fullpath = NULL; 1011 char *issuer = NULL; 1012 char *subject = NULL; 1013 KMF_BIGINT *serial = NULL; 1014 KMF_CERT_VALIDITY validity; 1015 1016 num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); 1017 if (num_certs == NULL) 1018 return (KMF_ERR_BAD_PARAMETER); 1019 1020 /* num_certs should reference the size of kmf_cert */ 1021 maxcerts = *num_certs; 1022 if (maxcerts == 0) 1023 maxcerts = 0xFFFFFFFF; 1024 *num_certs = 0; 1025 1026 /* Get the optional returned certificate list */ 1027 kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist, 1028 numattr); 1029 1030 /* 1031 * The dirpath attribute and the filename attribute can not be NULL 1032 * at the same time. 1033 */ 1034 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 1035 filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, 1036 numattr); 1037 1038 fullpath = get_fullpath(dirpath, filename); 1039 if (fullpath == NULL) 1040 return (KMF_ERR_BAD_PARAMETER); 1041 1042 /* Get optional search criteria attributes */ 1043 issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); 1044 subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); 1045 serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); 1046 rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, 1047 &validity, NULL); 1048 if (rv != KMF_OK) { 1049 validity = KMF_ALL_CERTS; 1050 rv = KMF_OK; 1051 } 1052 1053 if (isdir(fullpath)) { 1054 DIR *dirp; 1055 struct dirent *dp; 1056 1057 n = 0; 1058 /* open all files in the directory and attempt to read them */ 1059 if ((dirp = opendir(fullpath)) == NULL) { 1060 return (KMF_ERR_BAD_PARAMETER); 1061 } 1062 while ((dp = readdir(dirp)) != NULL) { 1063 char *fname; 1064 KMF_DATA *certlist = NULL; 1065 uint32_t loaded_certs = 0; 1066 1067 if (strcmp(dp->d_name, ".") == 0 || 1068 strcmp(dp->d_name, "..") == 0) 1069 continue; 1070 1071 fname = get_fullpath(fullpath, (char *)&dp->d_name); 1072 1073 rv = load_certs(kmfh, issuer, subject, serial, 1074 validity, fname, &certlist, &loaded_certs); 1075 1076 if (rv != KMF_OK) { 1077 free(fname); 1078 if (certlist != NULL) { 1079 for (i = 0; i < loaded_certs; i++) 1080 kmf_free_data(&certlist[i]); 1081 free(certlist); 1082 } 1083 continue; 1084 } 1085 1086 /* If load succeeds, add certdata to the list */ 1087 if (kmf_cert != NULL) { 1088 for (i = 0; i < loaded_certs && 1089 n < maxcerts; i++) { 1090 kmf_cert[n].certificate.Data = 1091 certlist[i].Data; 1092 kmf_cert[n].certificate.Length = 1093 certlist[i].Length; 1094 1095 kmf_cert[n].kmf_private.keystore_type = 1096 KMF_KEYSTORE_OPENSSL; 1097 kmf_cert[n].kmf_private.flags = 1098 KMF_FLAG_CERT_VALID; 1099 kmf_cert[n].kmf_private.label = 1100 strdup(fname); 1101 n++; 1102 } 1103 /* 1104 * If maxcerts < loaded_certs, clean up the 1105 * certs that were not used. 1106 */ 1107 for (; i < loaded_certs; i++) 1108 kmf_free_data(&certlist[i]); 1109 } else { 1110 for (i = 0; i < loaded_certs; i++) 1111 kmf_free_data(&certlist[i]); 1112 n += loaded_certs; 1113 } 1114 free(certlist); 1115 free(fname); 1116 } 1117 (*num_certs) = n; 1118 if (*num_certs == 0) 1119 rv = KMF_ERR_CERT_NOT_FOUND; 1120 if (*num_certs > 0) 1121 rv = KMF_OK; 1122 exit: 1123 (void) closedir(dirp); 1124 } else { 1125 KMF_DATA *certlist = NULL; 1126 uint32_t loaded_certs = 0; 1127 1128 rv = load_certs(kmfh, issuer, subject, serial, validity, 1129 fullpath, &certlist, &loaded_certs); 1130 if (rv != KMF_OK) { 1131 free(fullpath); 1132 return (rv); 1133 } 1134 1135 n = 0; 1136 if (kmf_cert != NULL && certlist != NULL) { 1137 for (i = 0; i < loaded_certs && i < maxcerts; i++) { 1138 kmf_cert[n].certificate.Data = 1139 certlist[i].Data; 1140 kmf_cert[n].certificate.Length = 1141 certlist[i].Length; 1142 kmf_cert[n].kmf_private.keystore_type = 1143 KMF_KEYSTORE_OPENSSL; 1144 kmf_cert[n].kmf_private.flags = 1145 KMF_FLAG_CERT_VALID; 1146 kmf_cert[n].kmf_private.label = 1147 strdup(fullpath); 1148 n++; 1149 } 1150 /* If maxcerts < loaded_certs, clean up */ 1151 for (; i < loaded_certs; i++) 1152 kmf_free_data(&certlist[i]); 1153 } else if (certlist != NULL) { 1154 for (i = 0; i < loaded_certs; i++) 1155 kmf_free_data(&certlist[i]); 1156 n = loaded_certs; 1157 } 1158 if (certlist != NULL) 1159 free(certlist); 1160 *num_certs = n; 1161 } 1162 1163 free(fullpath); 1164 1165 return (rv); 1166 } 1167 1168 void 1169 /*ARGSUSED*/ 1170 OpenSSL_FreeKMFCert(KMF_HANDLE_T handle, 1171 KMF_X509_DER_CERT *kmf_cert) 1172 { 1173 if (kmf_cert != NULL) { 1174 if (kmf_cert->certificate.Data != NULL) { 1175 free(kmf_cert->certificate.Data); 1176 kmf_cert->certificate.Data = NULL; 1177 kmf_cert->certificate.Length = 0; 1178 } 1179 if (kmf_cert->kmf_private.label) 1180 free(kmf_cert->kmf_private.label); 1181 } 1182 } 1183 1184 /*ARGSUSED*/ 1185 KMF_RETURN 1186 OpenSSL_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 1187 { 1188 KMF_RETURN ret = KMF_OK; 1189 KMF_DATA *cert = NULL; 1190 char *outfilename = NULL; 1191 char *dirpath = NULL; 1192 char *fullpath = NULL; 1193 KMF_ENCODE_FORMAT format; 1194 1195 /* Get the cert data */ 1196 cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr); 1197 if (cert == NULL || cert->Data == NULL) 1198 return (KMF_ERR_BAD_PARAMETER); 1199 1200 /* Check the output filename and directory attributes. */ 1201 outfilename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, 1202 numattr); 1203 if (outfilename == NULL) 1204 return (KMF_ERR_BAD_PARAMETER); 1205 1206 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 1207 fullpath = get_fullpath(dirpath, outfilename); 1208 if (fullpath == NULL) 1209 return (KMF_ERR_BAD_CERTFILE); 1210 1211 /* Check the optional format attribute */ 1212 ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, 1213 &format, NULL); 1214 if (ret != KMF_OK) { 1215 /* If there is no format attribute, then default to PEM */ 1216 format = KMF_FORMAT_PEM; 1217 ret = KMF_OK; 1218 } else if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM) { 1219 ret = KMF_ERR_BAD_CERT_FORMAT; 1220 goto out; 1221 } 1222 1223 /* Store the certificate in the file with the specified format */ 1224 ret = kmf_create_cert_file(cert, format, fullpath); 1225 1226 out: 1227 if (fullpath != NULL) 1228 free(fullpath); 1229 1230 return (ret); 1231 } 1232 1233 1234 KMF_RETURN 1235 OpenSSL_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 1236 { 1237 KMF_RETURN rv; 1238 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1239 KMF_DATA certdata = {NULL, 0}; 1240 char *dirpath = NULL; 1241 char *filename = NULL; 1242 char *fullpath = NULL; 1243 char *issuer = NULL; 1244 char *subject = NULL; 1245 KMF_BIGINT *serial = NULL; 1246 KMF_CERT_VALIDITY validity; 1247 1248 /* 1249 * Get the DIRPATH and CERT_FILENAME attributes. They can not be 1250 * NULL at the same time. 1251 */ 1252 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 1253 filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, 1254 numattr); 1255 fullpath = get_fullpath(dirpath, filename); 1256 if (fullpath == NULL) 1257 return (KMF_ERR_BAD_PARAMETER); 1258 1259 /* Get optional search criteria attributes */ 1260 issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr); 1261 subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr); 1262 serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr); 1263 rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr, 1264 &validity, NULL); 1265 if (rv != KMF_OK) { 1266 validity = KMF_ALL_CERTS; 1267 rv = KMF_OK; 1268 } 1269 1270 if (isdir(fullpath)) { 1271 DIR *dirp; 1272 struct dirent *dp; 1273 1274 /* open all files in the directory and attempt to read them */ 1275 if ((dirp = opendir(fullpath)) == NULL) { 1276 return (KMF_ERR_BAD_PARAMETER); 1277 } 1278 1279 while ((dp = readdir(dirp)) != NULL) { 1280 if (strcmp(dp->d_name, ".") != 0 && 1281 strcmp(dp->d_name, "..") != 0) { 1282 char *fname; 1283 1284 fname = get_fullpath(fullpath, 1285 (char *)&dp->d_name); 1286 1287 if (fname == NULL) { 1288 rv = KMF_ERR_MEMORY; 1289 break; 1290 } 1291 1292 rv = kmf_load_cert(kmfh, issuer, subject, 1293 serial, validity, fname, &certdata); 1294 1295 if (rv == KMF_ERR_CERT_NOT_FOUND) { 1296 free(fname); 1297 if (certdata.Data) 1298 free(certdata.Data); 1299 rv = KMF_OK; 1300 continue; 1301 } else if (rv != KMF_OK) { 1302 free(fname); 1303 break; 1304 } 1305 1306 if (unlink(fname) != 0) { 1307 SET_SYS_ERROR(kmfh, errno); 1308 rv = KMF_ERR_INTERNAL; 1309 free(fname); 1310 break; 1311 } 1312 free(fname); 1313 if (certdata.Data) 1314 free(certdata.Data); 1315 } 1316 } 1317 (void) closedir(dirp); 1318 } else { 1319 /* Just try to load a single certificate */ 1320 rv = kmf_load_cert(kmfh, issuer, subject, serial, validity, 1321 fullpath, &certdata); 1322 if (rv == KMF_OK) { 1323 if (unlink(fullpath) != 0) { 1324 SET_SYS_ERROR(kmfh, errno); 1325 rv = KMF_ERR_INTERNAL; 1326 } 1327 } 1328 } 1329 1330 out: 1331 if (fullpath != NULL) 1332 free(fullpath); 1333 1334 if (certdata.Data) 1335 free(certdata.Data); 1336 1337 return (rv); 1338 } 1339 1340 KMF_RETURN 1341 OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 1342 KMF_DATA *keydata) 1343 { 1344 KMF_RETURN rv = KMF_OK; 1345 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1346 int n; 1347 1348 if (key == NULL || keydata == NULL || 1349 key->keyp == NULL) 1350 return (KMF_ERR_BAD_PARAMETER); 1351 1352 if (key->keyalg == KMF_RSA) { 1353 RSA *pubkey = EVP_PKEY_get1_RSA(key->keyp); 1354 1355 if (!(n = i2d_RSA_PUBKEY(pubkey, &keydata->Data))) { 1356 SET_ERROR(kmfh, ERR_get_error()); 1357 return (KMF_ERR_ENCODING); 1358 } 1359 RSA_free(pubkey); 1360 } else if (key->keyalg == KMF_DSA) { 1361 DSA *pubkey = EVP_PKEY_get1_DSA(key->keyp); 1362 1363 if (!(n = i2d_DSA_PUBKEY(pubkey, &keydata->Data))) { 1364 SET_ERROR(kmfh, ERR_get_error()); 1365 return (KMF_ERR_ENCODING); 1366 } 1367 DSA_free(pubkey); 1368 } else { 1369 return (KMF_ERR_BAD_PARAMETER); 1370 } 1371 keydata->Length = n; 1372 1373 cleanup: 1374 if (rv != KMF_OK) { 1375 if (keydata->Data) 1376 free(keydata->Data); 1377 keydata->Data = NULL; 1378 keydata->Length = 0; 1379 } 1380 1381 return (rv); 1382 } 1383 1384 static KMF_RETURN 1385 ssl_write_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out, 1386 KMF_CREDENTIAL *cred, EVP_PKEY *pkey, boolean_t private) 1387 { 1388 int rv = 0; 1389 RSA *rsa; 1390 DSA *dsa; 1391 1392 switch (format) { 1393 case KMF_FORMAT_ASN1: 1394 if (pkey->type == EVP_PKEY_RSA) { 1395 rsa = EVP_PKEY_get1_RSA(pkey); 1396 if (private) 1397 rv = i2d_RSAPrivateKey_bio(out, rsa); 1398 else 1399 rv = i2d_RSAPublicKey_bio(out, rsa); 1400 RSA_free(rsa); 1401 } else if (pkey->type == EVP_PKEY_DSA) { 1402 dsa = EVP_PKEY_get1_DSA(pkey); 1403 rv = i2d_DSAPrivateKey_bio(out, dsa); 1404 DSA_free(dsa); 1405 } 1406 if (rv == 1) { 1407 rv = KMF_OK; 1408 } else { 1409 SET_ERROR(kmfh, rv); 1410 } 1411 break; 1412 case KMF_FORMAT_PEM: 1413 if (pkey->type == EVP_PKEY_RSA) { 1414 rsa = EVP_PKEY_get1_RSA(pkey); 1415 if (private) 1416 rv = PEM_write_bio_RSAPrivateKey(out, 1417 rsa, NULL, NULL, 0, NULL, 1418 (cred != NULL ? cred->cred : NULL)); 1419 else 1420 rv = PEM_write_bio_RSAPublicKey(out, 1421 rsa); 1422 RSA_free(rsa); 1423 } else if (pkey->type == EVP_PKEY_DSA) { 1424 dsa = EVP_PKEY_get1_DSA(pkey); 1425 rv = PEM_write_bio_DSAPrivateKey(out, 1426 dsa, NULL, NULL, 0, NULL, 1427 (cred != NULL ? cred->cred : NULL)); 1428 DSA_free(dsa); 1429 } 1430 1431 if (rv == 1) { 1432 rv = KMF_OK; 1433 } else { 1434 SET_ERROR(kmfh, rv); 1435 } 1436 break; 1437 1438 default: 1439 rv = KMF_ERR_BAD_PARAMETER; 1440 } 1441 1442 return (rv); 1443 } 1444 1445 KMF_RETURN 1446 OpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr, 1447 KMF_ATTRIBUTE *attrlist) 1448 { 1449 KMF_RETURN rv = KMF_OK; 1450 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1451 uint32_t eValue = 0x010001; 1452 RSA *sslPrivKey = NULL; 1453 DSA *sslDSAKey = NULL; 1454 EVP_PKEY *eprikey = NULL; 1455 EVP_PKEY *epubkey = NULL; 1456 BIO *out = NULL; 1457 KMF_KEY_HANDLE *pubkey = NULL, *privkey = NULL; 1458 uint32_t keylen = 1024; 1459 uint32_t keylen_size = sizeof (uint32_t); 1460 boolean_t storekey = TRUE; 1461 KMF_KEY_ALG keytype = KMF_RSA; 1462 1463 rv = kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attrlist, numattr, 1464 &storekey, NULL); 1465 if (rv != KMF_OK) { 1466 /* "storekey" is optional. Default is TRUE */ 1467 rv = KMF_OK; 1468 } 1469 1470 rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, 1471 (void *)&keytype, NULL); 1472 if (rv != KMF_OK) 1473 /* keytype is optional. KMF_RSA is default */ 1474 rv = KMF_OK; 1475 1476 pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr); 1477 if (pubkey == NULL) 1478 return (KMF_ERR_BAD_PARAMETER); 1479 1480 privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr); 1481 if (privkey == NULL) 1482 return (KMF_ERR_BAD_PARAMETER); 1483 1484 (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE)); 1485 (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE)); 1486 1487 eprikey = EVP_PKEY_new(); 1488 if (eprikey == NULL) { 1489 SET_ERROR(kmfh, ERR_get_error()); 1490 rv = KMF_ERR_KEYGEN_FAILED; 1491 goto cleanup; 1492 } 1493 epubkey = EVP_PKEY_new(); 1494 if (epubkey == NULL) { 1495 SET_ERROR(kmfh, ERR_get_error()); 1496 rv = KMF_ERR_KEYGEN_FAILED; 1497 goto cleanup; 1498 } 1499 if (keytype == KMF_RSA) { 1500 KMF_BIGINT *rsaexp = NULL; 1501 1502 rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attrlist, numattr); 1503 if (rsaexp != NULL) { 1504 if (rsaexp->len > 0 && 1505 rsaexp->len <= sizeof (eValue) && 1506 rsaexp->val != NULL) { 1507 /*LINTED*/ 1508 eValue = *(uint32_t *)rsaexp->val; 1509 } else { 1510 rv = KMF_ERR_BAD_PARAMETER; 1511 goto cleanup; 1512 } 1513 } else { 1514 /* RSA Exponent is optional. Default is 0x10001 */ 1515 rv = KMF_OK; 1516 } 1517 1518 rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, 1519 &keylen, &keylen_size); 1520 if (rv == KMF_ERR_ATTR_NOT_FOUND) 1521 /* keylen is optional, default is 1024 */ 1522 rv = KMF_OK; 1523 if (rv != KMF_OK) { 1524 rv = KMF_ERR_BAD_PARAMETER; 1525 goto cleanup; 1526 } 1527 1528 sslPrivKey = RSA_generate_key(keylen, eValue, NULL, NULL); 1529 if (sslPrivKey == NULL) { 1530 SET_ERROR(kmfh, ERR_get_error()); 1531 rv = KMF_ERR_KEYGEN_FAILED; 1532 } else { 1533 (void) EVP_PKEY_set1_RSA(eprikey, sslPrivKey); 1534 privkey->kstype = KMF_KEYSTORE_OPENSSL; 1535 privkey->keyalg = KMF_RSA; 1536 privkey->keyclass = KMF_ASYM_PRI; 1537 privkey->israw = FALSE; 1538 privkey->keyp = (void *)eprikey; 1539 1540 /* OpenSSL derives the public key from the private */ 1541 (void) EVP_PKEY_set1_RSA(epubkey, sslPrivKey); 1542 pubkey->kstype = KMF_KEYSTORE_OPENSSL; 1543 pubkey->keyalg = KMF_RSA; 1544 pubkey->israw = FALSE; 1545 pubkey->keyclass = KMF_ASYM_PUB; 1546 pubkey->keyp = (void *)epubkey; 1547 } 1548 } else if (keytype == KMF_DSA) { 1549 DSA *dp; 1550 sslDSAKey = DSA_new(); 1551 if (sslDSAKey == NULL) { 1552 SET_ERROR(kmfh, ERR_get_error()); 1553 return (KMF_ERR_MEMORY); 1554 } 1555 1556 if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) == 1557 NULL) { 1558 SET_ERROR(kmfh, ERR_get_error()); 1559 rv = KMF_ERR_KEYGEN_FAILED; 1560 goto cleanup; 1561 } 1562 if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) == 1563 NULL) { 1564 SET_ERROR(kmfh, ERR_get_error()); 1565 rv = KMF_ERR_KEYGEN_FAILED; 1566 goto cleanup; 1567 } 1568 if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) == 1569 NULL) { 1570 SET_ERROR(kmfh, ERR_get_error()); 1571 rv = KMF_ERR_KEYGEN_FAILED; 1572 goto cleanup; 1573 } 1574 1575 if (!DSA_generate_key(sslDSAKey)) { 1576 SET_ERROR(kmfh, ERR_get_error()); 1577 rv = KMF_ERR_KEYGEN_FAILED; 1578 goto cleanup; 1579 } 1580 1581 privkey->kstype = KMF_KEYSTORE_OPENSSL; 1582 privkey->keyalg = KMF_DSA; 1583 privkey->keyclass = KMF_ASYM_PRI; 1584 privkey->israw = FALSE; 1585 if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) { 1586 privkey->keyp = (void *)eprikey; 1587 } else { 1588 SET_ERROR(kmfh, ERR_get_error()); 1589 rv = KMF_ERR_KEYGEN_FAILED; 1590 goto cleanup; 1591 } 1592 dp = DSA_new(); 1593 /* Make a copy for the public key */ 1594 if (dp != NULL) { 1595 if ((dp->p = BN_new()) == NULL) { 1596 SET_ERROR(kmfh, ERR_get_error()); 1597 rv = KMF_ERR_MEMORY; 1598 DSA_free(dp); 1599 goto cleanup; 1600 } 1601 if ((dp->q = BN_new()) == NULL) { 1602 SET_ERROR(kmfh, ERR_get_error()); 1603 rv = KMF_ERR_MEMORY; 1604 BN_free(dp->p); 1605 DSA_free(dp); 1606 goto cleanup; 1607 } 1608 if ((dp->g = BN_new()) == NULL) { 1609 SET_ERROR(kmfh, ERR_get_error()); 1610 rv = KMF_ERR_MEMORY; 1611 BN_free(dp->q); 1612 BN_free(dp->p); 1613 DSA_free(dp); 1614 goto cleanup; 1615 } 1616 if ((dp->pub_key = BN_new()) == NULL) { 1617 SET_ERROR(kmfh, ERR_get_error()); 1618 rv = KMF_ERR_MEMORY; 1619 BN_free(dp->q); 1620 BN_free(dp->p); 1621 BN_free(dp->g); 1622 DSA_free(dp); 1623 goto cleanup; 1624 } 1625 (void) BN_copy(dp->p, sslDSAKey->p); 1626 (void) BN_copy(dp->q, sslDSAKey->q); 1627 (void) BN_copy(dp->g, sslDSAKey->g); 1628 (void) BN_copy(dp->pub_key, sslDSAKey->pub_key); 1629 1630 pubkey->kstype = KMF_KEYSTORE_OPENSSL; 1631 pubkey->keyalg = KMF_DSA; 1632 pubkey->keyclass = KMF_ASYM_PUB; 1633 pubkey->israw = FALSE; 1634 1635 if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) { 1636 pubkey->keyp = (void *)epubkey; 1637 } else { 1638 SET_ERROR(kmfh, ERR_get_error()); 1639 rv = KMF_ERR_KEYGEN_FAILED; 1640 goto cleanup; 1641 } 1642 } 1643 } 1644 1645 if (rv != KMF_OK) { 1646 goto cleanup; 1647 } 1648 1649 if (storekey) { 1650 KMF_ATTRIBUTE storeattrs[4]; /* max. 4 attributes needed */ 1651 int i = 0; 1652 char *keyfile = NULL, *dirpath = NULL; 1653 KMF_ENCODE_FORMAT format; 1654 /* 1655 * Construct a new attribute arrray and call openssl_store_key 1656 */ 1657 kmf_set_attr_at_index(storeattrs, i, KMF_PRIVKEY_HANDLE_ATTR, 1658 privkey, sizeof (privkey)); 1659 i++; 1660 1661 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 1662 if (dirpath != NULL) { 1663 storeattrs[i].type = KMF_DIRPATH_ATTR; 1664 storeattrs[i].pValue = dirpath; 1665 storeattrs[i].valueLen = strlen(dirpath); 1666 i++; 1667 } else { 1668 rv = KMF_OK; /* DIRPATH is optional */ 1669 } 1670 keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, 1671 attrlist, numattr); 1672 if (keyfile != NULL) { 1673 storeattrs[i].type = KMF_KEY_FILENAME_ATTR; 1674 storeattrs[i].pValue = keyfile; 1675 storeattrs[i].valueLen = strlen(keyfile); 1676 i++; 1677 } else { 1678 goto cleanup; /* KEYFILE is required */ 1679 } 1680 rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, 1681 (void *)&format, NULL); 1682 if (rv == KMF_OK) { 1683 storeattrs[i].type = KMF_ENCODE_FORMAT_ATTR; 1684 storeattrs[i].pValue = &format; 1685 storeattrs[i].valueLen = sizeof (format); 1686 i++; 1687 } 1688 1689 rv = OpenSSL_StoreKey(handle, i, storeattrs); 1690 } 1691 1692 cleanup: 1693 if (rv != KMF_OK) { 1694 if (eprikey != NULL) 1695 EVP_PKEY_free(eprikey); 1696 1697 if (epubkey != NULL) 1698 EVP_PKEY_free(epubkey); 1699 1700 if (pubkey->keylabel) { 1701 free(pubkey->keylabel); 1702 pubkey->keylabel = NULL; 1703 } 1704 1705 if (privkey->keylabel) { 1706 free(privkey->keylabel); 1707 privkey->keylabel = NULL; 1708 } 1709 1710 pubkey->keyp = NULL; 1711 privkey->keyp = NULL; 1712 } 1713 1714 if (sslPrivKey) 1715 RSA_free(sslPrivKey); 1716 1717 if (sslDSAKey) 1718 DSA_free(sslDSAKey); 1719 1720 if (out != NULL) 1721 (void) BIO_free(out); 1722 1723 return (rv); 1724 } 1725 1726 KMF_RETURN 1727 OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 1728 KMF_OID *AlgOID, KMF_DATA *tobesigned, KMF_DATA *output) 1729 { 1730 KMF_RETURN ret = KMF_OK; 1731 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1732 KMF_ALGORITHM_INDEX AlgId; 1733 EVP_MD_CTX ctx; 1734 const EVP_MD *md; 1735 1736 if (key == NULL || AlgOID == NULL || 1737 tobesigned == NULL || output == NULL || 1738 tobesigned->Data == NULL || 1739 output->Data == NULL) 1740 return (KMF_ERR_BAD_PARAMETER); 1741 1742 /* Map the OID to an OpenSSL algorithm */ 1743 AlgId = x509_algoid_to_algid(AlgOID); 1744 if (AlgId == KMF_ALGID_NONE) 1745 return (KMF_ERR_BAD_PARAMETER); 1746 1747 if (key->keyalg == KMF_RSA) { 1748 EVP_PKEY *pkey = (EVP_PKEY *)key->keyp; 1749 uchar_t *p; 1750 int len; 1751 if (AlgId == KMF_ALGID_MD5WithRSA) 1752 md = EVP_md5(); 1753 else if (AlgId == KMF_ALGID_MD2WithRSA) 1754 md = EVP_md2(); 1755 else if (AlgId == KMF_ALGID_SHA1WithRSA) 1756 md = EVP_sha1(); 1757 else if (AlgId == KMF_ALGID_RSA) 1758 md = NULL; 1759 else 1760 return (KMF_ERR_BAD_PARAMETER); 1761 1762 if ((md == NULL) && (AlgId == KMF_ALGID_RSA)) { 1763 RSA *rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey); 1764 1765 p = output->Data; 1766 if ((len = RSA_private_encrypt(tobesigned->Length, 1767 tobesigned->Data, p, rsa, 1768 RSA_PKCS1_PADDING)) <= 0) { 1769 SET_ERROR(kmfh, ERR_get_error()); 1770 ret = KMF_ERR_INTERNAL; 1771 } 1772 output->Length = len; 1773 } else { 1774 (void) EVP_MD_CTX_init(&ctx); 1775 (void) EVP_SignInit_ex(&ctx, md, NULL); 1776 (void) EVP_SignUpdate(&ctx, tobesigned->Data, 1777 (uint32_t)tobesigned->Length); 1778 len = (uint32_t)output->Length; 1779 p = output->Data; 1780 if (!EVP_SignFinal(&ctx, p, (uint32_t *)&len, pkey)) { 1781 SET_ERROR(kmfh, ERR_get_error()); 1782 len = 0; 1783 ret = KMF_ERR_INTERNAL; 1784 } 1785 output->Length = len; 1786 (void) EVP_MD_CTX_cleanup(&ctx); 1787 } 1788 } else if (key->keyalg == KMF_DSA) { 1789 DSA *dsa = EVP_PKEY_get1_DSA(key->keyp); 1790 1791 uchar_t hash[EVP_MAX_MD_SIZE]; 1792 uint32_t hashlen; 1793 DSA_SIG *dsasig; 1794 1795 /* 1796 * OpenSSL EVP_Sign operation automatically converts to 1797 * ASN.1 output so we do the operations separately so we 1798 * are assured of NOT getting ASN.1 output returned. 1799 * KMF does not want ASN.1 encoded results because 1800 * not all mechanisms return ASN.1 encodings (PKCS#11 1801 * and NSS return raw signature data). 1802 */ 1803 md = EVP_sha1(); 1804 EVP_MD_CTX_init(&ctx); 1805 (void) EVP_DigestInit_ex(&ctx, md, NULL); 1806 (void) EVP_DigestUpdate(&ctx, tobesigned->Data, 1807 tobesigned->Length); 1808 (void) EVP_DigestFinal_ex(&ctx, hash, &hashlen); 1809 (void) EVP_MD_CTX_cleanup(&ctx); 1810 1811 dsasig = DSA_do_sign(hash, hashlen, dsa); 1812 if (dsasig != NULL) { 1813 int i; 1814 output->Length = i = BN_bn2bin(dsasig->r, output->Data); 1815 output->Length += BN_bn2bin(dsasig->s, 1816 &output->Data[i]); 1817 DSA_SIG_free(dsasig); 1818 } else { 1819 SET_ERROR(kmfh, ERR_get_error()); 1820 } 1821 } else { 1822 return (KMF_ERR_BAD_PARAMETER); 1823 } 1824 cleanup: 1825 return (ret); 1826 } 1827 1828 KMF_RETURN 1829 /*ARGSUSED*/ 1830 OpenSSL_DeleteKey(KMF_HANDLE_T handle, 1831 int numattr, KMF_ATTRIBUTE *attrlist) 1832 { 1833 KMF_RETURN rv = KMF_OK; 1834 KMF_KEY_HANDLE *key; 1835 boolean_t destroy = B_TRUE; 1836 1837 key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 1838 if (key == NULL || key->keyp == NULL) 1839 return (KMF_ERR_BAD_PARAMETER); 1840 1841 rv = kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr, 1842 (void *)&destroy, NULL); 1843 if (rv != KMF_OK) { 1844 /* "destroy" is optional. Default is TRUE */ 1845 rv = KMF_OK; 1846 } 1847 1848 if (key->keyclass != KMF_ASYM_PUB && 1849 key->keyclass != KMF_ASYM_PRI && 1850 key->keyclass != KMF_SYMMETRIC) 1851 return (KMF_ERR_BAD_KEY_CLASS); 1852 1853 if (key->keyclass == KMF_SYMMETRIC) { 1854 kmf_free_raw_sym_key((KMF_RAW_SYM_KEY *)key->keyp); 1855 key->keyp = NULL; 1856 } else { 1857 if (key->keyp != NULL) { 1858 EVP_PKEY_free(key->keyp); 1859 key->keyp = NULL; 1860 } 1861 } 1862 1863 if (key->keylabel != NULL) { 1864 EVP_PKEY *pkey = NULL; 1865 /* If the file exists, make sure it is a proper key. */ 1866 pkey = openssl_load_key(handle, key->keylabel); 1867 if (pkey == NULL) { 1868 free(key->keylabel); 1869 key->keylabel = NULL; 1870 return (KMF_ERR_KEY_NOT_FOUND); 1871 } 1872 EVP_PKEY_free(pkey); 1873 1874 if (destroy) { 1875 if (unlink(key->keylabel) != 0) { 1876 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1877 SET_SYS_ERROR(kmfh, errno); 1878 rv = KMF_ERR_INTERNAL; 1879 } 1880 } 1881 if (key->keylabel != NULL) { 1882 free(key->keylabel); 1883 key->keylabel = NULL; 1884 } 1885 } 1886 return (rv); 1887 } 1888 1889 KMF_RETURN 1890 OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr) 1891 { 1892 KMF_RETURN ret = KMF_OK; 1893 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1894 char str[256]; /* OpenSSL needs at least 120 byte buffer */ 1895 1896 ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str)); 1897 if (strlen(str)) { 1898 *msgstr = (char *)strdup(str); 1899 if ((*msgstr) == NULL) 1900 ret = KMF_ERR_MEMORY; 1901 } else { 1902 *msgstr = NULL; 1903 } 1904 1905 return (ret); 1906 } 1907 1908 static int 1909 ext2NID(int kmfext) 1910 { 1911 switch (kmfext) { 1912 case KMF_X509_EXT_KEY_USAGE: 1913 return (NID_key_usage); 1914 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD: 1915 return (NID_private_key_usage_period); 1916 case KMF_X509_EXT_CERT_POLICIES: 1917 return (NID_certificate_policies); 1918 case KMF_X509_EXT_SUBJ_ALTNAME: 1919 return (NID_subject_alt_name); 1920 case KMF_X509_EXT_ISSUER_ALTNAME: 1921 return (NID_issuer_alt_name); 1922 case KMF_X509_EXT_BASIC_CONSTRAINTS: 1923 return (NID_basic_constraints); 1924 case KMF_X509_EXT_EXT_KEY_USAGE: 1925 return (NID_ext_key_usage); 1926 case KMF_X509_EXT_AUTH_KEY_ID: 1927 return (NID_authority_key_identifier); 1928 case KMF_X509_EXT_CRL_DIST_POINTS: 1929 return (NID_crl_distribution_points); 1930 case KMF_X509_EXT_SUBJ_KEY_ID: 1931 return (NID_subject_key_identifier); 1932 case KMF_X509_EXT_POLICY_MAPPINGS: 1933 return (OBJ_sn2nid("policyMappings")); 1934 case KMF_X509_EXT_NAME_CONSTRAINTS: 1935 return (OBJ_sn2nid("nameConstraints")); 1936 case KMF_X509_EXT_POLICY_CONSTRAINTS: 1937 return (OBJ_sn2nid("policyConstraints")); 1938 case KMF_X509_EXT_INHIBIT_ANY_POLICY: 1939 return (OBJ_sn2nid("inhibitAnyPolicy")); 1940 case KMF_X509_EXT_FRESHEST_CRL: 1941 return (OBJ_sn2nid("freshestCRL")); 1942 default: 1943 return (NID_undef); 1944 } 1945 } 1946 1947 KMF_RETURN 1948 OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert, 1949 KMF_PRINTABLE_ITEM flag, char *resultStr) 1950 { 1951 KMF_RETURN ret = KMF_OK; 1952 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 1953 X509 *xcert = NULL; 1954 unsigned char *outbuf = NULL; 1955 unsigned char *outbuf_p; 1956 char *tmpstr = NULL; 1957 int j; 1958 int ext_index, nid, len; 1959 BIO *mem = NULL; 1960 STACK *emlst = NULL; 1961 X509_EXTENSION *ex; 1962 X509_CINF *ci; 1963 1964 if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) { 1965 return (KMF_ERR_BAD_PARAMETER); 1966 } 1967 1968 /* copy cert data to outbuf */ 1969 outbuf = malloc(pcert->Length); 1970 if (outbuf == NULL) { 1971 return (KMF_ERR_MEMORY); 1972 } 1973 (void) memcpy(outbuf, pcert->Data, pcert->Length); 1974 1975 outbuf_p = outbuf; /* use a temp pointer; required by openssl */ 1976 xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length); 1977 if (xcert == NULL) { 1978 SET_ERROR(kmfh, ERR_get_error()); 1979 ret = KMF_ERR_ENCODING; 1980 goto out; 1981 } 1982 1983 mem = BIO_new(BIO_s_mem()); 1984 if (mem == NULL) { 1985 SET_ERROR(kmfh, ERR_get_error()); 1986 ret = KMF_ERR_MEMORY; 1987 goto out; 1988 } 1989 1990 switch (flag) { 1991 case KMF_CERT_ISSUER: 1992 (void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0, 1993 XN_FLAG_SEP_CPLUS_SPC); 1994 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 1995 break; 1996 1997 case KMF_CERT_SUBJECT: 1998 (void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0, 1999 XN_FLAG_SEP_CPLUS_SPC); 2000 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 2001 break; 2002 2003 case KMF_CERT_VERSION: 2004 tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version); 2005 (void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN); 2006 OPENSSL_free(tmpstr); 2007 len = strlen(resultStr); 2008 break; 2009 2010 case KMF_CERT_SERIALNUM: 2011 if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) { 2012 (void) strcpy(resultStr, "0x"); 2013 len = BIO_gets(mem, &resultStr[2], 2014 KMF_CERT_PRINTABLE_LEN - 2); 2015 } 2016 break; 2017 2018 case KMF_CERT_NOTBEFORE: 2019 (void) ASN1_TIME_print(mem, X509_get_notBefore(xcert)); 2020 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 2021 break; 2022 2023 case KMF_CERT_NOTAFTER: 2024 (void) ASN1_TIME_print(mem, X509_get_notAfter(xcert)); 2025 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 2026 break; 2027 2028 case KMF_CERT_PUBKEY_DATA: 2029 { 2030 EVP_PKEY *pkey = X509_get_pubkey(xcert); 2031 if (pkey == NULL) { 2032 SET_ERROR(kmfh, ERR_get_error()); 2033 ret = KMF_ERR_ENCODING; 2034 goto out; 2035 } 2036 2037 if (pkey->type == EVP_PKEY_RSA) { 2038 (void) BIO_printf(mem, 2039 "RSA Public Key: (%d bit)\n", 2040 BN_num_bits(pkey->pkey.rsa->n)); 2041 (void) RSA_print(mem, pkey->pkey.rsa, 0); 2042 } else if (pkey->type == EVP_PKEY_DSA) { 2043 (void) BIO_printf(mem, 2044 "%12sDSA Public Key:\n", ""); 2045 (void) DSA_print(mem, pkey->pkey.dsa, 0); 2046 } else { 2047 (void) BIO_printf(mem, 2048 "%12sUnknown Public Key:\n", ""); 2049 } 2050 (void) BIO_printf(mem, "\n"); 2051 EVP_PKEY_free(pkey); 2052 } 2053 len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 2054 break; 2055 case KMF_CERT_SIGNATURE_ALG: 2056 case KMF_CERT_PUBKEY_ALG: 2057 if (flag == KMF_CERT_SIGNATURE_ALG) { 2058 len = i2a_ASN1_OBJECT(mem, 2059 xcert->sig_alg->algorithm); 2060 } else { 2061 len = i2a_ASN1_OBJECT(mem, 2062 xcert->cert_info->key->algor->algorithm); 2063 } 2064 2065 if (len > 0) { 2066 len = BIO_read(mem, resultStr, 2067 KMF_CERT_PRINTABLE_LEN); 2068 } 2069 break; 2070 2071 case KMF_CERT_EMAIL: 2072 emlst = X509_get1_email(xcert); 2073 for (j = 0; j < sk_num(emlst); j++) 2074 (void) BIO_printf(mem, "%s\n", sk_value(emlst, j)); 2075 2076 len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 2077 X509_email_free(emlst); 2078 break; 2079 case KMF_X509_EXT_ISSUER_ALTNAME: 2080 case KMF_X509_EXT_SUBJ_ALTNAME: 2081 case KMF_X509_EXT_KEY_USAGE: 2082 case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD: 2083 case KMF_X509_EXT_CERT_POLICIES: 2084 case KMF_X509_EXT_BASIC_CONSTRAINTS: 2085 case KMF_X509_EXT_NAME_CONSTRAINTS: 2086 case KMF_X509_EXT_POLICY_CONSTRAINTS: 2087 case KMF_X509_EXT_EXT_KEY_USAGE: 2088 case KMF_X509_EXT_INHIBIT_ANY_POLICY: 2089 case KMF_X509_EXT_AUTH_KEY_ID: 2090 case KMF_X509_EXT_SUBJ_KEY_ID: 2091 case KMF_X509_EXT_POLICY_MAPPINGS: 2092 case KMF_X509_EXT_CRL_DIST_POINTS: 2093 case KMF_X509_EXT_FRESHEST_CRL: 2094 nid = ext2NID(flag); 2095 if (nid == NID_undef) { 2096 ret = KMF_ERR_EXTENSION_NOT_FOUND; 2097 goto out; 2098 } 2099 ci = xcert->cert_info; 2100 2101 ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1); 2102 if (ext_index == -1) { 2103 SET_ERROR(kmfh, ERR_get_error()); 2104 2105 ret = KMF_ERR_EXTENSION_NOT_FOUND; 2106 goto out; 2107 } 2108 ex = X509v3_get_ext(ci->extensions, ext_index); 2109 2110 (void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex)); 2111 2112 if (BIO_printf(mem, ": %s\n", 2113 X509_EXTENSION_get_critical(ex) ? "critical" : "") <= 0) { 2114 SET_ERROR(kmfh, ERR_get_error()); 2115 ret = KMF_ERR_ENCODING; 2116 goto out; 2117 } 2118 if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) { 2119 (void) BIO_printf(mem, "%*s", 4, ""); 2120 (void) M_ASN1_OCTET_STRING_print(mem, ex->value); 2121 } 2122 if (BIO_write(mem, "\n", 1) <= 0) { 2123 SET_ERROR(kmfh, ERR_get_error()); 2124 ret = KMF_ERR_ENCODING; 2125 goto out; 2126 } 2127 len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN); 2128 } 2129 if (len <= 0) { 2130 SET_ERROR(kmfh, ERR_get_error()); 2131 ret = KMF_ERR_ENCODING; 2132 } 2133 2134 out: 2135 if (outbuf != NULL) { 2136 free(outbuf); 2137 } 2138 2139 if (xcert != NULL) { 2140 X509_free(xcert); 2141 } 2142 2143 if (mem != NULL) { 2144 (void) BIO_free(mem); 2145 } 2146 2147 return (ret); 2148 } 2149 2150 KMF_RETURN 2151 /*ARGSUSED*/ 2152 OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr, 2153 KMF_ATTRIBUTE *attrlist) 2154 { 2155 KMF_RETURN rv = KMF_OK; 2156 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 2157 KMF_KEY_CLASS keyclass = KMF_ASYM_PRI; 2158 KMF_KEY_HANDLE *key = NULL; 2159 uint32_t numkeys = 1; /* 1 key only */ 2160 char *dirpath = NULL; 2161 char *keyfile = NULL; 2162 KMF_ATTRIBUTE new_attrlist[16]; 2163 int i = 0; 2164 2165 /* 2166 * This is really just a FindKey operation, reuse the 2167 * FindKey function. 2168 */ 2169 kmf_set_attr_at_index(new_attrlist, i, 2170 KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 2171 i++; 2172 2173 kmf_set_attr_at_index(new_attrlist, i, 2174 KMF_COUNT_ATTR, &numkeys, sizeof (uint32_t)); 2175 i++; 2176 2177 kmf_set_attr_at_index(new_attrlist, i, 2178 KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass)); 2179 i++; 2180 2181 key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 2182 if (key == NULL) { 2183 return (KMF_ERR_BAD_PARAMETER); 2184 } else { 2185 kmf_set_attr_at_index(new_attrlist, i, 2186 KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE)); 2187 i++; 2188 } 2189 2190 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 2191 if (dirpath != NULL) { 2192 kmf_set_attr_at_index(new_attrlist, i, 2193 KMF_DIRPATH_ATTR, dirpath, strlen(dirpath)); 2194 i++; 2195 } 2196 2197 keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); 2198 if (keyfile == NULL) 2199 return (KMF_ERR_BAD_PARAMETER); 2200 else { 2201 kmf_set_attr_at_index(new_attrlist, i, 2202 KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile)); 2203 i++; 2204 } 2205 2206 rv = OpenSSL_FindKey(handle, i, new_attrlist); 2207 return (rv); 2208 } 2209 2210 KMF_RETURN 2211 /*ARGSUSED*/ 2212 OpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key, 2213 KMF_OID *AlgOID, KMF_DATA *ciphertext, 2214 KMF_DATA *output) 2215 { 2216 KMF_RETURN ret = KMF_OK; 2217 RSA *rsa = NULL; 2218 unsigned int in_len = 0, out_len = 0; 2219 unsigned int total_decrypted = 0, modulus_len = 0; 2220 uint8_t *in_data, *out_data; 2221 int i, blocks; 2222 2223 if (key == NULL || AlgOID == NULL || 2224 ciphertext == NULL || output == NULL || 2225 ciphertext->Data == NULL || 2226 output->Data == NULL) 2227 return (KMF_ERR_BAD_PARAMETER); 2228 2229 if (key->keyalg == KMF_RSA) { 2230 rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp); 2231 modulus_len = RSA_size(rsa); 2232 } else { 2233 return (KMF_ERR_BAD_PARAMETER); 2234 } 2235 2236 blocks = ciphertext->Length/modulus_len; 2237 out_data = output->Data; 2238 in_data = ciphertext->Data; 2239 out_len = modulus_len - 11; 2240 in_len = modulus_len; 2241 2242 for (i = 0; i < blocks; i++) { 2243 out_len = RSA_private_decrypt(in_len, 2244 in_data, out_data, rsa, RSA_PKCS1_PADDING); 2245 2246 if (out_len == 0) { 2247 ret = KMF_ERR_INTERNAL; 2248 goto cleanup; 2249 } 2250 2251 out_data += out_len; 2252 total_decrypted += out_len; 2253 in_data += in_len; 2254 } 2255 2256 output->Length = total_decrypted; 2257 2258 cleanup: 2259 RSA_free(rsa); 2260 if (ret != KMF_OK) 2261 output->Length = 0; 2262 2263 return (ret); 2264 2265 } 2266 2267 /* 2268 * This function will create a certid from issuer_cert and user_cert. 2269 * The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate 2270 * certid memory after use. 2271 */ 2272 static KMF_RETURN 2273 create_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert, 2274 const KMF_DATA *user_cert, OCSP_CERTID **certid) 2275 { 2276 KMF_RETURN ret = KMF_OK; 2277 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2278 X509 *issuer = NULL; 2279 X509 *cert = NULL; 2280 unsigned char *ptmp; 2281 2282 if (issuer_cert == NULL || user_cert == NULL) { 2283 return (KMF_ERR_BAD_PARAMETER); 2284 } 2285 2286 /* convert the DER-encoded issuer cert to an internal X509 */ 2287 ptmp = issuer_cert->Data; 2288 issuer = d2i_X509(NULL, (const uchar_t **)&ptmp, 2289 issuer_cert->Length); 2290 if (issuer == NULL) { 2291 SET_ERROR(kmfh, ERR_get_error()); 2292 ret = KMF_ERR_OCSP_BAD_ISSUER; 2293 goto end; 2294 } 2295 2296 /* convert the DER-encoded user cert to an internal X509 */ 2297 ptmp = user_cert->Data; 2298 cert = d2i_X509(NULL, (const uchar_t **)&ptmp, 2299 user_cert->Length); 2300 if (cert == NULL) { 2301 SET_ERROR(kmfh, ERR_get_error()); 2302 2303 ret = KMF_ERR_OCSP_BAD_CERT; 2304 goto end; 2305 } 2306 2307 /* create a CERTID */ 2308 *certid = OCSP_cert_to_id(NULL, cert, issuer); 2309 if (*certid == NULL) { 2310 SET_ERROR(kmfh, ERR_get_error()); 2311 ret = KMF_ERR_OCSP_CERTID; 2312 goto end; 2313 } 2314 2315 end: 2316 if (issuer != NULL) { 2317 X509_free(issuer); 2318 } 2319 2320 if (cert != NULL) { 2321 X509_free(cert); 2322 } 2323 2324 return (ret); 2325 } 2326 2327 KMF_RETURN 2328 OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle, 2329 int numattr, KMF_ATTRIBUTE *attrlist) 2330 { 2331 KMF_RETURN ret = KMF_OK; 2332 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2333 OCSP_CERTID *id = NULL; 2334 OCSP_REQUEST *req = NULL; 2335 BIO *derbio = NULL; 2336 char *reqfile; 2337 KMF_DATA *issuer_cert; 2338 KMF_DATA *user_cert; 2339 2340 user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR, 2341 attrlist, numattr); 2342 if (user_cert == NULL) 2343 return (KMF_ERR_BAD_PARAMETER); 2344 2345 issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR, 2346 attrlist, numattr); 2347 if (issuer_cert == NULL) 2348 return (KMF_ERR_BAD_PARAMETER); 2349 2350 reqfile = kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR, 2351 attrlist, numattr); 2352 if (reqfile == NULL) 2353 return (KMF_ERR_BAD_PARAMETER); 2354 2355 ret = create_certid(handle, issuer_cert, user_cert, &id); 2356 if (ret != KMF_OK) { 2357 return (ret); 2358 } 2359 2360 /* Create an OCSP request */ 2361 req = OCSP_REQUEST_new(); 2362 if (req == NULL) { 2363 SET_ERROR(kmfh, ERR_get_error()); 2364 ret = KMF_ERR_OCSP_CREATE_REQUEST; 2365 goto end; 2366 } 2367 2368 if (!OCSP_request_add0_id(req, id)) { 2369 ret = KMF_ERR_OCSP_CREATE_REQUEST; 2370 goto end; 2371 } 2372 2373 /* Write the request to the output file with DER encoding */ 2374 derbio = BIO_new_file(reqfile, "wb"); 2375 if (!derbio) { 2376 SET_ERROR(kmfh, ERR_get_error()); 2377 ret = KMF_ERR_OPEN_FILE; 2378 goto end; 2379 } 2380 if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) { 2381 ret = KMF_ERR_ENCODING; 2382 } 2383 2384 end: 2385 /* 2386 * We don't need to free "id" explicitely, because OCSP_REQUEST_free() 2387 * will deallocate certid's space also. 2388 */ 2389 if (req != NULL) { 2390 OCSP_REQUEST_free(req); 2391 } 2392 2393 if (derbio != NULL) { 2394 (void) BIO_free(derbio); 2395 } 2396 2397 return (ret); 2398 } 2399 2400 /* ocsp_find_signer_sk() is copied from openssl source */ 2401 static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) 2402 { 2403 int i; 2404 unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash; 2405 2406 /* Easy if lookup by name */ 2407 if (id->type == V_OCSP_RESPID_NAME) 2408 return (X509_find_by_subject(certs, id->value.byName)); 2409 2410 /* Lookup by key hash */ 2411 2412 /* If key hash isn't SHA1 length then forget it */ 2413 if (id->value.byKey->length != SHA_DIGEST_LENGTH) 2414 return (NULL); 2415 2416 keyhash = id->value.byKey->data; 2417 /* Calculate hash of each key and compare */ 2418 for (i = 0; i < sk_X509_num(certs); i++) { 2419 /*LINTED*/ 2420 X509 *x = sk_X509_value(certs, i); 2421 (void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); 2422 if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) 2423 return (x); 2424 } 2425 return (NULL); 2426 } 2427 2428 /* ocsp_find_signer() is copied from openssl source */ 2429 /*ARGSUSED*/ 2430 static int 2431 ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs, 2432 X509_STORE *st, unsigned long flags) 2433 { 2434 X509 *signer; 2435 OCSP_RESPID *rid = bs->tbsResponseData->responderId; 2436 if ((signer = ocsp_find_signer_sk(certs, rid))) { 2437 *psigner = signer; 2438 return (2); 2439 } 2440 if (!(flags & OCSP_NOINTERN) && 2441 (signer = ocsp_find_signer_sk(bs->certs, rid))) { 2442 *psigner = signer; 2443 return (1); 2444 } 2445 /* Maybe lookup from store if by subject name */ 2446 2447 *psigner = NULL; 2448 return (0); 2449 } 2450 2451 /* 2452 * This function will verify the signature of a basic response, using 2453 * the public key from the OCSP responder certificate. 2454 */ 2455 static KMF_RETURN 2456 check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs, 2457 KMF_DATA *signer_cert, KMF_DATA *issuer_cert) 2458 { 2459 KMF_RETURN ret = KMF_OK; 2460 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 2461 STACK_OF(X509) *cert_stack = NULL; 2462 X509 *signer = NULL; 2463 X509 *issuer = NULL; 2464 EVP_PKEY *skey = NULL; 2465 unsigned char *ptmp; 2466 2467 2468 if (bs == NULL || issuer_cert == NULL) 2469 return (KMF_ERR_BAD_PARAMETER); 2470 2471 /* 2472 * Find the certificate that signed the basic response. 2473 * 2474 * If signer_cert is not NULL, we will use that as the signer cert. 2475 * Otherwise, we will check if the issuer cert is actually the signer. 2476 * If we still do not find a signer, we will look for it from the 2477 * certificate list came with the response file. 2478 */ 2479 if (signer_cert != NULL) { 2480 ptmp = signer_cert->Data; 2481 signer = d2i_X509(NULL, (const uchar_t **)&ptmp, 2482 signer_cert->Length); 2483 if (signer == NULL) { 2484 SET_ERROR(kmfh, ERR_get_error()); 2485 ret = KMF_ERR_OCSP_BAD_SIGNER; 2486 goto end; 2487 } 2488 } else { 2489 /* 2490 * Convert the issuer cert into X509 and push it into a 2491 * stack to be used by ocsp_find_signer(). 2492 */ 2493 ptmp = issuer_cert->Data; 2494 issuer = d2i_X509(NULL, (const uchar_t **)&ptmp, 2495 issuer_cert->Length); 2496 if (issuer == NULL) { 2497 SET_ERROR(kmfh, ERR_get_error()); 2498 ret = KMF_ERR_OCSP_BAD_ISSUER; 2499 goto end; 2500 } 2501 2502 if ((cert_stack = sk_X509_new_null()) == NULL) { 2503 ret = KMF_ERR_INTERNAL; 2504 goto end; 2505 } 2506 2507 if (sk_X509_push(cert_stack, issuer) == NULL) { 2508 ret = KMF_ERR_INTERNAL; 2509 goto end; 2510 } 2511 2512 ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0); 2513 if (!ret) { 2514 /* can not find the signer */ 2515 ret = KMF_ERR_OCSP_BAD_SIGNER; 2516 goto end; 2517 } 2518 } 2519 2520 /* Verify the signature of the response */ 2521 skey = X509_get_pubkey(signer); 2522 if (skey == NULL) { 2523 ret = KMF_ERR_OCSP_BAD_SIGNER; 2524 goto end; 2525 } 2526 2527 ret = OCSP_BASICRESP_verify(bs, skey, 0); 2528 if (ret == 0) { 2529 ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE; 2530 goto end; 2531 } 2532 2533 end: 2534 if (issuer != NULL) { 2535 X509_free(issuer); 2536 } 2537 2538 if (signer != NULL) { 2539 X509_free(signer); 2540 } 2541 2542 if (skey != NULL) { 2543 EVP_PKEY_free(skey); 2544 } 2545 2546 if (cert_stack != NULL) { 2547 sk_X509_free(cert_stack); 2548 } 2549 2550 return (ret); 2551 } 2552 2553 2554 2555 KMF_RETURN 2556 OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle, 2557 int numattr, KMF_ATTRIBUTE *attrlist) 2558 { 2559 KMF_RETURN ret = KMF_OK; 2560 BIO *derbio = NULL; 2561 OCSP_RESPONSE *resp = NULL; 2562 OCSP_BASICRESP *bs = NULL; 2563 OCSP_CERTID *id = NULL; 2564 OCSP_SINGLERESP *single = NULL; 2565 ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; 2566 int index, status, reason; 2567 KMF_DATA *issuer_cert; 2568 KMF_DATA *user_cert; 2569 KMF_DATA *signer_cert; 2570 KMF_DATA *response; 2571 int *response_reason, *response_status, *cert_status; 2572 boolean_t ignore_response_sign = B_FALSE; /* default is FALSE */ 2573 uint32_t response_lifetime; 2574 2575 issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR, 2576 attrlist, numattr); 2577 if (issuer_cert == NULL) 2578 return (KMF_ERR_BAD_PARAMETER); 2579 2580 user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR, 2581 attrlist, numattr); 2582 if (user_cert == NULL) 2583 return (KMF_ERR_BAD_PARAMETER); 2584 2585 response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR, 2586 attrlist, numattr); 2587 if (response == NULL) 2588 return (KMF_ERR_BAD_PARAMETER); 2589 2590 response_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR, 2591 attrlist, numattr); 2592 if (response_status == NULL) 2593 return (KMF_ERR_BAD_PARAMETER); 2594 2595 response_reason = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR, 2596 attrlist, numattr); 2597 if (response_reason == NULL) 2598 return (KMF_ERR_BAD_PARAMETER); 2599 2600 cert_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR, 2601 attrlist, numattr); 2602 if (cert_status == NULL) 2603 return (KMF_ERR_BAD_PARAMETER); 2604 2605 /* Read in the response */ 2606 derbio = BIO_new_mem_buf(response->Data, response->Length); 2607 if (!derbio) { 2608 ret = KMF_ERR_MEMORY; 2609 return (ret); 2610 } 2611 2612 resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); 2613 if (resp == NULL) { 2614 ret = KMF_ERR_OCSP_MALFORMED_RESPONSE; 2615 goto end; 2616 } 2617 2618 /* Check the response status */ 2619 status = OCSP_response_status(resp); 2620 *response_status = status; 2621 if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { 2622 ret = KMF_ERR_OCSP_RESPONSE_STATUS; 2623 goto end; 2624 } 2625 2626 #ifdef DEBUG 2627 printf("Successfully checked the response file status.\n"); 2628 #endif /* DEBUG */ 2629 2630 /* Extract basic response */ 2631 bs = OCSP_response_get1_basic(resp); 2632 if (bs == NULL) { 2633 ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE; 2634 goto end; 2635 } 2636 2637 #ifdef DEBUG 2638 printf("Successfully retrieved the basic response.\n"); 2639 #endif /* DEBUG */ 2640 2641 /* Check the basic response signature if required */ 2642 ret = kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR, attrlist, numattr, 2643 (void *)&ignore_response_sign, NULL); 2644 if (ret != KMF_OK) 2645 ret = KMF_OK; 2646 2647 signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR, 2648 attrlist, numattr); 2649 2650 if (ignore_response_sign == B_FALSE) { 2651 ret = check_response_signature(handle, bs, 2652 signer_cert, issuer_cert); 2653 if (ret != KMF_OK) 2654 goto end; 2655 } 2656 2657 #ifdef DEBUG 2658 printf("Successfully verified the response signature.\n"); 2659 #endif /* DEBUG */ 2660 2661 /* Create a certid for the certificate in question */ 2662 ret = create_certid(handle, issuer_cert, user_cert, &id); 2663 if (ret != KMF_OK) { 2664 ret = KMF_ERR_OCSP_CERTID; 2665 goto end; 2666 } 2667 2668 #ifdef DEBUG 2669 printf("successfully created a certid for the cert.\n"); 2670 #endif /* DEBUG */ 2671 2672 /* Find the index of the single response for the certid */ 2673 index = OCSP_resp_find(bs, id, -1); 2674 if (index < 0) { 2675 /* cound not find this certificate in the response */ 2676 ret = KMF_ERR_OCSP_UNKNOWN_CERT; 2677 goto end; 2678 } 2679 2680 #ifdef DEBUG 2681 printf("Successfully found the single response index for the cert.\n"); 2682 #endif /* DEBUG */ 2683 2684 /* Retrieve the single response and get the cert status */ 2685 single = OCSP_resp_get0(bs, index); 2686 status = OCSP_single_get0_status(single, &reason, &rev, &thisupd, 2687 &nextupd); 2688 if (status == V_OCSP_CERTSTATUS_GOOD) { 2689 *cert_status = OCSP_GOOD; 2690 } else if (status == V_OCSP_CERTSTATUS_UNKNOWN) { 2691 *cert_status = OCSP_UNKNOWN; 2692 } else { /* revoked */ 2693 *cert_status = OCSP_REVOKED; 2694 *response_reason = reason; 2695 } 2696 ret = KMF_OK; 2697 2698 /* resp. time is optional, so we don't care about the return code. */ 2699 (void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR, attrlist, numattr, 2700 (void *)&response_lifetime, NULL); 2701 2702 if (!OCSP_check_validity(thisupd, nextupd, 300, 2703 response_lifetime)) { 2704 ret = KMF_ERR_OCSP_STATUS_TIME_INVALID; 2705 goto end; 2706 } 2707 2708 #ifdef DEBUG 2709 printf("Successfully verify the time.\n"); 2710 #endif /* DEBUG */ 2711 2712 end: 2713 if (derbio != NULL) 2714 (void) BIO_free(derbio); 2715 2716 if (resp != NULL) 2717 OCSP_RESPONSE_free(resp); 2718 2719 if (bs != NULL) 2720 OCSP_BASICRESP_free(bs); 2721 2722 if (id != NULL) 2723 OCSP_CERTID_free(id); 2724 2725 return (ret); 2726 } 2727 2728 static KMF_RETURN 2729 fetch_key(KMF_HANDLE_T handle, char *path, 2730 KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key) 2731 { 2732 KMF_RETURN rv = KMF_OK; 2733 EVP_PKEY *pkey = NULL; 2734 KMF_RAW_SYM_KEY *rkey = NULL; 2735 2736 if (keyclass == KMF_ASYM_PRI || 2737 keyclass == KMF_ASYM_PUB) { 2738 pkey = openssl_load_key(handle, path); 2739 if (pkey == NULL) { 2740 return (KMF_ERR_KEY_NOT_FOUND); 2741 } 2742 if (key != NULL) { 2743 if (pkey->type == EVP_PKEY_RSA) 2744 key->keyalg = KMF_RSA; 2745 else if (pkey->type == EVP_PKEY_DSA) 2746 key->keyalg = KMF_DSA; 2747 2748 key->kstype = KMF_KEYSTORE_OPENSSL; 2749 key->keyclass = keyclass; 2750 key->keyp = (void *)pkey; 2751 key->israw = FALSE; 2752 key->keylabel = path; 2753 } else { 2754 EVP_PKEY_free(pkey); 2755 pkey = NULL; 2756 } 2757 } else if (keyclass == KMF_SYMMETRIC) { 2758 KMF_ENCODE_FORMAT fmt; 2759 /* 2760 * If the file is a recognized format, 2761 * then it is NOT a symmetric key. 2762 */ 2763 rv = kmf_get_file_format(path, &fmt); 2764 if (rv == KMF_OK || fmt != 0) { 2765 return (KMF_ERR_KEY_NOT_FOUND); 2766 } else if (rv == KMF_ERR_ENCODING) { 2767 /* 2768 * If we don't know the encoding, 2769 * it is probably a symmetric key. 2770 */ 2771 rv = KMF_OK; 2772 } else if (rv == KMF_ERR_OPEN_FILE) { 2773 return (KMF_ERR_KEY_NOT_FOUND); 2774 } 2775 2776 if (key != NULL) { 2777 KMF_DATA keyvalue; 2778 rkey = malloc(sizeof (KMF_RAW_SYM_KEY)); 2779 if (rkey == NULL) { 2780 rv = KMF_ERR_MEMORY; 2781 goto out; 2782 } 2783 2784 (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 2785 rv = kmf_read_input_file(handle, path, &keyvalue); 2786 if (rv != KMF_OK) 2787 goto out; 2788 2789 rkey->keydata.len = keyvalue.Length; 2790 rkey->keydata.val = keyvalue.Data; 2791 2792 key->kstype = KMF_KEYSTORE_OPENSSL; 2793 key->keyclass = keyclass; 2794 key->israw = TRUE; 2795 key->keylabel = path; 2796 key->keyp = (void *)rkey; 2797 } 2798 } 2799 out: 2800 if (rv != KMF_OK) { 2801 if (rkey != NULL) { 2802 kmf_free_raw_sym_key(rkey); 2803 } 2804 if (pkey != NULL) 2805 EVP_PKEY_free(pkey); 2806 2807 if (key != NULL) { 2808 key->keyalg = KMF_KEYALG_NONE; 2809 key->keyclass = KMF_KEYCLASS_NONE; 2810 key->keyp = NULL; 2811 } 2812 } 2813 2814 return (rv); 2815 } 2816 2817 KMF_RETURN 2818 OpenSSL_FindKey(KMF_HANDLE_T handle, 2819 int numattr, KMF_ATTRIBUTE *attrlist) 2820 { 2821 KMF_RETURN rv = KMF_OK; 2822 char *fullpath = NULL; 2823 uint32_t maxkeys; 2824 KMF_KEY_HANDLE *key; 2825 uint32_t *numkeys; 2826 KMF_KEY_CLASS keyclass; 2827 KMF_RAW_KEY_DATA *rawkey; 2828 char *dirpath; 2829 char *keyfile; 2830 2831 if (handle == NULL) 2832 return (KMF_ERR_BAD_PARAMETER); 2833 2834 numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr); 2835 if (numkeys == NULL) 2836 return (KMF_ERR_BAD_PARAMETER); 2837 2838 rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr, 2839 (void *)&keyclass, NULL); 2840 if (rv != KMF_OK) 2841 return (KMF_ERR_BAD_PARAMETER); 2842 2843 if (keyclass != KMF_ASYM_PUB && 2844 keyclass != KMF_ASYM_PRI && 2845 keyclass != KMF_SYMMETRIC) 2846 return (KMF_ERR_BAD_KEY_CLASS); 2847 2848 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 2849 keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); 2850 2851 fullpath = get_fullpath(dirpath, keyfile); 2852 2853 if (fullpath == NULL) 2854 return (KMF_ERR_BAD_PARAMETER); 2855 2856 maxkeys = *numkeys; 2857 if (maxkeys == 0) 2858 maxkeys = 0xFFFFFFFF; 2859 *numkeys = 0; 2860 2861 key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 2862 /* it is okay to have "keys" contains NULL */ 2863 2864 /* 2865 * The caller may want a list of the raw key data as well. 2866 * Useful for importing keys from a file into other keystores. 2867 */ 2868 rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr); 2869 2870 if (isdir(fullpath)) { 2871 DIR *dirp; 2872 struct dirent *dp; 2873 int n = 0; 2874 2875 /* open all files in the directory and attempt to read them */ 2876 if ((dirp = opendir(fullpath)) == NULL) { 2877 return (KMF_ERR_BAD_PARAMETER); 2878 } 2879 rewinddir(dirp); 2880 while ((dp = readdir(dirp)) != NULL && n < maxkeys) { 2881 if (strcmp(dp->d_name, ".") && 2882 strcmp(dp->d_name, "..")) { 2883 char *fname; 2884 2885 fname = get_fullpath(fullpath, 2886 (char *)&dp->d_name); 2887 2888 rv = fetch_key(handle, fname, 2889 keyclass, key ? &key[n] : NULL); 2890 2891 if (rv == KMF_OK) { 2892 if (key != NULL && rawkey != NULL) 2893 rv = convertToRawKey( 2894 key[n].keyp, &rawkey[n]); 2895 n++; 2896 } 2897 2898 if (rv != KMF_OK || key == NULL) 2899 free(fname); 2900 } 2901 } 2902 (void) closedir(dirp); 2903 free(fullpath); 2904 (*numkeys) = n; 2905 } else { 2906 rv = fetch_key(handle, fullpath, keyclass, key); 2907 if (rv == KMF_OK) 2908 (*numkeys) = 1; 2909 2910 if (rv != KMF_OK || key == NULL) 2911 free(fullpath); 2912 2913 if (rv == KMF_OK && key != NULL && rawkey != NULL) { 2914 rv = convertToRawKey(key->keyp, rawkey); 2915 } 2916 } 2917 2918 if (rv == KMF_OK && (*numkeys) == 0) 2919 rv = KMF_ERR_KEY_NOT_FOUND; 2920 2921 return (rv); 2922 } 2923 2924 #define HANDLE_PK12_ERROR { \ 2925 SET_ERROR(kmfh, ERR_get_error()); \ 2926 rv = KMF_ERR_ENCODING; \ 2927 goto out; \ 2928 } 2929 2930 static KMF_RETURN 2931 write_pkcs12(KMF_HANDLE *kmfh, 2932 BIO *bio, 2933 KMF_CREDENTIAL *cred, 2934 EVP_PKEY *pkey, 2935 X509 *sslcert) 2936 { 2937 KMF_RETURN rv = KMF_OK; 2938 STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL; 2939 PKCS12_SAFEBAG *bag = NULL; 2940 PKCS7 *cert_authsafe = NULL; 2941 PKCS8_PRIV_KEY_INFO *p8 = NULL; 2942 PKCS7 *key_authsafe = NULL; 2943 STACK_OF(PKCS7) *authsafe_stack = NULL; 2944 PKCS12 *p12_elem = NULL; 2945 char *lab = NULL; 2946 int lab_len = 0; 2947 unsigned char keyid[EVP_MAX_MD_SIZE]; 2948 unsigned int keyidlen = 0; 2949 2950 /* Must have at least a cert OR a key */ 2951 if (sslcert == NULL && pkey == NULL) 2952 return (KMF_ERR_BAD_PARAMETER); 2953 2954 (void) memset(keyid, 0, sizeof (keyid)); 2955 /* 2956 * Section 1: 2957 * 2958 * The first PKCS#12 container (safebag) will hold the certificates 2959 * associated with this key. The result of this section is a 2960 * PIN-encrypted PKCS#7 container (authsafe). If there are no 2961 * certificates, there is no point in creating the "safebag" or the 2962 * "authsafe" so we go to the next section. 2963 */ 2964 if (sslcert != NULL && pkey != NULL) { 2965 if (X509_check_private_key(sslcert, pkey)) { 2966 (void) X509_digest(sslcert, EVP_sha1(), keyid, 2967 &keyidlen); 2968 } else { 2969 /* The key doesn't match the cert */ 2970 HANDLE_PK12_ERROR 2971 } 2972 } 2973 2974 bag_stack = sk_PKCS12_SAFEBAG_new_null(); 2975 if (bag_stack == NULL) 2976 return (KMF_ERR_MEMORY); 2977 2978 if (sslcert != NULL) { 2979 /* Convert cert from X509 struct to PKCS#12 bag */ 2980 bag = PKCS12_x5092certbag(sslcert); 2981 if (bag == NULL) { 2982 HANDLE_PK12_ERROR 2983 } 2984 2985 /* Add the key id to the certificate bag. */ 2986 if (keyidlen > 0 && 2987 !PKCS12_add_localkeyid(bag, keyid, keyidlen)) { 2988 HANDLE_PK12_ERROR 2989 } 2990 2991 /* Pile it on the bag_stack. */ 2992 if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 2993 HANDLE_PK12_ERROR 2994 } 2995 #if 0 2996 /* No support for CA certs yet */ 2997 if (cacerts != NULL && ncacerts > 0) { 2998 int i; 2999 for (i = 0; i < ncacerts; i++) { 3000 KMF_X509_DER_CERT *c = &cacerts[i]; 3001 X509 *ca = NULL; 3002 3003 uchar_t *p = (uchar_t *)c->certificate.Data; 3004 ca = d2i_X509(NULL, &p, c->certificate.Length); 3005 if (ca == NULL) { 3006 HANDLE_PK12_ERROR 3007 } 3008 /* Convert CA cert to PKCS#12 bag. */ 3009 bag = PKCS12_x5092certbag(ca); 3010 if (bag == NULL) { 3011 sk_PKCS12_SAFEBAG_pop_free(bag_stack, 3012 PKCS12_SAFEBAG_free); 3013 HANDLE_PK12_ERROR 3014 } 3015 /* Pile it onto the bag_stack. */ 3016 if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 3017 HANDLE_PK12_ERROR 3018 } 3019 } 3020 } 3021 #endif 3022 /* Turn bag_stack of certs into encrypted authsafe. */ 3023 cert_authsafe = PKCS12_pack_p7encdata( 3024 NID_pbe_WithSHA1And40BitRC2_CBC, 3025 cred->cred, cred->credlen, NULL, 0, 3026 PKCS12_DEFAULT_ITER, bag_stack); 3027 3028 /* Clear away this bag_stack, we're done with it. */ 3029 sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 3030 bag_stack = NULL; 3031 3032 if (cert_authsafe == NULL) { 3033 HANDLE_PK12_ERROR 3034 } 3035 } 3036 /* 3037 * Section 2: 3038 * 3039 * The second PKCS#12 container (safebag) will hold the private key 3040 * that goes with the certificates above. The results of this section 3041 * is an unencrypted PKCS#7 container (authsafe). If there is no 3042 * private key, there is no point in creating the "safebag" or the 3043 * "authsafe" so we go to the next section. 3044 */ 3045 if (pkey != NULL) { 3046 p8 = EVP_PKEY2PKCS8(pkey); 3047 if (p8 == NULL) { 3048 HANDLE_PK12_ERROR 3049 } 3050 /* Put the shrouded key into a PKCS#12 bag. */ 3051 bag = PKCS12_MAKE_SHKEYBAG( 3052 NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 3053 cred->cred, cred->credlen, 3054 NULL, 0, PKCS12_DEFAULT_ITER, p8); 3055 3056 /* Clean up the PKCS#8 shrouded key, don't need it now. */ 3057 PKCS8_PRIV_KEY_INFO_free(p8); 3058 p8 = NULL; 3059 3060 if (bag == NULL) { 3061 HANDLE_PK12_ERROR 3062 } 3063 if (keyidlen && 3064 !PKCS12_add_localkeyid(bag, keyid, keyidlen)) { 3065 HANDLE_PK12_ERROR 3066 } 3067 if (lab != NULL) { 3068 if (!PKCS12_add_friendlyname(bag, 3069 (char *)lab, lab_len)) { 3070 HANDLE_PK12_ERROR 3071 } 3072 } 3073 /* Start a PKCS#12 safebag container for the private key. */ 3074 bag_stack = sk_PKCS12_SAFEBAG_new_null(); 3075 if (bag_stack == NULL) { 3076 HANDLE_PK12_ERROR 3077 } 3078 3079 /* Pile on the private key on the bag_stack. */ 3080 if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) { 3081 HANDLE_PK12_ERROR 3082 } 3083 key_authsafe = PKCS12_pack_p7data(bag_stack); 3084 3085 /* Clear away this bag_stack, we're done with it. */ 3086 sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 3087 bag_stack = NULL; 3088 3089 if (key_authsafe == NULL) { 3090 HANDLE_PK12_ERROR 3091 } 3092 } 3093 /* 3094 * Section 3: 3095 * 3096 * This is where the two PKCS#7 containers, one for the certificates 3097 * and one for the private key, are put together into a PKCS#12 3098 * element. This final PKCS#12 element is written to the export file. 3099 */ 3100 3101 /* Start a PKCS#7 stack. */ 3102 authsafe_stack = sk_PKCS7_new_null(); 3103 if (authsafe_stack == NULL) { 3104 HANDLE_PK12_ERROR 3105 } 3106 if (key_authsafe != NULL) { 3107 if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) { 3108 HANDLE_PK12_ERROR 3109 } 3110 } 3111 if (cert_authsafe != NULL) { 3112 if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) { 3113 HANDLE_PK12_ERROR 3114 } 3115 } 3116 p12_elem = PKCS12_init(NID_pkcs7_data); 3117 if (p12_elem == NULL) { 3118 sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 3119 HANDLE_PK12_ERROR 3120 } 3121 3122 /* Put the PKCS#7 stack into the PKCS#12 element. */ 3123 if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) { 3124 HANDLE_PK12_ERROR 3125 } 3126 /* Clear away the PKCS#7 stack, we're done with it. */ 3127 sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 3128 authsafe_stack = NULL; 3129 3130 /* Set the integrity MAC on the PKCS#12 element. */ 3131 if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen, 3132 NULL, 0, PKCS12_DEFAULT_ITER, NULL)) { 3133 HANDLE_PK12_ERROR 3134 } 3135 3136 /* Write the PKCS#12 element to the export file. */ 3137 if (!i2d_PKCS12_bio(bio, p12_elem)) { 3138 HANDLE_PK12_ERROR 3139 } 3140 3141 PKCS12_free(p12_elem); 3142 out: 3143 if (rv != KMF_OK) { 3144 /* Clear away this bag_stack, we're done with it. */ 3145 sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free); 3146 sk_PKCS7_pop_free(authsafe_stack, PKCS7_free); 3147 } 3148 return (rv); 3149 } 3150 3151 static EVP_PKEY * 3152 ImportRawRSAKey(KMF_RAW_RSA_KEY *key) 3153 { 3154 RSA *rsa = NULL; 3155 EVP_PKEY *newkey = NULL; 3156 3157 if ((rsa = RSA_new()) == NULL) 3158 return (NULL); 3159 3160 if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL) 3161 return (NULL); 3162 3163 if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) == 3164 NULL) 3165 return (NULL); 3166 3167 if (key->priexp.val != NULL) 3168 if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len, 3169 rsa->d)) == NULL) 3170 return (NULL); 3171 3172 if (key->prime1.val != NULL) 3173 if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len, 3174 rsa->p)) == NULL) 3175 return (NULL); 3176 3177 if (key->prime2.val != NULL) 3178 if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len, 3179 rsa->q)) == NULL) 3180 return (NULL); 3181 3182 if (key->exp1.val != NULL) 3183 if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len, 3184 rsa->dmp1)) == NULL) 3185 return (NULL); 3186 3187 if (key->exp2.val != NULL) 3188 if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len, 3189 rsa->dmq1)) == NULL) 3190 return (NULL); 3191 3192 if (key->coef.val != NULL) 3193 if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len, 3194 rsa->iqmp)) == NULL) 3195 return (NULL); 3196 3197 if ((newkey = EVP_PKEY_new()) == NULL) 3198 return (NULL); 3199 3200 (void) EVP_PKEY_set1_RSA(newkey, rsa); 3201 3202 /* The original key must be freed once here or it leaks memory */ 3203 RSA_free(rsa); 3204 3205 return (newkey); 3206 } 3207 3208 static EVP_PKEY * 3209 ImportRawDSAKey(KMF_RAW_DSA_KEY *key) 3210 { 3211 DSA *dsa = NULL; 3212 EVP_PKEY *newkey = NULL; 3213 3214 if ((dsa = DSA_new()) == NULL) 3215 return (NULL); 3216 3217 if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len, 3218 dsa->p)) == NULL) 3219 return (NULL); 3220 3221 if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len, 3222 dsa->q)) == NULL) 3223 return (NULL); 3224 3225 if ((dsa->g = BN_bin2bn(key->base.val, key->base.len, 3226 dsa->g)) == NULL) 3227 return (NULL); 3228 3229 if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len, 3230 dsa->priv_key)) == NULL) 3231 return (NULL); 3232 3233 if (key->pubvalue.val != NULL) { 3234 if ((dsa->pub_key = BN_bin2bn(key->pubvalue.val, 3235 key->pubvalue.len, dsa->pub_key)) == NULL) 3236 return (NULL); 3237 } 3238 3239 if ((newkey = EVP_PKEY_new()) == NULL) 3240 return (NULL); 3241 3242 (void) EVP_PKEY_set1_DSA(newkey, dsa); 3243 3244 /* The original key must be freed once here or it leaks memory */ 3245 DSA_free(dsa); 3246 return (newkey); 3247 } 3248 3249 static KMF_RETURN 3250 ExportPK12FromRawData(KMF_HANDLE_T handle, 3251 KMF_CREDENTIAL *cred, 3252 int numcerts, KMF_X509_DER_CERT *certlist, 3253 int numkeys, KMF_KEY_HANDLE *keylist, 3254 char *filename) 3255 { 3256 KMF_RETURN rv = KMF_OK; 3257 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3258 BIO *bio = NULL; 3259 X509 *xcert = NULL; 3260 EVP_PKEY *pkey = NULL; 3261 int i; 3262 3263 /* 3264 * Open the output file. 3265 */ 3266 if ((bio = BIO_new_file(filename, "wb")) == NULL) { 3267 SET_ERROR(kmfh, ERR_get_error()); 3268 rv = KMF_ERR_OPEN_FILE; 3269 goto cleanup; 3270 } 3271 3272 if (numcerts > 0 && numkeys > 0) { 3273 for (i = 0; rv == KMF_OK && i < numcerts; i++) { 3274 KMF_RAW_KEY_DATA *key = NULL; 3275 const uchar_t *p = certlist[i].certificate.Data; 3276 long len = certlist[i].certificate.Length; 3277 3278 if (i < numkeys) { 3279 key = (KMF_RAW_KEY_DATA *)keylist[i].keyp; 3280 3281 if (key->keytype == KMF_RSA) { 3282 pkey = ImportRawRSAKey( 3283 &key->rawdata.rsa); 3284 } else if (key->keytype == KMF_DSA) { 3285 pkey = ImportRawDSAKey( 3286 &key->rawdata.dsa); 3287 } else { 3288 rv = KMF_ERR_BAD_PARAMETER; 3289 } 3290 } 3291 3292 xcert = d2i_X509(NULL, &p, len); 3293 if (xcert == NULL) { 3294 SET_ERROR(kmfh, ERR_get_error()); 3295 rv = KMF_ERR_ENCODING; 3296 } 3297 /* Stick the key and the cert into a PKCS#12 file */ 3298 rv = write_pkcs12(kmfh, bio, cred, pkey, xcert); 3299 if (xcert) 3300 X509_free(xcert); 3301 if (pkey) 3302 EVP_PKEY_free(pkey); 3303 } 3304 } 3305 3306 cleanup: 3307 3308 if (bio != NULL) 3309 (void) BIO_free_all(bio); 3310 3311 return (rv); 3312 } 3313 3314 3315 KMF_RETURN 3316 openssl_build_pk12(KMF_HANDLE_T handle, int numcerts, 3317 KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist, 3318 KMF_CREDENTIAL *p12cred, char *filename) 3319 { 3320 KMF_RETURN rv; 3321 3322 if (certlist == NULL && keylist == NULL) 3323 return (KMF_ERR_BAD_PARAMETER); 3324 3325 rv = ExportPK12FromRawData(handle, p12cred, numcerts, certlist, 3326 numkeys, keylist, filename); 3327 3328 return (rv); 3329 } 3330 3331 3332 KMF_RETURN 3333 OpenSSL_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 3334 { 3335 KMF_RETURN rv; 3336 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 3337 BIO *bio = NULL; 3338 X509 *xcert = NULL; 3339 char *fullpath = NULL; 3340 EVP_PKEY *pkey = NULL; 3341 char *dirpath = NULL; 3342 char *certfile = NULL; 3343 char *keyfile = NULL; 3344 char *filename = NULL; 3345 KMF_CREDENTIAL *p12cred = NULL; 3346 3347 if (handle == NULL) 3348 return (KMF_ERR_BAD_PARAMETER); 3349 3350 /* 3351 * First, find the certificate. 3352 */ 3353 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 3354 certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); 3355 if (certfile != NULL) { 3356 fullpath = get_fullpath(dirpath, certfile); 3357 if (fullpath == NULL) 3358 return (KMF_ERR_BAD_PARAMETER); 3359 3360 if (isdir(fullpath)) { 3361 free(fullpath); 3362 return (KMF_ERR_AMBIGUOUS_PATHNAME); 3363 } 3364 3365 rv = load_X509cert(kmfh, NULL, NULL, NULL, fullpath, &xcert); 3366 if (rv != KMF_OK) 3367 goto end; 3368 3369 free(fullpath); 3370 } 3371 3372 /* 3373 * Now find the private key. 3374 */ 3375 keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); 3376 if (keyfile != NULL) { 3377 fullpath = get_fullpath(dirpath, keyfile); 3378 if (fullpath == NULL) 3379 return (KMF_ERR_BAD_PARAMETER); 3380 3381 if (isdir(fullpath)) { 3382 free(fullpath); 3383 return (KMF_ERR_AMBIGUOUS_PATHNAME); 3384 } 3385 3386 pkey = openssl_load_key(handle, fullpath); 3387 if (pkey == NULL) { 3388 rv = KMF_ERR_KEY_NOT_FOUND; 3389 goto end; 3390 } 3391 } 3392 3393 /* 3394 * Open the output file. 3395 */ 3396 filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist, 3397 numattr); 3398 if (filename == NULL) { 3399 rv = KMF_ERR_BAD_PARAMETER; 3400 goto end; 3401 } 3402 3403 if ((bio = BIO_new_file(filename, "wb")) == NULL) { 3404 SET_ERROR(kmfh, ERR_get_error()); 3405 rv = KMF_ERR_OPEN_FILE; 3406 goto end; 3407 } 3408 3409 /* Stick the key and the cert into a PKCS#12 file */ 3410 p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr); 3411 if (p12cred == NULL) { 3412 rv = KMF_ERR_BAD_PARAMETER; 3413 goto end; 3414 } 3415 3416 rv = write_pkcs12(kmfh, bio, p12cred, pkey, xcert); 3417 3418 end: 3419 if (fullpath) 3420 free(fullpath); 3421 if (xcert) 3422 X509_free(xcert); 3423 if (pkey) 3424 EVP_PKEY_free(pkey); 3425 if (bio) 3426 (void) BIO_free(bio); 3427 3428 return (rv); 3429 } 3430 3431 3432 #define MAX_CHAIN_LENGTH 100 3433 /* 3434 * Helper function to extract keys and certificates from 3435 * a single PEM file. Typically the file should contain a 3436 * private key and an associated public key wrapped in an x509 cert. 3437 * However, the file may be just a list of X509 certs with no keys. 3438 */ 3439 static KMF_RETURN 3440 extract_pem(KMF_HANDLE *kmfh, 3441 char *issuer, char *subject, KMF_BIGINT *serial, 3442 char *filename, CK_UTF8CHAR *pin, 3443 CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs, 3444 int *numcerts) 3445 /* ARGSUSED */ 3446 { 3447 KMF_RETURN rv = KMF_OK; 3448 FILE *fp; 3449 STACK_OF(X509_INFO) *x509_info_stack = NULL; 3450 int i, ncerts = 0, matchcerts = 0; 3451 EVP_PKEY *pkey = NULL; 3452 X509_INFO *info; 3453 X509 *x; 3454 X509_INFO *cert_infos[MAX_CHAIN_LENGTH]; 3455 KMF_DATA *certlist = NULL; 3456 3457 if (priv_key) 3458 *priv_key = NULL; 3459 if (certs) 3460 *certs = NULL; 3461 fp = fopen(filename, "r"); 3462 if (fp == NULL) { 3463 return (KMF_ERR_OPEN_FILE); 3464 } 3465 x509_info_stack = PEM_X509_INFO_read(fp, NULL, NULL, pin); 3466 if (x509_info_stack == NULL) { 3467 (void) fclose(fp); 3468 return (KMF_ERR_ENCODING); 3469 } 3470 3471 3472 for (i = 0; 3473 i < sk_X509_INFO_num(x509_info_stack) && i < MAX_CHAIN_LENGTH; 3474 i++) { 3475 /* LINTED */ 3476 cert_infos[ncerts] = sk_X509_INFO_value(x509_info_stack, i); 3477 ncerts++; 3478 } 3479 3480 if (ncerts == 0) { 3481 (void) fclose(fp); 3482 rv = KMF_ERR_CERT_NOT_FOUND; 3483 goto err; 3484 } 3485 3486 if (priv_key != NULL) { 3487 rewind(fp); 3488 pkey = PEM_read_PrivateKey(fp, NULL, NULL, pin); 3489 } 3490 (void) fclose(fp); 3491 3492 x = cert_infos[ncerts - 1]->x509; 3493 /* 3494 * Make sure the private key matchs the last cert in the file. 3495 */ 3496 if (pkey != NULL && !X509_check_private_key(x, pkey)) { 3497 EVP_PKEY_free(pkey); 3498 rv = KMF_ERR_KEY_MISMATCH; 3499 goto err; 3500 } 3501 3502 certlist = (KMF_DATA *)malloc(ncerts * sizeof (KMF_DATA)); 3503 if (certlist == NULL) { 3504 if (pkey != NULL) 3505 EVP_PKEY_free(pkey); 3506 rv = KMF_ERR_MEMORY; 3507 goto err; 3508 } 3509 3510 /* 3511 * Convert all of the certs to DER format. 3512 */ 3513 matchcerts = 0; 3514 for (i = 0; rv == KMF_OK && certs != NULL && i < ncerts; i++) { 3515 boolean_t match = FALSE; 3516 info = cert_infos[ncerts - 1 - i]; 3517 3518 rv = check_cert(info->x509, issuer, subject, serial, &match); 3519 if (rv != KMF_OK || match != TRUE) { 3520 rv = KMF_OK; 3521 continue; 3522 } 3523 3524 rv = ssl_cert2KMFDATA(kmfh, info->x509, 3525 &certlist[matchcerts++]); 3526 3527 if (rv != KMF_OK) { 3528 free(certlist); 3529 certlist = NULL; 3530 ncerts = matchcerts = 0; 3531 } 3532 } 3533 3534 if (numcerts != NULL) 3535 *numcerts = matchcerts; 3536 if (certs != NULL) 3537 *certs = certlist; 3538 3539 if (priv_key == NULL && pkey != NULL) 3540 EVP_PKEY_free(pkey); 3541 else if (priv_key != NULL && pkey != NULL) 3542 *priv_key = pkey; 3543 3544 err: 3545 /* Cleanup the stack of X509 info records */ 3546 for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) { 3547 /*LINTED*/ 3548 info = (X509_INFO *)sk_X509_INFO_value(x509_info_stack, i); 3549 X509_INFO_free(info); 3550 } 3551 if (x509_info_stack) 3552 sk_X509_INFO_free(x509_info_stack); 3553 3554 return (rv); 3555 } 3556 3557 /* 3558 * Helper function to decrypt and parse PKCS#12 import file. 3559 */ 3560 static KMF_RETURN 3561 extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen, 3562 EVP_PKEY **priv_key, X509 **cert, STACK_OF(X509) **ca) 3563 /* ARGSUSED */ 3564 { 3565 PKCS12 *pk12, *pk12_tmp; 3566 EVP_PKEY *temp_pkey = NULL; 3567 X509 *temp_cert = NULL; 3568 STACK_OF(X509) *temp_ca = NULL; 3569 3570 if ((pk12 = PKCS12_new()) == NULL) { 3571 return (KMF_ERR_MEMORY); 3572 } 3573 3574 if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) { 3575 /* This is ok; it seems to mean there is no more to read. */ 3576 if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 && 3577 ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG) 3578 goto end_extract_pkcs12; 3579 3580 PKCS12_free(pk12); 3581 return (KMF_ERR_PKCS12_FORMAT); 3582 } 3583 pk12 = pk12_tmp; 3584 3585 if (PKCS12_parse(pk12, (char *)pin, &temp_pkey, &temp_cert, 3586 &temp_ca) <= 0) { 3587 PKCS12_free(pk12); 3588 return (KMF_ERR_PKCS12_FORMAT); 3589 } 3590 3591 end_extract_pkcs12: 3592 3593 *priv_key = temp_pkey; 3594 *cert = temp_cert; 3595 *ca = temp_ca; 3596 3597 PKCS12_free(pk12); 3598 return (KMF_OK); 3599 } 3600 3601 static KMF_RETURN 3602 sslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to) 3603 { 3604 KMF_RETURN rv = KMF_OK; 3605 uint32_t sz; 3606 3607 sz = BN_num_bytes(from); 3608 to->val = (uchar_t *)malloc(sz); 3609 if (to->val == NULL) 3610 return (KMF_ERR_MEMORY); 3611 3612 if ((to->len = BN_bn2bin(from, to->val)) != sz) { 3613 free(to->val); 3614 to->val = NULL; 3615 to->len = 0; 3616 rv = KMF_ERR_MEMORY; 3617 } 3618 3619 return (rv); 3620 } 3621 3622 static KMF_RETURN 3623 exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key) 3624 { 3625 KMF_RETURN rv; 3626 KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa; 3627 3628 (void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY)); 3629 if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK) 3630 goto cleanup; 3631 3632 if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK) 3633 goto cleanup; 3634 3635 if (rsa->d != NULL) 3636 if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK) 3637 goto cleanup; 3638 3639 if (rsa->p != NULL) 3640 if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK) 3641 goto cleanup; 3642 3643 if (rsa->q != NULL) 3644 if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK) 3645 goto cleanup; 3646 3647 if (rsa->dmp1 != NULL) 3648 if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK) 3649 goto cleanup; 3650 3651 if (rsa->dmq1 != NULL) 3652 if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK) 3653 goto cleanup; 3654 3655 if (rsa->iqmp != NULL) 3656 if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK) 3657 goto cleanup; 3658 cleanup: 3659 if (rv != KMF_OK) 3660 kmf_free_raw_key(key); 3661 else 3662 key->keytype = KMF_RSA; 3663 3664 /* 3665 * Free the reference to this key, SSL will not actually free 3666 * the memory until the refcount == 0, so this is safe. 3667 */ 3668 RSA_free(rsa); 3669 3670 return (rv); 3671 } 3672 3673 static KMF_RETURN 3674 exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key) 3675 { 3676 KMF_RETURN rv; 3677 KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa; 3678 3679 (void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY)); 3680 if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK) 3681 goto cleanup; 3682 3683 if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK) 3684 goto cleanup; 3685 3686 if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK) 3687 goto cleanup; 3688 3689 if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK) 3690 goto cleanup; 3691 3692 cleanup: 3693 if (rv != KMF_OK) 3694 kmf_free_raw_key(key); 3695 else 3696 key->keytype = KMF_DSA; 3697 3698 /* 3699 * Free the reference to this key, SSL will not actually free 3700 * the memory until the refcount == 0, so this is safe. 3701 */ 3702 DSA_free(dsa); 3703 3704 return (rv); 3705 } 3706 3707 static KMF_RETURN 3708 add_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert, 3709 KMF_DATA **certlist, int *ncerts) 3710 { 3711 KMF_RETURN rv = KMF_OK; 3712 KMF_DATA *list = (*certlist); 3713 KMF_DATA cert; 3714 int n = (*ncerts); 3715 3716 if (list == NULL) { 3717 list = (KMF_DATA *)malloc(sizeof (KMF_DATA)); 3718 } else { 3719 list = (KMF_DATA *)realloc(list, sizeof (KMF_DATA) * (n + 1)); 3720 } 3721 3722 if (list == NULL) 3723 return (KMF_ERR_MEMORY); 3724 3725 rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert); 3726 if (rv == KMF_OK) { 3727 list[n] = cert; 3728 (*ncerts) = n + 1; 3729 3730 *certlist = list; 3731 } else { 3732 free(list); 3733 } 3734 3735 return (rv); 3736 } 3737 3738 static KMF_RETURN 3739 add_key_to_list(KMF_RAW_KEY_DATA **keylist, 3740 KMF_RAW_KEY_DATA *newkey, int *nkeys) 3741 { 3742 KMF_RAW_KEY_DATA *list = (*keylist); 3743 int n = (*nkeys); 3744 3745 if (list == NULL) { 3746 list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA)); 3747 } else { 3748 list = (KMF_RAW_KEY_DATA *)realloc(list, 3749 sizeof (KMF_RAW_KEY_DATA) * (n + 1)); 3750 } 3751 3752 if (list == NULL) 3753 return (KMF_ERR_MEMORY); 3754 3755 list[n] = *newkey; 3756 (*nkeys) = n + 1; 3757 3758 *keylist = list; 3759 3760 return (KMF_OK); 3761 } 3762 3763 static KMF_RETURN 3764 convertToRawKey(EVP_PKEY *pkey, KMF_RAW_KEY_DATA *key) 3765 { 3766 KMF_RETURN rv = KMF_OK; 3767 3768 if (pkey == NULL || key == NULL) 3769 return (KMF_ERR_BAD_PARAMETER); 3770 /* Convert SSL key to raw key */ 3771 switch (pkey->type) { 3772 case EVP_PKEY_RSA: 3773 rv = exportRawRSAKey(EVP_PKEY_get1_RSA(pkey), 3774 key); 3775 if (rv != KMF_OK) 3776 return (rv); 3777 break; 3778 case EVP_PKEY_DSA: 3779 rv = exportRawDSAKey(EVP_PKEY_get1_DSA(pkey), 3780 key); 3781 if (rv != KMF_OK) 3782 return (rv); 3783 break; 3784 default: 3785 return (KMF_ERR_BAD_PARAMETER); 3786 } 3787 3788 return (rv); 3789 } 3790 3791 static KMF_RETURN 3792 convertPK12Objects( 3793 KMF_HANDLE *kmfh, 3794 EVP_PKEY *sslkey, X509 *sslcert, STACK_OF(X509) *sslcacerts, 3795 KMF_RAW_KEY_DATA **keylist, int *nkeys, 3796 KMF_DATA **certlist, int *ncerts) 3797 { 3798 KMF_RETURN rv = KMF_OK; 3799 KMF_RAW_KEY_DATA key; 3800 int i; 3801 3802 if (sslkey != NULL) { 3803 rv = convertToRawKey(sslkey, &key); 3804 if (rv == KMF_OK) 3805 rv = add_key_to_list(keylist, &key, nkeys); 3806 3807 if (rv != KMF_OK) 3808 return (rv); 3809 } 3810 3811 /* Now add the certificate to the certlist */ 3812 if (sslcert != NULL) { 3813 rv = add_cert_to_list(kmfh, sslcert, certlist, ncerts); 3814 if (rv != KMF_OK) 3815 return (rv); 3816 } 3817 3818 /* Also add any included CA certs to the list */ 3819 for (i = 0; sslcacerts != NULL && i < sk_X509_num(sslcacerts); i++) { 3820 X509 *c; 3821 /* 3822 * sk_X509_value() is macro that embeds a cast to (X509 *). 3823 * Here it translates into ((X509 *)sk_value((ca), (i))). 3824 * Lint is complaining about the embedded casting, and 3825 * to fix it, you need to fix openssl header files. 3826 */ 3827 /* LINTED E_BAD_PTR_CAST_ALIGN */ 3828 c = sk_X509_value(sslcacerts, i); 3829 3830 /* Now add the ca cert to the certlist */ 3831 rv = add_cert_to_list(kmfh, c, certlist, ncerts); 3832 if (rv != KMF_OK) 3833 return (rv); 3834 } 3835 return (rv); 3836 } 3837 3838 KMF_RETURN 3839 openssl_import_objects(KMF_HANDLE *kmfh, 3840 char *filename, KMF_CREDENTIAL *cred, 3841 KMF_DATA **certlist, int *ncerts, 3842 KMF_RAW_KEY_DATA **keylist, int *nkeys) 3843 { 3844 KMF_RETURN rv = KMF_OK; 3845 EVP_PKEY *privkey = NULL; 3846 KMF_ENCODE_FORMAT format; 3847 BIO *bio = NULL; 3848 X509 *cert = NULL; 3849 STACK_OF(X509) *cacerts = NULL; 3850 3851 /* 3852 * auto-detect the file format, regardless of what 3853 * the 'format' parameters in the params say. 3854 */ 3855 rv = kmf_get_file_format(filename, &format); 3856 if (rv != KMF_OK) { 3857 return (rv); 3858 } 3859 3860 /* This function only works for PEM or PKCS#12 files */ 3861 if (format != KMF_FORMAT_PEM && 3862 format != KMF_FORMAT_PEM_KEYPAIR && 3863 format != KMF_FORMAT_PKCS12) 3864 return (KMF_ERR_ENCODING); 3865 3866 *certlist = NULL; 3867 *keylist = NULL; 3868 *ncerts = 0; 3869 *nkeys = 0; 3870 3871 if (format == KMF_FORMAT_PKCS12) { 3872 bio = BIO_new_file(filename, "rb"); 3873 if (bio == NULL) { 3874 SET_ERROR(kmfh, ERR_get_error()); 3875 rv = KMF_ERR_OPEN_FILE; 3876 goto end; 3877 } 3878 3879 rv = extract_pkcs12(bio, (uchar_t *)cred->cred, 3880 (uint32_t)cred->credlen, &privkey, &cert, &cacerts); 3881 3882 if (rv == KMF_OK) 3883 /* Convert keys and certs to exportable format */ 3884 rv = convertPK12Objects(kmfh, privkey, cert, cacerts, 3885 keylist, nkeys, certlist, ncerts); 3886 3887 } else { 3888 rv = extract_pem(kmfh, NULL, NULL, NULL, filename, 3889 (uchar_t *)cred->cred, (uint32_t)cred->credlen, 3890 &privkey, certlist, ncerts); 3891 3892 /* Reached end of import file? */ 3893 if (rv == KMF_OK) 3894 /* Convert keys and certs to exportable format */ 3895 rv = convertPK12Objects(kmfh, privkey, NULL, NULL, 3896 keylist, nkeys, NULL, NULL); 3897 } 3898 3899 end: 3900 if (privkey) 3901 EVP_PKEY_free(privkey); 3902 3903 if (bio != NULL) 3904 (void) BIO_free(bio); 3905 3906 if (cert) 3907 X509_free(cert); 3908 3909 if (cacerts) 3910 sk_X509_free(cacerts); 3911 3912 return (rv); 3913 } 3914 3915 static KMF_RETURN 3916 create_deskey(DES_cblock **deskey) 3917 { 3918 DES_cblock *key; 3919 3920 key = (DES_cblock *) malloc(sizeof (DES_cblock)); 3921 if (key == NULL) { 3922 return (KMF_ERR_MEMORY); 3923 } 3924 3925 if (DES_random_key(key) == 0) { 3926 free(key); 3927 return (KMF_ERR_KEYGEN_FAILED); 3928 } 3929 3930 *deskey = key; 3931 return (KMF_OK); 3932 } 3933 3934 #define KEYGEN_RETRY 3 3935 #define DES3_KEY_SIZE 24 3936 3937 static KMF_RETURN 3938 create_des3key(unsigned char **des3key) 3939 { 3940 KMF_RETURN ret = KMF_OK; 3941 DES_cblock *deskey1 = NULL; 3942 DES_cblock *deskey2 = NULL; 3943 DES_cblock *deskey3 = NULL; 3944 unsigned char *newkey = NULL; 3945 int retry; 3946 3947 if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) { 3948 return (KMF_ERR_MEMORY); 3949 } 3950 3951 /* create the 1st DES key */ 3952 if ((ret = create_deskey(&deskey1)) != KMF_OK) { 3953 goto out; 3954 } 3955 3956 /* 3957 * Create the 2nd DES key and make sure its value is different 3958 * from the 1st DES key. 3959 */ 3960 retry = 0; 3961 do { 3962 if (deskey2 != NULL) { 3963 free(deskey2); 3964 deskey2 = NULL; 3965 } 3966 3967 if ((ret = create_deskey(&deskey2)) != KMF_OK) { 3968 goto out; 3969 } 3970 3971 if (memcmp((const void *) deskey1, (const void *) deskey2, 8) 3972 == 0) { 3973 ret = KMF_ERR_KEYGEN_FAILED; 3974 retry++; 3975 } 3976 } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY); 3977 3978 if (ret != KMF_OK) { 3979 goto out; 3980 } 3981 3982 /* 3983 * Create the 3rd DES key and make sure its value is different 3984 * from the 2nd DES key. 3985 */ 3986 retry = 0; 3987 do { 3988 if (deskey3 != NULL) { 3989 free(deskey3); 3990 deskey3 = NULL; 3991 } 3992 3993 if ((ret = create_deskey(&deskey3)) != KMF_OK) { 3994 goto out; 3995 } 3996 3997 if (memcmp((const void *)deskey2, (const void *)deskey3, 8) 3998 == 0) { 3999 ret = KMF_ERR_KEYGEN_FAILED; 4000 retry++; 4001 } 4002 } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY); 4003 4004 if (ret != KMF_OK) { 4005 goto out; 4006 } 4007 4008 /* Concatenate 3 DES keys into a DES3 key */ 4009 (void) memcpy((void *)newkey, (const void *)deskey1, 8); 4010 (void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8); 4011 (void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8); 4012 *des3key = newkey; 4013 4014 out: 4015 if (deskey1 != NULL) 4016 free(deskey1); 4017 4018 if (deskey2 != NULL) 4019 free(deskey2); 4020 4021 if (deskey3 != NULL) 4022 free(deskey3); 4023 4024 if (ret != KMF_OK && newkey != NULL) 4025 free(newkey); 4026 4027 return (ret); 4028 } 4029 4030 KMF_RETURN 4031 OpenSSL_CreateSymKey(KMF_HANDLE_T handle, 4032 int numattr, KMF_ATTRIBUTE *attrlist) 4033 { 4034 KMF_RETURN ret = KMF_OK; 4035 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4036 char *fullpath = NULL; 4037 KMF_RAW_SYM_KEY *rkey = NULL; 4038 DES_cblock *deskey = NULL; 4039 unsigned char *des3key = NULL; 4040 unsigned char *random = NULL; 4041 int fd = -1; 4042 KMF_KEY_HANDLE *symkey; 4043 KMF_KEY_ALG keytype; 4044 uint32_t keylen; 4045 uint32_t keylen_size = sizeof (keylen); 4046 char *dirpath; 4047 char *keyfile; 4048 4049 if (kmfh == NULL) 4050 return (KMF_ERR_UNINITIALIZED); 4051 4052 symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr); 4053 if (symkey == NULL) 4054 return (KMF_ERR_BAD_PARAMETER); 4055 4056 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 4057 4058 keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr); 4059 if (keyfile == NULL) 4060 return (KMF_ERR_BAD_PARAMETER); 4061 4062 ret = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, 4063 (void *)&keytype, NULL); 4064 if (ret != KMF_OK) 4065 return (KMF_ERR_BAD_PARAMETER); 4066 4067 ret = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, 4068 &keylen, &keylen_size); 4069 if (ret == KMF_ERR_ATTR_NOT_FOUND && 4070 (keytype == KMF_DES || keytype == KMF_DES3)) 4071 /* keylength is not required for DES and 3DES */ 4072 ret = KMF_OK; 4073 if (ret != KMF_OK) 4074 return (KMF_ERR_BAD_PARAMETER); 4075 4076 fullpath = get_fullpath(dirpath, keyfile); 4077 if (fullpath == NULL) 4078 return (KMF_ERR_BAD_PARAMETER); 4079 4080 /* If the requested file exists, return an error */ 4081 if (test_for_file(fullpath, 0400) == 1) { 4082 free(fullpath); 4083 return (KMF_ERR_DUPLICATE_KEYFILE); 4084 } 4085 4086 fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400); 4087 if (fd == -1) { 4088 ret = KMF_ERR_OPEN_FILE; 4089 goto out; 4090 } 4091 4092 rkey = malloc(sizeof (KMF_RAW_SYM_KEY)); 4093 if (rkey == NULL) { 4094 ret = KMF_ERR_MEMORY; 4095 goto out; 4096 } 4097 (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY)); 4098 4099 if (keytype == KMF_DES) { 4100 if ((ret = create_deskey(&deskey)) != KMF_OK) { 4101 goto out; 4102 } 4103 rkey->keydata.val = (uchar_t *)deskey; 4104 rkey->keydata.len = 8; 4105 4106 symkey->keyalg = KMF_DES; 4107 4108 } else if (keytype == KMF_DES3) { 4109 if ((ret = create_des3key(&des3key)) != KMF_OK) { 4110 goto out; 4111 } 4112 rkey->keydata.val = (uchar_t *)des3key; 4113 rkey->keydata.len = DES3_KEY_SIZE; 4114 symkey->keyalg = KMF_DES3; 4115 4116 } else if (keytype == KMF_AES || keytype == KMF_RC4 || 4117 keytype == KMF_GENERIC_SECRET) { 4118 int bytes; 4119 4120 if (keylen % 8 != 0) { 4121 ret = KMF_ERR_BAD_KEY_SIZE; 4122 goto out; 4123 } 4124 4125 if (keytype == KMF_AES) { 4126 if (keylen != 128 && 4127 keylen != 192 && 4128 keylen != 256) { 4129 ret = KMF_ERR_BAD_KEY_SIZE; 4130 goto out; 4131 } 4132 } 4133 4134 bytes = keylen/8; 4135 random = malloc(bytes); 4136 if (random == NULL) { 4137 ret = KMF_ERR_MEMORY; 4138 goto out; 4139 } 4140 if (RAND_bytes(random, bytes) != 1) { 4141 ret = KMF_ERR_KEYGEN_FAILED; 4142 goto out; 4143 } 4144 4145 rkey->keydata.val = (uchar_t *)random; 4146 rkey->keydata.len = bytes; 4147 symkey->keyalg = keytype; 4148 4149 } else { 4150 ret = KMF_ERR_BAD_KEY_TYPE; 4151 goto out; 4152 } 4153 4154 (void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len); 4155 4156 symkey->kstype = KMF_KEYSTORE_OPENSSL; 4157 symkey->keyclass = KMF_SYMMETRIC; 4158 symkey->keylabel = (char *)fullpath; 4159 symkey->israw = TRUE; 4160 symkey->keyp = rkey; 4161 4162 out: 4163 if (fd != -1) 4164 (void) close(fd); 4165 4166 if (ret != KMF_OK && fullpath != NULL) { 4167 free(fullpath); 4168 } 4169 if (ret != KMF_OK) { 4170 kmf_free_raw_sym_key(rkey); 4171 symkey->keyp = NULL; 4172 symkey->keyalg = KMF_KEYALG_NONE; 4173 } 4174 4175 return (ret); 4176 } 4177 4178 /* 4179 * Check a file to see if it is a CRL file with PEM or DER format. 4180 * If success, return its format in the "pformat" argument. 4181 */ 4182 KMF_RETURN 4183 OpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat) 4184 { 4185 KMF_RETURN ret = KMF_OK; 4186 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4187 BIO *bio = NULL; 4188 X509_CRL *xcrl = NULL; 4189 4190 if (filename == NULL) { 4191 return (KMF_ERR_BAD_PARAMETER); 4192 } 4193 4194 bio = BIO_new_file(filename, "rb"); 4195 if (bio == NULL) { 4196 SET_ERROR(kmfh, ERR_get_error()); 4197 ret = KMF_ERR_OPEN_FILE; 4198 goto out; 4199 } 4200 4201 if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) { 4202 *pformat = KMF_FORMAT_PEM; 4203 goto out; 4204 } 4205 (void) BIO_free(bio); 4206 4207 /* 4208 * Now try to read it as raw DER data. 4209 */ 4210 bio = BIO_new_file(filename, "rb"); 4211 if (bio == NULL) { 4212 SET_ERROR(kmfh, ERR_get_error()); 4213 ret = KMF_ERR_OPEN_FILE; 4214 goto out; 4215 } 4216 4217 if ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) { 4218 *pformat = KMF_FORMAT_ASN1; 4219 } else { 4220 ret = KMF_ERR_BAD_CRLFILE; 4221 } 4222 4223 out: 4224 if (bio != NULL) 4225 (void) BIO_free(bio); 4226 4227 if (xcrl != NULL) 4228 X509_CRL_free(xcrl); 4229 4230 return (ret); 4231 } 4232 4233 /* 4234 * Check a file to see if it is a certficate file with PEM or DER format. 4235 * If success, return its format in the pformat argument. 4236 */ 4237 KMF_RETURN 4238 OpenSSL_IsCertFile(KMF_HANDLE_T handle, char *filename, 4239 KMF_ENCODE_FORMAT *pformat) 4240 { 4241 KMF_RETURN ret = KMF_OK; 4242 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4243 BIO *bio = NULL; 4244 X509 *xcert = NULL; 4245 4246 if (filename == NULL) { 4247 return (KMF_ERR_BAD_PARAMETER); 4248 } 4249 4250 ret = kmf_get_file_format(filename, pformat); 4251 if (ret != KMF_OK) 4252 return (ret); 4253 4254 bio = BIO_new_file(filename, "rb"); 4255 if (bio == NULL) { 4256 SET_ERROR(kmfh, ERR_get_error()); 4257 ret = KMF_ERR_OPEN_FILE; 4258 goto out; 4259 } 4260 4261 if ((*pformat) == KMF_FORMAT_PEM) { 4262 if ((xcert = PEM_read_bio_X509(bio, NULL, 4263 NULL, NULL)) == NULL) { 4264 ret = KMF_ERR_BAD_CERTFILE; 4265 } 4266 } else if ((*pformat) == KMF_FORMAT_ASN1) { 4267 if ((xcert = d2i_X509_bio(bio, NULL)) == NULL) { 4268 ret = KMF_ERR_BAD_CERTFILE; 4269 } 4270 } else { 4271 ret = KMF_ERR_BAD_CERTFILE; 4272 } 4273 4274 out: 4275 if (bio != NULL) 4276 (void) BIO_free(bio); 4277 4278 if (xcert != NULL) 4279 X509_free(xcert); 4280 4281 return (ret); 4282 } 4283 4284 KMF_RETURN 4285 OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, 4286 KMF_RAW_SYM_KEY *rkey) 4287 { 4288 KMF_RETURN rv = KMF_OK; 4289 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4290 KMF_DATA keyvalue; 4291 4292 if (kmfh == NULL) 4293 return (KMF_ERR_UNINITIALIZED); 4294 4295 if (symkey == NULL || rkey == NULL) 4296 return (KMF_ERR_BAD_PARAMETER); 4297 else if (symkey->keyclass != KMF_SYMMETRIC) 4298 return (KMF_ERR_BAD_KEY_CLASS); 4299 4300 if (symkey->israw) { 4301 KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp; 4302 4303 if (rawkey == NULL || 4304 rawkey->keydata.val == NULL || 4305 rawkey->keydata.len == 0) 4306 return (KMF_ERR_BAD_KEYHANDLE); 4307 4308 rkey->keydata.len = rawkey->keydata.len; 4309 if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL) 4310 return (KMF_ERR_MEMORY); 4311 (void) memcpy(rkey->keydata.val, rawkey->keydata.val, 4312 rkey->keydata.len); 4313 } else { 4314 rv = kmf_read_input_file(handle, symkey->keylabel, &keyvalue); 4315 if (rv != KMF_OK) 4316 return (rv); 4317 rkey->keydata.len = keyvalue.Length; 4318 rkey->keydata.val = keyvalue.Data; 4319 } 4320 4321 return (rv); 4322 } 4323 4324 /* 4325 * id-sha1 OBJECT IDENTIFIER ::= { 4326 * iso(1) identified-organization(3) oiw(14) secsig(3) 4327 * algorithms(2) 26 4328 * } 4329 */ 4330 #define ASN1_SHA1_OID_PREFIX_LEN 15 4331 static uchar_t SHA1_DER_PREFIX[ASN1_SHA1_OID_PREFIX_LEN] = { 4332 0x30, 0x21, 0x30, 0x09, 4333 0x06, 0x05, 0x2b, 0x0e, 4334 0x03, 0x02, 0x1a, 0x05, 4335 0x00, 0x04, 0x14 4336 }; 4337 4338 /* 4339 * id-md2 OBJECT IDENTIFIER ::= { 4340 * iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2 4341 * } 4342 */ 4343 #define ASN1_MD2_OID_PREFIX_LEN 18 4344 static uchar_t MD2_DER_PREFIX[ASN1_MD2_OID_PREFIX_LEN] = { 4345 0x30, 0x20, 0x30, 0x0c, 4346 0x06, 0x08, 0x2a, 0x86, 4347 0x48, 0x86, 0xf7, 0x0d, 4348 0x02, 0x02, 0x05, 0x00, 4349 0x04, 0x10 4350 }; 4351 4352 /* 4353 * id-md5 OBJECT IDENTIFIER ::= { 4354 * iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 4355 * } 4356 */ 4357 #define ASN1_MD5_OID_PREFIX_LEN 18 4358 static uchar_t MD5_DER_PREFIX[ASN1_MD5_OID_PREFIX_LEN] = { 4359 0x30, 0x20, 0x30, 0x0c, 4360 0x06, 0x08, 0x2a, 0x86, 4361 0x48, 0x86, 0xf7, 0x0d, 4362 0x02, 0x05, 0x05, 0x00, 4363 0x04, 0x10 4364 }; 4365 4366 KMF_RETURN 4367 OpenSSL_VerifyDataWithCert(KMF_HANDLE_T handle, 4368 KMF_ALGORITHM_INDEX algid, KMF_DATA *indata, 4369 KMF_DATA *insig, KMF_DATA *cert) 4370 { 4371 KMF_RETURN ret = KMF_OK; 4372 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4373 X509 *xcert = NULL; 4374 EVP_PKEY *pkey = NULL; 4375 uchar_t *p; 4376 uchar_t *rsaout = NULL; 4377 uchar_t *pfx = NULL; 4378 const EVP_MD *md; 4379 int pfxlen = 0, len; 4380 4381 if (handle == NULL || indata == NULL || 4382 indata->Data == NULL || indata->Length == 0 || 4383 insig == NULL|| insig->Data == NULL || insig->Length == 0 || 4384 cert == NULL || cert->Data == NULL || cert->Length == 0) 4385 return (KMF_ERR_BAD_PARAMETER); 4386 4387 p = cert->Data; 4388 xcert = d2i_X509(NULL, (const uchar_t **)&p, cert->Length); 4389 if (xcert == NULL) { 4390 SET_ERROR(kmfh, ERR_get_error()); 4391 ret = KMF_ERR_BAD_CERT_FORMAT; 4392 goto cleanup; 4393 } 4394 4395 pkey = X509_get_pubkey(xcert); 4396 if (pkey == NULL) { 4397 SET_ERROR(kmfh, ERR_get_error()); 4398 ret = KMF_ERR_BAD_CERT_FORMAT; 4399 goto cleanup; 4400 } 4401 4402 if (algid != KMF_ALGID_NONE) { 4403 switch (algid) { 4404 case KMF_ALGID_MD5WithRSA: 4405 md = EVP_md5(); 4406 break; 4407 case KMF_ALGID_MD2WithRSA: 4408 md = EVP_md2(); 4409 break; 4410 case KMF_ALGID_SHA1WithRSA: 4411 md = EVP_sha1(); 4412 break; 4413 case KMF_ALGID_RSA: 4414 md = NULL; 4415 break; 4416 default: 4417 ret = KMF_ERR_BAD_PARAMETER; 4418 goto cleanup; 4419 } 4420 } else { 4421 /* Get the hash type from the cert signature */ 4422 md = EVP_get_digestbyobj(xcert->sig_alg->algorithm); 4423 if (md == NULL) { 4424 SET_ERROR(kmfh, ERR_get_error()); 4425 ret = KMF_ERR_BAD_PARAMETER; 4426 goto cleanup; 4427 } 4428 } 4429 if (md != NULL) { 4430 switch (EVP_MD_type(md)) { 4431 case NID_md2: 4432 case NID_md2WithRSAEncryption: 4433 pfxlen = ASN1_MD2_OID_PREFIX_LEN; 4434 pfx = MD2_DER_PREFIX; 4435 break; 4436 case NID_md5: 4437 case NID_md5WithRSAEncryption: 4438 pfxlen = ASN1_MD5_OID_PREFIX_LEN; 4439 pfx = MD5_DER_PREFIX; 4440 break; 4441 case NID_sha1: 4442 case NID_sha1WithRSAEncryption: 4443 pfxlen = ASN1_SHA1_OID_PREFIX_LEN; 4444 pfx = SHA1_DER_PREFIX; 4445 break; 4446 default: /* Unsupported */ 4447 pfxlen = 0; 4448 pfx = NULL; 4449 break; 4450 } 4451 } 4452 4453 /* RSA with no hash is a special case */ 4454 rsaout = malloc(RSA_size(pkey->pkey.rsa)); 4455 if (rsaout == NULL) 4456 return (KMF_ERR_MEMORY); 4457 4458 /* Decrypt the input signature */ 4459 len = RSA_public_decrypt(insig->Length, 4460 insig->Data, rsaout, pkey->pkey.rsa, RSA_PKCS1_PADDING); 4461 if (len < 1) { 4462 SET_ERROR(kmfh, ERR_get_error()); 4463 ret = KMF_ERR_BAD_PARAMETER; 4464 } else { 4465 size_t hashlen = 0; 4466 uint32_t dlen; 4467 char *digest = NULL; 4468 4469 /* 4470 * If the AlgId requires it, hash the input data before 4471 * comparing it to the decrypted signature. 4472 */ 4473 if (md) { 4474 EVP_MD_CTX ctx; 4475 4476 hashlen = md->md_size; 4477 4478 digest = malloc(hashlen + pfxlen); 4479 if (digest == NULL) 4480 return (KMF_ERR_MEMORY); 4481 /* Add the prefix to the comparison buffer. */ 4482 if (pfx && pfxlen > 0) { 4483 (void) memcpy(digest, pfx, pfxlen); 4484 } 4485 (void) EVP_DigestInit(&ctx, md); 4486 (void) EVP_DigestUpdate(&ctx, indata->Data, 4487 indata->Length); 4488 4489 /* Add the digest AFTER the ASN1 prefix */ 4490 (void) EVP_DigestFinal(&ctx, 4491 (uchar_t *)digest + pfxlen, &dlen); 4492 4493 dlen += pfxlen; 4494 } else { 4495 digest = (char *)indata->Data; 4496 dlen = indata->Length; 4497 } 4498 4499 /* 4500 * The result of the RSA decryption should be ASN1(OID | Hash). 4501 * Compare the output hash to the input data for the final 4502 * result. 4503 */ 4504 if (memcmp(rsaout, digest, dlen)) 4505 ret = KMF_ERR_INTERNAL; 4506 else 4507 ret = KMF_OK; 4508 4509 /* If we had to allocate space for the digest, free it now */ 4510 if (hashlen) 4511 free(digest); 4512 } 4513 cleanup: 4514 if (pkey) 4515 EVP_PKEY_free(pkey); 4516 4517 if (xcert) 4518 X509_free(xcert); 4519 4520 if (rsaout) 4521 free(rsaout); 4522 4523 return (ret); 4524 } 4525 4526 /* 4527 * substitute for the unsafe access(2) function. 4528 * If the file in question already exists, return 1. 4529 * else 0. If an error occurs during testing (other 4530 * than EEXIST), return -1. 4531 */ 4532 static int 4533 test_for_file(char *filename, mode_t mode) 4534 { 4535 int fd; 4536 4537 /* 4538 * Try to create the file with the EXCL flag. 4539 * The call should fail if the file exists. 4540 */ 4541 fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode); 4542 if (fd == -1 && errno == EEXIST) 4543 return (1); 4544 else if (fd == -1) /* some other error */ 4545 return (-1); 4546 4547 /* The file did NOT exist. Delete the testcase. */ 4548 (void) close(fd); 4549 (void) unlink(filename); 4550 return (0); 4551 } 4552 4553 KMF_RETURN 4554 OpenSSL_StoreKey(KMF_HANDLE_T handle, int numattr, 4555 KMF_ATTRIBUTE *attrlist) 4556 { 4557 KMF_RETURN rv = KMF_OK; 4558 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4559 KMF_KEY_HANDLE *pubkey = NULL, *prikey = NULL; 4560 KMF_RAW_KEY_DATA *rawkey; 4561 EVP_PKEY *pkey = NULL; 4562 KMF_ENCODE_FORMAT format = KMF_FORMAT_PEM; 4563 KMF_CREDENTIAL cred = {NULL, 0}; 4564 BIO *out = NULL; 4565 int keys = 0; 4566 char *fullpath = NULL; 4567 char *keyfile = NULL; 4568 char *dirpath = NULL; 4569 4570 pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr); 4571 if (pubkey != NULL) 4572 keys++; 4573 4574 prikey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr); 4575 if (prikey != NULL) 4576 keys++; 4577 4578 rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr); 4579 if (rawkey != NULL) 4580 keys++; 4581 4582 /* 4583 * Exactly 1 type of key must be passed to this function. 4584 */ 4585 if (keys != 1) 4586 return (KMF_ERR_BAD_PARAMETER); 4587 4588 keyfile = (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, 4589 numattr); 4590 if (keyfile == NULL) 4591 return (KMF_ERR_BAD_PARAMETER); 4592 4593 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 4594 4595 fullpath = get_fullpath(dirpath, keyfile); 4596 4597 /* Once we have the full path, we don't need the pieces */ 4598 if (fullpath == NULL) 4599 return (KMF_ERR_BAD_PARAMETER); 4600 4601 /* If the requested file exists, return an error */ 4602 if (test_for_file(fullpath, 0400) == 1) { 4603 free(fullpath); 4604 return (KMF_ERR_DUPLICATE_KEYFILE); 4605 } 4606 4607 rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, 4608 &format, NULL); 4609 if (rv != KMF_OK) 4610 /* format is optional. */ 4611 rv = KMF_OK; 4612 4613 /* CRED is not required for OpenSSL files */ 4614 (void) kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr, 4615 &cred, NULL); 4616 4617 /* Store the private key to the keyfile */ 4618 out = BIO_new_file(fullpath, "wb"); 4619 if (out == NULL) { 4620 SET_ERROR(kmfh, ERR_get_error()); 4621 rv = KMF_ERR_OPEN_FILE; 4622 goto end; 4623 } 4624 4625 if (prikey != NULL && prikey->keyp != NULL) { 4626 if (prikey->keyalg == KMF_RSA || 4627 prikey->keyalg == KMF_DSA) { 4628 pkey = (EVP_PKEY *)prikey->keyp; 4629 4630 rv = ssl_write_key(kmfh, format, 4631 out, &cred, pkey, TRUE); 4632 4633 if (rv == KMF_OK && prikey->keylabel == NULL) { 4634 prikey->keylabel = strdup(fullpath); 4635 if (prikey->keylabel == NULL) 4636 rv = KMF_ERR_MEMORY; 4637 } 4638 } 4639 } else if (pubkey != NULL && pubkey->keyp != NULL) { 4640 if (pubkey->keyalg == KMF_RSA || 4641 pubkey->keyalg == KMF_DSA) { 4642 pkey = (EVP_PKEY *)pubkey->keyp; 4643 4644 rv = ssl_write_key(kmfh, format, 4645 out, &cred, pkey, FALSE); 4646 4647 if (rv == KMF_OK && pubkey->keylabel == NULL) { 4648 pubkey->keylabel = strdup(fullpath); 4649 if (pubkey->keylabel == NULL) 4650 rv = KMF_ERR_MEMORY; 4651 } 4652 } 4653 } else if (rawkey != NULL) { 4654 /* RAW keys are always private */ 4655 if (rawkey->keytype == KMF_RSA) { 4656 pkey = ImportRawRSAKey(&rawkey->rawdata.rsa); 4657 } else if (rawkey->keytype == KMF_DSA) { 4658 pkey = ImportRawDSAKey(&rawkey->rawdata.dsa); 4659 } else { 4660 rv = KMF_ERR_BAD_PARAMETER; 4661 } 4662 rv = ssl_write_key(kmfh, format, out, &cred, pkey, TRUE); 4663 } 4664 4665 end: 4666 4667 if (out) 4668 (void) BIO_free(out); 4669 4670 if (rv == KMF_OK) 4671 (void) chmod(fullpath, 0400); 4672 4673 free(fullpath); 4674 return (rv); 4675 } 4676 4677 KMF_RETURN 4678 OpenSSL_ImportCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 4679 { 4680 KMF_RETURN ret = KMF_OK; 4681 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4682 X509_CRL *xcrl = NULL; 4683 X509 *xcert = NULL; 4684 EVP_PKEY *pkey; 4685 KMF_ENCODE_FORMAT format; 4686 BIO *in = NULL, *out = NULL; 4687 int openssl_ret = 0; 4688 KMF_ENCODE_FORMAT outformat; 4689 boolean_t crlcheck = FALSE; 4690 char *certfile, *dirpath, *crlfile, *incrl, *outcrl, *outcrlfile; 4691 4692 if (numattr == 0 || attrlist == NULL) { 4693 return (KMF_ERR_BAD_PARAMETER); 4694 } 4695 4696 /* CRL check is optional */ 4697 (void) kmf_get_attr(KMF_CRL_CHECK_ATTR, attrlist, numattr, 4698 &crlcheck, NULL); 4699 4700 certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); 4701 if (crlcheck == B_TRUE && certfile == NULL) { 4702 return (KMF_ERR_BAD_CERTFILE); 4703 } 4704 4705 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 4706 incrl = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, attrlist, numattr); 4707 outcrl = kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR, attrlist, numattr); 4708 4709 crlfile = get_fullpath(dirpath, incrl); 4710 4711 if (crlfile == NULL) 4712 return (KMF_ERR_BAD_CRLFILE); 4713 4714 outcrlfile = get_fullpath(dirpath, outcrl); 4715 if (outcrlfile == NULL) 4716 return (KMF_ERR_BAD_CRLFILE); 4717 4718 if (isdir(outcrlfile)) { 4719 free(outcrlfile); 4720 return (KMF_ERR_BAD_CRLFILE); 4721 } 4722 4723 ret = kmf_is_crl_file(handle, crlfile, &format); 4724 if (ret != KMF_OK) { 4725 free(outcrlfile); 4726 return (ret); 4727 } 4728 4729 in = BIO_new_file(crlfile, "rb"); 4730 if (in == NULL) { 4731 SET_ERROR(kmfh, ERR_get_error()); 4732 ret = KMF_ERR_OPEN_FILE; 4733 goto end; 4734 } 4735 4736 if (format == KMF_FORMAT_ASN1) { 4737 xcrl = d2i_X509_CRL_bio(in, NULL); 4738 } else if (format == KMF_FORMAT_PEM) { 4739 xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 4740 } 4741 4742 if (xcrl == NULL) { 4743 SET_ERROR(kmfh, ERR_get_error()); 4744 ret = KMF_ERR_BAD_CRLFILE; 4745 goto end; 4746 } 4747 4748 /* If bypasscheck is specified, no need to verify. */ 4749 if (crlcheck == B_FALSE) 4750 goto output; 4751 4752 ret = kmf_is_cert_file(handle, certfile, &format); 4753 if (ret != KMF_OK) 4754 goto end; 4755 4756 /* Read in the CA cert file and convert to X509 */ 4757 if (BIO_read_filename(in, certfile) <= 0) { 4758 SET_ERROR(kmfh, ERR_get_error()); 4759 ret = KMF_ERR_OPEN_FILE; 4760 goto end; 4761 } 4762 4763 if (format == KMF_FORMAT_ASN1) { 4764 xcert = d2i_X509_bio(in, NULL); 4765 } else if (format == KMF_FORMAT_PEM) { 4766 xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); 4767 } else { 4768 ret = KMF_ERR_BAD_CERT_FORMAT; 4769 goto end; 4770 } 4771 4772 if (xcert == NULL) { 4773 SET_ERROR(kmfh, ERR_get_error()); 4774 ret = KMF_ERR_BAD_CERT_FORMAT; 4775 goto end; 4776 } 4777 /* Now get the public key from the CA cert */ 4778 pkey = X509_get_pubkey(xcert); 4779 if (pkey == NULL) { 4780 SET_ERROR(kmfh, ERR_get_error()); 4781 ret = KMF_ERR_BAD_CERTFILE; 4782 goto end; 4783 } 4784 4785 /* Verify the CRL with the CA's public key */ 4786 openssl_ret = X509_CRL_verify(xcrl, pkey); 4787 EVP_PKEY_free(pkey); 4788 if (openssl_ret > 0) { 4789 ret = KMF_OK; /* verify succeed */ 4790 } else { 4791 SET_ERROR(kmfh, openssl_ret); 4792 ret = KMF_ERR_BAD_CRLFILE; 4793 } 4794 4795 output: 4796 ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr, 4797 &outformat, NULL); 4798 if (ret != KMF_OK) { 4799 ret = KMF_OK; 4800 outformat = KMF_FORMAT_PEM; 4801 } 4802 4803 out = BIO_new_file(outcrlfile, "wb"); 4804 if (out == NULL) { 4805 SET_ERROR(kmfh, ERR_get_error()); 4806 ret = KMF_ERR_OPEN_FILE; 4807 goto end; 4808 } 4809 4810 if (outformat == KMF_FORMAT_ASN1) { 4811 openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl); 4812 } else if (outformat == KMF_FORMAT_PEM) { 4813 openssl_ret = PEM_write_bio_X509_CRL(out, xcrl); 4814 } else { 4815 ret = KMF_ERR_BAD_PARAMETER; 4816 goto end; 4817 } 4818 4819 if (openssl_ret <= 0) { 4820 SET_ERROR(kmfh, ERR_get_error()); 4821 ret = KMF_ERR_WRITE_FILE; 4822 } else { 4823 ret = KMF_OK; 4824 } 4825 4826 end: 4827 if (xcrl != NULL) 4828 X509_CRL_free(xcrl); 4829 4830 if (xcert != NULL) 4831 X509_free(xcert); 4832 4833 if (in != NULL) 4834 (void) BIO_free(in); 4835 4836 if (out != NULL) 4837 (void) BIO_free(out); 4838 4839 if (outcrlfile != NULL) 4840 free(outcrlfile); 4841 4842 return (ret); 4843 } 4844 4845 KMF_RETURN 4846 OpenSSL_ListCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 4847 { 4848 KMF_RETURN ret = KMF_OK; 4849 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4850 X509_CRL *x = NULL; 4851 KMF_ENCODE_FORMAT format; 4852 char *crlfile = NULL; 4853 BIO *in = NULL; 4854 BIO *mem = NULL; 4855 long len; 4856 char *memptr; 4857 char *data = NULL; 4858 char **crldata; 4859 char *crlfilename, *dirpath; 4860 4861 if (numattr == 0 || attrlist == NULL) { 4862 return (KMF_ERR_BAD_PARAMETER); 4863 } 4864 crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, 4865 attrlist, numattr); 4866 if (crlfilename == NULL) 4867 return (KMF_ERR_BAD_CRLFILE); 4868 4869 crldata = (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR, 4870 attrlist, numattr); 4871 4872 if (crldata == NULL) 4873 return (KMF_ERR_BAD_PARAMETER); 4874 4875 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 4876 4877 crlfile = get_fullpath(dirpath, crlfilename); 4878 4879 if (crlfile == NULL) 4880 return (KMF_ERR_BAD_CRLFILE); 4881 4882 if (isdir(crlfile)) { 4883 free(crlfile); 4884 return (KMF_ERR_BAD_CRLFILE); 4885 } 4886 4887 ret = kmf_is_crl_file(handle, crlfile, &format); 4888 if (ret != KMF_OK) { 4889 free(crlfile); 4890 return (ret); 4891 } 4892 4893 if (bio_err == NULL) 4894 bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); 4895 4896 in = BIO_new_file(crlfile, "rb"); 4897 if (in == NULL) { 4898 SET_ERROR(kmfh, ERR_get_error()); 4899 ret = KMF_ERR_OPEN_FILE; 4900 goto end; 4901 } 4902 4903 if (format == KMF_FORMAT_ASN1) { 4904 x = d2i_X509_CRL_bio(in, NULL); 4905 } else if (format == KMF_FORMAT_PEM) { 4906 x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 4907 } 4908 4909 if (x == NULL) { /* should not happen */ 4910 SET_ERROR(kmfh, ERR_get_error()); 4911 ret = KMF_ERR_OPEN_FILE; 4912 goto end; 4913 } 4914 4915 mem = BIO_new(BIO_s_mem()); 4916 if (mem == NULL) { 4917 SET_ERROR(kmfh, ERR_get_error()); 4918 ret = KMF_ERR_MEMORY; 4919 goto end; 4920 } 4921 4922 (void) X509_CRL_print(mem, x); 4923 len = BIO_get_mem_data(mem, &memptr); 4924 if (len <= 0) { 4925 SET_ERROR(kmfh, ERR_get_error()); 4926 ret = KMF_ERR_MEMORY; 4927 goto end; 4928 } 4929 4930 data = malloc(len + 1); 4931 if (data == NULL) { 4932 ret = KMF_ERR_MEMORY; 4933 goto end; 4934 } 4935 4936 (void) memcpy(data, memptr, len); 4937 data[len] = '\0'; 4938 *crldata = data; 4939 4940 end: 4941 if (x != NULL) 4942 X509_CRL_free(x); 4943 4944 if (crlfile != NULL) 4945 free(crlfile); 4946 4947 if (in != NULL) 4948 (void) BIO_free(in); 4949 4950 if (mem != NULL) 4951 (void) BIO_free(mem); 4952 4953 return (ret); 4954 } 4955 4956 KMF_RETURN 4957 OpenSSL_DeleteCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 4958 { 4959 KMF_RETURN ret = KMF_OK; 4960 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 4961 KMF_ENCODE_FORMAT format; 4962 char *crlfile = NULL; 4963 BIO *in = NULL; 4964 char *crlfilename, *dirpath; 4965 4966 if (numattr == 0 || attrlist == NULL) { 4967 return (KMF_ERR_BAD_PARAMETER); 4968 } 4969 4970 crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, 4971 attrlist, numattr); 4972 4973 if (crlfilename == NULL) 4974 return (KMF_ERR_BAD_CRLFILE); 4975 4976 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 4977 4978 crlfile = get_fullpath(dirpath, crlfilename); 4979 4980 if (crlfile == NULL) 4981 return (KMF_ERR_BAD_CRLFILE); 4982 4983 if (isdir(crlfile)) { 4984 ret = KMF_ERR_BAD_CRLFILE; 4985 goto end; 4986 } 4987 4988 ret = kmf_is_crl_file(handle, crlfile, &format); 4989 if (ret != KMF_OK) 4990 goto end; 4991 4992 if (unlink(crlfile) != 0) { 4993 SET_SYS_ERROR(kmfh, errno); 4994 ret = KMF_ERR_INTERNAL; 4995 goto end; 4996 } 4997 4998 end: 4999 if (in != NULL) 5000 (void) BIO_free(in); 5001 if (crlfile != NULL) 5002 free(crlfile); 5003 5004 return (ret); 5005 } 5006 5007 KMF_RETURN 5008 OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist) 5009 { 5010 KMF_RETURN ret = KMF_OK; 5011 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 5012 KMF_ENCODE_FORMAT format; 5013 BIO *in = NULL; 5014 X509 *xcert = NULL; 5015 X509_CRL *xcrl = NULL; 5016 STACK_OF(X509_REVOKED) *revoke_stack = NULL; 5017 X509_REVOKED *revoke; 5018 int i; 5019 char *crlfilename, *crlfile, *dirpath, *certfile; 5020 5021 if (numattr == 0 || attrlist == NULL) { 5022 return (KMF_ERR_BAD_PARAMETER); 5023 } 5024 5025 crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, 5026 attrlist, numattr); 5027 5028 if (crlfilename == NULL) 5029 return (KMF_ERR_BAD_CRLFILE); 5030 5031 certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr); 5032 if (certfile == NULL) 5033 return (KMF_ERR_BAD_CRLFILE); 5034 5035 dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr); 5036 5037 crlfile = get_fullpath(dirpath, crlfilename); 5038 5039 if (crlfile == NULL) 5040 return (KMF_ERR_BAD_CRLFILE); 5041 5042 if (isdir(crlfile)) { 5043 ret = KMF_ERR_BAD_CRLFILE; 5044 goto end; 5045 } 5046 5047 ret = kmf_is_crl_file(handle, crlfile, &format); 5048 if (ret != KMF_OK) 5049 goto end; 5050 5051 /* Read the CRL file and load it into a X509_CRL structure */ 5052 in = BIO_new_file(crlfilename, "rb"); 5053 if (in == NULL) { 5054 SET_ERROR(kmfh, ERR_get_error()); 5055 ret = KMF_ERR_OPEN_FILE; 5056 goto end; 5057 } 5058 5059 if (format == KMF_FORMAT_ASN1) { 5060 xcrl = d2i_X509_CRL_bio(in, NULL); 5061 } else if (format == KMF_FORMAT_PEM) { 5062 xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); 5063 } 5064 5065 if (xcrl == NULL) { 5066 SET_ERROR(kmfh, ERR_get_error()); 5067 ret = KMF_ERR_BAD_CRLFILE; 5068 goto end; 5069 } 5070 (void) BIO_free(in); 5071 5072 /* Read the Certificate file and load it into a X509 structure */ 5073 ret = kmf_is_cert_file(handle, certfile, &format); 5074 if (ret != KMF_OK) 5075 goto end; 5076 5077 in = BIO_new_file(certfile, "rb"); 5078 if (in == NULL) { 5079 SET_ERROR(kmfh, ERR_get_error()); 5080 ret = KMF_ERR_OPEN_FILE; 5081 goto end; 5082 } 5083 5084 if (format == KMF_FORMAT_ASN1) { 5085 xcert = d2i_X509_bio(in, NULL); 5086 } else if (format == KMF_FORMAT_PEM) { 5087 xcert = PEM_read_bio_X509(in, NULL, NULL, NULL); 5088 } 5089 5090 if (xcert == NULL) { 5091 SET_ERROR(kmfh, ERR_get_error()); 5092 ret = KMF_ERR_BAD_CERTFILE; 5093 goto end; 5094 } 5095 5096 /* Check if the certificate and the CRL have same issuer */ 5097 if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) { 5098 ret = KMF_ERR_ISSUER; 5099 goto end; 5100 } 5101 5102 /* Check to see if the certificate serial number is revoked */ 5103 revoke_stack = X509_CRL_get_REVOKED(xcrl); 5104 if (sk_X509_REVOKED_num(revoke_stack) <= 0) { 5105 /* No revoked certificates in the CRL file */ 5106 SET_ERROR(kmfh, ERR_get_error()); 5107 ret = KMF_ERR_EMPTY_CRL; 5108 goto end; 5109 } 5110 5111 for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) { 5112 /*LINTED*/ 5113 revoke = sk_X509_REVOKED_value(revoke_stack, i); 5114 if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber, 5115 revoke->serialNumber) == 0) { 5116 break; 5117 } 5118 } 5119 5120 if (i < sk_X509_REVOKED_num(revoke_stack)) { 5121 ret = KMF_OK; 5122 } else { 5123 ret = KMF_ERR_NOT_REVOKED; 5124 } 5125 5126 end: 5127 if (in != NULL) 5128 (void) BIO_free(in); 5129 if (xcrl != NULL) 5130 X509_CRL_free(xcrl); 5131 if (xcert != NULL) 5132 X509_free(xcert); 5133 5134 return (ret); 5135 } 5136 5137 KMF_RETURN 5138 OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, char *crlname, KMF_DATA *tacert) 5139 { 5140 KMF_RETURN ret = KMF_OK; 5141 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 5142 BIO *bcrl = NULL; 5143 X509_CRL *xcrl = NULL; 5144 X509 *xcert = NULL; 5145 EVP_PKEY *pkey; 5146 int sslret; 5147 KMF_ENCODE_FORMAT crl_format; 5148 unsigned char *p; 5149 long len; 5150 5151 if (handle == NULL || crlname == NULL || tacert == NULL) { 5152 return (KMF_ERR_BAD_PARAMETER); 5153 } 5154 5155 ret = kmf_get_file_format(crlname, &crl_format); 5156 if (ret != KMF_OK) 5157 return (ret); 5158 5159 bcrl = BIO_new_file(crlname, "rb"); 5160 if (bcrl == NULL) { 5161 SET_ERROR(kmfh, ERR_get_error()); 5162 ret = KMF_ERR_OPEN_FILE; 5163 goto cleanup; 5164 } 5165 5166 if (crl_format == KMF_FORMAT_ASN1) { 5167 xcrl = d2i_X509_CRL_bio(bcrl, NULL); 5168 } else if (crl_format == KMF_FORMAT_PEM) { 5169 xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); 5170 } else { 5171 ret = KMF_ERR_BAD_PARAMETER; 5172 goto cleanup; 5173 } 5174 5175 if (xcrl == NULL) { 5176 SET_ERROR(kmfh, ERR_get_error()); 5177 ret = KMF_ERR_BAD_CRLFILE; 5178 goto cleanup; 5179 } 5180 5181 p = tacert->Data; 5182 len = tacert->Length; 5183 xcert = d2i_X509(NULL, (const uchar_t **)&p, len); 5184 5185 if (xcert == NULL) { 5186 SET_ERROR(kmfh, ERR_get_error()); 5187 ret = KMF_ERR_BAD_CERTFILE; 5188 goto cleanup; 5189 } 5190 5191 /* Get issuer certificate public key */ 5192 pkey = X509_get_pubkey(xcert); 5193 if (pkey == NULL) { 5194 SET_ERROR(kmfh, ERR_get_error()); 5195 ret = KMF_ERR_BAD_CERT_FORMAT; 5196 goto cleanup; 5197 } 5198 5199 /* Verify CRL signature */ 5200 sslret = X509_CRL_verify(xcrl, pkey); 5201 EVP_PKEY_free(pkey); 5202 if (sslret > 0) { 5203 ret = KMF_OK; 5204 } else { 5205 SET_ERROR(kmfh, sslret); 5206 ret = KMF_ERR_BAD_CRLFILE; 5207 } 5208 5209 cleanup: 5210 if (bcrl != NULL) 5211 (void) BIO_free(bcrl); 5212 5213 if (xcrl != NULL) 5214 X509_CRL_free(xcrl); 5215 5216 if (xcert != NULL) 5217 X509_free(xcert); 5218 5219 return (ret); 5220 5221 } 5222 5223 KMF_RETURN 5224 OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, char *crlname) 5225 { 5226 KMF_RETURN ret = KMF_OK; 5227 KMF_HANDLE *kmfh = (KMF_HANDLE *)handle; 5228 KMF_ENCODE_FORMAT crl_format; 5229 BIO *bcrl = NULL; 5230 X509_CRL *xcrl = NULL; 5231 int i; 5232 5233 if (handle == NULL || crlname == NULL) { 5234 return (KMF_ERR_BAD_PARAMETER); 5235 } 5236 5237 ret = kmf_is_crl_file(handle, crlname, &crl_format); 5238 if (ret != KMF_OK) 5239 return (ret); 5240 5241 bcrl = BIO_new_file(crlname, "rb"); 5242 if (bcrl == NULL) { 5243 SET_ERROR(kmfh, ERR_get_error()); 5244 ret = KMF_ERR_OPEN_FILE; 5245 goto cleanup; 5246 } 5247 5248 if (crl_format == KMF_FORMAT_ASN1) { 5249 xcrl = d2i_X509_CRL_bio(bcrl, NULL); 5250 } else if (crl_format == KMF_FORMAT_PEM) { 5251 xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL); 5252 } 5253 5254 if (xcrl == NULL) { 5255 SET_ERROR(kmfh, ERR_get_error()); 5256 ret = KMF_ERR_BAD_CRLFILE; 5257 goto cleanup; 5258 } 5259 5260 i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL); 5261 if (i >= 0) { 5262 ret = KMF_ERR_VALIDITY_PERIOD; 5263 goto cleanup; 5264 } 5265 5266 if (X509_CRL_get_nextUpdate(xcrl)) { 5267 i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL); 5268 5269 if (i <= 0) { 5270 ret = KMF_ERR_VALIDITY_PERIOD; 5271 goto cleanup; 5272 } 5273 } 5274 5275 ret = KMF_OK; 5276 5277 cleanup: 5278 if (bcrl != NULL) 5279 (void) BIO_free(bcrl); 5280 5281 if (xcrl != NULL) 5282 X509_CRL_free(xcrl); 5283 5284 return (ret); 5285 } 5286