summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwyllys <none@none>2007-01-11 18:12:31 -0800
committerwyllys <none@none>2007-01-11 18:12:31 -0800
commit71593db26bb6ef7b739cffe06d53bf990cac112c (patch)
tree00b868c1641a6b333cbb82ec94e8890bbd11c62c
parent24424a35444c8487648be681d47bee4f57af0ffc (diff)
downloadillumos-joyent-71593db26bb6ef7b739cffe06d53bf990cac112c.tar.gz
6501154 kssladm could use KMF
--HG-- rename : usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/openssl_util.c => usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/ksslutil.c
-rw-r--r--usr/src/cmd/cmd-crypto/pktool/delete.c3
-rw-r--r--usr/src/cmd/cmd-crypto/pktool/list.c5
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/Makefile17
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm.h23
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm_create.c1123
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/ksslutil.c172
-rw-r--r--usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/openssl_util.c406
-rw-r--r--usr/src/lib/libkmf/include/kmfapi.h5
-rw-r--r--usr/src/lib/libkmf/include/kmftypes.h12
-rw-r--r--usr/src/lib/libkmf/libkmf/common/certop.c45
-rw-r--r--usr/src/lib/libkmf/libkmf/common/generalop.c10
-rw-r--r--usr/src/lib/libkmf/libkmf/common/mapfile-vers5
-rw-r--r--usr/src/lib/libkmf/libkmf/common/pk11tokens.c13
-rw-r--r--usr/src/lib/libkmf/plugins/kmf_openssl/common/mapfile-vers4
-rw-r--r--usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c348
-rw-r--r--usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c116
16 files changed, 1156 insertions, 1151 deletions
diff --git a/usr/src/cmd/cmd-crypto/pktool/delete.c b/usr/src/cmd/cmd-crypto/pktool/delete.c
index 57d484cbe2..f2dcfbd8d2 100644
--- a/usr/src/cmd/cmd-crypto/pktool/delete.c
+++ b/usr/src/cmd/cmd-crypto/pktool/delete.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -280,6 +280,7 @@ delete_pk11_keys(KMF_HANDLE_T kmfhandle,
parms.findLabel = (char *)objlabel;
parms.keytype = 0;
parms.pkcs11parms.private = ((oclass & PK_PRIVATE_OBJ) > 0);
+ parms.pkcs11parms.token = 1;
parms.cred.cred = tokencred->cred;
parms.cred.credlen = tokencred->credlen;
diff --git a/usr/src/cmd/cmd-crypto/pktool/list.c b/usr/src/cmd/cmd-crypto/pktool/list.c
index 2a427dfc36..9898fd03ec 100644
--- a/usr/src/cmd/cmd-crypto/pktool/list.c
+++ b/usr/src/cmd/cmd-crypto/pktool/list.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -291,6 +291,7 @@ list_pk11_objects(KMF_HANDLE_T kmfhandle, char *token, int oclass,
parms.cred = *tokencred;
parms.pkcs11parms.private =
((oclass & PK_PRIVATE_OBJ) > 0);
+ parms.pkcs11parms.token = 1;
/* list asymmetric private keys */
rv = pk_list_keys(kmfhandle, &parms);
@@ -303,6 +304,7 @@ list_pk11_objects(KMF_HANDLE_T kmfhandle, char *token, int oclass,
parms.format = KMF_FORMAT_RAWKEY;
parms.pkcs11parms.private =
((oclass & PK_PRIVATE_OBJ) > 0);
+ parms.pkcs11parms.token = 1;
/* list symmetric keys */
rv = pk_list_keys(kmfhandle, &parms);
@@ -313,6 +315,7 @@ list_pk11_objects(KMF_HANDLE_T kmfhandle, char *token, int oclass,
parms.findLabel = objlabel;
parms.pkcs11parms.private =
((oclass & PK_PRIVATE_OBJ) > 0);
+ parms.pkcs11parms.token = 1;
/* list asymmetric public keys (if any) */
rv = pk_list_keys(kmfhandle, &parms);
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/Makefile b/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/Makefile
index 725e3c3ab6..80acedff33 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/Makefile
+++ b/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/Makefile
@@ -2,9 +2,8 @@
# 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.
+# 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
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -31,13 +30,12 @@
PROG= kssladm
include $(SRC)/cmd/Makefile.cmd
-include $(SRC)/lib/openssl/Makefile.openssl
OBJS = \
kssladm.o \
kssladm_create.o \
kssladm_delete.o \
- openssl_util.o
+ ksslutil.o
SRCS = $(OBJS:%.o=%.c)
@@ -47,12 +45,7 @@ ROOTUSRLIBPROG = $(PROG:%=$(ROOTLIB)/%)
CFLAGS += $(CCVERBOSE)
-CPPFLAGS += $(OPENSSL_CPPFLAGS)
-DYNFLAGS += $(OPENSSL_DYNFLAGS)
-LDFLAGS += $(OPENSSL_LDFLAGS)
-LINTFLAGS += $(OPENSSL_LDFLAGS)
-
-LDLIBS += -lnsl -lpkcs11 -lcrypto -lcryptoutil
+LDLIBS += -lkmf -lpkcs11 -lcryptoutil -lnsl
all: $(PROG)
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm.h b/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm.h
index fa22c51307..a5fc30e1b3 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm.h
+++ b/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,13 +38,21 @@ extern "C" {
#endif
#include <netinet/in.h>
-#include <openssl/rsa.h>
+#include <kmfapi.h>
#define SUCCESS 0
#define FAILURE 1
#define ERROR_USAGE 2
#define MAX_CHAIN_LENGTH 12
+#define REPORT_KMF_ERROR(r, t, e) { \
+ (void) KMF_GetKMFErrorString(r, &e); \
+ (void) fprintf(stderr, t ": %s\n", \
+ (e != NULL ? e : "<unknown error>")); \
+ if (e) free(e); \
+}
+
+#define MAX_ATTR_CNT 8
extern boolean_t verbose;
@@ -53,11 +61,12 @@ extern int do_delete(int argc, char *argv[]);
extern void usage_create(boolean_t do_print);
extern void usage_delete(boolean_t do_print);
-extern uchar_t *get_modulus(uchar_t *ber_buf, int buflen, int *modlen);
-extern uchar_t **PEM_get_rsa_key_certs(const char *filename,
- char *password_file, RSA **rsa, int **cert_sizes, int *ncerts);
-extern uchar_t **PKCS12_get_rsa_key_certs(const char *filename,
- const char *password_file, RSA **rsa, int **cert_sizes, int *ncerts);
+extern int PEM_get_rsa_key_certs(const char *,
+ char *, KMF_RAW_KEY_DATA **, KMF_DATA **);
+
+extern int PKCS12_get_rsa_key_certs(const char *,
+ const char *, KMF_RAW_KEY_DATA **, KMF_DATA **);
+
extern int get_passphrase(const char *password_file, char *buf, int buf_size);
extern int kssl_send_command(char *buf, int cmd);
extern int parse_and_set_addr(char *arg1, char *arg2, struct sockaddr_in *addr);
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm_create.c b/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm_create.c
index a483977df8..bc1b2181ed 100644
--- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm_create.c
+++ b/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/kssladm_create.c
@@ -20,28 +20,32 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
-#include <arpa/inet.h>
#include <errno.h>
#include <sys/sysmacros.h>
-#include <netdb.h> /* hostent */
-#include <netinet/in.h>
-#include <openssl/rsa.h>
#include <security/cryptoki.h>
#include <security/pkcs11.h>
-#include <cryptoutil.h>
#include <stdio.h>
#include <strings.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include <sys/socket.h>
-#include <libscf.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <fcntl.h>
#include <inet/kssl/kssl.h>
+#include <cryptoutil.h>
+#include <libscf.h>
#include "kssladm.h"
+#include <kmfapi.h>
+
void
usage_create(boolean_t do_print)
{
@@ -69,56 +73,6 @@ usage_create(boolean_t do_print)
"\t[-v]\n");
}
-static uchar_t *
-get_cert_val(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE cert_obj, int *len)
-{
- CK_RV rv;
- uchar_t *buf;
- CK_ATTRIBUTE cert_attrs[] = {{CKA_VALUE, NULL_PTR, 0}};
-
- /* the certs ... */
- rv = C_GetAttributeValue(sess, cert_obj, cert_attrs, 1);
- if (rv != CKR_OK) {
- (void) fprintf(stderr, "Cannot get cert size."
- " error = %s\n", pkcs11_strerror(rv));
- return (NULL);
- }
-
- buf = malloc(cert_attrs[0].ulValueLen);
- if (buf == NULL)
- return (NULL);
- cert_attrs[0].pValue = buf;
-
- rv = C_GetAttributeValue(sess, cert_obj, cert_attrs, 1);
- if (rv != CKR_OK) {
- (void) fprintf(stderr, "Cannot get cert value."
- " error = %s\n", pkcs11_strerror(rv));
- free(buf);
- return (NULL);
- }
-
- *len = cert_attrs[0].ulValueLen;
- return (buf);
-}
-
-#define OPT_ATTR_CNT 6
-#define MAX_ATTR_CNT 16
-
-int known_attr_cnt = 0;
-
-#define CKA_TOKEN_INDEX 1
-/*
- * The order of the attributes must stay in the same order
- * as in the attribute template, privkey_tmpl, in load_from_pkcs11().
- */
-CK_ATTRIBUTE key_gattrs[MAX_ATTR_CNT] = {
- {CKA_MODULUS, NULL_PTR, 0},
- {CKA_TOKEN, NULL_PTR, 0},
- {CKA_CLASS, NULL_PTR, 0},
- {CKA_KEY_TYPE, NULL_PTR, 0},
-};
-CK_ATTRIBUTE known_cert_attrs[1];
-
/*
* Everything is allocated in one single contiguous buffer.
* The layout is the following:
@@ -134,86 +88,96 @@ CK_ATTRIBUTE known_cert_attrs[1];
* to sc_sizes[0] and sc_certs_offset points to sc_certs[0].
*/
static kssl_params_t *
-pkcs11_to_kssl(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE privkey_obj,
- boolean_t is_nxkey, int *paramsize, char *label, char *pin, int pinlen)
+kmf_to_kssl(int nxkey, KMF_RAW_KEY_DATA *rsa, int ncerts,
+ KMF_DATA *certs, int *paramsize, char *token_label, KMF_DATA *idstr,
+ KMF_CREDENTIAL *creds)
{
- int i;
- CK_RV rv;
- int total_attr_cnt;
- uint32_t cert_size, bufsize;
- char *buf;
- kssl_key_t *key;
+ int i, tcsize;
kssl_params_t *kssl_params;
- CK_ATTRIBUTE privkey_opt_attrs[OPT_ATTR_CNT] = {
- {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}
- };
+ kssl_key_t *key;
+ char *buf;
+ uint32_t bufsize;
+ static CK_BBOOL true = TRUE;
+ static CK_BBOOL false = FALSE;
+ static CK_OBJECT_CLASS class = CKO_PRIVATE_KEY;
+ static CK_KEY_TYPE keytype = CKK_RSA;
kssl_object_attribute_t kssl_attrs[MAX_ATTR_CNT];
+ CK_ATTRIBUTE exkey_attrs[MAX_ATTR_CNT] = {
+ {CKA_TOKEN, &true, sizeof (true)},
+ {CKA_EXTRACTABLE, &false, sizeof (false)},
+ {CKA_CLASS, &class, sizeof (class) },
+ {CKA_KEY_TYPE, &keytype, sizeof (keytype) },
+ {CKA_ID, NULL, 0}
+ };
+ kssl_object_attribute_t kssl_tmpl_attrs[MAX_ATTR_CNT] = {
+ {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}
+ };
+ KMF_BIGINT priv_key_bignums[MAX_ATTR_CNT];
+ int attr_cnt;
- /* Get the certificate size */
- bufsize = sizeof (kssl_params_t);
- cert_size = (uint32_t)known_cert_attrs[0].ulValueLen;
- bufsize += cert_size + MAX_CHAIN_LENGTH * sizeof (uint32_t);
-
- /* These are attributes for which we have the value and length */
- for (i = 0; i < known_attr_cnt; i++) {
- bufsize += sizeof (crypto_object_attribute_t) +
- key_gattrs[i].ulValueLen;
- }
- total_attr_cnt = known_attr_cnt;
-
- if (!is_nxkey) {
- /* Add CKA_PRIVATE_EXPONENT for extractable key */
- key_gattrs[total_attr_cnt].type = CKA_PRIVATE_EXPONENT;
- key_gattrs[total_attr_cnt].pValue = NULL_PTR;
- key_gattrs[total_attr_cnt].ulValueLen = 0;
-
- rv = C_GetAttributeValue(sess, privkey_obj,
- &key_gattrs[total_attr_cnt], 1);
- if (rv != CKR_OK) {
- (void) fprintf(stderr,
- "Cannot get private key object attribute."
- " error = %s\n", pkcs11_strerror(rv));
- return (NULL);
- }
-
- bufsize += sizeof (crypto_object_attribute_t) +
- key_gattrs[total_attr_cnt].ulValueLen;
- total_attr_cnt++;
+ if (nxkey && idstr != NULL) {
+ exkey_attrs[4].pValue = idstr->Data;
+ exkey_attrs[4].ulValueLen = idstr->Length;
}
+ tcsize = 0;
+ for (i = 0; i < ncerts; i++)
+ tcsize += certs[i].Length;
- /*
- * 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.
- */
- if (!is_nxkey) {
- rv = C_GetAttributeValue(sess, privkey_obj, privkey_opt_attrs,
- OPT_ATTR_CNT);
- if (rv != CKR_OK && rv != CKR_ATTRIBUTE_TYPE_INVALID) {
+ bufsize = sizeof (kssl_params_t);
+ bufsize += (tcsize + (MAX_CHAIN_LENGTH * sizeof (uint32_t)));
+
+ if (!nxkey) {
+ bzero(priv_key_bignums, sizeof (KMF_BIGINT) *
+ MAX_ATTR_CNT);
+ /* and the key attributes */
+ priv_key_bignums[0] = rsa->rawdata.rsa.mod;
+ priv_key_bignums[1] = rsa->rawdata.rsa.pubexp;
+ priv_key_bignums[2] = rsa->rawdata.rsa.priexp;
+ priv_key_bignums[3] = rsa->rawdata.rsa.prime1;
+ priv_key_bignums[4] = rsa->rawdata.rsa.prime2;
+ priv_key_bignums[5] = rsa->rawdata.rsa.exp1;
+ priv_key_bignums[6] = rsa->rawdata.rsa.exp2;
+ priv_key_bignums[7] = rsa->rawdata.rsa.coef;
+
+ if (rsa->rawdata.rsa.mod.val == NULL ||
+ rsa->rawdata.rsa.priexp.val == NULL) {
(void) fprintf(stderr,
- "Cannot get private key object attributes."
- " error = %s\n", pkcs11_strerror(rv));
+ "missing required attributes in private key.\n");
return (NULL);
}
- for (i = 0; i < OPT_ATTR_CNT; i++) {
- if (privkey_opt_attrs[i].ulValueLen == (CK_ULONG)-1 ||
- privkey_opt_attrs[i].ulValueLen == 0)
+ attr_cnt = 0;
+ for (i = 0; i < MAX_ATTR_CNT; i++) {
+ if (priv_key_bignums[i].val == NULL)
continue;
- /* Structure copy */
- key_gattrs[total_attr_cnt] = privkey_opt_attrs[i];
+ kssl_attrs[attr_cnt].ka_type =
+ kssl_tmpl_attrs[i].ka_type;
+ kssl_attrs[attr_cnt].ka_value_len =
+ priv_key_bignums[i].len;
+ bufsize += sizeof (crypto_object_attribute_t) +
+ kssl_attrs[attr_cnt].ka_value_len;
+ attr_cnt++;
+ }
+ } else {
+ /*
+ * Compute space for the attributes and values that the
+ * kssl kernel module will need in order to search for
+ * the private key.
+ */
+ for (attr_cnt = 0; attr_cnt < 5; attr_cnt++) {
bufsize += sizeof (crypto_object_attribute_t) +
- privkey_opt_attrs[i].ulValueLen;
- total_attr_cnt++;
+ exkey_attrs[attr_cnt].ulValueLen;
}
- } else
- bufsize += pinlen;
+ if (creds)
+ bufsize += creds->credlen;
+ }
/* Add 4-byte cushion as sc_sizes[0] needs 32-bit alignment */
bufsize += sizeof (uint32_t);
@@ -221,8 +185,8 @@ pkcs11_to_kssl(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE privkey_obj,
/* Now the big memory allocation */
if ((buf = calloc(bufsize, 1)) == NULL) {
(void) fprintf(stderr,
- "Cannot allocate memory for the kssl_params "
- "and values\n");
+ "Cannot allocate memory for the kssl_params "
+ "and values\n");
return (NULL);
}
@@ -231,542 +195,458 @@ pkcs11_to_kssl(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE privkey_obj,
buf = (char *)(kssl_params + 1);
- if (is_nxkey) {
+ if (!nxkey) {
+ /* the keys attributes structs array */
+ key = &kssl_params->kssl_privkey;
+ key->ks_format = CRYPTO_KEY_ATTR_LIST;
+ key->ks_count = attr_cnt;
+ key->ks_attrs_offset = buf - (char *)kssl_params;
+ buf += attr_cnt * sizeof (kssl_object_attribute_t);
+
+ attr_cnt = 0;
+ /* then the key attributes values */
+ for (i = 0; i < MAX_ATTR_CNT; i++) {
+ if (priv_key_bignums[i].val == NULL)
+ continue;
+ (void) memcpy(buf, priv_key_bignums[i].val,
+ priv_key_bignums[i].len);
+ kssl_attrs[attr_cnt].ka_value_offset =
+ buf - (char *)kssl_params;
+ buf += kssl_attrs[attr_cnt].ka_value_len;
+ attr_cnt++;
+ }
+ } else {
+ char tlabel[CRYPTO_EXT_SIZE_LABEL];
+ bzero(tlabel, sizeof (tlabel));
+ (void) strlcpy(tlabel, token_label, sizeof (tlabel));
+
+ /*
+ * For a non-extractable key, we must provide the PIN
+ * so the kssl module can access the token to find
+ * the key handle.
+ */
kssl_params->kssl_is_nxkey = 1;
- bcopy(label, kssl_params->kssl_token.toklabel,
- CRYPTO_EXT_SIZE_LABEL);
- kssl_params->kssl_token.pinlen = pinlen;
+ bcopy(tlabel, kssl_params->kssl_token.toklabel,
+ CRYPTO_EXT_SIZE_LABEL);
+ kssl_params->kssl_token.pinlen = creds->credlen;
kssl_params->kssl_token.tokpin_offset =
- buf - (char *)kssl_params;
+ buf - (char *)kssl_params;
kssl_params->kssl_token.ck_rv = 0;
- bcopy(pin, buf, pinlen);
- buf += pinlen;
- }
+ bcopy(creds->cred, buf, creds->credlen);
+ buf += creds->credlen;
- /* the keys attributes structs array */
- key = &kssl_params->kssl_privkey;
- key->ks_format = CRYPTO_KEY_ATTR_LIST;
- key->ks_count = total_attr_cnt;
- key->ks_attrs_offset = buf - (char *)kssl_params;
- buf += total_attr_cnt * sizeof (kssl_object_attribute_t);
-
- /* These are attributes for which we already have the value */
- for (i = 0; i < known_attr_cnt; i++) {
- bcopy(key_gattrs[i].pValue, buf, key_gattrs[i].ulValueLen);
- kssl_attrs[i].ka_type = key_gattrs[i].type;
- kssl_attrs[i].ka_value_offset = buf - (char *)kssl_params;
- kssl_attrs[i].ka_value_len = key_gattrs[i].ulValueLen;
- buf += key_gattrs[i].ulValueLen;
- }
+ /*
+ * Next in the buffer, we must provide the attributes
+ * that the kssl module will use to search in the
+ * token to find the protected key handle.
+ */
+ key = &kssl_params->kssl_privkey;
+ key->ks_format = CRYPTO_KEY_ATTR_LIST;
+ key->ks_count = attr_cnt;
+ key->ks_attrs_offset = buf - (char *)kssl_params;
+
+ buf += attr_cnt * sizeof (kssl_object_attribute_t);
+ for (i = 0; i < attr_cnt; i++) {
+ bcopy(exkey_attrs[i].pValue, buf,
+ exkey_attrs[i].ulValueLen);
- if (total_attr_cnt > known_attr_cnt) {
- /* These are attributes for which we need to get the value */
- for (i = known_attr_cnt; i < total_attr_cnt; i++) {
- key_gattrs[i].pValue = buf;
- kssl_attrs[i].ka_type = key_gattrs[i].type;
+ kssl_attrs[i].ka_type = exkey_attrs[i].type;
kssl_attrs[i].ka_value_offset =
- buf - (char *)kssl_params;
- kssl_attrs[i].ka_value_len = key_gattrs[i].ulValueLen;
- buf += key_gattrs[i].ulValueLen;
- }
+ buf - (char *)kssl_params;
+ kssl_attrs[i].ka_value_len = exkey_attrs[i].ulValueLen;
- rv = C_GetAttributeValue(sess, privkey_obj,
- &key_gattrs[known_attr_cnt],
- total_attr_cnt - known_attr_cnt);
- if (rv != CKR_OK) {
- (void) fprintf(stderr,
- "Cannot get private key object attributes."
- " error = %s\n", pkcs11_strerror(rv));
- return (NULL);
+ buf += exkey_attrs[i].ulValueLen;
}
}
-
+ /* Copy the key attributes array here */
bcopy(kssl_attrs, ((char *)kssl_params) + key->ks_attrs_offset,
- total_attr_cnt * sizeof (kssl_object_attribute_t));
+ attr_cnt * sizeof (kssl_object_attribute_t));
buf = (char *)P2ROUNDUP((uintptr_t)buf, sizeof (uint32_t));
- kssl_params->kssl_certs.sc_count = 1;
- bcopy(&cert_size, buf, sizeof (uint32_t));
+
+ /*
+ * Finally, add the certificate chain to the buffer.
+ */
+ kssl_params->kssl_certs.sc_count = ncerts;
+
+ /* First, an array of certificate sizes */
+ for (i = 0; i < ncerts; i++) {
+ uint32_t certsz = (uint32_t)certs[i].Length;
+ char *p = buf + (i * sizeof (uint32_t));
+ bcopy(&certsz, p, sizeof (uint32_t));
+ }
+
kssl_params->kssl_certs.sc_sizes_offset = buf - (char *)kssl_params;
buf += MAX_CHAIN_LENGTH * sizeof (uint32_t);
- /* now the certs values */
- bcopy(known_cert_attrs[0].pValue, buf, known_cert_attrs[0].ulValueLen);
- free(known_cert_attrs[0].pValue);
kssl_params->kssl_certs.sc_certs_offset = buf - (char *)kssl_params;
+ /* Now add the certificate data (ASN.1 DER encoded) */
+ for (i = 0; i < ncerts; i++) {
+ bcopy(certs[i].Data, buf, certs[i].Length);
+ buf += certs[i].Length;
+ }
+
*paramsize = bufsize;
- bzero(pin, pinlen);
- (void) C_Logout(sess);
- (void) C_CloseSession(sess);
return (kssl_params);
}
-#define max_num_cert 32
-
-static kssl_params_t *
-load_from_pkcs11(const char *token_label, const char *password_file,
- const char *certname, int *bufsize)
+/*
+ * Extract a sensitive key via wrap/unwrap operations.
+ *
+ * This function requires that we call PKCS#11 API directly since
+ * KMF does not yet support wrapping/unwrapping of keys. By extracting
+ * a sensitive key in wrapped form, we then unwrap it into a session key
+ * object. KMF is then used to find the session key and return it in
+ * KMF_RAW_KEY format which is then passed along to KSSL by the caller.
+ */
+static KMF_RETURN
+get_sensitive_key_data(KMF_HANDLE_T kmfh, KMF_FINDKEY_PARAMS *fkparams,
+ KMF_KEY_HANDLE *key, KMF_KEY_HANDLE *rawkey)
{
+ KMF_RETURN rv = KMF_OK;
+ static CK_BYTE aes_param[16];
+ static CK_OBJECT_CLASS privkey_class = CKO_PRIVATE_KEY;
+ static CK_KEY_TYPE privkey_type = CKK_RSA;
static CK_BBOOL true = TRUE;
static CK_BBOOL false = FALSE;
+ char *err = NULL;
+ char wrapkey_label[BUFSIZ];
+ int fd;
+ uint32_t nkeys = 0;
+ CK_RV ckrv;
+ CK_SESSION_HANDLE pk11session;
+ CK_BYTE aes_key_val[16];
+
+ CK_MECHANISM aes_cbc_pad_mech = {CKM_AES_CBC_PAD, aes_param,
+ sizeof (aes_param)};
+ CK_OBJECT_HANDLE aes_key_obj = CK_INVALID_HANDLE;
+ CK_OBJECT_HANDLE sess_privkey_obj = CK_INVALID_HANDLE;
+ CK_BYTE *wrapped_privkey = NULL;
+ CK_ULONG wrapped_privkey_len = 0;
- CK_RV rv;
- CK_SLOT_ID slot;
- CK_SLOT_ID_PTR pk11_slots;
- CK_ULONG slotcnt = 10;
- CK_TOKEN_INFO token_info;
- CK_SESSION_HANDLE sess;
- static CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE;
- static CK_CERTIFICATE_TYPE cert_type = CKC_X_509;
- CK_ATTRIBUTE cert_tmpl[4] = {
- {CKA_TOKEN, &true, sizeof (true)},
- {CKA_LABEL, NULL_PTR, 0},
- {CKA_CLASS, &cert_class, sizeof (cert_class)},
- {CKA_CERTIFICATE_TYPE, &cert_type, sizeof (cert_type)}
- };
- CK_ULONG cert_tmpl_count = 4, cert_obj_count = 1;
- CK_OBJECT_HANDLE cert_obj, privkey_obj;
- CK_OBJECT_HANDLE cert_objs[max_num_cert];
- static CK_OBJECT_CLASS privkey_class = CKO_PRIVATE_KEY;
- static CK_KEY_TYPE privkey_type = CKK_RSA;
- CK_ATTRIBUTE privkey_tmpl[] = {
- /*
- * The order of attributes must stay in the same order
- * as in the global attribute array, key_gattrs.
- */
- {CKA_MODULUS, NULL_PTR, 0},
- {CKA_TOKEN, &true, sizeof (true)},
+ CK_ATTRIBUTE unwrap_tmpl[] = {
+ /* code below depends on the following attribute order */
+ {CKA_TOKEN, &false, sizeof (false)},
{CKA_CLASS, &privkey_class, sizeof (privkey_class)},
- {CKA_KEY_TYPE, &privkey_type, sizeof (privkey_type)}
- };
- CK_ULONG privkey_tmpl_count = 4, privkey_obj_count = 1;
- CK_BBOOL is_extractable;
- CK_ATTRIBUTE privkey_attrs[1] = {
- {CKA_EXTRACTABLE, NULL_PTR, 0},
+ {CKA_KEY_TYPE, &privkey_type, sizeof (privkey_type)},
+ {CKA_SENSITIVE, &false, sizeof (false)},
+ {CKA_PRIVATE, &false, sizeof (false)},
+ {CKA_LABEL, NULL, 0}
};
- boolean_t bingo = B_FALSE;
- int i, blen, mlen;
- uchar_t *mval, *ber_buf;
- char token_label_padded[sizeof (token_info.label) + 1];
- char passphrase[MAX_PIN_LENGTH];
- CK_ULONG ulPinLen;
- (void) snprintf(token_label_padded, sizeof (token_label_padded),
- "%-32s", token_label);
-
- rv = C_Initialize(NULL_PTR);
-
- if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) {
- (void) fprintf(stderr,
- "Cannot initialize PKCS#11. error = %s\n",
- pkcs11_strerror(rv));
- return (NULL);
+ /*
+ * Create a wrap key with random data.
+ */
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd == -1) {
+ perror("Error reading /dev/urandom");
+ return (KMF_ERR_INTERNAL);
}
-
- /* Get slot count */
- rv = C_GetSlotList(1, NULL_PTR, &slotcnt);
- if (rv != CKR_OK || slotcnt == 0) {
- (void) fprintf(stderr,
- "Cannot get PKCS#11 slot list. error = %s\n",
- pkcs11_strerror(rv));
- return (NULL);
+ if (read(fd, aes_key_val, sizeof (aes_key_val)) !=
+ sizeof (aes_key_val)) {
+ perror("Error reading from /dev/urandom");
+ (void) close(fd);
+ return (KMF_ERR_INTERNAL);
}
+ (void) close(fd);
- pk11_slots = calloc(slotcnt, sizeof (CK_SLOT_ID));
- if (pk11_slots == NULL) {
- (void) fprintf(stderr,
- "Cannot get memory for %ld slots\n", slotcnt);
- return (NULL);
- }
+ pk11session = KMF_GetPK11Handle(kmfh);
- rv = C_GetSlotList(1, pk11_slots, &slotcnt);
- if (rv != CKR_OK) {
+ /*
+ * Login to create the wrap key stuff.
+ */
+ ckrv = C_Login(pk11session, CKU_USER,
+ (CK_UTF8CHAR_PTR)fkparams->cred.cred,
+ fkparams->cred.credlen);
+ if (ckrv != CKR_OK && ckrv != CKR_USER_ALREADY_LOGGED_IN) {
(void) fprintf(stderr,
- "Cannot get PKCS#11 slot list. error = %s\n",
- pkcs11_strerror(rv));
- return (NULL);
- }
-
- if (verbose)
- (void) printf("Found %ld slots\n", slotcnt);
-
- /* Search the token that matches the label */
- while (slotcnt > 0) {
- rv = C_GetTokenInfo(pk11_slots[--slotcnt], &token_info);
- if (rv != CKR_OK)
- continue;
-
- if (verbose)
- (void) printf("slot [%ld] = %s\n",
- slotcnt, token_info.label);
- if (memcmp(token_label_padded, token_info.label,
- sizeof (token_info.label)) == 0) {
- bingo = B_TRUE;
- slot = pk11_slots[slotcnt];
- break;
- }
- if (verbose) {
- token_info.label[31] = '\0';
- (void) printf("found slot [%s]\n", token_info.label);
- }
+ "Cannot login to the token. error = %s\n",
+ pkcs11_strerror(ckrv));
+ return (KMF_ERR_INTERNAL);
}
- if (!bingo) {
- (void) fprintf(stderr, "no matching PKCS#11 token found\n");
- return (NULL);
+ /*
+ * Turn the random key into a PKCS#11 session object.
+ */
+ ckrv = SUNW_C_KeyToObject(pk11session, CKM_AES_CBC_PAD, aes_key_val,
+ sizeof (aes_key_val), &aes_key_obj);
+ if (ckrv != CKR_OK) {
+ (void) fprintf(stderr,
+ "Cannot create wrapping key. error = %s\n",
+ pkcs11_strerror(ckrv));
+ return (KMF_ERR_INTERNAL);
}
- rv = C_OpenSession(slot, CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR,
- &sess);
- if (rv != CKR_OK) {
- (void) fprintf(stderr, "Cannot open session. error = %s\n",
- pkcs11_strerror(rv));
- return (NULL);
+ /*
+ * Find the original private key that we are going to wrap.
+ */
+ rv = KMF_FindKey(kmfh, fkparams, key, &nkeys);
+ if (rv != KMF_OK) {
+ REPORT_KMF_ERROR(rv, "Error finding private key", err);
+ goto out;
}
/*
- * Some tokens may not be setting CKF_LOGIN_REQUIRED. So, we do
- * not check for this flag and always login to be safe.
+ * Get the size of the wrapped private key.
*/
- ulPinLen = get_passphrase(password_file, passphrase,
- sizeof (passphrase));
- if (ulPinLen == 0) {
- (void) fprintf(stderr, "Unable to read passphrase");
- return (NULL);
+ bzero(aes_param, sizeof (aes_param));
+ ckrv = C_WrapKey(pk11session, &aes_cbc_pad_mech,
+ aes_key_obj, (CK_OBJECT_HANDLE)key->keyp,
+ NULL, &wrapped_privkey_len);
+ if (ckrv != CKR_OK) {
+ /*
+ * Most common error here is that the token doesn't
+ * support the wrapping mechanism or the key is
+ * marked non-extractable. Return an error and let
+ * the caller deal with it gracefully.
+ */
+ (void) fprintf(stderr,
+ "Cannot get wrap key size. error = %s\n",
+ pkcs11_strerror(ckrv));
+ rv = KMF_ERR_INTERNAL;
+ goto out;
}
-
- rv = C_Login(sess, CKU_USER, (CK_UTF8CHAR_PTR)passphrase,
- ulPinLen);
- if (rv != CKR_OK) {
- (void) fprintf(stderr, "Cannot login to the token."
- " error = %s\n", pkcs11_strerror(rv));
- return (NULL);
+ wrapped_privkey = malloc(wrapped_privkey_len);
+ if (wrapped_privkey == NULL) {
+ rv = KMF_ERR_MEMORY;
+ goto out;
}
-
- cert_tmpl[1].pValue = (CK_VOID_PTR) certname;
- cert_tmpl[1].ulValueLen = strlen(certname);
-
- rv = C_FindObjectsInit(sess, cert_tmpl, cert_tmpl_count);
- if (rv != CKR_OK) {
+ /*
+ * Now get the actual wrapped key data.
+ */
+ ckrv = C_WrapKey(pk11session, &aes_cbc_pad_mech,
+ aes_key_obj, (CK_OBJECT_HANDLE)key->keyp,
+ wrapped_privkey, &wrapped_privkey_len);
+ if (ckrv != CKR_OK) {
(void) fprintf(stderr,
- "Cannot initialize cert search."
- " error = %s\n", pkcs11_strerror(rv));
- return (NULL);
+ "Cannot wrap private key. error = %s\n",
+ pkcs11_strerror(ckrv));
+ rv = KMF_ERR_INTERNAL;
+ goto out;
}
+ /*
+ * Create a label for the wrapped session key so we can find
+ * it easier later.
+ */
+ snprintf(wrapkey_label, sizeof (wrapkey_label), "ksslprikey_%d",
+ getpid());
- rv = C_FindObjects(sess, cert_objs,
- (certname == NULL ? 1 : max_num_cert), &cert_obj_count);
- if (rv != CKR_OK) {
+ unwrap_tmpl[5].pValue = wrapkey_label;
+ unwrap_tmpl[5].ulValueLen = strlen(wrapkey_label);
+
+ /*
+ * Unwrap the key into the template and create a temporary
+ * session private key.
+ */
+ ckrv = C_UnwrapKey(pk11session, &aes_cbc_pad_mech, aes_key_obj,
+ wrapped_privkey, wrapped_privkey_len,
+ unwrap_tmpl, 6, &sess_privkey_obj);
+ if (ckrv != CKR_OK) {
(void) fprintf(stderr,
- "Cannot retrieve cert object. error = %s\n",
- pkcs11_strerror(rv));
- return (NULL);
+ "Cannot unwrap private key. error = %s\n",
+ pkcs11_strerror(ckrv));
+ rv = KMF_ERR_INTERNAL;
+ goto out;
}
- /* Who cares if this fails! */
- (void) C_FindObjectsFinal(sess);
- if (verbose)
- (void) printf("found %ld certificates\n", cert_obj_count);
-
- if (cert_obj_count == 0) {
- (void) fprintf(stderr, "\"%s\" not found.\n", certname);
- (void) fprintf(stderr, "no certs. bye.\n");
- return (NULL);
+ /*
+ * Use KMF to find the session key and return it as RAW data
+ * so we can pass it along to KSSL.
+ */
+ fkparams->kstype = KMF_KEYSTORE_PK11TOKEN;
+ fkparams->keyclass = KMF_ASYM_PRI;
+ fkparams->format = KMF_FORMAT_RAWKEY;
+ fkparams->findLabel = wrapkey_label;
+ fkparams->pkcs11parms.sensitive = FALSE;
+ fkparams->pkcs11parms.private = FALSE;
+ fkparams->pkcs11parms.token = FALSE; /* <-- very important! */
+
+ rv = KMF_FindKey(kmfh, fkparams, rawkey, &nkeys);
+ if (rv != KMF_OK) {
+ REPORT_KMF_ERROR(rv, "Error finding raw private key", err);
+ goto out;
}
+out:
+ if (wrapped_privkey)
+ free(wrapped_privkey);
- cert_obj = cert_objs[0];
+ if (aes_key_obj != CK_INVALID_HANDLE)
+ C_DestroyObject(pk11session, aes_key_obj);
- /* Get the modulus value from the certificate */
- ber_buf = get_cert_val(sess, cert_obj, &blen);
- if (ber_buf == NULL) {
- (void) fprintf(stderr,
- "Cannot get certificate data for \"%s\".\n", certname);
- return (NULL);
- }
+ if (sess_privkey_obj != CK_INVALID_HANDLE)
+ C_DestroyObject(pk11session, sess_privkey_obj);
- /* Store it for later use. We free the buffer at that time. */
- known_cert_attrs[0].type = CKA_VALUE;
- known_cert_attrs[0].pValue = ber_buf;
- known_cert_attrs[0].ulValueLen = blen;
+ return (rv);
+}
- mval = get_modulus(ber_buf, blen, &mlen);
- if (mval == NULL) {
- (void) fprintf(stderr,
- "Cannot get Modulus in certificate \"%s\".\n", certname);
- return (NULL);
+static kssl_params_t *
+load_from_pkcs11(const char *token_label, const char *password_file,
+ const char *certname, int *bufsize)
+{
+ KMF_RETURN rv;
+ KMF_HANDLE_T kmfh;
+ KMF_X509_DER_CERT cert;
+ KMF_KEY_HANDLE key, rawkey;
+ KMF_CREDENTIAL creds;
+ KMF_FINDCERT_PARAMS fcparams;
+ KMF_FINDKEY_PARAMS fkparams;
+ KMF_CONFIG_PARAMS cfgparams;
+ KMF_DATA iddata = { NULL, 0 };
+ kssl_params_t *kssl_params = NULL;
+ uint32_t ncerts, nkeys;
+ char *err, *idstr = NULL;
+ char password_buf[1024];
+ int nxkey = 0;
+
+ rv = KMF_Initialize(&kmfh, NULL, NULL);
+ if (rv != KMF_OK) {
+ REPORT_KMF_ERROR(rv, "Error initializing KMF", err);
+ return (0);
}
-
- /* Now get the private key */
- privkey_tmpl[0].pValue = mval;
- privkey_tmpl[0].ulValueLen = mlen;
-
- rv = C_FindObjectsInit(sess, privkey_tmpl, privkey_tmpl_count);
- if (rv != CKR_OK) {
- (void) fprintf(stderr, "Cannot intialize private key search."
- " error = %s\n", pkcs11_strerror(rv));
- return (NULL);
+ if (get_passphrase(password_file, password_buf,
+ sizeof (password_buf)) <= 0) {
+ perror("Unable to read passphrase");
+ goto done;
}
+ creds.cred = password_buf;
+ creds.credlen = strlen(password_buf);
- rv = C_FindObjects(sess, &privkey_obj, 1, &privkey_obj_count);
- if (rv != CKR_OK) {
- (void) fprintf(stderr, "Cannot retrieve private key object "
- " error = %s\n", pkcs11_strerror(rv));
- return (NULL);
- }
- /* Who cares if this fails! */
- (void) C_FindObjectsFinal(sess);
+ bzero(&cfgparams, sizeof (cfgparams));
+ bzero(&fcparams, sizeof (fcparams));
+ bzero(&fkparams, sizeof (fkparams));
- if (privkey_obj_count == 0) {
- (void) fprintf(stderr, "no private keys. bye.\n");
- return (NULL);
- }
+ cfgparams.kstype = KMF_KEYSTORE_PK11TOKEN;
+ cfgparams.pkcs11config.label = (char *)token_label;
+ cfgparams.pkcs11config.readonly = B_FALSE;
- (void) printf("found %ld private keys\n", privkey_obj_count);
- if (verbose) {
- (void) printf("private key attributes: \n");
- (void) printf("\tmodulus: size %d \n", mlen);
+ rv = KMF_ConfigureKeystore(kmfh, &cfgparams);
+ if (rv != KMF_OK) {
+ REPORT_KMF_ERROR(rv, "Error configuring KMF keystore", err);
+ goto done;
}
/*
- * Store it for later use. The index of the attributes
- * is the same in both the structures.
+ * Find the certificate matching the given label.
*/
- known_attr_cnt = privkey_tmpl_count;
- for (i = 0; i < privkey_tmpl_count; i++)
- key_gattrs[i] = privkey_tmpl[i];
+ fcparams.kstype = KMF_KEYSTORE_PK11TOKEN;
+ fcparams.certLabel = (char *)certname;
+ rv = KMF_FindCert(kmfh, &fcparams, &cert, &ncerts);
+ if (rv != KMF_OK || ncerts == 0)
+ goto done;
/*
- * Get CKA_EXTRACTABLE value. We set the default value
- * TRUE if the token returns CKR_ATTRIBUTE_TYPE_INVALID.
- * The token would supply this attribute if the key
- * is not extractable.
+ * Find the associated private key for this cert by
+ * keying off of the label and the ASCII ID string.
*/
- privkey_attrs[0].pValue = &is_extractable;
- privkey_attrs[0].ulValueLen = sizeof (is_extractable);
- rv = C_GetAttributeValue(sess, privkey_obj, privkey_attrs, 1);
- if (rv != CKR_OK && rv != CKR_ATTRIBUTE_TYPE_INVALID) {
- (void) fprintf(stderr,
- "Cannot get CKA_EXTRACTABLE attribute."
- " error = %s\n", pkcs11_strerror(rv));
- return (NULL);
- }
-
- if (rv == CKR_ATTRIBUTE_TYPE_INVALID)
- is_extractable = TRUE;
- key_gattrs[known_attr_cnt++] = privkey_attrs[0];
-
- if (is_extractable) {
- /* Now wrap the key, then unwrap it */
- CK_BYTE aes_key_val[16] = {
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
- static CK_BYTE aes_param[16] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- CK_MECHANISM aes_cbc_pad_mech = {CKM_AES_CBC_PAD, aes_param, 16};
- CK_OBJECT_HANDLE aes_key_obj, sess_privkey_obj;
- CK_BYTE *wrapped_privkey;
- CK_ULONG wrapped_privkey_len;
-
- CK_ATTRIBUTE unwrap_tmpl[] = {
- /* code below depends on the following attribute order */
- {CKA_TOKEN, &false, sizeof (false)},
- {CKA_CLASS, &privkey_class, sizeof (privkey_class)},
- {CKA_KEY_TYPE, &privkey_type, sizeof (privkey_type)},
- {CKA_SENSITIVE, &false, sizeof (false)},
- {CKA_PRIVATE, &false, sizeof (false)}
- };
-
- rv = SUNW_C_KeyToObject(sess, CKM_AES_CBC_PAD, aes_key_val, 16,
- &aes_key_obj);
-
- if (rv != CKR_OK) {
- (void) fprintf(stderr,
- "Cannot create wrapping key. error = %s\n",
- pkcs11_strerror(rv));
- return (NULL);
- }
-
- /* get the size of the wrapped key */
- rv = C_WrapKey(sess, &aes_cbc_pad_mech, aes_key_obj, privkey_obj,
- NULL, &wrapped_privkey_len);
- if (rv != CKR_OK) {
- (void) fprintf(stderr, "Cannot get key size. error = %s\n",
- pkcs11_strerror(rv));
- return (NULL);
- }
-
- wrapped_privkey = malloc(wrapped_privkey_len * sizeof (CK_BYTE));
- if (wrapped_privkey == NULL) {
- return (NULL);
- }
-
- /* do the actual key wrapping */
- rv = C_WrapKey(sess, &aes_cbc_pad_mech, aes_key_obj, privkey_obj,
- wrapped_privkey, &wrapped_privkey_len);
- if (rv != CKR_OK) {
- (void) fprintf(stderr, "Cannot wrap private key. error = %s\n",
- pkcs11_strerror(rv));
- return (NULL);
- }
- (void) printf("private key successfully wrapped, "
- "wrapped blob length: %ld\n",
- wrapped_privkey_len);
-
- rv = C_UnwrapKey(sess, &aes_cbc_pad_mech, aes_key_obj,
- wrapped_privkey, wrapped_privkey_len,
- unwrap_tmpl, 5, &sess_privkey_obj);
- if (rv != CKR_OK) {
- (void) fprintf(stderr, "Cannot unwrap private key."
- " error = %s\n", pkcs11_strerror(rv));
- return (NULL);
- }
- (void) printf("session private key successfully unwrapped\n");
-
- privkey_obj = sess_privkey_obj;
- /* Store the one modified attribute and the two new attributes. */
- key_gattrs[CKA_TOKEN_INDEX] = unwrap_tmpl[0];
- key_gattrs[known_attr_cnt++] = unwrap_tmpl[3];
- key_gattrs[known_attr_cnt++] = unwrap_tmpl[4];
- }
+ rv = KMF_GetCertIDString(&cert.certificate, &idstr);
+ if (rv != KMF_OK)
+ goto done;
+
+ fkparams.kstype = KMF_KEYSTORE_PK11TOKEN;
+ fkparams.keyclass = KMF_ASYM_PRI;
+ fkparams.cred = creds;
+ fkparams.format = KMF_FORMAT_RAWKEY;
+ fkparams.findLabel = (char *)certname;
+ fkparams.idstr = idstr;
+ fkparams.pkcs11parms.private = TRUE;
+ fkparams.pkcs11parms.token = TRUE;
+
+ rv = KMF_FindKey(kmfh, &fkparams, &key, &nkeys);
+ if (rv == KMF_ERR_SENSITIVE_KEY) {
+ KMF_FreeKMFKey(kmfh, &key);
+ /*
+ * Get a normal key handle and then do a wrap/unwrap
+ * in order to get the necessary raw data fields needed
+ * to send to KSSL.
+ */
+ fkparams.format = KMF_FORMAT_NATIVE;
+ rv = get_sensitive_key_data(kmfh, &fkparams, &key, &rawkey);
+ if (rv == KMF_OK) {
+ /* Swap "key" for "rawkey" */
+ KMF_FreeKMFKey(kmfh, &key);
+
+ key = rawkey;
+ } else {
+ KMF_FreeKMFKey(kmfh, &key);
+
+ /* Let kssl try to find the key. */
+ nxkey = 1;
+ rv = KMF_GetCertIDData(&cert.certificate, &iddata);
+ }
+ } else if (rv == KMF_ERR_UNEXTRACTABLE_KEY) {
+ KMF_FreeKMFKey(kmfh, &key);
+
+ /* Let kssl try to find the key. */
+ nxkey = 1;
+ rv = KMF_GetCertIDData(&cert.certificate, &iddata);
+ } else if (rv != KMF_OK || nkeys == 0)
+ goto done;
+
+ if (rv == KMF_OK)
+ kssl_params = kmf_to_kssl(nxkey, (KMF_RAW_KEY_DATA *)key.keyp,
+ 1, &cert.certificate, bufsize,
+ (char *)token_label, &iddata, &creds);
+done:
+ if (ncerts != 0)
+ KMF_FreeKMFCert(kmfh, &cert);
+ if (nkeys != 0)
+ KMF_FreeKMFKey(kmfh, &key);
+ if (idstr)
+ free(idstr);
+
+ if (kmfh != NULL)
+ (void) KMF_Finalize(kmfh);
- return (pkcs11_to_kssl(sess, privkey_obj, !is_extractable, bufsize,
- token_label_padded, passphrase, ulPinLen));
+ return (kssl_params);
}
-#define MAX_OPENSSL_ATTR_CNT 8
-
/*
- * See the comments for pkcs11_to_kssl() for the layout of the
- * returned buffer.
+ * add_cacerts
+ *
+ * Load a chain of certificates from a PEM file.
*/
static kssl_params_t *
-openssl_to_kssl(RSA *rsa, int ncerts, uchar_t *cert_bufs[], int *cert_sizes,
- int *paramsize)
+add_cacerts(kssl_params_t *old_params, const char *cacert_chain_file)
{
- int i, tcsize;
- kssl_params_t *kssl_params;
- kssl_key_t *key;
+ int i, newlen;
+ uint32_t certlen = 0, ncerts;
char *buf;
- uint32_t bufsize;
- kssl_object_attribute_t kssl_attrs[MAX_OPENSSL_ATTR_CNT];
- kssl_object_attribute_t kssl_tmpl_attrs[MAX_OPENSSL_ATTR_CNT] = {
- {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}
- };
- BIGNUM *priv_key_bignums[MAX_OPENSSL_ATTR_CNT];
- int attr_cnt;
+ KMF_RETURN rv;
+ KMF_X509_DER_CERT *certs = NULL;
+ KMF_FINDCERT_PARAMS fcparms;
+ kssl_params_t *kssl_params;
+ KMF_HANDLE_T kmfh;
+ char *err = NULL;
- tcsize = 0;
- for (i = 0; i < ncerts; i++)
- tcsize += cert_sizes[i];
+ bzero(&fcparms, sizeof (fcparms));
+ fcparms.kstype = KMF_KEYSTORE_OPENSSL;
+ fcparms.sslparms.certfile = (char *)cacert_chain_file;
- bufsize = sizeof (kssl_params_t);
- bufsize += (tcsize + MAX_CHAIN_LENGTH * sizeof (uint32_t));
-
- /* and the key attributes */
- priv_key_bignums[0] = rsa->n; /* MODULUS */
- priv_key_bignums[1] = rsa->e; /* PUBLIC_EXPONENT */
- priv_key_bignums[2] = rsa->d; /* PRIVATE_EXPONENT */
- priv_key_bignums[3] = rsa->p; /* PRIME_1 */
- priv_key_bignums[4] = rsa->q; /* PRIME_2 */
- priv_key_bignums[5] = rsa->dmp1; /* EXPONENT_1 */
- priv_key_bignums[6] = rsa->dmq1; /* EXPONENT_2 */
- priv_key_bignums[7] = rsa->iqmp; /* COEFFICIENT */
-
- if (rsa->n == NULL || rsa->d == NULL) {
- (void) fprintf(stderr,
- "missing required attributes in private key.\n");
- return (NULL);
+ rv = KMF_Initialize(&kmfh, NULL, NULL);
+ if (rv != KMF_OK) {
+ REPORT_KMF_ERROR(rv, "Error initializing KMF", err);
+ return (0);
}
-
- attr_cnt = 0;
- for (i = 0; i < MAX_OPENSSL_ATTR_CNT; i++) {
- if (priv_key_bignums[i] == NULL)
- continue;
- kssl_attrs[attr_cnt].ka_type = kssl_tmpl_attrs[i].ka_type;
- kssl_attrs[attr_cnt].ka_value_len =
- BN_num_bytes(priv_key_bignums[i]);
- bufsize += sizeof (crypto_object_attribute_t) +
- kssl_attrs[attr_cnt].ka_value_len;
- attr_cnt++;
+ rv = KMF_FindCert(kmfh, &fcparms, NULL, &ncerts);
+ if (rv != KMF_OK) {
+ REPORT_KMF_ERROR(rv, "Error finding CA certificates", err);
+ (void) KMF_Finalize(kmfh);
+ return (0);
}
-
- /* Add 4-byte cushion as sc_sizes[0] needs 32-bit alignment */
- bufsize += sizeof (uint32_t);
-
- /* Now the big memory allocation */
- if ((buf = calloc(bufsize, 1)) == NULL) {
- (void) fprintf(stderr,
- "Cannot allocate memory for the kssl_params "
- "and values\n");
+ certs = (KMF_X509_DER_CERT *)malloc(ncerts *
+ sizeof (KMF_X509_DER_CERT));
+ if (certs == NULL) {
+ (void) fprintf(stderr, "memory allocation error.\n");
+ (void) KMF_Finalize(kmfh);
return (NULL);
}
+ bzero(certs, ncerts * sizeof (KMF_X509_DER_CERT));
+ rv = KMF_FindCert(kmfh, &fcparms, certs, &ncerts);
- /* LINTED */
- kssl_params = (kssl_params_t *)buf;
-
- buf = (char *)(kssl_params + 1);
-
- /* the keys attributes structs array */
- key = &kssl_params->kssl_privkey;
- key->ks_format = CRYPTO_KEY_ATTR_LIST;
- key->ks_count = attr_cnt;
- key->ks_attrs_offset = buf - (char *)kssl_params;
- buf += attr_cnt * sizeof (kssl_object_attribute_t);
-
- attr_cnt = 0;
- /* then the key attributes values */
- for (i = 0; i < MAX_OPENSSL_ATTR_CNT; i++) {
- if (priv_key_bignums[i] == NULL)
- continue;
- (void) BN_bn2bin(priv_key_bignums[i], (unsigned char *)buf);
- kssl_attrs[attr_cnt].ka_value_offset =
- buf - (char *)kssl_params;
- buf += kssl_attrs[attr_cnt].ka_value_len;
- attr_cnt++;
- }
-
- bcopy(kssl_attrs, ((char *)kssl_params) + key->ks_attrs_offset,
- attr_cnt * sizeof (kssl_object_attribute_t));
+ (void) KMF_Finalize(kmfh);
- buf = (char *)P2ROUNDUP((uintptr_t)buf, sizeof (uint32_t));
- kssl_params->kssl_certs.sc_count = ncerts;
- bcopy(cert_sizes, buf, ncerts * sizeof (uint32_t));
- kssl_params->kssl_certs.sc_sizes_offset = buf - (char *)kssl_params;
- buf += MAX_CHAIN_LENGTH * sizeof (uint32_t);
-
- kssl_params->kssl_certs.sc_certs_offset = buf - (char *)kssl_params;
- /* now the certs values */
- for (i = 0; i < ncerts; i++) {
- bcopy(cert_bufs[i], buf, cert_sizes[i]);
- buf += cert_sizes[i];
- }
-
- *paramsize = bufsize;
- return (kssl_params);
-}
-
-static kssl_params_t *
-add_cacerts(kssl_params_t *old_params, const char *cacert_chain_file,
- const char *password_file)
-{
- int i, ncerts, newlen;
- int *cert_sizes;
- uint32_t certlen = 0;
- char *buf;
- uchar_t **cert_bufs;
- kssl_params_t *kssl_params;
-
- ncerts = 0;
- cert_bufs = PEM_get_rsa_key_certs(cacert_chain_file,
- (char *)password_file, NULL, &cert_sizes, &ncerts);
- if (cert_bufs == NULL || ncerts == 0) {
+ if (rv != KMF_OK || ncerts == 0) {
bzero(old_params, old_params->kssl_params_size);
free(old_params);
return (NULL);
@@ -778,7 +658,7 @@ add_cacerts(kssl_params_t *old_params, const char *cacert_chain_file,
newlen = old_params->kssl_params_size;
for (i = 0; i < ncerts; i++)
- newlen += cert_sizes[i];
+ newlen += certs[i].certificate.Length;
/*
* Get a bigger structure and update the
@@ -789,12 +669,16 @@ add_cacerts(kssl_params_t *old_params, const char *cacert_chain_file,
kssl_params->kssl_params_size = newlen;
kssl_params->kssl_certs.sc_count += ncerts;
- /* Put the cert_sizes starting from sc_sizes[1] */
+ /* Put the cert size info starting from sc_sizes[1] */
buf = (char *)kssl_params;
buf += kssl_params->kssl_certs.sc_sizes_offset;
bcopy(buf, &certlen, sizeof (uint32_t));
buf += sizeof (uint32_t);
- bcopy(cert_sizes, buf, ncerts * sizeof (uint32_t));
+ for (i = 0; i < ncerts; i++) {
+ uint32_t size = (uint32_t)certs[i].certificate.Length;
+ bcopy(&size, buf, sizeof (uint32_t));
+ buf += sizeof (uint32_t);
+ }
/* Put the cert_bufs starting from sc_certs[1] */
buf = (char *)kssl_params;
@@ -803,60 +687,65 @@ add_cacerts(kssl_params_t *old_params, const char *cacert_chain_file,
/* now the certs values */
for (i = 0; i < ncerts; i++) {
- bcopy(cert_bufs[i], buf, cert_sizes[i]);
- buf += cert_sizes[i];
+ bcopy(certs[i].certificate.Data, buf,
+ certs[i].certificate.Length);
+ buf += certs[i].certificate.Length;
}
for (i = 0; i < ncerts; i++)
- free(cert_bufs[i]);
- free(cert_bufs);
- free(cert_sizes);
+ KMF_FreeKMFCert(kmfh, &certs[i]);
+ free(certs);
return (kssl_params);
}
+/*
+ * Find a key and certificate(s) from a single PEM file.
+ */
static kssl_params_t *
load_from_pem(const char *filename, const char *password_file, int *paramsize)
{
- uchar_t **cert_bufs;
- int *cert_sizes, ncerts, i;
- RSA *rsa;
+ int ncerts = 0, i;
kssl_params_t *kssl_params;
+ KMF_RAW_KEY_DATA *rsa = NULL;
+ KMF_DATA *certs = NULL;
- ncerts = 0;
- cert_bufs = PEM_get_rsa_key_certs(filename, (char *)password_file,
- &rsa, &cert_sizes, &ncerts);
- if (rsa == NULL || cert_bufs == NULL || ncerts == 0) {
+ ncerts = PEM_get_rsa_key_certs(filename, (char *)password_file,
+ &rsa, &certs);
+ if (rsa == NULL || certs == NULL || ncerts == 0) {
return (NULL);
}
if (verbose)
(void) printf("%d certificates read successfully\n", ncerts);
- kssl_params = openssl_to_kssl(rsa, ncerts, cert_bufs,
- cert_sizes, paramsize);
+ kssl_params = kmf_to_kssl(0, rsa, ncerts, certs, paramsize, NULL,
+ NULL, NULL);
for (i = 0; i < ncerts; i++)
- free(cert_bufs[i]);
- free(cert_bufs);
- free(cert_sizes);
- RSA_free(rsa);
+ KMF_FreeData(&certs[i]);
+ free(certs);
+ KMF_FreeRawKey(rsa);
+
return (kssl_params);
}
+/*
+ * Load a raw key and certificate(s) from a PKCS#12 file.
+ */
static kssl_params_t *
load_from_pkcs12(const char *filename, const char *password_file,
int *paramsize)
{
- RSA *rsa;
+ KMF_RAW_KEY_DATA *rsa = NULL;
kssl_params_t *kssl_params;
- uchar_t **cert_bufs;
- int *cert_sizes, ncerts, i;
+ KMF_DATA *certs = NULL;
+ int ncerts = 0, i;
- ncerts = 0;
- cert_bufs = PKCS12_get_rsa_key_certs(filename, password_file, &rsa,
- &cert_sizes, &ncerts);
- if (cert_bufs == NULL || ncerts == 0) {
+ ncerts = PKCS12_get_rsa_key_certs(filename,
+ password_file, &rsa, &certs);
+
+ if (certs == NULL || ncerts == 0) {
(void) fprintf(stderr,
"Unable to read cert and/or key from %s\n", filename);
return (NULL);
@@ -865,19 +754,17 @@ load_from_pkcs12(const char *filename, const char *password_file,
if (verbose)
(void) printf("%d certificates read successfully\n", ncerts);
- kssl_params = openssl_to_kssl(rsa, ncerts, cert_bufs,
- cert_sizes, paramsize);
+ kssl_params = kmf_to_kssl(0, rsa, ncerts, certs, paramsize, NULL,
+ NULL, NULL);
for (i = 0; i < ncerts; i++)
- free(cert_bufs[i]);
- free(cert_bufs);
- free(cert_sizes);
+ KMF_FreeData(&certs[i]);
+ free(certs);
- RSA_free(rsa);
+ KMF_FreeRawKey(rsa);
return (kssl_params);
}
-
int
parse_and_set_addr(char *server_address, char *server_port,
struct sockaddr_in *addr)
@@ -1105,6 +992,9 @@ do_create(int argc, char *argv[])
return (FAILURE);
}
+ /*
+ * Add the list of supported ciphers to the buffer.
+ */
bcopy(kssl_suites, kssl_params->kssl_suites,
sizeof (kssl_params->kssl_suites));
kssl_params->kssl_params_size = bufsize;
@@ -1114,8 +1004,7 @@ do_create(int argc, char *argv[])
kssl_params->kssl_session_cache_size = scache_size;
if (cacert_chain_file != NULL) {
- kssl_params = add_cacerts(kssl_params, cacert_chain_file,
- password_file);
+ kssl_params = add_cacerts(kssl_params, cacert_chain_file);
if (kssl_params == NULL) {
return (FAILURE);
}
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/ksslutil.c b/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/ksslutil.c
new file mode 100644
index 0000000000..30f9d5f581
--- /dev/null
+++ b/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/ksslutil.c
@@ -0,0 +1,172 @@
+/*
+ * 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
+ * or http://www.opensolaris.org/os/licensing.
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdio.h>
+#include <assert.h>
+#include <strings.h>
+
+#include <kmfapi.h>
+#include "kssladm.h"
+
+/*
+ * Extract the Certificate and raw key data from a PKCS#12 file.
+ * The password needed for decrypting the PKCS#12 PDU is stored
+ * in plaintext in the given "password_file" parameter.
+ */
+int
+PKCS12_get_rsa_key_certs(const char *filename, const char *password_file,
+ KMF_RAW_KEY_DATA **rsa, KMF_DATA **certs)
+{
+ char password_buf[1024];
+ KMF_HANDLE_T kmfh;
+ KMF_RETURN rv = KMF_OK;
+ KMF_CREDENTIAL pk12cred;
+ KMF_DATA *tcerts;
+ KMF_RAW_KEY_DATA *keys;
+ int ncerts, nkeys;
+ char *err = NULL;
+
+ rv = KMF_Initialize(&kmfh, NULL, NULL);
+ if (rv != KMF_OK) {
+ REPORT_KMF_ERROR(rv, "Error initializing KMF", err);
+ return (0);
+ }
+
+ tcerts = NULL;
+ keys = NULL;
+ ncerts = 0;
+ nkeys = 0;
+
+ if (get_passphrase(password_file, password_buf,
+ sizeof (password_buf)) <= 0) {
+ perror("Unable to read passphrase");
+ goto done;
+ }
+ pk12cred.cred = password_buf;
+ pk12cred.credlen = strlen(password_buf);
+
+ rv = KMF_ImportPK12(kmfh, (char *)filename, &pk12cred, &tcerts, &ncerts,
+ &keys, &nkeys);
+ if (rv != KMF_OK) {
+ REPORT_KMF_ERROR(rv, "Error importing PKCS12 data", err);
+ }
+
+done:
+ if (rv != KMF_OK) {
+ int i;
+ if (tcerts != NULL) {
+ for (i = 0; i < ncerts; i++)
+ KMF_FreeData(&tcerts[i]);
+ free(tcerts);
+ }
+ tcerts = NULL;
+ ncerts = 0;
+ if (keys != NULL) {
+ for (i = 0; i < nkeys; i++)
+ KMF_FreeRawKey(&keys[i]);
+ free(keys);
+ }
+ keys = NULL;
+ }
+ *certs = tcerts;
+ *rsa = keys;
+
+ (void) KMF_Finalize(kmfh);
+
+ return (ncerts);
+}
+
+/*
+ * Parse a PEM file which should contain RSA private keys and
+ * their associated X.509v3 certificates. More than 1 may
+ * be present in the file.
+ */
+int
+PEM_get_rsa_key_certs(const char *filename, char *password_file,
+ KMF_RAW_KEY_DATA **rsa, KMF_DATA **certs)
+{
+ KMF_HANDLE_T kmfh;
+ KMF_RETURN rv = KMF_OK;
+ KMF_CREDENTIAL creds;
+ KMF_DATA *tcerts;
+ KMF_RAW_KEY_DATA *keys;
+ int ncerts, nkeys;
+ char *err = NULL;
+ char password_buf[1024];
+
+ rv = KMF_Initialize(&kmfh, NULL, NULL);
+ if (rv != KMF_OK) {
+ REPORT_KMF_ERROR(rv, "Error initializing KMF", err);
+ return (0);
+ }
+
+ tcerts = NULL;
+ keys = NULL;
+ ncerts = 0;
+ nkeys = 0;
+
+ if (get_passphrase(password_file, password_buf,
+ sizeof (password_buf)) <= 0) {
+ perror("Unable to read passphrase");
+ goto done;
+ }
+ creds.cred = password_buf;
+ creds.credlen = strlen(password_buf);
+
+ rv = KMF_ImportKeypair(kmfh, (char *)filename, &creds, &tcerts, &ncerts,
+ &keys, &nkeys);
+ if (rv != KMF_OK) {
+ REPORT_KMF_ERROR(rv, "Error importing key data", err);
+ }
+
+done:
+ if (rv != KMF_OK) {
+ int i;
+ if (tcerts != NULL) {
+ for (i = 0; i < ncerts; i++)
+ KMF_FreeData(&tcerts[i]);
+ free(tcerts);
+ }
+ tcerts = NULL;
+ ncerts = 0;
+ if (keys != NULL) {
+ for (i = 0; i < nkeys; i++)
+ KMF_FreeRawKey(&keys[i]);
+ free(keys);
+ }
+ keys = NULL;
+ }
+ if (certs != NULL)
+ *certs = tcerts;
+ if (rsa != NULL)
+ *rsa = keys;
+
+ (void) KMF_Finalize(kmfh);
+
+ return (ncerts);
+}
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/openssl_util.c b/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/openssl_util.c
deleted file mode 100644
index 589bbb8576..0000000000
--- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/kssladm/openssl_util.c
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * 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
- * or http://www.opensolaris.org/os/licensing.
- * 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 <assert.h>
-#include <strings.h>
-#include <openssl/err.h>
-#include <openssl/pem.h>
-#include <openssl/x509.h>
-#include <openssl/pkcs12.h>
-#include "kssladm.h"
-
-static void
-print_crypto_error(void)
-{
- ERR_load_crypto_strings();
- ERR_print_errors_fp(stderr);
-}
-
-/* ARGSUSED */
-static int
-pem_password_callback(char *buf, int size, int rwflag, void *userdata)
-{
- return (get_passphrase((const char *)userdata, buf, size));
-}
-
-
-static STACK_OF(X509_INFO) *
-PEM_get_x509_info_stack(const char *filename, char *password_file)
-{
- FILE *fp;
- STACK_OF(X509_INFO) *x509_info_stack;
-
- fp = fopen(filename, "r");
- if (fp == NULL) {
- perror("Unable to open pem file for reading");
- return (NULL);
- }
- if (verbose)
- (void) printf("In PEM_get_x509_info_stack: %s opened\n",
- filename);
-
- OpenSSL_add_all_algorithms();
-
- x509_info_stack = PEM_X509_INFO_read(
- fp, NULL, pem_password_callback, password_file);
- (void) fclose(fp);
-
- if (x509_info_stack == NULL) {
- print_crypto_error();
- }
-
- return (x509_info_stack);
-}
-
-static EVP_PKEY *
-PEM_get_key(const char *filename, const char *password_file)
-{
- FILE *fp;
- EVP_PKEY *pkey = NULL;
-
- fp = fopen(filename, "r");
- if (fp == NULL) {
- perror("Unable to open pem file for reading");
- return (NULL);
- }
- if (verbose)
- (void) printf("In PEM_get_key: %s opened\n", filename);
-
- OpenSSL_add_all_algorithms();
-
- pkey = PEM_read_PrivateKey(fp, NULL, pem_password_callback,
- (char *)password_file);
- (void) fclose(fp);
-
- if (pkey == NULL) {
- print_crypto_error();
- }
-
- return (pkey);
-}
-
-uchar_t *
-get_modulus(uchar_t *ber_buf, int buflen, int *modlen)
-{
- int i, j, v;
- X509 *x;
- EVP_PKEY *pkey;
- BIGNUM *bn;
- uchar_t *m = NULL, *mptr;
-
- x = d2i_X509(NULL, (const unsigned char **) &ber_buf, buflen);
- if (x != NULL) {
- pkey = X509_get_pubkey(x);
- if (pkey == NULL) {
- X509_free(x);
- return (NULL);
- }
-
- bn = pkey->pkey.rsa->n;
- mptr = m = malloc(bn->top * BN_BYTES);
- for (i = bn->top - 1; i >= 0; i--) {
- for (j = BN_BITS2 - 8; j >= 0; j -= 8) {
- v = ((int)(bn->d[i] >> (long)j)) & 0xff;
- *m = v;
- m++;
- }
- }
- *modlen = bn->top * BN_BYTES;
- EVP_PKEY_free(pkey);
- X509_free(x);
- }
-
- return (mptr);
-}
-
-static uchar_t *
-X509_to_bytes(X509 *cert, int *cert_size)
-{
- uchar_t *cert_buf = NULL;
- int size;
-
- size = i2d_X509(cert, &cert_buf);
- if (size < 0) {
- perror("Invalid cert\n");
- return (NULL);
- }
-
- *cert_size = size;
- return (cert_buf);
-}
-
-static uchar_t **
-init_cert_vars(int **rlens)
-{
- int i;
- uchar_t **cert_bufs;
- int *lcert_lens;
-
- cert_bufs = (uchar_t **)malloc(MAX_CHAIN_LENGTH * sizeof (uchar_t **));
- if (cert_bufs == NULL)
- return (NULL);
- for (i = 0; i < MAX_CHAIN_LENGTH; i++)
- cert_bufs[i] = NULL;
-
- lcert_lens = malloc(MAX_CHAIN_LENGTH * sizeof (int));
- if (lcert_lens == NULL) {
- free(cert_bufs);
- return (NULL);
- }
- for (i = 0; i < MAX_CHAIN_LENGTH; i++)
- lcert_lens[i] = 0;
-
- *rlens = lcert_lens;
- return (cert_bufs);
-}
-
-static void
-print_subject(X509 *x)
-{
- char buf[256];
-
- (void) X509_NAME_oneline(X509_get_subject_name(x),
- buf, sizeof (buf));
- (void) fprintf(stdout, "/* subject: %s */ \n", buf);
-}
-
-/*
- * Returns DER encoded certs in an array of pointers
- * and their sizes in cert_sizes. If the rsa argument is
- * not NULL, we return the RSA key in it. The caller needs
- * to free the structures when done.
- */
-uchar_t **
-PEM_get_rsa_key_certs(const char *filename, char *password_file,
- RSA **rsa, int **cert_sizes, int *n)
-{
- int i, cert_size, ncerts;
- int *cert_lens;
- uchar_t **cert_bufs;
- EVP_PKEY *pkey = NULL;
- X509_INFO *info;
- X509_INFO *cert_infos[MAX_CHAIN_LENGTH];
- STACK_OF(X509_INFO) *x509_info_stack;
-
- x509_info_stack = PEM_get_x509_info_stack(filename, password_file);
- if (x509_info_stack == NULL) {
- return (NULL);
- }
-
- ncerts = 0;
- /* LINTED */
- while ((info = sk_X509_INFO_pop(x509_info_stack)) != NULL &&
- ncerts < MAX_CHAIN_LENGTH) {
- cert_infos[ncerts] = info;
- ncerts++;
- if (verbose)
- print_subject(info->x509);
- }
-
- if (ncerts == 0) {
- (void) fprintf(stderr, "No cert found\n");
- return (NULL);
- }
-
- if (rsa != NULL) {
- X509 *x;
-
- pkey = PEM_get_key(filename, password_file);
- if (pkey == NULL)
- return (NULL);
-
- x = cert_infos[ncerts - 1]->x509;
- if (!X509_check_private_key(x, pkey)) {
- (void) fprintf(stderr, "Error: Server certificate "
- "and server private key do not match.\n");
- EVP_PKEY_free(pkey);
- return (NULL);
- }
-
- *rsa = EVP_PKEY_get1_RSA(pkey);
- }
-
- if ((cert_bufs = init_cert_vars(&cert_lens)) == NULL) {
- if (pkey != NULL)
- EVP_PKEY_free(pkey);
- return (NULL);
- }
-
- /*
- * cert_infos[] is constructed from a stack of certificates structure
- * and hence the order is high level CA certificate first. SSL protocol
- * needs the certificates in the order of low level CA certificate
- * first. So, we walk cert_infos[] in reverse order below.
- */
- for (i = 0; i < ncerts; i++) {
- info = cert_infos[ncerts - 1 - i];
- cert_bufs[i] = X509_to_bytes(info->x509, &cert_size);
- cert_lens[i] = cert_size;
- X509_INFO_free(info);
- }
-
- *cert_sizes = cert_lens;
- *n = ncerts;
- return (cert_bufs);
-}
-
-static PKCS12 *
-PKCS12_load(const char *filename)
-{
- FILE *fp;
- PKCS12 *p12;
-
- fp = fopen(filename, "r");
- if (fp == NULL) {
- perror("Unable to open file for reading");
- return (NULL);
- }
-
- OpenSSL_add_all_algorithms();
-
- p12 = d2i_PKCS12_fp(fp, NULL);
- (void) fclose(fp);
- if (p12 == NULL) {
- ERR_load_PKCS12_strings();
- ERR_print_errors_fp(stderr);
- (void) fprintf(stderr, "Unable to load from %s\n", filename);
- return (NULL);
- }
-
- return (p12);
-}
-
-/*
- * Returns DER encoded certs in an array of pointers and their
- * sizes in cert_sizes. The RSA key is returned in the rsa argument.
- * The caller needs to free the structures when done.
- */
-uchar_t **
-PKCS12_get_rsa_key_certs(const char *filename, const char *password_file,
- RSA **rsa, int **cert_sizes, int *n)
-{
- int i, ncerts, cert_size;
- int *cert_lens;
- char *password = NULL;
- char password_buf[1024];
- uchar_t **cert_bufs = NULL;
- uchar_t *cert_buf;
- PKCS12 *p12 = NULL;
- EVP_PKEY *pkey = NULL;
- X509 *x509 = NULL;
- X509 *certs[MAX_CHAIN_LENGTH];
- STACK_OF(X509) *ca = NULL;
-
- p12 = PKCS12_load(filename);
- if (p12 == NULL) {
- return (NULL);
- }
-
- if (! PKCS12_verify_mac(p12, NULL, 0)) {
- if (get_passphrase(
- password_file, password_buf, sizeof (password_buf)) <= 0) {
- perror("Unable to read passphrase");
- goto done;
- }
-
- password = password_buf;
- }
-
- if (PKCS12_parse(p12, password, &pkey, &x509, &ca) <= 0) {
- (void) fprintf(stderr, "Unable to parse PKCS12 file.\n");
- goto done;
- }
-
- if (pkey == NULL) {
- (void) fprintf(stderr, "No key returned\n");
- goto done;
- }
- if (x509 == NULL) {
- (void) fprintf(stderr, "No cert returned\n");
- goto done;
- }
-
- if (!X509_check_private_key(x509, pkey)) {
- (void) fprintf(stderr, "Error: Server certificate and server "
- "private key do not match.\n");
- goto done;
- }
-
- cert_buf = X509_to_bytes(x509, &cert_size);
- if (cert_buf == NULL)
- goto done;
- X509_free(x509);
-
- *rsa = EVP_PKEY_get1_RSA(pkey);
- if (*rsa == NULL) {
- goto done;
- }
-
- if ((cert_bufs = init_cert_vars(&cert_lens)) == NULL) {
- RSA_free(*rsa);
- goto done;
- }
-
- ncerts = 0;
- cert_bufs[0] = cert_buf;
- cert_lens[0] = cert_size;
- ncerts++;
-
- /* LINTED */
- while ((ca != NULL) && ((x509 = sk_X509_pop(ca)) != NULL) &&
- ncerts < MAX_CHAIN_LENGTH) {
- certs[ncerts] = x509;
- ncerts++;
- if (verbose)
- print_subject(x509);
- }
-
- /*
- * certs[1..ncerts-1] is constructed from a stack of certificates
- * structure and hence the order is high level CA certificate first.
- * SSL protocol needs the certificates in the order of low level CA
- * certificate first. So, we walk certs[] in reverse order below.
- */
- for (i = 1; i < ncerts; i++) {
- x509 = certs[ncerts - i];
- cert_bufs[i] = X509_to_bytes(x509, &cert_size);
- cert_lens[i] = cert_size;
- X509_free(x509);
- }
-
- *cert_sizes = cert_lens;
- *n = ncerts;
-
-done:
- if (pkey != NULL)
- EVP_PKEY_free(pkey);
- if (p12 != NULL)
- PKCS12_free(p12);
-
- return (cert_bufs);
-}
diff --git a/usr/src/lib/libkmf/include/kmfapi.h b/usr/src/lib/libkmf/include/kmfapi.h
index 64ded2ce6a..c7506ab9e6 100644
--- a/usr/src/lib/libkmf/include/kmfapi.h
+++ b/usr/src/lib/libkmf/include/kmfapi.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
*
@@ -269,6 +269,8 @@ extern KMF_RETURN KMF_SetCertBasicConstraintExt(KMF_X509_CERTIFICATE *,
extern KMF_RETURN KMF_ExportPK12(KMF_HANDLE_T, KMF_EXPORTP12_PARAMS *, char *);
extern KMF_RETURN KMF_ImportPK12(KMF_HANDLE_T, char *, KMF_CREDENTIAL *,
KMF_DATA **, int *, KMF_RAW_KEY_DATA **, int *);
+extern KMF_RETURN KMF_ImportKeypair(KMF_HANDLE_T, char *, KMF_CREDENTIAL *,
+ KMF_DATA **, int *, KMF_RAW_KEY_DATA **, int *);
/*
* Get OCSP response operation.
@@ -339,6 +341,7 @@ extern void KMF_FreeCRLDistributionPoints(KMF_X509EXT_CRLDISTPOINTS *);
/* APIs for PKCS#11 token */
extern KMF_RETURN KMF_PK11TokenLookup(KMF_HANDLE_T, char *, CK_SLOT_ID *);
+extern CK_SESSION_HANDLE KMF_GetPK11Handle(KMF_HANDLE_T);
#ifdef __cplusplus
}
diff --git a/usr/src/lib/libkmf/include/kmftypes.h b/usr/src/lib/libkmf/include/kmftypes.h
index a5f71d30d9..682b1f453e 100644
--- a/usr/src/lib/libkmf/include/kmftypes.h
+++ b/usr/src/lib/libkmf/include/kmftypes.h
@@ -23,7 +23,7 @@
*
* Copyright (c) 1995-2000 Intel Corporation. All rights reserved.
*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -110,8 +110,10 @@ typedef enum {
KMF_FORMAT_ASN1 = 1, /* DER */
KMF_FORMAT_PEM = 2,
KMF_FORMAT_PKCS12 = 3,
- KMF_FORMAT_RAWKEY = 4 /* For FindKey operation */
+ KMF_FORMAT_RAWKEY = 4, /* For FindKey operation */
+ KMF_FORMAT_PEM_KEYPAIR = 5
} KMF_ENCODE_FORMAT;
+#define KMF_FORMAT_NATIVE KMF_FORMAT_UNDEF
typedef enum {
KMF_ALL_CERTS = 0,
@@ -193,6 +195,7 @@ typedef struct {
boolean_t private; /* for finding CKA_PRIVATE objects */
boolean_t sensitive;
boolean_t not_extractable;
+ boolean_t token; /* true == token object, false == session */
} KMF_PKCS11_PARAMS;
typedef struct {
@@ -599,7 +602,10 @@ typedef enum {
KMF_ERR_UNINITIALIZED_TOKEN = 0x4d,
KMF_ERR_INCOMPLETE_TBS_CERT = 0x4e,
KMF_ERR_MISSING_ERRCODE = 0x4f,
- KMF_KEYSTORE_ALREADY_INITIALIZED = 0x50
+ KMF_KEYSTORE_ALREADY_INITIALIZED = 0x50,
+ KMF_ERR_SENSITIVE_KEY = 0x51,
+ KMF_ERR_UNEXTRACTABLE_KEY = 0x52,
+ KMF_ERR_KEY_MISMATCH = 0x53
} KMF_RETURN;
typedef enum {
diff --git a/usr/src/lib/libkmf/libkmf/common/certop.c b/usr/src/lib/libkmf/libkmf/common/certop.c
index db24590caa..8e7074d0ed 100644
--- a/usr/src/lib/libkmf/libkmf/common/certop.c
+++ b/usr/src/lib/libkmf/libkmf/common/certop.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Copyright(c) 1995-2000 Intel Corporation. All rights reserved.
@@ -2289,6 +2289,49 @@ KMF_ImportPK12(KMF_HANDLE_T handle, char *filename,
return (rv);
}
+KMF_RETURN
+KMF_ImportKeypair(KMF_HANDLE_T handle, char *filename,
+ KMF_CREDENTIAL *cred,
+ KMF_DATA **certs, int *ncerts,
+ KMF_RAW_KEY_DATA **rawkeys, int *nkeys)
+{
+ KMF_RETURN rv;
+ KMF_PLUGIN *plugin;
+ KMF_RETURN (*import_keypair)(KMF_HANDLE *,
+ char *, KMF_CREDENTIAL *,
+ KMF_DATA **, int *,
+ KMF_RAW_KEY_DATA **, int *);
+
+ CLEAR_ERROR(handle, rv);
+ if (rv != KMF_OK)
+ return (rv);
+
+ if (filename == NULL ||
+ cred == NULL ||
+ certs == NULL || ncerts == NULL ||
+ rawkeys == NULL || nkeys == NULL)
+ return (KMF_ERR_BAD_PARAMETER);
+
+ /*
+ * Use the Keypair reader from the OpenSSL plugin.
+ */
+ plugin = FindPlugin(handle, KMF_KEYSTORE_OPENSSL);
+ if (plugin == NULL || plugin->dldesc == NULL) {
+ return (KMF_ERR_PLUGIN_NOTFOUND);
+ }
+
+ import_keypair = (KMF_RETURN(*)())dlsym(plugin->dldesc,
+ "openssl_import_keypair");
+ if (import_keypair == NULL) {
+ return (KMF_ERR_FUNCTION_NOT_FOUND);
+ }
+
+ /* Use OpenSSL interfaces to get raw key and cert data */
+ rv = import_keypair(handle, filename, cred, certs, ncerts,
+ rawkeys, nkeys);
+
+ return (rv);
+}
KMF_BOOL
IsEqualOid(KMF_OID *Oid1, KMF_OID *Oid2)
diff --git a/usr/src/lib/libkmf/libkmf/common/generalop.c b/usr/src/lib/libkmf/libkmf/common/generalop.c
index 1617acc119..ad596856b1 100644
--- a/usr/src/lib/libkmf/libkmf/common/generalop.c
+++ b/usr/src/lib/libkmf/libkmf/common/generalop.c
@@ -19,10 +19,9 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
- * Copyright(c) 1995-2000 Intel Corporation. All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -135,7 +134,10 @@ static kmf_error_map kmf_errcodes[] = {
{KMF_ERR_UNINITIALIZED_TOKEN, "KMF_ERR_UNINITIALIZED_TOKEN"},
{KMF_ERR_INCOMPLETE_TBS_CERT, "KMF_ERR_INCOMPLETE_TBS_CERT"},
{KMF_ERR_MISSING_ERRCODE, "KMF_ERR_MISSING_ERRCODE"},
- {KMF_KEYSTORE_ALREADY_INITIALIZED, "KMF_KEYSTORE_ALREADY_INITIALIZED"}
+ {KMF_KEYSTORE_ALREADY_INITIALIZED, "KMF_KEYSTORE_ALREADY_INITIALIZED"},
+ {KMF_ERR_SENSITIVE_KEY, "KMF_ERR_SENSITIVE_KEY"},
+ {KMF_ERR_UNEXTRACTABLE_KEY, "KMF_ERR_UNEXTRACTABLE_KEY"},
+ {KMF_ERR_KEY_MISMATCH, "KMF_ERR_KEY_MISMATCH"}
};
@@ -720,6 +722,8 @@ KMF_GetFileFormat(char *filename, KMF_ENCODE_FORMAT *fmt)
} else {
*fmt = KMF_FORMAT_ASN1;
}
+ } else if (memcmp(buf, "Bag Attr", 8) == 0) {
+ *fmt = KMF_FORMAT_PEM_KEYPAIR;
} else {
/* Cannot determine this file format */
*fmt = 0;
diff --git a/usr/src/lib/libkmf/libkmf/common/mapfile-vers b/usr/src/lib/libkmf/libkmf/common/mapfile-vers
index 6de1bf01f5..044a945d26 100644
--- a/usr/src/lib/libkmf/libkmf/common/mapfile-vers
+++ b/usr/src/lib/libkmf/libkmf/common/mapfile-vers
@@ -18,8 +18,7 @@
#
# CDDL HEADER END
#
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -105,12 +104,14 @@ SUNWprivate_1.1 {
KMF_GetKMFErrorString;
KMF_GetOCSPForCert;
KMF_GetOCSPStatusForCert;
+ KMF_GetPK11Handle;
KMF_GetPluginErrorString;
KMF_GetPolicy;
KMF_GetSymKeyValue;
KMF_HexString2Bytes;
KMF_ImportCRL;
KMF_ImportCert;
+ KMF_ImportKeypair;
KMF_ImportPK12;
KMF_Initialize;
KMF_IsCRLFile;
diff --git a/usr/src/lib/libkmf/libkmf/common/pk11tokens.c b/usr/src/lib/libkmf/libkmf/common/pk11tokens.c
index f5e9c62c61..20f8c2db13 100644
--- a/usr/src/lib/libkmf/libkmf/common/pk11tokens.c
+++ b/usr/src/lib/libkmf/libkmf/common/pk11tokens.c
@@ -17,11 +17,10 @@
* 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.
*
+ *
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -529,3 +528,9 @@ KMF_SelectToken(KMF_HANDLE_T handle, char *label,
return (kmf_rv);
}
+
+CK_SESSION_HANDLE
+KMF_GetPK11Handle(KMF_HANDLE_T kmfh)
+{
+ return (kmfh->pk11handle);
+}
diff --git a/usr/src/lib/libkmf/plugins/kmf_openssl/common/mapfile-vers b/usr/src/lib/libkmf/plugins/kmf_openssl/common/mapfile-vers
index cd910effa4..ae025ddd8f 100644
--- a/usr/src/lib/libkmf/plugins/kmf_openssl/common/mapfile-vers
+++ b/usr/src/lib/libkmf/plugins/kmf_openssl/common/mapfile-vers
@@ -18,8 +18,7 @@
#
# CDDL HEADER END
#
-#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -56,6 +55,7 @@ SUNWprivate_1.1 {
OpenSSL_StorePrivateKey;
OpenSSL_VerifyCRLFile;
openssl_read_pkcs12;
+ openssl_import_keypair;
local:
*;
};
diff --git a/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c b/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c
index 0f16832dd4..cd8b1815b6 100644
--- a/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c
+++ b/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c
@@ -20,12 +20,13 @@
*
* OpenSSL keystore wrapper
*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
+#include <stdlib.h>
#include <kmfapiP.h>
#include <ber_der.h>
#include <oidsalg.h>
@@ -99,6 +100,13 @@ static uchar_t G[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a,
mutex_t init_lock = DEFAULTMUTEX;
static int ssl_initialized = 0;
+static KMF_RETURN
+extract_objects(KMF_HANDLE *, char *, CK_UTF8CHAR *, CK_ULONG,
+ EVP_PKEY **, KMF_DATA **, int *);
+
+static KMF_RETURN
+kmf_load_cert(KMF_HANDLE *, KMF_FINDCERT_PARAMS *, char *, KMF_DATA *);
+
KMF_RETURN
OpenSSL_FindCert(KMF_HANDLE_T,
KMF_FINDCERT_PARAMS *,
@@ -567,6 +575,99 @@ cleanup:
return (rv);
}
+static int
+datacmp(const void *a, const void *b)
+{
+ KMF_DATA *adata = (KMF_DATA *)a;
+ KMF_DATA *bdata = (KMF_DATA *)b;
+ if (adata->Length > bdata->Length)
+ return (-1);
+ if (adata->Length < bdata->Length)
+ return (1);
+ return (0);
+}
+
+static KMF_RETURN
+load_certs(KMF_HANDLE *kmfh, KMF_FINDCERT_PARAMS *params, char *pathname,
+ KMF_DATA **certlist, uint32_t *numcerts)
+{
+ KMF_RETURN rv = KMF_OK;
+ int i;
+ KMF_DATA *certs = NULL;
+ int nc = 0;
+ int hits = 0;
+ KMF_ENCODE_FORMAT format;
+
+ rv = KMF_GetFileFormat(pathname, &format);
+ if (rv != KMF_OK) {
+ if (rv == KMF_ERR_OPEN_FILE)
+ rv = KMF_ERR_CERT_NOT_FOUND;
+ return (rv);
+ }
+ if (format == KMF_FORMAT_ASN1) {
+ /* load a single certificate */
+ certs = (KMF_DATA *)malloc(sizeof (KMF_DATA));
+ if (certs == NULL)
+ return (KMF_ERR_MEMORY);
+ certs->Data = NULL;
+ certs->Length = 0;
+ rv = kmf_load_cert(kmfh, params, pathname, certs);
+ if (rv == KMF_OK) {
+ *certlist = certs;
+ *numcerts = 1;
+ }
+ return (rv);
+ } else if (format == KMF_FORMAT_PKCS12) {
+ /* We need a credential to access a PKCS#12 file */
+ rv = KMF_ERR_BAD_CERT_FORMAT;
+ } else if (format == KMF_FORMAT_PEM ||
+ format != KMF_FORMAT_PEM_KEYPAIR) {
+
+ /* This function only works on PEM files */
+ rv = extract_objects(kmfh, pathname,
+ (uchar_t *)NULL, 0, NULL,
+ &certs, &nc);
+ } else {
+ return (KMF_ERR_ENCODING);
+ }
+
+ if (rv != KMF_OK)
+ return (rv);
+
+ for (i = 0; i < nc; i++) {
+ if (params->find_cert_validity == KMF_NONEXPIRED_CERTS) {
+ rv = KMF_CheckCertDate(kmfh, &certs[i]);
+ } else if (params->find_cert_validity == KMF_EXPIRED_CERTS) {
+ rv = KMF_CheckCertDate(kmfh, &certs[i]);
+ if (rv == KMF_OK)
+ rv = KMF_ERR_CERT_NOT_FOUND;
+ if (rv == KMF_ERR_VALIDITY_PERIOD)
+ rv = KMF_OK;
+ }
+ if (rv != KMF_OK) {
+ /* Remove this cert from the list by clearing it. */
+ KMF_FreeData(&certs[i]);
+ } else {
+ hits++; /* count valid certs found */
+ }
+ rv = KMF_OK;
+ }
+ if (rv == KMF_OK && hits == 0) {
+ rv = KMF_ERR_CERT_NOT_FOUND;
+ } else if (rv == KMF_OK && hits > 0) {
+ /*
+ * Sort the list of certs by length to put the cleared ones
+ * at the end so they don't get accessed by the caller.
+ */
+ qsort((void *)certs, nc, sizeof (KMF_DATA), datacmp);
+ *certlist = certs;
+
+ /* since we sorted the list, just return the number of hits */
+ *numcerts = hits;
+ }
+ return (rv);
+}
+
static KMF_RETURN
kmf_load_cert(KMF_HANDLE *kmfh,
KMF_FINDCERT_PARAMS *params,
@@ -631,7 +732,8 @@ openssl_load_key(KMF_HANDLE_T handle, const char *file)
if (format == KMF_FORMAT_ASN1)
pkey = d2i_PrivateKey_bio(keyfile, NULL);
- else if (format == KMF_FORMAT_PEM)
+ else if (format == KMF_FORMAT_PEM ||
+ format == KMF_FORMAT_PEM_KEYPAIR)
pkey = PEM_read_bio_PrivateKey(keyfile, NULL, NULL, NULL);
end:
@@ -652,8 +754,8 @@ OpenSSL_FindCert(KMF_HANDLE_T handle,
{
KMF_RETURN rv = KMF_OK;
KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
- KMF_DATA certdata = {NULL, 0};
char *fullpath;
+ int i;
if (num_certs == NULL || params == NULL)
return (KMF_ERR_BAD_PARAMETER);
@@ -677,6 +779,9 @@ OpenSSL_FindCert(KMF_HANDLE_T handle,
}
while ((dp = readdir(dirp)) != NULL) {
char *fname;
+ KMF_DATA *certlist = NULL;
+ uint32_t numcerts = 0;
+
if (strcmp(dp->d_name, ".") == 0 ||
strcmp(dp->d_name, "..") == 0)
continue;
@@ -684,34 +789,43 @@ OpenSSL_FindCert(KMF_HANDLE_T handle,
fname = get_fullpath(fullpath,
(char *)&dp->d_name);
- rv = kmf_load_cert(kmfh, params, fname,
- &certdata);
+ rv = load_certs(kmfh, params, fname, &certlist,
+ &numcerts);
if (rv != KMF_OK) {
free(fname);
- KMF_FreeData(&certdata);
+ if (certlist != NULL) {
+ for (i = 0; i < numcerts; i++)
+ KMF_FreeData(&certlist[i]);
+ free(certlist);
+ }
continue;
}
/* If load succeeds, add certdata to the list */
if (kmf_cert != NULL) {
- kmf_cert[n].certificate.Data = certdata.Data;
- kmf_cert[n].certificate.Length =
- certdata.Length;
-
- kmf_cert[n].kmf_private.keystore_type =
- KMF_KEYSTORE_OPENSSL;
- kmf_cert[n].kmf_private.flags =
- KMF_FLAG_CERT_VALID;
- kmf_cert[n].kmf_private.label = fname;
-
- certdata.Data = NULL;
- certdata.Length = 0;
+ for (i = 0; i < numcerts; i++) {
+ kmf_cert[n].certificate.Data =
+ certlist[i].Data;
+ kmf_cert[n].certificate.Length =
+ certlist[i].Length;
+
+ kmf_cert[n].kmf_private.keystore_type =
+ KMF_KEYSTORE_OPENSSL;
+ kmf_cert[n].kmf_private.flags =
+ KMF_FLAG_CERT_VALID;
+ kmf_cert[n].kmf_private.label =
+ strdup(fname);
+ n++;
+ }
+ free(certlist);
} else {
- free(fname);
- KMF_FreeData(&certdata);
+ for (i = 0; i < numcerts; i++)
+ KMF_FreeData(&certlist[i]);
+ free(certlist);
+ n += numcerts;
}
- n++;
+ free(fname);
}
(*num_certs) = n;
if (*num_certs == 0)
@@ -721,33 +835,42 @@ OpenSSL_FindCert(KMF_HANDLE_T handle,
exit:
(void) closedir(dirp);
} else {
- /* Just try to load a single certificate */
- rv = kmf_load_cert(kmfh, params, fullpath, &certdata);
+ KMF_DATA *certlist = NULL;
+ uint32_t numcerts = 0;
+
+ rv = load_certs(kmfh, params, fullpath, &certlist, &numcerts);
if (rv != KMF_OK) {
free(fullpath);
- KMF_FreeData(&certdata);
return (rv);
}
- if (kmf_cert != NULL) {
- kmf_cert->certificate.Data = certdata.Data;
- kmf_cert->certificate.Length = certdata.Length;
- kmf_cert->kmf_private.keystore_type =
- KMF_KEYSTORE_OPENSSL;
- kmf_cert->kmf_private.flags = KMF_FLAG_CERT_VALID;
- kmf_cert->kmf_private.label = fullpath;
+ if (kmf_cert != NULL && certlist != NULL) {
+ for (i = 0; i < numcerts; i++) {
+ kmf_cert[i].certificate.Data =
+ certlist[i].Data;
+ kmf_cert[i].certificate.Length =
+ certlist[i].Length;
+ kmf_cert[i].kmf_private.keystore_type =
+ KMF_KEYSTORE_OPENSSL;
+ kmf_cert[i].kmf_private.flags =
+ KMF_FLAG_CERT_VALID;
+ kmf_cert[i].kmf_private.label =
+ strdup(fullpath);
+ }
+ free(certlist);
} else {
- KMF_FreeData(&certdata);
+ if (certlist != NULL) {
+ for (i = 0; i < numcerts; i++)
+ KMF_FreeData(&certlist[i]);
+ free(certlist);
+ }
}
-
- *num_certs = 1;
+ *num_certs = numcerts;
}
- if (kmf_cert == NULL || rv != KMF_OK)
- free(fullpath);
+ free(fullpath);
return (rv);
-
}
void
@@ -3265,6 +3388,107 @@ end:
return (rv);
}
+#define MAX_CHAIN_LENGTH 100
+/*
+ * Helper function to extract keys and certificates from
+ * a single PEM file. Typically the file should contain a
+ * private key and an associated public key wrapped in an x509 cert.
+ * However, the file may be just a list of X509 certs with no keys.
+ */
+static KMF_RETURN
+extract_objects(KMF_HANDLE *kmfh, char *filename, CK_UTF8CHAR *pin,
+ CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs,
+ int *numcerts)
+/* ARGSUSED */
+{
+ KMF_RETURN rv = KMF_OK;
+ FILE *fp;
+ STACK_OF(X509_INFO) *x509_info_stack;
+ int i, ncerts = 0;
+ EVP_PKEY *pkey = NULL;
+ X509_INFO *info;
+ X509 *x;
+ X509_INFO *cert_infos[MAX_CHAIN_LENGTH];
+ KMF_DATA *certlist = NULL;
+
+ if (priv_key)
+ *priv_key = NULL;
+ if (certs)
+ *certs = NULL;
+ fp = fopen(filename, "r");
+ if (fp == NULL) {
+ return (KMF_ERR_OPEN_FILE);
+ }
+ x509_info_stack = PEM_X509_INFO_read(fp, NULL, NULL, pin);
+ if (x509_info_stack == NULL) {
+ (void) fclose(fp);
+ return (KMF_ERR_ENCODING);
+ }
+
+ /*LINTED*/
+ while ((info = sk_X509_INFO_pop(x509_info_stack)) != NULL &&
+ ncerts < MAX_CHAIN_LENGTH) {
+ cert_infos[ncerts] = info;
+ ncerts++;
+ }
+
+ if (ncerts == 0) {
+ (void) fclose(fp);
+ return (KMF_ERR_CERT_NOT_FOUND);
+ }
+
+ if (priv_key != NULL) {
+ rewind(fp);
+ pkey = PEM_read_PrivateKey(fp, NULL, NULL, pin);
+ }
+ (void) fclose(fp);
+
+ x = cert_infos[ncerts - 1]->x509;
+ /*
+ * Make sure the private key matchs the last cert in the file.
+ */
+ if (pkey != NULL && !X509_check_private_key(x, pkey)) {
+ EVP_PKEY_free(pkey);
+ return (KMF_ERR_KEY_MISMATCH);
+ }
+
+ certlist = (KMF_DATA *)malloc(ncerts * sizeof (KMF_DATA));
+ if (certlist == NULL) {
+ if (pkey != NULL)
+ EVP_PKEY_free(pkey);
+ X509_INFO_free(info);
+ return (KMF_ERR_MEMORY);
+ }
+
+ /*
+ * Convert all of the certs to DER format.
+ */
+ for (i = 0; rv == KMF_OK && certs != NULL && i < ncerts; i++) {
+ info = cert_infos[ncerts - 1 - i];
+
+ rv = ssl_cert2KMFDATA(kmfh, info->x509, &certlist[i]);
+
+ if (rv != KMF_OK) {
+ free(certlist);
+ certlist = NULL;
+ ncerts = 0;
+ }
+ X509_INFO_free(info);
+ }
+
+ if (numcerts != NULL)
+ *numcerts = ncerts;
+ if (certs != NULL)
+ *certs = certlist;
+
+ if (priv_key == NULL && pkey != NULL)
+ EVP_PKEY_free(pkey);
+ else if (priv_key != NULL && pkey != NULL)
+ *priv_key = pkey;
+
+ return (rv);
+}
+
/*
* Helper function to decrypt and parse PKCS#12 import file.
*/
@@ -3517,7 +3741,7 @@ convertPK12Objects(
}
/* Also add any included CA certs to the list */
- for (i = 0; i != sk_X509_num(sslcacerts); i++) {
+ for (i = 0; sslcacerts != NULL && i < sk_X509_num(sslcacerts); i++) {
X509 *c;
/*
* sk_X509_value() is macro that embeds a cast to (X509 *).
@@ -3601,6 +3825,54 @@ end:
}
KMF_RETURN
+openssl_import_keypair(KMF_HANDLE *kmfh,
+ char *filename, KMF_CREDENTIAL *cred,
+ KMF_DATA **certlist, int *ncerts,
+ KMF_RAW_KEY_DATA **keylist, int *nkeys)
+{
+ KMF_RETURN rv = KMF_OK;
+ EVP_PKEY *privkey = NULL;
+ KMF_ENCODE_FORMAT format;
+
+ /*
+ * auto-detect the file format, regardless of what
+ * the 'format' parameters in the params say.
+ */
+ rv = KMF_GetFileFormat(filename, &format);
+ if (rv != KMF_OK) {
+ if (rv == KMF_ERR_OPEN_FILE)
+ rv = KMF_ERR_CERT_NOT_FOUND;
+ return (rv);
+ }
+
+ /* This function only works on PEM files */
+ if (format != KMF_FORMAT_PEM &&
+ format != KMF_FORMAT_PEM_KEYPAIR)
+ return (KMF_ERR_ENCODING);
+
+ *certlist = NULL;
+ *keylist = NULL;
+ *ncerts = 0;
+ *nkeys = 0;
+ rv = extract_objects(kmfh, filename,
+ (uchar_t *)cred->cred,
+ (uint32_t)cred->credlen,
+ &privkey, certlist, ncerts);
+
+ /* Reached end of import file? */
+ if (rv == KMF_OK)
+ /* Convert keys and certs to exportable format */
+ rv = convertPK12Objects(kmfh, privkey, NULL, NULL,
+ keylist, nkeys, NULL, NULL);
+
+end:
+ if (privkey)
+ EVP_PKEY_free(privkey);
+
+ return (rv);
+}
+
+KMF_RETURN
OpenSSL_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params,
KMF_RAW_KEY_DATA *key)
{
diff --git a/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c b/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c
index e548c64eb8..cc8a0afc0f 100644
--- a/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c
+++ b/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c
@@ -21,7 +21,7 @@
/*
* PKCS11 token KMF Plugin
*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -57,6 +57,9 @@ static KMF_RETURN
search_certs(KMF_HANDLE_T, char *, char *, char *, KMF_BIGINT *,
boolean_t, KMF_CERT_VALIDITY, OBJLIST **, uint32_t *);
+static CK_RV
+getObjectLabel(KMF_HANDLE_T, CK_OBJECT_HANDLE, char **);
+
static KMF_RETURN
keyObj2RawKey(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_KEY_DATA **);
@@ -213,13 +216,12 @@ PK11Cert2KMFCert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE hObj,
CK_CERTIFICATE_TYPE cktype;
CK_OBJECT_CLASS class;
- CK_BBOOL cktrusted, token;
CK_ULONG subject_len, value_len, issuer_len, serno_len, id_len;
CK_BYTE *subject = NULL, *value = NULL;
- CK_BYTE *label = NULL;
- CK_ULONG label_len = 0;
+ char *label = NULL;
CK_ATTRIBUTE templ[10];
+ (void) memset(templ, 0, 10 * sizeof (CK_ATTRIBUTE));
SETATTR(templ, 0, CKA_CLASS, &class, sizeof (class));
/* Is this a certificate object ? */
@@ -230,30 +232,32 @@ PK11Cert2KMFCert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE hObj,
}
SETATTR(templ, 0, CKA_CERTIFICATE_TYPE, &cktype, sizeof (cktype));
- SETATTR(templ, 1, CKA_TOKEN, &token, sizeof (token));
- SETATTR(templ, 2, CKA_TRUSTED, &cktrusted, sizeof (cktrusted));
-
- ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 3);
+ ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1);
if (ckrv != CKR_OK || cktype != CKC_X_509) {
SET_ERROR(kmfh, ckrv);
return (ckrv);
} else {
+ int i = 0;
/* What attributes are available and how big are they? */
- subject_len = issuer_len = serno_len = id_len = value_len =
- label_len = 0;
- SETATTR(templ, 0, CKA_SUBJECT, NULL, subject_len);
- SETATTR(templ, 1, CKA_ISSUER, NULL, issuer_len);
- SETATTR(templ, 2, CKA_SERIAL_NUMBER, NULL, serno_len);
- SETATTR(templ, 3, CKA_ID, NULL, id_len);
- SETATTR(templ, 4, CKA_VALUE, NULL, value_len);
- SETATTR(templ, 5, CKA_LABEL, NULL, label_len);
+ subject_len = issuer_len = serno_len = id_len = value_len = 0;
+
+ SETATTR(templ, i, CKA_SUBJECT, NULL, subject_len);
+ i++;
+ SETATTR(templ, i, CKA_ISSUER, NULL, issuer_len);
+ i++;
+ SETATTR(templ, i, CKA_SERIAL_NUMBER, NULL, serno_len);
+ i++;
+ SETATTR(templ, i, CKA_ID, NULL, id_len);
+ i++;
+ SETATTR(templ, i, CKA_VALUE, NULL, value_len);
+ i++;
/*
* Query the object with NULL values in the pValue spot
* so we know how much space to allocate for each field.
*/
- ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 6);
+ ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, i);
if (ckrv != CKR_OK) {
SET_ERROR(kmfh, ckrv);
return (KMF_ERR_INTERNAL); /* TODO - Error messages ? */
@@ -264,7 +268,6 @@ PK11Cert2KMFCert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE hObj,
serno_len = templ[2].ulValueLen;
id_len = templ[3].ulValueLen;
value_len = templ[4].ulValueLen;
- label_len = templ[5].ulValueLen;
/*
* For PKCS#11 CKC_X_509 certificate objects,
@@ -288,17 +291,6 @@ PK11Cert2KMFCert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE hObj,
SETATTR(templ, i, CKA_VALUE, value, value_len);
i++;
- if (label_len > 0) {
- label = malloc(label_len + 1);
- if (label == NULL) {
- rv = KMF_ERR_MEMORY;
- goto errout;
- }
- (void) memset(label, 0, label_len + 1);
- SETATTR(templ, i, CKA_LABEL, label,
- label_len);
- i++;
- }
/* re-query the object with room for the value attr */
ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj,
@@ -315,7 +307,11 @@ PK11Cert2KMFCert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE hObj,
kmfcert->kmf_private.flags |= KMF_FLAG_CERT_SIGNED;
kmfcert->kmf_private.keystore_type =
KMF_KEYSTORE_PK11TOKEN;
- kmfcert->kmf_private.label = (char *)label;
+
+ ckrv = getObjectLabel(kmfh, hObj, &label);
+ if (ckrv == CKR_OK && label != NULL) {
+ kmfcert->kmf_private.label = (char *)label;
+ }
rv = KMF_OK;
}
@@ -1024,7 +1020,7 @@ CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert)
CK_RV ckrv;
CK_ULONG subject_len, issuer_len, serno_len;
- CK_BYTE *subject, *issuer, *serial;
+ CK_BYTE *subject, *issuer, *serial, nullserno;
CK_BBOOL true = TRUE;
CK_CERTIFICATE_TYPE certtype = CKC_X_509;
CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
@@ -1082,8 +1078,13 @@ CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert)
serial = signed_cert_ptr->certificate.serialNumber.val;
serno_len = signed_cert_ptr->certificate.serialNumber.len;
} else {
- rv = KMF_ERR_ENCODING;
- goto cleanup;
+ /*
+ * RFC3280 says to gracefully handle certs with serial numbers
+ * of 0.
+ */
+ nullserno = '\0';
+ serial = &nullserno;
+ serno_len = 1;
}
/* Generate an ID from the SPKI data */
@@ -1110,7 +1111,6 @@ CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert)
SETATTR(x509templ, i, CKA_LABEL, label, strlen(label));
i++;
}
-
/*
* The cert object handle is actually "leaked" here. If the app
* really wants to clean up the data space, it will have to call
@@ -1999,6 +1999,7 @@ static KMF_RETURN
get_raw_rsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_RSA_KEY *rawrsa)
{
KMF_RETURN rv = KMF_OK;
+ CK_RV ckrv;
CK_SESSION_HANDLE sess = kmfh->pk11handle;
CK_ATTRIBUTE rsa_pri_attrs[8] = {
{ CKA_MODULUS, NULL, 0 },
@@ -2013,10 +2014,16 @@ get_raw_rsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_RSA_KEY *rawrsa)
CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE);
int i;
- if ((rv = C_GetAttributeValue(sess, obj,
+ if ((ckrv = C_GetAttributeValue(sess, obj,
rsa_pri_attrs, count)) != CKR_OK) {
- SET_ERROR(kmfh, rv);
- return (KMF_ERR_INTERNAL);
+ SET_ERROR(kmfh, ckrv);
+ /* Tell the caller know why the key data cannot be retrieved. */
+ if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
+ return (KMF_ERR_SENSITIVE_KEY);
+ else if (ckrv == CKR_KEY_UNEXTRACTABLE)
+ return (KMF_ERR_UNEXTRACTABLE_KEY);
+ else
+ return (KMF_ERR_INTERNAL);
}
/* Allocate memory for each attribute. */
@@ -2314,7 +2321,6 @@ KMFPK11_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms,
CK_ATTRIBUTE pTmpl[10];
CK_OBJECT_CLASS class;
CK_BBOOL true = TRUE;
- CK_BBOOL false = FALSE;
CK_ULONG alg;
CK_BBOOL is_token;
@@ -2332,15 +2338,13 @@ KMFPK11_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms,
else
want_keys = MAXINT; /* count them all */
+ is_token = parms->pkcs11parms.token;
if (parms->keyclass == KMF_ASYM_PUB) {
class = CKO_PUBLIC_KEY;
- is_token = false;
} else if (parms->keyclass == KMF_ASYM_PRI) {
class = CKO_PRIVATE_KEY;
- is_token = true;
} else if (parms->keyclass == KMF_SYMMETRIC) {
class = CKO_SECRET_KEY;
- is_token = true;
} else {
return (KMF_ERR_BAD_KEY_CLASS);
}
@@ -2403,7 +2407,11 @@ KMFPK11_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms,
i++;
}
- if (is_token) {
+ /*
+ * Authenticate if the object is a token object,
+ * a private or secred key, or if the user passed in credentials.
+ */
+ if (parms->cred.credlen > 0) {
rv = pk11_authenticate(handle, &parms->cred);
if (rv != KMF_OK) {
return (rv);
@@ -2462,17 +2470,18 @@ KMFPK11_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms,
/* "numkeys" indicates the number that were actually found */
*numkeys = n;
}
- if (ckrv == KMF_OK && keys != NULL && (*numkeys) > 0 &&
- parms->format == KMF_FORMAT_RAWKEY) {
- /* Convert keys to "rawkey" format */
- for (i = 0; i < (*numkeys); i++) {
- KMF_RAW_KEY_DATA *rkey = NULL;
- rv = keyObj2RawKey(handle, &keys[i], &rkey);
- if (rv == KMF_OK) {
- keys[i].keyp = rkey;
- keys[i].israw = TRUE;
- } else {
- break;
+ if (ckrv == KMF_OK && keys != NULL && (*numkeys) > 0) {
+ if (parms->format == KMF_FORMAT_RAWKEY) {
+ /* Convert keys to "rawkey" format */
+ for (i = 0; i < (*numkeys); i++) {
+ KMF_RAW_KEY_DATA *rkey = NULL;
+ rv = keyObj2RawKey(handle, &keys[i], &rkey);
+ if (rv == KMF_OK) {
+ keys[i].keyp = rkey;
+ keys[i].israw = TRUE;
+ } else {
+ break;
+ }
}
}
}
@@ -2604,6 +2613,7 @@ KMFPK11_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params,
SETATTR(templ, i, CKA_TOKEN, &cktrue, sizeof (cktrue)); i++;
SETATTR(templ, i, CKA_PRIVATE, &cktrue, sizeof (cktrue)); i++;
SETATTR(templ, i, CKA_SUBJECT, subject.Data, subject.Length); i++;
+ SETATTR(templ, i, CKA_DECRYPT, &cktrue, sizeof (cktrue)); i++;
/*
* Only set the KeyUsage stuff if the KU extension was present.