xref: /titanic_52/usr/src/uts/common/inet/kssl/ksslioctl.c (revision f841f6ad96ea6675d6c6b35c749eaac601799fdf)
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