c28749e97052f09388969427adf7df641cdcdc22kais/*
c28749e97052f09388969427adf7df641cdcdc22kais * CDDL HEADER START
c28749e97052f09388969427adf7df641cdcdc22kais *
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 *
c28749e97052f09388969427adf7df641cdcdc22kais * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c28749e97052f09388969427adf7df641cdcdc22kais * or http://www.opensolaris.org/os/licensing.
c28749e97052f09388969427adf7df641cdcdc22kais * See the License for the specific language governing permissions
c28749e97052f09388969427adf7df641cdcdc22kais * and limitations under the License.
c28749e97052f09388969427adf7df641cdcdc22kais *
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 *
c28749e97052f09388969427adf7df641cdcdc22kais * CDDL HEADER END
c28749e97052f09388969427adf7df641cdcdc22kais */
c28749e97052f09388969427adf7df641cdcdc22kais/*
65d184575ba5adcc532b970fc99d2f67e2df7af6Vladimir Kotal * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
c28749e97052f09388969427adf7df641cdcdc22kais * Use is subject to license terms.
c28749e97052f09388969427adf7df641cdcdc22kais */
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais/*
c28749e97052f09388969427adf7df641cdcdc22kais * The kernel SSL module ioctls.
c28749e97052f09388969427adf7df641cdcdc22kais */
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais#include <sys/types.h>
c28749e97052f09388969427adf7df641cdcdc22kais#include <sys/modctl.h>
c28749e97052f09388969427adf7df641cdcdc22kais#include <sys/conf.h>
c28749e97052f09388969427adf7df641cdcdc22kais#include <sys/ddi.h>
c28749e97052f09388969427adf7df641cdcdc22kais#include <sys/sunddi.h>
c28749e97052f09388969427adf7df641cdcdc22kais#include <sys/kmem.h>
c28749e97052f09388969427adf7df641cdcdc22kais#include <sys/errno.h>
c28749e97052f09388969427adf7df641cdcdc22kais#include <sys/file.h>
c28749e97052f09388969427adf7df641cdcdc22kais#include <sys/cred.h>
c28749e97052f09388969427adf7df641cdcdc22kais#include <sys/proc.h>
c28749e97052f09388969427adf7df641cdcdc22kais#include <sys/task.h>
c28749e97052f09388969427adf7df641cdcdc22kais#include <sys/model.h>
c28749e97052f09388969427adf7df641cdcdc22kais#include <sys/sysmacros.h>
c28749e97052f09388969427adf7df641cdcdc22kais#include <sys/policy.h>
c28749e97052f09388969427adf7df641cdcdc22kais#include <sys/crypto/common.h>
c28749e97052f09388969427adf7df641cdcdc22kais#include <sys/crypto/api.h>
c28749e97052f09388969427adf7df641cdcdc22kais#include <inet/common.h>
c28749e97052f09388969427adf7df641cdcdc22kais#include <inet/ip.h>
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais#include "ksslimpl.h"
c28749e97052f09388969427adf7df641cdcdc22kais#include "kssl.h"
c28749e97052f09388969427adf7df641cdcdc22kais#include "ksslproto.h"
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kaiskssl_entry_t **kssl_entry_tab;
c28749e97052f09388969427adf7df641cdcdc22kaisint kssl_entry_tab_size;
c28749e97052f09388969427adf7df641cdcdc22kaisint kssl_entry_tab_nentries;
65d184575ba5adcc532b970fc99d2f67e2df7af6Vladimir Kotaluint_t null_cipher_suite; /* setable in /etc/system */
c28749e97052f09388969427adf7df641cdcdc22kaiskmutex_t kssl_tab_mutex;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void
c28749e97052f09388969427adf7df641cdcdc22kaiscertificate_free(Certificate_t *cert)
c28749e97052f09388969427adf7df641cdcdc22kais{
c28749e97052f09388969427adf7df641cdcdc22kais kmem_free(cert->msg, cert->len);
c28749e97052f09388969427adf7df641cdcdc22kais kmem_free(cert, sizeof (struct Certificate));
c28749e97052f09388969427adf7df641cdcdc22kais}
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void
c28749e97052f09388969427adf7df641cdcdc22kaisprivateKey_free(crypto_key_t *privkey)
c28749e97052f09388969427adf7df641cdcdc22kais{
c28749e97052f09388969427adf7df641cdcdc22kais int i;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna size_t attrs_size;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna crypto_object_attribute_t *attrs;
c28749e97052f09388969427adf7df641cdcdc22kais
c892ebf1bef94f4f922f282c11516677c134dbe0krishna attrs = privkey->ck_attrs;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna attrs_size = privkey->ck_count * sizeof (crypto_object_attribute_t);
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < privkey->ck_count; i++) {
c28749e97052f09388969427adf7df641cdcdc22kais bzero(attrs[i].oa_value, attrs[i].oa_value_len);
c28749e97052f09388969427adf7df641cdcdc22kais kmem_free(attrs[i].oa_value, attrs[i].oa_value_len);
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais kmem_free(attrs, attrs_size);
c28749e97052f09388969427adf7df641cdcdc22kais kmem_free(privkey, sizeof (crypto_key_t));
c28749e97052f09388969427adf7df641cdcdc22kais}
c28749e97052f09388969427adf7df641cdcdc22kais
c892ebf1bef94f4f922f282c11516677c134dbe0krishnastatic void
c892ebf1bef94f4f922f282c11516677c134dbe0krishnasess_free(kssl_session_info_t *s)
c892ebf1bef94f4f922f282c11516677c134dbe0krishna{
c892ebf1bef94f4f922f282c11516677c134dbe0krishna if (s->is_valid_handle) {
c892ebf1bef94f4f922f282c11516677c134dbe0krishna (void) crypto_session_logout(s->prov, s->sid, NULL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna (void) crypto_session_close(s->prov, s->sid, NULL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna crypto_release_provider(s->prov);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna s->is_valid_handle = B_FALSE;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna }
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c892ebf1bef94f4f922f282c11516677c134dbe0krishna if (s->evnt_handle != NULL) {
c892ebf1bef94f4f922f282c11516677c134dbe0krishna crypto_unnotify_events(s->evnt_handle);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna s->evnt_handle = NULL;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna }
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c892ebf1bef94f4f922f282c11516677c134dbe0krishna bzero(s->tokpin, s->pinlen);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna kmem_free(s, sizeof (kssl_session_info_t) + s->pinlen);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna}
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c28749e97052f09388969427adf7df641cdcdc22kais/*
c28749e97052f09388969427adf7df641cdcdc22kais * Frees the space for the entry and the keys and certs
c28749e97052f09388969427adf7df641cdcdc22kais * it carries.
c28749e97052f09388969427adf7df641cdcdc22kais */
c28749e97052f09388969427adf7df641cdcdc22kaisvoid
c28749e97052f09388969427adf7df641cdcdc22kaiskssl_free_entry(kssl_entry_t *kssl_entry)
c28749e97052f09388969427adf7df641cdcdc22kais{
c28749e97052f09388969427adf7df641cdcdc22kais int i;
c28749e97052f09388969427adf7df641cdcdc22kais Certificate_t *cert;
c28749e97052f09388969427adf7df641cdcdc22kais crypto_key_t *privkey;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna kssl_session_info_t *s;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais if (kssl_entry->ke_no_freeall) {
c28749e97052f09388969427adf7df641cdcdc22kais kmem_free(kssl_entry, sizeof (kssl_entry_t));
c28749e97052f09388969427adf7df641cdcdc22kais return;
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais if ((cert = kssl_entry->ke_server_certificate) != NULL) {
c28749e97052f09388969427adf7df641cdcdc22kais certificate_free(cert);
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais if ((privkey = kssl_entry->ke_private_key) != NULL) {
c28749e97052f09388969427adf7df641cdcdc22kais privateKey_free(privkey);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < kssl_entry->sid_cache_nentries; i++)
c28749e97052f09388969427adf7df641cdcdc22kais mutex_destroy(&(kssl_entry->sid_cache[i].se_lock));
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais kmem_free(kssl_entry->sid_cache,
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->sid_cache_nentries * sizeof (kssl_sid_ent_t));
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais ASSERT(kssl_entry->ke_proxy_head == NULL);
c28749e97052f09388969427adf7df641cdcdc22kais ASSERT(kssl_entry->ke_fallback_head == NULL);
c28749e97052f09388969427adf7df641cdcdc22kais
c892ebf1bef94f4f922f282c11516677c134dbe0krishna if ((s = kssl_entry->ke_sessinfo) != NULL) {
c892ebf1bef94f4f922f282c11516677c134dbe0krishna ASSERT(kssl_entry->ke_is_nxkey);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna sess_free(s);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna }
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c28749e97052f09388969427adf7df641cdcdc22kais kmem_free(kssl_entry, sizeof (kssl_entry_t));
c28749e97052f09388969427adf7df641cdcdc22kais}
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais/*
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.
c28749e97052f09388969427adf7df641cdcdc22kais */
c28749e97052f09388969427adf7df641cdcdc22kaisstatic int
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yendurikssl_find_entry(in6_addr_t laddr, in_port_t port, int type,
c28749e97052f09388969427adf7df641cdcdc22kais boolean_t wild_card_match)
c28749e97052f09388969427adf7df641cdcdc22kais{
c28749e97052f09388969427adf7df641cdcdc22kais int i;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry_t *ep;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais ASSERT(MUTEX_HELD(&kssl_tab_mutex));
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < kssl_entry_tab_size; i++) {
c28749e97052f09388969427adf7df641cdcdc22kais ep = kssl_entry_tab[i];
c28749e97052f09388969427adf7df641cdcdc22kais if (ep == NULL)
c28749e97052f09388969427adf7df641cdcdc22kais continue;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais if (!((type == IS_SSL_PORT && ep->ke_ssl_port == port) ||
c28749e97052f09388969427adf7df641cdcdc22kais (type == IS_PROXY_PORT && ep->ke_proxy_port == port)))
c28749e97052f09388969427adf7df641cdcdc22kais continue;
c28749e97052f09388969427adf7df641cdcdc22kais
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri if (IN6_ARE_ADDR_EQUAL(&laddr, &ep->ke_laddr) ||
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri (wild_card_match && (IN6_IS_ADDR_UNSPECIFIED(&laddr) ||
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri IN6_IS_ADDR_UNSPECIFIED(&ep->ke_laddr))))
c28749e97052f09388969427adf7df641cdcdc22kais break;
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais if (i == kssl_entry_tab_size)
c28749e97052f09388969427adf7df641cdcdc22kais return (-1);
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais return (i);
c28749e97052f09388969427adf7df641cdcdc22kais}
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void
c28749e97052f09388969427adf7df641cdcdc22kaiscopy_int_to_bytearray(int x, uchar_t *buf)
c28749e97052f09388969427adf7df641cdcdc22kais{
c28749e97052f09388969427adf7df641cdcdc22kais buf[0] = (x >> 16) & 0xff;
c28749e97052f09388969427adf7df641cdcdc22kais buf[1] = (x >> 8) & 0xff;
c28749e97052f09388969427adf7df641cdcdc22kais buf[2] = (x) & 0xff;
c28749e97052f09388969427adf7df641cdcdc22kais}
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kaisstatic int
c28749e97052f09388969427adf7df641cdcdc22kaisextract_certificate(kssl_params_t *kssl_params, Certificate_t **certpp)
c28749e97052f09388969427adf7df641cdcdc22kais{
c28749e97052f09388969427adf7df641cdcdc22kais int i, len;
c28749e97052f09388969427adf7df641cdcdc22kais uint64_t in_size;
c28749e97052f09388969427adf7df641cdcdc22kais uchar_t *end_pos;
c28749e97052f09388969427adf7df641cdcdc22kais uint32_t ncert;
c28749e97052f09388969427adf7df641cdcdc22kais uint32_t *cert_sizes;
c28749e97052f09388969427adf7df641cdcdc22kais Certificate_t *cert;
c28749e97052f09388969427adf7df641cdcdc22kais char *begin = (char *)kssl_params;
c28749e97052f09388969427adf7df641cdcdc22kais uchar_t *cert_buf;
c28749e97052f09388969427adf7df641cdcdc22kais int cert_buf_len;
c28749e97052f09388969427adf7df641cdcdc22kais uchar_t *cert_from, *cert_to;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais ASSERT(kssl_params);
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais in_size = kssl_params->kssl_params_size;
c28749e97052f09388969427adf7df641cdcdc22kais end_pos = (uchar_t *)kssl_params + in_size;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais /*
c28749e97052f09388969427adf7df641cdcdc22kais * Get the certs array. First the array of sizes, then the actual
c28749e97052f09388969427adf7df641cdcdc22kais * certs.
c28749e97052f09388969427adf7df641cdcdc22kais */
c28749e97052f09388969427adf7df641cdcdc22kais ncert = kssl_params->kssl_certs.sc_count;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais if (ncert == 0) {
c28749e97052f09388969427adf7df641cdcdc22kais /* no certs in here! why did ya call? */
c28749e97052f09388969427adf7df641cdcdc22kais return (EINVAL);
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais if (in_size < (sizeof (kssl_params_t) + ncert * sizeof (uint32_t))) {
c28749e97052f09388969427adf7df641cdcdc22kais return (EINVAL);
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c892ebf1bef94f4f922f282c11516677c134dbe0krishna /* Trusting that the system call preserved the 4-byte alignment */
c28749e97052f09388969427adf7df641cdcdc22kais cert_sizes = (uint32_t *)(begin +
c28749e97052f09388969427adf7df641cdcdc22kais kssl_params->kssl_certs.sc_sizes_offset);
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais /* should this be an ASSERT()? */
c28749e97052f09388969427adf7df641cdcdc22kais if (!IS_P2ALIGNED(cert_sizes, sizeof (uint32_t))) {
c28749e97052f09388969427adf7df641cdcdc22kais return (EINVAL);
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais len = 0;
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < ncert; i++) {
c28749e97052f09388969427adf7df641cdcdc22kais if (cert_sizes[i] < 1) {
c28749e97052f09388969427adf7df641cdcdc22kais return (EINVAL);
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais len += cert_sizes[i] + 3;
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais len += 3; /* length of certificate message without msg header */
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais cert_buf_len = len + 4 + 4; /* add space for msg headers */
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais cert_buf = kmem_alloc(cert_buf_len, KM_SLEEP);
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais cert_buf[0] = (uchar_t)certificate;
c28749e97052f09388969427adf7df641cdcdc22kais copy_int_to_bytearray(len, & cert_buf[1]);
c28749e97052f09388969427adf7df641cdcdc22kais copy_int_to_bytearray(len - 3, & cert_buf[4]);
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais cert_from = (uchar_t *)(begin +
c28749e97052f09388969427adf7df641cdcdc22kais kssl_params->kssl_certs.sc_certs_offset);
c28749e97052f09388969427adf7df641cdcdc22kais cert_to = &cert_buf[7];
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < ncert; i++) {
c28749e97052f09388969427adf7df641cdcdc22kais copy_int_to_bytearray(cert_sizes[i], cert_to);
c28749e97052f09388969427adf7df641cdcdc22kais cert_to += 3;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais if (cert_from + cert_sizes[i] > end_pos) {
c28749e97052f09388969427adf7df641cdcdc22kais kmem_free(cert_buf, cert_buf_len);
c28749e97052f09388969427adf7df641cdcdc22kais return (EINVAL);
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais bcopy(cert_from, cert_to, cert_sizes[i]);
c28749e97052f09388969427adf7df641cdcdc22kais cert_from += cert_sizes[i];
c28749e97052f09388969427adf7df641cdcdc22kais cert_to += cert_sizes[i];
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais len += 4;
c28749e97052f09388969427adf7df641cdcdc22kais cert_buf[len] = (uchar_t)server_hello_done;
c28749e97052f09388969427adf7df641cdcdc22kais copy_int_to_bytearray(0, & cert_buf[len + 1]);
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais cert = kmem_alloc(sizeof (Certificate_t), KM_SLEEP);
c28749e97052f09388969427adf7df641cdcdc22kais cert->msg = cert_buf;
c28749e97052f09388969427adf7df641cdcdc22kais cert->len = cert_buf_len;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais *certpp = cert;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais return (0);
c28749e97052f09388969427adf7df641cdcdc22kais}
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kaisstatic int
c28749e97052f09388969427adf7df641cdcdc22kaisextract_private_key(kssl_params_t *kssl_params, crypto_key_t **privkey)
c28749e97052f09388969427adf7df641cdcdc22kais{
c28749e97052f09388969427adf7df641cdcdc22kais char *begin = (char *)kssl_params;
c28749e97052f09388969427adf7df641cdcdc22kais char *end_pos;
c28749e97052f09388969427adf7df641cdcdc22kais int i, j, rv;
c28749e97052f09388969427adf7df641cdcdc22kais size_t attrs_size;
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri crypto_object_attribute_t *newattrs;
c28749e97052f09388969427adf7df641cdcdc22kais char *mp_attrs;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_object_attribute_t att;
c28749e97052f09388969427adf7df641cdcdc22kais char *attval;
c28749e97052f09388969427adf7df641cdcdc22kais uint32_t attlen;
c28749e97052f09388969427adf7df641cdcdc22kais crypto_key_t *kssl_privkey;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais end_pos = (char *)kssl_params + kssl_params->kssl_params_size;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais kssl_privkey = kmem_alloc(sizeof (crypto_key_t), KM_SLEEP);
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais kssl_privkey->ck_format = kssl_params->kssl_privkey.ks_format;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_privkey->ck_count = kssl_params->kssl_privkey.ks_count;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais switch (kssl_privkey->ck_format) {
c28749e97052f09388969427adf7df641cdcdc22kais case CRYPTO_KEY_ATTR_LIST:
c28749e97052f09388969427adf7df641cdcdc22kais break;
c28749e97052f09388969427adf7df641cdcdc22kais case CRYPTO_KEY_RAW:
c28749e97052f09388969427adf7df641cdcdc22kais case CRYPTO_KEY_REFERENCE:
c28749e97052f09388969427adf7df641cdcdc22kais default:
c28749e97052f09388969427adf7df641cdcdc22kais rv = EINVAL;
c28749e97052f09388969427adf7df641cdcdc22kais goto err1;
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais /* allocate the attributes */
c28749e97052f09388969427adf7df641cdcdc22kais attrs_size = kssl_privkey->ck_count *
c28749e97052f09388969427adf7df641cdcdc22kais sizeof (crypto_object_attribute_t);
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais mp_attrs = begin + kssl_params->kssl_privkey.ks_attrs_offset;
c28749e97052f09388969427adf7df641cdcdc22kais if (mp_attrs + attrs_size > end_pos) {
c28749e97052f09388969427adf7df641cdcdc22kais rv = EINVAL;
c28749e97052f09388969427adf7df641cdcdc22kais goto err1;
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c892ebf1bef94f4f922f282c11516677c134dbe0krishna newattrs = kmem_alloc(attrs_size, KM_SLEEP);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c28749e97052f09388969427adf7df641cdcdc22kais /* Now the individual attributes */
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < kssl_privkey->ck_count; i++) {
c28749e97052f09388969427adf7df641cdcdc22kais bcopy(mp_attrs, &att, sizeof (kssl_object_attribute_t));
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais mp_attrs += sizeof (kssl_object_attribute_t);
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais attval = begin + att.ka_value_offset;
c28749e97052f09388969427adf7df641cdcdc22kais attlen = att.ka_value_len;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais if (attval + attlen > end_pos) {
c28749e97052f09388969427adf7df641cdcdc22kais rv = EINVAL;
c28749e97052f09388969427adf7df641cdcdc22kais goto err2;
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais newattrs[i].oa_type = att.ka_type;
c28749e97052f09388969427adf7df641cdcdc22kais newattrs[i].oa_value_len = attlen;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna newattrs[i].oa_value = kmem_alloc(attlen, KM_SLEEP);
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais bcopy(attval, newattrs[i].oa_value, attlen);
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais kssl_privkey->ck_attrs = newattrs;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais *privkey = kssl_privkey;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais return (0);
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kaiserr2:
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);
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais kmem_free(newattrs, attrs_size);
c28749e97052f09388969427adf7df641cdcdc22kaiserr1:
c28749e97052f09388969427adf7df641cdcdc22kais kmem_free(kssl_privkey, sizeof (crypto_key_t));
c28749e97052f09388969427adf7df641cdcdc22kais return (rv);
c28749e97052f09388969427adf7df641cdcdc22kais}
c28749e97052f09388969427adf7df641cdcdc22kais
c892ebf1bef94f4f922f282c11516677c134dbe0krishnastatic int
c892ebf1bef94f4f922f282c11516677c134dbe0krishnacreate_sessinfo(kssl_params_t *kssl_params, kssl_entry_t *kssl_entry)
c892ebf1bef94f4f922f282c11516677c134dbe0krishna{
c892ebf1bef94f4f922f282c11516677c134dbe0krishna int rv;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna char *p;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna kssl_session_info_t *s;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna kssl_tokinfo_t *t;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c892ebf1bef94f4f922f282c11516677c134dbe0krishna t = &kssl_params->kssl_token;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna /* Do a sanity check */
c892ebf1bef94f4f922f282c11516677c134dbe0krishna if (t->pinlen > MAX_PIN_LENGTH) {
c892ebf1bef94f4f922f282c11516677c134dbe0krishna return (EINVAL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna }
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c892ebf1bef94f4f922f282c11516677c134dbe0krishna s = kmem_zalloc(sizeof (kssl_session_info_t) + t->pinlen, KM_SLEEP);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna s->pinlen = t->pinlen;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna bcopy(t->toklabel, s->toklabel, CRYPTO_EXT_SIZE_LABEL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna p = (char *)kssl_params + t->tokpin_offset;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna bcopy(p, s->tokpin, s->pinlen);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna ASSERT(kssl_entry->ke_sessinfo == NULL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna kssl_entry->ke_sessinfo = s;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c892ebf1bef94f4f922f282c11516677c134dbe0krishna /* Get the handle to the non extractable key */
c892ebf1bef94f4f922f282c11516677c134dbe0krishna rv = kssl_get_obj_handle(kssl_entry);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna kssl_params->kssl_token.ck_rv = rv;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna if (rv != CRYPTO_SUCCESS) {
c892ebf1bef94f4f922f282c11516677c134dbe0krishna sess_free(s);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna kssl_entry->ke_sessinfo = NULL;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna return (EINVAL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna }
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c892ebf1bef94f4f922f282c11516677c134dbe0krishna kssl_entry->ke_sessinfo->is_valid_handle = B_TRUE;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna kssl_entry->ke_sessinfo->do_reauth = B_FALSE;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna kssl_entry->ke_sessinfo->evnt_handle =
c892ebf1bef94f4f922f282c11516677c134dbe0krishna crypto_notify_events(kssl_prov_evnt,
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna CRYPTO_EVENT_PROVIDER_REGISTERED |
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna CRYPTO_EVENT_PROVIDER_UNREGISTERED);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c892ebf1bef94f4f922f282c11516677c134dbe0krishna return (0);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna}
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c28749e97052f09388969427adf7df641cdcdc22kaisstatic kssl_entry_t *
c28749e97052f09388969427adf7df641cdcdc22kaiscreate_kssl_entry(kssl_params_t *kssl_params, Certificate_t *cert,
c28749e97052f09388969427adf7df641cdcdc22kais crypto_key_t *privkey)
c28749e97052f09388969427adf7df641cdcdc22kais{
c28749e97052f09388969427adf7df641cdcdc22kais int i;
c28749e97052f09388969427adf7df641cdcdc22kais uint16_t s;
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna kssl_entry_t *kssl_entry, *ep;
c28749e97052f09388969427adf7df641cdcdc22kais uint_t cnt, mech_count;
c28749e97052f09388969427adf7df641cdcdc22kais crypto_mech_name_t *mechs;
c28749e97052f09388969427adf7df641cdcdc22kais boolean_t got_rsa, got_md5, got_sha1, got_rc4, got_des, got_3des;
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna boolean_t got_aes;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry = kmem_zalloc(sizeof (kssl_entry_t), KM_SLEEP);
c28749e97052f09388969427adf7df641cdcdc22kais
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri kssl_entry->ke_laddr = kssl_params->kssl_addr.sin6_addr;
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri kssl_entry->ke_ssl_port = kssl_params->kssl_addr.sin6_port;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->ke_proxy_port = kssl_params->kssl_proxy_port;
c28749e97052f09388969427adf7df641cdcdc22kais if (kssl_params->kssl_session_cache_timeout == 0)
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->sid_cache_timeout = DEFAULT_SID_TIMEOUT;
c28749e97052f09388969427adf7df641cdcdc22kais else
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->sid_cache_timeout =
c28749e97052f09388969427adf7df641cdcdc22kais kssl_params->kssl_session_cache_timeout;
c28749e97052f09388969427adf7df641cdcdc22kais if (kssl_params->kssl_session_cache_size == 0)
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->sid_cache_nentries = DEFAULT_SID_CACHE_NENTRIES;
c28749e97052f09388969427adf7df641cdcdc22kais else
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->sid_cache_nentries =
c28749e97052f09388969427adf7df641cdcdc22kais kssl_params->kssl_session_cache_size;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->ke_private_key = privkey;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->ke_server_certificate = cert;
c28749e97052f09388969427adf7df641cdcdc22kais
c892ebf1bef94f4f922f282c11516677c134dbe0krishna kssl_entry->ke_is_nxkey = kssl_params->kssl_is_nxkey;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna if (kssl_entry->ke_is_nxkey) {
c892ebf1bef94f4f922f282c11516677c134dbe0krishna if (create_sessinfo(kssl_params, kssl_entry) != 0) {
c892ebf1bef94f4f922f282c11516677c134dbe0krishna kmem_free(kssl_entry, sizeof (kssl_entry_t));
c892ebf1bef94f4f922f282c11516677c134dbe0krishna return (NULL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna }
c892ebf1bef94f4f922f282c11516677c134dbe0krishna }
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c28749e97052f09388969427adf7df641cdcdc22kais mechs = crypto_get_mech_list(&mech_count, KM_SLEEP);
c28749e97052f09388969427adf7df641cdcdc22kais if (mechs != NULL) {
c28749e97052f09388969427adf7df641cdcdc22kais got_rsa = got_md5 = got_sha1 = got_rc4 =
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna got_des = got_3des = got_aes = B_FALSE;
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < mech_count; i++) {
c28749e97052f09388969427adf7df641cdcdc22kais if (strncmp(SUN_CKM_RSA_X_509, mechs[i],
c28749e97052f09388969427adf7df641cdcdc22kais CRYPTO_MAX_MECH_NAME) == 0)
c28749e97052f09388969427adf7df641cdcdc22kais got_rsa = B_TRUE;
c28749e97052f09388969427adf7df641cdcdc22kais else if (strncmp(SUN_CKM_MD5_HMAC, mechs[i],
c28749e97052f09388969427adf7df641cdcdc22kais CRYPTO_MAX_MECH_NAME) == 0)
c28749e97052f09388969427adf7df641cdcdc22kais got_md5 = B_TRUE;
c28749e97052f09388969427adf7df641cdcdc22kais else if (strncmp(SUN_CKM_SHA1_HMAC, mechs[i],
c28749e97052f09388969427adf7df641cdcdc22kais CRYPTO_MAX_MECH_NAME) == 0)
c28749e97052f09388969427adf7df641cdcdc22kais got_sha1 = B_TRUE;
c28749e97052f09388969427adf7df641cdcdc22kais else if (strncmp(SUN_CKM_RC4, mechs[i],
c28749e97052f09388969427adf7df641cdcdc22kais CRYPTO_MAX_MECH_NAME) == 0)
c28749e97052f09388969427adf7df641cdcdc22kais got_rc4 = B_TRUE;
c28749e97052f09388969427adf7df641cdcdc22kais else if (strncmp(SUN_CKM_DES_CBC, mechs[i],
c28749e97052f09388969427adf7df641cdcdc22kais CRYPTO_MAX_MECH_NAME) == 0)
c28749e97052f09388969427adf7df641cdcdc22kais got_des = B_TRUE;
c28749e97052f09388969427adf7df641cdcdc22kais else if (strncmp(SUN_CKM_DES3_CBC, mechs[i],
c28749e97052f09388969427adf7df641cdcdc22kais CRYPTO_MAX_MECH_NAME) == 0)
c28749e97052f09388969427adf7df641cdcdc22kais got_3des = B_TRUE;
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna else if (strncmp(SUN_CKM_AES_CBC, mechs[i],
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna CRYPTO_MAX_MECH_NAME) == 0)
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna got_aes = B_TRUE;
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais cnt = 0;
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna ep = kssl_entry;
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < CIPHER_SUITE_COUNT - 1; i++) {
c28749e97052f09388969427adf7df641cdcdc22kais switch (s = kssl_params->kssl_suites[i]) {
c28749e97052f09388969427adf7df641cdcdc22kais case SSL_RSA_WITH_RC4_128_MD5:
c28749e97052f09388969427adf7df641cdcdc22kais if (got_rsa && got_rc4 && got_md5)
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna ep->kssl_cipherSuites[cnt++] = s;
c28749e97052f09388969427adf7df641cdcdc22kais break;
c28749e97052f09388969427adf7df641cdcdc22kais case SSL_RSA_WITH_RC4_128_SHA:
c28749e97052f09388969427adf7df641cdcdc22kais if (got_rsa && got_rc4 && got_sha1)
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna ep->kssl_cipherSuites[cnt++] = s;
c28749e97052f09388969427adf7df641cdcdc22kais break;
c28749e97052f09388969427adf7df641cdcdc22kais case SSL_RSA_WITH_DES_CBC_SHA:
c28749e97052f09388969427adf7df641cdcdc22kais if (got_rsa && got_des && got_sha1)
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna ep->kssl_cipherSuites[cnt++] = s;
c28749e97052f09388969427adf7df641cdcdc22kais break;
c28749e97052f09388969427adf7df641cdcdc22kais case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
c28749e97052f09388969427adf7df641cdcdc22kais if (got_rsa && got_3des && got_sha1)
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna ep->kssl_cipherSuites[cnt++] = s;
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna break;
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna case TLS_RSA_WITH_AES_128_CBC_SHA:
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna if (got_rsa && got_aes && got_sha1)
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna ep->kssl_cipherSuites[cnt++] = s;
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna break;
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna case TLS_RSA_WITH_AES_256_CBC_SHA:
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna if (got_rsa && got_aes && got_sha1)
2bd70d4be73561631df9cb3d9eb4c65fa94fa665krishna ep->kssl_cipherSuites[cnt++] = s;
c28749e97052f09388969427adf7df641cdcdc22kais break;
c28749e97052f09388969427adf7df641cdcdc22kais case CIPHER_NOTSET:
c28749e97052f09388969427adf7df641cdcdc22kais default:
c28749e97052f09388969427adf7df641cdcdc22kais break;
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais crypto_free_mech_list(mechs, mech_count);
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
65d184575ba5adcc532b970fc99d2f67e2df7af6Vladimir Kotal /*
65d184575ba5adcc532b970fc99d2f67e2df7af6Vladimir Kotal * Add the no encryption suite to the end if requested by the
65d184575ba5adcc532b970fc99d2f67e2df7af6Vladimir Kotal * kssl:null_cipher_suite /etc/system tunable since we do not want
65d184575ba5adcc532b970fc99d2f67e2df7af6Vladimir Kotal * to be running with it by default.
65d184575ba5adcc532b970fc99d2f67e2df7af6Vladimir Kotal */
65d184575ba5adcc532b970fc99d2f67e2df7af6Vladimir Kotal if (null_cipher_suite && got_rsa && got_sha1)
65d184575ba5adcc532b970fc99d2f67e2df7af6Vladimir Kotal kssl_entry->kssl_cipherSuites[cnt++] = SSL_RSA_WITH_NULL_SHA;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->kssl_cipherSuites_nentries = cnt;
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < cnt; i++)
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->kssl_saved_Suites[i] =
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->kssl_cipherSuites[i];
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->sid_cache = kmem_alloc(
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->sid_cache_nentries * sizeof (kssl_sid_ent_t), KM_SLEEP);
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < kssl_entry->sid_cache_nentries; i++) {
c28749e97052f09388969427adf7df641cdcdc22kais mutex_init(&(kssl_entry->sid_cache[i].se_lock), NULL,
c28749e97052f09388969427adf7df641cdcdc22kais MUTEX_DEFAULT, NULL);
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->sid_cache[i].se_used = 0;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry->sid_cache[i].se_sid.cached = B_FALSE;
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais KSSL_ENTRY_REFHOLD(kssl_entry);
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais return (kssl_entry);
c28749e97052f09388969427adf7df641cdcdc22kais}
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kaisint
c28749e97052f09388969427adf7df641cdcdc22kaiskssl_add_entry(kssl_params_t *kssl_params)
c28749e97052f09388969427adf7df641cdcdc22kais{
c28749e97052f09388969427adf7df641cdcdc22kais int rv, index, i;
c28749e97052f09388969427adf7df641cdcdc22kais Certificate_t *cert;
c28749e97052f09388969427adf7df641cdcdc22kais crypto_key_t *privkey;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry_t *kssl_entry;
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri in6_addr_t laddr;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais if ((rv = extract_certificate(kssl_params, &cert)) != 0) {
c28749e97052f09388969427adf7df641cdcdc22kais return (rv);
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais if ((rv = extract_private_key(kssl_params, &privkey)) != 0) {
c28749e97052f09388969427adf7df641cdcdc22kais certificate_free(cert);
c28749e97052f09388969427adf7df641cdcdc22kais return (rv);
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry = create_kssl_entry(kssl_params, cert, privkey);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna if (kssl_entry == NULL) {
c892ebf1bef94f4f922f282c11516677c134dbe0krishna certificate_free(cert);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna privateKey_free(privkey);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna return (EINVAL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna }
c28749e97052f09388969427adf7df641cdcdc22kais
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri laddr = kssl_params->kssl_addr.sin6_addr;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kaisretry:
c28749e97052f09388969427adf7df641cdcdc22kais mutex_enter(&kssl_tab_mutex);
c28749e97052f09388969427adf7df641cdcdc22kais /* Allocate the array first time here */
c28749e97052f09388969427adf7df641cdcdc22kais if (kssl_entry_tab == NULL) {
c28749e97052f09388969427adf7df641cdcdc22kais size_t allocsize;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry_t **tmp_tab;
c28749e97052f09388969427adf7df641cdcdc22kais int tmp_size;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais tmp_size = KSSL_TAB_INITSIZE;
c28749e97052f09388969427adf7df641cdcdc22kais allocsize = tmp_size * sizeof (kssl_entry_t *);
c28749e97052f09388969427adf7df641cdcdc22kais mutex_exit(&kssl_tab_mutex);
c28749e97052f09388969427adf7df641cdcdc22kais tmp_tab = kmem_zalloc(allocsize, KM_SLEEP);
c28749e97052f09388969427adf7df641cdcdc22kais mutex_enter(&kssl_tab_mutex);
c28749e97052f09388969427adf7df641cdcdc22kais if (kssl_entry_tab != NULL) {
c28749e97052f09388969427adf7df641cdcdc22kais mutex_exit(&kssl_tab_mutex);
c28749e97052f09388969427adf7df641cdcdc22kais kmem_free(tmp_tab, allocsize);
c28749e97052f09388969427adf7df641cdcdc22kais goto retry;
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry_tab_size = tmp_size;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry_tab = tmp_tab;
c28749e97052f09388969427adf7df641cdcdc22kais index = 0;
c28749e97052f09388969427adf7df641cdcdc22kais } else {
c28749e97052f09388969427adf7df641cdcdc22kais /* Check if a matching entry exists already */
c28749e97052f09388969427adf7df641cdcdc22kais index = kssl_find_entry(laddr,
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri kssl_params->kssl_addr.sin6_port, IS_SSL_PORT, B_TRUE);
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais if (index == -1) {
c28749e97052f09388969427adf7df641cdcdc22kais /* Check if an entry with the same proxy port exists */
c28749e97052f09388969427adf7df641cdcdc22kais if (kssl_find_entry(laddr, kssl_params->kssl_proxy_port,
c28749e97052f09388969427adf7df641cdcdc22kais IS_PROXY_PORT, B_TRUE) != -1) {
c28749e97052f09388969427adf7df641cdcdc22kais mutex_exit(&kssl_tab_mutex);
c28749e97052f09388969427adf7df641cdcdc22kais kssl_free_entry(kssl_entry);
c28749e97052f09388969427adf7df641cdcdc22kais return (EADDRINUSE);
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais /* No matching entry, find an empty spot */
c28749e97052f09388969427adf7df641cdcdc22kais for (i = 0; i < kssl_entry_tab_size; i++) {
c28749e97052f09388969427adf7df641cdcdc22kais if (kssl_entry_tab[i] == NULL)
c28749e97052f09388969427adf7df641cdcdc22kais break;
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais /* Table full. Gotta grow it */
c28749e97052f09388969427adf7df641cdcdc22kais if (i == kssl_entry_tab_size) {
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry_t **new_tab, **old_tab;
c28749e97052f09388969427adf7df641cdcdc22kais size_t allocsize;
c28749e97052f09388969427adf7df641cdcdc22kais size_t oldtabsize = kssl_entry_tab_size *
c28749e97052f09388969427adf7df641cdcdc22kais sizeof (kssl_entry_t *);
c28749e97052f09388969427adf7df641cdcdc22kais int tmp_size, old_size;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais tmp_size = old_size = kssl_entry_tab_size;
c28749e97052f09388969427adf7df641cdcdc22kais tmp_size += KSSL_TAB_INITSIZE;
c28749e97052f09388969427adf7df641cdcdc22kais allocsize = tmp_size * sizeof (kssl_entry_t *);
c28749e97052f09388969427adf7df641cdcdc22kais mutex_exit(&kssl_tab_mutex);
c28749e97052f09388969427adf7df641cdcdc22kais new_tab = kmem_zalloc(allocsize, KM_SLEEP);
c28749e97052f09388969427adf7df641cdcdc22kais mutex_enter(&kssl_tab_mutex);
c28749e97052f09388969427adf7df641cdcdc22kais if (kssl_entry_tab_size > old_size) {
c28749e97052f09388969427adf7df641cdcdc22kais mutex_exit(&kssl_tab_mutex);
c28749e97052f09388969427adf7df641cdcdc22kais kmem_free(new_tab, allocsize);
c28749e97052f09388969427adf7df641cdcdc22kais goto retry;
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry_tab_size = tmp_size;
c28749e97052f09388969427adf7df641cdcdc22kais bcopy(kssl_entry_tab, new_tab, oldtabsize);
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais old_tab = kssl_entry_tab;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry_tab = new_tab;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais kmem_free(old_tab, oldtabsize);
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais index = i;
c28749e97052f09388969427adf7df641cdcdc22kais } else {
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri kssl_entry_t *ep;
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri
c28749e97052f09388969427adf7df641cdcdc22kais /*
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 */
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri ep = kssl_entry_tab[index];
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri if ((IN6_IS_ADDR_UNSPECIFIED(&laddr) &&
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri !IN6_IS_ADDR_UNSPECIFIED(&ep->ke_laddr)) ||
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri (!IN6_IS_ADDR_UNSPECIFIED(&laddr) &&
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri IN6_IS_ADDR_UNSPECIFIED(&ep->ke_laddr))) {
c28749e97052f09388969427adf7df641cdcdc22kais mutex_exit(&kssl_tab_mutex);
c28749e97052f09388969427adf7df641cdcdc22kais kssl_free_entry(kssl_entry);
c28749e97052f09388969427adf7df641cdcdc22kais return (EEXIST);
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais /* Replace the existing entry */
c28749e97052f09388969427adf7df641cdcdc22kais KSSL_ENTRY_REFRELE(kssl_entry_tab[index]);
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry_tab[index] = NULL;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry_tab_nentries--;
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry_tab[index] = kssl_entry;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry_tab_nentries++;
c28749e97052f09388969427adf7df641cdcdc22kais mutex_exit(&kssl_tab_mutex);
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais return (0);
c28749e97052f09388969427adf7df641cdcdc22kais}
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kaisint
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yendurikssl_delete_entry(struct sockaddr_in6 *kssl_addr)
c28749e97052f09388969427adf7df641cdcdc22kais{
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri in6_addr_t laddr;
c28749e97052f09388969427adf7df641cdcdc22kais int index;
c28749e97052f09388969427adf7df641cdcdc22kais
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri laddr = kssl_addr->sin6_addr;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais mutex_enter(&kssl_tab_mutex);
2ec7cc7fc084163eaed884efee9bbd322cc8951bKrishna Yenduri index = kssl_find_entry(laddr, kssl_addr->sin6_port,
c28749e97052f09388969427adf7df641cdcdc22kais IS_SSL_PORT, B_FALSE);
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais if (index == -1) {
c28749e97052f09388969427adf7df641cdcdc22kais mutex_exit(&kssl_tab_mutex);
c28749e97052f09388969427adf7df641cdcdc22kais return (ENOENT);
c28749e97052f09388969427adf7df641cdcdc22kais }
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais KSSL_ENTRY_REFRELE(kssl_entry_tab[index]);
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry_tab[index] = NULL;
c28749e97052f09388969427adf7df641cdcdc22kais kssl_entry_tab_nentries--;
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais mutex_exit(&kssl_tab_mutex);
c28749e97052f09388969427adf7df641cdcdc22kais
c28749e97052f09388969427adf7df641cdcdc22kais return (0);
c28749e97052f09388969427adf7df641cdcdc22kais}
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c892ebf1bef94f4f922f282c11516677c134dbe0krishna/*
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * We care about only one private key object.
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * So, set the max count to only 1.
c892ebf1bef94f4f922f282c11516677c134dbe0krishna */
c892ebf1bef94f4f922f282c11516677c134dbe0krishna#define MAX_OBJECT_COUNT 1
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c892ebf1bef94f4f922f282c11516677c134dbe0krishna/*
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 *
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * Note that the handle will be invalid if we logout or close
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * the session to the provider.
c892ebf1bef94f4f922f282c11516677c134dbe0krishna */
c892ebf1bef94f4f922f282c11516677c134dbe0krishnaint
c892ebf1bef94f4f922f282c11516677c134dbe0krishnakssl_get_obj_handle(kssl_entry_t *kp)
c892ebf1bef94f4f922f282c11516677c134dbe0krishna{
c892ebf1bef94f4f922f282c11516677c134dbe0krishna int rv;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna unsigned int count;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna void *cookie = NULL;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna crypto_provider_t prov;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna kssl_session_info_t *s;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna crypto_session_id_t sid;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna crypto_object_attribute_t *attrs;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna crypto_object_id_t ohndl[MAX_OBJECT_COUNT];
c892ebf1bef94f4f922f282c11516677c134dbe0krishna char label[CRYPTO_EXT_SIZE_LABEL + 1];
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c892ebf1bef94f4f922f282c11516677c134dbe0krishna ASSERT(kp->ke_is_nxkey);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna s = kp->ke_sessinfo;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c892ebf1bef94f4f922f282c11516677c134dbe0krishna bcopy(s->toklabel, label, CRYPTO_EXT_SIZE_LABEL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna label[CRYPTO_EXT_SIZE_LABEL] = '\0';
c892ebf1bef94f4f922f282c11516677c134dbe0krishna prov = crypto_get_provider(label, NULL, NULL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna if (prov == NULL)
c892ebf1bef94f4f922f282c11516677c134dbe0krishna return (CRYPTO_UNKNOWN_PROVIDER);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c892ebf1bef94f4f922f282c11516677c134dbe0krishna rv = crypto_session_open(prov, &sid, NULL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna if (rv != CRYPTO_SUCCESS) {
c892ebf1bef94f4f922f282c11516677c134dbe0krishna goto err1;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna }
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c892ebf1bef94f4f922f282c11516677c134dbe0krishna rv = crypto_session_login(prov, sid, CRYPTO_USER,
c892ebf1bef94f4f922f282c11516677c134dbe0krishna s->tokpin, s->pinlen, NULL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna if (rv != CRYPTO_SUCCESS) {
c892ebf1bef94f4f922f282c11516677c134dbe0krishna goto err2;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna }
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c892ebf1bef94f4f922f282c11516677c134dbe0krishna count = kp->ke_private_key->ck_count;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna attrs = kp->ke_private_key->ck_attrs;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c892ebf1bef94f4f922f282c11516677c134dbe0krishna rv = crypto_object_find_init(prov, sid, attrs, count, &cookie, NULL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna if (rv != CRYPTO_SUCCESS) {
c892ebf1bef94f4f922f282c11516677c134dbe0krishna goto err3;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna }
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c892ebf1bef94f4f922f282c11516677c134dbe0krishna rv = crypto_object_find(prov, cookie, ohndl, &count,
c892ebf1bef94f4f922f282c11516677c134dbe0krishna MAX_OBJECT_COUNT, NULL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna if (rv != CRYPTO_SUCCESS || count == 0) {
c892ebf1bef94f4f922f282c11516677c134dbe0krishna if (count == 0)
c892ebf1bef94f4f922f282c11516677c134dbe0krishna rv = CRYPTO_FAILED;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna goto err3;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna }
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c892ebf1bef94f4f922f282c11516677c134dbe0krishna (void) crypto_object_find_final(prov, cookie, NULL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c892ebf1bef94f4f922f282c11516677c134dbe0krishna s->sid = sid;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna s->prov = prov;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna s->key.ck_format = CRYPTO_KEY_REFERENCE;
c892ebf1bef94f4f922f282c11516677c134dbe0krishna /* Keep the handle around for later use */
c892ebf1bef94f4f922f282c11516677c134dbe0krishna s->key.ck_obj_id = ohndl[0];
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c892ebf1bef94f4f922f282c11516677c134dbe0krishna return (CRYPTO_SUCCESS);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna
c892ebf1bef94f4f922f282c11516677c134dbe0krishnaerr3:
c892ebf1bef94f4f922f282c11516677c134dbe0krishna (void) crypto_session_logout(prov, sid, NULL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishnaerr2:
c892ebf1bef94f4f922f282c11516677c134dbe0krishna (void) crypto_session_close(prov, sid, NULL);
c892ebf1bef94f4f922f282c11516677c134dbe0krishnaerr1:
c892ebf1bef94f4f922f282c11516677c134dbe0krishna crypto_release_provider(prov);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna return (rv);
c892ebf1bef94f4f922f282c11516677c134dbe0krishna}