1 /* $OpenBSD: req.c,v 1.23 2022/02/03 17:44:04 tb Exp $ */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59 /* Until the key-gen callbacks are modified to use newer prototypes, we allow
60 * deprecated functions for openssl-internal code */
61 #ifdef OPENSSL_NO_DEPRECATED
62 #undef OPENSSL_NO_DEPRECATED
63 #endif
64
65 #include <ctype.h>
66 #include <limits.h>
67 #include <stdio.h>
68 #include <stdlib.h>
69 #include <string.h>
70 #include <time.h>
71
72 #include "apps.h"
73
74 #include <openssl/asn1.h>
75 #include <openssl/bio.h>
76 #include <openssl/bn.h>
77 #include <openssl/conf.h>
78 #include <openssl/err.h>
79 #include <openssl/evp.h>
80 #include <openssl/objects.h>
81 #include <openssl/pem.h>
82 #include <openssl/x509.h>
83 #include <openssl/x509v3.h>
84
85 #include <openssl/dsa.h>
86
87 #include <openssl/rsa.h>
88
89 #define SECTION "req"
90
91 #define BITS "default_bits"
92 #define KEYFILE "default_keyfile"
93 #define PROMPT "prompt"
94 #define DISTINGUISHED_NAME "distinguished_name"
95 #define ATTRIBUTES "attributes"
96 #define V3_EXTENSIONS "x509_extensions"
97 #define REQ_EXTENSIONS "req_extensions"
98 #define STRING_MASK "string_mask"
99 #define UTF8_IN "utf8"
100
101 #define DEFAULT_KEY_LENGTH 2048
102 #define MIN_KEY_LENGTH 384
103
104 static int make_REQ(X509_REQ * req, EVP_PKEY * pkey, char *dn, int multirdn,
105 int attribs, unsigned long chtype);
106 static int build_subject(X509_REQ * req, char *subj, unsigned long chtype,
107 int multirdn);
108 static int prompt_info(X509_REQ * req,
109 STACK_OF(CONF_VALUE) * dn_sk, char *dn_sect,
110 STACK_OF(CONF_VALUE) * attr_sk, char *attr_sect, int attribs,
111 unsigned long chtype);
112 static int auto_info(X509_REQ * req, STACK_OF(CONF_VALUE) * sk,
113 STACK_OF(CONF_VALUE) * attr, int attribs,
114 unsigned long chtype);
115 static int add_attribute_object(X509_REQ * req, char *text, const char *def,
116 char *value, int nid, int n_min,
117 int n_max, unsigned long chtype);
118 static int add_DN_object(X509_NAME * n, char *text, const char *def, char *value,
119 int nid, int n_min, int n_max, unsigned long chtype, int mval);
120 static int genpkey_cb(EVP_PKEY_CTX * ctx);
121 static int req_check_len(int len, int n_min, int n_max);
122 static int check_end(const char *str, const char *end);
123 static EVP_PKEY_CTX *set_keygen_ctx(BIO * err, const char *gstr, int *pkey_type,
124 long *pkeylen, char **palgnam);
125 static unsigned long ext_name_hash(const OPENSSL_STRING *a);
126 static int ext_name_cmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b);
127 static void exts_cleanup(OPENSSL_STRING *x);
128 static int duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv);
129 static CONF *req_conf = NULL;
130 static CONF *addext_conf = NULL;
131
132 struct {
133 LHASH_OF(OPENSSL_STRING) *addexts;
134 BIO *addext_bio;
135 int batch;
136 unsigned long chtype;
137 int days;
138 const EVP_MD *digest;
139 char *extensions;
140 char *infile;
141 int informat;
142 char *keyalg;
143 char *keyfile;
144 int keyform;
145 char *keyout;
146 int modulus;
147 int multirdn;
148 int newhdr;
149 long newkey;
150 int newreq;
151 unsigned long nmflag;
152 int nodes;
153 int noout;
154 char *outfile;
155 int outformat;
156 char *passargin;
157 char *passargout;
158 STACK_OF(OPENSSL_STRING) *pkeyopts;
159 int pubkey;
160 char *req_exts;
161 unsigned long reqflag;
162 ASN1_INTEGER *serial;
163 STACK_OF(OPENSSL_STRING) *sigopts;
164 char *subj;
165 int subject;
166 char *template;
167 int text;
168 int verbose;
169 int verify;
170 int x509;
171 } req_config;
172
173 static int
req_opt_addext(char * arg)174 req_opt_addext(char *arg)
175 {
176 int i;
177
178 if (req_config.addexts == NULL) {
179 req_config.addexts = (LHASH_OF(OPENSSL_STRING) *)lh_new(
180 (LHASH_HASH_FN_TYPE)ext_name_hash,
181 (LHASH_COMP_FN_TYPE)ext_name_cmp);
182 req_config.addext_bio = BIO_new(BIO_s_mem());
183 if (req_config.addexts == NULL ||
184 req_config.addext_bio == NULL)
185 return (1);
186 }
187 i = duplicated(req_config.addexts, arg);
188 if (i == 1)
189 return (1);
190 if (i < 0 || BIO_printf(req_config.addext_bio, "%s\n", arg) < 0)
191 return (1);
192
193 return (0);
194 }
195
196 static int
req_opt_days(char * arg)197 req_opt_days(char *arg)
198 {
199 const char *errstr;
200
201 req_config.days = strtonum(arg, 1, INT_MAX, &errstr);
202 if (errstr != NULL) {
203 BIO_printf(bio_err, "bad -days %s, using 0: %s\n",
204 arg, errstr);
205 req_config.days = 30;
206 }
207 return (0);
208 }
209
210 static int
req_opt_digest(int argc,char ** argv,int * argsused)211 req_opt_digest(int argc, char **argv, int *argsused)
212 {
213 char *name = argv[0];
214
215 if (*name++ != '-')
216 return (1);
217
218 if ((req_config.digest = EVP_get_digestbyname(name)) == NULL)
219 return (1);
220
221 *argsused = 1;
222 return (0);
223 }
224
225 static int
req_opt_newkey(char * arg)226 req_opt_newkey(char *arg)
227 {
228 req_config.keyalg = arg;
229 req_config.newreq = 1;
230 return (0);
231 }
232
233 static int
req_opt_nameopt(char * arg)234 req_opt_nameopt(char *arg)
235 {
236 if (!set_name_ex(&req_config.nmflag, arg))
237 return (1);
238 return (0);
239 }
240
241 static int
req_opt_pkeyopt(char * arg)242 req_opt_pkeyopt(char *arg)
243 {
244 if (req_config.pkeyopts == NULL)
245 req_config.pkeyopts = sk_OPENSSL_STRING_new_null();
246 if (req_config.pkeyopts == NULL)
247 return (1);
248 if (!sk_OPENSSL_STRING_push(req_config.pkeyopts, arg))
249 return (1);
250 return (0);
251 }
252
253 static int
req_opt_reqopt(char * arg)254 req_opt_reqopt(char *arg)
255 {
256 if (!set_cert_ex(&req_config.reqflag, arg))
257 return (1);
258 return (0);
259 }
260
261 static int
req_opt_set_serial(char * arg)262 req_opt_set_serial(char *arg)
263 {
264 req_config.serial = s2i_ASN1_INTEGER(NULL, arg);
265 if (req_config.serial == NULL)
266 return (1);
267 return (0);
268 }
269
270 static int
req_opt_sigopt(char * arg)271 req_opt_sigopt(char *arg)
272 {
273 if (req_config.sigopts == NULL)
274 req_config.sigopts = sk_OPENSSL_STRING_new_null();
275 if (req_config.sigopts == NULL)
276 return (1);
277 if (!sk_OPENSSL_STRING_push(req_config.sigopts, arg))
278 return (1);
279 return (0);
280 }
281
282 static int
req_opt_utf8(void)283 req_opt_utf8(void)
284 {
285 req_config.chtype = MBSTRING_UTF8;
286 return (0);
287 }
288
289 static const struct option req_options[] = {
290 {
291 .name = "addext",
292 .argname = "key=value",
293 .desc = "Additional certificate extension (may be repeated)",
294 .type = OPTION_ARG_FUNC,
295 .opt.argfunc = req_opt_addext,
296 },
297 {
298 .name = "batch",
299 .desc = "Operate in batch mode",
300 .type = OPTION_FLAG,
301 .opt.flag = &req_config.batch,
302 },
303 {
304 .name = "config",
305 .argname = "file",
306 .desc = "Configuration file to use as request template",
307 .type = OPTION_ARG,
308 .opt.arg = &req_config.template,
309 },
310 {
311 .name = "days",
312 .argname = "number",
313 .desc = "Number of days generated certificate is valid for",
314 .type = OPTION_ARG_FUNC,
315 .opt.argfunc = req_opt_days,
316 },
317 {
318 .name = "extensions",
319 .argname = "section",
320 .desc = "Config section to use for certificate extensions",
321 .type = OPTION_ARG,
322 .opt.arg = &req_config.extensions,
323 },
324 {
325 .name = "in",
326 .argname = "file",
327 .desc = "Input file (default stdin)",
328 .type = OPTION_ARG,
329 .opt.arg = &req_config.infile,
330 },
331 {
332 .name = "inform",
333 .argname = "format",
334 .desc = "Input format (DER or PEM (default))",
335 .type = OPTION_ARG_FORMAT,
336 .opt.value = &req_config.informat,
337 },
338 {
339 .name = "key",
340 .argname = "file",
341 .desc = "Private key file",
342 .type = OPTION_ARG,
343 .opt.arg = &req_config.keyfile,
344 },
345 {
346 .name = "keyform",
347 .argname = "format",
348 .desc = "Private key format (DER or PEM (default))",
349 .type = OPTION_ARG_FORMAT,
350 .opt.value = &req_config.keyform,
351 },
352 {
353 .name = "keyout",
354 .argname = "file",
355 .desc = "Private key output file",
356 .type = OPTION_ARG,
357 .opt.arg = &req_config.keyout,
358 },
359 {
360 .name = "modulus",
361 .desc = "Print RSA modulus",
362 .type = OPTION_FLAG,
363 .opt.flag = &req_config.modulus,
364 },
365 {
366 .name = "multivalue-rdn",
367 .desc = "Enable support for multivalued RDNs",
368 .type = OPTION_FLAG,
369 .opt.flag = &req_config.multirdn,
370 },
371 {
372 .name = "nameopt",
373 .argname = "arg",
374 .desc = "Certificate name options",
375 .type = OPTION_ARG_FUNC,
376 .opt.argfunc = req_opt_nameopt,
377 },
378 {
379 .name = "new",
380 .desc = "New request",
381 .type = OPTION_FLAG,
382 .opt.flag = &req_config.newreq,
383 },
384 {
385 .name = "newhdr",
386 .desc = "Include 'NEW' in header lines",
387 .type = OPTION_FLAG,
388 .opt.flag = &req_config.newhdr,
389 },
390 {
391 .name = "newkey",
392 .argname = "param",
393 .desc = "Generate a new key using given parameters",
394 .type = OPTION_ARG_FUNC,
395 .opt.argfunc = req_opt_newkey,
396 },
397 {
398 .name = "nodes",
399 .desc = "Do not encrypt output private key",
400 .type = OPTION_FLAG,
401 .opt.flag = &req_config.nodes,
402 },
403 {
404 .name = "noout",
405 .desc = "Do not output request",
406 .type = OPTION_FLAG,
407 .opt.flag = &req_config.noout,
408 },
409 {
410 .name = "out",
411 .argname = "file",
412 .desc = "Output file (default stdout)",
413 .type = OPTION_ARG,
414 .opt.arg = &req_config.outfile,
415 },
416 {
417 .name = "outform",
418 .argname = "format",
419 .desc = "Output format (DER or PEM (default))",
420 .type = OPTION_ARG_FORMAT,
421 .opt.value = &req_config.outformat,
422 },
423 {
424 .name = "passin",
425 .argname = "source",
426 .desc = "Private key input password source",
427 .type = OPTION_ARG,
428 .opt.arg = &req_config.passargin,
429 },
430 {
431 .name = "passout",
432 .argname = "source",
433 .desc = "Private key output password source",
434 .type = OPTION_ARG,
435 .opt.arg = &req_config.passargout,
436 },
437 {
438 .name = "pkeyopt",
439 .argname = "opt:val",
440 .desc = "Set the public key algorithm option opt to val",
441 .type = OPTION_ARG_FUNC,
442 .opt.argfunc = req_opt_pkeyopt,
443 },
444 {
445 .name = "pubkey",
446 .desc = "Output the public key",
447 .type = OPTION_FLAG,
448 .opt.flag = &req_config.pubkey,
449 },
450 {
451 .name = "reqexts",
452 .argname = "section",
453 .desc = "Config section to use for request extensions",
454 .type = OPTION_ARG,
455 .opt.arg = &req_config.req_exts,
456 },
457 {
458 .name = "reqopt",
459 .argname = "option",
460 .desc = "Request text options",
461 .type = OPTION_ARG_FUNC,
462 .opt.argfunc = req_opt_reqopt,
463 },
464 {
465 .name = "set_serial",
466 .argname = "serial",
467 .desc = "Serial number to use for generated certificate",
468 .type = OPTION_ARG_FUNC,
469 .opt.argfunc = req_opt_set_serial,
470 },
471 {
472 .name = "sigopt",
473 .argname = "name:val",
474 .desc = "Signature options",
475 .type = OPTION_ARG_FUNC,
476 .opt.argfunc = req_opt_sigopt,
477 },
478 {
479 .name = "subj",
480 .argname = "name",
481 .desc = "Set or modify the request subject",
482 .type = OPTION_ARG,
483 .opt.arg = &req_config.subj,
484 },
485 {
486 .name = "subject",
487 .desc = "Output the subject of the request",
488 .type = OPTION_FLAG,
489 .opt.flag = &req_config.subject,
490 },
491 {
492 .name = "text",
493 .desc = "Print request in text form",
494 .type = OPTION_FLAG,
495 .opt.flag = &req_config.text,
496 },
497 {
498 .name = "utf8",
499 .desc = "Input characters are in UTF-8 (default ASCII)",
500 .type = OPTION_FUNC,
501 .opt.func = req_opt_utf8,
502 },
503 {
504 .name = "verbose",
505 .desc = "Verbose",
506 .type = OPTION_FLAG,
507 .opt.flag = &req_config.verbose,
508 },
509 {
510 .name = "verify",
511 .desc = "Verify signature on request",
512 .type = OPTION_FLAG,
513 .opt.flag = &req_config.verify,
514 },
515 {
516 .name = "x509",
517 .desc = "Output an X.509 structure instead of a certificate request",
518 .type = OPTION_FLAG,
519 .opt.flag = &req_config.x509,
520 },
521 {
522 .name = NULL,
523 .desc = "",
524 .type = OPTION_ARGV_FUNC,
525 .opt.argvfunc = req_opt_digest,
526 },
527 { NULL },
528 };
529
530 static void
req_usage(void)531 req_usage(void)
532 {
533 fprintf(stderr,
534 "usage: req [-addext ext] [-batch] [-config file]\n"
535 " [-days n] [-extensions section] [-in file]\n"
536 " [-inform der | pem] [-key keyfile] [-keyform der | pem]\n"
537 " [-keyout file] [-md4 | -md5 | -sha1] [-modulus]\n"
538 " [-multivalue-rdn] [-nameopt option] [-new] [-newhdr]\n"
539 " [-newkey arg] [-nodes] [-noout]\n"
540 " [-out file] [-outform der | pem] [-passin arg]\n"
541 " [-passout arg] [-pkeyopt opt:value] [-pubkey]\n"
542 " [-reqexts section] [-reqopt option] [-set_serial n]\n"
543 " [-sigopt nm:v] [-subj arg] [-subject] [-text] [-utf8]\n"
544 " [-verbose] [-verify] [-x509]\n\n");
545
546 options_usage(req_options);
547 fprintf(stderr, "\n");
548 }
549
550 int
req_main(int argc,char ** argv)551 req_main(int argc, char **argv)
552 {
553 int ex = 1;
554 X509 *x509ss = NULL;
555 X509_REQ *req = NULL;
556 EVP_PKEY_CTX *genctx = NULL;
557 char *keyalgstr = NULL;
558 const EVP_CIPHER *cipher = NULL;
559 EVP_PKEY *pkey = NULL;
560 int i = 0, pkey_type = -1;
561 BIO *in = NULL, *out = NULL;
562 char *passin = NULL, *passout = NULL;
563 const EVP_MD *md_alg = NULL;
564 char *p;
565
566 if (single_execution) {
567 if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
568 perror("pledge");
569 exit(1);
570 }
571 }
572
573 memset(&req_config, 0, sizeof(req_config));
574
575 req_config.chtype = MBSTRING_ASC;
576 req_config.days = 30;
577 req_config.digest = EVP_sha256();
578 req_config.newkey = -1;
579 req_config.informat = FORMAT_PEM;
580 req_config.keyform = FORMAT_PEM;
581 req_config.outformat = FORMAT_PEM;
582
583 if (options_parse(argc, argv, req_options, NULL, NULL) != 0) {
584 req_usage();
585 return (1);
586 }
587
588 req_conf = NULL;
589 cipher = EVP_aes_256_cbc();
590
591 if (!app_passwd(bio_err, req_config.passargin, req_config.passargout, &passin, &passout)) {
592 BIO_printf(bio_err, "Error getting passwords\n");
593 goto end;
594 }
595 if (req_config.template != NULL) {
596 long errline = -1;
597
598 if (req_config.verbose)
599 BIO_printf(bio_err, "Using configuration from %s\n", req_config.template);
600 if ((req_conf = NCONF_new(NULL)) == NULL)
601 goto end;
602 if(!NCONF_load(req_conf, req_config.template, &errline)) {
603 BIO_printf(bio_err, "error on line %ld of %s\n", errline, req_config.template);
604 goto end;
605 }
606 } else {
607 req_conf = config;
608
609 if (req_conf == NULL) {
610 BIO_printf(bio_err, "Unable to load config info from %s\n", default_config_file);
611 if (req_config.newreq)
612 goto end;
613 } else if (req_config.verbose)
614 BIO_printf(bio_err, "Using configuration from %s\n",
615 default_config_file);
616 }
617
618 if (req_config.addext_bio != NULL) {
619 long errline = -1;
620 if (req_config.verbose)
621 BIO_printf(bio_err,
622 "Using additional configuration from command line\n");
623 if ((addext_conf = NCONF_new(NULL)) == NULL)
624 goto end;
625 if (!NCONF_load_bio(addext_conf, req_config.addext_bio, &errline)) {
626 BIO_printf(bio_err,
627 "req: Error on line %ld of config input\n",
628 errline);
629 goto end;
630 }
631 }
632
633 if (req_conf != NULL) {
634 if (!load_config(bio_err, req_conf))
635 goto end;
636 p = NCONF_get_string(req_conf, NULL, "oid_file");
637 if (p == NULL)
638 ERR_clear_error();
639 if (p != NULL) {
640 BIO *oid_bio;
641
642 oid_bio = BIO_new_file(p, "r");
643 if (oid_bio == NULL) {
644 /*
645 BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
646 ERR_print_errors(bio_err);
647 */
648 } else {
649 OBJ_create_objects(oid_bio);
650 BIO_free(oid_bio);
651 }
652 }
653 }
654 if (!add_oid_section(bio_err, req_conf))
655 goto end;
656
657 if (md_alg == NULL) {
658 p = NCONF_get_string(req_conf, SECTION, "default_md");
659 if (p == NULL)
660 ERR_clear_error();
661 if (p != NULL) {
662 if ((md_alg = EVP_get_digestbyname(p)) != NULL)
663 req_config.digest = md_alg;
664 }
665 }
666 if (!req_config.extensions) {
667 req_config.extensions = NCONF_get_string(req_conf, SECTION, V3_EXTENSIONS);
668 if (!req_config.extensions)
669 ERR_clear_error();
670 }
671 if (req_config.extensions) {
672 /* Check syntax of file */
673 X509V3_CTX ctx;
674 X509V3_set_ctx_test(&ctx);
675 X509V3_set_nconf(&ctx, req_conf);
676 if (!X509V3_EXT_add_nconf(req_conf, &ctx, req_config.extensions, NULL)) {
677 BIO_printf(bio_err,
678 "Error Loading extension section %s\n", req_config.extensions);
679 goto end;
680 }
681 }
682 if (addext_conf != NULL) {
683 /* Check syntax of command line extensions */
684 X509V3_CTX ctx;
685 X509V3_set_ctx_test(&ctx);
686 X509V3_set_nconf(&ctx, addext_conf);
687 if (!X509V3_EXT_add_nconf(addext_conf, &ctx, "default", NULL)) {
688 BIO_printf(bio_err,
689 "Error Loading command line extensions\n");
690 goto end;
691 }
692 }
693 if (!passin) {
694 passin = NCONF_get_string(req_conf, SECTION, "input_password");
695 if (!passin)
696 ERR_clear_error();
697 }
698 if (!passout) {
699 passout = NCONF_get_string(req_conf, SECTION, "output_password");
700 if (!passout)
701 ERR_clear_error();
702 }
703 p = NCONF_get_string(req_conf, SECTION, STRING_MASK);
704 if (!p)
705 ERR_clear_error();
706
707 if (p && !ASN1_STRING_set_default_mask_asc(p)) {
708 BIO_printf(bio_err, "Invalid global string mask setting %s\n", p);
709 goto end;
710 }
711 if (req_config.chtype != MBSTRING_UTF8) {
712 p = NCONF_get_string(req_conf, SECTION, UTF8_IN);
713 if (!p)
714 ERR_clear_error();
715 else if (!strcmp(p, "yes"))
716 req_config.chtype = MBSTRING_UTF8;
717 }
718 if (!req_config.req_exts) {
719 req_config.req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS);
720 if (!req_config.req_exts)
721 ERR_clear_error();
722 }
723 if (req_config.req_exts) {
724 /* Check syntax of file */
725 X509V3_CTX ctx;
726 X509V3_set_ctx_test(&ctx);
727 X509V3_set_nconf(&ctx, req_conf);
728 if (!X509V3_EXT_add_nconf(req_conf, &ctx, req_config.req_exts, NULL)) {
729 BIO_printf(bio_err,
730 "Error Loading request extension section %s\n",
731 req_config.req_exts);
732 goto end;
733 }
734 }
735 in = BIO_new(BIO_s_file());
736 out = BIO_new(BIO_s_file());
737 if ((in == NULL) || (out == NULL))
738 goto end;
739
740 if (req_config.keyfile != NULL) {
741 pkey = load_key(bio_err, req_config.keyfile, req_config.keyform, 0, passin,
742 "Private Key");
743 if (!pkey) {
744 /*
745 * load_key() has already printed an appropriate
746 * message
747 */
748 goto end;
749 }
750 }
751 if (req_config.newreq && (pkey == NULL)) {
752 if (!NCONF_get_number(req_conf, SECTION, BITS, &req_config.newkey)) {
753 req_config.newkey = DEFAULT_KEY_LENGTH;
754 }
755 if (req_config.keyalg) {
756 genctx = set_keygen_ctx(bio_err, req_config.keyalg, &pkey_type, &req_config.newkey,
757 &keyalgstr);
758 if (!genctx)
759 goto end;
760 }
761 if (req_config.newkey < MIN_KEY_LENGTH && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA)) {
762 BIO_printf(bio_err, "private key length is too short,\n");
763 BIO_printf(bio_err, "it needs to be at least %d bits, not %ld\n", MIN_KEY_LENGTH, req_config.newkey);
764 goto end;
765 }
766 if (!genctx) {
767 genctx = set_keygen_ctx(bio_err, NULL, &pkey_type, &req_config.newkey,
768 &keyalgstr);
769 if (!genctx)
770 goto end;
771 }
772 if (req_config.pkeyopts) {
773 char *genopt;
774 for (i = 0; i < sk_OPENSSL_STRING_num(req_config.pkeyopts); i++) {
775 genopt = sk_OPENSSL_STRING_value(req_config.pkeyopts, i);
776 if (pkey_ctrl_string(genctx, genopt) <= 0) {
777 BIO_printf(bio_err,
778 "parameter error \"%s\"\n",
779 genopt);
780 ERR_print_errors(bio_err);
781 goto end;
782 }
783 }
784 }
785 BIO_printf(bio_err, "Generating a %ld bit %s private key\n",
786 req_config.newkey, keyalgstr);
787
788 EVP_PKEY_CTX_set_cb(genctx, genpkey_cb);
789 EVP_PKEY_CTX_set_app_data(genctx, bio_err);
790
791 if (EVP_PKEY_keygen(genctx, &pkey) <= 0) {
792 BIO_puts(bio_err, "Error Generating Key\n");
793 goto end;
794 }
795 EVP_PKEY_CTX_free(genctx);
796 genctx = NULL;
797
798 if (req_config.keyout == NULL) {
799 req_config.keyout = NCONF_get_string(req_conf, SECTION, KEYFILE);
800 if (req_config.keyout == NULL)
801 ERR_clear_error();
802 }
803 if (req_config.keyout == NULL) {
804 BIO_printf(bio_err, "writing new private key to stdout\n");
805 BIO_set_fp(out, stdout, BIO_NOCLOSE);
806 } else {
807 BIO_printf(bio_err, "writing new private key to '%s'\n", req_config.keyout);
808 if (BIO_write_filename(out, req_config.keyout) <= 0) {
809 perror(req_config.keyout);
810 goto end;
811 }
812 }
813
814 p = NCONF_get_string(req_conf, SECTION, "encrypt_rsa_key");
815 if (p == NULL) {
816 ERR_clear_error();
817 p = NCONF_get_string(req_conf, SECTION, "encrypt_key");
818 if (p == NULL)
819 ERR_clear_error();
820 }
821 if ((p != NULL) && (strcmp(p, "no") == 0))
822 cipher = NULL;
823 if (req_config.nodes)
824 cipher = NULL;
825
826 i = 0;
827 loop:
828 if (!PEM_write_bio_PrivateKey(out, pkey, cipher,
829 NULL, 0, NULL, passout)) {
830 if ((ERR_GET_REASON(ERR_peek_error()) ==
831 PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3)) {
832 ERR_clear_error();
833 i++;
834 goto loop;
835 }
836 goto end;
837 }
838 BIO_printf(bio_err, "-----\n");
839 }
840 if (!req_config.newreq) {
841 if (req_config.infile == NULL)
842 BIO_set_fp(in, stdin, BIO_NOCLOSE);
843 else {
844 if (BIO_read_filename(in, req_config.infile) <= 0) {
845 perror(req_config.infile);
846 goto end;
847 }
848 }
849
850 if (req_config.informat == FORMAT_ASN1)
851 req = d2i_X509_REQ_bio(in, NULL);
852 else if (req_config.informat == FORMAT_PEM)
853 req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
854 else {
855 BIO_printf(bio_err, "bad input format specified for X509 request\n");
856 goto end;
857 }
858 if (req == NULL) {
859 BIO_printf(bio_err, "unable to load X509 request\n");
860 goto end;
861 }
862 }
863 if (req_config.newreq || req_config.x509) {
864 if (pkey == NULL) {
865 BIO_printf(bio_err, "you need to specify a private key\n");
866 goto end;
867 }
868 if (req == NULL) {
869 req = X509_REQ_new();
870 if (req == NULL) {
871 goto end;
872 }
873 i = make_REQ(req, pkey, req_config.subj, req_config.multirdn, !req_config.x509, req_config.chtype);
874 req_config.subj = NULL; /* done processing '-subj' option */
875 if (!i) {
876 BIO_printf(bio_err, "problems making Certificate Request\n");
877 goto end;
878 }
879 }
880 if (req_config.x509) {
881 EVP_PKEY *tmppkey;
882
883 X509V3_CTX ext_ctx;
884 if ((x509ss = X509_new()) == NULL)
885 goto end;
886
887 /* Set version to V3 */
888 if ((req_config.extensions != NULL || addext_conf != NULL) &&
889 !X509_set_version(x509ss, 2))
890 goto end;
891 if (req_config.serial) {
892 if (!X509_set_serialNumber(x509ss, req_config.serial))
893 goto end;
894 } else {
895 if (!rand_serial(NULL,
896 X509_get_serialNumber(x509ss)))
897 goto end;
898 }
899
900 if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req)))
901 goto end;
902 if (!X509_gmtime_adj(X509_get_notBefore(x509ss), 0))
903 goto end;
904 if (!X509_time_adj_ex(X509_get_notAfter(x509ss), req_config.days, 0, NULL))
905 goto end;
906 if (!X509_set_subject_name(x509ss, X509_REQ_get_subject_name(req)))
907 goto end;
908 if ((tmppkey = X509_REQ_get0_pubkey(req)) == NULL)
909 goto end;
910 if (!X509_set_pubkey(x509ss, tmppkey))
911 goto end;
912
913 /* Set up V3 context struct */
914
915 X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0);
916 X509V3_set_nconf(&ext_ctx, req_conf);
917
918 /* Add extensions */
919 if (req_config.extensions && !X509V3_EXT_add_nconf(req_conf,
920 &ext_ctx, req_config.extensions, x509ss)) {
921 BIO_printf(bio_err,
922 "Error Loading extension section %s\n",
923 req_config.extensions);
924 goto end;
925 }
926 if (addext_conf != NULL &&
927 !X509V3_EXT_add_nconf(addext_conf, &ext_ctx,
928 "default", x509ss)) {
929 BIO_printf(bio_err,
930 "Error Loading command line extensions\n");
931 goto end;
932 }
933 i = do_X509_sign(bio_err, x509ss, pkey, req_config.digest, req_config.sigopts);
934 if (!i) {
935 ERR_print_errors(bio_err);
936 goto end;
937 }
938 } else {
939 X509V3_CTX ext_ctx;
940
941 /* Set up V3 context struct */
942
943 X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0);
944 X509V3_set_nconf(&ext_ctx, req_conf);
945
946 /* Add extensions */
947 if (req_config.req_exts && !X509V3_EXT_REQ_add_nconf(req_conf,
948 &ext_ctx, req_config.req_exts, req)) {
949 BIO_printf(bio_err,
950 "Error Loading extension section %s\n",
951 req_config.req_exts);
952 goto end;
953 }
954 if (addext_conf != NULL &&
955 !X509V3_EXT_REQ_add_nconf(addext_conf, &ext_ctx,
956 "default", req)) {
957 BIO_printf(bio_err,
958 "Error Loading command line extensions\n");
959 goto end;
960 }
961 i = do_X509_REQ_sign(bio_err, req, pkey, req_config.digest, req_config.sigopts);
962 if (!i) {
963 ERR_print_errors(bio_err);
964 goto end;
965 }
966 }
967 }
968 if (req_config.subj && req_config.x509) {
969 BIO_printf(bio_err, "Cannot modify certificate subject\n");
970 goto end;
971 }
972 if (req_config.subj && !req_config.x509) {
973 if (req_config.verbose) {
974 BIO_printf(bio_err, "Modifying Request's Subject\n");
975 print_name(bio_err, "old subject=", X509_REQ_get_subject_name(req), req_config.nmflag);
976 }
977 if (build_subject(req, req_config.subj, req_config.chtype, req_config.multirdn) == 0) {
978 BIO_printf(bio_err, "ERROR: cannot modify subject\n");
979 ex = 1;
980 goto end;
981 }
982
983 if (req_config.verbose) {
984 print_name(bio_err, "new subject=", X509_REQ_get_subject_name(req), req_config.nmflag);
985 }
986 }
987 if (req_config.verify && !req_config.x509) {
988 EVP_PKEY *pubkey = pkey;
989
990 if (pubkey == NULL)
991 pubkey = X509_REQ_get0_pubkey(req);
992 if (pubkey == NULL)
993 goto end;
994 i = X509_REQ_verify(req, pubkey);
995 if (i < 0) {
996 goto end;
997 } else if (i == 0) {
998 BIO_printf(bio_err, "verify failure\n");
999 ERR_print_errors(bio_err);
1000 } else /* if (i > 0) */
1001 BIO_printf(bio_err, "verify OK\n");
1002 }
1003 if (req_config.noout && !req_config.text && !req_config.modulus && !req_config.subject && !req_config.pubkey) {
1004 ex = 0;
1005 goto end;
1006 }
1007 if (req_config.outfile == NULL) {
1008 BIO_set_fp(out, stdout, BIO_NOCLOSE);
1009 } else {
1010 if ((req_config.keyout != NULL) && (strcmp(req_config.outfile, req_config.keyout) == 0))
1011 i = (int) BIO_append_filename(out, req_config.outfile);
1012 else
1013 i = (int) BIO_write_filename(out, req_config.outfile);
1014 if (!i) {
1015 perror(req_config.outfile);
1016 goto end;
1017 }
1018 }
1019
1020 if (req_config.pubkey) {
1021 EVP_PKEY *tpubkey;
1022
1023 if ((tpubkey = X509_REQ_get0_pubkey(req)) == NULL) {
1024 BIO_printf(bio_err, "Error getting public key\n");
1025 ERR_print_errors(bio_err);
1026 goto end;
1027 }
1028 PEM_write_bio_PUBKEY(out, tpubkey);
1029 }
1030 if (req_config.text) {
1031 if (req_config.x509)
1032 X509_print_ex(out, x509ss, req_config.nmflag, req_config.reqflag);
1033 else
1034 X509_REQ_print_ex(out, req, req_config.nmflag, req_config.reqflag);
1035 }
1036 if (req_config.subject) {
1037 if (req_config.x509)
1038 print_name(out, "subject=", X509_get_subject_name(x509ss), req_config.nmflag);
1039 else
1040 print_name(out, "subject=", X509_REQ_get_subject_name(req), req_config.nmflag);
1041 }
1042 if (req_config.modulus) {
1043 EVP_PKEY *tpubkey;
1044
1045 if (req_config.x509)
1046 tpubkey = X509_get0_pubkey(x509ss);
1047 else
1048 tpubkey = X509_REQ_get0_pubkey(req);
1049 if (tpubkey == NULL) {
1050 fprintf(stdout, "Modulus=unavailable\n");
1051 goto end;
1052 }
1053 fprintf(stdout, "Modulus=");
1054 if (EVP_PKEY_base_id(tpubkey) == EVP_PKEY_RSA) {
1055 const BIGNUM *n = NULL;
1056
1057 RSA_get0_key(EVP_PKEY_get0_RSA(tpubkey), &n, NULL, NULL);
1058
1059 BN_print(out, n);
1060 } else
1061 fprintf(stdout, "Wrong Algorithm type");
1062 fprintf(stdout, "\n");
1063 }
1064 if (!req_config.noout && !req_config.x509) {
1065 if (req_config.outformat == FORMAT_ASN1)
1066 i = i2d_X509_REQ_bio(out, req);
1067 else if (req_config.outformat == FORMAT_PEM) {
1068 if (req_config.newhdr)
1069 i = PEM_write_bio_X509_REQ_NEW(out, req);
1070 else
1071 i = PEM_write_bio_X509_REQ(out, req);
1072 } else {
1073 BIO_printf(bio_err, "bad output format specified for outfile\n");
1074 goto end;
1075 }
1076 if (!i) {
1077 BIO_printf(bio_err, "unable to write X509 request\n");
1078 goto end;
1079 }
1080 }
1081 if (!req_config.noout && req_config.x509 && (x509ss != NULL)) {
1082 if (req_config.outformat == FORMAT_ASN1)
1083 i = i2d_X509_bio(out, x509ss);
1084 else if (req_config.outformat == FORMAT_PEM)
1085 i = PEM_write_bio_X509(out, x509ss);
1086 else {
1087 BIO_printf(bio_err, "bad output format specified for outfile\n");
1088 goto end;
1089 }
1090 if (!i) {
1091 BIO_printf(bio_err, "unable to write X509 certificate\n");
1092 goto end;
1093 }
1094 }
1095 ex = 0;
1096 end:
1097 if (ex) {
1098 ERR_print_errors(bio_err);
1099 }
1100 if ((req_conf != NULL) && (req_conf != config))
1101 NCONF_free(req_conf);
1102 NCONF_free(addext_conf);
1103 BIO_free(req_config.addext_bio);
1104 BIO_free(in);
1105 BIO_free_all(out);
1106 EVP_PKEY_free(pkey);
1107 if (genctx)
1108 EVP_PKEY_CTX_free(genctx);
1109 if (req_config.pkeyopts)
1110 sk_OPENSSL_STRING_free(req_config.pkeyopts);
1111 if (req_config.sigopts)
1112 sk_OPENSSL_STRING_free(req_config.sigopts);
1113 lh_OPENSSL_STRING_doall(req_config.addexts, (LHASH_DOALL_FN_TYPE)exts_cleanup);
1114 lh_OPENSSL_STRING_free(req_config.addexts);
1115 free(keyalgstr);
1116 X509_REQ_free(req);
1117 X509_free(x509ss);
1118 ASN1_INTEGER_free(req_config.serial);
1119 if (req_config.passargin && passin)
1120 free(passin);
1121 if (req_config.passargout && passout)
1122 free(passout);
1123 OBJ_cleanup();
1124
1125 return (ex);
1126 }
1127
1128 static int
make_REQ(X509_REQ * req,EVP_PKEY * pkey,char * subj,int multirdn,int attribs,unsigned long chtype)1129 make_REQ(X509_REQ * req, EVP_PKEY * pkey, char *subj, int multirdn,
1130 int attribs, unsigned long chtype)
1131 {
1132 int ret = 0, i;
1133 char no_prompt = 0;
1134 STACK_OF(CONF_VALUE) * dn_sk, *attr_sk = NULL;
1135 char *tmp, *dn_sect, *attr_sect;
1136
1137 tmp = NCONF_get_string(req_conf, SECTION, PROMPT);
1138 if (tmp == NULL)
1139 ERR_clear_error();
1140 if ((tmp != NULL) && !strcmp(tmp, "no"))
1141 no_prompt = 1;
1142
1143 dn_sect = NCONF_get_string(req_conf, SECTION, DISTINGUISHED_NAME);
1144 if (dn_sect == NULL) {
1145 BIO_printf(bio_err, "unable to find '%s' in config\n",
1146 DISTINGUISHED_NAME);
1147 goto err;
1148 }
1149 dn_sk = NCONF_get_section(req_conf, dn_sect);
1150 if (dn_sk == NULL) {
1151 BIO_printf(bio_err, "unable to get '%s' section\n", dn_sect);
1152 goto err;
1153 }
1154 attr_sect = NCONF_get_string(req_conf, SECTION, ATTRIBUTES);
1155 if (attr_sect == NULL) {
1156 ERR_clear_error();
1157 attr_sk = NULL;
1158 } else {
1159 attr_sk = NCONF_get_section(req_conf, attr_sect);
1160 if (attr_sk == NULL) {
1161 BIO_printf(bio_err, "unable to get '%s' section\n", attr_sect);
1162 goto err;
1163 }
1164 }
1165
1166 /* setup version number */
1167 if (!X509_REQ_set_version(req, 0L))
1168 goto err; /* version 1 */
1169
1170 if (no_prompt)
1171 i = auto_info(req, dn_sk, attr_sk, attribs, chtype);
1172 else {
1173 if (subj)
1174 i = build_subject(req, subj, chtype, multirdn);
1175 else
1176 i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs, chtype);
1177 }
1178 if (!i)
1179 goto err;
1180
1181 if (!X509_REQ_set_pubkey(req, pkey))
1182 goto err;
1183
1184 ret = 1;
1185 err:
1186 return (ret);
1187 }
1188
1189 /*
1190 * subject is expected to be in the format /type0=value0/type1=value1/type2=...
1191 * where characters may be escaped by \
1192 */
1193 static int
build_subject(X509_REQ * req,char * subject,unsigned long chtype,int multirdn)1194 build_subject(X509_REQ * req, char *subject, unsigned long chtype, int multirdn)
1195 {
1196 X509_NAME *n;
1197
1198 if (!(n = parse_name(subject, chtype, multirdn)))
1199 return 0;
1200
1201 if (!X509_REQ_set_subject_name(req, n)) {
1202 X509_NAME_free(n);
1203 return 0;
1204 }
1205 X509_NAME_free(n);
1206 return 1;
1207 }
1208
1209
1210 static int
prompt_info(X509_REQ * req,STACK_OF (CONF_VALUE)* dn_sk,char * dn_sect,STACK_OF (CONF_VALUE)* attr_sk,char * attr_sect,int attribs,unsigned long chtype)1211 prompt_info(X509_REQ * req,
1212 STACK_OF(CONF_VALUE) * dn_sk, char *dn_sect,
1213 STACK_OF(CONF_VALUE) * attr_sk, char *attr_sect, int attribs,
1214 unsigned long chtype)
1215 {
1216 int i;
1217 char *p, *q;
1218 char buf[100];
1219 int nid, mval;
1220 long n_min, n_max;
1221 char *type, *value;
1222 const char *def;
1223 CONF_VALUE *v;
1224 X509_NAME *subj;
1225 subj = X509_REQ_get_subject_name(req);
1226
1227 if (!req_config.batch) {
1228 BIO_printf(bio_err, "You are about to be asked to enter information that will be incorporated\n");
1229 BIO_printf(bio_err, "into your certificate request.\n");
1230 BIO_printf(bio_err, "What you are about to enter is what is called a Distinguished Name or a DN.\n");
1231 BIO_printf(bio_err, "There are quite a few fields but you can leave some blank\n");
1232 BIO_printf(bio_err, "For some fields there will be a default value,\n");
1233 BIO_printf(bio_err, "If you enter '.', the field will be left blank.\n");
1234 BIO_printf(bio_err, "-----\n");
1235 }
1236 if (sk_CONF_VALUE_num(dn_sk)) {
1237 i = -1;
1238 start: for (;;) {
1239 int ret;
1240 i++;
1241 if (sk_CONF_VALUE_num(dn_sk) <= i)
1242 break;
1243
1244 v = sk_CONF_VALUE_value(dn_sk, i);
1245 p = q = NULL;
1246 type = v->name;
1247 if (!check_end(type, "_min") || !check_end(type, "_max") ||
1248 !check_end(type, "_default") ||
1249 !check_end(type, "_value"))
1250 continue;
1251 /*
1252 * Skip past any leading X. X: X, etc to allow for
1253 * multiple instances
1254 */
1255 for (p = v->name; *p; p++)
1256 if ((*p == ':') || (*p == ',') ||
1257 (*p == '.')) {
1258 p++;
1259 if (*p)
1260 type = p;
1261 break;
1262 }
1263 if (*type == '+') {
1264 mval = -1;
1265 type++;
1266 } else
1267 mval = 0;
1268 /* If OBJ not recognised ignore it */
1269 if ((nid = OBJ_txt2nid(type)) == NID_undef)
1270 goto start;
1271 ret = snprintf(buf, sizeof buf, "%s_default", v->name);
1272 if (ret < 0 || ret >= sizeof(buf)) {
1273 BIO_printf(bio_err, "Name '%s' too long for default\n",
1274 v->name);
1275 return 0;
1276 }
1277 if ((def = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
1278 ERR_clear_error();
1279 def = "";
1280 }
1281 ret = snprintf(buf, sizeof buf, "%s_value", v->name);
1282 if (ret < 0 || ret >= sizeof(buf)) {
1283 BIO_printf(bio_err, "Name '%s' too long for value\n",
1284 v->name);
1285 return 0;
1286 }
1287 if ((value = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
1288 ERR_clear_error();
1289 value = NULL;
1290 }
1291 ret = snprintf(buf, sizeof buf, "%s_min", v->name);
1292 if (ret < 0 || ret >= sizeof(buf)) {
1293 BIO_printf(bio_err, "Name '%s' too long for min\n",
1294 v->name);
1295 return 0;
1296 }
1297 if (!NCONF_get_number(req_conf, dn_sect, buf, &n_min)) {
1298 ERR_clear_error();
1299 n_min = -1;
1300 }
1301 ret = snprintf(buf, sizeof buf, "%s_max", v->name);
1302 if (ret < 0 || ret >= sizeof(buf)) {
1303 BIO_printf(bio_err, "Name '%s' too long for max\n",
1304 v->name);
1305 return 0;
1306 }
1307 if (!NCONF_get_number(req_conf, dn_sect, buf, &n_max)) {
1308 ERR_clear_error();
1309 n_max = -1;
1310 }
1311 if (!add_DN_object(subj, v->value, def, value, nid,
1312 n_min, n_max, chtype, mval))
1313 return 0;
1314 }
1315 if (X509_NAME_entry_count(subj) == 0) {
1316 BIO_printf(bio_err, "error, no objects specified in config file\n");
1317 return 0;
1318 }
1319 if (attribs) {
1320 if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0) &&
1321 (!req_config.batch)) {
1322 BIO_printf(bio_err,
1323 "\nPlease enter the following 'extra' attributes\n");
1324 BIO_printf(bio_err,
1325 "to be sent with your certificate request\n");
1326 }
1327 i = -1;
1328 start2: for (;;) {
1329 int ret;
1330 i++;
1331 if ((attr_sk == NULL) ||
1332 (sk_CONF_VALUE_num(attr_sk) <= i))
1333 break;
1334
1335 v = sk_CONF_VALUE_value(attr_sk, i);
1336 type = v->name;
1337 if ((nid = OBJ_txt2nid(type)) == NID_undef)
1338 goto start2;
1339 ret = snprintf(buf, sizeof buf, "%s_default", type);
1340 if (ret < 0 || ret >= sizeof(buf)) {
1341 BIO_printf(bio_err, "Name '%s' too long for default\n",
1342 v->name);
1343 return 0;
1344 }
1345 if ((def = NCONF_get_string(req_conf, attr_sect, buf))
1346 == NULL) {
1347 ERR_clear_error();
1348 def = "";
1349 }
1350 ret = snprintf(buf, sizeof buf, "%s_value", type);
1351 if (ret < 0 || ret >= sizeof(buf)) {
1352 BIO_printf(bio_err, "Name '%s' too long for value\n",
1353 v->name);
1354 return 0;
1355 }
1356 if ((value = NCONF_get_string(req_conf, attr_sect, buf))
1357 == NULL) {
1358 ERR_clear_error();
1359 value = NULL;
1360 }
1361 ret = snprintf(buf, sizeof buf, "%s_min", type);
1362 if (ret < 0 || ret >= sizeof(buf)) {
1363 BIO_printf(bio_err, "Name '%s' too long for min\n",
1364 v->name);
1365 return 0;
1366 }
1367 if (!NCONF_get_number(req_conf, attr_sect, buf, &n_min)) {
1368 ERR_clear_error();
1369 n_min = -1;
1370 }
1371 ret = snprintf(buf, sizeof buf, "%s_max", type);
1372 if (ret < 0 || ret >= sizeof(buf)) {
1373 BIO_printf(bio_err, "Name '%s' too long for max\n",
1374 v->name);
1375 return 0;
1376 }
1377 if (!NCONF_get_number(req_conf, attr_sect, buf, &n_max)) {
1378 ERR_clear_error();
1379 n_max = -1;
1380 }
1381 if (!add_attribute_object(req,
1382 v->value, def, value, nid, n_min, n_max, chtype))
1383 return 0;
1384 }
1385 }
1386 } else {
1387 BIO_printf(bio_err, "No template, please set one up.\n");
1388 return 0;
1389 }
1390
1391 return 1;
1392
1393 }
1394
1395 static int
auto_info(X509_REQ * req,STACK_OF (CONF_VALUE)* dn_sk,STACK_OF (CONF_VALUE)* attr_sk,int attribs,unsigned long chtype)1396 auto_info(X509_REQ * req, STACK_OF(CONF_VALUE) * dn_sk,
1397 STACK_OF(CONF_VALUE) * attr_sk, int attribs, unsigned long chtype)
1398 {
1399 int i;
1400 char *p, *q;
1401 char *type;
1402 CONF_VALUE *v;
1403 X509_NAME *subj;
1404
1405 subj = X509_REQ_get_subject_name(req);
1406
1407 for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
1408 int mval;
1409 v = sk_CONF_VALUE_value(dn_sk, i);
1410 p = q = NULL;
1411 type = v->name;
1412 /*
1413 * Skip past any leading X. X: X, etc to allow for multiple
1414 * instances
1415 */
1416 for (p = v->name; *p; p++)
1417 if ((*p == ':') || (*p == ',') || (*p == '.')) {
1418 p++;
1419 if (*p)
1420 type = p;
1421 break;
1422 }
1423 if (*p == '+') {
1424 p++;
1425 mval = -1;
1426 } else
1427 mval = 0;
1428 if (!X509_NAME_add_entry_by_txt(subj, type, chtype,
1429 (unsigned char *) v->value, -1, -1, mval))
1430 return 0;
1431
1432 }
1433
1434 if (!X509_NAME_entry_count(subj)) {
1435 BIO_printf(bio_err, "error, no objects specified in config file\n");
1436 return 0;
1437 }
1438 if (attribs) {
1439 for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) {
1440 v = sk_CONF_VALUE_value(attr_sk, i);
1441 if (!X509_REQ_add1_attr_by_txt(req, v->name, chtype,
1442 (unsigned char *) v->value, -1))
1443 return 0;
1444 }
1445 }
1446 return 1;
1447 }
1448
1449
1450 static int
add_DN_object(X509_NAME * n,char * text,const char * def,char * value,int nid,int n_min,int n_max,unsigned long chtype,int mval)1451 add_DN_object(X509_NAME * n, char *text, const char *def, char *value,
1452 int nid, int n_min, int n_max, unsigned long chtype, int mval)
1453 {
1454 int i, ret = 0;
1455 char buf[1024];
1456 start:
1457 if (!req_config.batch)
1458 BIO_printf(bio_err, "%s [%s]:", text, def);
1459 (void) BIO_flush(bio_err);
1460 if (value != NULL) {
1461 strlcpy(buf, value, sizeof buf);
1462 strlcat(buf, "\n", sizeof buf);
1463 BIO_printf(bio_err, "%s\n", value);
1464 } else {
1465 buf[0] = '\0';
1466 if (!req_config.batch) {
1467 if (!fgets(buf, sizeof buf, stdin))
1468 return 0;
1469 } else {
1470 buf[0] = '\n';
1471 buf[1] = '\0';
1472 }
1473 }
1474
1475 if (buf[0] == '\0')
1476 return (0);
1477 else if (buf[0] == '\n') {
1478 if ((def == NULL) || (def[0] == '\0'))
1479 return (1);
1480 strlcpy(buf, def, sizeof buf);
1481 strlcat(buf, "\n", sizeof buf);
1482 } else if ((buf[0] == '.') && (buf[1] == '\n'))
1483 return (1);
1484
1485 i = strlen(buf);
1486 if (buf[i - 1] != '\n') {
1487 BIO_printf(bio_err, "weird input :-(\n");
1488 return (0);
1489 }
1490 buf[--i] = '\0';
1491 if (!req_check_len(i, n_min, n_max))
1492 goto start;
1493 if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
1494 (unsigned char *) buf, -1, -1, mval))
1495 goto err;
1496 ret = 1;
1497 err:
1498 return (ret);
1499 }
1500
1501 static int
add_attribute_object(X509_REQ * req,char * text,const char * def,char * value,int nid,int n_min,int n_max,unsigned long chtype)1502 add_attribute_object(X509_REQ * req, char *text, const char *def,
1503 char *value, int nid, int n_min,
1504 int n_max, unsigned long chtype)
1505 {
1506 int i;
1507 static char buf[1024];
1508
1509 start:
1510 if (!req_config.batch)
1511 BIO_printf(bio_err, "%s [%s]:", text, def);
1512 (void) BIO_flush(bio_err);
1513 if (value != NULL) {
1514 strlcpy(buf, value, sizeof buf);
1515 strlcat(buf, "\n", sizeof buf);
1516 BIO_printf(bio_err, "%s\n", value);
1517 } else {
1518 buf[0] = '\0';
1519 if (!req_config.batch) {
1520 if (!fgets(buf, sizeof buf, stdin))
1521 return 0;
1522 } else {
1523 buf[0] = '\n';
1524 buf[1] = '\0';
1525 }
1526 }
1527
1528 if (buf[0] == '\0')
1529 return (0);
1530 else if (buf[0] == '\n') {
1531 if ((def == NULL) || (def[0] == '\0'))
1532 return (1);
1533 strlcpy(buf, def, sizeof buf);
1534 strlcat(buf, "\n", sizeof buf);
1535 } else if ((buf[0] == '.') && (buf[1] == '\n'))
1536 return (1);
1537
1538 i = strlen(buf);
1539 if (buf[i - 1] != '\n') {
1540 BIO_printf(bio_err, "weird input :-(\n");
1541 return (0);
1542 }
1543 buf[--i] = '\0';
1544 if (!req_check_len(i, n_min, n_max))
1545 goto start;
1546
1547 if (!X509_REQ_add1_attr_by_NID(req, nid, chtype,
1548 (unsigned char *) buf, -1)) {
1549 BIO_printf(bio_err, "Error adding attribute\n");
1550 ERR_print_errors(bio_err);
1551 goto err;
1552 }
1553 return (1);
1554 err:
1555 return (0);
1556 }
1557
1558 static int
req_check_len(int len,int n_min,int n_max)1559 req_check_len(int len, int n_min, int n_max)
1560 {
1561 if ((n_min > 0) && (len < n_min)) {
1562 BIO_printf(bio_err, "string is too short, it needs to be at least %d bytes long\n", n_min);
1563 return (0);
1564 }
1565 if ((n_max >= 0) && (len > n_max)) {
1566 BIO_printf(bio_err, "string is too long, it needs to be less than %d bytes long\n", n_max);
1567 return (0);
1568 }
1569 return (1);
1570 }
1571
1572 /* Check if the end of a string matches 'end' */
1573 static int
check_end(const char * str,const char * end)1574 check_end(const char *str, const char *end)
1575 {
1576 int elen, slen;
1577 const char *tmp;
1578 elen = strlen(end);
1579 slen = strlen(str);
1580 if (elen > slen)
1581 return 1;
1582 tmp = str + slen - elen;
1583 return strcmp(tmp, end);
1584 }
1585
1586 static EVP_PKEY_CTX *
set_keygen_ctx(BIO * err,const char * gstr,int * pkey_type,long * pkeylen,char ** palgnam)1587 set_keygen_ctx(BIO * err, const char *gstr, int *pkey_type,
1588 long *pkeylen, char **palgnam)
1589 {
1590 EVP_PKEY_CTX *gctx = NULL;
1591 EVP_PKEY *param = NULL;
1592 long keylen = -1;
1593 BIO *pbio = NULL;
1594 const char *paramfile = NULL;
1595 const char *errstr;
1596
1597 if (gstr == NULL) {
1598 *pkey_type = EVP_PKEY_RSA;
1599 keylen = *pkeylen;
1600 } else if (gstr[0] >= '0' && gstr[0] <= '9') {
1601 *pkey_type = EVP_PKEY_RSA;
1602 keylen = strtonum(gstr, 0, LONG_MAX, &errstr);
1603 if (errstr) {
1604 BIO_printf(err, "bad algorithm %s: %s\n", gstr, errstr);
1605 return NULL;
1606 }
1607 *pkeylen = keylen;
1608 } else if (!strncmp(gstr, "param:", 6))
1609 paramfile = gstr + 6;
1610 else {
1611 const char *p = strchr(gstr, ':');
1612 int len;
1613 const EVP_PKEY_ASN1_METHOD *ameth;
1614
1615 if (p)
1616 len = p - gstr;
1617 else
1618 len = strlen(gstr);
1619
1620 ameth = EVP_PKEY_asn1_find_str(NULL, gstr, len);
1621
1622 if (!ameth) {
1623 BIO_printf(err, "Unknown algorithm %.*s\n", len, gstr);
1624 return NULL;
1625 }
1626 EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL,
1627 ameth);
1628 if (*pkey_type == EVP_PKEY_RSA) {
1629 if (p) {
1630 keylen = strtonum(p + 1, 0, LONG_MAX, &errstr);
1631 if (errstr) {
1632 BIO_printf(err, "bad algorithm %s: %s\n",
1633 p + 1, errstr);
1634 return NULL;
1635 }
1636 *pkeylen = keylen;
1637 } else
1638 keylen = *pkeylen;
1639 } else if (p)
1640 paramfile = p + 1;
1641 }
1642
1643 if (paramfile) {
1644 pbio = BIO_new_file(paramfile, "r");
1645 if (!pbio) {
1646 BIO_printf(err, "Can't open parameter file %s\n",
1647 paramfile);
1648 return NULL;
1649 }
1650 param = PEM_read_bio_Parameters(pbio, NULL);
1651
1652 if (!param) {
1653 X509 *x;
1654 (void) BIO_reset(pbio);
1655 x = PEM_read_bio_X509(pbio, NULL, NULL, NULL);
1656 if (x) {
1657 param = X509_get_pubkey(x);
1658 X509_free(x);
1659 }
1660 }
1661 BIO_free(pbio);
1662
1663 if (!param) {
1664 BIO_printf(err, "Error reading parameter file %s\n",
1665 paramfile);
1666 return NULL;
1667 }
1668 if (*pkey_type == -1)
1669 *pkey_type = EVP_PKEY_id(param);
1670 else if (*pkey_type != EVP_PKEY_base_id(param)) {
1671 BIO_printf(err, "Key Type does not match parameters\n");
1672 EVP_PKEY_free(param);
1673 return NULL;
1674 }
1675 }
1676 if (palgnam) {
1677 const EVP_PKEY_ASN1_METHOD *ameth;
1678 const char *anam;
1679 ameth = EVP_PKEY_asn1_find(NULL, *pkey_type);
1680 if (!ameth) {
1681 BIO_puts(err, "Internal error: can't find key algorithm\n");
1682 return NULL;
1683 }
1684 EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth);
1685 *palgnam = strdup(anam);
1686 }
1687 if (param) {
1688 gctx = EVP_PKEY_CTX_new(param, NULL);
1689 *pkeylen = EVP_PKEY_bits(param);
1690 EVP_PKEY_free(param);
1691 } else
1692 gctx = EVP_PKEY_CTX_new_id(*pkey_type, NULL);
1693
1694 if (!gctx) {
1695 BIO_puts(err, "Error allocating keygen context\n");
1696 ERR_print_errors(err);
1697 return NULL;
1698 }
1699 if (EVP_PKEY_keygen_init(gctx) <= 0) {
1700 BIO_puts(err, "Error initializing keygen context\n");
1701 ERR_print_errors(err);
1702 return NULL;
1703 }
1704 if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) {
1705 if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0) {
1706 BIO_puts(err, "Error setting RSA keysize\n");
1707 ERR_print_errors(err);
1708 EVP_PKEY_CTX_free(gctx);
1709 return NULL;
1710 }
1711 }
1712
1713 return gctx;
1714 }
1715
1716 static int
genpkey_cb(EVP_PKEY_CTX * ctx)1717 genpkey_cb(EVP_PKEY_CTX * ctx)
1718 {
1719 char c = '*';
1720 BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
1721 int p;
1722 p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
1723 if (p == 0)
1724 c = '.';
1725 if (p == 1)
1726 c = '+';
1727 if (p == 2)
1728 c = '*';
1729 if (p == 3)
1730 c = '\n';
1731 BIO_write(b, &c, 1);
1732 (void) BIO_flush(b);
1733 return 1;
1734 }
1735
1736 static int
do_sign_init(BIO * err,EVP_MD_CTX * ctx,EVP_PKEY * pkey,const EVP_MD * md,STACK_OF (OPENSSL_STRING)* sigopts)1737 do_sign_init(BIO * err, EVP_MD_CTX * ctx, EVP_PKEY * pkey,
1738 const EVP_MD * md, STACK_OF(OPENSSL_STRING) * sigopts)
1739 {
1740 EVP_PKEY_CTX *pkctx = NULL;
1741 int i;
1742 EVP_MD_CTX_init(ctx);
1743 if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey))
1744 return 0;
1745 for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
1746 char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
1747 if (pkey_ctrl_string(pkctx, sigopt) <= 0) {
1748 BIO_printf(err, "parameter error \"%s\"\n", sigopt);
1749 ERR_print_errors(bio_err);
1750 return 0;
1751 }
1752 }
1753 return 1;
1754 }
1755
1756 int
do_X509_sign(BIO * err,X509 * x,EVP_PKEY * pkey,const EVP_MD * md,STACK_OF (OPENSSL_STRING)* sigopts)1757 do_X509_sign(BIO * err, X509 * x, EVP_PKEY * pkey, const EVP_MD * md,
1758 STACK_OF(OPENSSL_STRING) * sigopts)
1759 {
1760 EVP_MD_CTX *mctx;
1761 int rv;
1762
1763 if ((mctx = EVP_MD_CTX_new()) == NULL)
1764 return 0;
1765
1766 rv = do_sign_init(err, mctx, pkey, md, sigopts);
1767 if (rv > 0)
1768 rv = X509_sign_ctx(x, mctx);
1769
1770 EVP_MD_CTX_free(mctx);
1771
1772 return rv > 0;
1773 }
1774
1775
1776 int
do_X509_REQ_sign(BIO * err,X509_REQ * x,EVP_PKEY * pkey,const EVP_MD * md,STACK_OF (OPENSSL_STRING)* sigopts)1777 do_X509_REQ_sign(BIO * err, X509_REQ * x, EVP_PKEY * pkey, const EVP_MD * md,
1778 STACK_OF(OPENSSL_STRING) * sigopts)
1779 {
1780 EVP_MD_CTX *mctx;
1781 int rv;
1782
1783 if ((mctx = EVP_MD_CTX_new()) == NULL)
1784 return 0;
1785
1786 rv = do_sign_init(err, mctx, pkey, md, sigopts);
1787 if (rv > 0)
1788 rv = X509_REQ_sign_ctx(x, mctx);
1789
1790 EVP_MD_CTX_free(mctx);
1791
1792 return rv > 0;
1793 }
1794
1795
1796
1797 int
do_X509_CRL_sign(BIO * err,X509_CRL * x,EVP_PKEY * pkey,const EVP_MD * md,STACK_OF (OPENSSL_STRING)* sigopts)1798 do_X509_CRL_sign(BIO * err, X509_CRL * x, EVP_PKEY * pkey, const EVP_MD * md,
1799 STACK_OF(OPENSSL_STRING) * sigopts)
1800 {
1801 int rv;
1802 EVP_MD_CTX *mctx;
1803
1804 if ((mctx = EVP_MD_CTX_new()) == NULL)
1805 return 0;
1806
1807 rv = do_sign_init(err, mctx, pkey, md, sigopts);
1808 if (rv > 0)
1809 rv = X509_CRL_sign_ctx(x, mctx);
1810
1811 EVP_MD_CTX_free(mctx);
1812
1813 return rv > 0;
1814 }
1815
1816 static unsigned long
ext_name_hash(const OPENSSL_STRING * a)1817 ext_name_hash(const OPENSSL_STRING *a)
1818 {
1819 return lh_strhash((const char *)a);
1820 }
1821
1822 static int
ext_name_cmp(const OPENSSL_STRING * a,const OPENSSL_STRING * b)1823 ext_name_cmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b)
1824 {
1825 return strcmp((const char *)a, (const char *)b);
1826 }
1827
1828 static void
exts_cleanup(OPENSSL_STRING * x)1829 exts_cleanup(OPENSSL_STRING *x)
1830 {
1831 free((char *)x);
1832 }
1833
1834 /*
1835 * Is the |kv| key already duplicated ? This is remarkably tricky to get right.
1836 * Return 0 if unique, -1 on runtime error; 1 if found or a syntax error.
1837 */
1838 static int
duplicated(LHASH_OF (OPENSSL_STRING)* addexts,char * kv)1839 duplicated(LHASH_OF(OPENSSL_STRING) *addexts, char *kv)
1840 {
1841 char *p;
1842 size_t off;
1843
1844 /* Check syntax. */
1845 /* Skip leading whitespace, make a copy. */
1846 while (*kv && isspace(*kv))
1847 if (*++kv == '\0')
1848 return 1;
1849 if ((p = strchr(kv, '=')) == NULL)
1850 return 1;
1851 off = p - kv;
1852 if ((kv = strdup(kv)) == NULL)
1853 return -1;
1854
1855 /* Skip trailing space before the equal sign. */
1856 for (p = kv + off; p > kv; --p)
1857 if (!isspace(p[-1]))
1858 break;
1859 if (p == kv) {
1860 free(kv);
1861 return 1;
1862 }
1863 *p = '\0';
1864
1865 /* See if "key" is there by attempting to add it. */
1866 if ((p = (char *)lh_OPENSSL_STRING_insert(addexts, (OPENSSL_STRING*)kv))
1867 != NULL || lh_OPENSSL_STRING_error(addexts)) {
1868 free(p != NULL ? p : kv);
1869 return -1;
1870 }
1871
1872 return 0;
1873 }
1874