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