kssladm_create.c revision c28749e97052f09388969427adf7df641cdcdc22
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <errno.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>"
" [options] [<server_address>] [<server_port>]\n");
" -f pkcs12 -i <certificate_file> -x <proxy_port>"
" [options] [<server_address>] [<server_port>]\n");
" -f pem -i <certificate_file> -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 sizes of the certificates, (value of sc_sizes_offset)
* . the array of key attribute structs, (value of ck_attrs)
* . the certificates values (values of sc_certs[i])
* . the key attributes values (values of ck_attrs[i].ck_value);
*
* The address of the certs and key attributes values are offsets
* from the beginning of the big buffer.
*/
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++;
}
/* Now the big memory allocation */
"Cannot allocate memory for the kssl_params "
"and values\n");
return (NULL);
}
/* LINTED */
/* the keys attributes structs array */
/* now the certs values */
return (NULL);
}
/* 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));
return (kssl_params);
}
#define max_num_cert 32
{
{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 intialize 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");
}
}
static kssl_params_t *
{
int i;
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;
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++;
}
/* Now the big memory allocation */
"Cannot allocate memory for the kssl_params "
"and values\n");
return (NULL);
}
/* LINTED */
/* the keys attributes structs array */
/* now the certs values */
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));
return (kssl_params);
}
{
int cert_size;
return (NULL);
}
if (verbose)
(void) printf("private key read successfully\n");
return (NULL);
}
if (verbose)
(void) printf("certificate read successfully size=%d\n",
return (kssl_params);
}
int *paramsize)
{
int cert_size;
&cert_size) < 0) {
return (NULL);
}
if (verbose)
(void) printf(
"key/certificate read successfully cert_size=%d\n",
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;
};
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;
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 '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"));
}
}
goto err;
}
goto err;
}
} else {
goto err;
}
if (kssl_params == NULL) {
return (FAILURE);
}
goto err;
return (FAILURE);
}
if (verbose)
(void) printf("Successfully loaded cert and key\n");
return (SUCCESS);
err:
return (SMF_EXIT_ERR_CONFIG);
}