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