kssladm_create.c revision 164c0dd6f561db19bdaf1d0b7f2a8dec44355b69
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <errno.h>
#include <sys/sysmacros.h>
#include <netdb.h> /* hostent */
#include <security/cryptoki.h>
#include <cryptoutil.h>
#include <stdio.h>
#include <strings.h>
#include <libscf.h>
#include "kssladm.h"
void
{
if (do_print)
" -f pkcs11 [-d softtoken_directory] -T <token_label>"
" -C <certificate_label> -x <proxy_port>"
" [-h <ca_certchain_file>]"
" [options] [<server_address>] [<server_port>]\n");
" -f pkcs12 -i <cert_and_key_pk12file> -x <proxy_port>"
" [options] [<server_address>] [<server_port>]\n");
" -f pem -i <cert_and_key_pemfile> -x <proxy_port>"
" [options] [<server_address>] [<server_port>]\n");
"\t[-c <ciphersuites>]\n"
"\t[-p <password_file>]\n"
"\t[-t <ssl_session_cache_timeout>]\n"
"\t[-z <ssl_session_cache_size>]\n"
"\t[-v]\n");
}
static uchar_t *
{
/* the certs ... */
return (NULL);
}
return (NULL);
return (NULL);
}
return (buf);
}
#define REQ_ATTR_CNT 2
#define OPT_ATTR_CNT 6
/*
* Everything is allocated in one single contiguous buffer.
* The layout is the following:
* . the kssl_params_t structure
* . the array of key attribute structs, (value of ck_attrs)
* . the key attributes values (values of ck_attrs[i].ck_value);
* . the array of sizes of the certificates, (referred to as sc_sizes[])
* . the certificates values (referred to as sc_certs[])
*
* The address of the certs and key attributes values are offsets
* from the beginning of the big buffer. sc_sizes_offset points
* to sc_sizes[0] and sc_certs_offset points to sc_certs[0].
*/
static kssl_params_t *
{
int i;
{CKA_MODULUS, NULL_PTR, 0},
{CKA_PRIVATE_EXPONENT, NULL_PTR, 0}
};
{CKA_PUBLIC_EXPONENT, NULL_PTR, 0},
{CKA_PRIME_1, NULL_PTR, 0},
{CKA_PRIME_2, NULL_PTR, 0},
{CKA_EXPONENT_1, NULL_PTR, 0},
{CKA_EXPONENT_2, NULL_PTR, 0},
{CKA_COEFFICIENT, NULL_PTR, 0}
};
char *buf;
int attr_cnt;
/* the certs ... */
return (NULL);
}
/* Get the sizes */
bufsize = sizeof (kssl_params_t);
/* and the required key attributes */
"Cannot get private key object attributes. error = %s\n",
return (NULL);
}
for (i = 0; i < REQ_ATTR_CNT; i++) {
bufsize += sizeof (crypto_object_attribute_t) +
}
/*
* Get the optional key attributes. The return values could be
* CKR_ATTRIBUTE_TYPE_INVALID with ulValueLen set to -1 OR
* CKR_OK with ulValueLen set to 0. The latter is done by
* soft token and seems dubious.
*/
"Cannot get private key object attributes. error = %s\n",
return (NULL);
}
for (i = 0; i < OPT_ATTR_CNT; i++) {
privkey_opt_attrs[i].ulValueLen == 0)
continue;
/* Structure copy */
bufsize += sizeof (crypto_object_attribute_t) +
attr_cnt++;
}
/* Add 4-byte cushion as sc_sizes[0] needs 32-bit aligment */
/* Now the big memory allocation */
"Cannot allocate memory for the kssl_params "
"and values\n");
return (NULL);
}
/* LINTED */
/* the keys attributes structs array */
/* then the attributes values */
for (i = 0; i < attr_cnt; i++) {
/*
* We assume the attribute types in the kernel are
* the same as the PKCS #11 values.
*/
}
/* then the key attributes values */
"Cannot get private key object attributes."
return (NULL);
}
attr_cnt * sizeof (kssl_object_attribute_t));
/* now the certs values */
return (NULL);
}
return (kssl_params);
}
#define max_num_cert 32
static kssl_params_t *
{
{CKA_TOKEN, &true, sizeof (true)},
};
CK_ATTRIBUTE privkey_tmpl[] = {
{CKA_MODULUS, NULL, 0},
{CKA_TOKEN, &true, sizeof (true)},
};
};
"%-32s", token_label);
"Cannot initialize PKCS#11. error = %s\n",
return (NULL);
}
/* Get slot count */
"Cannot get PKCS#11 slot list. error = %s\n",
return (NULL);
}
if (pk11_slots == NULL) {
"Cannot get memory for %ld slots\n", slotcnt);
return (NULL);
}
"Cannot get PKCS#11 slot list. error = %s\n",
return (NULL);
}
if (verbose)
/* Search the token that matches the label */
while (slotcnt > 0) {
continue;
if (verbose)
(void) printf("slot [%ld] = %s\n",
sizeof (token_info.label)) == 0) {
break;
}
if (verbose) {
}
}
if (!bingo) {
return (NULL);
}
&sess);
return (NULL);
}
"Cannot initialize cert search."
return (NULL);
}
"Cannot retrieve cert object. error = %s\n",
return (NULL);
}
/* Who cares if this fails! */
(void) C_FindObjectsFinal(sess);
if (verbose)
if (cert_obj_count == 0) {
return (NULL);
}
/* Get the modulus value from the certificate */
"Cannot get certificate data for \"%s\".\n", certname);
return (NULL);
}
"Cannot get Modulus in certificate \"%s\".\n", certname);
return (NULL);
}
/* Now get the private key */
/* Gotta authenticate first if login is required. */
char passphrase[1024];
if (ulPinLen == 0) {
return (NULL);
}
ulPinLen);
return (NULL);
}
}
return (NULL);
}
return (NULL);
}
/* Who cares if this fails! */
(void) C_FindObjectsFinal(sess);
if (privkey_obj_count == 0) {
return (NULL);
}
"Cannot get private key object attributes."
return (NULL);
}
if (verbose) {
(void) printf("private key attributes: \n");
(void) printf("\tmodulus: size %ld value:",
privkey_attrs[0].ulValueLen);
}
/* Now wrap the key, then unwrap it */
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
CK_ATTRIBUTE unwrap_tmpl[] = {
{CKA_TOKEN, &false, sizeof (false)},
{CKA_SENSITIVE, &false, sizeof (false)},
{CKA_PRIVATE, &false, sizeof (false)}
};
&aes_key_obj);
"Cannot create wrapping key. error = %s\n",
return (NULL);
}
/* get the size of the wrapped key */
return (NULL);
}
if (wrapped_privkey == NULL) {
return (NULL);
}
/* do the actual key wrapping */
return (NULL);
}
(void) printf("private key successfully wrapped, "
"wrapped blob length: %ld\n",
return (NULL);
}
(void) printf("session private key successfully unwrapped\n");
}
}
/*
* See the comments for pkcs11_to_kssl() for the layout of the
* returned buffer.
*/
static kssl_params_t *
int *paramsize)
{
int i, tcsize;
char *buf;
{SUN_CKA_MODULUS, NULL, 0},
{SUN_CKA_PUBLIC_EXPONENT, NULL, 0},
{SUN_CKA_PRIVATE_EXPONENT, NULL, 0},
{SUN_CKA_PRIME_1, NULL, 0},
{SUN_CKA_PRIME_2, NULL, 0},
{SUN_CKA_EXPONENT_1, NULL, 0},
{SUN_CKA_EXPONENT_2, NULL, 0},
{SUN_CKA_COEFFICIENT, NULL, 0}
};
int attr_cnt;
tcsize = 0;
for (i = 0; i < ncerts; i++)
tcsize += cert_sizes[i];
bufsize = sizeof (kssl_params_t);
/* and the key attributes */
"missing required attributes in private key.\n");
return (NULL);
}
attr_cnt = 0;
for (i = 0; i < MAX_ATTR_CNT; i++) {
if (priv_key_bignums[i] == NULL)
continue;
bufsize += sizeof (crypto_object_attribute_t) +
attr_cnt++;
}
/* Add 4-byte cushion as sc_sizes[0] needs 32-bit aligment */
/* Now the big memory allocation */
"Cannot allocate memory for the kssl_params "
"and values\n");
return (NULL);
}
/* LINTED */
/* the keys attributes structs array */
attr_cnt = 0;
/* then the key attributes values */
for (i = 0; i < MAX_ATTR_CNT; i++) {
if (priv_key_bignums[i] == NULL)
continue;
buf - (char *)kssl_params;
attr_cnt++;
}
attr_cnt * sizeof (kssl_object_attribute_t));
/* now the certs values */
for (i = 0; i < ncerts; i++) {
buf += cert_sizes[i];
}
return (kssl_params);
}
static kssl_params_t *
const char *password_file)
{
int *cert_sizes;
char *buf;
ncerts = 0;
return (NULL);
}
if (verbose) {
}
for (i = 0; i < ncerts; i++)
newlen += cert_sizes[i];
/*
* Get a bigger structure and update the
* fields to account for the additional certs.
*/
/* Put the cert_sizes starting from sc_sizes[1] */
buf = (char *)kssl_params;
/* Put the cert_bufs starting from sc_certs[1] */
buf = (char *)kssl_params;
/* now the certs values */
for (i = 0; i < ncerts; i++) {
buf += cert_sizes[i];
}
for (i = 0; i < ncerts; i++)
return (kssl_params);
}
static kssl_params_t *
{
int *cert_sizes, ncerts, i;
ncerts = 0;
return (NULL);
}
if (verbose)
for (i = 0; i < ncerts; i++)
return (kssl_params);
}
static kssl_params_t *
int *paramsize)
{
int *cert_sizes, ncerts, i;
ncerts = 0;
&cert_sizes, &ncerts);
return (NULL);
}
if (verbose)
for (i = 0; i < ncerts; i++)
return (kssl_params);
}
int
struct sockaddr_in *addr)
{
if (server_port == NULL) {
return (-1);
}
if (server_address == NULL) {
} else {
"Error: Unknown host: %s\n",
return (-1);
}
hp->h_addr_list[0],
}
}
errno = 0;
return (-1);
}
return (0);
}
/*
* The order of the ciphers is important. It is used as the
* default order (when -c is not specified).
*/
struct csuite {
const char *suite;
};
static int
{
int i;
int err = 0;
char *suite;
int sindx = 0;
for (i = 0; i < CIPHER_SUITE_COUNT - 1; i++)
sarray[i] = CIPHER_NOTSET;
} else {
for (i = 0; i < CIPHER_SUITE_COUNT - 1; i++)
return (err);
}
do {
for (i = 0; i < CIPHER_SUITE_COUNT - 1; i++) {
if (!cipher_suites[i].seen) {
}
break;
}
}
if (i == (CIPHER_SUITE_COUNT - 1)) {
"Unknown Cipher suite name: %s\n", suite);
err++;
}
return (err);
}
int
{
const char *softtoken_dir = NULL;
const char *token_label = NULL;
const char *password_file = NULL;
const char *cert_key_file = NULL;
const char *cacert_chain_file = NULL;
int proxy_port = -1;
struct sockaddr_in server_addr;
char c;
int pcnt;
int bufsize;
argc -= 1;
argv += 1;
switch (c) {
case 'd':
break;
case 'c':
break;
case 'C':
break;
case 'f':
break;
case 'h':
break;
case 'i':
break;
case 'T':
break;
case 'p':
break;
case 't':
break;
case 'x':
break;
case 'v':
break;
case 'z':
break;
default:
goto err;
}
}
if (pcnt == 0) {
} else if (pcnt == 1) {
} else if (pcnt == 2) {
} else {
goto err;
}
goto err;
}
if (verbose) {
(void) printf("addr=%s, port = %d\n",
}
goto err;
}
goto err;
}
if (softtoken_dir != NULL) {
if (verbose) {
(void) printf(
"SOFTTOKEN_DIR=%s\n",
getenv("SOFTTOKEN_DIR"));
}
}
if (cert_key_file == NULL) {
goto err;
}
if (cert_key_file == NULL) {
goto err;
}
} else {
goto err;
}
if (kssl_params == NULL) {
return (FAILURE);
}
goto err;
if (cacert_chain_file != NULL) {
if (kssl_params == NULL) {
return (FAILURE);
}
}
return (FAILURE);
}
if (verbose)
(void) printf("Successfully loaded cert and key\n");
return (SUCCESS);
err:
return (SMF_EXIT_ERR_CONFIG);
}