Annotation of src/usr.bin/openssl/req.c, Revision 1.6
1.6 ! jsing 1: /* $OpenBSD: req.c,v 1.5 2015/06/20 01:07:25 doug Exp $ */
1.1 jsing 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 <stdio.h>
66: #include <stdlib.h>
67: #include <limits.h>
68: #include <string.h>
69: #include <time.h>
70:
71: #include "apps.h"
72:
73: #include <openssl/asn1.h>
74: #include <openssl/bio.h>
75: #include <openssl/bn.h>
76: #include <openssl/conf.h>
77: #include <openssl/err.h>
78: #include <openssl/evp.h>
79: #include <openssl/objects.h>
80: #include <openssl/pem.h>
81: #include <openssl/x509.h>
82: #include <openssl/x509v3.h>
83:
84: #include <openssl/dsa.h>
85:
86: #include <openssl/rsa.h>
87:
88: #define SECTION "req"
89:
90: #define BITS "default_bits"
91: #define KEYFILE "default_keyfile"
92: #define PROMPT "prompt"
93: #define DISTINGUISHED_NAME "distinguished_name"
94: #define ATTRIBUTES "attributes"
95: #define V3_EXTENSIONS "x509_extensions"
96: #define REQ_EXTENSIONS "req_extensions"
97: #define STRING_MASK "string_mask"
98: #define UTF8_IN "utf8"
99:
1.3 sthen 100: #define DEFAULT_KEY_LENGTH 2048
1.1 jsing 101: #define MIN_KEY_LENGTH 384
102:
103:
104: /* -inform arg - input format - default PEM (DER or PEM)
105: * -outform arg - output format - default PEM
106: * -in arg - input file - default stdin
107: * -out arg - output file - default stdout
108: * -verify - check request signature
109: * -noout - don't print stuff out.
110: * -text - print out human readable text.
111: * -nodes - no des encryption
112: * -config file - Load configuration file.
113: * -key file - make a request using key in file (or use it for verification).
114: * -keyform arg - key file format.
115: * -newkey - make a key and a request.
116: * -modulus - print RSA modulus.
117: * -pubkey - output Public Key.
118: * -x509 - output a self signed X509 structure instead.
119: * -asn1-kludge - output new certificate request in a format that some CA's
120: * require. This format is wrong
121: */
122:
123: static int make_REQ(X509_REQ * req, EVP_PKEY * pkey, char *dn, int mutlirdn,
124: int attribs, unsigned long chtype);
125: static int build_subject(X509_REQ * req, char *subj, unsigned long chtype,
126: int multirdn);
127: static int prompt_info(X509_REQ * req,
128: STACK_OF(CONF_VALUE) * dn_sk, char *dn_sect,
129: STACK_OF(CONF_VALUE) * attr_sk, char *attr_sect, int attribs,
130: unsigned long chtype);
131: static int auto_info(X509_REQ * req, STACK_OF(CONF_VALUE) * sk,
132: STACK_OF(CONF_VALUE) * attr, int attribs,
133: unsigned long chtype);
134: static int add_attribute_object(X509_REQ * req, char *text, const char *def,
135: char *value, int nid, int n_min,
136: int n_max, unsigned long chtype);
137: static int add_DN_object(X509_NAME * n, char *text, const char *def, char *value,
138: int nid, int n_min, int n_max, unsigned long chtype, int mval);
139: static int genpkey_cb(EVP_PKEY_CTX * ctx);
140: static int req_check_len(int len, int n_min, int n_max);
141: static int check_end(const char *str, const char *end);
142: static EVP_PKEY_CTX *set_keygen_ctx(BIO * err, const char *gstr, int *pkey_type,
143: long *pkeylen, char **palgnam,
144: ENGINE * keygen_engine);
145: static CONF *req_conf = NULL;
146: static int batch = 0;
147:
148: int
149: req_main(int argc, char **argv)
150: {
151: ENGINE *e = NULL, *gen_eng = NULL;
152: unsigned long nmflag = 0, reqflag = 0;
153: int ex = 1, x509 = 0, days = 30;
154: X509 *x509ss = NULL;
155: X509_REQ *req = NULL;
156: EVP_PKEY_CTX *genctx = NULL;
157: const char *keyalg = NULL;
158: char *keyalgstr = NULL;
159: STACK_OF(OPENSSL_STRING) * pkeyopts = NULL, *sigopts = NULL;
160: EVP_PKEY *pkey = NULL;
161: int i = 0, badops = 0, newreq = 0, verbose = 0, pkey_type = -1;
162: long newkey = -1;
163: BIO *in = NULL, *out = NULL;
164: int informat, outformat, verify = 0, noout = 0, text = 0, keyform = FORMAT_PEM;
165: int nodes = 0, kludge = 0, newhdr = 0, subject = 0, pubkey = 0;
166: char *infile, *outfile, *prog, *keyfile = NULL, *template = NULL,
167: *keyout = NULL;
168: #ifndef OPENSSL_NO_ENGINE
169: char *engine = NULL;
170: #endif
171: char *extensions = NULL;
172: char *req_exts = NULL;
173: const EVP_CIPHER *cipher = NULL;
174: ASN1_INTEGER *serial = NULL;
175: int modulus = 0;
176: char *passargin = NULL, *passargout = NULL;
177: char *passin = NULL, *passout = NULL;
178: char *p;
179: char *subj = NULL;
180: int multirdn = 0;
181: const EVP_MD *md_alg = NULL, *digest = NULL;
182: unsigned long chtype = MBSTRING_ASC;
183:
184: req_conf = NULL;
1.3 sthen 185: cipher = EVP_aes_256_cbc();
186: digest = EVP_sha256();
1.1 jsing 187:
188: infile = NULL;
189: outfile = NULL;
190: informat = FORMAT_PEM;
191: outformat = FORMAT_PEM;
192:
193: prog = argv[0];
194: argc--;
195: argv++;
196: while (argc >= 1) {
197: if (strcmp(*argv, "-inform") == 0) {
198: if (--argc < 1)
199: goto bad;
200: informat = str2fmt(*(++argv));
201: } else if (strcmp(*argv, "-outform") == 0) {
202: if (--argc < 1)
203: goto bad;
204: outformat = str2fmt(*(++argv));
205: }
206: #ifndef OPENSSL_NO_ENGINE
207: else if (strcmp(*argv, "-engine") == 0) {
208: if (--argc < 1)
209: goto bad;
210: engine = *(++argv);
211: } else if (strcmp(*argv, "-keygen_engine") == 0) {
212: if (--argc < 1)
213: goto bad;
214: gen_eng = ENGINE_by_id(*(++argv));
215: if (gen_eng == NULL) {
216: BIO_printf(bio_err, "Can't find keygen engine %s\n", *argv);
217: goto end;
218: }
219: }
220: #endif
221: else if (strcmp(*argv, "-key") == 0) {
222: if (--argc < 1)
223: goto bad;
224: keyfile = *(++argv);
225: } else if (strcmp(*argv, "-pubkey") == 0) {
226: pubkey = 1;
227: } else if (strcmp(*argv, "-new") == 0) {
228: newreq = 1;
229: } else if (strcmp(*argv, "-config") == 0) {
230: if (--argc < 1)
231: goto bad;
232: template = *(++argv);
233: } else if (strcmp(*argv, "-keyform") == 0) {
234: if (--argc < 1)
235: goto bad;
236: keyform = str2fmt(*(++argv));
237: } else if (strcmp(*argv, "-in") == 0) {
238: if (--argc < 1)
239: goto bad;
240: infile = *(++argv);
241: } else if (strcmp(*argv, "-out") == 0) {
242: if (--argc < 1)
243: goto bad;
244: outfile = *(++argv);
245: } else if (strcmp(*argv, "-keyout") == 0) {
246: if (--argc < 1)
247: goto bad;
248: keyout = *(++argv);
249: } else if (strcmp(*argv, "-passin") == 0) {
250: if (--argc < 1)
251: goto bad;
252: passargin = *(++argv);
253: } else if (strcmp(*argv, "-passout") == 0) {
254: if (--argc < 1)
255: goto bad;
256: passargout = *(++argv);
257: } else if (strcmp(*argv, "-newkey") == 0) {
258: if (--argc < 1)
259: goto bad;
260: keyalg = *(++argv);
261: newreq = 1;
262: } else if (strcmp(*argv, "-pkeyopt") == 0) {
263: if (--argc < 1)
264: goto bad;
265: if (!pkeyopts)
266: pkeyopts = sk_OPENSSL_STRING_new_null();
267: if (!pkeyopts || !sk_OPENSSL_STRING_push(pkeyopts, *(++argv)))
268: goto bad;
269: } else if (strcmp(*argv, "-sigopt") == 0) {
270: if (--argc < 1)
271: goto bad;
272: if (!sigopts)
273: sigopts = sk_OPENSSL_STRING_new_null();
274: if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
275: goto bad;
276: } else if (strcmp(*argv, "-batch") == 0)
277: batch = 1;
278: else if (strcmp(*argv, "-newhdr") == 0)
279: newhdr = 1;
280: else if (strcmp(*argv, "-modulus") == 0)
281: modulus = 1;
282: else if (strcmp(*argv, "-verify") == 0)
283: verify = 1;
284: else if (strcmp(*argv, "-nodes") == 0)
285: nodes = 1;
286: else if (strcmp(*argv, "-noout") == 0)
287: noout = 1;
288: else if (strcmp(*argv, "-verbose") == 0)
289: verbose = 1;
290: else if (strcmp(*argv, "-utf8") == 0)
291: chtype = MBSTRING_UTF8;
292: else if (strcmp(*argv, "-nameopt") == 0) {
293: if (--argc < 1)
294: goto bad;
295: if (!set_name_ex(&nmflag, *(++argv)))
296: goto bad;
297: } else if (strcmp(*argv, "-reqopt") == 0) {
298: if (--argc < 1)
299: goto bad;
300: if (!set_cert_ex(&reqflag, *(++argv)))
301: goto bad;
302: } else if (strcmp(*argv, "-subject") == 0)
303: subject = 1;
304: else if (strcmp(*argv, "-text") == 0)
305: text = 1;
306: else if (strcmp(*argv, "-x509") == 0)
307: x509 = 1;
308: else if (strcmp(*argv, "-asn1-kludge") == 0)
309: kludge = 1;
310: else if (strcmp(*argv, "-no-asn1-kludge") == 0)
311: kludge = 0;
312: else if (strcmp(*argv, "-subj") == 0) {
313: if (--argc < 1)
314: goto bad;
315: subj = *(++argv);
316: } else if (strcmp(*argv, "-multivalue-rdn") == 0)
317: multirdn = 1;
318: else if (strcmp(*argv, "-days") == 0) {
319: const char *errstr;
320:
321: if (--argc < 1)
322: goto bad;
323: days = strtonum(*(++argv), 1, INT_MAX, &errstr);
324: if (errstr) {
325: BIO_printf(bio_err, "bad -days %s, using 0: %s\n",
326: *argv, errstr);
327: days = 30;
328: }
329: } else if (strcmp(*argv, "-set_serial") == 0) {
330: if (--argc < 1)
331: goto bad;
332: serial = s2i_ASN1_INTEGER(NULL, *(++argv));
333: if (!serial)
334: goto bad;
335: } else if (strcmp(*argv, "-extensions") == 0) {
336: if (--argc < 1)
337: goto bad;
338: extensions = *(++argv);
339: } else if (strcmp(*argv, "-reqexts") == 0) {
340: if (--argc < 1)
341: goto bad;
342: req_exts = *(++argv);
343: } else if ((md_alg = EVP_get_digestbyname(&((*argv)[1]))) != NULL) {
344: /* ok */
345: digest = md_alg;
346: } else {
347: BIO_printf(bio_err, "unknown option %s\n", *argv);
348: badops = 1;
349: break;
350: }
351: argc--;
352: argv++;
353: }
354:
355: if (badops) {
356: bad:
357: BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog);
358: BIO_printf(bio_err, "where options are\n");
359: BIO_printf(bio_err, " -inform arg input format - DER or PEM\n");
360: BIO_printf(bio_err, " -outform arg output format - DER or PEM\n");
361: BIO_printf(bio_err, " -in arg input file\n");
362: BIO_printf(bio_err, " -out arg output file\n");
363: BIO_printf(bio_err, " -text text form of request\n");
364: BIO_printf(bio_err, " -pubkey output public key\n");
365: BIO_printf(bio_err, " -noout do not output REQ\n");
366: BIO_printf(bio_err, " -verify verify signature on REQ\n");
367: BIO_printf(bio_err, " -modulus RSA modulus\n");
368: BIO_printf(bio_err, " -nodes don't encrypt the output key\n");
369: #ifndef OPENSSL_NO_ENGINE
370: BIO_printf(bio_err, " -engine e use engine e, possibly a hardware device\n");
371: #endif
372: BIO_printf(bio_err, " -subject output the request's subject\n");
373: BIO_printf(bio_err, " -passin private key password source\n");
374: BIO_printf(bio_err, " -key file use the private key contained in file\n");
375: BIO_printf(bio_err, " -keyform arg key file format\n");
376: BIO_printf(bio_err, " -keyout arg file to send the key to\n");
377: BIO_printf(bio_err, " -newkey rsa:bits generate a new RSA key of 'bits' in size\n");
378: BIO_printf(bio_err, " -newkey dsa:file generate a new DSA key, parameters taken from CA in 'file'\n");
379: BIO_printf(bio_err, " -newkey ec:file generate a new EC key, parameters taken from CA in 'file'\n");
1.5 doug 380: BIO_printf(bio_err, " -[digest] Digest to sign with (md5, sha1, md4)\n");
1.1 jsing 381: BIO_printf(bio_err, " -config file request template file.\n");
382: BIO_printf(bio_err, " -subj arg set or modify request subject\n");
383: BIO_printf(bio_err, " -multivalue-rdn enable support for multivalued RDNs\n");
384: BIO_printf(bio_err, " -new new request.\n");
385: BIO_printf(bio_err, " -batch do not ask anything during request generation\n");
386: BIO_printf(bio_err, " -x509 output a x509 structure instead of a cert. req.\n");
387: BIO_printf(bio_err, " -days number of days a certificate generated by -x509 is valid for.\n");
388: BIO_printf(bio_err, " -set_serial serial number to use for a certificate generated by -x509.\n");
389: BIO_printf(bio_err, " -newhdr output \"NEW\" in the header lines\n");
390: BIO_printf(bio_err, " -asn1-kludge Output the 'request' in a format that is wrong but some CA's\n");
391: BIO_printf(bio_err, " have been reported as requiring\n");
392: BIO_printf(bio_err, " -extensions .. specify certificate extension section (override value in config file)\n");
393: BIO_printf(bio_err, " -reqexts .. specify request extension section (override value in config file)\n");
394: BIO_printf(bio_err, " -utf8 input characters are UTF8 (default ASCII)\n");
395: BIO_printf(bio_err, " -nameopt arg - various certificate name options\n");
396: BIO_printf(bio_err, " -reqopt arg - various request text options\n\n");
397: goto end;
398: }
1.2 jsing 399:
1.1 jsing 400: if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
401: BIO_printf(bio_err, "Error getting passwords\n");
402: goto end;
403: }
404: if (template != NULL) {
405: long errline = -1;
406:
407: if (verbose)
408: BIO_printf(bio_err, "Using configuration from %s\n", template);
409: req_conf = NCONF_new(NULL);
410: i = NCONF_load(req_conf, template, &errline);
411: if (i == 0) {
412: BIO_printf(bio_err, "error on line %ld of %s\n", errline, template);
413: goto end;
414: }
415: } else {
416: req_conf = config;
417:
418: if (req_conf == NULL) {
419: BIO_printf(bio_err, "Unable to load config info from %s\n", default_config_file);
420: if (newreq)
421: goto end;
422: } else if (verbose)
423: BIO_printf(bio_err, "Using configuration from %s\n",
424: default_config_file);
425: }
426:
427: if (req_conf != NULL) {
428: if (!load_config(bio_err, req_conf))
429: goto end;
430: p = NCONF_get_string(req_conf, NULL, "oid_file");
431: if (p == NULL)
432: ERR_clear_error();
433: if (p != NULL) {
434: BIO *oid_bio;
435:
436: oid_bio = BIO_new_file(p, "r");
437: if (oid_bio == NULL) {
438: /*
439: BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
440: ERR_print_errors(bio_err);
441: */
442: } else {
443: OBJ_create_objects(oid_bio);
444: BIO_free(oid_bio);
445: }
446: }
447: }
448: if (!add_oid_section(bio_err, req_conf))
449: goto end;
450:
451: if (md_alg == NULL) {
452: p = NCONF_get_string(req_conf, SECTION, "default_md");
453: if (p == NULL)
454: ERR_clear_error();
455: if (p != NULL) {
456: if ((md_alg = EVP_get_digestbyname(p)) != NULL)
457: digest = md_alg;
458: }
459: }
460: if (!extensions) {
461: extensions = NCONF_get_string(req_conf, SECTION, V3_EXTENSIONS);
462: if (!extensions)
463: ERR_clear_error();
464: }
465: if (extensions) {
466: /* Check syntax of file */
467: X509V3_CTX ctx;
468: X509V3_set_ctx_test(&ctx);
469: X509V3_set_nconf(&ctx, req_conf);
470: if (!X509V3_EXT_add_nconf(req_conf, &ctx, extensions, NULL)) {
471: BIO_printf(bio_err,
472: "Error Loading extension section %s\n", extensions);
473: goto end;
474: }
475: }
476: if (!passin) {
477: passin = NCONF_get_string(req_conf, SECTION, "input_password");
478: if (!passin)
479: ERR_clear_error();
480: }
481: if (!passout) {
482: passout = NCONF_get_string(req_conf, SECTION, "output_password");
483: if (!passout)
484: ERR_clear_error();
485: }
486: p = NCONF_get_string(req_conf, SECTION, STRING_MASK);
487: if (!p)
488: ERR_clear_error();
489:
490: if (p && !ASN1_STRING_set_default_mask_asc(p)) {
491: BIO_printf(bio_err, "Invalid global string mask setting %s\n", p);
492: goto end;
493: }
494: if (chtype != MBSTRING_UTF8) {
495: p = NCONF_get_string(req_conf, SECTION, UTF8_IN);
496: if (!p)
497: ERR_clear_error();
498: else if (!strcmp(p, "yes"))
499: chtype = MBSTRING_UTF8;
500: }
501: if (!req_exts) {
502: req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS);
503: if (!req_exts)
504: ERR_clear_error();
505: }
506: if (req_exts) {
507: /* Check syntax of file */
508: X509V3_CTX ctx;
509: X509V3_set_ctx_test(&ctx);
510: X509V3_set_nconf(&ctx, req_conf);
511: if (!X509V3_EXT_add_nconf(req_conf, &ctx, req_exts, NULL)) {
512: BIO_printf(bio_err,
513: "Error Loading request extension section %s\n",
514: req_exts);
515: goto end;
516: }
517: }
518: in = BIO_new(BIO_s_file());
519: out = BIO_new(BIO_s_file());
520: if ((in == NULL) || (out == NULL))
521: goto end;
522:
523: #ifndef OPENSSL_NO_ENGINE
524: e = setup_engine(bio_err, engine, 0);
525: #endif
526:
527: if (keyfile != NULL) {
528: pkey = load_key(bio_err, keyfile, keyform, 0, passin, e,
529: "Private Key");
530: if (!pkey) {
531: /*
532: * load_key() has already printed an appropriate
533: * message
534: */
535: goto end;
536: }
537: }
538: if (newreq && (pkey == NULL)) {
539: if (!NCONF_get_number(req_conf, SECTION, BITS, &newkey)) {
540: newkey = DEFAULT_KEY_LENGTH;
541: }
542: if (keyalg) {
543: genctx = set_keygen_ctx(bio_err, keyalg, &pkey_type, &newkey,
544: &keyalgstr, gen_eng);
545: if (!genctx)
546: goto end;
547: }
548: if (newkey < MIN_KEY_LENGTH && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA)) {
549: BIO_printf(bio_err, "private key length is too short,\n");
550: BIO_printf(bio_err, "it needs to be at least %d bits, not %ld\n", MIN_KEY_LENGTH, newkey);
551: goto end;
552: }
553: if (!genctx) {
554: genctx = set_keygen_ctx(bio_err, NULL, &pkey_type, &newkey,
555: &keyalgstr, gen_eng);
556: if (!genctx)
557: goto end;
558: }
559: if (pkeyopts) {
560: char *genopt;
561: for (i = 0; i < sk_OPENSSL_STRING_num(pkeyopts); i++) {
562: genopt = sk_OPENSSL_STRING_value(pkeyopts, i);
563: if (pkey_ctrl_string(genctx, genopt) <= 0) {
564: BIO_printf(bio_err,
565: "parameter error \"%s\"\n",
566: genopt);
567: ERR_print_errors(bio_err);
568: goto end;
569: }
570: }
571: }
572: BIO_printf(bio_err, "Generating a %ld bit %s private key\n",
573: newkey, keyalgstr);
574:
575: EVP_PKEY_CTX_set_cb(genctx, genpkey_cb);
576: EVP_PKEY_CTX_set_app_data(genctx, bio_err);
577:
578: if (EVP_PKEY_keygen(genctx, &pkey) <= 0) {
579: BIO_puts(bio_err, "Error Generating Key\n");
580: goto end;
581: }
582: EVP_PKEY_CTX_free(genctx);
583: genctx = NULL;
584:
585: if (keyout == NULL) {
586: keyout = NCONF_get_string(req_conf, SECTION, KEYFILE);
587: if (keyout == NULL)
588: ERR_clear_error();
589: }
590: if (keyout == NULL) {
591: BIO_printf(bio_err, "writing new private key to stdout\n");
592: BIO_set_fp(out, stdout, BIO_NOCLOSE);
593: } else {
594: BIO_printf(bio_err, "writing new private key to '%s'\n", keyout);
595: if (BIO_write_filename(out, keyout) <= 0) {
596: perror(keyout);
597: goto end;
598: }
599: }
600:
601: p = NCONF_get_string(req_conf, SECTION, "encrypt_rsa_key");
602: if (p == NULL) {
603: ERR_clear_error();
604: p = NCONF_get_string(req_conf, SECTION, "encrypt_key");
605: if (p == NULL)
606: ERR_clear_error();
607: }
608: if ((p != NULL) && (strcmp(p, "no") == 0))
609: cipher = NULL;
610: if (nodes)
611: cipher = NULL;
612:
613: i = 0;
614: loop:
615: if (!PEM_write_bio_PrivateKey(out, pkey, cipher,
616: NULL, 0, NULL, passout)) {
617: if ((ERR_GET_REASON(ERR_peek_error()) ==
618: PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3)) {
619: ERR_clear_error();
620: i++;
621: goto loop;
622: }
623: goto end;
624: }
625: BIO_printf(bio_err, "-----\n");
626: }
627: if (!newreq) {
628: /*
629: * Since we are using a pre-existing certificate request, the
630: * kludge 'format' info should not be changed.
631: */
632: kludge = -1;
633: if (infile == NULL)
634: BIO_set_fp(in, stdin, BIO_NOCLOSE);
635: else {
636: if (BIO_read_filename(in, infile) <= 0) {
637: perror(infile);
638: goto end;
639: }
640: }
641:
642: if (informat == FORMAT_ASN1)
643: req = d2i_X509_REQ_bio(in, NULL);
644: else if (informat == FORMAT_PEM)
645: req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
646: else {
647: BIO_printf(bio_err, "bad input format specified for X509 request\n");
648: goto end;
649: }
650: if (req == NULL) {
651: BIO_printf(bio_err, "unable to load X509 request\n");
652: goto end;
653: }
654: }
655: if (newreq || x509) {
656: if (pkey == NULL) {
657: BIO_printf(bio_err, "you need to specify a private key\n");
658: goto end;
659: }
660: if (req == NULL) {
661: req = X509_REQ_new();
662: if (req == NULL) {
663: goto end;
664: }
665: i = make_REQ(req, pkey, subj, multirdn, !x509, chtype);
666: subj = NULL; /* done processing '-subj' option */
667: if ((kludge > 0) && !sk_X509_ATTRIBUTE_num(req->req_info->attributes)) {
668: sk_X509_ATTRIBUTE_free(req->req_info->attributes);
669: req->req_info->attributes = NULL;
670: }
671: if (!i) {
672: BIO_printf(bio_err, "problems making Certificate Request\n");
673: goto end;
674: }
675: }
676: if (x509) {
677: EVP_PKEY *tmppkey;
678: X509V3_CTX ext_ctx;
679: if ((x509ss = X509_new()) == NULL)
680: goto end;
681:
682: /* Set version to V3 */
683: if (extensions && !X509_set_version(x509ss, 2))
684: goto end;
685: if (serial) {
686: if (!X509_set_serialNumber(x509ss, serial))
687: goto end;
688: } else {
689: if (!rand_serial(NULL,
690: X509_get_serialNumber(x509ss)))
691: goto end;
692: }
693:
694: if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req)))
695: goto end;
696: if (!X509_gmtime_adj(X509_get_notBefore(x509ss), 0))
697: goto end;
698: if (!X509_time_adj_ex(X509_get_notAfter(x509ss), days, 0, NULL))
699: goto end;
700: if (!X509_set_subject_name(x509ss, X509_REQ_get_subject_name(req)))
701: goto end;
702: tmppkey = X509_REQ_get_pubkey(req);
703: if (!tmppkey || !X509_set_pubkey(x509ss, tmppkey))
704: goto end;
705: EVP_PKEY_free(tmppkey);
706:
707: /* Set up V3 context struct */
708:
709: X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0);
710: X509V3_set_nconf(&ext_ctx, req_conf);
711:
712: /* Add extensions */
713: if (extensions && !X509V3_EXT_add_nconf(req_conf,
714: &ext_ctx, extensions, x509ss)) {
715: BIO_printf(bio_err,
716: "Error Loading extension section %s\n",
717: extensions);
718: goto end;
719: }
720: i = do_X509_sign(bio_err, x509ss, pkey, digest, sigopts);
721: if (!i) {
722: ERR_print_errors(bio_err);
723: goto end;
724: }
725: } else {
726: X509V3_CTX ext_ctx;
727:
728: /* Set up V3 context struct */
729:
730: X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0);
731: X509V3_set_nconf(&ext_ctx, req_conf);
732:
733: /* Add extensions */
734: if (req_exts && !X509V3_EXT_REQ_add_nconf(req_conf,
735: &ext_ctx, req_exts, req)) {
736: BIO_printf(bio_err,
737: "Error Loading extension section %s\n",
738: req_exts);
739: goto end;
740: }
741: i = do_X509_REQ_sign(bio_err, req, pkey, digest, sigopts);
742: if (!i) {
743: ERR_print_errors(bio_err);
744: goto end;
745: }
746: }
747: }
748: if (subj && x509) {
749: BIO_printf(bio_err, "Cannot modifiy certificate subject\n");
750: goto end;
751: }
752: if (subj && !x509) {
753: if (verbose) {
754: BIO_printf(bio_err, "Modifying Request's Subject\n");
755: print_name(bio_err, "old subject=", X509_REQ_get_subject_name(req), nmflag);
756: }
757: if (build_subject(req, subj, chtype, multirdn) == 0) {
758: BIO_printf(bio_err, "ERROR: cannot modify subject\n");
759: ex = 1;
760: goto end;
761: }
762: req->req_info->enc.modified = 1;
763:
764: if (verbose) {
765: print_name(bio_err, "new subject=", X509_REQ_get_subject_name(req), nmflag);
766: }
767: }
768: if (verify && !x509) {
769: int tmp = 0;
770:
771: if (pkey == NULL) {
772: pkey = X509_REQ_get_pubkey(req);
773: tmp = 1;
774: if (pkey == NULL)
775: goto end;
776: }
777: i = X509_REQ_verify(req, pkey);
778: if (tmp) {
779: EVP_PKEY_free(pkey);
780: pkey = NULL;
781: }
782: if (i < 0) {
783: goto end;
784: } else if (i == 0) {
785: BIO_printf(bio_err, "verify failure\n");
786: ERR_print_errors(bio_err);
787: } else /* if (i > 0) */
788: BIO_printf(bio_err, "verify OK\n");
789: }
790: if (noout && !text && !modulus && !subject && !pubkey) {
791: ex = 0;
792: goto end;
793: }
794: if (outfile == NULL) {
795: BIO_set_fp(out, stdout, BIO_NOCLOSE);
796: } else {
797: if ((keyout != NULL) && (strcmp(outfile, keyout) == 0))
798: i = (int) BIO_append_filename(out, outfile);
799: else
800: i = (int) BIO_write_filename(out, outfile);
801: if (!i) {
802: perror(outfile);
803: goto end;
804: }
805: }
806:
807: if (pubkey) {
808: EVP_PKEY *tpubkey;
809: tpubkey = X509_REQ_get_pubkey(req);
810: if (tpubkey == NULL) {
811: BIO_printf(bio_err, "Error getting public key\n");
812: ERR_print_errors(bio_err);
813: goto end;
814: }
815: PEM_write_bio_PUBKEY(out, tpubkey);
816: EVP_PKEY_free(tpubkey);
817: }
818: if (text) {
819: if (x509)
820: X509_print_ex(out, x509ss, nmflag, reqflag);
821: else
822: X509_REQ_print_ex(out, req, nmflag, reqflag);
823: }
824: if (subject) {
825: if (x509)
826: print_name(out, "subject=", X509_get_subject_name(x509ss), nmflag);
827: else
828: print_name(out, "subject=", X509_REQ_get_subject_name(req), nmflag);
829: }
830: if (modulus) {
831: EVP_PKEY *tpubkey;
832:
833: if (x509)
834: tpubkey = X509_get_pubkey(x509ss);
835: else
836: tpubkey = X509_REQ_get_pubkey(req);
837: if (tpubkey == NULL) {
838: fprintf(stdout, "Modulus=unavailable\n");
839: goto end;
840: }
841: fprintf(stdout, "Modulus=");
842: if (EVP_PKEY_base_id(tpubkey) == EVP_PKEY_RSA)
843: BN_print(out, tpubkey->pkey.rsa->n);
844: else
845: fprintf(stdout, "Wrong Algorithm type");
846: EVP_PKEY_free(tpubkey);
847: fprintf(stdout, "\n");
848: }
849: if (!noout && !x509) {
850: if (outformat == FORMAT_ASN1)
851: i = i2d_X509_REQ_bio(out, req);
852: else if (outformat == FORMAT_PEM) {
853: if (newhdr)
854: i = PEM_write_bio_X509_REQ_NEW(out, req);
855: else
856: i = PEM_write_bio_X509_REQ(out, req);
857: } else {
858: BIO_printf(bio_err, "bad output format specified for outfile\n");
859: goto end;
860: }
861: if (!i) {
862: BIO_printf(bio_err, "unable to write X509 request\n");
863: goto end;
864: }
865: }
866: if (!noout && x509 && (x509ss != NULL)) {
867: if (outformat == FORMAT_ASN1)
868: i = i2d_X509_bio(out, x509ss);
869: else if (outformat == FORMAT_PEM)
870: i = PEM_write_bio_X509(out, x509ss);
871: else {
872: BIO_printf(bio_err, "bad output format specified for outfile\n");
873: goto end;
874: }
875: if (!i) {
876: BIO_printf(bio_err, "unable to write X509 certificate\n");
877: goto end;
878: }
879: }
880: ex = 0;
881: end:
882: if (ex) {
883: ERR_print_errors(bio_err);
884: }
885: if ((req_conf != NULL) && (req_conf != config))
886: NCONF_free(req_conf);
887: BIO_free(in);
888: BIO_free_all(out);
889: EVP_PKEY_free(pkey);
890: if (genctx)
891: EVP_PKEY_CTX_free(genctx);
892: if (pkeyopts)
893: sk_OPENSSL_STRING_free(pkeyopts);
894: if (sigopts)
895: sk_OPENSSL_STRING_free(sigopts);
896: #ifndef OPENSSL_NO_ENGINE
897: if (gen_eng)
898: ENGINE_free(gen_eng);
899: #endif
900: free(keyalgstr);
901: X509_REQ_free(req);
902: X509_free(x509ss);
903: ASN1_INTEGER_free(serial);
904: if (passargin && passin)
905: free(passin);
906: if (passargout && passout)
907: free(passout);
908: OBJ_cleanup();
909:
910: return (ex);
911: }
912:
913: static int
914: make_REQ(X509_REQ * req, EVP_PKEY * pkey, char *subj, int multirdn,
915: int attribs, unsigned long chtype)
916: {
917: int ret = 0, i;
918: char no_prompt = 0;
919: STACK_OF(CONF_VALUE) * dn_sk, *attr_sk = NULL;
920: char *tmp, *dn_sect, *attr_sect;
921:
922: tmp = NCONF_get_string(req_conf, SECTION, PROMPT);
923: if (tmp == NULL)
924: ERR_clear_error();
925: if ((tmp != NULL) && !strcmp(tmp, "no"))
926: no_prompt = 1;
927:
928: dn_sect = NCONF_get_string(req_conf, SECTION, DISTINGUISHED_NAME);
929: if (dn_sect == NULL) {
930: BIO_printf(bio_err, "unable to find '%s' in config\n",
931: DISTINGUISHED_NAME);
932: goto err;
933: }
934: dn_sk = NCONF_get_section(req_conf, dn_sect);
935: if (dn_sk == NULL) {
936: BIO_printf(bio_err, "unable to get '%s' section\n", dn_sect);
937: goto err;
938: }
939: attr_sect = NCONF_get_string(req_conf, SECTION, ATTRIBUTES);
940: if (attr_sect == NULL) {
941: ERR_clear_error();
942: attr_sk = NULL;
943: } else {
944: attr_sk = NCONF_get_section(req_conf, attr_sect);
945: if (attr_sk == NULL) {
946: BIO_printf(bio_err, "unable to get '%s' section\n", attr_sect);
947: goto err;
948: }
949: }
950:
951: /* setup version number */
952: if (!X509_REQ_set_version(req, 0L))
953: goto err; /* version 1 */
954:
955: if (no_prompt)
956: i = auto_info(req, dn_sk, attr_sk, attribs, chtype);
957: else {
958: if (subj)
959: i = build_subject(req, subj, chtype, multirdn);
960: else
961: i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs, chtype);
962: }
963: if (!i)
964: goto err;
965:
966: if (!X509_REQ_set_pubkey(req, pkey))
967: goto err;
968:
969: ret = 1;
970: err:
971: return (ret);
972: }
973:
974: /*
975: * subject is expected to be in the format /type0=value0/type1=value1/type2=...
976: * where characters may be escaped by \
977: */
978: static int
979: build_subject(X509_REQ * req, char *subject, unsigned long chtype, int multirdn)
980: {
981: X509_NAME *n;
982:
983: if (!(n = parse_name(subject, chtype, multirdn)))
984: return 0;
985:
986: if (!X509_REQ_set_subject_name(req, n)) {
987: X509_NAME_free(n);
988: return 0;
989: }
990: X509_NAME_free(n);
991: return 1;
992: }
993:
994:
995: static int
996: prompt_info(X509_REQ * req,
997: STACK_OF(CONF_VALUE) * dn_sk, char *dn_sect,
998: STACK_OF(CONF_VALUE) * attr_sk, char *attr_sect, int attribs,
999: unsigned long chtype)
1000: {
1001: int i;
1002: char *p, *q;
1003: char buf[100];
1004: int nid, mval;
1005: long n_min, n_max;
1006: char *type, *value;
1007: const char *def;
1008: CONF_VALUE *v;
1009: X509_NAME *subj;
1010: subj = X509_REQ_get_subject_name(req);
1011:
1012: if (!batch) {
1013: BIO_printf(bio_err, "You are about to be asked to enter information that will be incorporated\n");
1014: BIO_printf(bio_err, "into your certificate request.\n");
1015: BIO_printf(bio_err, "What you are about to enter is what is called a Distinguished Name or a DN.\n");
1016: BIO_printf(bio_err, "There are quite a few fields but you can leave some blank\n");
1017: BIO_printf(bio_err, "For some fields there will be a default value,\n");
1018: BIO_printf(bio_err, "If you enter '.', the field will be left blank.\n");
1019: BIO_printf(bio_err, "-----\n");
1020: }
1021: if (sk_CONF_VALUE_num(dn_sk)) {
1022: i = -1;
1023: start: for (;;) {
1024: int ret;
1025: i++;
1026: if (sk_CONF_VALUE_num(dn_sk) <= i)
1027: break;
1028:
1029: v = sk_CONF_VALUE_value(dn_sk, i);
1030: p = q = NULL;
1031: type = v->name;
1032: if (!check_end(type, "_min") || !check_end(type, "_max") ||
1033: !check_end(type, "_default") ||
1034: !check_end(type, "_value"))
1035: continue;
1036: /*
1037: * Skip past any leading X. X: X, etc to allow for
1038: * multiple instances
1039: */
1040: for (p = v->name; *p; p++)
1041: if ((*p == ':') || (*p == ',') ||
1042: (*p == '.')) {
1043: p++;
1044: if (*p)
1045: type = p;
1046: break;
1047: }
1048: if (*type == '+') {
1049: mval = -1;
1050: type++;
1051: } else
1052: mval = 0;
1053: /* If OBJ not recognised ignore it */
1054: if ((nid = OBJ_txt2nid(type)) == NID_undef)
1055: goto start;
1056: ret = snprintf(buf, sizeof buf, "%s_default", v->name);
1057: if (ret == -1 || ret >= sizeof(buf)) {
1058: BIO_printf(bio_err, "Name '%s' too long for default\n",
1059: v->name);
1060: return 0;
1061: }
1062: if ((def = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
1063: ERR_clear_error();
1064: def = "";
1065: }
1066: ret = snprintf(buf, sizeof buf, "%s_value", v->name);
1067: if (ret == -1 || ret >= sizeof(buf)) {
1068: BIO_printf(bio_err, "Name '%s' too long for value\n",
1069: v->name);
1070: return 0;
1071: }
1072: if ((value = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
1073: ERR_clear_error();
1074: value = NULL;
1075: }
1076: ret = snprintf(buf, sizeof buf, "%s_min", v->name);
1077: if (ret == -1 || ret >= sizeof(buf)) {
1078: BIO_printf(bio_err, "Name '%s' too long for min\n",
1079: v->name);
1080: return 0;
1081: }
1082: if (!NCONF_get_number(req_conf, dn_sect, buf, &n_min)) {
1083: ERR_clear_error();
1084: n_min = -1;
1085: }
1086: ret = snprintf(buf, sizeof buf, "%s_max", v->name);
1087: if (ret == -1 || ret >= sizeof(buf)) {
1088: BIO_printf(bio_err, "Name '%s' too long for max\n",
1089: v->name);
1090: return 0;
1091: }
1092: if (!NCONF_get_number(req_conf, dn_sect, buf, &n_max)) {
1093: ERR_clear_error();
1094: n_max = -1;
1095: }
1096: if (!add_DN_object(subj, v->value, def, value, nid,
1097: n_min, n_max, chtype, mval))
1098: return 0;
1099: }
1100: if (X509_NAME_entry_count(subj) == 0) {
1101: BIO_printf(bio_err, "error, no objects specified in config file\n");
1102: return 0;
1103: }
1104: if (attribs) {
1105: if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0) &&
1106: (!batch)) {
1107: BIO_printf(bio_err,
1108: "\nPlease enter the following 'extra' attributes\n");
1109: BIO_printf(bio_err,
1110: "to be sent with your certificate request\n");
1111: }
1112: i = -1;
1113: start2: for (;;) {
1114: int ret;
1115: i++;
1116: if ((attr_sk == NULL) ||
1117: (sk_CONF_VALUE_num(attr_sk) <= i))
1118: break;
1119:
1120: v = sk_CONF_VALUE_value(attr_sk, i);
1121: type = v->name;
1122: if ((nid = OBJ_txt2nid(type)) == NID_undef)
1123: goto start2;
1124: ret = snprintf(buf, sizeof buf, "%s_default", type);
1125: if (ret == -1 || ret >= sizeof(buf)) {
1126: BIO_printf(bio_err, "Name '%s' too long for default\n",
1127: v->name);
1128: return 0;
1129: }
1130: if ((def = NCONF_get_string(req_conf, attr_sect, buf))
1131: == NULL) {
1132: ERR_clear_error();
1133: def = "";
1134: }
1135: ret = snprintf(buf, sizeof buf, "%s_value", type);
1136: if (ret == -1 || ret >= sizeof(buf)) {
1137: BIO_printf(bio_err, "Name '%s' too long for value\n",
1138: v->name);
1139: return 0;
1140: }
1141: if ((value = NCONF_get_string(req_conf, attr_sect, buf))
1142: == NULL) {
1143: ERR_clear_error();
1144: value = NULL;
1145: }
1146: ret = snprintf(buf, sizeof buf, "%s_min", type);
1147: if (ret == -1 || ret >= sizeof(buf)) {
1148: BIO_printf(bio_err, "Name '%s' too long for min\n",
1149: v->name);
1150: return 0;
1151: }
1152: if (!NCONF_get_number(req_conf, attr_sect, buf, &n_min)) {
1153: ERR_clear_error();
1154: n_min = -1;
1155: }
1156: ret = snprintf(buf, sizeof buf, "%s_max", type);
1157: if (ret == -1 || ret >= sizeof(buf)) {
1158: BIO_printf(bio_err, "Name '%s' too long for max\n",
1159: v->name);
1160: return 0;
1161: }
1162: if (!NCONF_get_number(req_conf, attr_sect, buf, &n_max)) {
1163: ERR_clear_error();
1164: n_max = -1;
1165: }
1166: if (!add_attribute_object(req,
1167: v->value, def, value, nid, n_min, n_max, chtype))
1168: return 0;
1169: }
1170: }
1171: } else {
1172: BIO_printf(bio_err, "No template, please set one up.\n");
1173: return 0;
1174: }
1175:
1176: return 1;
1177:
1178: }
1179:
1180: static int
1181: auto_info(X509_REQ * req, STACK_OF(CONF_VALUE) * dn_sk,
1182: STACK_OF(CONF_VALUE) * attr_sk, int attribs, unsigned long chtype)
1183: {
1184: int i;
1185: char *p, *q;
1186: char *type;
1187: CONF_VALUE *v;
1188: X509_NAME *subj;
1189:
1190: subj = X509_REQ_get_subject_name(req);
1191:
1192: for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
1193: int mval;
1194: v = sk_CONF_VALUE_value(dn_sk, i);
1195: p = q = NULL;
1196: type = v->name;
1197: /*
1198: * Skip past any leading X. X: X, etc to allow for multiple
1199: * instances
1200: */
1201: for (p = v->name; *p; p++)
1202: if ((*p == ':') || (*p == ',') || (*p == '.')) {
1203: p++;
1204: if (*p)
1205: type = p;
1206: break;
1207: }
1208: if (*p == '+') {
1209: p++;
1210: mval = -1;
1211: } else
1212: mval = 0;
1213: if (!X509_NAME_add_entry_by_txt(subj, type, chtype,
1214: (unsigned char *) v->value, -1, -1, mval))
1215: return 0;
1216:
1217: }
1218:
1219: if (!X509_NAME_entry_count(subj)) {
1220: BIO_printf(bio_err, "error, no objects specified in config file\n");
1221: return 0;
1222: }
1223: if (attribs) {
1224: for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) {
1225: v = sk_CONF_VALUE_value(attr_sk, i);
1226: if (!X509_REQ_add1_attr_by_txt(req, v->name, chtype,
1227: (unsigned char *) v->value, -1))
1228: return 0;
1229: }
1230: }
1231: return 1;
1232: }
1233:
1234:
1235: static int
1236: add_DN_object(X509_NAME * n, char *text, const char *def, char *value,
1237: int nid, int n_min, int n_max, unsigned long chtype, int mval)
1238: {
1239: int i, ret = 0;
1240: char buf[1024];
1241: start:
1242: if (!batch)
1243: BIO_printf(bio_err, "%s [%s]:", text, def);
1244: (void) BIO_flush(bio_err);
1245: if (value != NULL) {
1246: strlcpy(buf, value, sizeof buf);
1247: strlcat(buf, "\n", sizeof buf);
1248: BIO_printf(bio_err, "%s\n", value);
1249: } else {
1250: buf[0] = '\0';
1251: if (!batch) {
1252: if (!fgets(buf, sizeof buf, stdin))
1253: return 0;
1254: } else {
1255: buf[0] = '\n';
1256: buf[1] = '\0';
1257: }
1258: }
1259:
1260: if (buf[0] == '\0')
1261: return (0);
1262: else if (buf[0] == '\n') {
1263: if ((def == NULL) || (def[0] == '\0'))
1264: return (1);
1265: strlcpy(buf, def, sizeof buf);
1266: strlcat(buf, "\n", sizeof buf);
1267: } else if ((buf[0] == '.') && (buf[1] == '\n'))
1268: return (1);
1269:
1270: i = strlen(buf);
1271: if (buf[i - 1] != '\n') {
1272: BIO_printf(bio_err, "weird input :-(\n");
1273: return (0);
1274: }
1275: buf[--i] = '\0';
1276: if (!req_check_len(i, n_min, n_max))
1277: goto start;
1278: if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
1279: (unsigned char *) buf, -1, -1, mval))
1280: goto err;
1281: ret = 1;
1282: err:
1283: return (ret);
1284: }
1285:
1286: static int
1287: add_attribute_object(X509_REQ * req, char *text, const char *def,
1288: char *value, int nid, int n_min,
1289: int n_max, unsigned long chtype)
1290: {
1291: int i;
1292: static char buf[1024];
1293:
1294: start:
1295: if (!batch)
1296: BIO_printf(bio_err, "%s [%s]:", text, def);
1297: (void) BIO_flush(bio_err);
1298: if (value != NULL) {
1299: strlcpy(buf, value, sizeof buf);
1300: strlcat(buf, "\n", sizeof buf);
1301: BIO_printf(bio_err, "%s\n", value);
1302: } else {
1303: buf[0] = '\0';
1304: if (!batch) {
1305: if (!fgets(buf, sizeof buf, stdin))
1306: return 0;
1307: } else {
1308: buf[0] = '\n';
1309: buf[1] = '\0';
1310: }
1311: }
1312:
1313: if (buf[0] == '\0')
1314: return (0);
1315: else if (buf[0] == '\n') {
1316: if ((def == NULL) || (def[0] == '\0'))
1317: return (1);
1318: strlcpy(buf, def, sizeof buf);
1319: strlcat(buf, "\n", sizeof buf);
1320: } else if ((buf[0] == '.') && (buf[1] == '\n'))
1321: return (1);
1322:
1323: i = strlen(buf);
1324: if (buf[i - 1] != '\n') {
1325: BIO_printf(bio_err, "weird input :-(\n");
1326: return (0);
1327: }
1328: buf[--i] = '\0';
1329: if (!req_check_len(i, n_min, n_max))
1330: goto start;
1331:
1332: if (!X509_REQ_add1_attr_by_NID(req, nid, chtype,
1333: (unsigned char *) buf, -1)) {
1334: BIO_printf(bio_err, "Error adding attribute\n");
1335: ERR_print_errors(bio_err);
1336: goto err;
1337: }
1338: return (1);
1339: err:
1340: return (0);
1341: }
1342:
1343: static int
1344: req_check_len(int len, int n_min, int n_max)
1345: {
1346: if ((n_min > 0) && (len < n_min)) {
1347: BIO_printf(bio_err, "string is too short, it needs to be at least %d bytes long\n", n_min);
1348: return (0);
1349: }
1350: if ((n_max >= 0) && (len > n_max)) {
1351: BIO_printf(bio_err, "string is too long, it needs to be less than %d bytes long\n", n_max);
1352: return (0);
1353: }
1354: return (1);
1355: }
1356:
1357: /* Check if the end of a string matches 'end' */
1358: static int
1359: check_end(const char *str, const char *end)
1360: {
1361: int elen, slen;
1362: const char *tmp;
1363: elen = strlen(end);
1364: slen = strlen(str);
1365: if (elen > slen)
1366: return 1;
1367: tmp = str + slen - elen;
1368: return strcmp(tmp, end);
1369: }
1370:
1371: static EVP_PKEY_CTX *
1372: set_keygen_ctx(BIO * err, const char *gstr, int *pkey_type,
1373: long *pkeylen, char **palgnam,
1374: ENGINE * keygen_engine)
1375: {
1376: EVP_PKEY_CTX *gctx = NULL;
1377: EVP_PKEY *param = NULL;
1378: long keylen = -1;
1379: BIO *pbio = NULL;
1380: const char *paramfile = NULL;
1381: const char *errstr;
1382:
1383: if (gstr == NULL) {
1384: *pkey_type = EVP_PKEY_RSA;
1385: keylen = *pkeylen;
1386: } else if (gstr[0] >= '0' && gstr[0] <= '9') {
1387: *pkey_type = EVP_PKEY_RSA;
1388: keylen = strtonum(gstr, 0, LONG_MAX, &errstr);
1389: if (errstr) {
1390: BIO_printf(err, "bad algorithm %s: %s\n", gstr, errstr);
1391: return NULL;
1392: }
1393: *pkeylen = keylen;
1394: } else if (!strncmp(gstr, "param:", 6))
1395: paramfile = gstr + 6;
1396: else {
1397: const char *p = strchr(gstr, ':');
1398: int len;
1399: ENGINE *tmpeng;
1400: const EVP_PKEY_ASN1_METHOD *ameth;
1401:
1402: if (p)
1403: len = p - gstr;
1404: else
1405: len = strlen(gstr);
1406: /*
1407: * The lookup of a the string will cover all engines so keep
1408: * a note of the implementation.
1409: */
1410:
1411: ameth = EVP_PKEY_asn1_find_str(&tmpeng, gstr, len);
1412:
1413: if (!ameth) {
1414: BIO_printf(err, "Unknown algorithm %.*s\n", len, gstr);
1415: return NULL;
1416: }
1417: EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL,
1418: ameth);
1419: #ifndef OPENSSL_NO_ENGINE
1420: if (tmpeng)
1421: ENGINE_finish(tmpeng);
1422: #endif
1423: if (*pkey_type == EVP_PKEY_RSA) {
1424: if (p) {
1425: keylen = strtonum(p + 1, 0, LONG_MAX, &errstr);
1426: if (errstr) {
1427: BIO_printf(err, "bad algorithm %s: %s\n",
1428: p + 1, errstr);
1429: return NULL;
1430: }
1431: *pkeylen = keylen;
1432: } else
1433: keylen = *pkeylen;
1434: } else if (p)
1435: paramfile = p + 1;
1436: }
1437:
1438: if (paramfile) {
1439: pbio = BIO_new_file(paramfile, "r");
1440: if (!pbio) {
1441: BIO_printf(err, "Can't open parameter file %s\n",
1442: paramfile);
1443: return NULL;
1444: }
1445: param = PEM_read_bio_Parameters(pbio, NULL);
1446:
1447: if (!param) {
1448: X509 *x;
1449: (void) BIO_reset(pbio);
1450: x = PEM_read_bio_X509(pbio, NULL, NULL, NULL);
1451: if (x) {
1452: param = X509_get_pubkey(x);
1453: X509_free(x);
1454: }
1455: }
1456: BIO_free(pbio);
1457:
1458: if (!param) {
1459: BIO_printf(err, "Error reading parameter file %s\n",
1460: paramfile);
1461: return NULL;
1462: }
1463: if (*pkey_type == -1)
1464: *pkey_type = EVP_PKEY_id(param);
1465: else if (*pkey_type != EVP_PKEY_base_id(param)) {
1466: BIO_printf(err, "Key Type does not match parameters\n");
1467: EVP_PKEY_free(param);
1468: return NULL;
1469: }
1470: }
1471: if (palgnam) {
1472: const EVP_PKEY_ASN1_METHOD *ameth;
1473: ENGINE *tmpeng;
1474: const char *anam;
1475: ameth = EVP_PKEY_asn1_find(&tmpeng, *pkey_type);
1476: if (!ameth) {
1477: BIO_puts(err, "Internal error: can't find key algorithm\n");
1478: return NULL;
1479: }
1480: EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth);
1.4 jsing 1481: *palgnam = strdup(anam);
1.1 jsing 1482: #ifndef OPENSSL_NO_ENGINE
1483: if (tmpeng)
1484: ENGINE_finish(tmpeng);
1485: #endif
1486: }
1487: if (param) {
1488: gctx = EVP_PKEY_CTX_new(param, keygen_engine);
1489: *pkeylen = EVP_PKEY_bits(param);
1490: EVP_PKEY_free(param);
1491: } else
1492: gctx = EVP_PKEY_CTX_new_id(*pkey_type, keygen_engine);
1493:
1494: if (!gctx) {
1495: BIO_puts(err, "Error allocating keygen context\n");
1496: ERR_print_errors(err);
1497: return NULL;
1498: }
1499: if (EVP_PKEY_keygen_init(gctx) <= 0) {
1500: BIO_puts(err, "Error initializing keygen context\n");
1501: ERR_print_errors(err);
1502: return NULL;
1503: }
1504: if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) {
1505: if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0) {
1506: BIO_puts(err, "Error setting RSA keysize\n");
1507: ERR_print_errors(err);
1508: EVP_PKEY_CTX_free(gctx);
1509: return NULL;
1510: }
1511: }
1512:
1513: return gctx;
1514: }
1515:
1516: static int
1517: genpkey_cb(EVP_PKEY_CTX * ctx)
1518: {
1519: char c = '*';
1520: BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
1521: int p;
1522: p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
1523: if (p == 0)
1524: c = '.';
1525: if (p == 1)
1526: c = '+';
1527: if (p == 2)
1528: c = '*';
1529: if (p == 3)
1530: c = '\n';
1531: BIO_write(b, &c, 1);
1532: (void) BIO_flush(b);
1533: return 1;
1534: }
1535:
1536: static int
1537: do_sign_init(BIO * err, EVP_MD_CTX * ctx, EVP_PKEY * pkey,
1538: const EVP_MD * md, STACK_OF(OPENSSL_STRING) * sigopts)
1539: {
1540: EVP_PKEY_CTX *pkctx = NULL;
1541: int i;
1542: EVP_MD_CTX_init(ctx);
1543: if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey))
1544: return 0;
1545: for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
1546: char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
1547: if (pkey_ctrl_string(pkctx, sigopt) <= 0) {
1548: BIO_printf(err, "parameter error \"%s\"\n", sigopt);
1549: ERR_print_errors(bio_err);
1550: return 0;
1551: }
1552: }
1553: return 1;
1554: }
1555:
1556: int
1557: do_X509_sign(BIO * err, X509 * x, EVP_PKEY * pkey, const EVP_MD * md,
1558: STACK_OF(OPENSSL_STRING) * sigopts)
1559: {
1560: int rv;
1561: EVP_MD_CTX mctx;
1562: EVP_MD_CTX_init(&mctx);
1563: rv = do_sign_init(err, &mctx, pkey, md, sigopts);
1564: if (rv > 0)
1565: rv = X509_sign_ctx(x, &mctx);
1566: EVP_MD_CTX_cleanup(&mctx);
1567: return rv > 0 ? 1 : 0;
1568: }
1569:
1570:
1571: int
1572: do_X509_REQ_sign(BIO * err, X509_REQ * x, EVP_PKEY * pkey, const EVP_MD * md,
1573: STACK_OF(OPENSSL_STRING) * sigopts)
1574: {
1575: int rv;
1576: EVP_MD_CTX mctx;
1577: EVP_MD_CTX_init(&mctx);
1578: rv = do_sign_init(err, &mctx, pkey, md, sigopts);
1579: if (rv > 0)
1580: rv = X509_REQ_sign_ctx(x, &mctx);
1581: EVP_MD_CTX_cleanup(&mctx);
1582: return rv > 0 ? 1 : 0;
1583: }
1584:
1585:
1586:
1587: int
1588: do_X509_CRL_sign(BIO * err, X509_CRL * x, EVP_PKEY * pkey, const EVP_MD * md,
1589: STACK_OF(OPENSSL_STRING) * sigopts)
1590: {
1591: int rv;
1592: EVP_MD_CTX mctx;
1593: EVP_MD_CTX_init(&mctx);
1594: rv = do_sign_init(err, &mctx, pkey, md, sigopts);
1595: if (rv > 0)
1596: rv = X509_CRL_sign_ctx(x, &mctx);
1597: EVP_MD_CTX_cleanup(&mctx);
1598: return rv > 0 ? 1 : 0;
1599: }