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