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 %s: 0x%02\n"), \
45 			s, kmfrv); \
46 		goto cleanup; \
47 	}
48 
49 static KMF_RETURN
50 gencsr_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 	int keylen,
55 	uint16_t kubits, int kucrit,
56 	KMF_ENCODE_FORMAT fmt, char *csrfile,
57 	KMF_CREDENTIAL *tokencred)
58 {
59 	KMF_RETURN kmfrv = KMF_OK;
60 	KMF_CREATEKEYPAIR_PARAMS kp_params;
61 	KMF_DELETEKEY_PARAMS dk_params;
62 	KMF_KEY_HANDLE pubk, prik;
63 	KMF_X509_NAME	csrSubject;
64 	KMF_CSR_DATA	csr;
65 	KMF_ALGORITHM_INDEX sigAlg;
66 	KMF_DATA signedCsr = {NULL, 0};
67 
68 	(void) memset(&csr, 0, sizeof (csr));
69 	(void) memset(&csrSubject, 0, sizeof (csrSubject));
70 	(void) memset(&kp_params, 0, sizeof (kp_params));
71 
72 	if (keyAlg == KMF_DSA)
73 		sigAlg = KMF_ALGID_SHA1WithDSA;
74 	else
75 		sigAlg = KMF_ALGID_MD5WithRSA;
76 
77 
78 	/* If the subject name cannot be parsed, flag it now and exit */
79 	if ((kmfrv = KMF_DNParser(subject, &csrSubject)) != KMF_OK) {
80 		return (kmfrv);
81 	}
82 
83 	kp_params.kstype = KMF_KEYSTORE_PK11TOKEN;
84 	kp_params.keylabel = certlabel;
85 	kp_params.keylength = keylen; /* bits */
86 	kp_params.keytype = keyAlg;
87 	kp_params.cred.cred = tokencred->cred;
88 	kp_params.cred.credlen = tokencred->credlen;
89 
90 	/* Select a PKCS11 token */
91 	kmfrv = select_token(kmfhandle, token, FALSE);
92 	if (kmfrv != KMF_OK) {
93 		return (kmfrv);
94 	}
95 
96 	kmfrv = KMF_CreateKeypair(kmfhandle, &kp_params, &prik, &pubk);
97 	if (kmfrv != KMF_OK) {
98 		return (kmfrv);
99 	}
100 
101 	SET_VALUE(KMF_SetCSRPubKey(kmfhandle, &pubk, &csr), "keypair");
102 
103 	SET_VALUE(KMF_SetCSRVersion(&csr, 2), "version number");
104 
105 	SET_VALUE(KMF_SetCSRSubjectName(&csr, &csrSubject),
106 		"subject name");
107 
108 	SET_VALUE(KMF_SetCSRSignatureAlgorithm(&csr, sigAlg),
109 		"SignatureAlgorithm");
110 
111 	if (altname != NULL) {
112 		SET_VALUE(KMF_SetCSRSubjectAltName(&csr, altname, altcrit,
113 			alttype), "SetCSRSubjectAltName");
114 	}
115 
116 	if (kubits != 0) {
117 		SET_VALUE(KMF_SetCSRKeyUsage(&csr, kucrit, kubits),
118 			"SetCSRKeyUsage");
119 	}
120 
121 	if ((kmfrv = KMF_SignCSR(kmfhandle, &csr, &prik, &signedCsr)) ==
122 		KMF_OK) {
123 		kmfrv = KMF_CreateCSRFile(&signedCsr, fmt, csrfile);
124 	}
125 
126 cleanup:
127 	(void) KMF_FreeData(&signedCsr);
128 	(void) KMF_FreeKMFKey(kmfhandle, &prik);
129 	/* delete the key */
130 	(void) memset(&dk_params, 0, sizeof (dk_params));
131 	dk_params.kstype = KMF_KEYSTORE_PK11TOKEN;
132 	(void) KMF_DeleteKeyFromKeystore(kmfhandle, &dk_params, &pubk);
133 	(void) KMF_FreeSignedCSR(&csr);
134 
135 	return (kmfrv);
136 }
137 
138 static KMF_RETURN
139 gencsr_file(KMF_HANDLE_T kmfhandle,
140 	KMF_KEY_ALG keyAlg,
141 	int keylen, KMF_ENCODE_FORMAT fmt,
142 	char *subject, char *altname, KMF_GENERALNAMECHOICES alttype,
143 	int altcrit, uint16_t kubits, int kucrit,
144 	char *dir, char *outcsr, char *outkey)
145 {
146 	KMF_RETURN kmfrv;
147 	KMF_CREATEKEYPAIR_PARAMS kp_params;
148 	KMF_KEY_HANDLE pubk, prik;
149 	KMF_X509_NAME	csrSubject;
150 	KMF_CSR_DATA	csr;
151 	KMF_ALGORITHM_INDEX sigAlg;
152 	KMF_DATA signedCsr = {NULL, 0};
153 	char *fullcsrpath = NULL;
154 	char *fullkeypath = NULL;
155 
156 	(void) memset(&csr, 0, sizeof (csr));
157 	(void) memset(&csrSubject, 0, sizeof (csrSubject));
158 	(void) memset(&kp_params, 0, sizeof (kp_params));
159 
160 	if (EMPTYSTRING(outcsr) || EMPTYSTRING(outkey)) {
161 		cryptoerror(LOG_STDERR,
162 			gettext("No output file was specified for "
163 				"the csr or key\n"));
164 		return (KMF_ERR_BAD_PARAMETER);
165 	}
166 	if (dir != NULL) {
167 		fullcsrpath = get_fullpath(dir, outcsr);
168 		if (fullcsrpath == NULL) {
169 			cryptoerror(LOG_STDERR,
170 				gettext("Cannot create file %s in "
171 					"directory %s\n"), dir, outcsr);
172 			return (PK_ERR_USAGE);
173 		}
174 	} else {
175 		fullcsrpath = strdup(outcsr);
176 	}
177 	if (verify_file(fullcsrpath)) {
178 		cryptoerror(LOG_STDERR,
179 			gettext("Cannot write the indicated output "
180 				"certificate file (%s).\n"), fullcsrpath);
181 		free(fullcsrpath);
182 		return (PK_ERR_USAGE);
183 	}
184 	if (dir != NULL) {
185 		fullkeypath = get_fullpath(dir, outkey);
186 		if (fullkeypath == NULL) {
187 			cryptoerror(LOG_STDERR,
188 				gettext("Cannot create file %s in "
189 					"directory %s\n"), dir, outkey);
190 			free(fullcsrpath);
191 			return (PK_ERR_USAGE);
192 		}
193 	} else {
194 		fullkeypath = strdup(outkey);
195 	}
196 	if (verify_file(fullcsrpath)) {
197 		cryptoerror(LOG_STDERR,
198 			gettext("Cannot write the indicated output "
199 				"key file (%s).\n"), fullkeypath);
200 		free(fullcsrpath);
201 		return (PK_ERR_USAGE);
202 	}
203 
204 	if (keyAlg == KMF_DSA)
205 		sigAlg = KMF_ALGID_SHA1WithDSA;
206 	else
207 		sigAlg = KMF_ALGID_MD5WithRSA;
208 
209 	/* If the subject name cannot be parsed, flag it now and exit */
210 	if ((kmfrv = KMF_DNParser(subject, &csrSubject)) != KMF_OK) {
211 		return (kmfrv);
212 	}
213 
214 	kp_params.kstype = KMF_KEYSTORE_OPENSSL;
215 	kp_params.keylength = keylen; /* bits */
216 	kp_params.keytype = keyAlg;
217 
218 	kp_params.sslparms.keyfile = fullkeypath;
219 	kp_params.sslparms.format = fmt;
220 
221 	kmfrv = KMF_CreateKeypair(kmfhandle, &kp_params, &prik, &pubk);
222 	if (kmfrv != KMF_OK) {
223 		goto cleanup;
224 	}
225 	SET_VALUE(KMF_SetCSRPubKey(kmfhandle, &pubk, &csr),
226 		"SetCSRPubKey");
227 
228 	SET_VALUE(KMF_SetCSRVersion(&csr, 2), "SetCSRVersion");
229 
230 	SET_VALUE(KMF_SetCSRSubjectName(&csr, &csrSubject),
231 		"SetCSRSubjectName");
232 
233 	SET_VALUE(KMF_SetCSRSignatureAlgorithm(&csr, sigAlg),
234 		"SetCSRSignatureAlgorithm");
235 
236 	if (altname != NULL) {
237 		SET_VALUE(KMF_SetCSRSubjectAltName(&csr, altname, altcrit,
238 			alttype), "SetCSRSubjectAltName");
239 	}
240 	if (kubits != NULL) {
241 		SET_VALUE(KMF_SetCSRKeyUsage(&csr, kucrit, kubits),
242 			"SetCSRKeyUsage");
243 	}
244 	if ((kmfrv = KMF_SignCSR(kmfhandle, &csr, &prik, &signedCsr)) ==
245 		KMF_OK) {
246 		kmfrv = KMF_CreateCSRFile(&signedCsr, fmt, fullcsrpath);
247 	}
248 
249 cleanup:
250 	if (fullkeypath)
251 		free(fullkeypath);
252 	if (fullcsrpath)
253 		free(fullcsrpath);
254 
255 	KMF_FreeData(&signedCsr);
256 	KMF_FreeKMFKey(kmfhandle, &prik);
257 	KMF_FreeSignedCSR(&csr);
258 
259 	return (kmfrv);
260 }
261 
262 static KMF_RETURN
263 gencsr_nss(KMF_HANDLE_T kmfhandle,
264 	char *token, char *subject, char *altname,
265 	KMF_GENERALNAMECHOICES alttype, int altcrit,
266 	char *nickname, char *dir, char *prefix,
267 	KMF_KEY_ALG keyAlg, int keylen,
268 	uint16_t kubits, int kucrit,
269 	KMF_ENCODE_FORMAT fmt, char *csrfile,
270 	KMF_CREDENTIAL *tokencred)
271 {
272 	KMF_RETURN kmfrv;
273 	KMF_CREATEKEYPAIR_PARAMS kp_params;
274 	KMF_KEY_HANDLE pubk, prik;
275 	KMF_X509_NAME	csrSubject;
276 	KMF_CSR_DATA	csr;
277 	KMF_ALGORITHM_INDEX sigAlg;
278 	KMF_DATA signedCsr = {NULL, 0};
279 	KMF_DELETEKEY_PARAMS dk_params;
280 
281 	if (token == NULL)
282 		token = DEFAULT_NSS_TOKEN;
283 
284 	if (keyAlg == KMF_DSA)
285 		sigAlg = KMF_ALGID_SHA1WithDSA;
286 	else
287 		sigAlg = KMF_ALGID_MD5WithRSA;
288 
289 	kmfrv = configure_nss(kmfhandle, dir, prefix);
290 	if (kmfrv != KMF_OK)
291 		return (kmfrv);
292 
293 	(void) memset(&csr, 0, sizeof (csr));
294 	(void) memset(&csrSubject, 0, sizeof (csrSubject));
295 
296 	/* If the subject name cannot be parsed, flag it now and exit */
297 	if ((kmfrv = KMF_DNParser(subject, &csrSubject)) != KMF_OK) {
298 		return (kmfrv);
299 	}
300 
301 	(void) memset(&kp_params, 0, sizeof (kp_params));
302 
303 	kp_params.kstype = KMF_KEYSTORE_NSS;
304 	kp_params.keylabel = nickname;
305 	kp_params.keylength = keylen; /* bits */
306 	kp_params.keytype = keyAlg;
307 	kp_params.cred.cred = tokencred->cred;
308 	kp_params.cred.credlen = tokencred->credlen;
309 	kp_params.nssparms.slotlabel = token;
310 
311 	kmfrv = KMF_CreateKeypair(kmfhandle, &kp_params, &prik, &pubk);
312 	if (kmfrv != KMF_OK) {
313 		goto cleanup;
314 	}
315 
316 	SET_VALUE(KMF_SetCSRPubKey(kmfhandle, &pubk, &csr), "SetCSRPubKey");
317 	SET_VALUE(KMF_SetCSRVersion(&csr, 2), "SetCSRVersion");
318 	SET_VALUE(KMF_SetCSRSubjectName(&csr, &csrSubject),
319 		"SetCSRSubjectName");
320 	SET_VALUE(KMF_SetCSRSignatureAlgorithm(&csr, sigAlg),
321 		"SetCSRSignatureAlgorithm");
322 
323 	if (altname != NULL) {
324 		SET_VALUE(KMF_SetCSRSubjectAltName(&csr, altname, altcrit,
325 			alttype), "SetCSRSubjectAltName");
326 	}
327 	if (kubits != NULL) {
328 		SET_VALUE(KMF_SetCSRKeyUsage(&csr, kucrit, kubits),
329 			"SetCSRKeyUsage");
330 	}
331 	if ((kmfrv = KMF_SignCSR(kmfhandle, &csr, &prik, &signedCsr)) ==
332 		KMF_OK) {
333 		kmfrv = KMF_CreateCSRFile(&signedCsr, fmt, csrfile);
334 	}
335 
336 cleanup:
337 	(void) KMF_FreeData(&signedCsr);
338 	(void) KMF_FreeKMFKey(kmfhandle, &prik);
339 	/* delete the key */
340 	(void) memset(&dk_params, 0, sizeof (dk_params));
341 	dk_params.kstype = KMF_KEYSTORE_NSS;
342 	dk_params.cred.cred = tokencred->cred;
343 	dk_params.cred.credlen = tokencred->credlen;
344 	dk_params.nssparms.slotlabel = token;
345 	(void) KMF_DeleteKeyFromKeystore(kmfhandle, &dk_params, &pubk);
346 	(void) KMF_FreeSignedCSR(&csr);
347 
348 	return (kmfrv);
349 }
350 
351 int
352 pk_gencsr(int argc, char *argv[])
353 {
354 	KMF_RETURN rv;
355 	int opt;
356 	extern int	optind_av;
357 	extern char	*optarg_av;
358 	KMF_KEYSTORE_TYPE kstype = 0;
359 	char *subject = NULL;
360 	char *tokenname = NULL;
361 	char *dir = NULL;
362 	char *prefix = NULL;
363 	int keylen = PK_DEFAULT_KEYLENGTH;
364 	char *certlabel = NULL;
365 	char *outcsr = NULL;
366 	char *outkey = NULL;
367 	char *format = NULL;
368 	char *altname = NULL;
369 	char *kustr = NULL;
370 	uint16_t kubits = 0;
371 	char *keytype = PK_DEFAULT_KEYTYPE;
372 	KMF_HANDLE_T kmfhandle = NULL;
373 	KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1;
374 	KMF_KEY_ALG keyAlg = KMF_RSA;
375 	KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_MD5WithRSA;
376 	boolean_t interactive = B_FALSE;
377 	char *subname = NULL;
378 	KMF_CREDENTIAL tokencred = {NULL, 0};
379 	KMF_GENERALNAMECHOICES alttype = 0;
380 	int altcrit = 0, kucrit = 0;
381 
382 	while ((opt = getopt_av(argc, argv,
383 		"ik:(keystore)s:(subject)n:(nickname)A:(altname)"
384 		"u:(keyusage)T:(token)d:(dir)p:(prefix)t:(keytype)"
385 		"y:(keylen)l:(label)c:(outcsr)"
386 		"K:(outkey)F:(format)")) != EOF) {
387 
388 		if (opt != 'i' && EMPTYSTRING(optarg_av))
389 			return (PK_ERR_USAGE);
390 
391 		switch (opt) {
392 			case 'A':
393 				altname = optarg_av;
394 				break;
395 			case 'i':
396 				if (interactive || subject)
397 					return (PK_ERR_USAGE);
398 				else
399 					interactive = B_TRUE;
400 				break;
401 			case 'k':
402 				kstype = KS2Int(optarg_av);
403 				if (kstype == 0)
404 					return (PK_ERR_USAGE);
405 				break;
406 			case 's':
407 				if (interactive || subject)
408 					return (PK_ERR_USAGE);
409 				else
410 					subject = optarg_av;
411 				break;
412 			case 'l':
413 			case 'n':
414 				if (certlabel)
415 					return (PK_ERR_USAGE);
416 				certlabel = optarg_av;
417 				break;
418 			case 'T':
419 				if (tokenname)
420 					return (PK_ERR_USAGE);
421 				tokenname = optarg_av;
422 				break;
423 			case 'd':
424 				dir = optarg_av;
425 				break;
426 			case 'p':
427 				if (prefix)
428 					return (PK_ERR_USAGE);
429 				prefix = optarg_av;
430 				break;
431 			case 't':
432 				keytype = optarg_av;
433 				break;
434 			case 'u':
435 				kustr = optarg_av;
436 				break;
437 			case 'y':
438 				if (sscanf(optarg_av, "%d",
439 					&keylen) != 1) {
440 					cryptoerror(LOG_STDERR,
441 						gettext("Unrecognized "
442 						"key length (%s)\n"),
443 						optarg_av);
444 					return (PK_ERR_USAGE);
445 				}
446 				break;
447 			case 'c':
448 				if (outcsr)
449 					return (PK_ERR_USAGE);
450 				outcsr = optarg_av;
451 				break;
452 			case 'K':
453 				if (outkey)
454 					return (PK_ERR_USAGE);
455 				outkey = optarg_av;
456 				break;
457 			case 'F':
458 				if (format)
459 					return (PK_ERR_USAGE);
460 				format = optarg_av;
461 				break;
462 			default:
463 				cryptoerror(LOG_STDERR, gettext(
464 					"unrecognized gencsr option '%s'\n"),
465 					argv[optind_av]);
466 				return (PK_ERR_USAGE);
467 		}
468 	}
469 	/* No additional args allowed. */
470 	argc -= optind_av;
471 	argv += optind_av;
472 	if (argc) {
473 		return (PK_ERR_USAGE);
474 	}
475 
476 	if ((rv = KMF_Initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
477 		cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n"));
478 		return (PK_ERR_USAGE);
479 	}
480 
481 	/* Assume keystore = PKCS#11 if not specified. */
482 	if (kstype == 0)
483 		kstype = KMF_KEYSTORE_PK11TOKEN;
484 
485 	if (EMPTYSTRING(outcsr)) {
486 		(void) printf(gettext("A filename must be specified to hold"
487 			"the final certificate request data.\n"));
488 		return (PK_ERR_USAGE);
489 	} else {
490 		/*
491 		 * verify that the outcsr file does not already exist
492 		 * and that it can be created.
493 		 */
494 		rv = verify_file(outcsr);
495 		if (rv != KMF_OK) {
496 			cryptoerror(LOG_STDERR, gettext("output file (%s) "
497 				"cannot be created.\n"), outcsr);
498 			return (PK_ERR_USAGE);
499 		}
500 	}
501 
502 	if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) &&
503 	    EMPTYSTRING(certlabel)) {
504 		cryptoerror(LOG_STDERR, gettext("A label must be specified "
505 		    "to create a certificate request.\n"));
506 		return (PK_ERR_USAGE);
507 	} else if (kstype == KMF_KEYSTORE_OPENSSL && EMPTYSTRING(outkey)) {
508 		cryptoerror(LOG_STDERR, gettext("A key filename must be "
509 		    "specified to create a certificate request.\n"));
510 		return (PK_ERR_USAGE);
511 	}
512 
513 	if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) {
514 		cryptoerror(LOG_STDERR,
515 			gettext("Error parsing format string (%s).\n"),
516 			format);
517 		return (PK_ERR_USAGE);
518 	}
519 	if (format && fmt != KMF_FORMAT_ASN1 && fmt != KMF_FORMAT_PEM) {
520 		cryptoerror(LOG_STDERR,
521 			gettext("CSR must be DER or PEM format.\n"));
522 		return (PK_ERR_USAGE);
523 	}
524 
525 	/*
526 	 * Check the subject name.
527 	 * If interactive is true, get it now interactively.
528 	 */
529 	if (interactive) {
530 		if (get_subname(&subname) != KMF_OK) {
531 			cryptoerror(LOG_STDERR, gettext("Failed to get the "
532 			    "subject name interactively.\n"));
533 			return (PK_ERR_USAGE);
534 		}
535 	} else {
536 		if (EMPTYSTRING(subject)) {
537 			cryptoerror(LOG_STDERR, gettext("A subject name or "
538 			    "-i must be specified to create a certificate "
539 			    "request.\n"));
540 			return (PK_ERR_USAGE);
541 		} else {
542 			subname = strdup(subject);
543 			if (subname == NULL) {
544 				cryptoerror(LOG_STDERR,
545 				    gettext("Out of memory.\n"));
546 				return (PK_ERR_SYSTEM);
547 			}
548 		}
549 	}
550 	if (altname != NULL) {
551 		rv = verify_altname(altname, &alttype, &altcrit);
552 		if (rv != KMF_OK) {
553 			cryptoerror(LOG_STDERR, gettext("Subject AltName "
554 				"must be specified as a name=value pair. "
555 				"See the man page for details."));
556 			goto end;
557 		} else {
558 			/* advance the altname past the '=' sign */
559 			char *p = strchr(altname, '=');
560 			if (p != NULL)
561 				altname = p + 1;
562 		}
563 	}
564 
565 	if (kustr != NULL) {
566 		rv = verify_keyusage(kustr, &kubits, &kucrit);
567 		if (rv != KMF_OK) {
568 			cryptoerror(LOG_STDERR, gettext("KeyUsage "
569 				"must be specified as a comma-separated list. "
570 				"See the man page for details."));
571 			goto end;
572 		}
573 	}
574 	if ((rv = Str2KeyType(keytype, &keyAlg, &sigAlg)) != 0) {
575 		cryptoerror(LOG_STDERR, gettext("Unrecognized keytype (%s).\n"),
576 			keytype);
577 		goto end;
578 	}
579 
580 	if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) {
581 		if (tokenname == NULL || !strlen(tokenname)) {
582 			if (kstype == KMF_KEYSTORE_NSS) {
583 				tokenname = "internal";
584 			} else  {
585 				tokenname = PK_DEFAULT_PK11TOKEN;
586 			}
587 		}
588 
589 		(void) get_token_password(kstype, tokenname, &tokencred);
590 	}
591 
592 	if (kstype == KMF_KEYSTORE_NSS) {
593 		if (dir == NULL)
594 			dir = PK_DEFAULT_DIRECTORY;
595 
596 		rv = gencsr_nss(kmfhandle,
597 			tokenname, subname, altname, alttype, altcrit,
598 			certlabel, dir, prefix,
599 			keyAlg, keylen, kubits, kucrit,
600 			fmt, outcsr, &tokencred);
601 
602 	} else if (kstype == KMF_KEYSTORE_PK11TOKEN) {
603 		rv = gencsr_pkcs11(kmfhandle,
604 			tokenname, subname, altname, alttype, altcrit,
605 			certlabel, keyAlg, keylen,
606 			kubits, kucrit, fmt, outcsr, &tokencred);
607 
608 	} else if (kstype == KMF_KEYSTORE_OPENSSL) {
609 		rv = gencsr_file(kmfhandle,
610 			keyAlg, keylen, fmt, subname, altname,
611 			alttype, altcrit, kubits, kucrit,
612 			dir, outcsr, outkey);
613 	}
614 
615 end:
616 	if (rv != KMF_OK)
617 		display_error(kmfhandle, rv,
618 			gettext("Error creating CSR or keypair"));
619 
620 	if (subname)
621 		free(subname);
622 
623 	if (tokencred.cred != NULL)
624 		free(tokencred.cred);
625 
626 	(void) KMF_Finalize(kmfhandle);
627 	if (rv != KMF_OK)
628 		return (PK_ERR_USAGE);
629 
630 	return (0);
631 }
632