gencert.c revision 3089:8ddeb2ace8aa
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#pragma ident	"%Z%%M%	%I%	%E% SMI"
27
28#include <stdio.h>
29#include <string.h>
30#include <ctype.h>
31#include <malloc.h>
32#include <libgen.h>
33#include <errno.h>
34#include <cryptoutil.h>
35#include <security/cryptoki.h>
36#include "common.h"
37
38#include <kmfapi.h>
39
40#define	SET_VALUE(f, s) \
41	kmfrv = f; \
42	if (kmfrv != KMF_OK) { \
43		cryptoerror(LOG_STDERR, \
44			gettext("Failed to set %s: 0x%02x\n"), \
45			s, kmfrv); \
46		goto cleanup; \
47	}
48
49static int
50gencert_pkcs11(KMF_HANDLE_T kmfhandle,
51	char *token, char *subject, char *altname,
52	KMF_GENERALNAMECHOICES alttype, int altcrit,
53	char *certlabel, KMF_KEY_ALG keyAlg,
54	KMF_ALGORITHM_INDEX sigAlg,
55	int keylen, uint32_t ltime, KMF_BIGINT *serial,
56	uint16_t kubits, int kucrit, KMF_CREDENTIAL *tokencred)
57{
58	KMF_RETURN kmfrv = KMF_OK;
59	KMF_CREATEKEYPAIR_PARAMS kp_params;
60	KMF_STORECERT_PARAMS sc_params;
61	KMF_KEY_HANDLE pubk, prik;
62	KMF_X509_CERTIFICATE signedCert;
63	KMF_X509_NAME	certSubject;
64	KMF_X509_NAME	certIssuer;
65	KMF_DATA x509DER;
66
67	(void) memset(&signedCert, 0, sizeof (signedCert));
68	(void) memset(&certSubject, 0, sizeof (certSubject));
69	(void) memset(&certIssuer, 0, sizeof (certIssuer));
70	(void) memset(&x509DER, 0, sizeof (x509DER));
71	(void) memset(&kp_params, 0, sizeof (kp_params));
72
73	/* If the subject name cannot be parsed, flag it now and exit */
74	if (KMF_DNParser(subject, &certSubject) != KMF_OK) {
75		cryptoerror(LOG_STDERR,
76			gettext("Subject name cannot be parsed.\n"));
77		return (PK_ERR_USAGE);
78	}
79
80	/* For a self-signed cert, the issuser and subject are the same */
81	if (KMF_DNParser(subject, &certIssuer) != KMF_OK) {
82		cryptoerror(LOG_STDERR,
83			gettext("Subject name cannot be parsed.\n"));
84		return (PK_ERR_USAGE);
85	}
86
87	kp_params.kstype = KMF_KEYSTORE_PK11TOKEN;
88	kp_params.keylabel = certlabel;
89	kp_params.keylength = keylen; /* bits */
90	kp_params.keytype = keyAlg;
91	kp_params.cred.cred = tokencred->cred;
92	kp_params.cred.credlen = tokencred->credlen;
93
94	/* Select a PKCS11 token */
95	kmfrv = select_token(kmfhandle, token, FALSE);
96
97	if (kmfrv != KMF_OK) {
98		return (kmfrv);
99	}
100
101	kmfrv = KMF_CreateKeypair(kmfhandle, &kp_params, &prik, &pubk);
102	if (kmfrv != KMF_OK) {
103		return (kmfrv);
104	}
105
106	SET_VALUE(KMF_SetCertPubKey(kmfhandle, &pubk, &signedCert),
107			"keypair");
108
109	SET_VALUE(KMF_SetCertVersion(&signedCert, 2), "version number");
110
111	SET_VALUE(KMF_SetCertSerialNumber(&signedCert, serial),
112			"serial number");
113
114	SET_VALUE(KMF_SetCertValidityTimes(&signedCert, NULL, ltime),
115		"validity time");
116
117	SET_VALUE(KMF_SetCertSignatureAlgorithm(&signedCert, sigAlg),
118		"signature algorithm");
119
120	SET_VALUE(KMF_SetCertSubjectName(&signedCert, &certSubject),
121		"subject name");
122
123	SET_VALUE(KMF_SetCertIssuerName(&signedCert, &certIssuer),
124		"issuer name");
125
126	if (altname != NULL)
127		SET_VALUE(KMF_SetCertSubjectAltName(&signedCert, altcrit,
128			alttype, altname), "subjectAltName");
129
130	if (kubits != 0)
131		SET_VALUE(KMF_SetCertKeyUsage(&signedCert, kucrit, kubits),
132			"KeyUsage");
133
134	if ((kmfrv = KMF_SignCertRecord(kmfhandle, &prik,
135		&signedCert, &x509DER)) != KMF_OK) {
136		goto cleanup;
137	}
138
139	(void) memset(&sc_params, 0, sizeof (sc_params));
140	sc_params.kstype = KMF_KEYSTORE_PK11TOKEN;
141	sc_params.certLabel = certlabel;
142
143	/*
144	 * Store the cert in the DB.
145	 */
146	kmfrv = KMF_StoreCert(kmfhandle, &sc_params, &x509DER);
147
148cleanup:
149	KMF_FreeData(&x509DER);
150	KMF_FreeDN(&certSubject);
151	KMF_FreeDN(&certIssuer);
152	return (kmfrv);
153}
154
155static int
156gencert_file(KMF_HANDLE_T kmfhandle,
157	KMF_KEY_ALG keyAlg, KMF_ALGORITHM_INDEX sigAlg,
158	int keylen, KMF_ENCODE_FORMAT fmt,
159	uint32_t ltime, char *subject, char *altname,
160	KMF_GENERALNAMECHOICES alttype, int altcrit,
161	KMF_BIGINT *serial, uint16_t kubits, int kucrit,
162	char *dir, char *outcert, char *outkey)
163{
164	KMF_RETURN kmfrv;
165	KMF_CREATEKEYPAIR_PARAMS kp_params;
166	KMF_STORECERT_PARAMS sc_params;
167	KMF_KEY_HANDLE pubk, prik;
168	KMF_X509_CERTIFICATE signedCert;
169	KMF_X509_NAME	certSubject;
170	KMF_X509_NAME	certIssuer;
171	KMF_DATA x509DER;
172	char *fullcertpath = NULL;
173	char *fullkeypath = NULL;
174
175	(void) memset(&signedCert, 0, sizeof (signedCert));
176	(void) memset(&certSubject, 0, sizeof (certSubject));
177	(void) memset(&certIssuer, 0, sizeof (certIssuer));
178	(void) memset(&x509DER, 0, sizeof (x509DER));
179	(void) memset(&kp_params, 0, sizeof (kp_params));
180	(void) memset(&sc_params, 0, sizeof (sc_params));
181
182	if (EMPTYSTRING(outcert) || EMPTYSTRING(outkey)) {
183		cryptoerror(LOG_STDERR,
184			gettext("No output file was specified for "
185				"the cert or key\n"));
186		return (PK_ERR_USAGE);
187	}
188	if (dir != NULL) {
189		fullcertpath = get_fullpath(dir, outcert);
190		if (fullcertpath == NULL) {
191			cryptoerror(LOG_STDERR,
192				gettext("Cannot create file %s in "
193					"directory %s\n"), dir, outcert);
194			return (PK_ERR_USAGE);
195		}
196	} else {
197		fullcertpath = strdup(outcert);
198	}
199	if (verify_file(fullcertpath)) {
200		cryptoerror(LOG_STDERR,
201			gettext("Cannot write the indicated output "
202				"certificate file (%s).\n"),
203				fullcertpath);
204		free(fullcertpath);
205		return (PK_ERR_USAGE);
206	}
207	if (dir != NULL) {
208		fullkeypath = get_fullpath(dir, outkey);
209		if (fullkeypath == NULL) {
210			cryptoerror(LOG_STDERR,
211				gettext("Cannot create file %s in "
212					"directory %s\n"), dir, outkey);
213			free(fullcertpath);
214			return (PK_ERR_USAGE);
215		}
216	} else {
217		fullkeypath = strdup(outkey);
218	}
219	if (verify_file(fullkeypath)) {
220		cryptoerror(LOG_STDERR,
221			gettext("Cannot write the indicated output "
222				"key file (%s).\n"),
223				fullkeypath);
224		free(fullkeypath);
225		free(fullcertpath);
226		return (PK_ERR_USAGE);
227	}
228
229	/* If the subject name cannot be parsed, flag it now and exit */
230	if (KMF_DNParser(subject, &certSubject) != KMF_OK) {
231		cryptoerror(LOG_STDERR,
232			gettext("Subject name cannot be parsed (%s)\n"),
233			subject);
234		return (PK_ERR_USAGE);
235	}
236
237	/* For a self-signed cert, the issuser and subject are the same */
238	if (KMF_DNParser(subject, &certIssuer) != KMF_OK) {
239		cryptoerror(LOG_STDERR,
240			gettext("Subject name cannot be parsed (%s)\n"),
241			subject);
242		KMF_FreeDN(&certSubject);
243		return (PK_ERR_USAGE);
244	}
245
246	kp_params.kstype = KMF_KEYSTORE_OPENSSL;
247	kp_params.keylength = keylen; /* bits */
248	kp_params.keytype = keyAlg;
249
250	kp_params.sslparms.keyfile = fullkeypath;
251	kp_params.sslparms.format = fmt;
252
253	kmfrv = KMF_CreateKeypair(kmfhandle, &kp_params, &prik, &pubk);
254	if (kmfrv != KMF_OK) {
255		goto cleanup;
256	}
257	SET_VALUE(KMF_SetCertPubKey(kmfhandle, &pubk, &signedCert),
258		"keypair");
259
260	SET_VALUE(KMF_SetCertVersion(&signedCert, 2), "version number");
261
262	SET_VALUE(KMF_SetCertSerialNumber(&signedCert, serial),
263		"serial number");
264
265	SET_VALUE(KMF_SetCertValidityTimes(&signedCert, NULL, ltime),
266		"validity time");
267
268	SET_VALUE(KMF_SetCertSignatureAlgorithm(&signedCert, sigAlg),
269		"signature algorithm");
270
271	SET_VALUE(KMF_SetCertSubjectName(&signedCert, &certSubject),
272		"subject name");
273
274	SET_VALUE(KMF_SetCertIssuerName(&signedCert, &certIssuer),
275		"issuer name");
276
277	if (altname != NULL)
278		SET_VALUE(KMF_SetCertSubjectAltName(&signedCert, altcrit,
279			alttype, altname), "subjectAltName");
280
281	if (kubits != 0)
282		SET_VALUE(KMF_SetCertKeyUsage(&signedCert, kucrit, kubits),
283			"KeyUsage");
284
285	if ((kmfrv = KMF_SignCertRecord(kmfhandle, &prik,
286		&signedCert, &x509DER)) != KMF_OK) {
287		goto cleanup;
288	}
289
290	sc_params.kstype = KMF_KEYSTORE_OPENSSL;
291	sc_params.sslparms.certfile = fullcertpath;
292	sc_params.sslparms.keyfile = fullkeypath;
293	sc_params.sslparms.format = fmt;
294	/*
295	 * Store the cert in the DB.
296	 */
297	kmfrv = KMF_StoreCert(kmfhandle, &sc_params, &x509DER);
298
299cleanup:
300	if (fullkeypath != NULL)
301		free(fullkeypath);
302	if (fullcertpath != NULL)
303		free(fullcertpath);
304
305	KMF_FreeData(&x509DER);
306	KMF_FreeDN(&certSubject);
307	KMF_FreeDN(&certIssuer);
308	return (kmfrv);
309}
310
311static KMF_RETURN
312gencert_nss(KMF_HANDLE_T kmfhandle,
313	char *token, char *subject, char *altname,
314	KMF_GENERALNAMECHOICES alttype, int altcrit,
315	char *nickname, char *dir, char *prefix,
316	KMF_KEY_ALG keyAlg,
317	KMF_ALGORITHM_INDEX sigAlg,
318	int keylen, char *trust,
319	uint32_t ltime, KMF_BIGINT *serial, uint16_t kubits,
320	int kucrit, KMF_CREDENTIAL *tokencred)
321{
322	KMF_RETURN kmfrv;
323	KMF_CREATEKEYPAIR_PARAMS kp_params;
324	KMF_STORECERT_PARAMS sc_params;
325	KMF_KEY_HANDLE pubk, prik;
326	KMF_X509_CERTIFICATE signedCert;
327	KMF_X509_NAME	certSubject;
328	KMF_X509_NAME	certIssuer;
329	KMF_DATA x509DER;
330
331	if (token == NULL)
332		token = DEFAULT_NSS_TOKEN;
333
334	kmfrv = configure_nss(kmfhandle, dir, prefix);
335	if (kmfrv != KMF_OK)
336		return (kmfrv);
337
338	(void) memset(&signedCert, 0, sizeof (signedCert));
339	(void) memset(&certSubject, 0, sizeof (certSubject));
340	(void) memset(&certIssuer, 0, sizeof (certIssuer));
341	(void) memset(&x509DER, 0, sizeof (x509DER));
342
343	/* If the subject name cannot be parsed, flag it now and exit */
344	if (KMF_DNParser(subject, &certSubject) != KMF_OK) {
345		cryptoerror(LOG_STDERR,
346			gettext("Subject name cannot be parsed.\n"));
347		return (PK_ERR_USAGE);
348	}
349
350	/* For a self-signed cert, the issuser and subject are the same */
351	if (KMF_DNParser(subject, &certIssuer) != KMF_OK) {
352		cryptoerror(LOG_STDERR,
353			gettext("Subject name cannot be parsed.\n"));
354		return (PK_ERR_USAGE);
355	}
356
357	(void) memset(&kp_params, 0, sizeof (kp_params));
358
359	kp_params.kstype = KMF_KEYSTORE_NSS;
360	kp_params.keylabel = nickname;
361	kp_params.keylength = keylen; /* bits */
362	kp_params.keytype = keyAlg;
363	kp_params.cred.cred = tokencred->cred;
364	kp_params.cred.credlen = tokencred->credlen;
365	kp_params.nssparms.slotlabel = token;
366
367	kmfrv = KMF_CreateKeypair(kmfhandle, &kp_params, &prik, &pubk);
368	if (kmfrv != KMF_OK) {
369		return (kmfrv);
370	}
371
372	SET_VALUE(KMF_SetCertPubKey(kmfhandle, &pubk, &signedCert),
373			"keypair");
374
375	SET_VALUE(KMF_SetCertVersion(&signedCert, 2), "version number");
376
377	SET_VALUE(KMF_SetCertSerialNumber(&signedCert, serial),
378			"serial number");
379
380	SET_VALUE(KMF_SetCertValidityTimes(&signedCert, NULL, ltime),
381		"validity time");
382
383	SET_VALUE(KMF_SetCertSignatureAlgorithm(&signedCert, sigAlg),
384		"signature algorithm");
385
386	SET_VALUE(KMF_SetCertSubjectName(&signedCert, &certSubject),
387		"subject name");
388
389	SET_VALUE(KMF_SetCertIssuerName(&signedCert, &certIssuer),
390		"issuer name");
391
392	if (altname != NULL)
393		SET_VALUE(KMF_SetCertSubjectAltName(&signedCert, altcrit,
394			alttype, altname), "subjectAltName");
395
396	if (kubits)
397		SET_VALUE(KMF_SetCertKeyUsage(&signedCert, kucrit, kubits),
398			"subjectAltName");
399
400	if ((kmfrv = KMF_SignCertRecord(kmfhandle, &prik,
401		&signedCert, &x509DER)) != KMF_OK) {
402		goto cleanup;
403	}
404
405	sc_params.kstype = KMF_KEYSTORE_NSS;
406	sc_params.certLabel = nickname;
407	sc_params.nssparms.trustflag = trust;
408	sc_params.nssparms.slotlabel = token;
409
410	/*
411	 * Store the cert in the DB.
412	 */
413	kmfrv = KMF_StoreCert(kmfhandle, &sc_params, &x509DER);
414
415cleanup:
416	KMF_FreeData(&x509DER);
417	KMF_FreeDN(&certSubject);
418	KMF_FreeDN(&certIssuer);
419	return (kmfrv);
420}
421
422int
423pk_gencert(int argc, char *argv[])
424{
425	int rv;
426	int opt;
427	extern int	optind_av;
428	extern char	*optarg_av;
429	KMF_KEYSTORE_TYPE kstype = 0;
430	char *subject = NULL;
431	char *tokenname = NULL;
432	char *dir = NULL;
433	char *prefix = NULL;
434	char *keytype = PK_DEFAULT_KEYTYPE;
435	int keylen = PK_DEFAULT_KEYLENGTH;
436	char *trust = NULL;
437	char *lifetime = NULL;
438	char *certlabel = NULL;
439	char *outcert = NULL;
440	char *outkey = NULL;
441	char *format = NULL;
442	char *serstr = NULL;
443	char *altname = NULL;
444	char *keyusagestr = NULL;
445	KMF_GENERALNAMECHOICES alttype = 0;
446	KMF_BIGINT serial = { NULL, 0 };
447	uint32_t ltime;
448	KMF_HANDLE_T kmfhandle = NULL;
449	KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1;
450	KMF_KEY_ALG keyAlg = KMF_RSA;
451	KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_MD5WithRSA;
452	boolean_t interactive = B_FALSE;
453	char *subname = NULL;
454	KMF_CREDENTIAL tokencred = {NULL, 0};
455	uint16_t kubits = 0;
456	int altcrit = 0, kucrit = 0;
457
458	while ((opt = getopt_av(argc, argv,
459		"ik:(keystore)s:(subject)n:(nickname)A:(altname)"
460		"T:(token)d:(dir)p:(prefix)t:(keytype)y:(keylen)"
461		"r:(trust)L:(lifetime)l:(label)c:(outcert)"
462		"K:(outkey)S:(serial)F:(format)u:(keyusage)")) != EOF) {
463
464		if (opt != 'i' && EMPTYSTRING(optarg_av))
465			return (PK_ERR_USAGE);
466
467		switch (opt) {
468			case 'A':
469				altname = optarg_av;
470				break;
471			case 'i':
472				if (interactive || subject)
473					return (PK_ERR_USAGE);
474				else
475					interactive = B_TRUE;
476				break;
477			case 'k':
478				kstype = KS2Int(optarg_av);
479				if (kstype == 0)
480					return (PK_ERR_USAGE);
481				break;
482			case 's':
483				if (interactive || subject)
484					return (PK_ERR_USAGE);
485				else
486					subject = optarg_av;
487				break;
488			case 'l':
489			case 'n':
490				if (certlabel)
491					return (PK_ERR_USAGE);
492				certlabel = optarg_av;
493				break;
494			case 'T':
495				if (tokenname)
496					return (PK_ERR_USAGE);
497				tokenname = optarg_av;
498				break;
499			case 'd':
500				if (dir)
501					return (PK_ERR_USAGE);
502				dir = optarg_av;
503				break;
504			case 'p':
505				if (prefix)
506					return (PK_ERR_USAGE);
507				prefix = optarg_av;
508				break;
509			case 't':
510				keytype = optarg_av;
511				break;
512			case 'u':
513				keyusagestr = optarg_av;
514				break;
515			case 'y':
516				if (sscanf(optarg_av, "%d",
517					&keylen) != 1) {
518					cryptoerror(LOG_STDERR,
519						gettext("key length must be"
520						"a numeric value (%s)\n"),
521						optarg_av);
522					return (PK_ERR_USAGE);
523				}
524				break;
525			case 'r':
526				if (trust)
527					return (PK_ERR_USAGE);
528				trust = optarg_av;
529				break;
530			case 'L':
531				if (lifetime)
532					return (PK_ERR_USAGE);
533				lifetime = optarg_av;
534				break;
535			case 'c':
536				if (outcert)
537					return (PK_ERR_USAGE);
538				outcert = optarg_av;
539				break;
540			case 'K':
541				if (outkey)
542					return (PK_ERR_USAGE);
543				outkey = optarg_av;
544				break;
545			case 'S':
546				serstr = optarg_av;
547				break;
548			case 'F':
549				if (format)
550					return (PK_ERR_USAGE);
551				format = optarg_av;
552				break;
553			default:
554				return (PK_ERR_USAGE);
555		}
556	}
557
558	/* No additional args allowed. */
559	argc -= optind_av;
560	argv += optind_av;
561	if (argc) {
562		return (PK_ERR_USAGE);
563	}
564
565	if ((rv = KMF_Initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
566		cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n"));
567		return (PK_ERR_USAGE);
568	}
569
570	/* Assume keystore = PKCS#11 if not specified. */
571	if (kstype == 0)
572		kstype = KMF_KEYSTORE_PK11TOKEN;
573
574	if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) &&
575	    EMPTYSTRING(certlabel)) {
576		cryptoerror(LOG_STDERR, gettext("A label must be specified "
577		    "to create a self-signed certificate.\n"));
578		return (PK_ERR_USAGE);
579	} else if (kstype == KMF_KEYSTORE_OPENSSL && EMPTYSTRING(outcert)) {
580		cryptoerror(LOG_STDERR, gettext("A certificate filename must "
581		    "be specified to create a self-signed certificate.\n"));
582		return (PK_ERR_USAGE);
583	}
584
585	if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) {
586		cryptoerror(LOG_STDERR,
587		    gettext("Error parsing format string (%s).\n"),
588		    format);
589		return (PK_ERR_USAGE);
590	}
591
592	if (Str2Lifetime(lifetime, &ltime) != 0) {
593		cryptoerror(LOG_STDERR,
594			gettext("Error parsing lifetime string\n"));
595		return (PK_ERR_USAGE);
596	}
597
598	if (Str2KeyType(keytype, &keyAlg, &sigAlg) != 0) {
599		cryptoerror(LOG_STDERR, gettext("Unrecognized keytype (%s).\n"),
600			keytype);
601		return (PK_ERR_USAGE);
602	}
603
604
605	/*
606	 * Check the subject name.
607	 * If interactive is true, get it now interactively.
608	 */
609	if (interactive) {
610		if (get_subname(&subname) != KMF_OK) {
611			cryptoerror(LOG_STDERR, gettext("Failed to get the "
612			    "subject name interactively.\n"));
613			return (PK_ERR_USAGE);
614		}
615	} else {
616		if (EMPTYSTRING(subject)) {
617			cryptoerror(LOG_STDERR, gettext("A subject name or "
618			    "-i must be specified to create a self-signed "
619			    "certificate.\n"));
620			return (PK_ERR_USAGE);
621		} else {
622			subname = strdup(subject);
623			if (subname == NULL) {
624				cryptoerror(LOG_STDERR,
625				    gettext("Out of memory.\n"));
626				return (PK_ERR_SYSTEM);
627			}
628		}
629	}
630
631	if (serstr == NULL) {
632		(void) fprintf(stderr, gettext("A serial number "
633			"must be specified as a hex number when creating"
634			" a self-signed certificate "
635			"(ex: serno=0x0102030405feedface)\n"));
636		rv = PK_ERR_USAGE;
637		goto end;
638	} else {
639		uchar_t *bytes = NULL;
640		size_t bytelen;
641
642		rv = KMF_HexString2Bytes((uchar_t *)serstr, &bytes, &bytelen);
643		if (rv != KMF_OK || bytes == NULL) {
644			(void) fprintf(stderr, gettext("serial number "
645				"must be specified as a hex number "
646				"(ex: 0x0102030405ffeeddee)\n"));
647			rv = PK_ERR_USAGE;
648			goto end;
649		}
650		serial.val = bytes;
651		serial.len = bytelen;
652	}
653
654	if (altname != NULL) {
655		rv = verify_altname(altname, &alttype, &altcrit);
656		if (rv != KMF_OK) {
657			(void) fprintf(stderr, gettext("Subject AltName "
658				"must be specified as a name=value pair. "
659				"See the man page for details.\n"));
660			rv = PK_ERR_USAGE;
661			goto end;
662		} else {
663			/* advance the altname past the '=' sign */
664			char *p = strchr(altname, '=');
665			if (p != NULL)
666				altname = p + 1;
667		}
668	}
669
670	if (keyusagestr != NULL) {
671		rv = verify_keyusage(keyusagestr, &kubits, &kucrit);
672		if (rv != KMF_OK) {
673			(void) fprintf(stderr, gettext("KeyUsage "
674				"must be specified as a comma-separated list. "
675				"See the man page for details.\n"));
676			rv = PK_ERR_USAGE;
677			goto end;
678		}
679	}
680
681	if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) {
682		if (tokenname == NULL || !strlen(tokenname)) {
683			if (kstype == KMF_KEYSTORE_NSS) {
684				tokenname = "internal";
685			} else  {
686				tokenname = PK_DEFAULT_PK11TOKEN;
687			}
688		}
689
690		(void) get_token_password(kstype, tokenname, &tokencred);
691	}
692
693	if (kstype == KMF_KEYSTORE_NSS) {
694		if (dir == NULL)
695			dir = PK_DEFAULT_DIRECTORY;
696
697		rv = gencert_nss(kmfhandle,
698			tokenname, subname, altname, alttype, altcrit,
699			certlabel, dir, prefix, keyAlg, sigAlg, keylen,
700			trust, ltime, &serial, kubits, kucrit, &tokencred);
701
702	} else if (kstype == KMF_KEYSTORE_PK11TOKEN) {
703		rv = gencert_pkcs11(kmfhandle,
704			tokenname, subname, altname, alttype, altcrit,
705			certlabel, keyAlg, sigAlg, keylen, ltime,
706			&serial, kubits, kucrit, &tokencred);
707
708	} else if (kstype == KMF_KEYSTORE_OPENSSL) {
709		rv = gencert_file(kmfhandle,
710			keyAlg, sigAlg, keylen, fmt,
711			ltime, subname, altname, alttype, altcrit,
712			&serial, kubits, kucrit, dir, outcert, outkey);
713	}
714
715	if (rv != KMF_OK)
716		display_error(kmfhandle, rv,
717			gettext("Error creating certificate and keypair"));
718end:
719	if (subname)
720		free(subname);
721	if (tokencred.cred != NULL)
722		free(tokencred.cred);
723
724	if (serial.val != NULL)
725		free(serial.val);
726
727	(void) KMF_Finalize(kmfhandle);
728	return (rv);
729}
730