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) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
22 */
23
24 /*
25 * This file implements the sign CSR operation for this tool.
26 */
27
28 #include <stdio.h>
29 #include <errno.h>
30 #include <string.h>
31 #include <cryptoutil.h>
32 #include <security/cryptoki.h>
33 #include "common.h"
34
35 #include <kmfapi.h>
36 #include <kmfapiP.h>
37
38 #define SET_VALUE(f, s) \
39 rv = f; \
40 if (rv != KMF_OK) { \
41 cryptoerror(LOG_STDERR, \
42 gettext("Failed to set %s: 0x%02x\n"), s, rv); \
43 goto cleanup; \
44 }
45
46
47 static int
read_csrdata(KMF_HANDLE_T handle,char * csrfile,KMF_CSR_DATA * csrdata)48 read_csrdata(KMF_HANDLE_T handle, char *csrfile, KMF_CSR_DATA *csrdata)
49 {
50 KMF_RETURN rv = KMF_OK;
51 KMF_ENCODE_FORMAT csrfmt;
52 KMF_DATA csrfiledata = { 0, NULL };
53 KMF_DATA rawcsr = { 0, NULL };
54
55 rv = kmf_get_file_format(csrfile, &csrfmt);
56 if (rv != KMF_OK)
57 return (rv);
58
59 rv = kmf_read_input_file(handle, csrfile, &csrfiledata);
60 if (rv != KMF_OK)
61 return (rv);
62
63 if (csrfmt == KMF_FORMAT_PEM) {
64 rv = kmf_pem_to_der(csrfiledata.Data, csrfiledata.Length,
65 &rawcsr.Data, (int *)&rawcsr.Length);
66 if (rv != KMF_OK)
67 return (rv);
68
69 kmf_free_data(&csrfiledata);
70 } else {
71 rawcsr.Data = csrfiledata.Data;
72 rawcsr.Length = csrfiledata.Length;
73 }
74
75 rv = kmf_decode_csr(handle, &rawcsr, csrdata);
76 kmf_free_data(&rawcsr);
77
78 return (rv);
79 }
80
81 static KMF_RETURN
find_csr_extn(KMF_X509_EXTENSIONS * extnlist,KMF_OID * extoid,KMF_X509_EXTENSION * outextn)82 find_csr_extn(KMF_X509_EXTENSIONS *extnlist, KMF_OID *extoid,
83 KMF_X509_EXTENSION *outextn)
84 {
85 int i, found = 0;
86 KMF_X509_EXTENSION *eptr;
87 KMF_RETURN rv = KMF_OK;
88
89 (void) memset(outextn, 0, sizeof (KMF_X509_EXTENSION));
90 for (i = 0; !found && i < extnlist->numberOfExtensions; i++) {
91 eptr = &extnlist->extensions[i];
92 if (IsEqualOid(extoid, &eptr->extnId)) {
93 rv = copy_extension_data(outextn, eptr);
94 found++;
95 }
96 }
97 if (found == 0 || rv != KMF_OK)
98 return (1);
99 else
100 return (rv);
101 }
102
103 static int
build_cert_from_csr(KMF_CSR_DATA * csrdata,KMF_X509_CERTIFICATE * signedCert,KMF_BIGINT * serial,uint32_t ltime,char * issuer,char * subject,char * altname,KMF_GENERALNAMECHOICES alttype,int altcrit,uint16_t kubits,int kucrit,EKU_LIST * ekulist)104 build_cert_from_csr(KMF_CSR_DATA *csrdata,
105 KMF_X509_CERTIFICATE *signedCert,
106 KMF_BIGINT *serial,
107 uint32_t ltime,
108 char *issuer, char *subject,
109 char *altname,
110 KMF_GENERALNAMECHOICES alttype,
111 int altcrit,
112 uint16_t kubits,
113 int kucrit,
114 EKU_LIST *ekulist)
115 {
116 KMF_RETURN rv = KMF_OK;
117 KMF_X509_NAME issuerDN, subjectDN;
118
119 /*
120 * If the CSR is ok, now we can generate the final certificate.
121 */
122 (void) memset(signedCert, 0, sizeof (KMF_X509_CERTIFICATE));
123 (void) memset(&issuerDN, 0, sizeof (issuerDN));
124 (void) memset(&subjectDN, 0, sizeof (subjectDN));
125
126 SET_VALUE(kmf_set_cert_version(signedCert, 2), "version number");
127
128 SET_VALUE(kmf_set_cert_serial(signedCert, serial), "serial number");
129
130 SET_VALUE(kmf_set_cert_validity(signedCert, NULL, ltime),
131 "validity time");
132
133 if (issuer) {
134 if (kmf_dn_parser(issuer, &issuerDN) != KMF_OK) {
135 cryptoerror(LOG_STDERR,
136 gettext("Issuer name cannot be parsed\n"));
137 return (PK_ERR_USAGE);
138 }
139 SET_VALUE(kmf_set_cert_issuer(signedCert, &issuerDN),
140 "Issuer Name");
141 }
142 if (subject) {
143 if (kmf_dn_parser(subject, &subjectDN) != KMF_OK) {
144 cryptoerror(LOG_STDERR,
145 gettext("Subject name cannot be parsed\n"));
146 return (PK_ERR_USAGE);
147 }
148 SET_VALUE(kmf_set_cert_subject(signedCert, &subjectDN),
149 "Subject Name");
150 } else {
151 signedCert->certificate.subject = csrdata->csr.subject;
152 }
153
154 signedCert->certificate.subjectPublicKeyInfo =
155 csrdata->csr.subjectPublicKeyInfo;
156
157 signedCert->certificate.extensions = csrdata->csr.extensions;
158
159 signedCert->certificate.signature =
160 csrdata->signature.algorithmIdentifier;
161
162 if (kubits != 0) {
163 KMF_X509_EXTENSION extn;
164 uint16_t oldbits;
165 /*
166 * If the CSR already has KU, merge them.
167 */
168 rv = find_csr_extn(&csrdata->csr.extensions,
169 (KMF_OID *)&KMFOID_KeyUsage, &extn);
170 if (rv == KMF_OK) {
171 extn.critical |= kucrit;
172 if (extn.value.tagAndValue->value.Length > 1) {
173 oldbits =
174 extn.value.tagAndValue->value.Data[1] << 8;
175 } else {
176 oldbits =
177 extn.value.tagAndValue->value.Data[0];
178 }
179 oldbits |= kubits;
180 } else {
181 SET_VALUE(kmf_set_cert_ku(signedCert, kucrit, kubits),
182 "KeyUsage");
183 }
184 }
185 if (altname != NULL) {
186 SET_VALUE(kmf_set_cert_subject_altname(signedCert,
187 altcrit, alttype, altname), "subjectAltName");
188 }
189 if (ekulist != NULL) {
190 int i;
191 for (i = 0; rv == KMF_OK && i < ekulist->eku_count; i++) {
192 SET_VALUE(kmf_add_cert_eku(signedCert,
193 &ekulist->ekulist[i],
194 ekulist->critlist[i]), "Extended Key Usage");
195 }
196 }
197 cleanup:
198 if (issuer != NULL)
199 kmf_free_dn(&issuerDN);
200 if (subject != NULL)
201 kmf_free_dn(&subjectDN);
202
203 return (rv);
204 }
205
206 static int
pk_sign_cert(KMF_HANDLE_T handle,KMF_X509_CERTIFICATE * cert,KMF_KEY_HANDLE * key,KMF_OID * sigoid,KMF_DATA * outdata)207 pk_sign_cert(KMF_HANDLE_T handle, KMF_X509_CERTIFICATE *cert,
208 KMF_KEY_HANDLE *key, KMF_OID *sigoid, KMF_DATA *outdata)
209 {
210 KMF_RETURN rv;
211 int numattr;
212 KMF_ATTRIBUTE attrlist[4];
213
214 numattr = 0;
215 kmf_set_attr_at_index(attrlist, numattr++, KMF_KEYSTORE_TYPE_ATTR,
216 &key->kstype, sizeof (KMF_KEYSTORE_TYPE));
217
218 kmf_set_attr_at_index(attrlist, numattr++, KMF_KEY_HANDLE_ATTR,
219 key, sizeof (KMF_KEY_HANDLE_ATTR));
220
221 /* cert data that is to be signed */
222 kmf_set_attr_at_index(attrlist, numattr++, KMF_X509_CERTIFICATE_ATTR,
223 cert, sizeof (KMF_X509_CERTIFICATE));
224
225 /* output buffer for the signed cert */
226 kmf_set_attr_at_index(attrlist, numattr++, KMF_CERT_DATA_ATTR,
227 outdata, sizeof (KMF_DATA));
228
229 /* Set the signature OID value so KMF knows how to generate the sig */
230 if (sigoid) {
231 kmf_set_attr_at_index(attrlist, numattr++, KMF_OID_ATTR,
232 sigoid, sizeof (KMF_OID));
233 }
234
235 if ((rv = kmf_sign_cert(handle, numattr, attrlist)) != KMF_OK) {
236 cryptoerror(LOG_STDERR,
237 gettext("Failed to sign certificate.\n"));
238 return (rv);
239 }
240
241 return (rv);
242 }
243
244 static int
pk_signcsr_files(KMF_HANDLE_T handle,char * signkey,char * csrfile,KMF_BIGINT * serial,char * certfile,char * issuer,char * subject,char * altname,KMF_GENERALNAMECHOICES alttype,int altcrit,uint16_t kubits,int kucrit,EKU_LIST * ekulist,uint32_t ltime,KMF_ENCODE_FORMAT fmt)245 pk_signcsr_files(KMF_HANDLE_T handle,
246 char *signkey,
247 char *csrfile,
248 KMF_BIGINT *serial,
249 char *certfile,
250 char *issuer,
251 char *subject,
252 char *altname,
253 KMF_GENERALNAMECHOICES alttype,
254 int altcrit,
255 uint16_t kubits,
256 int kucrit,
257 EKU_LIST *ekulist,
258 uint32_t ltime,
259 KMF_ENCODE_FORMAT fmt)
260 {
261 KMF_RETURN rv = KMF_OK;
262 KMF_CSR_DATA csrdata;
263 KMF_ATTRIBUTE attrlist[16];
264 KMF_X509_CERTIFICATE signedCert;
265 KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
266 KMF_KEY_CLASS keyclass = KMF_ASYM_PRI;
267 KMF_KEY_HANDLE cakey;
268 KMF_DATA certdata = { 0, NULL };
269 int numattr, count;
270
271 (void) memset(&cakey, 0, sizeof (cakey));
272 (void) memset(&signedCert, 0, sizeof (signedCert));
273
274 rv = read_csrdata(handle, csrfile, &csrdata);
275 if (rv != KMF_OK) {
276 cryptoerror(LOG_STDERR,
277 gettext("Error reading CSR data\n"));
278 return (rv);
279 }
280
281 /* verify the signature first */
282 numattr = 0;
283 kmf_set_attr_at_index(attrlist, numattr, KMF_CSR_DATA_ATTR,
284 &csrdata, sizeof (csrdata));
285 numattr++;
286
287 rv = kmf_verify_csr(handle, numattr, attrlist);
288 if (rv != KMF_OK) {
289 cryptoerror(LOG_STDERR, gettext("CSR signature "
290 "verification failed.\n"));
291 goto cleanup;
292 }
293
294 rv = build_cert_from_csr(&csrdata, &signedCert, serial, ltime,
295 issuer, subject, altname, alttype, altcrit, kubits,
296 kucrit, ekulist);
297
298 if (rv != KMF_OK)
299 goto cleanup;
300
301 /*
302 * Find the signing key.
303 */
304 (void) memset(&cakey, 0, sizeof (cakey));
305
306 numattr = 0;
307 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
308 &kstype, sizeof (kstype));
309 numattr++;
310
311 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_FILENAME_ATTR,
312 signkey, strlen(signkey));
313 numattr++;
314
315 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
316 &keyclass, sizeof (keyclass));
317 numattr++;
318
319 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
320 &cakey, sizeof (cakey));
321 numattr++;
322
323 count = 1;
324 kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
325 &count, sizeof (count));
326 numattr++;
327
328 rv = kmf_find_key(handle, numattr, attrlist);
329 if (rv != KMF_OK) {
330 cryptoerror(LOG_STDERR, gettext(
331 "Error finding CA signing key\n"));
332 goto cleanup;
333 }
334
335 rv = pk_sign_cert(handle, &signedCert, &cakey, NULL, &certdata);
336 if (rv != KMF_OK) {
337 cryptoerror(LOG_STDERR, gettext(
338 "Error signing certificate.\n"));
339 goto cleanup;
340 }
341
342 rv = kmf_create_cert_file(&certdata, fmt, certfile);
343
344 cleanup:
345 kmf_free_signed_csr(&csrdata);
346 kmf_free_data(&certdata);
347 kmf_free_kmf_key(handle, &cakey);
348 return (rv);
349 }
350
351 static int
pk_signcsr_pk11_nss(KMF_HANDLE_T handle,KMF_KEYSTORE_TYPE kstype,char * dir,char * prefix,char * token,KMF_CREDENTIAL * cred,char * signkey,char * csrfile,KMF_BIGINT * serial,char * certfile,char * issuer,char * subject,char * altname,KMF_GENERALNAMECHOICES alttype,int altcrit,uint16_t kubits,int kucrit,EKU_LIST * ekulist,uint32_t ltime,KMF_ENCODE_FORMAT fmt,int store,char * outlabel)352 pk_signcsr_pk11_nss(KMF_HANDLE_T handle,
353 KMF_KEYSTORE_TYPE kstype,
354 char *dir, char *prefix,
355 char *token, KMF_CREDENTIAL *cred,
356 char *signkey, char *csrfile,
357 KMF_BIGINT *serial, char *certfile, char *issuer, char *subject,
358 char *altname, KMF_GENERALNAMECHOICES alttype, int altcrit,
359 uint16_t kubits, int kucrit,
360 EKU_LIST *ekulist, uint32_t ltime,
361 KMF_ENCODE_FORMAT fmt, int store, char *outlabel)
362 {
363 KMF_RETURN rv = KMF_OK;
364 KMF_DATA outcert = { 0, NULL };
365 KMF_CSR_DATA csrdata = { 0, NULL };
366 KMF_KEY_HANDLE casignkey;
367 KMF_KEY_CLASS keyclass = KMF_ASYM_PRI;
368 KMF_ATTRIBUTE attrlist[16];
369 KMF_X509_CERTIFICATE signedCert;
370 boolean_t token_bool = B_TRUE;
371 boolean_t private_bool = B_TRUE;
372 int numattr = 0;
373 int keys = 1;
374
375 (void) memset(&casignkey, 0, sizeof (KMF_KEY_HANDLE));
376 (void) memset(&signedCert, 0, sizeof (signedCert));
377
378 rv = read_csrdata(handle, csrfile, &csrdata);
379 if (rv != KMF_OK) {
380 cryptoerror(LOG_STDERR,
381 gettext("Error reading CSR data\n"));
382 return (rv);
383 }
384
385 if (kstype == KMF_KEYSTORE_PK11TOKEN) {
386 rv = select_token(handle, token, FALSE);
387 } else if (kstype == KMF_KEYSTORE_NSS) {
388 rv = configure_nss(handle, dir, prefix);
389 }
390
391 /* verify the signature first */
392 kmf_set_attr_at_index(attrlist, numattr, KMF_CSR_DATA_ATTR,
393 &csrdata, sizeof (csrdata));
394 numattr++;
395
396 rv = kmf_verify_csr(handle, numattr, attrlist);
397 if (rv != KMF_OK) {
398 cryptoerror(LOG_STDERR, gettext("CSR signature "
399 "verification failed.\n"));
400 goto cleanup;
401 }
402
403 rv = build_cert_from_csr(&csrdata,
404 &signedCert, serial, ltime,
405 issuer, subject, altname,
406 alttype, altcrit, kubits,
407 kucrit, ekulist);
408
409 if (rv != KMF_OK)
410 goto cleanup;
411
412 /*
413 * Find the signing key.
414 */
415 numattr = 0;
416 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
417 &kstype, sizeof (kstype));
418 numattr++;
419 if (kstype == KMF_KEYSTORE_NSS) {
420 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_LABEL_ATTR,
421 token, strlen(token));
422 numattr++;
423 }
424
425 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYLABEL_ATTR, signkey,
426 strlen(signkey));
427 numattr++;
428
429 kmf_set_attr_at_index(attrlist, numattr, KMF_PRIVATE_BOOL_ATTR,
430 &private_bool, sizeof (private_bool));
431 numattr++;
432
433 kmf_set_attr_at_index(attrlist, numattr, KMF_TOKEN_BOOL_ATTR,
434 &token_bool, sizeof (token_bool));
435 numattr++;
436
437 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYCLASS_ATTR,
438 &keyclass, sizeof (keyclass));
439 numattr++;
440
441 kmf_set_attr_at_index(attrlist, numattr, KMF_CREDENTIAL_ATTR,
442 cred, sizeof (KMF_CREDENTIAL_ATTR));
443 numattr++;
444
445 kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
446 &keys, sizeof (keys));
447 numattr++;
448
449 kmf_set_attr_at_index(attrlist, numattr, KMF_KEY_HANDLE_ATTR,
450 &casignkey, sizeof (casignkey));
451 numattr++;
452
453 rv = kmf_find_key(handle, numattr, attrlist);
454 if (rv != KMF_OK) {
455 cryptoerror(LOG_STDERR,
456 gettext("Failed to find signing key\n"));
457 goto cleanup;
458 }
459 /*
460 * If we found the key, now we can sign the cert.
461 */
462 rv = pk_sign_cert(handle, &signedCert, &casignkey, NULL,
463 &outcert);
464 if (rv != KMF_OK) {
465 cryptoerror(LOG_STDERR, gettext(
466 "Error signing certificate.\n"));
467 goto cleanup;
468 }
469
470 /*
471 * Store it on the token if the user asked for it.
472 */
473 if (store) {
474 numattr = 0;
475 kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
476 &kstype, sizeof (kstype));
477 numattr++;
478
479 kmf_set_attr_at_index(attrlist, numattr, KMF_CERT_DATA_ATTR,
480 &outcert, sizeof (KMF_DATA));
481 numattr++;
482
483 if (outlabel != NULL) {
484 kmf_set_attr_at_index(attrlist, numattr,
485 KMF_CERT_LABEL_ATTR,
486 outlabel, strlen(outlabel));
487 numattr++;
488 }
489
490 if (kstype == KMF_KEYSTORE_NSS) {
491 if (token != NULL)
492 kmf_set_attr_at_index(attrlist, numattr,
493 KMF_TOKEN_LABEL_ATTR,
494 token, strlen(token));
495 numattr++;
496 }
497
498 rv = kmf_store_cert(handle, numattr, attrlist);
499 if (rv != KMF_OK) {
500 display_error(handle, rv,
501 gettext("Failed to store cert "
502 "on PKCS#11 token.\n"));
503 rv = KMF_OK;
504 /* Not fatal, we can still write it to a file. */
505 }
506 }
507 rv = kmf_create_cert_file(&outcert, fmt, certfile);
508
509 cleanup:
510 kmf_free_signed_csr(&csrdata);
511 kmf_free_data(&outcert);
512 kmf_free_kmf_key(handle, &casignkey);
513
514 return (rv);
515 }
516
517 /*
518 * sign a CSR and generate an x509v3 certificate file.
519 */
520 int
pk_signcsr(int argc,char * argv[])521 pk_signcsr(int argc, char *argv[])
522 {
523 int opt;
524 extern int optind_av;
525 extern char *optarg_av;
526 char *token_spec = NULL;
527 char *subject = NULL;
528 char *issuer = NULL;
529 char *dir = NULL;
530 char *prefix = NULL;
531 char *csrfile = NULL;
532 char *serstr = NULL;
533 char *ekustr = NULL;
534 char *kustr = NULL;
535 char *format = NULL;
536 char *storestr = NULL;
537 char *altname = NULL;
538 char *certfile = NULL;
539 char *lifetime = NULL;
540 char *signkey = NULL;
541 char *outlabel = NULL;
542 uint32_t ltime = 365 * 24 * 60 * 60; /* 1 Year */
543 int store = 0;
544 uint16_t kubits = 0;
545 int altcrit = 0, kucrit = 0;
546 KMF_BIGINT serial = { NULL, 0 };
547 EKU_LIST *ekulist = NULL;
548 KMF_KEYSTORE_TYPE kstype = 0;
549 KMF_RETURN rv = KMF_OK;
550 KMF_HANDLE_T kmfhandle = NULL;
551 KMF_CREDENTIAL tokencred = { NULL, 0 };
552 KMF_GENERALNAMECHOICES alttype = 0;
553 KMF_ENCODE_FORMAT fmt = KMF_FORMAT_PEM;
554
555 /* Parse command line options. Do NOT i18n/l10n. */
556 while ((opt = getopt_av(argc, argv,
557 "k:(keystore)c:(csr)T:(token)d:(dir)"
558 "p:(prefix)S:(serial)s:(subject)a:(altname)"
559 "t:(store)F:(format)K:(keyusage)l:(signkey)"
560 "L:(lifetime)e:(eku)i:(issuer)"
561 "n:(outlabel)o:(outcert)")) != EOF) {
562 if (EMPTYSTRING(optarg_av))
563 return (PK_ERR_USAGE);
564 switch (opt) {
565 case 'k':
566 if (kstype != 0)
567 return (PK_ERR_USAGE);
568 kstype = KS2Int(optarg_av);
569 if (kstype == 0)
570 return (PK_ERR_USAGE);
571 break;
572 case 't':
573 if (storestr != NULL)
574 return (PK_ERR_USAGE);
575 storestr = optarg_av;
576 store = yn_to_int(optarg_av);
577 if (store == -1)
578 return (PK_ERR_USAGE);
579 break;
580 case 'a':
581 if (altname)
582 return (PK_ERR_USAGE);
583 altname = optarg_av;
584 break;
585 case 's':
586 if (subject)
587 return (PK_ERR_USAGE);
588 subject = optarg_av;
589 break;
590 case 'i':
591 if (issuer)
592 return (PK_ERR_USAGE);
593 issuer = optarg_av;
594 break;
595 case 'd':
596 if (dir)
597 return (PK_ERR_USAGE);
598 dir = optarg_av;
599 break;
600 case 'p':
601 if (prefix)
602 return (PK_ERR_USAGE);
603 prefix = optarg_av;
604 break;
605 case 'S':
606 if (serstr != NULL)
607 return (PK_ERR_USAGE);
608 serstr = optarg_av;
609 break;
610 case 'c':
611 if (csrfile)
612 return (PK_ERR_USAGE);
613 csrfile = optarg_av;
614 break;
615 case 'T': /* token specifier */
616 if (token_spec)
617 return (PK_ERR_USAGE);
618 token_spec = optarg_av;
619 break;
620 case 'l': /* object with specific label */
621 if (signkey)
622 return (PK_ERR_USAGE);
623 signkey = optarg_av;
624 break;
625 case 'e':
626 if (ekustr != NULL)
627 return (PK_ERR_USAGE);
628 ekustr = optarg_av;
629 break;
630 case 'K':
631 if (kustr != NULL)
632 return (PK_ERR_USAGE);
633 kustr = optarg_av;
634 break;
635 case 'F':
636 if (format != NULL)
637 return (PK_ERR_USAGE);
638 format = optarg_av;
639 break;
640 case 'o':
641 if (certfile != NULL)
642 return (PK_ERR_USAGE);
643 certfile = optarg_av;
644 break;
645 case 'L':
646 if (lifetime != NULL)
647 return (PK_ERR_USAGE);
648 lifetime = optarg_av;
649 break;
650 case 'n':
651 if (outlabel != NULL)
652 return (PK_ERR_USAGE);
653 outlabel = optarg_av;
654 break;
655 default:
656 return (PK_ERR_USAGE);
657 }
658 }
659 /* No additional args allowed. */
660 argc -= optind_av;
661 argv += optind_av;
662 if (argc)
663 return (PK_ERR_USAGE);
664
665
666 /* Assume keystore = PKCS#11 if not specified. */
667 if (kstype == 0)
668 kstype = KMF_KEYSTORE_PK11TOKEN;
669
670 DIR_OPTION_CHECK(kstype, dir);
671
672 if (signkey == NULL) {
673 (void) fprintf(stderr, gettext("The signing key label "
674 "or filename was not specified\n"));
675 return (PK_ERR_USAGE);
676 }
677 if (csrfile == NULL) {
678 (void) fprintf(stderr, gettext("The CSR filename was not"
679 " specified\n"));
680 return (PK_ERR_USAGE);
681 }
682 if (certfile == NULL) {
683 (void) fprintf(stderr, gettext("The output certificate file "
684 "was not specified\n"));
685 return (PK_ERR_USAGE);
686 }
687 if (issuer == NULL) {
688 (void) fprintf(stderr, gettext("The issuer DN "
689 "was not specified\n"));
690 return (PK_ERR_USAGE);
691 }
692 if (lifetime != NULL) {
693 if (Str2Lifetime(lifetime, <ime) != 0) {
694 cryptoerror(LOG_STDERR,
695 gettext("Error parsing lifetime string\n"));
696 return (PK_ERR_USAGE);
697 }
698 }
699 if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) {
700 token_spec = PK_DEFAULT_PK11TOKEN;
701 } else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) {
702 token_spec = DEFAULT_NSS_TOKEN;
703 }
704
705 if (serstr != NULL) {
706 uchar_t *bytes = NULL;
707 size_t bytelen;
708
709 rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen);
710 if (rv != KMF_OK || bytes == NULL) {
711 (void) fprintf(stderr, gettext("Serial number "
712 "must be specified as a hex number "
713 "(ex: 0x0102030405ffeeddee)\n"));
714 return (PK_ERR_USAGE);
715 }
716 serial.val = bytes;
717 serial.len = bytelen;
718 } else {
719 (void) fprintf(stderr, gettext("The serial number was not"
720 " specified\n"));
721 return (PK_ERR_USAGE);
722 }
723
724 if ((kstype == KMF_KEYSTORE_PK11TOKEN ||
725 kstype == KMF_KEYSTORE_NSS)) {
726 /* Need to get password for private key access */
727 (void) get_token_password(kstype, token_spec,
728 &tokencred);
729 }
730 if (kustr != NULL) {
731 rv = verify_keyusage(kustr, &kubits, &kucrit);
732 if (rv != KMF_OK) {
733 (void) fprintf(stderr, gettext("KeyUsage "
734 "must be specified as a comma-separated list. "
735 "See the man page for details.\n"));
736 rv = PK_ERR_USAGE;
737 goto end;
738 }
739 }
740 if (ekustr != NULL) {
741 rv = verify_ekunames(ekustr, &ekulist);
742 if (rv != KMF_OK) {
743 (void) fprintf(stderr, gettext("EKUs must "
744 "be specified as a comma-separated list. "
745 "See the man page for details.\n"));
746 rv = PK_ERR_USAGE;
747 goto end;
748 }
749 }
750 if (altname != NULL) {
751 char *p;
752 rv = verify_altname(altname, &alttype, &altcrit);
753 if (rv != KMF_OK) {
754 (void) fprintf(stderr, gettext("Subject AltName "
755 "must be specified as a name=value pair. "
756 "See the man page for details.\n"));
757 rv = PK_ERR_USAGE;
758 goto end;
759 }
760 /* advance the altname past the '=' sign */
761 p = strchr(altname, '=');
762 if (p != NULL)
763 altname = p + 1;
764 }
765 if (format && (fmt = Str2Format(format)) == KMF_FORMAT_UNDEF) {
766 cryptoerror(LOG_STDERR,
767 gettext("Error parsing format string (%s).\n"),
768 format);
769 return (PK_ERR_USAGE);
770 }
771
772 if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
773 return (rv);
774 }
775
776 if (kstype == KMF_KEYSTORE_PK11TOKEN) {
777 rv = pk_signcsr_pk11_nss(kmfhandle,
778 kstype, dir, prefix, token_spec, &tokencred,
779 signkey, csrfile, &serial, certfile, issuer, subject,
780 altname, alttype, altcrit, kubits, kucrit,
781 ekulist, ltime, fmt, store, outlabel);
782
783 } else if (kstype == KMF_KEYSTORE_NSS) {
784 if (dir == NULL)
785 dir = PK_DEFAULT_DIRECTORY;
786
787 rv = pk_signcsr_pk11_nss(kmfhandle,
788 kstype, dir, prefix, token_spec, &tokencred,
789 signkey, csrfile, &serial, certfile, issuer, subject,
790 altname, alttype, altcrit, kubits, kucrit,
791 ekulist, ltime, fmt, store, outlabel);
792
793 } else if (kstype == KMF_KEYSTORE_OPENSSL) {
794 rv = pk_signcsr_files(kmfhandle,
795 signkey, csrfile, &serial, certfile, issuer, subject,
796 altname, alttype, altcrit, kubits, kucrit,
797 ekulist, ltime, fmt);
798 }
799
800 end:
801 if (rv != KMF_OK) {
802 display_error(kmfhandle, rv,
803 gettext("Error listing objects"));
804 }
805
806 if (serial.val != NULL)
807 free(serial.val);
808
809 if (tokencred.cred != NULL)
810 free(tokencred.cred);
811
812 free_eku_list(ekulist);
813
814 (void) kmf_finalize(kmfhandle);
815 return (rv);
816 }
817