13089Swyllys /* 23089Swyllys * CDDL HEADER START 33089Swyllys * 43089Swyllys * The contents of this file are subject to the terms of the 53089Swyllys * Common Development and Distribution License (the "License"). 63089Swyllys * You may not use this file except in compliance with the License. 73089Swyllys * 83089Swyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 93089Swyllys * or http://www.opensolaris.org/os/licensing. 103089Swyllys * See the License for the specific language governing permissions 113089Swyllys * and limitations under the License. 123089Swyllys * 133089Swyllys * When distributing Covered Code, include this CDDL HEADER in each 143089Swyllys * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 153089Swyllys * If applicable, add the following below this CDDL HEADER, with the 163089Swyllys * fields enclosed by brackets "[]" replaced with your own identifying 173089Swyllys * information: Portions Copyright [yyyy] [name of copyright owner] 183089Swyllys * 193089Swyllys * CDDL HEADER END 203089Swyllys */ 213089Swyllys /* 22*9145SHuie-Ying.Lee@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 233089Swyllys * Use is subject to license terms. 243089Swyllys */ 253089Swyllys 263089Swyllys #include <stdio.h> 273089Swyllys #include <string.h> 283089Swyllys #include <ctype.h> 293089Swyllys #include <malloc.h> 303089Swyllys #include <libgen.h> 313089Swyllys #include <errno.h> 323089Swyllys #include <cryptoutil.h> 333089Swyllys #include <security/cryptoki.h> 343089Swyllys #include "common.h" 353089Swyllys 363089Swyllys #include <kmfapi.h> 373089Swyllys 383089Swyllys #define SET_VALUE(f, s) \ 393089Swyllys kmfrv = f; \ 403089Swyllys if (kmfrv != KMF_OK) { \ 413089Swyllys cryptoerror(LOG_STDERR, \ 423089Swyllys gettext("Failed to set %s: 0x%02x\n"), \ 433089Swyllys s, kmfrv); \ 443089Swyllys goto cleanup; \ 453089Swyllys } 463089Swyllys 473089Swyllys static int 483089Swyllys gencert_pkcs11(KMF_HANDLE_T kmfhandle, 493089Swyllys char *token, char *subject, char *altname, 503089Swyllys KMF_GENERALNAMECHOICES alttype, int altcrit, 513089Swyllys char *certlabel, KMF_KEY_ALG keyAlg, 523089Swyllys KMF_ALGORITHM_INDEX sigAlg, 533089Swyllys int keylen, uint32_t ltime, KMF_BIGINT *serial, 546051Swyllys uint16_t kubits, int kucrit, KMF_CREDENTIAL *tokencred, 556051Swyllys EKU_LIST *ekulist) 563089Swyllys { 573089Swyllys KMF_RETURN kmfrv = KMF_OK; 583089Swyllys KMF_KEY_HANDLE pubk, prik; 593089Swyllys KMF_X509_CERTIFICATE signedCert; 603089Swyllys KMF_X509_NAME certSubject; 613089Swyllys KMF_X509_NAME certIssuer; 623089Swyllys KMF_DATA x509DER; 635051Swyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; 645051Swyllys KMF_ATTRIBUTE attrlist[16]; 655051Swyllys int numattr = 0; 665051Swyllys KMF_KEY_ALG keytype; 675051Swyllys uint32_t keylength; 683089Swyllys 693089Swyllys (void) memset(&signedCert, 0, sizeof (signedCert)); 703089Swyllys (void) memset(&certSubject, 0, sizeof (certSubject)); 713089Swyllys (void) memset(&certIssuer, 0, sizeof (certIssuer)); 723089Swyllys (void) memset(&x509DER, 0, sizeof (x509DER)); 733089Swyllys 743089Swyllys /* If the subject name cannot be parsed, flag it now and exit */ 755051Swyllys if (kmf_dn_parser(subject, &certSubject) != KMF_OK) { 763089Swyllys cryptoerror(LOG_STDERR, 775051Swyllys gettext("Subject name cannot be parsed.\n")); 783089Swyllys return (PK_ERR_USAGE); 793089Swyllys } 803089Swyllys 813089Swyllys /* For a self-signed cert, the issuser and subject are the same */ 825051Swyllys if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) { 833089Swyllys cryptoerror(LOG_STDERR, 845051Swyllys gettext("Subject name cannot be parsed.\n")); 853089Swyllys return (PK_ERR_USAGE); 863089Swyllys } 873089Swyllys 885051Swyllys keylength = keylen; /* bits */ 895051Swyllys keytype = keyAlg; 903089Swyllys 913089Swyllys /* Select a PKCS11 token */ 923089Swyllys kmfrv = select_token(kmfhandle, token, FALSE); 933089Swyllys 943089Swyllys if (kmfrv != KMF_OK) { 953089Swyllys return (kmfrv); 963089Swyllys } 973089Swyllys 985051Swyllys kmf_set_attr_at_index(attrlist, numattr, 995051Swyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, 1005051Swyllys sizeof (kstype)); 1015051Swyllys numattr++; 1025051Swyllys 1035051Swyllys kmf_set_attr_at_index(attrlist, numattr, 1045051Swyllys KMF_KEYALG_ATTR, &keytype, 1055051Swyllys sizeof (keytype)); 1065051Swyllys numattr++; 1075051Swyllys 1085051Swyllys kmf_set_attr_at_index(attrlist, numattr, 1095051Swyllys KMF_KEYLENGTH_ATTR, &keylength, 1105051Swyllys sizeof (keylength)); 1115051Swyllys numattr++; 1125051Swyllys 1135051Swyllys if (certlabel != NULL) { 1145051Swyllys kmf_set_attr_at_index(attrlist, numattr, 1155051Swyllys KMF_KEYLABEL_ATTR, certlabel, 1165051Swyllys strlen(certlabel)); 1175051Swyllys numattr++; 1185051Swyllys } 1195051Swyllys 1206354Swyllys if (tokencred != NULL && tokencred->cred != NULL) { 1215051Swyllys kmf_set_attr_at_index(attrlist, numattr, 1225051Swyllys KMF_CREDENTIAL_ATTR, tokencred, 1235051Swyllys sizeof (KMF_CREDENTIAL)); 1245051Swyllys numattr++; 1255051Swyllys } 1265051Swyllys 1275051Swyllys kmf_set_attr_at_index(attrlist, numattr, 1285051Swyllys KMF_PRIVKEY_HANDLE_ATTR, &prik, 1295051Swyllys sizeof (KMF_KEY_HANDLE)); 1305051Swyllys numattr++; 1315051Swyllys 1325051Swyllys kmf_set_attr_at_index(attrlist, numattr, 1335051Swyllys KMF_PUBKEY_HANDLE_ATTR, &pubk, 1345051Swyllys sizeof (KMF_KEY_HANDLE)); 1355051Swyllys numattr++; 1365051Swyllys 1375051Swyllys kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); 1383089Swyllys if (kmfrv != KMF_OK) { 1393089Swyllys return (kmfrv); 1403089Swyllys } 1413089Swyllys 1425051Swyllys SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert), 1435051Swyllys "keypair"); 1443089Swyllys 1455051Swyllys SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number"); 1463089Swyllys 1475051Swyllys SET_VALUE(kmf_set_cert_serial(&signedCert, serial), 1485051Swyllys "serial number"); 1493089Swyllys 1505051Swyllys SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime), 1515051Swyllys "validity time"); 1523089Swyllys 1535051Swyllys SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg), 1545051Swyllys "signature algorithm"); 1553089Swyllys 1565051Swyllys SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject), 1575051Swyllys "subject name"); 1583089Swyllys 1595051Swyllys SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer), 1605051Swyllys "issuer name"); 1613089Swyllys 1623089Swyllys if (altname != NULL) 1635051Swyllys SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit, 1645051Swyllys alttype, altname), "subjectAltName"); 1653089Swyllys 1663089Swyllys if (kubits != 0) 1675051Swyllys SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits), 1685051Swyllys "KeyUsage"); 1695051Swyllys 1706051Swyllys if (ekulist != NULL) { 1716051Swyllys int i; 1726051Swyllys for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) { 1736051Swyllys SET_VALUE(kmf_add_cert_eku(&signedCert, 1746051Swyllys &ekulist->ekulist[i], ekulist->critlist[i]), 1756051Swyllys "Extended Key Usage"); 1766051Swyllys } 1776051Swyllys } 1786051Swyllys 1795051Swyllys /* 1805051Swyllys * Construct attributes for the kmf_sign_cert operation. 1815051Swyllys */ 1825051Swyllys numattr = 0; 1835051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 1845051Swyllys &kstype, sizeof (kstype)); 1855051Swyllys numattr++; 1863089Swyllys 1875051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 1885051Swyllys &prik, sizeof (KMF_KEY_HANDLE_ATTR)); 1895051Swyllys numattr++; 1905051Swyllys 1915051Swyllys /* cert data that is to be signed */ 1925051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR, 1935051Swyllys &signedCert, sizeof (KMF_X509_CERTIFICATE)); 1945051Swyllys numattr++; 1955051Swyllys 1965051Swyllys /* output buffer for the signed cert */ 1975051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 1985051Swyllys &x509DER, sizeof (KMF_DATA)); 1995051Swyllys numattr++; 2005051Swyllys 2015051Swyllys if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) != 2025051Swyllys KMF_OK) { 2033089Swyllys goto cleanup; 2043089Swyllys } 2053089Swyllys 2063089Swyllys /* 2073089Swyllys * Store the cert in the DB. 2083089Swyllys */ 2095051Swyllys numattr = 0; 2105051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 2115051Swyllys &kstype, sizeof (kstype)); 2125051Swyllys numattr++; 2135051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 2145051Swyllys &x509DER, sizeof (KMF_DATA)); 2155051Swyllys numattr++; 2165051Swyllys 2175051Swyllys if (certlabel != NULL) { 2185051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR, 2195051Swyllys certlabel, strlen(certlabel)); 2205051Swyllys numattr++; 2215051Swyllys } 2225051Swyllys 2235051Swyllys kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist); 2245051Swyllys 2253089Swyllys cleanup: 2265051Swyllys kmf_free_data(&x509DER); 2275051Swyllys kmf_free_dn(&certSubject); 2285051Swyllys kmf_free_dn(&certIssuer); 229*9145SHuie-Ying.Lee@Sun.COM 230*9145SHuie-Ying.Lee@Sun.COM /* 231*9145SHuie-Ying.Lee@Sun.COM * If kmf_sign_cert or kmf_store_cert failed, then we need to clean up 232*9145SHuie-Ying.Lee@Sun.COM * the key pair from the token. 233*9145SHuie-Ying.Lee@Sun.COM */ 234*9145SHuie-Ying.Lee@Sun.COM if (kmfrv != KMF_OK) { 235*9145SHuie-Ying.Lee@Sun.COM /* delete the public key */ 236*9145SHuie-Ying.Lee@Sun.COM numattr = 0; 237*9145SHuie-Ying.Lee@Sun.COM kmf_set_attr_at_index(attrlist, numattr, 238*9145SHuie-Ying.Lee@Sun.COM KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 239*9145SHuie-Ying.Lee@Sun.COM numattr++; 240*9145SHuie-Ying.Lee@Sun.COM 241*9145SHuie-Ying.Lee@Sun.COM kmf_set_attr_at_index(attrlist, numattr, 242*9145SHuie-Ying.Lee@Sun.COM KMF_KEY_HANDLE_ATTR, &pubk, sizeof (KMF_KEY_HANDLE)); 243*9145SHuie-Ying.Lee@Sun.COM numattr++; 244*9145SHuie-Ying.Lee@Sun.COM 245*9145SHuie-Ying.Lee@Sun.COM if (tokencred != NULL && tokencred->cred != NULL) { 246*9145SHuie-Ying.Lee@Sun.COM kmf_set_attr_at_index(attrlist, numattr, 247*9145SHuie-Ying.Lee@Sun.COM KMF_CREDENTIAL_ATTR, tokencred, 248*9145SHuie-Ying.Lee@Sun.COM sizeof (KMF_CREDENTIAL)); 249*9145SHuie-Ying.Lee@Sun.COM numattr++; 250*9145SHuie-Ying.Lee@Sun.COM } 251*9145SHuie-Ying.Lee@Sun.COM 252*9145SHuie-Ying.Lee@Sun.COM (void) kmf_delete_key_from_keystore(kmfhandle, numattr, 253*9145SHuie-Ying.Lee@Sun.COM attrlist); 254*9145SHuie-Ying.Lee@Sun.COM 255*9145SHuie-Ying.Lee@Sun.COM /* delete the private key */ 256*9145SHuie-Ying.Lee@Sun.COM numattr = 0; 257*9145SHuie-Ying.Lee@Sun.COM kmf_set_attr_at_index(attrlist, numattr, 258*9145SHuie-Ying.Lee@Sun.COM KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); 259*9145SHuie-Ying.Lee@Sun.COM numattr++; 260*9145SHuie-Ying.Lee@Sun.COM 261*9145SHuie-Ying.Lee@Sun.COM kmf_set_attr_at_index(attrlist, numattr, 262*9145SHuie-Ying.Lee@Sun.COM KMF_KEY_HANDLE_ATTR, &prik, sizeof (KMF_KEY_HANDLE)); 263*9145SHuie-Ying.Lee@Sun.COM numattr++; 264*9145SHuie-Ying.Lee@Sun.COM 265*9145SHuie-Ying.Lee@Sun.COM if (tokencred != NULL && tokencred->cred != NULL) { 266*9145SHuie-Ying.Lee@Sun.COM kmf_set_attr_at_index(attrlist, numattr, 267*9145SHuie-Ying.Lee@Sun.COM KMF_CREDENTIAL_ATTR, tokencred, 268*9145SHuie-Ying.Lee@Sun.COM sizeof (KMF_CREDENTIAL)); 269*9145SHuie-Ying.Lee@Sun.COM numattr++; 270*9145SHuie-Ying.Lee@Sun.COM } 271*9145SHuie-Ying.Lee@Sun.COM 272*9145SHuie-Ying.Lee@Sun.COM (void) kmf_delete_key_from_keystore(kmfhandle, numattr, 273*9145SHuie-Ying.Lee@Sun.COM attrlist); 274*9145SHuie-Ying.Lee@Sun.COM } 275*9145SHuie-Ying.Lee@Sun.COM 2763089Swyllys return (kmfrv); 2773089Swyllys } 2783089Swyllys 2793089Swyllys static int 2803089Swyllys gencert_file(KMF_HANDLE_T kmfhandle, 2813089Swyllys KMF_KEY_ALG keyAlg, KMF_ALGORITHM_INDEX sigAlg, 2823089Swyllys int keylen, KMF_ENCODE_FORMAT fmt, 2833089Swyllys uint32_t ltime, char *subject, char *altname, 2843089Swyllys KMF_GENERALNAMECHOICES alttype, int altcrit, 2853089Swyllys KMF_BIGINT *serial, uint16_t kubits, int kucrit, 2866669Swyllys char *outcert, char *outkey, 2876051Swyllys EKU_LIST *ekulist) 2883089Swyllys { 2893089Swyllys KMF_RETURN kmfrv; 2903089Swyllys KMF_KEY_HANDLE pubk, prik; 2913089Swyllys KMF_X509_CERTIFICATE signedCert; 2923089Swyllys KMF_X509_NAME certSubject; 2933089Swyllys KMF_X509_NAME certIssuer; 2943089Swyllys KMF_DATA x509DER; 2953089Swyllys char *fullcertpath = NULL; 2963089Swyllys char *fullkeypath = NULL; 2975051Swyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL; 2985051Swyllys KMF_ATTRIBUTE attrlist[10]; 2995051Swyllys int numattr = 0; 3005051Swyllys KMF_KEY_ALG keytype; 3015051Swyllys uint32_t keylength; 3025051Swyllys KMF_ENCODE_FORMAT format; 3033089Swyllys 3043089Swyllys (void) memset(&signedCert, 0, sizeof (signedCert)); 3053089Swyllys (void) memset(&certSubject, 0, sizeof (certSubject)); 3063089Swyllys (void) memset(&certIssuer, 0, sizeof (certIssuer)); 3073089Swyllys (void) memset(&x509DER, 0, sizeof (x509DER)); 3083089Swyllys 3093089Swyllys if (EMPTYSTRING(outcert) || EMPTYSTRING(outkey)) { 3103089Swyllys cryptoerror(LOG_STDERR, 3115051Swyllys gettext("No output file was specified for " 3125051Swyllys "the cert or key\n")); 3133089Swyllys return (PK_ERR_USAGE); 3143089Swyllys } 3156669Swyllys fullcertpath = strdup(outcert); 3163089Swyllys if (verify_file(fullcertpath)) { 3173089Swyllys cryptoerror(LOG_STDERR, 3185051Swyllys gettext("Cannot write the indicated output " 3195051Swyllys "certificate file (%s).\n"), fullcertpath); 3203089Swyllys free(fullcertpath); 3213089Swyllys return (PK_ERR_USAGE); 3223089Swyllys } 3236669Swyllys 3246669Swyllys fullkeypath = strdup(outkey); 3253089Swyllys if (verify_file(fullkeypath)) { 3263089Swyllys cryptoerror(LOG_STDERR, 3275051Swyllys gettext("Cannot write the indicated output " 3285051Swyllys "key file (%s).\n"), fullkeypath); 3293089Swyllys free(fullkeypath); 3303089Swyllys free(fullcertpath); 3313089Swyllys return (PK_ERR_USAGE); 3323089Swyllys } 3333089Swyllys 3343089Swyllys /* If the subject name cannot be parsed, flag it now and exit */ 3355051Swyllys if (kmf_dn_parser(subject, &certSubject) != KMF_OK) { 3363089Swyllys cryptoerror(LOG_STDERR, 3375051Swyllys gettext("Subject name cannot be parsed (%s)\n"), subject); 3383089Swyllys return (PK_ERR_USAGE); 3393089Swyllys } 3403089Swyllys 3413089Swyllys /* For a self-signed cert, the issuser and subject are the same */ 3425051Swyllys if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) { 3433089Swyllys cryptoerror(LOG_STDERR, 3445051Swyllys gettext("Subject name cannot be parsed (%s)\n"), subject); 3455051Swyllys kmf_free_dn(&certSubject); 3463089Swyllys return (PK_ERR_USAGE); 3473089Swyllys } 3483089Swyllys 3495051Swyllys keylength = keylen; /* bits */ 3505051Swyllys keytype = keyAlg; 3515051Swyllys format = fmt; 3525051Swyllys 3535051Swyllys kmf_set_attr_at_index(attrlist, numattr, 3545051Swyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, 3555051Swyllys sizeof (kstype)); 3565051Swyllys numattr++; 3575051Swyllys 3585051Swyllys kmf_set_attr_at_index(attrlist, numattr, 3595051Swyllys KMF_KEYALG_ATTR, &keytype, 3605051Swyllys sizeof (keytype)); 3615051Swyllys numattr++; 3625051Swyllys 3635051Swyllys kmf_set_attr_at_index(attrlist, numattr, 3645051Swyllys KMF_KEYLENGTH_ATTR, &keylength, 3655051Swyllys sizeof (keylength)); 3665051Swyllys numattr++; 3673089Swyllys 3685051Swyllys if (fullkeypath != NULL) { 3695051Swyllys kmf_set_attr_at_index(attrlist, numattr, 3705051Swyllys KMF_KEY_FILENAME_ATTR, fullkeypath, 3715051Swyllys strlen(fullkeypath)); 3725051Swyllys numattr++; 3735051Swyllys } 3745051Swyllys 3755051Swyllys kmf_set_attr_at_index(attrlist, numattr, 3765051Swyllys KMF_ENCODE_FORMAT_ATTR, &format, 3775051Swyllys sizeof (format)); 3785051Swyllys numattr++; 3793089Swyllys 3805051Swyllys kmf_set_attr_at_index(attrlist, numattr, 3815051Swyllys KMF_PRIVKEY_HANDLE_ATTR, &prik, 3825051Swyllys sizeof (KMF_KEY_HANDLE)); 3835051Swyllys numattr++; 3845051Swyllys 3855051Swyllys kmf_set_attr_at_index(attrlist, numattr, 3865051Swyllys KMF_PUBKEY_HANDLE_ATTR, &pubk, 3875051Swyllys sizeof (KMF_KEY_HANDLE)); 3885051Swyllys numattr++; 3895051Swyllys 3905051Swyllys kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); 3913089Swyllys if (kmfrv != KMF_OK) { 3923089Swyllys goto cleanup; 3933089Swyllys } 3945051Swyllys 3955051Swyllys SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert), 3965051Swyllys "keypair"); 3973089Swyllys 3985051Swyllys SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number"); 3993089Swyllys 4005051Swyllys SET_VALUE(kmf_set_cert_serial(&signedCert, serial), 4015051Swyllys "serial number"); 4023089Swyllys 4035051Swyllys SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime), 4045051Swyllys "validity time"); 4053089Swyllys 4065051Swyllys SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg), 4075051Swyllys "signature algorithm"); 4083089Swyllys 4095051Swyllys SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject), 4105051Swyllys "subject name"); 4113089Swyllys 4125051Swyllys SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer), 4135051Swyllys "issuer name"); 4143089Swyllys 4153089Swyllys if (altname != NULL) 4165051Swyllys SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit, 4175051Swyllys alttype, altname), "subjectAltName"); 4183089Swyllys 4193089Swyllys if (kubits != 0) 4205051Swyllys SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits), 4215051Swyllys "KeyUsage"); 4226051Swyllys 4236051Swyllys if (ekulist != NULL) { 4246051Swyllys int i; 4256051Swyllys for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) { 4266051Swyllys SET_VALUE(kmf_add_cert_eku(&signedCert, 4276051Swyllys &ekulist->ekulist[i], 4286051Swyllys ekulist->critlist[i]), "Extended Key Usage"); 4296051Swyllys } 4306051Swyllys } 4315051Swyllys /* 4325051Swyllys * Construct attributes for the kmf_sign_cert operation. 4335051Swyllys */ 4345051Swyllys numattr = 0; 4355051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 4365051Swyllys &kstype, sizeof (kstype)); 4375051Swyllys numattr++; 4383089Swyllys 4395051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 4405051Swyllys &prik, sizeof (KMF_KEY_HANDLE_ATTR)); 4415051Swyllys numattr++; 4425051Swyllys 4435051Swyllys /* cert data that is to be signed */ 4445051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR, 4455051Swyllys &signedCert, sizeof (KMF_X509_CERTIFICATE)); 4465051Swyllys numattr++; 4475051Swyllys 4485051Swyllys /* output buffer for the signed cert */ 4495051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 4505051Swyllys &x509DER, sizeof (KMF_DATA)); 4515051Swyllys numattr++; 4525051Swyllys 4535051Swyllys if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) != 4545051Swyllys KMF_OK) { 4553089Swyllys goto cleanup; 4563089Swyllys } 4573089Swyllys 4583089Swyllys /* 4593089Swyllys * Store the cert in the DB. 4603089Swyllys */ 4615051Swyllys numattr = 0; 4625051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 4635051Swyllys &kstype, sizeof (kstype)); 4645051Swyllys numattr++; 4655051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 4665051Swyllys &x509DER, sizeof (KMF_DATA)); 4675051Swyllys numattr++; 4685051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR, 4695051Swyllys fullcertpath, strlen(fullcertpath)); 4705051Swyllys numattr++; 4715051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR, 4725051Swyllys &fmt, sizeof (fmt)); 4735051Swyllys numattr++; 4745051Swyllys 4755051Swyllys kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist); 4763089Swyllys 4773089Swyllys cleanup: 4783089Swyllys if (fullkeypath != NULL) 4793089Swyllys free(fullkeypath); 4803089Swyllys if (fullcertpath != NULL) 4813089Swyllys free(fullcertpath); 4823089Swyllys 4835051Swyllys kmf_free_data(&x509DER); 4845051Swyllys kmf_free_dn(&certSubject); 4855051Swyllys kmf_free_dn(&certIssuer); 4863089Swyllys return (kmfrv); 4873089Swyllys } 4883089Swyllys 4893089Swyllys static KMF_RETURN 4903089Swyllys gencert_nss(KMF_HANDLE_T kmfhandle, 4913089Swyllys char *token, char *subject, char *altname, 4923089Swyllys KMF_GENERALNAMECHOICES alttype, int altcrit, 4933089Swyllys char *nickname, char *dir, char *prefix, 4943089Swyllys KMF_KEY_ALG keyAlg, 4953089Swyllys KMF_ALGORITHM_INDEX sigAlg, 4963089Swyllys int keylen, char *trust, 4973089Swyllys uint32_t ltime, KMF_BIGINT *serial, uint16_t kubits, 4986051Swyllys int kucrit, KMF_CREDENTIAL *tokencred, 4996051Swyllys EKU_LIST *ekulist) 5003089Swyllys { 5013089Swyllys KMF_RETURN kmfrv; 5023089Swyllys KMF_KEY_HANDLE pubk, prik; 5033089Swyllys KMF_X509_CERTIFICATE signedCert; 5043089Swyllys KMF_X509_NAME certSubject; 5053089Swyllys KMF_X509_NAME certIssuer; 5063089Swyllys KMF_DATA x509DER; 5075051Swyllys KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS; 5085051Swyllys KMF_ATTRIBUTE attrlist[16]; 5095051Swyllys int numattr = 0; 5105051Swyllys KMF_KEY_ALG keytype; 5115051Swyllys uint32_t keylength; 5123089Swyllys 5133089Swyllys if (token == NULL) 5143089Swyllys token = DEFAULT_NSS_TOKEN; 5153089Swyllys 5163089Swyllys kmfrv = configure_nss(kmfhandle, dir, prefix); 5173089Swyllys if (kmfrv != KMF_OK) 5183089Swyllys return (kmfrv); 5193089Swyllys 5203089Swyllys (void) memset(&signedCert, 0, sizeof (signedCert)); 5213089Swyllys (void) memset(&certSubject, 0, sizeof (certSubject)); 5223089Swyllys (void) memset(&certIssuer, 0, sizeof (certIssuer)); 5233089Swyllys (void) memset(&x509DER, 0, sizeof (x509DER)); 5243089Swyllys 5253089Swyllys /* If the subject name cannot be parsed, flag it now and exit */ 5265051Swyllys if (kmf_dn_parser(subject, &certSubject) != KMF_OK) { 5273089Swyllys cryptoerror(LOG_STDERR, 5285051Swyllys gettext("Subject name cannot be parsed.\n")); 5293089Swyllys return (PK_ERR_USAGE); 5303089Swyllys } 5313089Swyllys 5323089Swyllys /* For a self-signed cert, the issuser and subject are the same */ 5335051Swyllys if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) { 5343089Swyllys cryptoerror(LOG_STDERR, 5355051Swyllys gettext("Subject name cannot be parsed.\n")); 5363089Swyllys return (PK_ERR_USAGE); 5373089Swyllys } 5383089Swyllys 5395051Swyllys keylength = keylen; /* bits */ 5405051Swyllys keytype = keyAlg; 5415051Swyllys 5425051Swyllys kmf_set_attr_at_index(attrlist, numattr, 5435051Swyllys KMF_KEYSTORE_TYPE_ATTR, &kstype, 5445051Swyllys sizeof (kstype)); 5455051Swyllys numattr++; 5465051Swyllys 5475051Swyllys kmf_set_attr_at_index(attrlist, numattr, 5485051Swyllys KMF_KEYALG_ATTR, &keytype, 5495051Swyllys sizeof (keytype)); 5505051Swyllys numattr++; 5515051Swyllys 5525051Swyllys kmf_set_attr_at_index(attrlist, numattr, 5535051Swyllys KMF_KEYLENGTH_ATTR, &keylength, 5545051Swyllys sizeof (keylength)); 5555051Swyllys numattr++; 5565051Swyllys 5575051Swyllys if (nickname != NULL) { 5585051Swyllys kmf_set_attr_at_index(attrlist, numattr, 5595051Swyllys KMF_KEYLABEL_ATTR, nickname, 5605051Swyllys strlen(nickname)); 5615051Swyllys numattr++; 5625051Swyllys } 5633089Swyllys 5646354Swyllys if (tokencred != NULL && tokencred->cred != NULL) { 5655051Swyllys kmf_set_attr_at_index(attrlist, numattr, 5665051Swyllys KMF_CREDENTIAL_ATTR, tokencred, 5675051Swyllys sizeof (KMF_CREDENTIAL)); 5685051Swyllys numattr++; 5695051Swyllys } 5703089Swyllys 5715051Swyllys if (token != NULL) { 5725051Swyllys kmf_set_attr_at_index(attrlist, numattr, 5735051Swyllys KMF_TOKEN_LABEL_ATTR, token, 5745051Swyllys strlen(token)); 5755051Swyllys numattr++; 5765051Swyllys } 5775051Swyllys 5785051Swyllys kmf_set_attr_at_index(attrlist, numattr, 5795051Swyllys KMF_PRIVKEY_HANDLE_ATTR, &prik, 5805051Swyllys sizeof (KMF_KEY_HANDLE)); 5815051Swyllys numattr++; 5825051Swyllys 5835051Swyllys kmf_set_attr_at_index(attrlist, numattr, 5845051Swyllys KMF_PUBKEY_HANDLE_ATTR, &pubk, 5855051Swyllys sizeof (KMF_KEY_HANDLE)); 5865051Swyllys numattr++; 5875051Swyllys 5885051Swyllys kmfrv = kmf_create_keypair(kmfhandle, numattr, attrlist); 5893089Swyllys if (kmfrv != KMF_OK) { 5903089Swyllys return (kmfrv); 5913089Swyllys } 5923089Swyllys 5935051Swyllys SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert), 5945051Swyllys "keypair"); 5953089Swyllys 5965051Swyllys SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number"); 5973089Swyllys 5985051Swyllys SET_VALUE(kmf_set_cert_serial(&signedCert, serial), 5995051Swyllys "serial number"); 6003089Swyllys 6015051Swyllys SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime), 6025051Swyllys "validity time"); 6033089Swyllys 6045051Swyllys SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg), 6055051Swyllys "signature algorithm"); 6063089Swyllys 6075051Swyllys SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject), 6085051Swyllys "subject name"); 6093089Swyllys 6105051Swyllys SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer), 6115051Swyllys "issuer name"); 6123089Swyllys 6133089Swyllys if (altname != NULL) 6145051Swyllys SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit, 6155051Swyllys alttype, altname), "subjectAltName"); 6163089Swyllys 6173089Swyllys if (kubits) 6185051Swyllys SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits), 6195051Swyllys "subjectAltName"); 6205051Swyllys 6216051Swyllys if (ekulist != NULL) { 6226051Swyllys int i; 6236051Swyllys for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) { 6246051Swyllys SET_VALUE(kmf_add_cert_eku(&signedCert, 6256051Swyllys &ekulist->ekulist[i], 6266051Swyllys ekulist->critlist[i]), "Extended Key Usage"); 6276051Swyllys } 6286051Swyllys } 6295051Swyllys /* 6305051Swyllys * Construct attributes for the kmf_sign_cert operation. 6315051Swyllys */ 6325051Swyllys numattr = 0; 6335051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 6345051Swyllys &kstype, sizeof (kstype)); 6355051Swyllys numattr++; 6363089Swyllys 6375051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR, 6385051Swyllys &prik, sizeof (KMF_KEY_HANDLE_ATTR)); 6395051Swyllys numattr++; 6405051Swyllys 6415051Swyllys /* cert data that is to be signed */ 6425051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR, 6435051Swyllys &signedCert, sizeof (KMF_X509_CERTIFICATE)); 6445051Swyllys numattr++; 6455051Swyllys 6465051Swyllys /* output buffer for the signed cert */ 6475051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 6485051Swyllys &x509DER, sizeof (KMF_DATA)); 6495051Swyllys numattr++; 6505051Swyllys 6515051Swyllys if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) != 6525051Swyllys KMF_OK) { 6533089Swyllys goto cleanup; 6543089Swyllys } 6553089Swyllys 6563089Swyllys /* 6573089Swyllys * Store the cert in the DB. 6583089Swyllys */ 6595051Swyllys numattr = 0; 6605051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR, 6615051Swyllys &kstype, sizeof (kstype)); 6625051Swyllys numattr++; 6635051Swyllys 6645051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR, 6655051Swyllys &x509DER, sizeof (KMF_DATA)); 6665051Swyllys numattr++; 6675051Swyllys 6685051Swyllys if (nickname != NULL) { 6695051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR, 6705051Swyllys nickname, strlen(nickname)); 6715051Swyllys numattr++; 6725051Swyllys } 6735051Swyllys 6745051Swyllys if (trust != NULL) { 6755051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TRUSTFLAG_ATTR, 6765051Swyllys trust, strlen(trust)); 6775051Swyllys numattr++; 6785051Swyllys } 6795051Swyllys 6805051Swyllys if (token != NULL) { 6815051Swyllys kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR, 6825051Swyllys token, strlen(token)); 6835051Swyllys numattr++; 6845051Swyllys } 6855051Swyllys 6865051Swyllys kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist); 6873089Swyllys 6883089Swyllys cleanup: 6895051Swyllys kmf_free_data(&x509DER); 6905051Swyllys kmf_free_dn(&certSubject); 6915051Swyllys kmf_free_dn(&certIssuer); 6923089Swyllys return (kmfrv); 6933089Swyllys } 6943089Swyllys 6953089Swyllys int 6963089Swyllys pk_gencert(int argc, char *argv[]) 6973089Swyllys { 6983089Swyllys int rv; 6993089Swyllys int opt; 7003089Swyllys extern int optind_av; 7013089Swyllys extern char *optarg_av; 7023089Swyllys KMF_KEYSTORE_TYPE kstype = 0; 7033089Swyllys char *subject = NULL; 7043089Swyllys char *tokenname = NULL; 7053089Swyllys char *dir = NULL; 7063089Swyllys char *prefix = NULL; 7073089Swyllys char *keytype = PK_DEFAULT_KEYTYPE; 7083089Swyllys int keylen = PK_DEFAULT_KEYLENGTH; 7093089Swyllys char *trust = NULL; 7103089Swyllys char *lifetime = NULL; 7113089Swyllys char *certlabel = NULL; 7123089Swyllys char *outcert = NULL; 7133089Swyllys char *outkey = NULL; 7143089Swyllys char *format = NULL; 7153089Swyllys char *serstr = NULL; 7163089Swyllys char *altname = NULL; 7173089Swyllys char *keyusagestr = NULL; 7186051Swyllys char *ekustr = NULL; 7193089Swyllys KMF_GENERALNAMECHOICES alttype = 0; 7203089Swyllys KMF_BIGINT serial = { NULL, 0 }; 7213089Swyllys uint32_t ltime; 7223089Swyllys KMF_HANDLE_T kmfhandle = NULL; 7233089Swyllys KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1; 7243089Swyllys KMF_KEY_ALG keyAlg = KMF_RSA; 7253089Swyllys KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_MD5WithRSA; 7263089Swyllys boolean_t interactive = B_FALSE; 7273089Swyllys char *subname = NULL; 7283089Swyllys KMF_CREDENTIAL tokencred = {NULL, 0}; 7293089Swyllys uint16_t kubits = 0; 7303089Swyllys int altcrit = 0, kucrit = 0; 7316051Swyllys EKU_LIST *ekulist = NULL; 7323089Swyllys 7333089Swyllys while ((opt = getopt_av(argc, argv, 7345051Swyllys "ik:(keystore)s:(subject)n:(nickname)A:(altname)" 7355051Swyllys "T:(token)d:(dir)p:(prefix)t:(keytype)y:(keylen)" 7366051Swyllys "r:(trust)L:(lifetime)l:(label)c:(outcert)e:(eku)" 7375051Swyllys "K:(outkey)S:(serial)F:(format)u:(keyusage)")) != EOF) { 7383089Swyllys 7393089Swyllys if (opt != 'i' && EMPTYSTRING(optarg_av)) 7403089Swyllys return (PK_ERR_USAGE); 7413089Swyllys 7423089Swyllys switch (opt) { 7433089Swyllys case 'A': 7443089Swyllys altname = optarg_av; 7453089Swyllys break; 7463089Swyllys case 'i': 7473089Swyllys if (interactive || subject) 7483089Swyllys return (PK_ERR_USAGE); 7493089Swyllys else 7503089Swyllys interactive = B_TRUE; 7513089Swyllys break; 7523089Swyllys case 'k': 7533089Swyllys kstype = KS2Int(optarg_av); 7543089Swyllys if (kstype == 0) 7553089Swyllys return (PK_ERR_USAGE); 7563089Swyllys break; 7573089Swyllys case 's': 7583089Swyllys if (interactive || subject) 7593089Swyllys return (PK_ERR_USAGE); 7603089Swyllys else 7613089Swyllys subject = optarg_av; 7623089Swyllys break; 7633089Swyllys case 'l': 7643089Swyllys case 'n': 7653089Swyllys if (certlabel) 7663089Swyllys return (PK_ERR_USAGE); 7673089Swyllys certlabel = optarg_av; 7683089Swyllys break; 7693089Swyllys case 'T': 7703089Swyllys if (tokenname) 7713089Swyllys return (PK_ERR_USAGE); 7723089Swyllys tokenname = optarg_av; 7733089Swyllys break; 7743089Swyllys case 'd': 7753089Swyllys if (dir) 7763089Swyllys return (PK_ERR_USAGE); 7773089Swyllys dir = optarg_av; 7783089Swyllys break; 7793089Swyllys case 'p': 7803089Swyllys if (prefix) 7813089Swyllys return (PK_ERR_USAGE); 7823089Swyllys prefix = optarg_av; 7833089Swyllys break; 7843089Swyllys case 't': 7853089Swyllys keytype = optarg_av; 7863089Swyllys break; 7873089Swyllys case 'u': 7883089Swyllys keyusagestr = optarg_av; 7893089Swyllys break; 7903089Swyllys case 'y': 7913089Swyllys if (sscanf(optarg_av, "%d", 7925051Swyllys &keylen) != 1) { 7933089Swyllys cryptoerror(LOG_STDERR, 7945051Swyllys gettext("key length must be" 7955051Swyllys "a numeric value (%s)\n"), 7965051Swyllys optarg_av); 7973089Swyllys return (PK_ERR_USAGE); 7983089Swyllys } 7993089Swyllys break; 8003089Swyllys case 'r': 8013089Swyllys if (trust) 8023089Swyllys return (PK_ERR_USAGE); 8033089Swyllys trust = optarg_av; 8043089Swyllys break; 8053089Swyllys case 'L': 8063089Swyllys if (lifetime) 8073089Swyllys return (PK_ERR_USAGE); 8083089Swyllys lifetime = optarg_av; 8093089Swyllys break; 8103089Swyllys case 'c': 8113089Swyllys if (outcert) 8123089Swyllys return (PK_ERR_USAGE); 8133089Swyllys outcert = optarg_av; 8143089Swyllys break; 8153089Swyllys case 'K': 8163089Swyllys if (outkey) 8173089Swyllys return (PK_ERR_USAGE); 8183089Swyllys outkey = optarg_av; 8193089Swyllys break; 8203089Swyllys case 'S': 8213089Swyllys serstr = optarg_av; 8223089Swyllys break; 8233089Swyllys case 'F': 8243089Swyllys if (format) 8253089Swyllys return (PK_ERR_USAGE); 8263089Swyllys format = optarg_av; 8273089Swyllys break; 8286051Swyllys case 'e': 8296051Swyllys ekustr = optarg_av; 8306051Swyllys break; 8313089Swyllys default: 8323089Swyllys return (PK_ERR_USAGE); 8333089Swyllys } 8343089Swyllys } 8353089Swyllys 8363089Swyllys /* No additional args allowed. */ 8373089Swyllys argc -= optind_av; 8383089Swyllys argv += optind_av; 8393089Swyllys if (argc) { 8403089Swyllys return (PK_ERR_USAGE); 8413089Swyllys } 8423089Swyllys 8435051Swyllys if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) { 8443089Swyllys cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n")); 8453089Swyllys return (PK_ERR_USAGE); 8463089Swyllys } 8473089Swyllys 8483089Swyllys /* Assume keystore = PKCS#11 if not specified. */ 8493089Swyllys if (kstype == 0) 8503089Swyllys kstype = KMF_KEYSTORE_PK11TOKEN; 8513089Swyllys 8525221Swyllys if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) { 8535221Swyllys if (interactive && EMPTYSTRING(certlabel)) { 8545221Swyllys (void) get_certlabel(&certlabel); 8555221Swyllys } 8565221Swyllys /* It better not be empty now */ 8575221Swyllys if (EMPTYSTRING(certlabel)) { 8585221Swyllys cryptoerror(LOG_STDERR, gettext("A label must be " 8595221Swyllys "specified to create a self-signed certificate." 8605221Swyllys "\n")); 8615221Swyllys return (PK_ERR_USAGE); 8625221Swyllys } 8633089Swyllys } else if (kstype == KMF_KEYSTORE_OPENSSL && EMPTYSTRING(outcert)) { 8643089Swyllys cryptoerror(LOG_STDERR, gettext("A certificate filename must " 8653089Swyllys "be specified to create a self-signed certificate.\n")); 8663089Swyllys return (PK_ERR_USAGE); 8673089Swyllys } 8683089Swyllys 8696884Swyllys DIR_OPTION_CHECK(kstype, dir); 8706884Swyllys 8713089Swyllys if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) { 8723089Swyllys cryptoerror(LOG_STDERR, 8733089Swyllys gettext("Error parsing format string (%s).\n"), 8743089Swyllys format); 8753089Swyllys return (PK_ERR_USAGE); 8763089Swyllys } 8773089Swyllys 8783089Swyllys if (Str2Lifetime(lifetime, <ime) != 0) { 8793089Swyllys cryptoerror(LOG_STDERR, 8805051Swyllys gettext("Error parsing lifetime string\n")); 8813089Swyllys return (PK_ERR_USAGE); 8823089Swyllys } 8833089Swyllys 8843089Swyllys if (Str2KeyType(keytype, &keyAlg, &sigAlg) != 0) { 8853089Swyllys cryptoerror(LOG_STDERR, gettext("Unrecognized keytype (%s).\n"), 8865051Swyllys keytype); 8873089Swyllys return (PK_ERR_USAGE); 8883089Swyllys } 8893089Swyllys 8903089Swyllys /* 8913089Swyllys * Check the subject name. 8923089Swyllys * If interactive is true, get it now interactively. 8933089Swyllys */ 8943089Swyllys if (interactive) { 8955221Swyllys subname = NULL; 8965221Swyllys if (get_subname(&subname) != KMF_OK || subname == NULL) { 8973089Swyllys cryptoerror(LOG_STDERR, gettext("Failed to get the " 8983089Swyllys "subject name interactively.\n")); 8993089Swyllys return (PK_ERR_USAGE); 9003089Swyllys } 9015221Swyllys if (serstr == NULL) { 9025221Swyllys (void) get_serial(&serstr); 9035221Swyllys } 9043089Swyllys } else { 9053089Swyllys if (EMPTYSTRING(subject)) { 9063089Swyllys cryptoerror(LOG_STDERR, gettext("A subject name or " 9073089Swyllys "-i must be specified to create a self-signed " 9083089Swyllys "certificate.\n")); 9093089Swyllys return (PK_ERR_USAGE); 9103089Swyllys } else { 9113089Swyllys subname = strdup(subject); 9123089Swyllys if (subname == NULL) { 9133089Swyllys cryptoerror(LOG_STDERR, 9143089Swyllys gettext("Out of memory.\n")); 9153089Swyllys return (PK_ERR_SYSTEM); 9163089Swyllys } 9173089Swyllys } 9183089Swyllys } 9193089Swyllys 9203089Swyllys if (serstr == NULL) { 9213089Swyllys (void) fprintf(stderr, gettext("A serial number " 9225051Swyllys "must be specified as a hex number when creating" 9235051Swyllys " a self-signed certificate " 9245051Swyllys "(ex: serial=0x0102030405feedface)\n")); 9253089Swyllys rv = PK_ERR_USAGE; 9263089Swyllys goto end; 9273089Swyllys } else { 9283089Swyllys uchar_t *bytes = NULL; 9293089Swyllys size_t bytelen; 9303089Swyllys 9315051Swyllys rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen); 9323089Swyllys if (rv != KMF_OK || bytes == NULL) { 9333089Swyllys (void) fprintf(stderr, gettext("serial number " 9345051Swyllys "must be specified as a hex number " 9355051Swyllys "(ex: 0x0102030405ffeeddee)\n")); 9363089Swyllys rv = PK_ERR_USAGE; 9373089Swyllys goto end; 9383089Swyllys } 9393089Swyllys serial.val = bytes; 9403089Swyllys serial.len = bytelen; 9413089Swyllys } 9423089Swyllys 9433089Swyllys if (altname != NULL) { 9443089Swyllys rv = verify_altname(altname, &alttype, &altcrit); 9453089Swyllys if (rv != KMF_OK) { 9463089Swyllys (void) fprintf(stderr, gettext("Subject AltName " 9475051Swyllys "must be specified as a name=value pair. " 9485051Swyllys "See the man page for details.\n")); 9493089Swyllys rv = PK_ERR_USAGE; 9503089Swyllys goto end; 9513089Swyllys } else { 9523089Swyllys /* advance the altname past the '=' sign */ 9533089Swyllys char *p = strchr(altname, '='); 9543089Swyllys if (p != NULL) 9553089Swyllys altname = p + 1; 9563089Swyllys } 9573089Swyllys } 9583089Swyllys 9593089Swyllys if (keyusagestr != NULL) { 9603089Swyllys rv = verify_keyusage(keyusagestr, &kubits, &kucrit); 9613089Swyllys if (rv != KMF_OK) { 9623089Swyllys (void) fprintf(stderr, gettext("KeyUsage " 9635051Swyllys "must be specified as a comma-separated list. " 9645051Swyllys "See the man page for details.\n")); 9653089Swyllys rv = PK_ERR_USAGE; 9663089Swyllys goto end; 9673089Swyllys } 9683089Swyllys } 9696051Swyllys if (ekustr != NULL) { 9706051Swyllys rv = verify_ekunames(ekustr, &ekulist); 9716051Swyllys if (rv != KMF_OK) { 9726051Swyllys (void) fprintf(stderr, gettext("EKUs must " 9736051Swyllys "be specified as a comma-separated list. " 9746051Swyllys "See the man page for details.\n")); 9756051Swyllys rv = PK_ERR_USAGE; 9766051Swyllys goto end; 9776051Swyllys } 9786051Swyllys } 9793089Swyllys 9803089Swyllys if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) { 9813089Swyllys if (tokenname == NULL || !strlen(tokenname)) { 9823089Swyllys if (kstype == KMF_KEYSTORE_NSS) { 9833089Swyllys tokenname = "internal"; 9843089Swyllys } else { 9853089Swyllys tokenname = PK_DEFAULT_PK11TOKEN; 9863089Swyllys } 9873089Swyllys } 9883089Swyllys 9893089Swyllys (void) get_token_password(kstype, tokenname, &tokencred); 9903089Swyllys } 9913089Swyllys 9923089Swyllys if (kstype == KMF_KEYSTORE_NSS) { 9933089Swyllys if (dir == NULL) 9943089Swyllys dir = PK_DEFAULT_DIRECTORY; 9953089Swyllys 9963089Swyllys rv = gencert_nss(kmfhandle, 9975051Swyllys tokenname, subname, altname, alttype, altcrit, 9985051Swyllys certlabel, dir, prefix, keyAlg, sigAlg, keylen, 9996051Swyllys trust, ltime, &serial, kubits, kucrit, &tokencred, 10006051Swyllys ekulist); 10013089Swyllys 10023089Swyllys } else if (kstype == KMF_KEYSTORE_PK11TOKEN) { 10033089Swyllys rv = gencert_pkcs11(kmfhandle, 10045051Swyllys tokenname, subname, altname, alttype, altcrit, 10055051Swyllys certlabel, keyAlg, sigAlg, keylen, ltime, 10066051Swyllys &serial, kubits, kucrit, &tokencred, ekulist); 10073089Swyllys 10083089Swyllys } else if (kstype == KMF_KEYSTORE_OPENSSL) { 10093089Swyllys rv = gencert_file(kmfhandle, 10105051Swyllys keyAlg, sigAlg, keylen, fmt, 10115051Swyllys ltime, subname, altname, alttype, altcrit, 10126669Swyllys &serial, kubits, kucrit, outcert, outkey, 10136051Swyllys ekulist); 10143089Swyllys } 10153089Swyllys 10163089Swyllys if (rv != KMF_OK) 10173089Swyllys display_error(kmfhandle, rv, 10185051Swyllys gettext("Error creating certificate and keypair")); 10193089Swyllys end: 10206051Swyllys if (ekulist != NULL) 10216051Swyllys free_eku_list(ekulist); 10223089Swyllys if (subname) 10233089Swyllys free(subname); 10243089Swyllys if (tokencred.cred != NULL) 10253089Swyllys free(tokencred.cred); 10263089Swyllys 10273089Swyllys if (serial.val != NULL) 10283089Swyllys free(serial.val); 10293089Swyllys 10305051Swyllys (void) kmf_finalize(kmfhandle); 10313089Swyllys return (rv); 10323089Swyllys } 1033