1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * The kernel SSL module ioctls. 28 */ 29 30 #include <sys/types.h> 31 #include <sys/modctl.h> 32 #include <sys/conf.h> 33 #include <sys/ddi.h> 34 #include <sys/sunddi.h> 35 #include <sys/kmem.h> 36 #include <sys/errno.h> 37 #include <sys/file.h> 38 #include <sys/cred.h> 39 #include <sys/proc.h> 40 #include <sys/task.h> 41 #include <sys/model.h> 42 #include <sys/sysmacros.h> 43 #include <sys/policy.h> 44 #include <sys/crypto/common.h> 45 #include <sys/crypto/api.h> 46 #include <inet/common.h> 47 #include <inet/ip.h> 48 49 #include "ksslimpl.h" 50 #include "kssl.h" 51 #include "ksslproto.h" 52 53 kssl_entry_t **kssl_entry_tab; 54 int kssl_entry_tab_size; 55 int kssl_entry_tab_nentries; 56 kmutex_t kssl_tab_mutex; 57 58 static void 59 certificate_free(Certificate_t *cert) 60 { 61 kmem_free(cert->msg, cert->len); 62 kmem_free(cert, sizeof (struct Certificate)); 63 } 64 65 static void 66 privateKey_free(crypto_key_t *privkey) 67 { 68 int i; 69 size_t attrs_size; 70 crypto_object_attribute_t *attrs; 71 72 attrs = privkey->ck_attrs; 73 attrs_size = privkey->ck_count * sizeof (crypto_object_attribute_t); 74 for (i = 0; i < privkey->ck_count; i++) { 75 bzero(attrs[i].oa_value, attrs[i].oa_value_len); 76 kmem_free(attrs[i].oa_value, attrs[i].oa_value_len); 77 } 78 kmem_free(attrs, attrs_size); 79 kmem_free(privkey, sizeof (crypto_key_t)); 80 } 81 82 static void 83 sess_free(kssl_session_info_t *s) 84 { 85 if (s->is_valid_handle) { 86 (void) crypto_session_logout(s->prov, s->sid, NULL); 87 (void) crypto_session_close(s->prov, s->sid, NULL); 88 crypto_release_provider(s->prov); 89 s->is_valid_handle = B_FALSE; 90 } 91 92 if (s->evnt_handle != NULL) { 93 crypto_unnotify_events(s->evnt_handle); 94 s->evnt_handle = NULL; 95 } 96 97 bzero(s->tokpin, s->pinlen); 98 kmem_free(s, sizeof (kssl_session_info_t) + s->pinlen); 99 } 100 101 /* 102 * Frees the space for the entry and the keys and certs 103 * it carries. 104 */ 105 void 106 kssl_free_entry(kssl_entry_t *kssl_entry) 107 { 108 int i; 109 Certificate_t *cert; 110 crypto_key_t *privkey; 111 kssl_session_info_t *s; 112 113 if (kssl_entry->ke_no_freeall) { 114 kmem_free(kssl_entry, sizeof (kssl_entry_t)); 115 return; 116 } 117 118 if ((cert = kssl_entry->ke_server_certificate) != NULL) { 119 certificate_free(cert); 120 } 121 122 if ((privkey = kssl_entry->ke_private_key) != NULL) { 123 privateKey_free(privkey); 124 } 125 126 for (i = 0; i < kssl_entry->sid_cache_nentries; i++) 127 mutex_destroy(&(kssl_entry->sid_cache[i].se_lock)); 128 129 kmem_free(kssl_entry->sid_cache, 130 kssl_entry->sid_cache_nentries * sizeof (kssl_sid_ent_t)); 131 132 ASSERT(kssl_entry->ke_proxy_head == NULL); 133 ASSERT(kssl_entry->ke_fallback_head == NULL); 134 135 if ((s = kssl_entry->ke_sessinfo) != NULL) { 136 ASSERT(kssl_entry->ke_is_nxkey); 137 sess_free(s); 138 } 139 140 kmem_free(kssl_entry, sizeof (kssl_entry_t)); 141 } 142 143 /* 144 * Returns the index of the entry in kssl_entry_tab[] that matches 145 * the address and port. Returns -1 if no match is found. 146 */ 147 static int 148 kssl_find_entry(in6_addr_t laddr, in_port_t port, int type, 149 boolean_t wild_card_match) 150 { 151 int i; 152 kssl_entry_t *ep; 153 154 ASSERT(MUTEX_HELD(&kssl_tab_mutex)); 155 156 for (i = 0; i < kssl_entry_tab_size; i++) { 157 ep = kssl_entry_tab[i]; 158 if (ep == NULL) 159 continue; 160 161 if (!((type == IS_SSL_PORT && ep->ke_ssl_port == port) || 162 (type == IS_PROXY_PORT && ep->ke_proxy_port == port))) 163 continue; 164 165 if (IN6_ARE_ADDR_EQUAL(&laddr, &ep->ke_laddr) || 166 (wild_card_match && (IN6_IS_ADDR_UNSPECIFIED(&laddr) || 167 IN6_IS_ADDR_UNSPECIFIED(&ep->ke_laddr)))) 168 break; 169 } 170 171 if (i == kssl_entry_tab_size) 172 return (-1); 173 174 return (i); 175 } 176 177 static void 178 copy_int_to_bytearray(int x, uchar_t *buf) 179 { 180 buf[0] = (x >> 16) & 0xff; 181 buf[1] = (x >> 8) & 0xff; 182 buf[2] = (x) & 0xff; 183 } 184 185 static int 186 extract_certificate(kssl_params_t *kssl_params, Certificate_t **certpp) 187 { 188 int i, len; 189 uint64_t in_size; 190 uchar_t *end_pos; 191 uint32_t ncert; 192 uint32_t *cert_sizes; 193 Certificate_t *cert; 194 char *begin = (char *)kssl_params; 195 uchar_t *cert_buf; 196 int cert_buf_len; 197 uchar_t *cert_from, *cert_to; 198 199 ASSERT(kssl_params); 200 201 in_size = kssl_params->kssl_params_size; 202 end_pos = (uchar_t *)kssl_params + in_size; 203 204 /* 205 * Get the certs array. First the array of sizes, then the actual 206 * certs. 207 */ 208 ncert = kssl_params->kssl_certs.sc_count; 209 210 if (ncert == 0) { 211 /* no certs in here! why did ya call? */ 212 return (EINVAL); 213 } 214 if (in_size < (sizeof (kssl_params_t) + ncert * sizeof (uint32_t))) { 215 return (EINVAL); 216 } 217 218 /* Trusting that the system call preserved the 4-byte alignment */ 219 cert_sizes = (uint32_t *)(begin + 220 kssl_params->kssl_certs.sc_sizes_offset); 221 222 /* should this be an ASSERT()? */ 223 if (!IS_P2ALIGNED(cert_sizes, sizeof (uint32_t))) { 224 return (EINVAL); 225 } 226 227 len = 0; 228 for (i = 0; i < ncert; i++) { 229 if (cert_sizes[i] < 1) { 230 return (EINVAL); 231 } 232 len += cert_sizes[i] + 3; 233 } 234 235 len += 3; /* length of certificate message without msg header */ 236 237 cert_buf_len = len + 4 + 4; /* add space for msg headers */ 238 239 cert_buf = kmem_alloc(cert_buf_len, KM_SLEEP); 240 241 cert_buf[0] = (uchar_t)certificate; 242 copy_int_to_bytearray(len, & cert_buf[1]); 243 copy_int_to_bytearray(len - 3, & cert_buf[4]); 244 245 cert_from = (uchar_t *)(begin + 246 kssl_params->kssl_certs.sc_certs_offset); 247 cert_to = &cert_buf[7]; 248 249 for (i = 0; i < ncert; i++) { 250 copy_int_to_bytearray(cert_sizes[i], cert_to); 251 cert_to += 3; 252 253 if (cert_from + cert_sizes[i] > end_pos) { 254 kmem_free(cert_buf, cert_buf_len); 255 return (EINVAL); 256 } 257 258 bcopy(cert_from, cert_to, cert_sizes[i]); 259 cert_from += cert_sizes[i]; 260 cert_to += cert_sizes[i]; 261 } 262 263 len += 4; 264 cert_buf[len] = (uchar_t)server_hello_done; 265 copy_int_to_bytearray(0, & cert_buf[len + 1]); 266 267 cert = kmem_alloc(sizeof (Certificate_t), KM_SLEEP); 268 cert->msg = cert_buf; 269 cert->len = cert_buf_len; 270 271 *certpp = cert; 272 273 return (0); 274 } 275 276 static int 277 extract_private_key(kssl_params_t *kssl_params, crypto_key_t **privkey) 278 { 279 char *begin = (char *)kssl_params; 280 char *end_pos; 281 int i, j, rv; 282 size_t attrs_size; 283 crypto_object_attribute_t *newattrs; 284 char *mp_attrs; 285 kssl_object_attribute_t att; 286 char *attval; 287 uint32_t attlen; 288 crypto_key_t *kssl_privkey; 289 290 end_pos = (char *)kssl_params + kssl_params->kssl_params_size; 291 292 kssl_privkey = kmem_alloc(sizeof (crypto_key_t), KM_SLEEP); 293 294 kssl_privkey->ck_format = kssl_params->kssl_privkey.ks_format; 295 kssl_privkey->ck_count = kssl_params->kssl_privkey.ks_count; 296 297 switch (kssl_privkey->ck_format) { 298 case CRYPTO_KEY_ATTR_LIST: 299 break; 300 case CRYPTO_KEY_RAW: 301 case CRYPTO_KEY_REFERENCE: 302 default: 303 rv = EINVAL; 304 goto err1; 305 } 306 307 /* allocate the attributes */ 308 attrs_size = kssl_privkey->ck_count * 309 sizeof (crypto_object_attribute_t); 310 311 mp_attrs = begin + kssl_params->kssl_privkey.ks_attrs_offset; 312 if (mp_attrs + attrs_size > end_pos) { 313 rv = EINVAL; 314 goto err1; 315 } 316 317 newattrs = kmem_alloc(attrs_size, KM_SLEEP); 318 319 /* Now the individual attributes */ 320 for (i = 0; i < kssl_privkey->ck_count; i++) { 321 bcopy(mp_attrs, &att, sizeof (kssl_object_attribute_t)); 322 323 mp_attrs += sizeof (kssl_object_attribute_t); 324 325 attval = begin + att.ka_value_offset; 326 attlen = att.ka_value_len; 327 328 if (attval + attlen > end_pos) { 329 rv = EINVAL; 330 goto err2; 331 } 332 333 newattrs[i].oa_type = att.ka_type; 334 newattrs[i].oa_value_len = attlen; 335 newattrs[i].oa_value = kmem_alloc(attlen, KM_SLEEP); 336 337 bcopy(attval, newattrs[i].oa_value, attlen); 338 } 339 340 kssl_privkey->ck_attrs = newattrs; 341 342 *privkey = kssl_privkey; 343 344 return (0); 345 346 err2: 347 for (j = 0; j < i; j++) { 348 bzero(newattrs[j].oa_value, newattrs[j].oa_value_len); 349 kmem_free(newattrs[j].oa_value, newattrs[j].oa_value_len); 350 } 351 kmem_free(newattrs, attrs_size); 352 err1: 353 kmem_free(kssl_privkey, sizeof (crypto_key_t)); 354 return (rv); 355 } 356 357 static int 358 create_sessinfo(kssl_params_t *kssl_params, kssl_entry_t *kssl_entry) 359 { 360 int rv; 361 char *p; 362 kssl_session_info_t *s; 363 kssl_tokinfo_t *t; 364 365 t = &kssl_params->kssl_token; 366 /* Do a sanity check */ 367 if (t->pinlen > MAX_PIN_LENGTH) { 368 return (EINVAL); 369 } 370 371 s = kmem_zalloc(sizeof (kssl_session_info_t) + t->pinlen, KM_SLEEP); 372 s->pinlen = t->pinlen; 373 bcopy(t->toklabel, s->toklabel, CRYPTO_EXT_SIZE_LABEL); 374 p = (char *)kssl_params + t->tokpin_offset; 375 bcopy(p, s->tokpin, s->pinlen); 376 ASSERT(kssl_entry->ke_sessinfo == NULL); 377 kssl_entry->ke_sessinfo = s; 378 379 /* Get the handle to the non extractable key */ 380 rv = kssl_get_obj_handle(kssl_entry); 381 kssl_params->kssl_token.ck_rv = rv; 382 if (rv != CRYPTO_SUCCESS) { 383 sess_free(s); 384 kssl_entry->ke_sessinfo = NULL; 385 return (EINVAL); 386 } 387 388 kssl_entry->ke_sessinfo->is_valid_handle = B_TRUE; 389 kssl_entry->ke_sessinfo->do_reauth = B_FALSE; 390 kssl_entry->ke_sessinfo->evnt_handle = 391 crypto_notify_events(kssl_prov_evnt, 392 CRYPTO_EVENT_PROVIDER_REGISTERED | 393 CRYPTO_EVENT_PROVIDER_UNREGISTERED); 394 395 return (0); 396 } 397 398 static kssl_entry_t * 399 create_kssl_entry(kssl_params_t *kssl_params, Certificate_t *cert, 400 crypto_key_t *privkey) 401 { 402 int i; 403 uint16_t s; 404 kssl_entry_t *kssl_entry, *ep; 405 uint_t cnt, mech_count; 406 crypto_mech_name_t *mechs; 407 boolean_t got_rsa, got_md5, got_sha1, got_rc4, got_des, got_3des; 408 boolean_t got_aes; 409 410 kssl_entry = kmem_zalloc(sizeof (kssl_entry_t), KM_SLEEP); 411 412 kssl_entry->ke_laddr = kssl_params->kssl_addr.sin6_addr; 413 kssl_entry->ke_ssl_port = kssl_params->kssl_addr.sin6_port; 414 kssl_entry->ke_proxy_port = kssl_params->kssl_proxy_port; 415 if (kssl_params->kssl_session_cache_timeout == 0) 416 kssl_entry->sid_cache_timeout = DEFAULT_SID_TIMEOUT; 417 else 418 kssl_entry->sid_cache_timeout = 419 kssl_params->kssl_session_cache_timeout; 420 if (kssl_params->kssl_session_cache_size == 0) 421 kssl_entry->sid_cache_nentries = DEFAULT_SID_CACHE_NENTRIES; 422 else 423 kssl_entry->sid_cache_nentries = 424 kssl_params->kssl_session_cache_size; 425 kssl_entry->ke_private_key = privkey; 426 kssl_entry->ke_server_certificate = cert; 427 428 kssl_entry->ke_is_nxkey = kssl_params->kssl_is_nxkey; 429 if (kssl_entry->ke_is_nxkey) { 430 if (create_sessinfo(kssl_params, kssl_entry) != 0) { 431 kmem_free(kssl_entry, sizeof (kssl_entry_t)); 432 return (NULL); 433 } 434 } 435 436 mechs = crypto_get_mech_list(&mech_count, KM_SLEEP); 437 if (mechs != NULL) { 438 got_rsa = got_md5 = got_sha1 = got_rc4 = 439 got_des = got_3des = got_aes = B_FALSE; 440 for (i = 0; i < mech_count; i++) { 441 if (strncmp(SUN_CKM_RSA_X_509, mechs[i], 442 CRYPTO_MAX_MECH_NAME) == 0) 443 got_rsa = B_TRUE; 444 else if (strncmp(SUN_CKM_MD5_HMAC, mechs[i], 445 CRYPTO_MAX_MECH_NAME) == 0) 446 got_md5 = B_TRUE; 447 else if (strncmp(SUN_CKM_SHA1_HMAC, mechs[i], 448 CRYPTO_MAX_MECH_NAME) == 0) 449 got_sha1 = B_TRUE; 450 else if (strncmp(SUN_CKM_RC4, mechs[i], 451 CRYPTO_MAX_MECH_NAME) == 0) 452 got_rc4 = B_TRUE; 453 else if (strncmp(SUN_CKM_DES_CBC, mechs[i], 454 CRYPTO_MAX_MECH_NAME) == 0) 455 got_des = B_TRUE; 456 else if (strncmp(SUN_CKM_DES3_CBC, mechs[i], 457 CRYPTO_MAX_MECH_NAME) == 0) 458 got_3des = B_TRUE; 459 else if (strncmp(SUN_CKM_AES_CBC, mechs[i], 460 CRYPTO_MAX_MECH_NAME) == 0) 461 got_aes = B_TRUE; 462 } 463 464 cnt = 0; 465 ep = kssl_entry; 466 for (i = 0; i < CIPHER_SUITE_COUNT - 1; i++) { 467 switch (s = kssl_params->kssl_suites[i]) { 468 case SSL_RSA_WITH_RC4_128_MD5: 469 if (got_rsa && got_rc4 && got_md5) 470 ep->kssl_cipherSuites[cnt++] = s; 471 break; 472 case SSL_RSA_WITH_RC4_128_SHA: 473 if (got_rsa && got_rc4 && got_sha1) 474 ep->kssl_cipherSuites[cnt++] = s; 475 break; 476 case SSL_RSA_WITH_DES_CBC_SHA: 477 if (got_rsa && got_des && got_sha1) 478 ep->kssl_cipherSuites[cnt++] = s; 479 break; 480 case SSL_RSA_WITH_3DES_EDE_CBC_SHA: 481 if (got_rsa && got_3des && got_sha1) 482 ep->kssl_cipherSuites[cnt++] = s; 483 break; 484 case TLS_RSA_WITH_AES_128_CBC_SHA: 485 if (got_rsa && got_aes && got_sha1) 486 ep->kssl_cipherSuites[cnt++] = s; 487 break; 488 case TLS_RSA_WITH_AES_256_CBC_SHA: 489 if (got_rsa && got_aes && got_sha1) 490 ep->kssl_cipherSuites[cnt++] = s; 491 break; 492 case CIPHER_NOTSET: 493 default: 494 break; 495 } 496 } 497 498 crypto_free_mech_list(mechs, mech_count); 499 } 500 501 /* Add the no encryption suite to the end */ 502 kssl_entry->kssl_cipherSuites[cnt++] = SSL_RSA_WITH_NULL_SHA; 503 kssl_entry->kssl_cipherSuites_nentries = cnt; 504 for (i = 0; i < cnt; i++) 505 kssl_entry->kssl_saved_Suites[i] = 506 kssl_entry->kssl_cipherSuites[i]; 507 508 kssl_entry->sid_cache = kmem_alloc( 509 kssl_entry->sid_cache_nentries * sizeof (kssl_sid_ent_t), KM_SLEEP); 510 511 for (i = 0; i < kssl_entry->sid_cache_nentries; i++) { 512 mutex_init(&(kssl_entry->sid_cache[i].se_lock), NULL, 513 MUTEX_DEFAULT, NULL); 514 kssl_entry->sid_cache[i].se_used = 0; 515 kssl_entry->sid_cache[i].se_sid.cached = B_FALSE; 516 } 517 518 KSSL_ENTRY_REFHOLD(kssl_entry); 519 520 return (kssl_entry); 521 } 522 523 int 524 kssl_add_entry(kssl_params_t *kssl_params) 525 { 526 int rv, index, i; 527 Certificate_t *cert; 528 crypto_key_t *privkey; 529 kssl_entry_t *kssl_entry; 530 in6_addr_t laddr; 531 532 if ((rv = extract_certificate(kssl_params, &cert)) != 0) { 533 return (rv); 534 } 535 536 if ((rv = extract_private_key(kssl_params, &privkey)) != 0) { 537 certificate_free(cert); 538 return (rv); 539 } 540 541 kssl_entry = create_kssl_entry(kssl_params, cert, privkey); 542 if (kssl_entry == NULL) { 543 certificate_free(cert); 544 privateKey_free(privkey); 545 return (EINVAL); 546 } 547 548 laddr = kssl_params->kssl_addr.sin6_addr; 549 550 retry: 551 mutex_enter(&kssl_tab_mutex); 552 /* Allocate the array first time here */ 553 if (kssl_entry_tab == NULL) { 554 size_t allocsize; 555 kssl_entry_t **tmp_tab; 556 int tmp_size; 557 558 tmp_size = KSSL_TAB_INITSIZE; 559 allocsize = tmp_size * sizeof (kssl_entry_t *); 560 mutex_exit(&kssl_tab_mutex); 561 tmp_tab = kmem_zalloc(allocsize, KM_SLEEP); 562 mutex_enter(&kssl_tab_mutex); 563 if (kssl_entry_tab != NULL) { 564 mutex_exit(&kssl_tab_mutex); 565 kmem_free(tmp_tab, allocsize); 566 goto retry; 567 } 568 kssl_entry_tab_size = tmp_size; 569 kssl_entry_tab = tmp_tab; 570 index = 0; 571 } else { 572 /* Check if a matching entry exists already */ 573 index = kssl_find_entry(laddr, 574 kssl_params->kssl_addr.sin6_port, IS_SSL_PORT, B_TRUE); 575 576 if (index == -1) { 577 /* Check if an entry with the same proxy port exists */ 578 if (kssl_find_entry(laddr, kssl_params->kssl_proxy_port, 579 IS_PROXY_PORT, B_TRUE) != -1) { 580 mutex_exit(&kssl_tab_mutex); 581 kssl_free_entry(kssl_entry); 582 return (EADDRINUSE); 583 } 584 585 /* No matching entry, find an empty spot */ 586 for (i = 0; i < kssl_entry_tab_size; i++) { 587 if (kssl_entry_tab[i] == NULL) 588 break; 589 } 590 /* Table full. Gotta grow it */ 591 if (i == kssl_entry_tab_size) { 592 kssl_entry_t **new_tab, **old_tab; 593 size_t allocsize; 594 size_t oldtabsize = kssl_entry_tab_size * 595 sizeof (kssl_entry_t *); 596 int tmp_size, old_size; 597 598 tmp_size = old_size = kssl_entry_tab_size; 599 tmp_size += KSSL_TAB_INITSIZE; 600 allocsize = tmp_size * sizeof (kssl_entry_t *); 601 mutex_exit(&kssl_tab_mutex); 602 new_tab = kmem_zalloc(allocsize, KM_SLEEP); 603 mutex_enter(&kssl_tab_mutex); 604 if (kssl_entry_tab_size > old_size) { 605 mutex_exit(&kssl_tab_mutex); 606 kmem_free(new_tab, allocsize); 607 goto retry; 608 } 609 610 kssl_entry_tab_size = tmp_size; 611 bcopy(kssl_entry_tab, new_tab, oldtabsize); 612 613 old_tab = kssl_entry_tab; 614 kssl_entry_tab = new_tab; 615 616 kmem_free(old_tab, oldtabsize); 617 } 618 index = i; 619 } else { 620 kssl_entry_t *ep; 621 622 /* 623 * We do not want an entry with a specific address and 624 * an entry with IN_ADDR_ANY to coexist. We could 625 * replace the existing entry. But, most likely this 626 * is misconfiguration. Better bail out with an error. 627 */ 628 ep = kssl_entry_tab[index]; 629 630 if ((IN6_IS_ADDR_UNSPECIFIED(&laddr) && 631 !IN6_IS_ADDR_UNSPECIFIED(&ep->ke_laddr)) || 632 (!IN6_IS_ADDR_UNSPECIFIED(&laddr) && 633 IN6_IS_ADDR_UNSPECIFIED(&ep->ke_laddr))) { 634 mutex_exit(&kssl_tab_mutex); 635 kssl_free_entry(kssl_entry); 636 return (EEXIST); 637 } 638 639 /* Replace the existing entry */ 640 KSSL_ENTRY_REFRELE(kssl_entry_tab[index]); 641 kssl_entry_tab[index] = NULL; 642 kssl_entry_tab_nentries--; 643 } 644 } 645 646 kssl_entry_tab[index] = kssl_entry; 647 kssl_entry_tab_nentries++; 648 mutex_exit(&kssl_tab_mutex); 649 650 return (0); 651 } 652 653 int 654 kssl_delete_entry(struct sockaddr_in6 *kssl_addr) 655 { 656 in6_addr_t laddr; 657 int index; 658 659 laddr = kssl_addr->sin6_addr; 660 661 mutex_enter(&kssl_tab_mutex); 662 index = kssl_find_entry(laddr, kssl_addr->sin6_port, 663 IS_SSL_PORT, B_FALSE); 664 665 if (index == -1) { 666 mutex_exit(&kssl_tab_mutex); 667 return (ENOENT); 668 } 669 670 KSSL_ENTRY_REFRELE(kssl_entry_tab[index]); 671 kssl_entry_tab[index] = NULL; 672 kssl_entry_tab_nentries--; 673 674 mutex_exit(&kssl_tab_mutex); 675 676 return (0); 677 } 678 679 /* 680 * We care about only one private key object. 681 * So, set the max count to only 1. 682 */ 683 #define MAX_OBJECT_COUNT 1 684 685 /* 686 * Open a session to the provider specified by the label and 687 * authenticate to it. Find the private key object with the 688 * specified attributes and save the handle. The userland component 689 * must set all the attributes in the template so as to uniquely 690 * identify the object. 691 * 692 * Note that the handle will be invalid if we logout or close 693 * the session to the provider. 694 */ 695 int 696 kssl_get_obj_handle(kssl_entry_t *kp) 697 { 698 int rv; 699 unsigned int count; 700 void *cookie = NULL; 701 crypto_provider_t prov; 702 kssl_session_info_t *s; 703 crypto_session_id_t sid; 704 crypto_object_attribute_t *attrs; 705 crypto_object_id_t ohndl[MAX_OBJECT_COUNT]; 706 char label[CRYPTO_EXT_SIZE_LABEL + 1]; 707 708 ASSERT(kp->ke_is_nxkey); 709 s = kp->ke_sessinfo; 710 711 bcopy(s->toklabel, label, CRYPTO_EXT_SIZE_LABEL); 712 label[CRYPTO_EXT_SIZE_LABEL] = '\0'; 713 prov = crypto_get_provider(label, NULL, NULL); 714 if (prov == NULL) 715 return (CRYPTO_UNKNOWN_PROVIDER); 716 717 rv = crypto_session_open(prov, &sid, NULL); 718 if (rv != CRYPTO_SUCCESS) { 719 goto err1; 720 } 721 722 rv = crypto_session_login(prov, sid, CRYPTO_USER, 723 s->tokpin, s->pinlen, NULL); 724 if (rv != CRYPTO_SUCCESS) { 725 goto err2; 726 } 727 728 count = kp->ke_private_key->ck_count; 729 attrs = kp->ke_private_key->ck_attrs; 730 731 rv = crypto_object_find_init(prov, sid, attrs, count, &cookie, NULL); 732 if (rv != CRYPTO_SUCCESS) { 733 goto err3; 734 } 735 736 rv = crypto_object_find(prov, cookie, ohndl, &count, 737 MAX_OBJECT_COUNT, NULL); 738 if (rv != CRYPTO_SUCCESS || count == 0) { 739 if (count == 0) 740 rv = CRYPTO_FAILED; 741 goto err3; 742 } 743 744 (void) crypto_object_find_final(prov, cookie, NULL); 745 746 s->sid = sid; 747 s->prov = prov; 748 s->key.ck_format = CRYPTO_KEY_REFERENCE; 749 /* Keep the handle around for later use */ 750 s->key.ck_obj_id = ohndl[0]; 751 752 return (CRYPTO_SUCCESS); 753 754 err3: 755 (void) crypto_session_logout(prov, sid, NULL); 756 err2: 757 (void) crypto_session_close(prov, sid, NULL); 758 err1: 759 crypto_release_provider(prov); 760 return (rv); 761 } 762