ksslioctl.c revision c892ebf1bef94f4f922f282c11516677c134dbe0
c28749e97052f09388969427adf7df641cdcdc22kais * CDDL HEADER START
c28749e97052f09388969427adf7df641cdcdc22kais * The contents of this file are subject to the terms of the
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * Common Development and Distribution License (the "License").
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * You may not use this file except in compliance with the License.
c28749e97052f09388969427adf7df641cdcdc22kais * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c28749e97052f09388969427adf7df641cdcdc22kais * See the License for the specific language governing permissions
c28749e97052f09388969427adf7df641cdcdc22kais * and limitations under the License.
c28749e97052f09388969427adf7df641cdcdc22kais * When distributing Covered Code, include this CDDL HEADER in each
c28749e97052f09388969427adf7df641cdcdc22kais * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
c28749e97052f09388969427adf7df641cdcdc22kais * If applicable, add the following below this CDDL HEADER, with the
c28749e97052f09388969427adf7df641cdcdc22kais * fields enclosed by brackets "[]" replaced with your own identifying
c28749e97052f09388969427adf7df641cdcdc22kais * information: Portions Copyright [yyyy] [name of copyright owner]
c28749e97052f09388969427adf7df641cdcdc22kais * CDDL HEADER END
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
c28749e97052f09388969427adf7df641cdcdc22kais * Use is subject to license terms.
c28749e97052f09388969427adf7df641cdcdc22kais#pragma ident "%Z%%M% %I% %E% SMI"
c28749e97052f09388969427adf7df641cdcdc22kais * The kernel SSL module ioctls.
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void
c892ebf1bef94f4f922f282c11516677c134dbe0krishna attrs_size = privkey->ck_count * sizeof (crypto_object_attribute_t);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna (void) crypto_session_logout(s->prov, s->sid, NULL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna kmem_free(s, sizeof (kssl_session_info_t) + s->pinlen);
c28749e97052f09388969427adf7df641cdcdc22kais * Frees the space for the entry and the keys and certs
c28749e97052f09388969427adf7df641cdcdc22kais * it carries.
c28749e97052f09388969427adf7df641cdcdc22kais if ((cert = kssl_entry->ke_server_certificate) != NULL) {
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->sid_cache_nentries * sizeof (kssl_sid_ent_t));
c28749e97052f09388969427adf7df641cdcdc22kais * Returns the index of the entry in kssl_entry_tab[] that matches
c28749e97052f09388969427adf7df641cdcdc22kais * the address and port. Returns -1 if no match is found.
c28749e97052f09388969427adf7df641cdcdc22kaiskssl_find_entry(ipaddr_t laddr, in_port_t port, int type,
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < kssl_entry_tab_size; i++) {
c28749e97052f09388969427adf7df641cdcdc22kais if (!((type == IS_SSL_PORT && ep->ke_ssl_port == port) ||
c28749e97052f09388969427adf7df641cdcdc22kais ((laddr == INADDR_ANY) || (ep->ke_laddr == INADDR_ANY))))
c28749e97052f09388969427adf7df641cdcdc22kais return (-1);
c28749e97052f09388969427adf7df641cdcdc22kais return (i);
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void
c28749e97052f09388969427adf7df641cdcdc22kaisextract_certificate(kssl_params_t *kssl_params, Certificate_t **certpp)
c28749e97052f09388969427adf7df641cdcdc22kais * Get the certs array. First the array of sizes, then the actual
c28749e97052f09388969427adf7df641cdcdc22kais if (ncert == 0) {
c28749e97052f09388969427adf7df641cdcdc22kais /* no certs in here! why did ya call? */
c28749e97052f09388969427adf7df641cdcdc22kais if (in_size < (sizeof (kssl_params_t) + ncert * sizeof (uint32_t))) {
c892ebf1bef94f4f922f282c11516677c134dbe0krishna /* Trusting that the system call preserved the 4-byte alignment */
c28749e97052f09388969427adf7df641cdcdc22kais /* should this be an ASSERT()? */
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < ncert; i++) {
c28749e97052f09388969427adf7df641cdcdc22kais len += 3; /* length of certificate message without msg header */
c28749e97052f09388969427adf7df641cdcdc22kais cert_buf_len = len + 4 + 4; /* add space for msg headers */
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < ncert; i++) {
c28749e97052f09388969427adf7df641cdcdc22kais return (0);
c28749e97052f09388969427adf7df641cdcdc22kaisextract_private_key(kssl_params_t *kssl_params, crypto_key_t **privkey)
c28749e97052f09388969427adf7df641cdcdc22kais int i, j, rv;
c28749e97052f09388969427adf7df641cdcdc22kais end_pos = (char *)kssl_params + kssl_params->kssl_params_size;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_privkey = kmem_alloc(sizeof (crypto_key_t), KM_SLEEP);
c28749e97052f09388969427adf7df641cdcdc22kais kssl_privkey->ck_format = kssl_params->kssl_privkey.ks_format;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_privkey->ck_count = kssl_params->kssl_privkey.ks_count;
c28749e97052f09388969427adf7df641cdcdc22kais /* allocate the attributes */
c28749e97052f09388969427adf7df641cdcdc22kais mp_attrs = begin + kssl_params->kssl_privkey.ks_attrs_offset;
c28749e97052f09388969427adf7df641cdcdc22kais /* Now the individual attributes */
c28749e97052f09388969427adf7df641cdcdc22kais bcopy(mp_attrs, &att, sizeof (kssl_object_attribute_t));
c892ebf1bef94f4f922f282c11516677c134dbe0krishna newattrs[i].oa_value = kmem_alloc(attlen, KM_SLEEP);
c28749e97052f09388969427adf7df641cdcdc22kais return (0);
c28749e97052f09388969427adf7df641cdcdc22kais for (j = 0; j < i; j++) {
c892ebf1bef94f4f922f282c11516677c134dbe0krishna bzero(newattrs[j].oa_value, newattrs[j].oa_value_len);
c28749e97052f09388969427adf7df641cdcdc22kais kmem_free(newattrs[j].oa_value, newattrs[j].oa_value_len);
c892ebf1bef94f4f922f282c11516677c134dbe0krishnacreate_sessinfo(kssl_params_t *kssl_params, kssl_entry_t *kssl_entry)
c892ebf1bef94f4f922f282c11516677c134dbe0krishna /* Do a sanity check */
c892ebf1bef94f4f922f282c11516677c134dbe0krishna s = kmem_zalloc(sizeof (kssl_session_info_t) + t->pinlen, KM_SLEEP);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna bcopy(t->toklabel, s->toklabel, CRYPTO_EXT_SIZE_LABEL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna /* Get the handle to the non extractable key */
c892ebf1bef94f4f922f282c11516677c134dbe0krishna return (0);
c28749e97052f09388969427adf7df641cdcdc22kaiscreate_kssl_entry(kssl_params_t *kssl_params, Certificate_t *cert,
c28749e97052f09388969427adf7df641cdcdc22kais boolean_t got_rsa, got_md5, got_sha1, got_rc4, got_des, got_3des;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry = kmem_zalloc(sizeof (kssl_entry_t), KM_SLEEP);
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->ke_laddr = kssl_params->kssl_addr.sin_addr.s_addr;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->ke_ssl_port = kssl_params->kssl_addr.sin_port;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->ke_proxy_port = kssl_params->kssl_proxy_port;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->sid_cache_nentries = DEFAULT_SID_CACHE_NENTRIES;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna kssl_entry->ke_is_nxkey = kssl_params->kssl_is_nxkey;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna if (create_sessinfo(kssl_params, kssl_entry) != 0) {
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < mech_count; i++) {
c28749e97052f09388969427adf7df641cdcdc22kais /* Add the no encryption suite to the end */
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->kssl_cipherSuites[cnt++] = SSL_RSA_WITH_NULL_SHA;
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < cnt; i++)
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->sid_cache_nentries * sizeof (kssl_sid_ent_t), KM_SLEEP);
c28749e97052f09388969427adf7df641cdcdc22kais if ((rv = extract_certificate(kssl_params, &cert)) != 0) {
c28749e97052f09388969427adf7df641cdcdc22kais if ((rv = extract_private_key(kssl_params, &privkey)) != 0) {
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry = create_kssl_entry(kssl_params, cert, privkey);
c28749e97052f09388969427adf7df641cdcdc22kais /* Revisit here for IPv6 support */
c28749e97052f09388969427adf7df641cdcdc22kais /* Allocate the array first time here */
c28749e97052f09388969427adf7df641cdcdc22kais /* Check if a matching entry exists already */
c28749e97052f09388969427adf7df641cdcdc22kais /* Check if an entry with the same proxy port exists */
c28749e97052f09388969427adf7df641cdcdc22kais if (kssl_find_entry(laddr, kssl_params->kssl_proxy_port,
c28749e97052f09388969427adf7df641cdcdc22kais /* No matching entry, find an empty spot */
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < kssl_entry_tab_size; i++) {
c28749e97052f09388969427adf7df641cdcdc22kais /* Table full. Gotta grow it */
c28749e97052f09388969427adf7df641cdcdc22kais * We do not want an entry with a specific address and
c28749e97052f09388969427adf7df641cdcdc22kais * an entry with IN_ADDR_ANY to coexist. We could
c28749e97052f09388969427adf7df641cdcdc22kais * replace the existing entry. But, most likely this
c28749e97052f09388969427adf7df641cdcdc22kais * is misconfiguration. Better bail out with an error.
c28749e97052f09388969427adf7df641cdcdc22kais /* Replace the existing entry */
c28749e97052f09388969427adf7df641cdcdc22kais return (0);
c28749e97052f09388969427adf7df641cdcdc22kais /* Revisit here for IPv6 support */
c28749e97052f09388969427adf7df641cdcdc22kais return (0);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * We care about only one private key object.
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * So, set the max count to only 1.
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * Open a session to the provider specified by the label and
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * authenticate to it. Find the private key object with the
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * specified attributes and save the handle. The userland component
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * must set all the attributes in the template so as to uniquely
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * identify the object.
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * Note that the handle will be invalid if we logout or close
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * the session to the provider.
c892ebf1bef94f4f922f282c11516677c134dbe0krishna unsigned int count;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna rv = crypto_object_find_init(prov, sid, attrs, count, &cookie, NULL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna rv = crypto_object_find(prov, cookie, ohndl, &count,
c892ebf1bef94f4f922f282c11516677c134dbe0krishna (void) crypto_object_find_final(prov, cookie, NULL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna /* Keep the handle around for later use */