gencert.c revision 11973:480f5412d630
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 2010 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#include <stdio.h>
27#include <string.h>
28#include <ctype.h>
29#include <malloc.h>
30#include <libgen.h>
31#include <errno.h>
32#include <cryptoutil.h>
33#include <security/cryptoki.h>
34#include "common.h"
35
36#include <kmfapi.h>
37
38#define	SET_VALUE(f, s) \
39	kmfrv = f; \
40	if (kmfrv != KMF_OK) { \
41		cryptoerror(LOG_STDERR, \
42			gettext("Failed to set %s: 0x%02x\n"), \
43			s, kmfrv); \
44		goto cleanup; \
45	}
46
47static int
48gencert_pkcs11(KMF_HANDLE_T kmfhandle,
49	char *token, char *subject, char *altname,
50	KMF_GENERALNAMECHOICES alttype, int altcrit,
51	char *certlabel, KMF_KEY_ALG keyAlg,
52	KMF_ALGORITHM_INDEX sigAlg,
53	int keylen, uint32_t ltime, KMF_BIGINT *serial,
54	uint16_t kubits, int kucrit, KMF_CREDENTIAL *tokencred,
55	EKU_LIST *ekulist, KMF_OID *curveoid)
56{
57	KMF_RETURN kmfrv = KMF_OK;
58	KMF_KEY_HANDLE pubk, prik;
59	KMF_X509_CERTIFICATE signedCert;
60	KMF_X509_NAME	certSubject;
61	KMF_X509_NAME	certIssuer;
62	KMF_DATA x509DER;
63	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
64	KMF_ATTRIBUTE attrlist[16];
65	int numattr = 0;
66	KMF_KEY_ALG keytype;
67	uint32_t keylength;
68
69	(void) memset(&signedCert, 0, sizeof (signedCert));
70	(void) memset(&certSubject, 0, sizeof (certSubject));
71	(void) memset(&certIssuer, 0, sizeof (certIssuer));
72	(void) memset(&x509DER, 0, sizeof (x509DER));
73
74	/* If the subject name cannot be parsed, flag it now and exit */
75	if (kmf_dn_parser(subject, &certSubject) != KMF_OK) {
76		cryptoerror(LOG_STDERR,
77		    gettext("Subject name cannot be parsed.\n"));
78		return (PK_ERR_USAGE);
79	}
80
81	/* For a self-signed cert, the issuser and subject are the same */
82	if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) {
83		cryptoerror(LOG_STDERR,
84		    gettext("Subject name cannot be parsed.\n"));
85		return (PK_ERR_USAGE);
86	}
87
88	keylength = keylen; /* bits */
89	keytype = keyAlg;
90
91	/* Select a PKCS11 token */
92	kmfrv = select_token(kmfhandle, token, FALSE);
93	if (kmfrv != KMF_OK) {
94		return (kmfrv);
95	}
96
97	/*
98	 * Share the "genkeypair" routine for creating the keypair.
99	 */
100	kmfrv = genkeypair_pkcs11(kmfhandle, token, certlabel,
101	    keytype, keylength, tokencred, curveoid, &prik, &pubk);
102	if (kmfrv != KMF_OK)
103		return (kmfrv);
104
105	SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert),
106	    "keypair");
107
108	SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number");
109
110	SET_VALUE(kmf_set_cert_serial(&signedCert, serial),
111	    "serial number");
112
113	SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime),
114	    "validity time");
115
116	SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg),
117	    "signature algorithm");
118
119	SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject),
120	    "subject name");
121
122	SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer),
123	    "issuer name");
124
125	if (altname != NULL)
126		SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit,
127		    alttype, altname), "subjectAltName");
128
129	if (kubits != 0)
130		SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits),
131		    "KeyUsage");
132
133	if (ekulist != NULL) {
134		int i;
135		for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
136			SET_VALUE(kmf_add_cert_eku(&signedCert,
137			    &ekulist->ekulist[i], ekulist->critlist[i]),
138			    "Extended Key Usage");
139		}
140	}
141
142	/*
143	 * Construct attributes for the kmf_sign_cert operation.
144	 */
145	numattr = 0;
146	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
147	    &kstype, sizeof (kstype));
148	numattr++;
149
150	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
151	    &prik, sizeof (KMF_KEY_HANDLE_ATTR));
152	numattr++;
153
154	/* cert data that is to be signed */
155	kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR,
156	    &signedCert, sizeof (KMF_X509_CERTIFICATE));
157	numattr++;
158
159	/* output buffer for the signed cert */
160	kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
161	    &x509DER, sizeof (KMF_DATA));
162	numattr++;
163
164	if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) !=
165	    KMF_OK) {
166		goto cleanup;
167	}
168
169	/*
170	 * Store the cert in the DB.
171	 */
172	numattr = 0;
173	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
174	    &kstype, sizeof (kstype));
175	numattr++;
176	kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
177	    &x509DER, sizeof (KMF_DATA));
178	numattr++;
179
180	if (certlabel != NULL) {
181		kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR,
182		    certlabel, strlen(certlabel));
183		numattr++;
184	}
185
186	kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist);
187
188cleanup:
189	kmf_free_data(&x509DER);
190	kmf_free_dn(&certSubject);
191	kmf_free_dn(&certIssuer);
192
193	/*
194	 * If kmf_sign_cert or kmf_store_cert failed, then we need to clean up
195	 * the key pair from the token.
196	 */
197	if (kmfrv != KMF_OK) {
198		/* delete the public key */
199		numattr = 0;
200		kmf_set_attr_at_index(attrlist, numattr,
201		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
202		numattr++;
203
204		kmf_set_attr_at_index(attrlist, numattr,
205		    KMF_KEY_HANDLE_ATTR, &pubk, sizeof (KMF_KEY_HANDLE));
206		numattr++;
207
208		if (tokencred != NULL && tokencred->cred != NULL) {
209			kmf_set_attr_at_index(attrlist, numattr,
210			    KMF_CREDENTIAL_ATTR, tokencred,
211			    sizeof (KMF_CREDENTIAL));
212			numattr++;
213		}
214
215		(void) kmf_delete_key_from_keystore(kmfhandle, numattr,
216		    attrlist);
217
218		/* delete the private key */
219		numattr = 0;
220		kmf_set_attr_at_index(attrlist, numattr,
221		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
222		numattr++;
223
224		kmf_set_attr_at_index(attrlist, numattr,
225		    KMF_KEY_HANDLE_ATTR, &prik, sizeof (KMF_KEY_HANDLE));
226		numattr++;
227
228		if (tokencred != NULL && tokencred->cred != NULL) {
229			kmf_set_attr_at_index(attrlist, numattr,
230			    KMF_CREDENTIAL_ATTR, tokencred,
231			    sizeof (KMF_CREDENTIAL));
232			numattr++;
233		}
234
235		(void) kmf_delete_key_from_keystore(kmfhandle, numattr,
236		    attrlist);
237	}
238
239	return (kmfrv);
240}
241
242static int
243gencert_file(KMF_HANDLE_T kmfhandle,
244	KMF_KEY_ALG keyAlg, KMF_ALGORITHM_INDEX sigAlg,
245	int keylen, KMF_ENCODE_FORMAT fmt,
246	uint32_t ltime, char *subject, char *altname,
247	KMF_GENERALNAMECHOICES alttype, int altcrit,
248	KMF_BIGINT *serial, uint16_t kubits, int kucrit,
249	char *outcert, char *outkey,
250	EKU_LIST *ekulist)
251{
252	KMF_RETURN kmfrv;
253	KMF_KEY_HANDLE pubk, prik;
254	KMF_X509_CERTIFICATE signedCert;
255	KMF_X509_NAME	certSubject;
256	KMF_X509_NAME	certIssuer;
257	KMF_DATA x509DER;
258	char *fullcertpath = NULL;
259	char *fullkeypath = NULL;
260	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
261	KMF_ATTRIBUTE attrlist[10];
262	int numattr = 0;
263
264	(void) memset(&signedCert, 0, sizeof (signedCert));
265	(void) memset(&certSubject, 0, sizeof (certSubject));
266	(void) memset(&certIssuer, 0, sizeof (certIssuer));
267	(void) memset(&x509DER, 0, sizeof (x509DER));
268
269	if (EMPTYSTRING(outcert) || EMPTYSTRING(outkey)) {
270		cryptoerror(LOG_STDERR,
271		    gettext("No output file was specified for "
272		    "the cert or key\n"));
273		return (PK_ERR_USAGE);
274	}
275	fullcertpath = strdup(outcert);
276	if (verify_file(fullcertpath)) {
277		cryptoerror(LOG_STDERR,
278		    gettext("Cannot write the indicated output "
279		    "certificate file (%s).\n"), fullcertpath);
280		free(fullcertpath);
281		return (PK_ERR_USAGE);
282	}
283
284	/* If the subject name cannot be parsed, flag it now and exit */
285	if (kmf_dn_parser(subject, &certSubject) != KMF_OK) {
286		cryptoerror(LOG_STDERR,
287		    gettext("Subject name cannot be parsed (%s)\n"), subject);
288		return (PK_ERR_USAGE);
289	}
290
291	/* For a self-signed cert, the issuser and subject are the same */
292	if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) {
293		cryptoerror(LOG_STDERR,
294		    gettext("Subject name cannot be parsed (%s)\n"), subject);
295		kmf_free_dn(&certSubject);
296		return (PK_ERR_USAGE);
297	}
298
299	/*
300	 * Share the "genkeypair" routine for creating the keypair.
301	 */
302	kmfrv = genkeypair_file(kmfhandle, keyAlg, keylen,
303	    fmt, outkey, &prik, &pubk);
304	if (kmfrv != KMF_OK)
305		return (kmfrv);
306
307	SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert),
308	    "keypair");
309
310	SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number");
311
312	SET_VALUE(kmf_set_cert_serial(&signedCert, serial),
313	    "serial number");
314
315	SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime),
316	    "validity time");
317
318	SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg),
319	    "signature algorithm");
320
321	SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject),
322	    "subject name");
323
324	SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer),
325	    "issuer name");
326
327	if (altname != NULL)
328		SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit,
329		    alttype, altname), "subjectAltName");
330
331	if (kubits != 0)
332		SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits),
333		    "KeyUsage");
334
335	if (ekulist != NULL) {
336		int i;
337		for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
338			SET_VALUE(kmf_add_cert_eku(&signedCert,
339			    &ekulist->ekulist[i],
340			    ekulist->critlist[i]), "Extended Key Usage");
341		}
342	}
343	/*
344	 * Construct attributes for the kmf_sign_cert operation.
345	 */
346	numattr = 0;
347	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
348	    &kstype, sizeof (kstype));
349	numattr++;
350
351	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
352	    &prik, sizeof (KMF_KEY_HANDLE_ATTR));
353	numattr++;
354
355	/* cert data that is to be signed */
356	kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR,
357	    &signedCert, sizeof (KMF_X509_CERTIFICATE));
358	numattr++;
359
360	/* output buffer for the signed cert */
361	kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
362	    &x509DER, sizeof (KMF_DATA));
363	numattr++;
364
365	if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) !=
366	    KMF_OK) {
367		goto cleanup;
368	}
369
370	/*
371	 * Store the cert in the DB.
372	 */
373	numattr = 0;
374	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
375	    &kstype, sizeof (kstype));
376	numattr++;
377	kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
378	    &x509DER, sizeof (KMF_DATA));
379	numattr++;
380	kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_FILENAME_ATTR,
381	    fullcertpath, strlen(fullcertpath));
382	numattr++;
383	kmf_set_attr_at_index(attrlist, numattr, KMF_ENCODE_FORMAT_ATTR,
384	    &fmt, sizeof (fmt));
385	numattr++;
386
387	kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist);
388
389cleanup:
390	if (fullkeypath != NULL)
391		free(fullkeypath);
392	if (fullcertpath != NULL)
393		free(fullcertpath);
394
395	kmf_free_data(&x509DER);
396	kmf_free_dn(&certSubject);
397	kmf_free_dn(&certIssuer);
398	return (kmfrv);
399}
400
401static KMF_RETURN
402gencert_nss(KMF_HANDLE_T kmfhandle,
403	char *token, char *subject, char *altname,
404	KMF_GENERALNAMECHOICES alttype, int altcrit,
405	char *nickname, char *dir, char *prefix,
406	KMF_KEY_ALG keyAlg,
407	KMF_ALGORITHM_INDEX sigAlg,
408	int keylen, char *trust,
409	uint32_t ltime, KMF_BIGINT *serial, uint16_t kubits,
410	int kucrit, KMF_CREDENTIAL *tokencred,
411	EKU_LIST *ekulist, KMF_OID *curveoid)
412{
413	KMF_RETURN kmfrv;
414	KMF_KEY_HANDLE pubk, prik;
415	KMF_X509_CERTIFICATE signedCert;
416	KMF_X509_NAME	certSubject;
417	KMF_X509_NAME	certIssuer;
418	KMF_DATA x509DER;
419	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
420	KMF_ATTRIBUTE attrlist[16];
421	int numattr = 0;
422
423	if (token == NULL)
424		token = DEFAULT_NSS_TOKEN;
425
426	kmfrv = configure_nss(kmfhandle, dir, prefix);
427	if (kmfrv != KMF_OK)
428		return (kmfrv);
429
430	(void) memset(&signedCert, 0, sizeof (signedCert));
431	(void) memset(&certSubject, 0, sizeof (certSubject));
432	(void) memset(&certIssuer, 0, sizeof (certIssuer));
433	(void) memset(&x509DER, 0, sizeof (x509DER));
434
435	/* If the subject name cannot be parsed, flag it now and exit */
436	if (kmf_dn_parser(subject, &certSubject) != KMF_OK) {
437		cryptoerror(LOG_STDERR,
438		    gettext("Subject name cannot be parsed.\n"));
439		return (PK_ERR_USAGE);
440	}
441
442	/* For a self-signed cert, the issuser and subject are the same */
443	if (kmf_dn_parser(subject, &certIssuer) != KMF_OK) {
444		cryptoerror(LOG_STDERR,
445		    gettext("Subject name cannot be parsed.\n"));
446		return (PK_ERR_USAGE);
447	}
448
449	kmfrv = genkeypair_nss(kmfhandle, token, nickname, dir,
450	    prefix, keyAlg, keylen, tokencred, curveoid,
451	    &prik, &pubk);
452	if (kmfrv != KMF_OK)
453		return (kmfrv);
454
455	SET_VALUE(kmf_set_cert_pubkey(kmfhandle, &pubk, &signedCert),
456	    "keypair");
457
458	SET_VALUE(kmf_set_cert_version(&signedCert, 2), "version number");
459
460	SET_VALUE(kmf_set_cert_serial(&signedCert, serial),
461	    "serial number");
462
463	SET_VALUE(kmf_set_cert_validity(&signedCert, NULL, ltime),
464	    "validity time");
465
466	SET_VALUE(kmf_set_cert_sig_alg(&signedCert, sigAlg),
467	    "signature algorithm");
468
469	SET_VALUE(kmf_set_cert_subject(&signedCert, &certSubject),
470	    "subject name");
471
472	SET_VALUE(kmf_set_cert_issuer(&signedCert, &certIssuer),
473	    "issuer name");
474
475	if (altname != NULL)
476		SET_VALUE(kmf_set_cert_subject_altname(&signedCert, altcrit,
477		    alttype, altname), "subjectAltName");
478
479	if (kubits)
480		SET_VALUE(kmf_set_cert_ku(&signedCert, kucrit, kubits),
481		    "subjectAltName");
482
483	if (ekulist != NULL) {
484		int i;
485		for (i = 0; kmfrv == KMF_OK && i < ekulist->eku_count; i++) {
486			SET_VALUE(kmf_add_cert_eku(&signedCert,
487			    &ekulist->ekulist[i],
488			    ekulist->critlist[i]), "Extended Key Usage");
489		}
490	}
491	/*
492	 * Construct attributes for the kmf_sign_cert operation.
493	 */
494	numattr = 0;
495	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
496	    &kstype, sizeof (kstype));
497	numattr++;
498
499	kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
500	    &prik, sizeof (KMF_KEY_HANDLE_ATTR));
501	numattr++;
502
503	/* cert data that is to be signed */
504	kmf_set_attr_at_index(attrlist, numattr, KMF_X509_CERTIFICATE_ATTR,
505	    &signedCert, sizeof (KMF_X509_CERTIFICATE));
506	numattr++;
507
508	/* output buffer for the signed cert */
509	kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
510	    &x509DER, sizeof (KMF_DATA));
511	numattr++;
512
513	if ((kmfrv = kmf_sign_cert(kmfhandle, numattr, attrlist)) !=
514	    KMF_OK) {
515		goto cleanup;
516	}
517
518	/*
519	 * Store the cert in the DB.
520	 */
521	numattr = 0;
522	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
523	    &kstype, sizeof (kstype));
524	numattr++;
525
526	kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
527	    &x509DER, sizeof (KMF_DATA));
528	numattr++;
529
530	if (nickname != NULL) {
531		kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_LABEL_ATTR,
532		    nickname, strlen(nickname));
533		numattr++;
534	}
535
536	if (trust != NULL) {
537		kmf_set_attr_at_index(attrlist, numattr, KMF_TRUSTFLAG_ATTR,
538		    trust, strlen(trust));
539		numattr++;
540	}
541
542	if (token != NULL) {
543		kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
544		    token, strlen(token));
545		numattr++;
546	}
547
548	kmfrv = kmf_store_cert(kmfhandle, numattr, attrlist);
549
550cleanup:
551	kmf_free_data(&x509DER);
552	kmf_free_dn(&certSubject);
553	kmf_free_dn(&certIssuer);
554	return (kmfrv);
555}
556
557int
558pk_gencert(int argc, char *argv[])
559{
560	int rv;
561	int opt;
562	extern int	optind_av;
563	extern char	*optarg_av;
564	KMF_KEYSTORE_TYPE kstype = 0;
565	char *subject = NULL;
566	char *tokenname = NULL;
567	char *dir = NULL;
568	char *prefix = NULL;
569	char *keytype = PK_DEFAULT_KEYTYPE;
570	int keylen = PK_DEFAULT_KEYLENGTH;
571	char *trust = NULL;
572	char *lifetime = NULL;
573	char *certlabel = NULL;
574	char *outcert = NULL;
575	char *outkey = NULL;
576	char *format = NULL;
577	char *serstr = NULL;
578	char *altname = NULL;
579	char *keyusagestr = NULL;
580	char *ekustr = NULL;
581	char *hashname = NULL;
582	KMF_GENERALNAMECHOICES alttype = 0;
583	KMF_BIGINT serial = { NULL, 0 };
584	uint32_t ltime;
585	KMF_HANDLE_T kmfhandle = NULL;
586	KMF_ENCODE_FORMAT fmt = KMF_FORMAT_ASN1;
587	KMF_KEY_ALG keyAlg = KMF_RSA;
588	KMF_ALGORITHM_INDEX sigAlg = KMF_ALGID_SHA1WithRSA;
589	boolean_t interactive = B_FALSE;
590	char *subname = NULL;
591	KMF_CREDENTIAL tokencred = {NULL, 0};
592	uint16_t kubits = 0;
593	int altcrit = 0, kucrit = 0;
594	EKU_LIST *ekulist = NULL;
595	KMF_OID *curveoid = NULL; /* ECC */
596	KMF_OID *hashoid = NULL;
597	int y_flag = 0;
598
599	while ((opt = getopt_av(argc, argv,
600	    "ik:(keystore)s:(subject)n:(nickname)A:(altname)"
601	    "T:(token)d:(dir)p:(prefix)t:(keytype)y:(keylen)"
602	    "r:(trust)L:(lifetime)l:(label)c:(outcert)e:(eku)"
603	    "K:(outkey)S:(serial)F:(format)u:(keyusage)C:(curve)"
604	    "E(listcurves)h:(hash)")) != EOF) {
605
606		if (opt != 'i' && opt != 'E' && EMPTYSTRING(optarg_av))
607			return (PK_ERR_USAGE);
608
609		switch (opt) {
610			case 'A':
611				altname = optarg_av;
612				break;
613			case 'i':
614				if (interactive || subject)
615					return (PK_ERR_USAGE);
616				else
617					interactive = B_TRUE;
618				break;
619			case 'k':
620				kstype = KS2Int(optarg_av);
621				if (kstype == 0)
622					return (PK_ERR_USAGE);
623				break;
624			case 's':
625				if (interactive || subject)
626					return (PK_ERR_USAGE);
627				else
628					subject = optarg_av;
629				break;
630			case 'l':
631			case 'n':
632				if (certlabel)
633					return (PK_ERR_USAGE);
634				certlabel = optarg_av;
635				break;
636			case 'T':
637				if (tokenname)
638					return (PK_ERR_USAGE);
639				tokenname = optarg_av;
640				break;
641			case 'd':
642				if (dir)
643					return (PK_ERR_USAGE);
644				dir = optarg_av;
645				break;
646			case 'p':
647				if (prefix)
648					return (PK_ERR_USAGE);
649				prefix = optarg_av;
650				break;
651			case 't':
652				keytype = optarg_av;
653				break;
654			case 'u':
655				keyusagestr = optarg_av;
656				break;
657			case 'y':
658				if (sscanf(optarg_av, "%d",
659				    &keylen) != 1) {
660					cryptoerror(LOG_STDERR,
661					    gettext("key length must be"
662					    "a numeric value (%s)\n"),
663					    optarg_av);
664					return (PK_ERR_USAGE);
665				}
666				y_flag++;
667				break;
668			case 'r':
669				if (trust)
670					return (PK_ERR_USAGE);
671				trust = optarg_av;
672				break;
673			case 'L':
674				if (lifetime)
675					return (PK_ERR_USAGE);
676				lifetime = optarg_av;
677				break;
678			case 'c':
679				if (outcert)
680					return (PK_ERR_USAGE);
681				outcert = optarg_av;
682				break;
683			case 'K':
684				if (outkey)
685					return (PK_ERR_USAGE);
686				outkey = optarg_av;
687				break;
688			case 'S':
689				serstr = optarg_av;
690				break;
691			case 'F':
692				if (format)
693					return (PK_ERR_USAGE);
694				format = optarg_av;
695				break;
696			case 'e':
697				ekustr = optarg_av;
698				break;
699			case 'C':
700				curveoid = ecc_name_to_oid(optarg_av);
701				if (curveoid == NULL) {
702					cryptoerror(LOG_STDERR,
703					    gettext("Unrecognized ECC "
704					    "curve.\n"));
705					return (PK_ERR_USAGE);
706				}
707				break;
708			case 'E':
709				/*
710				 * This argument is only to be used
711				 * by itself, no other options should
712				 * be present.
713				 */
714				if (argc != 2) {
715					cryptoerror(LOG_STDERR,
716					    gettext("listcurves has no other "
717					    "options.\n"));
718					return (PK_ERR_USAGE);
719				}
720				show_ecc_curves();
721				return (0);
722			case 'h':
723				hashname = optarg_av;
724				hashoid = ecc_name_to_oid(optarg_av);
725				if (hashoid == NULL) {
726					cryptoerror(LOG_STDERR,
727					    gettext("Unrecognized hash.\n"));
728					return (PK_ERR_USAGE);
729				}
730				break;
731			default:
732				return (PK_ERR_USAGE);
733		}
734	}
735
736	/* No additional args allowed. */
737	argc -= optind_av;
738	argv += optind_av;
739	if (argc) {
740		return (PK_ERR_USAGE);
741	}
742
743	if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
744		cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n"));
745		return (PK_ERR_USAGE);
746	}
747
748	/* Assume keystore = PKCS#11 if not specified. */
749	if (kstype == 0)
750		kstype = KMF_KEYSTORE_PK11TOKEN;
751
752	if ((kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN)) {
753		if (interactive && EMPTYSTRING(certlabel)) {
754			(void) get_certlabel(&certlabel);
755		}
756		/* It better not be empty now */
757		if (EMPTYSTRING(certlabel)) {
758			cryptoerror(LOG_STDERR, gettext("A label must be "
759			    "specified to create a self-signed certificate."
760			    "\n"));
761			return (PK_ERR_USAGE);
762		}
763	} else if (kstype == KMF_KEYSTORE_OPENSSL && EMPTYSTRING(outcert)) {
764		cryptoerror(LOG_STDERR, gettext("A certificate filename must "
765		    "be specified to create a self-signed certificate.\n"));
766		return (PK_ERR_USAGE);
767	}
768
769	DIR_OPTION_CHECK(kstype, dir);
770
771	if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) {
772		cryptoerror(LOG_STDERR,
773		    gettext("Error parsing format string (%s).\n"),
774		    format);
775		return (PK_ERR_USAGE);
776	}
777
778	if (Str2Lifetime(lifetime, &ltime) != 0) {
779		cryptoerror(LOG_STDERR,
780		    gettext("Error parsing lifetime string\n"));
781		return (PK_ERR_USAGE);
782	}
783
784	if (Str2KeyType(keytype, hashoid, &keyAlg, &sigAlg) != 0) {
785		cryptoerror(LOG_STDERR,
786		    gettext("Unsupported key/hash combination (%s/%s).\n"),
787		    keytype, (hashname ? hashname : "none"));
788		return (PK_ERR_USAGE);
789	}
790	if (curveoid != NULL && keyAlg != KMF_ECDSA) {
791		cryptoerror(LOG_STDERR, gettext("EC curves are only "
792		    "valid for EC keytypes.\n"));
793		return (PK_ERR_USAGE);
794	}
795	if (keyAlg == KMF_ECDSA && curveoid == NULL) {
796		cryptoerror(LOG_STDERR, gettext("A curve must be "
797		    "specifed when using EC keys.\n"));
798		return (PK_ERR_USAGE);
799	}
800	/* Adjust default keylength for NSS and DSA */
801	if (keyAlg == KMF_DSA && !y_flag && kstype == KMF_KEYSTORE_NSS)
802		keylen = 1024;
803
804	/*
805	 * Check the subject name.
806	 * If interactive is true, get it now interactively.
807	 */
808	if (interactive) {
809		subname = NULL;
810		if (get_subname(&subname) != KMF_OK || subname == NULL) {
811			cryptoerror(LOG_STDERR, gettext("Failed to get the "
812			    "subject name interactively.\n"));
813			return (PK_ERR_USAGE);
814		}
815		if (serstr == NULL) {
816			(void) get_serial(&serstr);
817		}
818	} else {
819		if (EMPTYSTRING(subject)) {
820			cryptoerror(LOG_STDERR, gettext("A subject name or "
821			    "-i must be specified to create a self-signed "
822			    "certificate.\n"));
823			return (PK_ERR_USAGE);
824		} else {
825			subname = strdup(subject);
826			if (subname == NULL) {
827				cryptoerror(LOG_STDERR,
828				    gettext("Out of memory.\n"));
829				return (PK_ERR_SYSTEM);
830			}
831		}
832	}
833
834	if (serstr == NULL) {
835		(void) fprintf(stderr, gettext("A serial number "
836		    "must be specified as a hex number when creating"
837		    " a self-signed certificate "
838		    "(ex: serial=0x0102030405feedface)\n"));
839		rv = PK_ERR_USAGE;
840		goto end;
841	} else {
842		uchar_t *bytes = NULL;
843		size_t bytelen;
844
845		rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen);
846		if (rv != KMF_OK || bytes == NULL) {
847			(void) fprintf(stderr, gettext("serial number "
848			    "must be specified as a hex number "
849			    "(ex: 0x0102030405ffeeddee)\n"));
850			rv = PK_ERR_USAGE;
851			goto end;
852		}
853		serial.val = bytes;
854		serial.len = bytelen;
855	}
856
857	if (altname != NULL) {
858		rv = verify_altname(altname, &alttype, &altcrit);
859		if (rv != KMF_OK) {
860			(void) fprintf(stderr, gettext("Subject AltName "
861			    "must be specified as a name=value pair. "
862			    "See the man page for details.\n"));
863			rv = PK_ERR_USAGE;
864			goto end;
865		} else {
866			/* advance the altname past the '=' sign */
867			char *p = strchr(altname, '=');
868			if (p != NULL)
869				altname = p + 1;
870		}
871	}
872
873	if (keyusagestr != NULL) {
874		rv = verify_keyusage(keyusagestr, &kubits, &kucrit);
875		if (rv != KMF_OK) {
876			(void) fprintf(stderr, gettext("KeyUsage "
877			    "must be specified as a comma-separated list. "
878			    "See the man page for details.\n"));
879			rv = PK_ERR_USAGE;
880			goto end;
881		}
882	}
883	if (ekustr != NULL) {
884		rv = verify_ekunames(ekustr, &ekulist);
885		if (rv != KMF_OK) {
886			(void) fprintf(stderr, gettext("EKUs must "
887			    "be specified as a comma-separated list. "
888			    "See the man page for details.\n"));
889			rv = PK_ERR_USAGE;
890			goto end;
891		}
892	}
893	if (keyAlg == KMF_ECDSA && kstype == KMF_KEYSTORE_OPENSSL) {
894		(void) fprintf(stderr, gettext("ECC certificates are"
895		    "only supported with the pkcs11 and nss keystores\n"));
896		rv = PK_ERR_USAGE;
897		goto end;
898	}
899
900	if (kstype == KMF_KEYSTORE_NSS || kstype == KMF_KEYSTORE_PK11TOKEN) {
901		if (tokenname == NULL || !strlen(tokenname)) {
902			if (kstype == KMF_KEYSTORE_NSS) {
903				tokenname = "internal";
904			} else  {
905				tokenname = PK_DEFAULT_PK11TOKEN;
906			}
907		}
908
909		(void) get_token_password(kstype, tokenname, &tokencred);
910	}
911
912	if (kstype == KMF_KEYSTORE_NSS) {
913		if (dir == NULL)
914			dir = PK_DEFAULT_DIRECTORY;
915
916		rv = gencert_nss(kmfhandle,
917		    tokenname, subname, altname, alttype, altcrit,
918		    certlabel, dir, prefix, keyAlg, sigAlg, keylen,
919		    trust, ltime, &serial, kubits, kucrit, &tokencred,
920		    ekulist, curveoid);
921
922	} else if (kstype == KMF_KEYSTORE_PK11TOKEN) {
923		rv = gencert_pkcs11(kmfhandle,
924		    tokenname, subname, altname, alttype, altcrit,
925		    certlabel, keyAlg, sigAlg, keylen, ltime,
926		    &serial, kubits, kucrit, &tokencred, ekulist,
927		    curveoid);
928
929	} else if (kstype == KMF_KEYSTORE_OPENSSL) {
930		rv = gencert_file(kmfhandle,
931		    keyAlg, sigAlg, keylen, fmt,
932		    ltime, subname, altname, alttype, altcrit,
933		    &serial, kubits, kucrit, outcert, outkey,
934		    ekulist);
935	}
936
937	if (rv != KMF_OK)
938		display_error(kmfhandle, rv,
939		    gettext("Error creating certificate and keypair"));
940end:
941	if (ekulist != NULL)
942		free_eku_list(ekulist);
943	if (subname)
944		free(subname);
945	if (tokencred.cred != NULL)
946		free(tokencred.cred);
947
948	if (serial.val != NULL)
949		free(serial.val);
950
951	(void) kmf_finalize(kmfhandle);
952	return (rv);
953}
954