diff options
author | wyllys <none@none> | 2006-11-10 15:34:56 -0800 |
---|---|---|
committer | wyllys <none@none> | 2006-11-10 15:34:56 -0800 |
commit | 99ebb4ca412cb0a19d77a3899a87c055b9c30fa8 (patch) | |
tree | a972f78468519a4e00234388688f45a506e934ba /usr/src/cmd/cmd-crypto/pktool/gencert.c | |
parent | 177fd15c9f814babb60e824f89984cdd8acf7c85 (diff) | |
download | illumos-joyent-99ebb4ca412cb0a19d77a3899a87c055b9c30fa8.tar.gz |
PSARC 2005/074 Solaris Key Management Framework
6224192 Solaris needs unified key management interfaces
--HG--
rename : usr/src/cmd/cmd-crypto/pktool/biginteger.h => deleted_files/usr/src/cmd/cmd-crypto/pktool/biginteger.h
rename : usr/src/cmd/cmd-crypto/pktool/derparse.c => deleted_files/usr/src/cmd/cmd-crypto/pktool/derparse.c
rename : usr/src/cmd/cmd-crypto/pktool/derparse.h => deleted_files/usr/src/cmd/cmd-crypto/pktool/derparse.h
rename : usr/src/cmd/cmd-crypto/pktool/osslcommon.c => deleted_files/usr/src/cmd/cmd-crypto/pktool/osslcommon.c
rename : usr/src/cmd/cmd-crypto/pktool/osslcommon.h => deleted_files/usr/src/cmd/cmd-crypto/pktool/osslcommon.h
rename : usr/src/cmd/cmd-crypto/pktool/p12common.c => deleted_files/usr/src/cmd/cmd-crypto/pktool/p12common.c
rename : usr/src/cmd/cmd-crypto/pktool/p12common.h => deleted_files/usr/src/cmd/cmd-crypto/pktool/p12common.h
Diffstat (limited to 'usr/src/cmd/cmd-crypto/pktool/gencert.c')
-rw-r--r-- | usr/src/cmd/cmd-crypto/pktool/gencert.c | 729 |
1 files changed, 729 insertions, 0 deletions
diff --git a/usr/src/cmd/cmd-crypto/pktool/gencert.c b/usr/src/cmd/cmd-crypto/pktool/gencert.c new file mode 100644 index 0000000000..ae79c579a4 --- /dev/null +++ b/usr/src/cmd/cmd-crypto/pktool/gencert.c @@ -0,0 +1,729 @@ +/* + * 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 <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; \ + } + +static int +gencert_pkcs11(KMF_HANDLE_T kmfhandle, + char *token, char *subject, char *altname, + KMF_GENERALNAMECHOICES alttype, int altcrit, + char *certlabel, KMF_KEY_ALG keyAlg, + KMF_ALGORITHM_INDEX sigAlg, + int keylen, uint32_t ltime, KMF_BIGINT *serial, + uint16_t kubits, int kucrit, KMF_CREDENTIAL *tokencred) +{ + KMF_RETURN kmfrv = KMF_OK; + KMF_CREATEKEYPAIR_PARAMS kp_params; + KMF_STORECERT_PARAMS sc_params; + KMF_KEY_HANDLE pubk, prik; + KMF_X509_CERTIFICATE signedCert; + KMF_X509_NAME certSubject; + KMF_X509_NAME certIssuer; + KMF_DATA x509DER; + + (void) memset(&signedCert, 0, sizeof (signedCert)); + (void) memset(&certSubject, 0, sizeof (certSubject)); + (void) memset(&certIssuer, 0, sizeof (certIssuer)); + (void) memset(&x509DER, 0, sizeof (x509DER)); + (void) memset(&kp_params, 0, sizeof (kp_params)); + + /* If the subject name cannot be parsed, flag it now and exit */ + if (KMF_DNParser(subject, &certSubject) != KMF_OK) { + cryptoerror(LOG_STDERR, + gettext("Subject name cannot be parsed.\n")); + return (PK_ERR_USAGE); + } + + /* For a self-signed cert, the issuser and subject are the same */ + if (KMF_DNParser(subject, &certIssuer) != KMF_OK) { + cryptoerror(LOG_STDERR, + gettext("Subject name cannot be parsed.\n")); + return (PK_ERR_USAGE); + } + + kp_params.kstype = KMF_KEYSTORE_PK11TOKEN; + kp_params.keylabel = certlabel; + kp_params.keylength = keylen; /* bits */ + kp_params.keytype = keyAlg; + kp_params.cred.cred = tokencred->cred; + kp_params.cred.credlen = tokencred->credlen; + + /* Select a PKCS11 token */ + kmfrv = select_token(kmfhandle, token, FALSE); + + if (kmfrv != KMF_OK) { + return (kmfrv); + } + + kmfrv = KMF_CreateKeypair(kmfhandle, &kp_params, &prik, &pubk); + if (kmfrv != KMF_OK) { + return (kmfrv); + } + + SET_VALUE(KMF_SetCertPubKey(kmfhandle, &pubk, &signedCert), + "keypair"); + + SET_VALUE(KMF_SetCertVersion(&signedCert, 2), "version number"); + + SET_VALUE(KMF_SetCertSerialNumber(&signedCert, serial), + "serial number"); + + SET_VALUE(KMF_SetCertValidityTimes(&signedCert, NULL, ltime), + "validity time"); + + SET_VALUE(KMF_SetCertSignatureAlgorithm(&signedCert, sigAlg), + "signature algorithm"); + + SET_VALUE(KMF_SetCertSubjectName(&signedCert, &certSubject), + "subject name"); + + SET_VALUE(KMF_SetCertIssuerName(&signedCert, &certIssuer), + "issuer name"); + + if (altname != NULL) + SET_VALUE(KMF_SetCertSubjectAltName(&signedCert, altcrit, + alttype, altname), "subjectAltName"); + + if (kubits != 0) + SET_VALUE(KMF_SetCertKeyUsage(&signedCert, kucrit, kubits), + "KeyUsage"); + + if ((kmfrv = KMF_SignCertRecord(kmfhandle, &prik, + &signedCert, &x509DER)) != KMF_OK) { + goto cleanup; + } + + (void) memset(&sc_params, 0, sizeof (sc_params)); + sc_params.kstype = KMF_KEYSTORE_PK11TOKEN; + sc_params.certLabel = certlabel; + + /* + * Store the cert in the DB. + */ + kmfrv = KMF_StoreCert(kmfhandle, &sc_params, &x509DER); + +cleanup: + KMF_FreeData(&x509DER); + KMF_FreeDN(&certSubject); + KMF_FreeDN(&certIssuer); + return (kmfrv); +} + +static int +gencert_file(KMF_HANDLE_T kmfhandle, + KMF_KEY_ALG keyAlg, KMF_ALGORITHM_INDEX sigAlg, + int keylen, KMF_ENCODE_FORMAT fmt, + uint32_t ltime, char *subject, char *altname, + KMF_GENERALNAMECHOICES alttype, int altcrit, + KMF_BIGINT *serial, uint16_t kubits, int kucrit, + char *dir, char *outcert, char *outkey) +{ + KMF_RETURN kmfrv; + KMF_CREATEKEYPAIR_PARAMS kp_params; + KMF_STORECERT_PARAMS sc_params; + KMF_KEY_HANDLE pubk, prik; + KMF_X509_CERTIFICATE signedCert; + KMF_X509_NAME certSubject; + KMF_X509_NAME certIssuer; + KMF_DATA x509DER; + char *fullcertpath = NULL; + char *fullkeypath = NULL; + + (void) memset(&signedCert, 0, sizeof (signedCert)); + (void) memset(&certSubject, 0, sizeof (certSubject)); + (void) memset(&certIssuer, 0, sizeof (certIssuer)); + (void) memset(&x509DER, 0, sizeof (x509DER)); + (void) memset(&kp_params, 0, sizeof (kp_params)); + (void) memset(&sc_params, 0, sizeof (sc_params)); + + if (EMPTYSTRING(outcert) || EMPTYSTRING(outkey)) { + cryptoerror(LOG_STDERR, + gettext("No output file was specified for " + "the cert or key\n")); + return (PK_ERR_USAGE); + } + if (dir != NULL) { + fullcertpath = get_fullpath(dir, outcert); + if (fullcertpath == NULL) { + cryptoerror(LOG_STDERR, + gettext("Cannot create file %s in " + "directory %s\n"), dir, outcert); + return (PK_ERR_USAGE); + } + } else { + fullcertpath = strdup(outcert); + } + if (verify_file(fullcertpath)) { + cryptoerror(LOG_STDERR, + gettext("Cannot write the indicated output " + "certificate file (%s).\n"), + fullcertpath); + free(fullcertpath); + return (PK_ERR_USAGE); + } + if (dir != NULL) { + fullkeypath = get_fullpath(dir, outkey); + if (fullkeypath == NULL) { + cryptoerror(LOG_STDERR, + gettext("Cannot create file %s in " + "directory %s\n"), dir, outkey); + free(fullcertpath); + return (PK_ERR_USAGE); + } + } else { + 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_DNParser(subject, &certSubject) != KMF_OK) { + cryptoerror(LOG_STDERR, + gettext("Subject name cannot be parsed (%s)\n"), + subject); + return (PK_ERR_USAGE); + } + + /* For a self-signed cert, the issuser and subject are the same */ + if (KMF_DNParser(subject, &certIssuer) != KMF_OK) { + cryptoerror(LOG_STDERR, + gettext("Subject name cannot be parsed (%s)\n"), + subject); + KMF_FreeDN(&certSubject); + return (PK_ERR_USAGE); + } + + kp_params.kstype = KMF_KEYSTORE_OPENSSL; + kp_params.keylength = keylen; /* bits */ + kp_params.keytype = keyAlg; + + kp_params.sslparms.keyfile = fullkeypath; + kp_params.sslparms.format = fmt; + + kmfrv = KMF_CreateKeypair(kmfhandle, &kp_params, &prik, &pubk); + if (kmfrv != KMF_OK) { + goto cleanup; + } + SET_VALUE(KMF_SetCertPubKey(kmfhandle, &pubk, &signedCert), + "keypair"); + + SET_VALUE(KMF_SetCertVersion(&signedCert, 2), "version number"); + + SET_VALUE(KMF_SetCertSerialNumber(&signedCert, serial), + "serial number"); + + SET_VALUE(KMF_SetCertValidityTimes(&signedCert, NULL, ltime), + "validity time"); + + SET_VALUE(KMF_SetCertSignatureAlgorithm(&signedCert, sigAlg), + "signature algorithm"); + + SET_VALUE(KMF_SetCertSubjectName(&signedCert, &certSubject), + "subject name"); + + SET_VALUE(KMF_SetCertIssuerName(&signedCert, &certIssuer), + "issuer name"); + + if (altname != NULL) + SET_VALUE(KMF_SetCertSubjectAltName(&signedCert, altcrit, + alttype, altname), "subjectAltName"); + + if (kubits != 0) + SET_VALUE(KMF_SetCertKeyUsage(&signedCert, kucrit, kubits), + "KeyUsage"); + + if ((kmfrv = KMF_SignCertRecord(kmfhandle, &prik, + &signedCert, &x509DER)) != KMF_OK) { + goto cleanup; + } + + sc_params.kstype = KMF_KEYSTORE_OPENSSL; + sc_params.sslparms.certfile = fullcertpath; + sc_params.sslparms.keyfile = fullkeypath; + sc_params.sslparms.format = fmt; + /* + * Store the cert in the DB. + */ + kmfrv = KMF_StoreCert(kmfhandle, &sc_params, &x509DER); + +cleanup: + if (fullkeypath != NULL) + free(fullkeypath); + if (fullcertpath != NULL) + free(fullcertpath); + + KMF_FreeData(&x509DER); + KMF_FreeDN(&certSubject); + KMF_FreeDN(&certIssuer); + return (kmfrv); +} + +static KMF_RETURN +gencert_nss(KMF_HANDLE_T kmfhandle, + char *token, char *subject, char *altname, + KMF_GENERALNAMECHOICES alttype, int altcrit, + char *nickname, char *dir, char *prefix, + KMF_KEY_ALG keyAlg, + KMF_ALGORITHM_INDEX sigAlg, + int keylen, char *trust, + uint32_t ltime, KMF_BIGINT *serial, uint16_t kubits, + int kucrit, KMF_CREDENTIAL *tokencred) +{ + KMF_RETURN kmfrv; + KMF_CREATEKEYPAIR_PARAMS kp_params; + KMF_STORECERT_PARAMS sc_params; + KMF_KEY_HANDLE pubk, prik; + KMF_X509_CERTIFICATE signedCert; + KMF_X509_NAME certSubject; + KMF_X509_NAME certIssuer; + KMF_DATA x509DER; + + if (token == NULL) + token = DEFAULT_NSS_TOKEN; + + kmfrv = configure_nss(kmfhandle, dir, prefix); + if (kmfrv != KMF_OK) + return (kmfrv); + + (void) memset(&signedCert, 0, sizeof (signedCert)); + (void) memset(&certSubject, 0, sizeof (certSubject)); + (void) memset(&certIssuer, 0, sizeof (certIssuer)); + (void) memset(&x509DER, 0, sizeof (x509DER)); + + /* If the subject name cannot be parsed, flag it now and exit */ + if (KMF_DNParser(subject, &certSubject) != KMF_OK) { + cryptoerror(LOG_STDERR, + gettext("Subject name cannot be parsed.\n")); + return (PK_ERR_USAGE); + } + + /* For a self-signed cert, the issuser and subject are the same */ + if (KMF_DNParser(subject, &certIssuer) != KMF_OK) { + cryptoerror(LOG_STDERR, + gettext("Subject name cannot be parsed.\n")); + return (PK_ERR_USAGE); + } + + (void) memset(&kp_params, 0, sizeof (kp_params)); + + kp_params.kstype = KMF_KEYSTORE_NSS; + kp_params.keylabel = nickname; + kp_params.keylength = keylen; /* bits */ + kp_params.keytype = keyAlg; + kp_params.cred.cred = tokencred->cred; + kp_params.cred.credlen = tokencred->credlen; + kp_params.nssparms.slotlabel = token; + + kmfrv = KMF_CreateKeypair(kmfhandle, &kp_params, &prik, &pubk); + if (kmfrv != KMF_OK) { + return (kmfrv); + } + + SET_VALUE(KMF_SetCertPubKey(kmfhandle, &pubk, &signedCert), + "keypair"); + + SET_VALUE(KMF_SetCertVersion(&signedCert, 2), "version number"); + + SET_VALUE(KMF_SetCertSerialNumber(&signedCert, serial), + "serial number"); + + SET_VALUE(KMF_SetCertValidityTimes(&signedCert, NULL, ltime), + "validity time"); + + SET_VALUE(KMF_SetCertSignatureAlgorithm(&signedCert, sigAlg), + "signature algorithm"); + + SET_VALUE(KMF_SetCertSubjectName(&signedCert, &certSubject), + "subject name"); + + SET_VALUE(KMF_SetCertIssuerName(&signedCert, &certIssuer), + "issuer name"); + + if (altname != NULL) + SET_VALUE(KMF_SetCertSubjectAltName(&signedCert, altcrit, + alttype, altname), "subjectAltName"); + + if (kubits) + SET_VALUE(KMF_SetCertKeyUsage(&signedCert, kucrit, kubits), + "subjectAltName"); + + if ((kmfrv = KMF_SignCertRecord(kmfhandle, &prik, + &signedCert, &x509DER)) != KMF_OK) { + goto cleanup; + } + + sc_params.kstype = KMF_KEYSTORE_NSS; + sc_params.certLabel = nickname; + sc_params.nssparms.trustflag = trust; + sc_params.nssparms.slotlabel = token; + + /* + * Store the cert in the DB. + */ + kmfrv = KMF_StoreCert(kmfhandle, &sc_params, &x509DER); + +cleanup: + KMF_FreeData(&x509DER); + KMF_FreeDN(&certSubject); + KMF_FreeDN(&certIssuer); + return (kmfrv); +} + +int +pk_gencert(int argc, char *argv[]) +{ + int rv; + int opt; + extern int optind_av; + extern char *optarg_av; + KMF_KEYSTORE_TYPE kstype = 0; + char *subject = NULL; + char *tokenname = NULL; + char *dir = NULL; + char *prefix = NULL; + char *keytype = PK_DEFAULT_KEYTYPE; + int keylen = PK_DEFAULT_KEYLENGTH; + char *trust = NULL; + char *lifetime = NULL; + char *certlabel = NULL; + char *outcert = NULL; + char *outkey = NULL; + char *format = NULL; + char *serstr = NULL; + char *altname = NULL; + char *keyusagestr = NULL; + KMF_GENERALNAMECHOICES alttype = 0; + KMF_BIGINT serial = { NULL, 0 }; + uint32_t ltime; + KMF_HANDLE_T kmfhandle = NULL; + KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1; + KMF_KEY_ALG keyAlg = KMF_RSA; + KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_MD5WithRSA; + boolean_t interactive = B_FALSE; + char *subname = NULL; + KMF_CREDENTIAL tokencred = {NULL, 0}; + uint16_t kubits = 0; + int altcrit = 0, kucrit = 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)" + "K:(outkey)S:(serial)F:(format)u:(keyusage)")) != EOF) { + + if (opt != 'i' && EMPTYSTRING(optarg_av)) + return (PK_ERR_USAGE); + + switch (opt) { + case 'A': + altname = optarg_av; + break; + case 'i': + if (interactive || subject) + return (PK_ERR_USAGE); + else + interactive = B_TRUE; + break; + case 'k': + kstype = KS2Int(optarg_av); + if (kstype == 0) + return (PK_ERR_USAGE); + break; + case 's': + if (interactive || subject) + return (PK_ERR_USAGE); + else + subject = optarg_av; + break; + case 'l': + case 'n': + if (certlabel) + return (PK_ERR_USAGE); + certlabel = 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 'u': + keyusagestr = 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); + } + break; + case 'r': + if (trust) + return (PK_ERR_USAGE); + trust = optarg_av; + break; + case 'L': + if (lifetime) + return (PK_ERR_USAGE); + lifetime = optarg_av; + break; + case 'c': + if (outcert) + return (PK_ERR_USAGE); + outcert = optarg_av; + break; + case 'K': + if (outkey) + return (PK_ERR_USAGE); + outkey = optarg_av; + break; + case 'S': + serstr = optarg_av; + break; + case 'F': + if (format) + return (PK_ERR_USAGE); + format = optarg_av; + break; + 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; + + if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) && + EMPTYSTRING(certlabel)) { + cryptoerror(LOG_STDERR, gettext("A label must be specified " + "to create a self-signed certificate.\n")); + return (PK_ERR_USAGE); + } else if (kstype == KMF_KEYSTORE_OPENSSL && EMPTYSTRING(outcert)) { + cryptoerror(LOG_STDERR, gettext("A certificate filename must " + "be specified to create a self-signed certificate.\n")); + return (PK_ERR_USAGE); + } + + if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) { + cryptoerror(LOG_STDERR, + gettext("Error parsing format string (%s).\n"), + format); + return (PK_ERR_USAGE); + } + + if (Str2Lifetime(lifetime, <ime) != 0) { + cryptoerror(LOG_STDERR, + gettext("Error parsing lifetime string\n")); + return (PK_ERR_USAGE); + } + + if (Str2KeyType(keytype, &keyAlg, &sigAlg) != 0) { + cryptoerror(LOG_STDERR, gettext("Unrecognized keytype (%s).\n"), + keytype); + return (PK_ERR_USAGE); + } + + + /* + * Check the subject name. + * If interactive is true, get it now interactively. + */ + if (interactive) { + if (get_subname(&subname) != KMF_OK) { + cryptoerror(LOG_STDERR, gettext("Failed to get the " + "subject name interactively.\n")); + return (PK_ERR_USAGE); + } + } else { + if (EMPTYSTRING(subject)) { + cryptoerror(LOG_STDERR, gettext("A subject name or " + "-i must be specified to create a self-signed " + "certificate.\n")); + return (PK_ERR_USAGE); + } else { + subname = strdup(subject); + if (subname == NULL) { + cryptoerror(LOG_STDERR, + gettext("Out of memory.\n")); + return (PK_ERR_SYSTEM); + } + } + } + + if (serstr == NULL) { + (void) fprintf(stderr, gettext("A serial number " + "must be specified as a hex number when creating" + " a self-signed certificate " + "(ex: serno=0x0102030405feedface)\n")); + rv = PK_ERR_USAGE; + goto end; + } else { + uchar_t *bytes = NULL; + size_t bytelen; + + rv = KMF_HexString2Bytes((uchar_t *)serstr, &bytes, &bytelen); + if (rv != KMF_OK || bytes == NULL) { + (void) fprintf(stderr, gettext("serial number " + "must be specified as a hex number " + "(ex: 0x0102030405ffeeddee)\n")); + rv = PK_ERR_USAGE; + goto end; + } + serial.val = bytes; + serial.len = bytelen; + } + + if (altname != NULL) { + rv = verify_altname(altname, &alttype, &altcrit); + if (rv != KMF_OK) { + (void) fprintf(stderr, gettext("Subject AltName " + "must be specified as a name=value pair. " + "See the man page for details.\n")); + rv = PK_ERR_USAGE; + goto end; + } else { + /* advance the altname past the '=' sign */ + char *p = strchr(altname, '='); + if (p != NULL) + altname = p + 1; + } + } + + if (keyusagestr != NULL) { + rv = verify_keyusage(keyusagestr, &kubits, &kucrit); + if (rv != KMF_OK) { + (void) fprintf(stderr, gettext("KeyUsage " + "must be specified as a comma-separated list. " + "See the man page for details.\n")); + rv = PK_ERR_USAGE; + goto end; + } + } + + if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) { + 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 = gencert_nss(kmfhandle, + tokenname, subname, altname, alttype, altcrit, + certlabel, dir, prefix, keyAlg, sigAlg, keylen, + trust, ltime, &serial, kubits, kucrit, &tokencred); + + } else if (kstype == KMF_KEYSTORE_PK11TOKEN) { + rv = gencert_pkcs11(kmfhandle, + tokenname, subname, altname, alttype, altcrit, + certlabel, keyAlg, sigAlg, keylen, ltime, + &serial, kubits, kucrit, &tokencred); + + } else if (kstype == KMF_KEYSTORE_OPENSSL) { + rv = gencert_file(kmfhandle, + keyAlg, sigAlg, keylen, fmt, + ltime, subname, altname, alttype, altcrit, + &serial, kubits, kucrit, dir, outcert, outkey); + } + + if (rv != KMF_OK) + display_error(kmfhandle, rv, + gettext("Error creating certificate and keypair")); +end: + if (subname) + free(subname); + if (tokencred.cred != NULL) + free(tokencred.cred); + + if (serial.val != NULL) + free(serial.val); + + (void) KMF_Finalize(kmfhandle); + return (rv); +} |