199ebb4caSwyllys /* 299ebb4caSwyllys * CDDL HEADER START 399ebb4caSwyllys * 499ebb4caSwyllys * The contents of this file are subject to the terms of the 599ebb4caSwyllys * Common Development and Distribution License (the "License"). 699ebb4caSwyllys * You may not use this file except in compliance with the License. 799ebb4caSwyllys * 899ebb4caSwyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 999ebb4caSwyllys * or http://www.opensolaris.org/os/licensing. 1099ebb4caSwyllys * See the License for the specific language governing permissions 1199ebb4caSwyllys * and limitations under the License. 1299ebb4caSwyllys * 1399ebb4caSwyllys * When distributing Covered Code, include this CDDL HEADER in each 1499ebb4caSwyllys * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1599ebb4caSwyllys * If applicable, add the following below this CDDL HEADER, with the 1699ebb4caSwyllys * fields enclosed by brackets "[]" replaced with your own identifying 1799ebb4caSwyllys * information: Portions Copyright [yyyy] [name of copyright owner] 1899ebb4caSwyllys * 1999ebb4caSwyllys * CDDL HEADER END 2099ebb4caSwyllys * 2199ebb4caSwyllys * 22a44b45c8SHuie-Ying Lee * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 2399ebb4caSwyllys * Use is subject to license terms. 2499ebb4caSwyllys */ 2599ebb4caSwyllys 2699ebb4caSwyllys #include <stdio.h> 2799ebb4caSwyllys #include <string.h> 2899ebb4caSwyllys #include <ctype.h> 2999ebb4caSwyllys #include <malloc.h> 3099ebb4caSwyllys #include <libgen.h> 3199ebb4caSwyllys #include <errno.h> 3299ebb4caSwyllys #include <cryptoutil.h> 3399ebb4caSwyllys #include <security/cryptoki.h> 3499ebb4caSwyllys #include "common.h" 3599ebb4caSwyllys 3699ebb4caSwyllys #include <kmfapi.h> 3799ebb4caSwyllys 3899ebb4caSwyllys #define SET_VALUE(f, s) \ 3999ebb4caSwyllys kmfrv = f; \ 4099ebb4caSwyllys if (kmfrv != KMF_OK) { \ 4199ebb4caSwyllys cryptoerror(LOG_STDERR, \ 4299ebb4caSwyllys gettext("Failed to %s: 0x%02\n"), \ 4399ebb4caSwyllys s, kmfrv); \ 4499ebb4caSwyllys goto cleanup; \ 4599ebb4caSwyllys } 4699ebb4caSwyllys 4799ebb4caSwyllys static KMF_RETURN 4899ebb4caSwyllys gencsr_pkcs11(KMF_HANDLE_T kmfhandle, 4999ebb4caSwyllys char *token, char *subject, char *altname, 5099ebb4caSwyllys KMF_GENERALNAMECHOICES alttype, int altcrit, 5199ebb4caSwyllys char *certlabel, KMF_KEY_ALG keyAlg, 52d00756ccSwyllys int keylen, uint16_t kubits, int kucrit, 5399ebb4caSwyllys KMF_ENCODE_FORMAT fmt, char *csrfile, 54d00756ccSwyllys KMF_CREDENTIAL *tokencred, EKU_LIST *ekulist) 5599ebb4caSwyllys { 5699ebb4caSwyllys KMF_RETURN kmfrv = KMF_OK; 5799ebb4caSwyllys KMF_KEY_HANDLE pubk, prik; 5899ebb4caSwyllys KMF_X509_NAME csrSubject; 5999ebb4caSwyllys KMF_CSR_DATA csr; 6099ebb4caSwyllys KMF_ALGORITHM_INDEX sigAlg; 6199ebb4caSwyllys KMF_DATA signedCsr = {NULL, 0}; 6299ebb4caSwyllys 6330a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 6430a5e8faSwyllys int numattr = 0; 6530a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 6630a5e8faSwyllys boolean_t storekey = TRUE; 6730a5e8faSwyllys 6899ebb4caSwyllys (void) memset(&csr, 0, sizeof (csr)); 6999ebb4caSwyllys (void) memset(&csrSubject, 0, sizeof (csrSubject)); 7099ebb4caSwyllys 7199ebb4caSwyllys if (keyAlg == KMF_DSA) 7299ebb4caSwyllys sigAlg = KMF_ALGID_SHA1WithDSA; 7399ebb4caSwyllys else 74*4165f465SWyllys Ingersoll sigAlg = KMF_ALGID_SHA1WithRSA; 7599ebb4caSwyllys 7699ebb4caSwyllys 7799ebb4caSwyllys /* If the subject name cannot be parsed, flag it now and exit */ 7830a5e8faSwyllys if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) { 7999ebb4caSwyllys return (kmfrv); 8099ebb4caSwyllys } 8199ebb4caSwyllys 8299ebb4caSwyllys /* Select a PKCS11 token */ 8399ebb4caSwyllys kmfrv = select_token(kmfhandle, token, FALSE); 8499ebb4caSwyllys if (kmfrv != KMF_OK) { 8599ebb4caSwyllys return (kmfrv); 8699ebb4caSwyllys } 8799ebb4caSwyllys 8830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 8930a5e8faSwyllys &kstype, sizeof (kstype)); 9030a5e8faSwyllys numattr++; 9130a5e8faSwyllys 9230a5e8faSwyllys if (certlabel != NULL && strlen(certlabel)) { 9330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, 9430a5e8faSwyllys certlabel, strlen(certlabel)); 9530a5e8faSwyllys numattr++; 9630a5e8faSwyllys } 9730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLENGTH_ATTR, 9830a5e8faSwyllys &keylen, sizeof (keylen)); 9930a5e8faSwyllys numattr++; 10030a5e8faSwyllys 10130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYALG_ATTR, 10230a5e8faSwyllys &keyAlg, sizeof (keyAlg)); 10330a5e8faSwyllys numattr++; 10430a5e8faSwyllys 10530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, 10630a5e8faSwyllys tokencred, sizeof (KMF_CREDENTIAL)); 10730a5e8faSwyllys numattr++; 10830a5e8faSwyllys 10930a5e8faSwyllys if (token && strlen(token)) { 11030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, 11130a5e8faSwyllys token, strlen(token)); 11230a5e8faSwyllys numattr++; 11330a5e8faSwyllys } 11430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR, 11530a5e8faSwyllys &pubk, sizeof (KMF_KEY_HANDLE)); 11630a5e8faSwyllys numattr++; 11730a5e8faSwyllys 11830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVKEY_HANDLE_ATTR, 11930a5e8faSwyllys &prik, sizeof (KMF_KEY_HANDLE)); 12030a5e8faSwyllys numattr++; 12130a5e8faSwyllys 12230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_STOREKEY_BOOL_ATTR, 12330a5e8faSwyllys &storekey, sizeof (storekey)); 12430a5e8faSwyllys numattr++; 12530a5e8faSwyllys 12630a5e8faSwyllys kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); 12799ebb4caSwyllys if (kmfrv != KMF_OK) { 12899ebb4caSwyllys return (kmfrv); 12999ebb4caSwyllys } 13099ebb4caSwyllys 13130a5e8faSwyllys SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr), "keypair"); 13299ebb4caSwyllys 13330a5e8faSwyllys SET_VALUE(kmf_set_csr_version(&csr, 2), "version number"); 13499ebb4caSwyllys 13530a5e8faSwyllys SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject), "subject name"); 13699ebb4caSwyllys 13730a5e8faSwyllys SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), 13899ebb4caSwyllys "SignatureAlgorithm"); 13999ebb4caSwyllys 14099ebb4caSwyllys if (altname != NULL) { 14130a5e8faSwyllys SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit, 14299ebb4caSwyllys alttype), "SetCSRSubjectAltName"); 14399ebb4caSwyllys } 14499ebb4caSwyllys 14599ebb4caSwyllys if (kubits != 0) { 14630a5e8faSwyllys SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits), 14799ebb4caSwyllys "SetCSRKeyUsage"); 14899ebb4caSwyllys } 149d00756ccSwyllys if (ekulist != NULL) { 150d00756ccSwyllys int i; 151d00756ccSwyllys for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) { 152d00756ccSwyllys SET_VALUE(kmf_add_csr_eku(&csr, 153d00756ccSwyllys &ekulist->ekulist[i], 154d00756ccSwyllys ekulist->critlist[i]), 155d00756ccSwyllys "Extended Key Usage"); 156d00756ccSwyllys } 157d00756ccSwyllys } 15830a5e8faSwyllys if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) == 15999ebb4caSwyllys KMF_OK) { 16030a5e8faSwyllys kmfrv = kmf_create_csr_file(&signedCsr, fmt, csrfile); 16199ebb4caSwyllys } 16299ebb4caSwyllys 16399ebb4caSwyllys cleanup: 16430a5e8faSwyllys (void) kmf_free_data(&signedCsr); 165a44b45c8SHuie-Ying Lee (void) kmf_free_signed_csr(&csr); 166a44b45c8SHuie-Ying Lee 167a44b45c8SHuie-Ying Lee /* delete the public key */ 16830a5e8faSwyllys numattr = 0; 16930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 17030a5e8faSwyllys &kstype, sizeof (kstype)); 17130a5e8faSwyllys numattr++; 17230a5e8faSwyllys 17330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR, 17430a5e8faSwyllys &pubk, sizeof (KMF_KEY_HANDLE)); 17530a5e8faSwyllys numattr++; 17630a5e8faSwyllys 177a44b45c8SHuie-Ying Lee if (tokencred != NULL && tokencred->cred != NULL) { 178a44b45c8SHuie-Ying Lee kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, 179a44b45c8SHuie-Ying Lee tokencred, sizeof (KMF_CREDENTIAL)); 180a44b45c8SHuie-Ying Lee numattr++; 181a44b45c8SHuie-Ying Lee } 182a44b45c8SHuie-Ying Lee 18330a5e8faSwyllys (void) kmf_delete_key_from_keystore(kmfhandle, numattr, attrlist); 18430a5e8faSwyllys 185a44b45c8SHuie-Ying Lee /* 186a44b45c8SHuie-Ying Lee * If there is an error, then we need to remove the private key 187a44b45c8SHuie-Ying Lee * from the token. 188a44b45c8SHuie-Ying Lee */ 189a44b45c8SHuie-Ying Lee if (kmfrv != KMF_OK) { 190a44b45c8SHuie-Ying Lee numattr = 0; 191a44b45c8SHuie-Ying Lee kmf_set_attr_at_index(attrlist, numattr, 192a44b45c8SHuie-Ying Lee KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 193a44b45c8SHuie-Ying Lee numattr++; 19499ebb4caSwyllys 195a44b45c8SHuie-Ying Lee kmf_set_attr_at_index(attrlist, numattr, 196a44b45c8SHuie-Ying Lee KMF_KEY_HANDLE_ATTR, &prik, sizeof (KMF_KEY_HANDLE)); 197a44b45c8SHuie-Ying Lee numattr++; 198a44b45c8SHuie-Ying Lee 199a44b45c8SHuie-Ying Lee if (tokencred != NULL && tokencred->cred != NULL) { 200a44b45c8SHuie-Ying Lee kmf_set_attr_at_index(attrlist, numattr, 201a44b45c8SHuie-Ying Lee KMF_CREDENTIAL_ATTR, tokencred, 202a44b45c8SHuie-Ying Lee sizeof (KMF_CREDENTIAL)); 203a44b45c8SHuie-Ying Lee numattr++; 204a44b45c8SHuie-Ying Lee } 205a44b45c8SHuie-Ying Lee 206a44b45c8SHuie-Ying Lee (void) kmf_delete_key_from_keystore(kmfhandle, numattr, 207a44b45c8SHuie-Ying Lee attrlist); 208a44b45c8SHuie-Ying Lee } 209a44b45c8SHuie-Ying Lee 210a44b45c8SHuie-Ying Lee (void) kmf_free_kmf_key(kmfhandle, &prik); 21199ebb4caSwyllys return (kmfrv); 21299ebb4caSwyllys } 21399ebb4caSwyllys 21499ebb4caSwyllys static KMF_RETURN 21599ebb4caSwyllys gencsr_file(KMF_HANDLE_T kmfhandle, 21699ebb4caSwyllys KMF_KEY_ALG keyAlg, 21799ebb4caSwyllys int keylen, KMF_ENCODE_FORMAT fmt, 21899ebb4caSwyllys char *subject, char *altname, KMF_GENERALNAMECHOICES alttype, 21999ebb4caSwyllys int altcrit, uint16_t kubits, int kucrit, 220448b8615Swyllys char *outcsr, char *outkey, EKU_LIST *ekulist) 22199ebb4caSwyllys { 22299ebb4caSwyllys KMF_RETURN kmfrv; 22399ebb4caSwyllys KMF_KEY_HANDLE pubk, prik; 22499ebb4caSwyllys KMF_X509_NAME csrSubject; 22599ebb4caSwyllys KMF_CSR_DATA csr; 22699ebb4caSwyllys KMF_ALGORITHM_INDEX sigAlg; 22799ebb4caSwyllys KMF_DATA signedCsr = {NULL, 0}; 22899ebb4caSwyllys char *fullcsrpath = NULL; 22999ebb4caSwyllys char *fullkeypath = NULL; 23099ebb4caSwyllys 23130a5e8faSwyllys int numattr = 0; 23230a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 23330a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 23430a5e8faSwyllys boolean_t storekey = TRUE; 23530a5e8faSwyllys 23699ebb4caSwyllys (void) memset(&csr, 0, sizeof (csr)); 23799ebb4caSwyllys (void) memset(&csrSubject, 0, sizeof (csrSubject)); 23899ebb4caSwyllys 23999ebb4caSwyllys if (EMPTYSTRING(outcsr) || EMPTYSTRING(outkey)) { 24099ebb4caSwyllys cryptoerror(LOG_STDERR, 24199ebb4caSwyllys gettext("No output file was specified for " 24299ebb4caSwyllys "the csr or key\n")); 24399ebb4caSwyllys return (KMF_ERR_BAD_PARAMETER); 24499ebb4caSwyllys } 24599ebb4caSwyllys fullcsrpath = strdup(outcsr); 24699ebb4caSwyllys if (verify_file(fullcsrpath)) { 24799ebb4caSwyllys cryptoerror(LOG_STDERR, 24899ebb4caSwyllys gettext("Cannot write the indicated output " 24999ebb4caSwyllys "certificate file (%s).\n"), fullcsrpath); 25099ebb4caSwyllys free(fullcsrpath); 25199ebb4caSwyllys return (PK_ERR_USAGE); 25299ebb4caSwyllys } 253448b8615Swyllys 25499ebb4caSwyllys fullkeypath = strdup(outkey); 25599ebb4caSwyllys if (verify_file(fullcsrpath)) { 25699ebb4caSwyllys cryptoerror(LOG_STDERR, 25799ebb4caSwyllys gettext("Cannot write the indicated output " 25899ebb4caSwyllys "key file (%s).\n"), fullkeypath); 25999ebb4caSwyllys free(fullcsrpath); 26099ebb4caSwyllys return (PK_ERR_USAGE); 26199ebb4caSwyllys } 26299ebb4caSwyllys 26399ebb4caSwyllys if (keyAlg == KMF_DSA) 26499ebb4caSwyllys sigAlg = KMF_ALGID_SHA1WithDSA; 26599ebb4caSwyllys else 266*4165f465SWyllys Ingersoll sigAlg = KMF_ALGID_SHA1WithRSA; 26799ebb4caSwyllys 26899ebb4caSwyllys /* If the subject name cannot be parsed, flag it now and exit */ 26930a5e8faSwyllys if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) { 27099ebb4caSwyllys return (kmfrv); 27199ebb4caSwyllys } 27299ebb4caSwyllys 27330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 27430a5e8faSwyllys &kstype, sizeof (kstype)); 27530a5e8faSwyllys numattr++; 27699ebb4caSwyllys 27730a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR, 27830a5e8faSwyllys fullkeypath, strlen(fullkeypath)); 27930a5e8faSwyllys numattr++; 28099ebb4caSwyllys 28130a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLENGTH_ATTR, 28230a5e8faSwyllys &keylen, sizeof (keylen)); 28330a5e8faSwyllys numattr++; 28430a5e8faSwyllys 28530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYALG_ATTR, 28630a5e8faSwyllys &keyAlg, sizeof (keyAlg)); 28730a5e8faSwyllys numattr++; 28830a5e8faSwyllys 28930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, 29030a5e8faSwyllys &fmt, sizeof (fmt)); 29130a5e8faSwyllys numattr++; 29230a5e8faSwyllys 29330a5e8faSwyllys (void) memset(&prik, 0, sizeof (prik)); 29430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVKEY_HANDLE_ATTR, 29530a5e8faSwyllys &prik, sizeof (KMF_KEY_HANDLE)); 29630a5e8faSwyllys numattr++; 29730a5e8faSwyllys 29830a5e8faSwyllys (void) memset(&pubk, 0, sizeof (pubk)); 29930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR, 30030a5e8faSwyllys &pubk, sizeof (KMF_KEY_HANDLE)); 30130a5e8faSwyllys numattr++; 30230a5e8faSwyllys 30330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_STOREKEY_BOOL_ATTR, 30430a5e8faSwyllys &storekey, sizeof (storekey)); 30530a5e8faSwyllys numattr++; 30630a5e8faSwyllys 30730a5e8faSwyllys kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); 30899ebb4caSwyllys if (kmfrv != KMF_OK) { 30999ebb4caSwyllys goto cleanup; 31099ebb4caSwyllys } 31130a5e8faSwyllys SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr), 31299ebb4caSwyllys "SetCSRPubKey"); 31399ebb4caSwyllys 31430a5e8faSwyllys SET_VALUE(kmf_set_csr_version(&csr, 2), "SetCSRVersion"); 31599ebb4caSwyllys 31630a5e8faSwyllys SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject), 31730a5e8faSwyllys "kmf_set_csr_subject"); 31899ebb4caSwyllys 31930a5e8faSwyllys SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), "kmf_set_csr_sig_alg"); 32099ebb4caSwyllys 32199ebb4caSwyllys if (altname != NULL) { 32230a5e8faSwyllys SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit, 32330a5e8faSwyllys alttype), "kmf_set_csr_subject_altname"); 32499ebb4caSwyllys } 32599ebb4caSwyllys if (kubits != NULL) { 32630a5e8faSwyllys SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits), 32730a5e8faSwyllys "kmf_set_csr_ku"); 32899ebb4caSwyllys } 329d00756ccSwyllys if (ekulist != NULL) { 330d00756ccSwyllys int i; 331d00756ccSwyllys for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) { 332d00756ccSwyllys SET_VALUE(kmf_add_csr_eku(&csr, 333d00756ccSwyllys &ekulist->ekulist[i], 334d00756ccSwyllys ekulist->critlist[i]), 335d00756ccSwyllys "Extended Key Usage"); 336d00756ccSwyllys } 337d00756ccSwyllys } 33830a5e8faSwyllys if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) == 33999ebb4caSwyllys KMF_OK) { 34030a5e8faSwyllys kmfrv = kmf_create_csr_file(&signedCsr, fmt, fullcsrpath); 34199ebb4caSwyllys } 34299ebb4caSwyllys 34399ebb4caSwyllys cleanup: 34499ebb4caSwyllys if (fullkeypath) 34599ebb4caSwyllys free(fullkeypath); 34699ebb4caSwyllys if (fullcsrpath) 34799ebb4caSwyllys free(fullcsrpath); 34899ebb4caSwyllys 34930a5e8faSwyllys kmf_free_data(&signedCsr); 35030a5e8faSwyllys kmf_free_kmf_key(kmfhandle, &prik); 35130a5e8faSwyllys kmf_free_signed_csr(&csr); 35299ebb4caSwyllys 35399ebb4caSwyllys return (kmfrv); 35499ebb4caSwyllys } 35599ebb4caSwyllys 35699ebb4caSwyllys static KMF_RETURN 35799ebb4caSwyllys gencsr_nss(KMF_HANDLE_T kmfhandle, 35899ebb4caSwyllys char *token, char *subject, char *altname, 35999ebb4caSwyllys KMF_GENERALNAMECHOICES alttype, int altcrit, 36099ebb4caSwyllys char *nickname, char *dir, char *prefix, 36199ebb4caSwyllys KMF_KEY_ALG keyAlg, int keylen, 36299ebb4caSwyllys uint16_t kubits, int kucrit, 36399ebb4caSwyllys KMF_ENCODE_FORMAT fmt, char *csrfile, 364d00756ccSwyllys KMF_CREDENTIAL *tokencred, EKU_LIST *ekulist) 36599ebb4caSwyllys { 36699ebb4caSwyllys KMF_RETURN kmfrv; 36799ebb4caSwyllys KMF_KEY_HANDLE pubk, prik; 36899ebb4caSwyllys KMF_X509_NAME csrSubject; 36999ebb4caSwyllys KMF_CSR_DATA csr; 37099ebb4caSwyllys KMF_ALGORITHM_INDEX sigAlg; 37199ebb4caSwyllys KMF_DATA signedCsr = {NULL, 0}; 37230a5e8faSwyllys 37330a5e8faSwyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 37430a5e8faSwyllys int numattr = 0; 37530a5e8faSwyllys KMF_ATTRIBUTE attrlist[16]; 37630a5e8faSwyllys boolean_t storekey = TRUE; 37799ebb4caSwyllys 37899ebb4caSwyllys if (token == NULL) 37999ebb4caSwyllys token = DEFAULT_NSS_TOKEN; 38099ebb4caSwyllys 38199ebb4caSwyllys if (keyAlg == KMF_DSA) 38299ebb4caSwyllys sigAlg = KMF_ALGID_SHA1WithDSA; 38399ebb4caSwyllys else 384*4165f465SWyllys Ingersoll sigAlg = KMF_ALGID_SHA1WithRSA; 38599ebb4caSwyllys 38699ebb4caSwyllys kmfrv = configure_nss(kmfhandle, dir, prefix); 38799ebb4caSwyllys if (kmfrv != KMF_OK) 38899ebb4caSwyllys return (kmfrv); 38999ebb4caSwyllys 39099ebb4caSwyllys (void) memset(&csr, 0, sizeof (csr)); 39199ebb4caSwyllys (void) memset(&csrSubject, 0, sizeof (csrSubject)); 392448b8615Swyllys (void) memset(&pubk, 0, sizeof (pubk)); 393448b8615Swyllys (void) memset(&prik, 0, sizeof (prik)); 39499ebb4caSwyllys 39599ebb4caSwyllys /* If the subject name cannot be parsed, flag it now and exit */ 39630a5e8faSwyllys if ((kmfrv = kmf_dn_parser(subject, &csrSubject)) != KMF_OK) { 39799ebb4caSwyllys return (kmfrv); 39899ebb4caSwyllys } 39999ebb4caSwyllys 40030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 40130a5e8faSwyllys &kstype, sizeof (kstype)); 40230a5e8faSwyllys numattr++; 40399ebb4caSwyllys 40430a5e8faSwyllys if (nickname != NULL && strlen(nickname)) { 40530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, 40630a5e8faSwyllys nickname, strlen(nickname)); 40730a5e8faSwyllys numattr++; 40830a5e8faSwyllys } 40930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLENGTH_ATTR, 41030a5e8faSwyllys &keylen, sizeof (keylen)); 41130a5e8faSwyllys numattr++; 41299ebb4caSwyllys 41330a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYALG_ATTR, 41430a5e8faSwyllys &keyAlg, sizeof (keyAlg)); 41530a5e8faSwyllys numattr++; 41630a5e8faSwyllys 41730a5e8faSwyllys if (tokencred != NULL && tokencred->credlen > 0) { 41830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, 41930a5e8faSwyllys tokencred, sizeof (KMF_CREDENTIAL)); 42030a5e8faSwyllys numattr++; 42130a5e8faSwyllys } 42230a5e8faSwyllys 42330a5e8faSwyllys if (token && strlen(token)) { 42430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, 42530a5e8faSwyllys token, strlen(token)); 42630a5e8faSwyllys numattr++; 42730a5e8faSwyllys } 42830a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR, 42930a5e8faSwyllys &pubk, sizeof (KMF_KEY_HANDLE)); 43030a5e8faSwyllys numattr++; 43130a5e8faSwyllys 43230a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVKEY_HANDLE_ATTR, 43330a5e8faSwyllys &prik, sizeof (KMF_KEY_HANDLE)); 43430a5e8faSwyllys numattr++; 43530a5e8faSwyllys 43630a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_STOREKEY_BOOL_ATTR, 43730a5e8faSwyllys &storekey, sizeof (storekey)); 43830a5e8faSwyllys numattr++; 43930a5e8faSwyllys 44030a5e8faSwyllys kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); 44199ebb4caSwyllys if (kmfrv != KMF_OK) { 44299ebb4caSwyllys goto cleanup; 44399ebb4caSwyllys } 44499ebb4caSwyllys 44530a5e8faSwyllys SET_VALUE(kmf_set_csr_pubkey(kmfhandle, &pubk, &csr), 44630a5e8faSwyllys "kmf_set_csr_pubkey"); 44730a5e8faSwyllys SET_VALUE(kmf_set_csr_version(&csr, 2), "kmf_set_csr_version"); 44830a5e8faSwyllys SET_VALUE(kmf_set_csr_subject(&csr, &csrSubject), 44930a5e8faSwyllys "kmf_set_csr_subject"); 45030a5e8faSwyllys SET_VALUE(kmf_set_csr_sig_alg(&csr, sigAlg), "kmf_set_csr_sig_alg"); 45199ebb4caSwyllys 45299ebb4caSwyllys if (altname != NULL) { 45330a5e8faSwyllys SET_VALUE(kmf_set_csr_subject_altname(&csr, altname, altcrit, 45430a5e8faSwyllys alttype), "kmf_set_csr_subject_altname"); 45599ebb4caSwyllys } 45699ebb4caSwyllys if (kubits != NULL) { 45730a5e8faSwyllys SET_VALUE(kmf_set_csr_ku(&csr, kucrit, kubits), 45830a5e8faSwyllys "kmf_set_csr_ku"); 45999ebb4caSwyllys } 460d00756ccSwyllys if (ekulist != NULL) { 461d00756ccSwyllys int i; 462d00756ccSwyllys for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) { 463d00756ccSwyllys SET_VALUE(kmf_add_csr_eku(&csr, 464d00756ccSwyllys &ekulist->ekulist[i], 465d00756ccSwyllys ekulist->critlist[i]), 466d00756ccSwyllys "Extended Key Usage"); 467d00756ccSwyllys } 468d00756ccSwyllys } 46930a5e8faSwyllys if ((kmfrv = kmf_sign_csr(kmfhandle, &csr, &prik, &signedCsr)) == 47099ebb4caSwyllys KMF_OK) { 47130a5e8faSwyllys kmfrv = kmf_create_csr_file(&signedCsr, fmt, csrfile); 47299ebb4caSwyllys } 47399ebb4caSwyllys 47499ebb4caSwyllys cleanup: 47530a5e8faSwyllys (void) kmf_free_data(&signedCsr); 47630a5e8faSwyllys (void) kmf_free_kmf_key(kmfhandle, &prik); 47730a5e8faSwyllys 47899ebb4caSwyllys /* delete the key */ 47930a5e8faSwyllys numattr = 0; 48030a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 48130a5e8faSwyllys &kstype, sizeof (kstype)); 48230a5e8faSwyllys numattr++; 48330a5e8faSwyllys 48430a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_PUBKEY_HANDLE_ATTR, 48530a5e8faSwyllys &pubk, sizeof (KMF_KEY_HANDLE)); 48630a5e8faSwyllys numattr++; 48730a5e8faSwyllys 48830a5e8faSwyllys if (tokencred != NULL && tokencred->credlen > 0) { 48930a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR, 49030a5e8faSwyllys tokencred, sizeof (KMF_CREDENTIAL)); 49130a5e8faSwyllys numattr++; 49230a5e8faSwyllys } 49330a5e8faSwyllys 49430a5e8faSwyllys if (token && strlen(token)) { 49530a5e8faSwyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, 49630a5e8faSwyllys token, strlen(token)); 49730a5e8faSwyllys numattr++; 49830a5e8faSwyllys } 49930a5e8faSwyllys 50030a5e8faSwyllys (void) kmf_delete_key_from_keystore(kmfhandle, numattr, attrlist); 50130a5e8faSwyllys 50230a5e8faSwyllys (void) kmf_free_signed_csr(&csr); 50399ebb4caSwyllys 50499ebb4caSwyllys return (kmfrv); 50599ebb4caSwyllys } 50699ebb4caSwyllys 50799ebb4caSwyllys int 50899ebb4caSwyllys pk_gencsr(int argc, char *argv[]) 50999ebb4caSwyllys { 51099ebb4caSwyllys KMF_RETURN rv; 51199ebb4caSwyllys int opt; 51299ebb4caSwyllys extern int optind_av; 51399ebb4caSwyllys extern char *optarg_av; 51499ebb4caSwyllys KMF_KEYSTORE_TYPE kstype = 0; 51599ebb4caSwyllys char *subject = NULL; 51699ebb4caSwyllys char *tokenname = NULL; 51799ebb4caSwyllys char *dir = NULL; 51899ebb4caSwyllys char *prefix = NULL; 51999ebb4caSwyllys int keylen = PK_DEFAULT_KEYLENGTH; 52099ebb4caSwyllys char *certlabel = NULL; 52199ebb4caSwyllys char *outcsr = NULL; 52299ebb4caSwyllys char *outkey = NULL; 52399ebb4caSwyllys char *format = NULL; 52499ebb4caSwyllys char *altname = NULL; 52599ebb4caSwyllys char *kustr = NULL; 526d00756ccSwyllys char *ekustr = NULL; 52799ebb4caSwyllys uint16_t kubits = 0; 52899ebb4caSwyllys char *keytype = PK_DEFAULT_KEYTYPE; 52999ebb4caSwyllys KMF_HANDLE_T kmfhandle = NULL; 53099ebb4caSwyllys KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1; 53199ebb4caSwyllys KMF_KEY_ALG keyAlg = KMF_RSA; 532*4165f465SWyllys Ingersoll KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_SHA1WithRSA; 53399ebb4caSwyllys boolean_t interactive = B_FALSE; 53499ebb4caSwyllys char *subname = NULL; 53599ebb4caSwyllys KMF_CREDENTIAL tokencred = {NULL, 0}; 53699ebb4caSwyllys KMF_GENERALNAMECHOICES alttype = 0; 53799ebb4caSwyllys int altcrit = 0, kucrit = 0; 538d00756ccSwyllys EKU_LIST *ekulist = NULL; 53999ebb4caSwyllys 54099ebb4caSwyllys while ((opt = getopt_av(argc, argv, 54199ebb4caSwyllys "ik:(keystore)s:(subject)n:(nickname)A:(altname)" 54299ebb4caSwyllys "u:(keyusage)T:(token)d:(dir)p:(prefix)t:(keytype)" 543d00756ccSwyllys "y:(keylen)l:(label)c:(outcsr)e:(eku)" 54499ebb4caSwyllys "K:(outkey)F:(format)")) != EOF) { 54599ebb4caSwyllys 54699ebb4caSwyllys if (opt != 'i' && EMPTYSTRING(optarg_av)) 54799ebb4caSwyllys return (PK_ERR_USAGE); 54899ebb4caSwyllys 54999ebb4caSwyllys switch (opt) { 55099ebb4caSwyllys case 'A': 55199ebb4caSwyllys altname = optarg_av; 55299ebb4caSwyllys break; 55399ebb4caSwyllys case 'i': 554592106a2SWyllys Ingersoll if (interactive) 55599ebb4caSwyllys return (PK_ERR_USAGE); 556592106a2SWyllys Ingersoll else if (subject) { 557592106a2SWyllys Ingersoll cryptoerror(LOG_STDERR, 558592106a2SWyllys Ingersoll gettext("Interactive (-i) and " 559592106a2SWyllys Ingersoll "subject options are mutually " 560592106a2SWyllys Ingersoll "exclusive.\n")); 561592106a2SWyllys Ingersoll return (PK_ERR_USAGE); 562592106a2SWyllys Ingersoll } else 56399ebb4caSwyllys interactive = B_TRUE; 56499ebb4caSwyllys break; 56599ebb4caSwyllys case 'k': 56699ebb4caSwyllys kstype = KS2Int(optarg_av); 56799ebb4caSwyllys if (kstype == 0) 56899ebb4caSwyllys return (PK_ERR_USAGE); 56999ebb4caSwyllys break; 57099ebb4caSwyllys case 's': 571592106a2SWyllys Ingersoll if (subject) 57299ebb4caSwyllys return (PK_ERR_USAGE); 573592106a2SWyllys Ingersoll else if (interactive) { 574592106a2SWyllys Ingersoll cryptoerror(LOG_STDERR, 575592106a2SWyllys Ingersoll gettext("Interactive (-i) and " 576592106a2SWyllys Ingersoll "subject options are mutually " 577592106a2SWyllys Ingersoll "exclusive.\n")); 578592106a2SWyllys Ingersoll return (PK_ERR_USAGE); 579592106a2SWyllys Ingersoll } else 58099ebb4caSwyllys subject = optarg_av; 58199ebb4caSwyllys break; 58299ebb4caSwyllys case 'l': 58399ebb4caSwyllys case 'n': 58499ebb4caSwyllys if (certlabel) 58599ebb4caSwyllys return (PK_ERR_USAGE); 58699ebb4caSwyllys certlabel = optarg_av; 58799ebb4caSwyllys break; 58899ebb4caSwyllys case 'T': 58999ebb4caSwyllys if (tokenname) 59099ebb4caSwyllys return (PK_ERR_USAGE); 59199ebb4caSwyllys tokenname = optarg_av; 59299ebb4caSwyllys break; 59399ebb4caSwyllys case 'd': 59499ebb4caSwyllys dir = optarg_av; 59599ebb4caSwyllys break; 59699ebb4caSwyllys case 'p': 59799ebb4caSwyllys if (prefix) 59899ebb4caSwyllys return (PK_ERR_USAGE); 59999ebb4caSwyllys prefix = optarg_av; 60099ebb4caSwyllys break; 60199ebb4caSwyllys case 't': 60299ebb4caSwyllys keytype = optarg_av; 60399ebb4caSwyllys break; 60499ebb4caSwyllys case 'u': 60599ebb4caSwyllys kustr = optarg_av; 60699ebb4caSwyllys break; 60799ebb4caSwyllys case 'y': 60899ebb4caSwyllys if (sscanf(optarg_av, "%d", 60999ebb4caSwyllys &keylen) != 1) { 61099ebb4caSwyllys cryptoerror(LOG_STDERR, 61199ebb4caSwyllys gettext("Unrecognized " 61230a5e8faSwyllys "key length (%s)\n"), optarg_av); 61399ebb4caSwyllys return (PK_ERR_USAGE); 61499ebb4caSwyllys } 61599ebb4caSwyllys break; 61699ebb4caSwyllys case 'c': 61799ebb4caSwyllys if (outcsr) 61899ebb4caSwyllys return (PK_ERR_USAGE); 61999ebb4caSwyllys outcsr = optarg_av; 62099ebb4caSwyllys break; 62199ebb4caSwyllys case 'K': 62299ebb4caSwyllys if (outkey) 62399ebb4caSwyllys return (PK_ERR_USAGE); 62499ebb4caSwyllys outkey = optarg_av; 62599ebb4caSwyllys break; 62699ebb4caSwyllys case 'F': 62799ebb4caSwyllys if (format) 62899ebb4caSwyllys return (PK_ERR_USAGE); 62999ebb4caSwyllys format = optarg_av; 63099ebb4caSwyllys break; 631d00756ccSwyllys case 'e': 632d00756ccSwyllys ekustr = optarg_av; 633d00756ccSwyllys break; 63499ebb4caSwyllys default: 63599ebb4caSwyllys cryptoerror(LOG_STDERR, gettext( 63699ebb4caSwyllys "unrecognized gencsr option '%s'\n"), 63799ebb4caSwyllys argv[optind_av]); 63899ebb4caSwyllys return (PK_ERR_USAGE); 63999ebb4caSwyllys } 64099ebb4caSwyllys } 64199ebb4caSwyllys /* No additional args allowed. */ 64299ebb4caSwyllys argc -= optind_av; 64399ebb4caSwyllys argv += optind_av; 64499ebb4caSwyllys if (argc) { 64599ebb4caSwyllys return (PK_ERR_USAGE); 64699ebb4caSwyllys } 64799ebb4caSwyllys 64899ebb4caSwyllys /* Assume keystore = PKCS#11 if not specified. */ 64999ebb4caSwyllys if (kstype == 0) 65099ebb4caSwyllys kstype = KMF_KEYSTORE_PK11TOKEN; 65199ebb4caSwyllys 652577f4726Swyllys DIR_OPTION_CHECK(kstype, dir); 653577f4726Swyllys 6542cbed729Swyllys if (EMPTYSTRING(outcsr) && interactive) { 6552cbed729Swyllys (void) get_filename("CSR", &outcsr); 6562cbed729Swyllys } 65799ebb4caSwyllys if (EMPTYSTRING(outcsr)) { 65899ebb4caSwyllys (void) printf(gettext("A filename must be specified to hold" 65999ebb4caSwyllys "the final certificate request data.\n")); 66099ebb4caSwyllys return (PK_ERR_USAGE); 6612cbed729Swyllys } 66299ebb4caSwyllys /* 66399ebb4caSwyllys * verify that the outcsr file does not already exist 66499ebb4caSwyllys * and that it can be created. 66599ebb4caSwyllys */ 66699ebb4caSwyllys rv = verify_file(outcsr); 66799ebb4caSwyllys if (rv != KMF_OK) { 66899ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("output file (%s) " 66999ebb4caSwyllys "cannot be created.\n"), outcsr); 67099ebb4caSwyllys return (PK_ERR_USAGE); 67199ebb4caSwyllys } 67299ebb4caSwyllys 6732cbed729Swyllys if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) { 6742cbed729Swyllys if (EMPTYSTRING(certlabel) && interactive) 6752cbed729Swyllys (void) get_certlabel(&certlabel); 6762cbed729Swyllys 6772cbed729Swyllys if (EMPTYSTRING(certlabel)) { 6782cbed729Swyllys cryptoerror(LOG_STDERR, gettext("A label must be " 67999ebb4caSwyllys "specified to create a certificate request.\n")); 68099ebb4caSwyllys return (PK_ERR_USAGE); 68199ebb4caSwyllys } 6822cbed729Swyllys } else if (kstype == KMF_KEYSTORE_OPENSSL) { 6832cbed729Swyllys if (EMPTYSTRING(outkey) && interactive) 6842cbed729Swyllys (void) get_filename("private key", &outkey); 6852cbed729Swyllys 6862cbed729Swyllys if (EMPTYSTRING(outkey)) { 6872cbed729Swyllys cryptoerror(LOG_STDERR, gettext("A key filename " 6882cbed729Swyllys "must be specified to create a certificate " 6892cbed729Swyllys "request.\n")); 6902cbed729Swyllys return (PK_ERR_USAGE); 6912cbed729Swyllys } 6922cbed729Swyllys } 69399ebb4caSwyllys 69499ebb4caSwyllys if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) { 69599ebb4caSwyllys cryptoerror(LOG_STDERR, 69630a5e8faSwyllys gettext("Error parsing format string (%s).\n"), format); 69799ebb4caSwyllys return (PK_ERR_USAGE); 69899ebb4caSwyllys } 69999ebb4caSwyllys if (format && fmt != KMF_FORMAT_ASN1 && fmt != KMF_FORMAT_PEM) { 70099ebb4caSwyllys cryptoerror(LOG_STDERR, 70199ebb4caSwyllys gettext("CSR must be DER or PEM format.\n")); 70299ebb4caSwyllys return (PK_ERR_USAGE); 70399ebb4caSwyllys } 70499ebb4caSwyllys 70599ebb4caSwyllys /* 70699ebb4caSwyllys * Check the subject name. 70799ebb4caSwyllys * If interactive is true, get it now interactively. 70899ebb4caSwyllys */ 70999ebb4caSwyllys if (interactive) { 71099ebb4caSwyllys if (get_subname(&subname) != KMF_OK) { 71199ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("Failed to get the " 71299ebb4caSwyllys "subject name interactively.\n")); 71399ebb4caSwyllys return (PK_ERR_USAGE); 71499ebb4caSwyllys } 71599ebb4caSwyllys } else { 71699ebb4caSwyllys if (EMPTYSTRING(subject)) { 71799ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("A subject name or " 71899ebb4caSwyllys "-i must be specified to create a certificate " 71999ebb4caSwyllys "request.\n")); 72099ebb4caSwyllys return (PK_ERR_USAGE); 72199ebb4caSwyllys } else { 72299ebb4caSwyllys subname = strdup(subject); 72399ebb4caSwyllys if (subname == NULL) { 72499ebb4caSwyllys cryptoerror(LOG_STDERR, 72599ebb4caSwyllys gettext("Out of memory.\n")); 72699ebb4caSwyllys return (PK_ERR_SYSTEM); 72799ebb4caSwyllys } 72899ebb4caSwyllys } 72999ebb4caSwyllys } 73099ebb4caSwyllys if (altname != NULL) { 73199ebb4caSwyllys rv = verify_altname(altname, &alttype, &altcrit); 73299ebb4caSwyllys if (rv != KMF_OK) { 73399ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("Subject AltName " 73499ebb4caSwyllys "must be specified as a name=value pair. " 73599ebb4caSwyllys "See the man page for details.")); 73699ebb4caSwyllys goto end; 73799ebb4caSwyllys } else { 73899ebb4caSwyllys /* advance the altname past the '=' sign */ 73999ebb4caSwyllys char *p = strchr(altname, '='); 74099ebb4caSwyllys if (p != NULL) 74199ebb4caSwyllys altname = p + 1; 74299ebb4caSwyllys } 74399ebb4caSwyllys } 74499ebb4caSwyllys 74599ebb4caSwyllys if (kustr != NULL) { 74699ebb4caSwyllys rv = verify_keyusage(kustr, &kubits, &kucrit); 74799ebb4caSwyllys if (rv != KMF_OK) { 74899ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("KeyUsage " 74999ebb4caSwyllys "must be specified as a comma-separated list. " 75099ebb4caSwyllys "See the man page for details.")); 75199ebb4caSwyllys goto end; 75299ebb4caSwyllys } 75399ebb4caSwyllys } 754d00756ccSwyllys if (ekustr != NULL) { 755d00756ccSwyllys rv = verify_ekunames(ekustr, &ekulist); 756d00756ccSwyllys if (rv != KMF_OK) { 757d00756ccSwyllys (void) fprintf(stderr, gettext("EKUs must " 758d00756ccSwyllys "be specified as a comma-separated list. " 759d00756ccSwyllys "See the man page for details.\n")); 760d00756ccSwyllys rv = PK_ERR_USAGE; 761d00756ccSwyllys goto end; 762d00756ccSwyllys } 763d00756ccSwyllys } 764d00756ccSwyllys 76599ebb4caSwyllys if ((rv = Str2KeyType(keytype, &keyAlg, &sigAlg)) != 0) { 76699ebb4caSwyllys cryptoerror(LOG_STDERR, gettext("Unrecognized keytype (%s).\n"), 76799ebb4caSwyllys keytype); 76899ebb4caSwyllys goto end; 76999ebb4caSwyllys } 77099ebb4caSwyllys 77199ebb4caSwyllys if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) { 77299ebb4caSwyllys if (tokenname == NULL || !strlen(tokenname)) { 77399ebb4caSwyllys if (kstype == KMF_KEYSTORE_NSS) { 77499ebb4caSwyllys tokenname = "internal"; 77599ebb4caSwyllys } else { 77699ebb4caSwyllys tokenname = PK_DEFAULT_PK11TOKEN; 77799ebb4caSwyllys } 77899ebb4caSwyllys } 77999ebb4caSwyllys 78099ebb4caSwyllys (void) get_token_password(kstype, tokenname, &tokencred); 78199ebb4caSwyllys } 78299ebb4caSwyllys 783577f4726Swyllys if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 784577f4726Swyllys cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n")); 785577f4726Swyllys return (PK_ERR_USAGE); 786577f4726Swyllys } 787577f4726Swyllys 788577f4726Swyllys 78999ebb4caSwyllys if (kstype == KMF_KEYSTORE_NSS) { 79099ebb4caSwyllys if (dir == NULL) 79199ebb4caSwyllys dir = PK_DEFAULT_DIRECTORY; 79299ebb4caSwyllys 79399ebb4caSwyllys rv = gencsr_nss(kmfhandle, 79499ebb4caSwyllys tokenname, subname, altname, alttype, altcrit, 79599ebb4caSwyllys certlabel, dir, prefix, 79699ebb4caSwyllys keyAlg, keylen, kubits, kucrit, 797d00756ccSwyllys fmt, outcsr, &tokencred, ekulist); 79899ebb4caSwyllys 79999ebb4caSwyllys } else if (kstype == KMF_KEYSTORE_PK11TOKEN) { 80099ebb4caSwyllys rv = gencsr_pkcs11(kmfhandle, 80199ebb4caSwyllys tokenname, subname, altname, alttype, altcrit, 80299ebb4caSwyllys certlabel, keyAlg, keylen, 803d00756ccSwyllys kubits, kucrit, fmt, outcsr, &tokencred, ekulist); 80499ebb4caSwyllys 80599ebb4caSwyllys } else if (kstype == KMF_KEYSTORE_OPENSSL) { 80699ebb4caSwyllys rv = gencsr_file(kmfhandle, 80799ebb4caSwyllys keyAlg, keylen, fmt, subname, altname, 80899ebb4caSwyllys alttype, altcrit, kubits, kucrit, 809448b8615Swyllys outcsr, outkey, ekulist); 81099ebb4caSwyllys } 81199ebb4caSwyllys 81299ebb4caSwyllys end: 813592106a2SWyllys Ingersoll if (rv != KMF_OK) { 81499ebb4caSwyllys display_error(kmfhandle, rv, 81599ebb4caSwyllys gettext("Error creating CSR or keypair")); 81699ebb4caSwyllys 817592106a2SWyllys Ingersoll if (rv == KMF_ERR_RDN_PARSER) { 818592106a2SWyllys Ingersoll cryptoerror(LOG_STDERR, gettext("subject or " 819592106a2SWyllys Ingersoll "issuer name must be in proper DN format.\n")); 820592106a2SWyllys Ingersoll } 821592106a2SWyllys Ingersoll } 822592106a2SWyllys Ingersoll 823d00756ccSwyllys if (ekulist != NULL) 824d00756ccSwyllys free_eku_list(ekulist); 825d00756ccSwyllys 82699ebb4caSwyllys if (subname) 82799ebb4caSwyllys free(subname); 82899ebb4caSwyllys 82999ebb4caSwyllys if (tokencred.cred != NULL) 83099ebb4caSwyllys free(tokencred.cred); 83199ebb4caSwyllys 83230a5e8faSwyllys (void) kmf_finalize(kmfhandle); 83399ebb4caSwyllys if (rv != KMF_OK) 83499ebb4caSwyllys return (PK_ERR_USAGE); 83599ebb4caSwyllys 83699ebb4caSwyllys return (0); 83799ebb4caSwyllys } 838