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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * The kernel SSL module ioctls. 31 */ 32 33 #include <sys/types.h> 34 #include <sys/modctl.h> 35 #include <sys/conf.h> 36 #include <sys/stat.h> 37 #include <sys/ddi.h> 38 #include <sys/sunddi.h> 39 #include <sys/kmem.h> 40 #include <sys/errno.h> 41 #include <sys/ksynch.h> 42 #include <sys/file.h> 43 #include <sys/open.h> 44 #include <sys/cred.h> 45 #include <sys/proc.h> 46 #include <sys/task.h> 47 #include <sys/mkdev.h> 48 #include <sys/model.h> 49 #include <sys/sysmacros.h> 50 #include <sys/policy.h> 51 #include <sys/crypto/common.h> 52 #include <sys/crypto/api.h> 53 #include <inet/common.h> 54 #include <inet/ip.h> 55 #include <inet/ip6.h> 56 57 #include "ksslimpl.h" 58 #include "kssl.h" 59 #include "ksslproto.h" 60 61 kssl_entry_t **kssl_entry_tab; 62 int kssl_entry_tab_size; 63 int kssl_entry_tab_nentries; 64 kmutex_t kssl_tab_mutex; 65 66 67 static void 68 certificate_free(Certificate_t *cert) 69 { 70 kmem_free(cert->msg, cert->len); 71 kmem_free(cert, sizeof (struct Certificate)); 72 } 73 74 static void 75 privateKey_free(crypto_key_t *privkey) 76 { 77 crypto_object_attribute_t *attrs = privkey->ck_attrs; 78 size_t attrs_size 79 = privkey->ck_count * sizeof (crypto_object_attribute_t); 80 81 int i; 82 83 for (i = 0; i < privkey->ck_count; i++) { 84 bzero(attrs[i].oa_value, attrs[i].oa_value_len); 85 kmem_free(attrs[i].oa_value, attrs[i].oa_value_len); 86 } 87 kmem_free(attrs, attrs_size); 88 kmem_free(privkey, sizeof (crypto_key_t)); 89 } 90 91 /* 92 * Frees the space for the entry and the keys and certs 93 * it carries. 94 */ 95 void 96 kssl_free_entry(kssl_entry_t *kssl_entry) 97 { 98 int i; 99 Certificate_t *cert; 100 crypto_key_t *privkey; 101 102 if (kssl_entry->ke_no_freeall) { 103 kmem_free(kssl_entry, sizeof (kssl_entry_t)); 104 return; 105 } 106 107 if ((cert = kssl_entry->ke_server_certificate) != NULL) { 108 certificate_free(cert); 109 } 110 111 if ((privkey = kssl_entry->ke_private_key) != NULL) { 112 privateKey_free(privkey); 113 }; 114 115 for (i = 0; i < kssl_entry->sid_cache_nentries; i++) 116 mutex_destroy(&(kssl_entry->sid_cache[i].se_lock)); 117 118 kmem_free(kssl_entry->sid_cache, 119 kssl_entry->sid_cache_nentries * sizeof (kssl_sid_ent_t)); 120 121 ASSERT(kssl_entry->ke_proxy_head == NULL); 122 ASSERT(kssl_entry->ke_fallback_head == NULL); 123 124 kmem_free(kssl_entry, sizeof (kssl_entry_t)); 125 } 126 127 /* 128 * Returns the index of the entry in kssl_entry_tab[] that matches 129 * the address and port. Returns -1 if no match is found. 130 */ 131 static int 132 kssl_find_entry(ipaddr_t laddr, in_port_t port, int type, 133 boolean_t wild_card_match) 134 { 135 int i; 136 kssl_entry_t *ep; 137 138 ASSERT(MUTEX_HELD(&kssl_tab_mutex)); 139 140 for (i = 0; i < kssl_entry_tab_size; i++) { 141 ep = kssl_entry_tab[i]; 142 if (ep == NULL) 143 continue; 144 145 if (!((type == IS_SSL_PORT && ep->ke_ssl_port == port) || 146 (type == IS_PROXY_PORT && ep->ke_proxy_port == port))) 147 continue; 148 149 if ((ep->ke_laddr == laddr) || (wild_card_match && 150 ((laddr == INADDR_ANY) || (ep->ke_laddr == INADDR_ANY)))) 151 break; 152 } 153 154 if (i == kssl_entry_tab_size) 155 return (-1); 156 157 return (i); 158 } 159 160 static void 161 copy_int_to_bytearray(int x, uchar_t *buf) 162 { 163 buf[0] = (x >> 16) & 0xff; 164 buf[1] = (x >> 8) & 0xff; 165 buf[2] = (x) & 0xff; 166 } 167 168 static int 169 extract_certificate(kssl_params_t *kssl_params, Certificate_t **certpp) 170 { 171 int i, len; 172 uint64_t in_size; 173 uchar_t *end_pos; 174 uint32_t ncert; 175 uint32_t *cert_sizes; 176 Certificate_t *cert; 177 char *begin = (char *)kssl_params; 178 uchar_t *cert_buf; 179 int cert_buf_len; 180 uchar_t *cert_from, *cert_to; 181 182 ASSERT(kssl_params); 183 184 in_size = kssl_params->kssl_params_size; 185 end_pos = (uchar_t *)kssl_params + in_size; 186 187 /* 188 * Get the certs array. First the array of sizes, then the actual 189 * certs. 190 */ 191 ncert = kssl_params->kssl_certs.sc_count; 192 193 if (ncert == 0) { 194 /* no certs in here! why did ya call? */ 195 return (EINVAL); 196 } 197 if (in_size < (sizeof (kssl_params_t) + ncert * sizeof (uint32_t))) { 198 return (EINVAL); 199 } 200 201 /* Trusting that the system call preserved the 4-byte aligment */ 202 cert_sizes = (uint32_t *)(begin + 203 kssl_params->kssl_certs.sc_sizes_offset); 204 205 /* should this be an ASSERT()? */ 206 if (!IS_P2ALIGNED(cert_sizes, sizeof (uint32_t))) { 207 return (EINVAL); 208 } 209 210 len = 0; 211 for (i = 0; i < ncert; i++) { 212 if (cert_sizes[i] < 1) { 213 return (EINVAL); 214 } 215 len += cert_sizes[i] + 3; 216 } 217 218 len += 3; /* length of certificate message without msg header */ 219 220 cert_buf_len = len + 4 + 4; /* add space for msg headers */ 221 222 cert_buf = kmem_alloc(cert_buf_len, KM_SLEEP); 223 224 cert_buf[0] = (uchar_t)certificate; 225 copy_int_to_bytearray(len, & cert_buf[1]); 226 copy_int_to_bytearray(len - 3, & cert_buf[4]); 227 228 cert_from = (uchar_t *)(begin + 229 kssl_params->kssl_certs.sc_certs_offset); 230 cert_to = &cert_buf[7]; 231 232 for (i = 0; i < ncert; i++) { 233 copy_int_to_bytearray(cert_sizes[i], cert_to); 234 cert_to += 3; 235 236 if (cert_from + cert_sizes[i] > end_pos) { 237 kmem_free(cert_buf, cert_buf_len); 238 return (EINVAL); 239 } 240 241 bcopy(cert_from, cert_to, cert_sizes[i]); 242 cert_from += cert_sizes[i]; 243 cert_to += cert_sizes[i]; 244 } 245 246 len += 4; 247 cert_buf[len] = (uchar_t)server_hello_done; 248 copy_int_to_bytearray(0, & cert_buf[len + 1]); 249 250 cert = kmem_alloc(sizeof (Certificate_t), KM_SLEEP); 251 cert->msg = cert_buf; 252 cert->len = cert_buf_len; 253 254 *certpp = cert; 255 256 return (0); 257 } 258 259 static int 260 extract_private_key(kssl_params_t *kssl_params, crypto_key_t **privkey) 261 { 262 char *begin = (char *)kssl_params; 263 char *end_pos; 264 int i, j, rv; 265 size_t attrs_size; 266 crypto_object_attribute_t *newattrs = NULL; 267 char *mp_attrs; 268 kssl_object_attribute_t att; 269 char *attval; 270 uint32_t attlen; 271 crypto_key_t *kssl_privkey; 272 273 end_pos = (char *)kssl_params + kssl_params->kssl_params_size; 274 275 kssl_privkey = kmem_alloc(sizeof (crypto_key_t), KM_SLEEP); 276 277 kssl_privkey->ck_format = kssl_params->kssl_privkey.ks_format; 278 kssl_privkey->ck_count = kssl_params->kssl_privkey.ks_count; 279 280 switch (kssl_privkey->ck_format) { 281 case CRYPTO_KEY_ATTR_LIST: 282 break; 283 case CRYPTO_KEY_RAW: 284 case CRYPTO_KEY_REFERENCE: 285 default: 286 rv = EINVAL; 287 goto err1; 288 } 289 290 /* allocate the attributes */ 291 attrs_size = kssl_privkey->ck_count * 292 sizeof (crypto_object_attribute_t); 293 294 newattrs = kmem_alloc(attrs_size, KM_NOSLEEP); 295 if (newattrs == NULL) { 296 rv = ENOMEM; 297 goto err1; 298 } 299 300 mp_attrs = begin + kssl_params->kssl_privkey.ks_attrs_offset; 301 if (mp_attrs + attrs_size > end_pos) { 302 rv = EINVAL; 303 goto err1; 304 } 305 306 /* Now the individual attributes */ 307 for (i = 0; i < kssl_privkey->ck_count; i++) { 308 309 bcopy(mp_attrs, &att, sizeof (kssl_object_attribute_t)); 310 311 mp_attrs += sizeof (kssl_object_attribute_t); 312 313 attval = begin + att.ka_value_offset; 314 attlen = att.ka_value_len; 315 316 if (attval + attlen > end_pos) { 317 rv = EINVAL; 318 goto err2; 319 } 320 321 newattrs[i].oa_type = att.ka_type; 322 newattrs[i].oa_value_len = attlen; 323 newattrs[i].oa_value = kmem_alloc(attlen, KM_NOSLEEP); 324 if (newattrs[i].oa_value == NULL) { 325 rv = ENOMEM; 326 goto err2; 327 } 328 329 bcopy(attval, newattrs[i].oa_value, attlen); 330 } 331 332 kssl_privkey->ck_attrs = newattrs; 333 334 *privkey = kssl_privkey; 335 336 return (0); 337 338 err2: 339 for (j = 0; j < i; j++) { 340 kmem_free(newattrs[j].oa_value, newattrs[j].oa_value_len); 341 } 342 kmem_free(newattrs, attrs_size); 343 err1: 344 kmem_free(kssl_privkey, sizeof (crypto_key_t)); 345 return (rv); 346 } 347 348 static kssl_entry_t * 349 create_kssl_entry(kssl_params_t *kssl_params, Certificate_t *cert, 350 crypto_key_t *privkey) 351 { 352 int i; 353 uint16_t s; 354 kssl_entry_t *kssl_entry; 355 uint_t cnt, mech_count; 356 crypto_mech_name_t *mechs; 357 boolean_t got_rsa, got_md5, got_sha1, got_rc4, got_des, got_3des; 358 359 kssl_entry = kmem_zalloc(sizeof (kssl_entry_t), KM_SLEEP); 360 361 kssl_entry->ke_laddr = kssl_params->kssl_addr.sin_addr.s_addr; 362 kssl_entry->ke_ssl_port = kssl_params->kssl_addr.sin_port; 363 kssl_entry->ke_proxy_port = kssl_params->kssl_proxy_port; 364 if (kssl_params->kssl_session_cache_timeout == 0) 365 kssl_entry->sid_cache_timeout = DEFAULT_SID_TIMEOUT; 366 else 367 kssl_entry->sid_cache_timeout = 368 kssl_params->kssl_session_cache_timeout; 369 if (kssl_params->kssl_session_cache_size == 0) 370 kssl_entry->sid_cache_nentries = DEFAULT_SID_CACHE_NENTRIES; 371 else 372 kssl_entry->sid_cache_nentries = 373 kssl_params->kssl_session_cache_size; 374 kssl_entry->ke_private_key = privkey; 375 kssl_entry->ke_server_certificate = cert; 376 377 mechs = crypto_get_mech_list(&mech_count, KM_SLEEP); 378 if (mechs != NULL) { 379 got_rsa = got_md5 = got_sha1 = got_rc4 = 380 got_des = got_3des = B_FALSE; 381 for (i = 0; i < mech_count; i++) { 382 if (strncmp(SUN_CKM_RSA_X_509, mechs[i], 383 CRYPTO_MAX_MECH_NAME) == 0) 384 got_rsa = B_TRUE; 385 else if (strncmp(SUN_CKM_MD5_HMAC, mechs[i], 386 CRYPTO_MAX_MECH_NAME) == 0) 387 got_md5 = B_TRUE; 388 else if (strncmp(SUN_CKM_SHA1_HMAC, mechs[i], 389 CRYPTO_MAX_MECH_NAME) == 0) 390 got_sha1 = B_TRUE; 391 else if (strncmp(SUN_CKM_RC4, mechs[i], 392 CRYPTO_MAX_MECH_NAME) == 0) 393 got_rc4 = B_TRUE; 394 else if (strncmp(SUN_CKM_DES_CBC, mechs[i], 395 CRYPTO_MAX_MECH_NAME) == 0) 396 got_des = B_TRUE; 397 else if (strncmp(SUN_CKM_DES3_CBC, mechs[i], 398 CRYPTO_MAX_MECH_NAME) == 0) 399 got_3des = B_TRUE; 400 } 401 402 cnt = 0; 403 for (i = 0; i < CIPHER_SUITE_COUNT - 1; i++) { 404 switch (s = kssl_params->kssl_suites[i]) { 405 case SSL_RSA_WITH_RC4_128_MD5: 406 if (got_rsa && got_rc4 && got_md5) 407 kssl_entry->kssl_cipherSuites[cnt++] = s; 408 break; 409 case SSL_RSA_WITH_RC4_128_SHA: 410 if (got_rsa && got_rc4 && got_sha1) 411 kssl_entry->kssl_cipherSuites[cnt++] = s; 412 break; 413 case SSL_RSA_WITH_DES_CBC_SHA: 414 if (got_rsa && got_des && got_sha1) 415 kssl_entry->kssl_cipherSuites[cnt++] = s; 416 break; 417 case SSL_RSA_WITH_3DES_EDE_CBC_SHA: 418 if (got_rsa && got_3des && got_sha1) 419 kssl_entry->kssl_cipherSuites[cnt++] = s; 420 break; 421 case CIPHER_NOTSET: 422 default: 423 break; 424 } 425 } 426 427 crypto_free_mech_list(mechs, mech_count); 428 } 429 430 /* Add the no encryption suite to the end */ 431 kssl_entry->kssl_cipherSuites[cnt++] = SSL_RSA_WITH_NULL_SHA; 432 kssl_entry->kssl_cipherSuites_nentries = cnt; 433 for (i = 0; i < cnt; i++) 434 kssl_entry->kssl_saved_Suites[i] = 435 kssl_entry->kssl_cipherSuites[i]; 436 437 kssl_entry->sid_cache = kmem_alloc( 438 kssl_entry->sid_cache_nentries * sizeof (kssl_sid_ent_t), KM_SLEEP); 439 440 for (i = 0; i < kssl_entry->sid_cache_nentries; i++) { 441 mutex_init(&(kssl_entry->sid_cache[i].se_lock), NULL, 442 MUTEX_DEFAULT, NULL); 443 kssl_entry->sid_cache[i].se_used = 0; 444 kssl_entry->sid_cache[i].se_sid.cached = B_FALSE; 445 } 446 447 KSSL_ENTRY_REFHOLD(kssl_entry); 448 449 return (kssl_entry); 450 } 451 452 int 453 kssl_add_entry(kssl_params_t *kssl_params) 454 { 455 int rv, index, i; 456 Certificate_t *cert; 457 crypto_key_t *privkey; 458 kssl_entry_t *kssl_entry; 459 ipaddr_t laddr; 460 461 if ((rv = extract_certificate(kssl_params, &cert)) != 0) { 462 return (rv); 463 } 464 465 if ((rv = extract_private_key(kssl_params, &privkey)) != 0) { 466 certificate_free(cert); 467 return (rv); 468 } 469 470 kssl_entry = create_kssl_entry(kssl_params, cert, privkey); 471 472 /* Revisit here for IPv6 support */ 473 laddr = kssl_params->kssl_addr.sin_addr.s_addr; 474 475 retry: 476 mutex_enter(&kssl_tab_mutex); 477 /* Allocate the array first time here */ 478 if (kssl_entry_tab == NULL) { 479 size_t allocsize; 480 kssl_entry_t **tmp_tab; 481 int tmp_size; 482 483 tmp_size = KSSL_TAB_INITSIZE; 484 allocsize = tmp_size * sizeof (kssl_entry_t *); 485 mutex_exit(&kssl_tab_mutex); 486 tmp_tab = kmem_zalloc(allocsize, KM_SLEEP); 487 mutex_enter(&kssl_tab_mutex); 488 if (kssl_entry_tab != NULL) { 489 mutex_exit(&kssl_tab_mutex); 490 kmem_free(tmp_tab, allocsize); 491 goto retry; 492 } 493 kssl_entry_tab_size = tmp_size; 494 kssl_entry_tab = tmp_tab; 495 index = 0; 496 } else { 497 /* Check if a matching entry exists already */ 498 index = kssl_find_entry(laddr, 499 kssl_params->kssl_addr.sin_port, IS_SSL_PORT, B_TRUE); 500 501 if (index == -1) { 502 /* Check if an entry with the same proxy port exists */ 503 if (kssl_find_entry(laddr, kssl_params->kssl_proxy_port, 504 IS_PROXY_PORT, B_TRUE) != -1) { 505 mutex_exit(&kssl_tab_mutex); 506 kssl_free_entry(kssl_entry); 507 return (EADDRINUSE); 508 } 509 510 /* No matching entry, find an empty spot */ 511 for (i = 0; i < kssl_entry_tab_size; i++) { 512 if (kssl_entry_tab[i] == NULL) 513 break; 514 } 515 /* Table full. Gotta grow it */ 516 if (i == kssl_entry_tab_size) { 517 kssl_entry_t **new_tab, **old_tab; 518 size_t allocsize; 519 size_t oldtabsize = kssl_entry_tab_size * 520 sizeof (kssl_entry_t *); 521 int tmp_size, old_size; 522 523 tmp_size = old_size = kssl_entry_tab_size; 524 tmp_size += KSSL_TAB_INITSIZE; 525 allocsize = tmp_size * sizeof (kssl_entry_t *); 526 mutex_exit(&kssl_tab_mutex); 527 new_tab = kmem_zalloc(allocsize, KM_SLEEP); 528 mutex_enter(&kssl_tab_mutex); 529 if (kssl_entry_tab_size > old_size) { 530 mutex_exit(&kssl_tab_mutex); 531 kmem_free(new_tab, allocsize); 532 goto retry; 533 } 534 535 kssl_entry_tab_size = tmp_size; 536 bcopy(kssl_entry_tab, new_tab, oldtabsize); 537 538 old_tab = kssl_entry_tab; 539 kssl_entry_tab = new_tab; 540 541 kmem_free(old_tab, oldtabsize); 542 } 543 index = i; 544 } else { 545 /* 546 * We do not want an entry with a specific address and 547 * an entry with IN_ADDR_ANY to coexist. We could 548 * replace the existing entry. But, most likely this 549 * is misconfiguration. Better bail out with an error. 550 */ 551 if ((laddr == INADDR_ANY && 552 (kssl_entry_tab[index]->ke_laddr != INADDR_ANY)) || 553 (laddr != INADDR_ANY && 554 (kssl_entry_tab[index]->ke_laddr == INADDR_ANY))) { 555 mutex_exit(&kssl_tab_mutex); 556 kssl_free_entry(kssl_entry); 557 return (EEXIST); 558 } 559 560 /* Replace the existing entry */ 561 KSSL_ENTRY_REFRELE(kssl_entry_tab[index]); 562 kssl_entry_tab[index] = NULL; 563 kssl_entry_tab_nentries--; 564 } 565 } 566 567 kssl_entry_tab[index] = kssl_entry; 568 kssl_entry_tab_nentries++; 569 mutex_exit(&kssl_tab_mutex); 570 571 return (0); 572 } 573 574 int 575 kssl_delete_entry(struct sockaddr_in *kssl_addr) 576 { 577 ipaddr_t laddr; 578 int index; 579 580 /* Revisit here for IPv6 support */ 581 laddr = kssl_addr->sin_addr.s_addr; 582 583 mutex_enter(&kssl_tab_mutex); 584 index = kssl_find_entry(laddr, kssl_addr->sin_port, 585 IS_SSL_PORT, B_FALSE); 586 587 if (index == -1) { 588 mutex_exit(&kssl_tab_mutex); 589 return (ENOENT); 590 } 591 592 KSSL_ENTRY_REFRELE(kssl_entry_tab[index]); 593 kssl_entry_tab[index] = NULL; 594 kssl_entry_tab_nentries--; 595 596 mutex_exit(&kssl_tab_mutex); 597 598 return (0); 599 } 600