diff options
Diffstat (limited to 'usr/src/cmd')
-rw-r--r-- | usr/src/cmd/cmd-crypto/pktool/Makefile | 10 | ||||
-rw-r--r-- | usr/src/cmd/cmd-crypto/pktool/common.c | 146 | ||||
-rw-r--r-- | usr/src/cmd/cmd-crypto/pktool/common.h | 22 | ||||
-rw-r--r-- | usr/src/cmd/cmd-crypto/pktool/gencert.c | 251 | ||||
-rw-r--r-- | usr/src/cmd/cmd-crypto/pktool/gencsr.c | 273 | ||||
-rw-r--r-- | usr/src/cmd/cmd-crypto/pktool/genkeypair.c | 523 | ||||
-rw-r--r-- | usr/src/cmd/cmd-crypto/pktool/list.c | 14 | ||||
-rw-r--r-- | usr/src/cmd/cmd-crypto/pktool/pktool.c | 65 | ||||
-rw-r--r-- | usr/src/cmd/cmd-crypto/pktool/signcsr.c | 6 |
9 files changed, 937 insertions, 373 deletions
diff --git a/usr/src/cmd/cmd-crypto/pktool/Makefile b/usr/src/cmd/cmd-crypto/pktool/Makefile index 0c375bd153..7e94f51d21 100644 --- a/usr/src/cmd/cmd-crypto/pktool/Makefile +++ b/usr/src/cmd/cmd-crypto/pktool/Makefile @@ -18,7 +18,7 @@ # # CDDL HEADER END # -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # @@ -37,7 +37,8 @@ OBJS = pktool.o \ gencsr.o \ download.o \ genkey.o \ - signcsr.o + signcsr.o \ + genkeypair.o include ../../Makefile.cmd @@ -47,10 +48,11 @@ POFILES = $(OBJS:%.o=%.po) POFILE = $(PROG)_msg.po MSGFILES=$(SRCS:%.c=%.i) -CPPFLAGS += -I. -I$(KMFDIR)/include -I/usr/include/libxml2 +CPPFLAGS += -I. -I$(KMFDIR)/include -I/usr/include/libxml2 \ + -I$(KMFDIR)/ber_der/inc + CFLAGS += $(CCVERBOSE) -DDEBUG -#LDFLAGS += -L$(SRC)/lib/libkmf/libkmf/$(MACH) LDLIBS += -lkmf -lpkcs11 -lcryptoutil .KEEP_STATE: diff --git a/usr/src/cmd/cmd-crypto/pktool/common.c b/usr/src/cmd/cmd-crypto/pktool/common.c index 8c95c2e480..95992e5d82 100644 --- a/usr/src/cmd/cmd-crypto/pktool/common.c +++ b/usr/src/cmd/cmd-crypto/pktool/common.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -67,6 +67,72 @@ char *optarg_av = NULL; static void close_sess(CK_SESSION_HANDLE); static void logout_token(CK_SESSION_HANDLE); +struct oid_table_entry { + const KMF_OID *oid; + char *name; +}; + +struct oid_table_entry oid_table[] = { + { &KMFOID_ECC_secp112r1, "secp112r1"}, + { &KMFOID_ECC_secp112r2, "secp112r2"}, + { &KMFOID_ECC_secp128r1, "secp128r1"}, + { &KMFOID_ECC_secp128r2, "secp128r2"}, + { &KMFOID_ECC_secp160k1, "secp160k1"}, + { &KMFOID_ECC_secp160r1, "secp160r1"}, + { &KMFOID_ECC_secp160r2, "secp160r2"}, + { &KMFOID_ECC_secp192k1, "secp192k1"}, + { &KMFOID_ECC_secp192r1, "secp192r1"}, + { &KMFOID_ECC_secp224k1, "secp224k1"}, + { &KMFOID_ECC_secp224r1, "secp224r1"}, + { &KMFOID_ECC_secp256k1, "secp256k1"}, + { &KMFOID_ECC_secp256r1, "secp256r1"}, + { &KMFOID_ECC_secp384r1, "secp384r1"}, + { &KMFOID_ECC_secp521r1, "secp521r1"}, + { &KMFOID_ECC_sect113r1, "sect113r1"}, + { &KMFOID_ECC_sect113r2, "sect113r2"}, + { &KMFOID_ECC_sect131r1, "sect131r1"}, + { &KMFOID_ECC_sect131r2, "sect131r2"}, + { &KMFOID_ECC_sect163k1, "sect163k1"}, + { &KMFOID_ECC_sect163r1, "sect163r1"}, + { &KMFOID_ECC_sect163r2, "sect163r2"}, + { &KMFOID_ECC_sect193r1, "sect193r1"}, + { &KMFOID_ECC_sect193r2, "sect193r2"}, + { &KMFOID_ECC_sect233k1, "sect233k1"}, + { &KMFOID_ECC_sect233r1, "sect233r1"}, + { &KMFOID_ECC_sect239k1, "sect239k1"}, + { &KMFOID_ECC_sect283k1, "sect283k1"}, + { &KMFOID_ECC_sect283r1, "sect283r1"}, + { &KMFOID_ECC_sect409k1, "sect409k1"}, + { &KMFOID_ECC_sect409r1, "sect409r1"}, + { &KMFOID_ECC_sect571k1, "sect571k1"}, + { &KMFOID_ECC_sect571r1, "sect571r1"}, + { &KMFOID_ECC_c2pnb163v1, "c2pnb163v1"}, + { &KMFOID_ECC_c2pnb163v2, "c2pnb163v2"}, + { &KMFOID_ECC_c2pnb163v3, "c2pnb163v3"}, + { &KMFOID_ECC_c2pnb176v1, "c2pnb176v1"}, + { &KMFOID_ECC_c2tnb191v1, "c2tnb191v1"}, + { &KMFOID_ECC_c2tnb191v2, "c2tnb191v2"}, + { &KMFOID_ECC_c2tnb191v3, "c2tnb191v3"}, + { &KMFOID_ECC_c2pnb208w1, "c2pnb208w1"}, + { &KMFOID_ECC_c2tnb239v1, "c2tnb239v1"}, + { &KMFOID_ECC_c2tnb239v2, "c2tnb239v2"}, + { &KMFOID_ECC_c2tnb239v3, "c2tnb239v3"}, + { &KMFOID_ECC_c2pnb272w1, "c2pnb272w1"}, + { &KMFOID_ECC_c2pnb304w1, "c2pnb304w1"}, + { &KMFOID_ECC_c2tnb359v1, "c2tnb359v1"}, + { &KMFOID_ECC_c2pnb368w1, "c2pnb368w1"}, + { &KMFOID_ECC_c2tnb431r1, "c2tnb431r1"}, + { &KMFOID_ECC_prime192v2, "prime192v2"}, + { &KMFOID_ECC_prime192v3, "prime192v3"}, + { &KMFOID_MD5, "md5"}, + { &KMFOID_SHA1, "sha1"}, + { &KMFOID_SHA256, "sha256"}, + { &KMFOID_SHA384, "sha384"}, + { &KMFOID_SHA512, "sha512"} +}; +int number_of_oids = sizeof (oid_table) / sizeof (struct oid_table_entry); +#define number_of_curves (number_of_oids - 5) + /* * Perform PKCS#11 setup here. Currently only C_Initialize is required, * along with setting/resetting state variables. @@ -457,19 +523,64 @@ KS2Int(char *keystore_str) return (0); } +/* + * compare_oids + * return 1 if equal + */ +boolean_t +compare_oids(KMF_OID *oid1, const KMF_OID *oid2) +{ + return ((oid1->Length == oid2->Length) && + !memcmp(oid1->Data, oid2->Data, oid1->Length)); +} int -Str2KeyType(char *algm, KMF_KEY_ALG *ktype, KMF_ALGORITHM_INDEX *sigAlg) +Str2KeyType(char *algm, KMF_OID *hashoid, KMF_KEY_ALG *ktype, + KMF_ALGORITHM_INDEX *sigAlg) { if (algm == NULL) { + /* Default to SHA1+RSA */ *sigAlg = KMF_ALGID_SHA1WithRSA; *ktype = KMF_RSA; } else if (strcasecmp(algm, "DSA") == 0) { - *sigAlg = KMF_ALGID_SHA1WithDSA; + if (hashoid == NULL || + compare_oids(hashoid, &KMFOID_SHA1)) + *sigAlg = KMF_ALGID_SHA1WithDSA; + else if (compare_oids(hashoid, &KMFOID_SHA256)) + *sigAlg = KMF_ALGID_SHA256WithDSA; + else + return (-1); /* unsupported hash/key combo */ *ktype = KMF_DSA; } else if (strcasecmp(algm, "RSA") == 0) { - *sigAlg = KMF_ALGID_SHA1WithRSA; + if (hashoid == NULL || + compare_oids(hashoid, &KMFOID_SHA1)) + *sigAlg = KMF_ALGID_SHA1WithRSA; + else if (compare_oids(hashoid, &KMFOID_SHA256)) + *sigAlg = KMF_ALGID_SHA256WithRSA; + else if (compare_oids(hashoid, &KMFOID_SHA384)) + *sigAlg = KMF_ALGID_SHA384WithRSA; + else if (compare_oids(hashoid, &KMFOID_SHA512)) + *sigAlg = KMF_ALGID_SHA512WithRSA; + else if (compare_oids(hashoid, &KMFOID_MD5)) + *sigAlg = KMF_ALGID_MD5WithRSA; + else + return (-1); /* unsupported hash/key combo */ *ktype = KMF_RSA; + } else if (strcasecmp(algm, "EC") == 0) { + /* EC keys may be used with some SHA2 hashes */ + if (hashoid == NULL || + compare_oids(hashoid, &KMFOID_SHA1)) + *sigAlg = KMF_ALGID_SHA1WithECDSA; + else if (compare_oids(hashoid, &KMFOID_SHA256)) + *sigAlg = KMF_ALGID_SHA256WithECDSA; + else if (compare_oids(hashoid, &KMFOID_SHA384)) + *sigAlg = KMF_ALGID_SHA384WithECDSA; + else if (compare_oids(hashoid, &KMFOID_SHA512)) + *sigAlg = KMF_ALGID_SHA512WithECDSA; + else + return (-1); /* unsupported hash/key combo */ + + *ktype = KMF_ECDSA; } else { return (-1); } @@ -1218,3 +1329,30 @@ token_auth_needed(KMF_HANDLE_T handle, char *tokenlabel, int *auth) return (KMF_OK); } + +void +show_ecc_curves() +{ + int i; + + (void) printf(gettext("Supported ECC curve names:\n")); + for (i = 0; i < number_of_curves; i++) { + (void) printf("%s", oid_table[i].name); + if (i > 0 && ((i+1) % 5) == 0) + (void) printf("\n"); + else if (i+1 < number_of_curves) + (void) printf(", "); + } + (void) printf("\n"); +} + +KMF_OID * +ecc_name_to_oid(char *name) +{ + int i; + for (i = 0; i < number_of_oids; i++) { + if (strcasecmp(name, oid_table[i].name) == 0) + return ((KMF_OID *)oid_table[i].oid); + } + return (NULL); +} diff --git a/usr/src/cmd/cmd-crypto/pktool/common.h b/usr/src/cmd/cmd-crypto/pktool/common.h index 5414d58b41..89e824b1a6 100644 --- a/usr/src/cmd/cmd-crypto/pktool/common.h +++ b/usr/src/cmd/cmd-crypto/pktool/common.h @@ -19,15 +19,13 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _PKTOOL_COMMON_H #define _PKTOOL_COMMON_H -#pragma ident "%Z%%M% %I% %E% SMI" - /* * This file contains data and functions shared between all the * modules that comprise this tool. @@ -70,7 +68,7 @@ extern "C" { PK_CERT_OBJ| PK_CRL_OBJ | PK_KEY_OBJ) #define PK_DEFAULT_KEYTYPE "rsa" -#define PK_DEFAULT_KEYLENGTH 1024 +#define PK_DEFAULT_KEYLENGTH 2048 #define PK_DEFAULT_DIRECTORY "." #define PK_DEFAULT_SERIALNUM 1 #define PK_DEFAULT_PK11TOKEN SOFT_TOKEN_LABEL @@ -114,7 +112,7 @@ extern int optind_av; int OT2Int(char *); int PK2Int(char *); KMF_KEYSTORE_TYPE KS2Int(char *); -int Str2KeyType(char *, KMF_KEY_ALG *, KMF_ALGORITHM_INDEX *); +int Str2KeyType(char *, KMF_OID *, KMF_KEY_ALG *, KMF_ALGORITHM_INDEX *); int Str2SymKeyType(char *, KMF_KEY_ALG *); int Str2Lifetime(char *, uint32_t *); KMF_RETURN select_token(void *, char *, int); @@ -128,6 +126,20 @@ KMF_RETURN verify_keyusage(char *arg, uint16_t *, int *); KMF_RETURN verify_file(char *); KMF_RETURN verify_ekunames(char *, EKU_LIST **); KMF_RETURN token_auth_needed(KMF_HANDLE_T, char *, int *); +KMF_OID *ecc_name_to_oid(char *); +void show_ecc_curves(); +KMF_RETURN genkeypair_pkcs11(KMF_HANDLE_T, char *, char *, KMF_KEY_ALG, + int, KMF_CREDENTIAL *, KMF_OID *, + KMF_KEY_HANDLE *, KMF_KEY_HANDLE *); + +KMF_RETURN genkeypair_file(KMF_HANDLE_T, + KMF_KEY_ALG, int, KMF_ENCODE_FORMAT, + char *, KMF_KEY_HANDLE *, KMF_KEY_HANDLE *); + +KMF_RETURN genkeypair_nss(KMF_HANDLE_T, + char *, char *, char *, char *, + KMF_KEY_ALG, int, KMF_CREDENTIAL *, + KMF_OID *, KMF_KEY_HANDLE *, KMF_KEY_HANDLE *); void free_eku_list(EKU_LIST *); diff --git a/usr/src/cmd/cmd-crypto/pktool/gencert.c b/usr/src/cmd/cmd-crypto/pktool/gencert.c index 3afd08a588..2b107b85be 100644 --- a/usr/src/cmd/cmd-crypto/pktool/gencert.c +++ b/usr/src/cmd/cmd-crypto/pktool/gencert.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -52,7 +52,7 @@ gencert_pkcs11(KMF_HANDLE_T kmfhandle, KMF_ALGORITHM_INDEX sigAlg, int keylen, uint32_t ltime, KMF_BIGINT *serial, uint16_t kubits, int kucrit, KMF_CREDENTIAL *tokencred, - EKU_LIST *ekulist) + EKU_LIST *ekulist, KMF_OID *curveoid) { KMF_RETURN kmfrv = KMF_OK; KMF_KEY_HANDLE pubk, prik; @@ -90,54 +90,17 @@ gencert_pkcs11(KMF_HANDLE_T kmfhandle, /* Select a PKCS11 token */ kmfrv = select_token(kmfhandle, token, FALSE); - if (kmfrv != KMF_OK) { return (kmfrv); } - kmf_set_attr_at_index(attrlist, numattr, - KMF_KEYSTORE_TYPE_ATTR, &kstype, - sizeof (kstype)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, - KMF_KEYALG_ATTR, &keytype, - sizeof (keytype)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, - KMF_KEYLENGTH_ATTR, &keylength, - sizeof (keylength)); - numattr++; - - if (certlabel != NULL) { - kmf_set_attr_at_index(attrlist, numattr, - KMF_KEYLABEL_ATTR, certlabel, - strlen(certlabel)); - numattr++; - } - - if (tokencred != NULL && tokencred->cred != NULL) { - kmf_set_attr_at_index(attrlist, numattr, - KMF_CREDENTIAL_ATTR, tokencred, - sizeof (KMF_CREDENTIAL)); - numattr++; - } - - kmf_set_attr_at_index(attrlist, numattr, - KMF_PRIVKEY_HANDLE_ATTR, &prik, - sizeof (KMF_KEY_HANDLE)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, - KMF_PUBKEY_HANDLE_ATTR, &pubk, - sizeof (KMF_KEY_HANDLE)); - numattr++; - - kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); - if (kmfrv != KMF_OK) { + /* + * Share the "genkeypair" routine for creating the keypair. + */ + kmfrv = genkeypair_pkcs11(kmfhandle, token, certlabel, + keytype, keylength, tokencred, curveoid, &prik, &pubk); + if (kmfrv != KMF_OK) return (kmfrv); - } SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert), "keypair"); @@ -297,9 +260,6 @@ gencert_file(KMF_HANDLE_T kmfhandle, KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; KMF_ATTRIBUTE attrlist[10]; int numattr = 0; - KMF_KEY_ALG keytype; - uint32_t keylength; - KMF_ENCODE_FORMAT format; (void) memset(&signedCert, 0, sizeof (signedCert)); (void) memset(&certSubject, 0, sizeof (certSubject)); @@ -321,16 +281,6 @@ gencert_file(KMF_HANDLE_T kmfhandle, return (PK_ERR_USAGE); } - fullkeypath = strdup(outkey); - if (verify_file(fullkeypath)) { - cryptoerror(LOG_STDERR, - gettext("Cannot write the indicated output " - "key file (%s).\n"), fullkeypath); - free(fullkeypath); - free(fullcertpath); - return (PK_ERR_USAGE); - } - /* If the subject name cannot be parsed, flag it now and exit */ if (kmf_dn_parser(subject, &certSubject) != KMF_OK) { cryptoerror(LOG_STDERR, @@ -346,51 +296,13 @@ gencert_file(KMF_HANDLE_T kmfhandle, return (PK_ERR_USAGE); } - keylength = keylen; /* bits */ - keytype = keyAlg; - format = fmt; - - kmf_set_attr_at_index(attrlist, numattr, - KMF_KEYSTORE_TYPE_ATTR, &kstype, - sizeof (kstype)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, - KMF_KEYALG_ATTR, &keytype, - sizeof (keytype)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, - KMF_KEYLENGTH_ATTR, &keylength, - sizeof (keylength)); - numattr++; - - if (fullkeypath != NULL) { - kmf_set_attr_at_index(attrlist, numattr, - KMF_KEY_FILENAME_ATTR, fullkeypath, - strlen(fullkeypath)); - numattr++; - } - - kmf_set_attr_at_index(attrlist, numattr, - KMF_ENCODE_FORMAT_ATTR, &format, - sizeof (format)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, - KMF_PRIVKEY_HANDLE_ATTR, &prik, - sizeof (KMF_KEY_HANDLE)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, - KMF_PUBKEY_HANDLE_ATTR, &pubk, - sizeof (KMF_KEY_HANDLE)); - numattr++; - - kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); - if (kmfrv != KMF_OK) { - goto cleanup; - } + /* + * Share the "genkeypair" routine for creating the keypair. + */ + kmfrv = genkeypair_file(kmfhandle, keyAlg, keylen, + fmt, outkey, &prik, &pubk); + if (kmfrv != KMF_OK) + return (kmfrv); SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert), "keypair"); @@ -496,7 +408,7 @@ gencert_nss(KMF_HANDLE_T kmfhandle, int keylen, char *trust, uint32_t ltime, KMF_BIGINT *serial, uint16_t kubits, int kucrit, KMF_CREDENTIAL *tokencred, - EKU_LIST *ekulist) + EKU_LIST *ekulist, KMF_OID *curveoid) { KMF_RETURN kmfrv; KMF_KEY_HANDLE pubk, prik; @@ -507,8 +419,6 @@ gencert_nss(KMF_HANDLE_T kmfhandle, KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; KMF_ATTRIBUTE attrlist[16]; int numattr = 0; - KMF_KEY_ALG keytype; - uint32_t keylength; if (token == NULL) token = DEFAULT_NSS_TOKEN; @@ -536,59 +446,11 @@ gencert_nss(KMF_HANDLE_T kmfhandle, return (PK_ERR_USAGE); } - keylength = keylen; /* bits */ - keytype = keyAlg; - - kmf_set_attr_at_index(attrlist, numattr, - KMF_KEYSTORE_TYPE_ATTR, &kstype, - sizeof (kstype)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, - KMF_KEYALG_ATTR, &keytype, - sizeof (keytype)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, - KMF_KEYLENGTH_ATTR, &keylength, - sizeof (keylength)); - numattr++; - - if (nickname != NULL) { - kmf_set_attr_at_index(attrlist, numattr, - KMF_KEYLABEL_ATTR, nickname, - strlen(nickname)); - numattr++; - } - - if (tokencred != NULL && tokencred->cred != NULL) { - kmf_set_attr_at_index(attrlist, numattr, - KMF_CREDENTIAL_ATTR, tokencred, - sizeof (KMF_CREDENTIAL)); - numattr++; - } - - if (token != NULL) { - kmf_set_attr_at_index(attrlist, numattr, - KMF_TOKEN_LABEL_ATTR, token, - strlen(token)); - numattr++; - } - - kmf_set_attr_at_index(attrlist, numattr, - KMF_PRIVKEY_HANDLE_ATTR, &prik, - sizeof (KMF_KEY_HANDLE)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, - KMF_PUBKEY_HANDLE_ATTR, &pubk, - sizeof (KMF_KEY_HANDLE)); - numattr++; - - kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); - if (kmfrv != KMF_OK) { + kmfrv = genkeypair_nss(kmfhandle, token, nickname, dir, + prefix, keyAlg, keylen, tokencred, curveoid, + &prik, &pubk); + if (kmfrv != KMF_OK) return (kmfrv); - } SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert), "keypair"); @@ -716,6 +578,7 @@ pk_gencert(int argc, char *argv[]) char *altname = NULL; char *keyusagestr = NULL; char *ekustr = NULL; + char *hashname = NULL; KMF_GENERALNAMECHOICES alttype = 0; KMF_BIGINT serial = { NULL, 0 }; uint32_t ltime; @@ -729,14 +592,18 @@ pk_gencert(int argc, char *argv[]) uint16_t kubits = 0; int altcrit = 0, kucrit = 0; EKU_LIST *ekulist = NULL; + KMF_OID *curveoid = NULL; /* ECC */ + KMF_OID *hashoid = NULL; + int y_flag = 0; while ((opt = getopt_av(argc, argv, "ik:(keystore)s:(subject)n:(nickname)A:(altname)" "T:(token)d:(dir)p:(prefix)t:(keytype)y:(keylen)" "r:(trust)L:(lifetime)l:(label)c:(outcert)e:(eku)" - "K:(outkey)S:(serial)F:(format)u:(keyusage)")) != EOF) { + "K:(outkey)S:(serial)F:(format)u:(keyusage)C:(curve)" + "E(listcurves)h:(hash)")) != EOF) { - if (opt != 'i' && EMPTYSTRING(optarg_av)) + if (opt != 'i' && opt != 'E' && EMPTYSTRING(optarg_av)) return (PK_ERR_USAGE); switch (opt) { @@ -796,6 +663,7 @@ pk_gencert(int argc, char *argv[]) optarg_av); return (PK_ERR_USAGE); } + y_flag++; break; case 'r': if (trust) @@ -828,6 +696,38 @@ pk_gencert(int argc, char *argv[]) case 'e': ekustr = optarg_av; break; + case 'C': + curveoid = ecc_name_to_oid(optarg_av); + if (curveoid == NULL) { + cryptoerror(LOG_STDERR, + gettext("Unrecognized ECC " + "curve.\n")); + return (PK_ERR_USAGE); + } + break; + case 'E': + /* + * This argument is only to be used + * by itself, no other options should + * be present. + */ + if (argc != 2) { + cryptoerror(LOG_STDERR, + gettext("listcurves has no other " + "options.\n")); + return (PK_ERR_USAGE); + } + show_ecc_curves(); + return (0); + case 'h': + hashname = optarg_av; + hashoid = ecc_name_to_oid(optarg_av); + if (hashoid == NULL) { + cryptoerror(LOG_STDERR, + gettext("Unrecognized hash.\n")); + return (PK_ERR_USAGE); + } + break; default: return (PK_ERR_USAGE); } @@ -881,11 +781,25 @@ pk_gencert(int argc, char *argv[]) return (PK_ERR_USAGE); } - if (Str2KeyType(keytype, &keyAlg, &sigAlg) != 0) { - cryptoerror(LOG_STDERR, gettext("Unrecognized keytype (%s).\n"), - keytype); + if (Str2KeyType(keytype, hashoid, &keyAlg, &sigAlg) != 0) { + cryptoerror(LOG_STDERR, + gettext("Unsupported key/hash combination (%s/%s).\n"), + keytype, (hashname ? hashname : "none")); + return (PK_ERR_USAGE); + } + if (curveoid != NULL && keyAlg != KMF_ECDSA) { + cryptoerror(LOG_STDERR, gettext("EC curves are only " + "valid for EC keytypes.\n")); + return (PK_ERR_USAGE); + } + if (keyAlg == KMF_ECDSA && curveoid == NULL) { + cryptoerror(LOG_STDERR, gettext("A curve must be " + "specifed when using EC keys.\n")); return (PK_ERR_USAGE); } + /* Adjust default keylength for NSS and DSA */ + if (keyAlg == KMF_DSA && !y_flag && kstype == KMF_KEYSTORE_NSS) + keylen = 1024; /* * Check the subject name. @@ -976,6 +890,12 @@ pk_gencert(int argc, char *argv[]) goto end; } } + if (keyAlg == KMF_ECDSA && kstype == KMF_KEYSTORE_OPENSSL) { + (void) fprintf(stderr, gettext("ECC certificates are" + "only supported with the pkcs11 and nss keystores\n")); + rv = PK_ERR_USAGE; + goto end; + } if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) { if (tokenname == NULL || !strlen(tokenname)) { @@ -997,13 +917,14 @@ pk_gencert(int argc, char *argv[]) tokenname, subname, altname, alttype, altcrit, certlabel, dir, prefix, keyAlg, sigAlg, keylen, trust, ltime, &serial, kubits, kucrit, &tokencred, - ekulist); + ekulist, curveoid); } else if (kstype == KMF_KEYSTORE_PK11TOKEN) { rv = gencert_pkcs11(kmfhandle, tokenname, subname, altname, alttype, altcrit, certlabel, keyAlg, sigAlg, keylen, ltime, - &serial, kubits, kucrit, &tokencred, ekulist); + &serial, kubits, kucrit, &tokencred, ekulist, + curveoid); } else if (kstype == KMF_KEYSTORE_OPENSSL) { rv = gencert_file(kmfhandle, diff --git a/usr/src/cmd/cmd-crypto/pktool/gencsr.c b/usr/src/cmd/cmd-crypto/pktool/gencsr.c index f65f4cf949..be85b222b1 100644 --- a/usr/src/cmd/cmd-crypto/pktool/gencsr.c +++ b/usr/src/cmd/cmd-crypto/pktool/gencsr.c @@ -19,7 +19,7 @@ * CDDL HEADER END * * - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -51,82 +51,37 @@ gencsr_pkcs11(KMF_HANDLE_T kmfhandle, char *certlabel, KMF_KEY_ALG keyAlg, int keylen, uint16_t kubits, int kucrit, KMF_ENCODE_FORMAT fmt, char *csrfile, - KMF_CREDENTIAL *tokencred, EKU_LIST *ekulist) + KMF_CREDENTIAL *tokencred, EKU_LIST *ekulist, + KMF_ALGORITHM_INDEX sigAlg, KMF_OID *curveoid) { KMF_RETURN kmfrv = KMF_OK; KMF_KEY_HANDLE pubk, prik; KMF_X509_NAME csrSubject; KMF_CSR_DATA csr; - KMF_ALGORITHM_INDEX sigAlg; KMF_DATA signedCsr = {NULL, 0}; KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; int numattr = 0; KMF_ATTRIBUTE attrlist[16]; - boolean_t storekey = TRUE; (void) memset(&csr, 0, sizeof (csr)); (void) memset(&csrSubject, 0, sizeof (csrSubject)); - if (keyAlg == KMF_DSA) - sigAlg = KMF_ALGID_SHA1WithDSA; - else - sigAlg = KMF_ALGID_SHA1WithRSA; - - /* If the subject name cannot be parsed, flag it now and exit */ - if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) { + if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) return (kmfrv); - } /* Select a PKCS11 token */ kmfrv = select_token(kmfhandle, token, FALSE); - if (kmfrv != KMF_OK) { + if (kmfrv != KMF_OK) return (kmfrv); - } - - kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, - &kstype, sizeof (kstype)); - numattr++; - - if (certlabel != NULL && strlen(certlabel)) { - kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, - certlabel, strlen(certlabel)); - numattr++; - } - kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLENGTH_ATTR, - &keylen, sizeof (keylen)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_KEYALG_ATTR, - &keyAlg, sizeof (keyAlg)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, - tokencred, sizeof (KMF_CREDENTIAL)); - numattr++; - - if (token && strlen(token)) { - kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, - token, strlen(token)); - numattr++; - } - kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR, - &pubk, sizeof (KMF_KEY_HANDLE)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVKEY_HANDLE_ATTR, - &prik, sizeof (KMF_KEY_HANDLE)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_STOREKEY_BOOL_ATTR, - &storekey, sizeof (storekey)); - numattr++; - - kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); - if (kmfrv != KMF_OK) { + /* + * Share the "genkeypair" routine for creating the keypair. + */ + kmfrv = genkeypair_pkcs11(kmfhandle, token, certlabel, + keyAlg, keylen, tokencred, curveoid, &prik, &pubk); + if (kmfrv != KMF_OK) return (kmfrv); - } SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr), "keypair"); @@ -217,21 +172,17 @@ gencsr_file(KMF_HANDLE_T kmfhandle, int keylen, KMF_ENCODE_FORMAT fmt, char *subject, char *altname, KMF_GENERALNAMECHOICES alttype, int altcrit, uint16_t kubits, int kucrit, - char *outcsr, char *outkey, EKU_LIST *ekulist) + char *outcsr, char *outkey, EKU_LIST *ekulist, + KMF_ALGORITHM_INDEX sigAlg) { KMF_RETURN kmfrv; KMF_KEY_HANDLE pubk, prik; KMF_X509_NAME csrSubject; KMF_CSR_DATA csr; - KMF_ALGORITHM_INDEX sigAlg; KMF_DATA signedCsr = {NULL, 0}; char *fullcsrpath = NULL; char *fullkeypath = NULL; - int numattr = 0; - KMF_ATTRIBUTE attrlist[16]; - KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; - boolean_t storekey = TRUE; (void) memset(&csr, 0, sizeof (csr)); (void) memset(&csrSubject, 0, sizeof (csrSubject)); @@ -251,63 +202,18 @@ gencsr_file(KMF_HANDLE_T kmfhandle, return (PK_ERR_USAGE); } - fullkeypath = strdup(outkey); - if (verify_file(fullcsrpath)) { - cryptoerror(LOG_STDERR, - gettext("Cannot write the indicated output " - "key file (%s).\n"), fullkeypath); - free(fullcsrpath); - return (PK_ERR_USAGE); - } - - if (keyAlg == KMF_DSA) - sigAlg = KMF_ALGID_SHA1WithDSA; - else - sigAlg = KMF_ALGID_SHA1WithRSA; - /* If the subject name cannot be parsed, flag it now and exit */ if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) { return (kmfrv); } + /* + * Share the "genkeypair" routine for creating the keypair. + */ + kmfrv = genkeypair_file(kmfhandle, keyAlg, keylen, + fmt, outkey, &prik, &pubk); + if (kmfrv != KMF_OK) + return (kmfrv); - kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, - &kstype, sizeof (kstype)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR, - fullkeypath, strlen(fullkeypath)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLENGTH_ATTR, - &keylen, sizeof (keylen)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_KEYALG_ATTR, - &keyAlg, sizeof (keyAlg)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, - &fmt, sizeof (fmt)); - numattr++; - - (void) memset(&prik, 0, sizeof (prik)); - kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVKEY_HANDLE_ATTR, - &prik, sizeof (KMF_KEY_HANDLE)); - numattr++; - - (void) memset(&pubk, 0, sizeof (pubk)); - kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR, - &pubk, sizeof (KMF_KEY_HANDLE)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_STOREKEY_BOOL_ATTR, - &storekey, sizeof (storekey)); - numattr++; - - kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); - if (kmfrv != KMF_OK) { - goto cleanup; - } SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr), "SetCSRPubKey"); @@ -361,28 +267,22 @@ gencsr_nss(KMF_HANDLE_T kmfhandle, KMF_KEY_ALG keyAlg, int keylen, uint16_t kubits, int kucrit, KMF_ENCODE_FORMAT fmt, char *csrfile, - KMF_CREDENTIAL *tokencred, EKU_LIST *ekulist) + KMF_CREDENTIAL *tokencred, EKU_LIST *ekulist, + KMF_ALGORITHM_INDEX sigAlg, KMF_OID *curveoid) { KMF_RETURN kmfrv; KMF_KEY_HANDLE pubk, prik; KMF_X509_NAME csrSubject; KMF_CSR_DATA csr; - KMF_ALGORITHM_INDEX sigAlg; KMF_DATA signedCsr = {NULL, 0}; KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; int numattr = 0; KMF_ATTRIBUTE attrlist[16]; - boolean_t storekey = TRUE; if (token == NULL) token = DEFAULT_NSS_TOKEN; - if (keyAlg == KMF_DSA) - sigAlg = KMF_ALGID_SHA1WithDSA; - else - sigAlg = KMF_ALGID_SHA1WithRSA; - kmfrv = configure_nss(kmfhandle, dir, prefix); if (kmfrv != KMF_OK) return (kmfrv); @@ -397,50 +297,11 @@ gencsr_nss(KMF_HANDLE_T kmfhandle, return (kmfrv); } - kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, - &kstype, sizeof (kstype)); - numattr++; - - if (nickname != NULL && strlen(nickname)) { - kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, - nickname, strlen(nickname)); - numattr++; - } - kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLENGTH_ATTR, - &keylen, sizeof (keylen)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_KEYALG_ATTR, - &keyAlg, sizeof (keyAlg)); - numattr++; - - if (tokencred != NULL && tokencred->credlen > 0) { - kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, - tokencred, sizeof (KMF_CREDENTIAL)); - numattr++; - } - - if (token && strlen(token)) { - kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, - token, strlen(token)); - numattr++; - } - kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR, - &pubk, sizeof (KMF_KEY_HANDLE)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVKEY_HANDLE_ATTR, - &prik, sizeof (KMF_KEY_HANDLE)); - numattr++; - - kmf_set_attr_at_index(attrlist, numattr, KMF_STOREKEY_BOOL_ATTR, - &storekey, sizeof (storekey)); - numattr++; - - kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); - if (kmfrv != KMF_OK) { - goto cleanup; - } + kmfrv = genkeypair_nss(kmfhandle, token, nickname, dir, + prefix, keyAlg, keylen, tokencred, curveoid, + &prik, &pubk); + if (kmfrv != KMF_OK) + return (kmfrv); SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr), "kmf_set_csr_pubkey"); @@ -524,6 +385,7 @@ pk_gencsr(int argc, char *argv[]) char *altname = NULL; char *kustr = NULL; char *ekustr = NULL; + char *hashname = NULL; uint16_t kubits = 0; char *keytype = PK_DEFAULT_KEYTYPE; KMF_HANDLE_T kmfhandle = NULL; @@ -536,15 +398,15 @@ pk_gencsr(int argc, char *argv[]) KMF_GENERALNAMECHOICES alttype = 0; int altcrit = 0, kucrit = 0; EKU_LIST *ekulist = NULL; + KMF_OID *curveoid = NULL; /* ECC */ + KMF_OID *hashoid = NULL; + int y_flag = 0; while ((opt = getopt_av(argc, argv, "ik:(keystore)s:(subject)n:(nickname)A:(altname)" "u:(keyusage)T:(token)d:(dir)p:(prefix)t:(keytype)" - "y:(keylen)l:(label)c:(outcsr)e:(eku)" - "K:(outkey)F:(format)")) != EOF) { - - if (opt != 'i' && EMPTYSTRING(optarg_av)) - return (PK_ERR_USAGE); + "y:(keylen)l:(label)c:(outcsr)e:(eku)C:(curve)" + "K:(outkey)F:(format)E(listcurves)h:(hash)")) != EOF) { switch (opt) { case 'A': @@ -612,6 +474,7 @@ pk_gencsr(int argc, char *argv[]) "key length (%s)\n"), optarg_av); return (PK_ERR_USAGE); } + y_flag++; break; case 'c': if (outcsr) @@ -631,6 +494,38 @@ pk_gencsr(int argc, char *argv[]) case 'e': ekustr = optarg_av; break; + case 'C': + curveoid = ecc_name_to_oid(optarg_av); + if (curveoid == NULL) { + cryptoerror(LOG_STDERR, + gettext("Unrecognized ECC " + "curve.\n")); + return (PK_ERR_USAGE); + } + break; + case 'E': + /* + * This argument is only to be used + * by itself, no other options should + * be present. + */ + if (argc != 2) { + cryptoerror(LOG_STDERR, + gettext("listcurves has no other " + "options.\n")); + return (PK_ERR_USAGE); + } + show_ecc_curves(); + return (0); + case 'h': + hashname = optarg_av; + hashoid = ecc_name_to_oid(optarg_av); + if (hashoid == NULL) { + cryptoerror(LOG_STDERR, + gettext("Unrecognized hash.\n")); + return (PK_ERR_USAGE); + } + break; default: cryptoerror(LOG_STDERR, gettext( "unrecognized gencsr option '%s'\n"), @@ -761,13 +656,33 @@ pk_gencsr(int argc, char *argv[]) goto end; } } - - if ((rv = Str2KeyType(keytype, &keyAlg, &sigAlg)) != 0) { - cryptoerror(LOG_STDERR, gettext("Unrecognized keytype (%s).\n"), - keytype); + if ((rv = Str2KeyType(keytype, hashoid, &keyAlg, &sigAlg)) != 0) { + cryptoerror(LOG_STDERR, + gettext("Unsupported key/hash combination (%s/%s).\n"), + keytype, (hashname ? hashname : "none")); + goto end; + } + if (curveoid != NULL && keyAlg != KMF_ECDSA) { + cryptoerror(LOG_STDERR, gettext("EC curves are only " + "valid for EC keytypes.\n")); + return (PK_ERR_USAGE); + } + if (keyAlg == KMF_ECDSA && curveoid == NULL) { + cryptoerror(LOG_STDERR, gettext("A curve must be " + "specifed when using EC keys.\n")); + return (PK_ERR_USAGE); + } + if (keyAlg == KMF_ECDSA && kstype == KMF_KEYSTORE_OPENSSL) { + (void) fprintf(stderr, gettext("ECC certificates are" + "only supported with the pkcs11 and nss keystores\n")); + rv = PK_ERR_USAGE; goto end; } + /* Adjust default keylength for NSS and DSA */ + if (keyAlg == KMF_DSA && !y_flag && kstype == KMF_KEYSTORE_NSS) + keylen = 1024; + if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) { if (tokenname == NULL || !strlen(tokenname)) { if (kstype == KMF_KEYSTORE_NSS) { @@ -794,19 +709,21 @@ pk_gencsr(int argc, char *argv[]) tokenname, subname, altname, alttype, altcrit, certlabel, dir, prefix, keyAlg, keylen, kubits, kucrit, - fmt, outcsr, &tokencred, ekulist); + fmt, outcsr, &tokencred, ekulist, + sigAlg, curveoid); } else if (kstype == KMF_KEYSTORE_PK11TOKEN) { rv = gencsr_pkcs11(kmfhandle, tokenname, subname, altname, alttype, altcrit, certlabel, keyAlg, keylen, - kubits, kucrit, fmt, outcsr, &tokencred, ekulist); + kubits, kucrit, fmt, outcsr, &tokencred, + ekulist, sigAlg, curveoid); } else if (kstype == KMF_KEYSTORE_OPENSSL) { rv = gencsr_file(kmfhandle, keyAlg, keylen, fmt, subname, altname, alttype, altcrit, kubits, kucrit, - outcsr, outkey, ekulist); + outcsr, outkey, ekulist, sigAlg); } end: diff --git a/usr/src/cmd/cmd-crypto/pktool/genkeypair.c b/usr/src/cmd/cmd-crypto/pktool/genkeypair.c new file mode 100644 index 0000000000..27c0af0cd2 --- /dev/null +++ b/usr/src/cmd/cmd-crypto/pktool/genkeypair.c @@ -0,0 +1,523 @@ +/* + * 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 2010 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <malloc.h> +#include <libgen.h> +#include <errno.h> +#include <cryptoutil.h> +#include <security/cryptoki.h> +#include "common.h" + +#include <kmfapi.h> + +#define SET_VALUE(f, s) \ + kmfrv = f; \ + if (kmfrv != KMF_OK) { \ + cryptoerror(LOG_STDERR, \ + gettext("Failed to set %s: 0x%02x\n"), \ + s, kmfrv); \ + goto cleanup; \ + } + +KMF_RETURN +genkeypair_pkcs11(KMF_HANDLE_T kmfhandle, + char *token, char *keylabel, KMF_KEY_ALG keyAlg, + int keylen, KMF_CREDENTIAL *tokencred, KMF_OID *curveoid, + KMF_KEY_HANDLE *outPriKey, KMF_KEY_HANDLE *outPubKey) +{ + KMF_RETURN kmfrv = KMF_OK; + KMF_KEY_HANDLE pubk, prik; + KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; + KMF_ATTRIBUTE attrlist[16]; + int numattr = 0; + KMF_KEY_ALG keytype; + uint32_t keylength; + + keylength = keylen; /* bits */ + keytype = keyAlg; + + /* Select a PKCS11 token */ + kmfrv = select_token(kmfhandle, token, FALSE); + if (kmfrv != KMF_OK) + return (kmfrv); + + kmf_set_attr_at_index(attrlist, numattr, + KMF_KEYSTORE_TYPE_ATTR, &kstype, + sizeof (kstype)); + numattr++; + + kmf_set_attr_at_index(attrlist, numattr, + KMF_KEYALG_ATTR, &keytype, + sizeof (keytype)); + numattr++; + + kmf_set_attr_at_index(attrlist, numattr, + KMF_KEYLENGTH_ATTR, &keylength, + sizeof (keylength)); + numattr++; + + if (keylabel != NULL) { + kmf_set_attr_at_index(attrlist, numattr, + KMF_KEYLABEL_ATTR, keylabel, + strlen(keylabel)); + numattr++; + } + + if (tokencred != NULL && tokencred->cred != NULL) { + kmf_set_attr_at_index(attrlist, numattr, + KMF_CREDENTIAL_ATTR, tokencred, + sizeof (KMF_CREDENTIAL)); + numattr++; + } + + kmf_set_attr_at_index(attrlist, numattr, + KMF_PRIVKEY_HANDLE_ATTR, &prik, + sizeof (KMF_KEY_HANDLE)); + numattr++; + + kmf_set_attr_at_index(attrlist, numattr, + KMF_PUBKEY_HANDLE_ATTR, &pubk, + sizeof (KMF_KEY_HANDLE)); + numattr++; + + if (keytype == KMF_ECDSA && curveoid != NULL) { + kmf_set_attr_at_index(attrlist, numattr, + KMF_ECC_CURVE_OID_ATTR, curveoid, + sizeof (KMF_OID)); + numattr++; + } + + kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); + if (kmfrv != KMF_OK) { + return (kmfrv); + } + +cleanup: + if (kmfrv == KMF_OK) { + if (outPriKey != NULL) + *outPriKey = prik; + if (outPubKey != NULL) + *outPubKey = pubk; + } + + return (kmfrv); +} + +KMF_RETURN +genkeypair_file(KMF_HANDLE_T kmfhandle, + KMF_KEY_ALG keyAlg, int keylen, KMF_ENCODE_FORMAT fmt, + char *outkey, + KMF_KEY_HANDLE *outPriKey, KMF_KEY_HANDLE *outPubKey) +{ + KMF_RETURN kmfrv; + KMF_KEY_HANDLE pubk, prik; + char *fullkeypath = NULL; + KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; + KMF_ATTRIBUTE attrlist[10]; + int numattr = 0; + KMF_KEY_ALG keytype; + uint32_t keylength; + KMF_ENCODE_FORMAT format; + + if (EMPTYSTRING(outkey)) { + cryptoerror(LOG_STDERR, + gettext("No output file was specified for " + "the key\n")); + return (PK_ERR_USAGE); + } + + fullkeypath = strdup(outkey); + if (verify_file(fullkeypath)) { + cryptoerror(LOG_STDERR, + gettext("Cannot write the indicated output " + "key file (%s).\n"), fullkeypath); + free(fullkeypath); + return (PK_ERR_USAGE); + } + + keylength = keylen; /* bits */ + keytype = keyAlg; + format = fmt; + + kmf_set_attr_at_index(attrlist, numattr, + KMF_KEYSTORE_TYPE_ATTR, &kstype, + sizeof (kstype)); + numattr++; + + kmf_set_attr_at_index(attrlist, numattr, + KMF_KEYALG_ATTR, &keytype, + sizeof (keytype)); + numattr++; + + kmf_set_attr_at_index(attrlist, numattr, + KMF_KEYLENGTH_ATTR, &keylength, + sizeof (keylength)); + numattr++; + + if (fullkeypath != NULL) { + kmf_set_attr_at_index(attrlist, numattr, + KMF_KEY_FILENAME_ATTR, fullkeypath, + strlen(fullkeypath)); + numattr++; + } + + kmf_set_attr_at_index(attrlist, numattr, + KMF_ENCODE_FORMAT_ATTR, &format, + sizeof (format)); + numattr++; + + kmf_set_attr_at_index(attrlist, numattr, + KMF_PRIVKEY_HANDLE_ATTR, &prik, + sizeof (KMF_KEY_HANDLE)); + numattr++; + + kmf_set_attr_at_index(attrlist, numattr, + KMF_PUBKEY_HANDLE_ATTR, &pubk, + sizeof (KMF_KEY_HANDLE)); + numattr++; + + kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); + if (kmfrv != KMF_OK) { + goto cleanup; + } + +cleanup: + if (fullkeypath != NULL) + free(fullkeypath); + + if (kmfrv == KMF_OK) { + if (outPriKey != NULL) + *outPriKey = prik; + if (outPubKey != NULL) + *outPubKey = pubk; + } + + return (kmfrv); +} + +KMF_RETURN +genkeypair_nss(KMF_HANDLE_T kmfhandle, + char *token, + char *nickname, char *dir, char *prefix, + KMF_KEY_ALG keyAlg, + int keylen, KMF_CREDENTIAL *tokencred, + KMF_OID *curveoid, + KMF_KEY_HANDLE *outPriKey, KMF_KEY_HANDLE *outPubKey) +{ + KMF_RETURN kmfrv; + KMF_KEY_HANDLE pubk, prik; + KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; + KMF_ATTRIBUTE attrlist[16]; + int numattr = 0; + KMF_KEY_ALG keytype; + uint32_t keylength; + + if (token == NULL) + token = DEFAULT_NSS_TOKEN; + + kmfrv = configure_nss(kmfhandle, dir, prefix); + if (kmfrv != KMF_OK) + return (kmfrv); + + keylength = keylen; /* bits */ + keytype = keyAlg; + + kmf_set_attr_at_index(attrlist, numattr, + KMF_KEYSTORE_TYPE_ATTR, &kstype, + sizeof (kstype)); + numattr++; + + kmf_set_attr_at_index(attrlist, numattr, + KMF_KEYALG_ATTR, &keytype, + sizeof (keytype)); + numattr++; + + kmf_set_attr_at_index(attrlist, numattr, + KMF_KEYLENGTH_ATTR, &keylength, + sizeof (keylength)); + numattr++; + + if (nickname != NULL) { + kmf_set_attr_at_index(attrlist, numattr, + KMF_KEYLABEL_ATTR, nickname, + strlen(nickname)); + numattr++; + } + + if (tokencred != NULL && tokencred->cred != NULL) { + kmf_set_attr_at_index(attrlist, numattr, + KMF_CREDENTIAL_ATTR, tokencred, + sizeof (KMF_CREDENTIAL)); + numattr++; + } + + if (token != NULL) { + kmf_set_attr_at_index(attrlist, numattr, + KMF_TOKEN_LABEL_ATTR, token, + strlen(token)); + numattr++; + } + + kmf_set_attr_at_index(attrlist, numattr, + KMF_PRIVKEY_HANDLE_ATTR, &prik, + sizeof (KMF_KEY_HANDLE)); + numattr++; + + kmf_set_attr_at_index(attrlist, numattr, + KMF_PUBKEY_HANDLE_ATTR, &pubk, + sizeof (KMF_KEY_HANDLE)); + numattr++; + + if (keytype == KMF_ECDSA && curveoid != NULL) { + kmf_set_attr_at_index(attrlist, numattr, + KMF_ECC_CURVE_OID_ATTR, curveoid, + sizeof (KMF_OID)); + numattr++; + } + + kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); + if (kmfrv != KMF_OK) { + return (kmfrv); + } +cleanup: + if (kmfrv == KMF_OK) { + if (outPriKey != NULL) + *outPriKey = prik; + if (outPubKey != NULL) + *outPubKey = pubk; + } + return (kmfrv); +} + +int +pk_genkeypair(int argc, char *argv[]) +{ + int rv; + int opt; + extern int optind_av; + extern char *optarg_av; + KMF_KEYSTORE_TYPE kstype = 0; + char *tokenname = NULL; + char *dir = NULL; + char *prefix = NULL; + char *keytype = PK_DEFAULT_KEYTYPE; + int keylen = PK_DEFAULT_KEYLENGTH; + char *label = NULL; + char *outkey = NULL; + char *format = NULL; + KMF_HANDLE_T kmfhandle = NULL; + KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1; + KMF_KEY_ALG keyAlg = KMF_RSA; + KMF_ALGORITHM_INDEX sigAlg; + KMF_CREDENTIAL tokencred = {NULL, 0}; + KMF_OID *curveoid = NULL; /* ECC */ + int y_flag = 0; + + while ((opt = getopt_av(argc, argv, + "k:(keystore)s:(subject)n:(nickname)" + "T:(token)d:(dir)p:(prefix)t:(keytype)y:(keylen)" + "l:(label)K:(outkey)F:(format)C:(curve)" + "E(listcurves)")) != EOF) { + + if (opt != 'i' && opt != 'E' && EMPTYSTRING(optarg_av)) + return (PK_ERR_USAGE); + + switch (opt) { + case 'k': + kstype = KS2Int(optarg_av); + if (kstype == 0) + return (PK_ERR_USAGE); + break; + case 'l': + case 'n': + if (label) + return (PK_ERR_USAGE); + label = optarg_av; + break; + case 'T': + if (tokenname) + return (PK_ERR_USAGE); + tokenname = optarg_av; + break; + case 'd': + if (dir) + return (PK_ERR_USAGE); + dir = optarg_av; + break; + case 'p': + if (prefix) + return (PK_ERR_USAGE); + prefix = optarg_av; + break; + case 't': + keytype = optarg_av; + break; + case 'y': + if (sscanf(optarg_av, "%d", + &keylen) != 1) { + cryptoerror(LOG_STDERR, + gettext("key length must be" + "a numeric value (%s)\n"), + optarg_av); + return (PK_ERR_USAGE); + } + y_flag++; + break; + case 'K': + if (outkey) + return (PK_ERR_USAGE); + outkey = optarg_av; + break; + case 'F': + if (format) + return (PK_ERR_USAGE); + format = optarg_av; + break; + case 'C': + curveoid = ecc_name_to_oid(optarg_av); + if (curveoid == NULL) { + cryptoerror(LOG_STDERR, + gettext( + "Unrecognized ECC curve.\n")); + return (PK_ERR_USAGE); + } + break; + case 'E': + show_ecc_curves(); + return (0); + default: + return (PK_ERR_USAGE); + } + } + + /* No additional args allowed. */ + argc -= optind_av; + argv += optind_av; + if (argc) { + return (PK_ERR_USAGE); + } + + if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { + cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n")); + return (PK_ERR_USAGE); + } + + /* Assume keystore = PKCS#11 if not specified. */ + if (kstype == 0) + kstype = KMF_KEYSTORE_PK11TOKEN; + + DIR_OPTION_CHECK(kstype, dir); + + if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) { + cryptoerror(LOG_STDERR, + gettext("Error parsing format string (%s).\n"), + format); + return (PK_ERR_USAGE); + } + + if (Str2KeyType(keytype, NULL, &keyAlg, &sigAlg) != 0) { + cryptoerror(LOG_STDERR, gettext("Unrecognized keytype (%s).\n"), + keytype); + return (PK_ERR_USAGE); + } + if (curveoid != NULL && keyAlg != KMF_ECDSA) { + cryptoerror(LOG_STDERR, gettext("EC curves are only " + "valid for EC keytypes.\n")); + return (PK_ERR_USAGE); + } + if (keyAlg == KMF_ECDSA && curveoid == NULL) { + cryptoerror(LOG_STDERR, gettext("A curve must be " + "specifed when using EC keys.\n")); + return (PK_ERR_USAGE); + } + if (keyAlg == KMF_ECDSA && kstype == KMF_KEYSTORE_OPENSSL) { + (void) fprintf(stderr, gettext("ECC certificates are" + "only supported with the pkcs11 and nss keystores\n")); + rv = PK_ERR_USAGE; + goto end; + } + /* Adjust default keylength for NSS and DSA */ + if (keyAlg == KMF_DSA && kstype == KMF_KEYSTORE_NSS) { + /* NSS only allows for 512-1024 bit DSA keys */ + if (!y_flag) + /* If nothing was given, default to 1024 */ + keylen = 1024; + else if (keylen > 1024 || keylen < 512) { + (void) fprintf(stderr, gettext("NSS keystore only " + "supports DSA keylengths of 512 - 1024 bits\n")); + rv = PK_ERR_USAGE; + goto end; + } + } + + if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) { + if (label == NULL) { + (void) fprintf(stderr, + gettext("No key label specified\n")); + rv = PK_ERR_USAGE; + goto end; + } + if (tokenname == NULL || !strlen(tokenname)) { + if (kstype == KMF_KEYSTORE_NSS) { + tokenname = "internal"; + } else { + tokenname = PK_DEFAULT_PK11TOKEN; + } + } + + (void) get_token_password(kstype, tokenname, &tokencred); + } + + if (kstype == KMF_KEYSTORE_NSS) { + if (dir == NULL) + dir = PK_DEFAULT_DIRECTORY; + + rv = genkeypair_nss(kmfhandle, + tokenname, label, dir, prefix, keyAlg, keylen, + &tokencred, curveoid, NULL, NULL); + + } else if (kstype == KMF_KEYSTORE_PK11TOKEN) { + rv = genkeypair_pkcs11(kmfhandle, + tokenname, label, keyAlg, keylen, + &tokencred, curveoid, NULL, NULL); + + } else if (kstype == KMF_KEYSTORE_OPENSSL) { + rv = genkeypair_file(kmfhandle, keyAlg, keylen, + fmt, outkey, NULL, NULL); + } + + if (rv != KMF_OK) + display_error(kmfhandle, rv, + gettext("Error creating and keypair")); +end: + if (tokencred.cred != NULL) + free(tokencred.cred); + + (void) kmf_finalize(kmfhandle); + return (rv); +} diff --git a/usr/src/cmd/cmd-crypto/pktool/list.c b/usr/src/cmd/cmd-crypto/pktool/list.c index ad20acb868..840b67df32 100644 --- a/usr/src/cmd/cmd-crypto/pktool/list.c +++ b/usr/src/cmd/cmd-crypto/pktool/list.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * This file implements the token object list operation for this tool. * It loads the PKCS#11 modules, finds the object to list, lists it, @@ -126,12 +124,16 @@ describeKey(KMF_KEY_HANDLE *key) return (gettext("RSA public key")); if (key->keyalg == KMF_DSA) return (gettext("DSA public key")); + if (key->keyalg == KMF_ECDSA) + return (gettext("ECDSA public key")); } if (key->keyclass == KMF_ASYM_PRI) { if (key->keyalg == KMF_RSA) - return ("RSA private key"); + return (gettext("RSA private key")); if (key->keyalg == KMF_DSA) - return ("DSA private key"); + return (gettext("DSA private key")); + if (key->keyalg == KMF_ECDSA) + return (gettext("ECDSA private key")); } if (key->keyclass == KMF_SYMMETRIC) { switch (key->keyalg) { @@ -320,7 +322,7 @@ list_pk11_objects(KMF_HANDLE_T kmfhandle, char *token, int oclass, KMF_CREDENTIAL cred = {NULL, 0}; /* - * Symmetric keys and RSA/DSA private keys are always + * Symmetric keys and RSA/DSA/ECDSA private keys are always * created with the "CKA_PRIVATE" field == TRUE, so * make sure we search for them with it also set. */ diff --git a/usr/src/cmd/cmd-crypto/pktool/pktool.c b/usr/src/cmd/cmd-crypto/pktool/pktool.c index 15a906b2a7..c6ddb6a2c4 100644 --- a/usr/src/cmd/cmd-crypto/pktool/pktool.c +++ b/usr/src/cmd/cmd-crypto/pktool/pktool.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -67,6 +67,7 @@ extern int pk_download(int argc, char *argv[]); extern int pk_genkey(int argc, char *argv[]); extern int pk_signcsr(int argc, char *argv[]); extern int pk_inittoken(int argc, char *argv[]); +extern int pk_genkeypair(int argc, char *argv[]); /* Forward declarations for "built-in" verb actions. */ static int pk_help(int argc, char *argv[]); @@ -296,16 +297,20 @@ static int pk_help(int argc, char *argv[]); #define GENCERT_VERB "gencert" #define GENCERT_SUMM gettext("creates a self-signed X.509v3 certificate") #define GENCERT_SYN \ + "gencert listcurves\n\t" \ +\ "gencert keystore=nss\n\t\t" \ "label=cert-nickname\n\t\t" \ - "serial=serial number hex string]\n\t\t" \ + "serial=serial number hex string\n\t\t" \ "[ -i ] | [subject=subject-DN]\n\t\t" \ "[ altname=[critical:]SubjectAltName ]\n\t\t" \ "[ keyusage=[critical:]usage,usage,...]\n\t\t" \ "[ token=token[:manuf[:serial]]]\n\t\t" \ "[ dir=directory-path ]\n\t\t" \ "[ prefix=DBprefix ]\n\t\t" \ - "[ keytype=rsa|dsa ]\n\t\t" \ + "[ keytype=rsa | ec [curve=ECC Curve Name] " \ + "[hash=md5 | sha1 | sha256 | sha384 | sha512]]\n\t\t" \ + "[ keytype=dsa [hash=sha1]]\n\t\t" \ "[ keylen=key-size ]\n\t\t" \ "[ trust=trust-value ]\n\t\t" \ "[ eku=[critical:]EKU name,...]\n\t\t" \ @@ -318,7 +323,9 @@ static int pk_help(int argc, char *argv[]); "[ altname=[critical:]SubjectAltName ]\n\t\t" \ "[ keyusage=[critical:]usage,usage,...]\n\t\t" \ "[ token=token[:manuf[:serial]]]\n\t\t" \ - "[ keytype=rsa|dsa ]\n\t\t" \ + "[ keytype=rsa | ec [curve=ECC Curve Name] " \ + "[hash=md5 | sha1 | sha256 | sha384 | sha512]]\n\t\t" \ + "[ keytype=dsa [hash=sha1 | sha256 ]]\n\t\t" \ "[ keylen=key-size ]\n\t\t" \ "[ eku=[critical:]EKU name,...]\n\t\t" \ "[ lifetime=number-hour|number-day|number-year ]\n\t" \ @@ -331,8 +338,8 @@ static int pk_help(int argc, char *argv[]); "[ altname=[critical:]SubjectAltName ]\n\t\t" \ "[ keyusage=[critical:]usage,usage,...]\n\t\t" \ "[ format=der|pem ]\n\t\t" \ - "[ prefix=DBprefix ]\n\t\t" \ - "[ keytype=rsa|dsa ]\n\t\t" \ + "[ keytype=rsa [hash=md5 | sha1 | sha256 | sha384 | sha512]]\n\t\t" \ + "[ keytype=dsa [hash=sha1 | sha256 ]]\n\t\t" \ "[ keylen=key-size ]\n\t\t" \ "[ eku=[critical:]EKU name,...]\n\t\t" \ "[ lifetime=number-hour|number-day|number-year ]\n\t" @@ -343,6 +350,8 @@ static int pk_help(int argc, char *argv[]); "request file") #define GENCSR_SYN \ + "gencsr listcurves\n\t" \ +\ "gencsr keystore=nss \n\t\t" \ "nickname=cert-nickname\n\t\t" \ "outcsr=csr-fn\n\t\t" \ @@ -352,7 +361,9 @@ static int pk_help(int argc, char *argv[]); "[ token=token[:manuf[:serial]]]\n\t\t" \ "[ dir=directory-path ]\n\t\t" \ "[ prefix=DBprefix ]\n\t\t" \ - "[ keytype=rsa|dsa ]\n\t\t" \ + "[ keytype=rsa | ec [curve=ECC Curve Name] " \ + "[hash=md5 | sha1 | sha256 | sha384 | sha512]]\n\t\t" \ + "[ keytype=dsa [hash=sha1]]\n\t\t" \ "[ keylen=key-size ]\n\t\t" \ "[ eku=[critical:]EKU name,...]\n\t\t" \ "[ format=pem|der ]\n\t" \ @@ -364,7 +375,9 @@ static int pk_help(int argc, char *argv[]); "[ altname=[critical:]SubjectAltName ]\n\t\t" \ "[ keyusage=[critical:]usage,usage,...]\n\t\t" \ "[ token=token[:manuf[:serial]]]\n\t\t" \ - "[ keytype=rsa|dsa ]\n\t\t" \ + "[ keytype=rsa | ec [curve=ECC Curve Name] " \ + "[hash=md5 | sha1 | sha256 | sha384 | sha512]]\n\t\t" \ + "[ keytype=dsa [hash=sha1 | sha256 ]]\n\t\t" \ "[ keylen=key-size ]\n\t\t" \ "[ eku=[critical:]EKU name,...]\n\t\t" \ "[ format=pem|der ]]\n\t" \ @@ -375,7 +388,8 @@ static int pk_help(int argc, char *argv[]); "[ -i ] | [subject=subject-DN]\n\t\t" \ "[ altname=[critical:]SubjectAltName ]\n\t\t" \ "[ keyusage=[critical:]usage,usage,...]\n\t\t" \ - "[ keytype=rsa|dsa ]\n\t\t" \ + "[ keytype=rsa [hash=md5 | sha1 | sha256 | sha384 | sha512]]\n\t\t" \ + "[ keytype=dsa [hash=sha1 | sha256 ]]\n\t\t" \ "[ keylen=key-size ]\n\t\t" \ "[ eku=[critical:]EKU name,...]\n\t\t" \ "[ format=pem|der ]\n\t" @@ -476,7 +490,33 @@ static int pk_help(int argc, char *argv[]); "[ currlabel=token[:manuf[:serial]]]\n\t\t" \ "[ newlabel=new token label ]\n\t" -#define HELP_IDX 12 +#define GENKEYPAIR_IDX 12 +#define GENKEYPAIR_VERB "genkeypair" +#define GENKEYPAIR_SUMM gettext("creates an asymmetric keypair") +#define GENKEYPAIR_SYN \ + "genkeypair listcurves\n\t" \ +\ + "genkeypair keystore=nss\n\t\t" \ + "label=key-nickname\n\t\t" \ + "[ token=token[:manuf[:serial]]]\n\t\t" \ + "[ dir=directory-path ]\n\t\t" \ + "[ prefix=DBprefix ]\n\t\t" \ + "[ keytype=rsa | dsa | ec [curve=ECC Curve Name]]\n\t\t" \ + "[ keylen=key-size ]\n\t" \ + \ + "genkeypair [ keystore=pkcs11 ]\n\t\t" \ + "label=key-label\n\t\t" \ + "[ token=token[:manuf[:serial]]]\n\t\t" \ + "[ keytype=rsa | dsa | ec [curve=ECC Curve Name]]\n\t\t" \ + "[ keylen=key-size ]\n\t" \ + \ + "genkeypair keystore=file\n\t\t" \ + "outkey=key_filename\n\t\t" \ + "[ format=der|pem ]\n\t\t" \ + "[ keytype=rsa|dsa ]\n\t\t" \ + "[ keylen=key-size ]\n\t" + +#define HELP_IDX 13 #define HELP_VERB "help" #define HELP_SUMM gettext("displays help message") #define HELP_SYN "help\t(help and usage)" @@ -495,6 +535,7 @@ static verbcmd cmds[] = { { NULL, pk_genkey, 0, NULL, NULL}, { NULL, pk_signcsr, 0, NULL, NULL}, { NULL, pk_inittoken, 0, NULL, NULL}, + { NULL, pk_genkeypair, 0, NULL, NULL}, { NULL, pk_help, 0, NULL, NULL} }; @@ -554,6 +595,10 @@ init_command_list() cmds[INITTOKEN_IDX].summary = INITTOKEN_SUMM; cmds[INITTOKEN_IDX].synopsis = INITTOKEN_SYN; + cmds[GENKEYPAIR_IDX].verb = GENKEYPAIR_VERB; + cmds[GENKEYPAIR_IDX].summary = GENKEYPAIR_SUMM; + cmds[GENKEYPAIR_IDX].synopsis = GENKEYPAIR_SYN; + cmds[HELP_IDX].verb = HELP_VERB; cmds[HELP_IDX].summary = HELP_SUMM; cmds[HELP_IDX].synopsis = HELP_SYN; diff --git a/usr/src/cmd/cmd-crypto/pktool/signcsr.c b/usr/src/cmd/cmd-crypto/pktool/signcsr.c index df85d3ec84..87c04662a9 100644 --- a/usr/src/cmd/cmd-crypto/pktool/signcsr.c +++ b/usr/src/cmd/cmd-crypto/pktool/signcsr.c @@ -19,7 +19,7 @@ * CDDL HEADER END * * - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -268,6 +268,9 @@ pk_signcsr_files(KMF_HANDLE_T handle, KMF_DATA certdata = {NULL, 0}; int numattr, count; + (void) memset(&cakey, 0, sizeof (cakey)); + (void) memset(&signedCert, 0, sizeof (signedCert)); + rv = read_csrdata(handle, csrfile, &csrdata); if (rv != KMF_OK) { cryptoerror(LOG_STDERR, @@ -370,6 +373,7 @@ pk_signcsr_pk11_nss(KMF_HANDLE_T handle, boolean_t private_bool = B_TRUE; (void) memset(&casignkey, 0, sizeof (KMF_KEY_HANDLE)); + (void) memset(&signedCert, 0, sizeof (signedCert)); rv = read_csrdata(handle, csrfile, &csrdata); if (rv != KMF_OK) { |