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