1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ssl/tsrc/BC/libcrypto/topenssl/src/req.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1694 @@
1.4 +/* apps/req.c */
1.5 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
1.6 + * All rights reserved.
1.7 + *
1.8 + * This package is an SSL implementation written
1.9 + * by Eric Young (eay@cryptsoft.com).
1.10 + * The implementation was written so as to conform with Netscapes SSL.
1.11 + *
1.12 + * This library is free for commercial and non-commercial use as long as
1.13 + * the following conditions are aheared to. The following conditions
1.14 + * apply to all code found in this distribution, be it the RC4, RSA,
1.15 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1.16 + * included with this distribution is covered by the same copyright terms
1.17 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1.18 + *
1.19 + * Copyright remains Eric Young's, and as such any Copyright notices in
1.20 + * the code are not to be removed.
1.21 + * If this package is used in a product, Eric Young should be given attribution
1.22 + * as the author of the parts of the library used.
1.23 + * This can be in the form of a textual message at program startup or
1.24 + * in documentation (online or textual) provided with the package.
1.25 + *
1.26 + * Redistribution and use in source and binary forms, with or without
1.27 + * modification, are permitted provided that the following conditions
1.28 + * are met:
1.29 + * 1. Redistributions of source code must retain the copyright
1.30 + * notice, this list of conditions and the following disclaimer.
1.31 + * 2. Redistributions in binary form must reproduce the above copyright
1.32 + * notice, this list of conditions and the following disclaimer in the
1.33 + * documentation and/or other materials provided with the distribution.
1.34 + * 3. All advertising materials mentioning features or use of this software
1.35 + * must display the following acknowledgement:
1.36 + * "This product includes cryptographic software written by
1.37 + * Eric Young (eay@cryptsoft.com)"
1.38 + * The word 'cryptographic' can be left out if the rouines from the library
1.39 + * being used are not cryptographic related :-).
1.40 + * 4. If you include any Windows specific code (or a derivative thereof) from
1.41 + * the apps directory (application code) you must include an acknowledgement:
1.42 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1.43 + *
1.44 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1.45 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.46 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1.47 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1.48 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1.49 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1.50 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1.52 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1.53 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1.54 + * SUCH DAMAGE.
1.55 + *
1.56 + * The licence and distribution terms for any publically available version or
1.57 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1.58 + * copied and put under another distribution licence
1.59 + * [including the GNU Public Licence.]
1.60 + */
1.61 +
1.62 +/* Until the key-gen callbacks are modified to use newer prototypes, we allow
1.63 + * deprecated functions for openssl-internal code */
1.64 +#ifdef OPENSSL_NO_DEPRECATED
1.65 +#undef OPENSSL_NO_DEPRECATED
1.66 +#endif
1.67 +
1.68 +#include <stdio.h>
1.69 +#include <stdlib.h>
1.70 +#include <time.h>
1.71 +#include <string.h>
1.72 +#ifdef OPENSSL_NO_STDIO
1.73 +#define APPS_WIN16
1.74 +#endif
1.75 +#include "apps.h"
1.76 +#include <openssl/bio.h>
1.77 +#include <openssl/evp.h>
1.78 +#include <openssl/conf.h>
1.79 +#include <openssl/err.h>
1.80 +#include <openssl/asn1.h>
1.81 +#include <openssl/x509.h>
1.82 +#include <openssl/x509v3.h>
1.83 +#include <openssl/objects.h>
1.84 +#include <openssl/pem.h>
1.85 +#include <openssl/bn.h>
1.86 +#ifndef OPENSSL_NO_RSA
1.87 +#include <openssl/rsa.h>
1.88 +#endif
1.89 +#ifndef OPENSSL_NO_DSA
1.90 +#include <openssl/dsa.h>
1.91 +#endif
1.92 +
1.93 +#define SECTION "req"
1.94 +
1.95 +#define BITS "default_bits"
1.96 +#define KEYFILE "default_keyfile"
1.97 +#define PROMPT "prompt"
1.98 +#define DISTINGUISHED_NAME "distinguished_name"
1.99 +#define ATTRIBUTES "attributes"
1.100 +#define V3_EXTENSIONS "x509_extensions"
1.101 +#define REQ_EXTENSIONS "req_extensions"
1.102 +#define STRING_MASK "string_mask"
1.103 +#define UTF8_IN "utf8"
1.104 +
1.105 +#define DEFAULT_KEY_LENGTH 512
1.106 +#define MIN_KEY_LENGTH 384
1.107 +
1.108 +#undef PROG
1.109 +#define PROG req_main
1.110 +
1.111 +/* -inform arg - input format - default PEM (DER or PEM)
1.112 + * -outform arg - output format - default PEM
1.113 + * -in arg - input file - default stdin
1.114 + * -out arg - output file - default stdout
1.115 + * -verify - check request signature
1.116 + * -noout - don't print stuff out.
1.117 + * -text - print out human readable text.
1.118 + * -nodes - no des encryption
1.119 + * -config file - Load configuration file.
1.120 + * -key file - make a request using key in file (or use it for verification).
1.121 + * -keyform arg - key file format.
1.122 + * -rand file(s) - load the file(s) into the PRNG.
1.123 + * -newkey - make a key and a request.
1.124 + * -modulus - print RSA modulus.
1.125 + * -pubkey - output Public Key.
1.126 + * -x509 - output a self signed X509 structure instead.
1.127 + * -asn1-kludge - output new certificate request in a format that some CA's
1.128 + * require. This format is wrong
1.129 + */
1.130 +
1.131 +static int make_REQ(X509_REQ *req,EVP_PKEY *pkey,char *dn,int mutlirdn,
1.132 + int attribs,unsigned long chtype);
1.133 +static int build_subject(X509_REQ *req, char *subj, unsigned long chtype,
1.134 + int multirdn);
1.135 +static int prompt_info(X509_REQ *req,
1.136 + STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect,
1.137 + STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs,
1.138 + unsigned long chtype);
1.139 +static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *sk,
1.140 + STACK_OF(CONF_VALUE) *attr, int attribs,
1.141 + unsigned long chtype);
1.142 +static int add_attribute_object(X509_REQ *req, char *text, const char *def,
1.143 + char *value, int nid, int n_min,
1.144 + int n_max, unsigned long chtype);
1.145 +static int add_DN_object(X509_NAME *n, char *text, const char *def, char *value,
1.146 + int nid,int n_min,int n_max, unsigned long chtype, int mval);
1.147 +#ifndef OPENSSL_NO_RSA
1.148 +static int MS_CALLBACK req_cb(int p, int n, BN_GENCB *cb);
1.149 +#endif
1.150 +static int req_check_len(int len,int n_min,int n_max);
1.151 +static int check_end(const char *str, const char *end);
1.152 +#ifndef MONOLITH
1.153 +static char *default_config_file=NULL;
1.154 +#endif
1.155 +static CONF *req_conf=NULL;
1.156 +static int batch=0;
1.157 +
1.158 +#define TYPE_RSA 1
1.159 +#define TYPE_DSA 2
1.160 +#define TYPE_DH 3
1.161 +#define TYPE_EC 4
1.162 +
1.163 +
1.164 +
1.165 +int MAIN(int, char **);
1.166 +
1.167 +int MAIN(int argc, char **argv)
1.168 + {
1.169 + ENGINE *e = NULL;
1.170 +#ifndef OPENSSL_NO_DSA
1.171 + DSA *dsa_params=NULL;
1.172 +#endif
1.173 +#ifndef OPENSSL_NO_ECDSA
1.174 + EC_KEY *ec_params = NULL;
1.175 +#endif
1.176 + unsigned long nmflag = 0, reqflag = 0;
1.177 + int ex=1,x509=0,days=30;
1.178 + X509 *x509ss=NULL;
1.179 + X509_REQ *req=NULL;
1.180 + EVP_PKEY *pkey=NULL;
1.181 + int i=0,badops=0,newreq=0,verbose=0,pkey_type=TYPE_RSA;
1.182 + long newkey = -1;
1.183 + BIO *in=NULL,*out=NULL;
1.184 + int informat,outformat,verify=0,noout=0,text=0,keyform=FORMAT_PEM;
1.185 + int nodes=0,kludge=0,newhdr=0,subject=0,pubkey=0;
1.186 + char *infile,*outfile,*prog,*keyfile=NULL,*template=NULL,*keyout=NULL;
1.187 +#ifndef OPENSSL_NO_ENGINE
1.188 + char *engine=NULL;
1.189 +#endif
1.190 + char *extensions = NULL;
1.191 + char *req_exts = NULL;
1.192 + const EVP_CIPHER *cipher=NULL;
1.193 + ASN1_INTEGER *serial = NULL;
1.194 + int modulus=0;
1.195 + char *inrand=NULL;
1.196 + char *passargin = NULL, *passargout = NULL;
1.197 + char *passin = NULL, *passout = NULL;
1.198 + char *p;
1.199 + char *subj = NULL;
1.200 + int multirdn = 0;
1.201 + const EVP_MD *md_alg=NULL,*digest=EVP_sha1();
1.202 + unsigned long chtype = MBSTRING_ASC;
1.203 +#ifndef MONOLITH
1.204 + char *to_free;
1.205 + long errline;
1.206 +#endif
1.207 +
1.208 + req_conf = NULL;
1.209 +#ifndef OPENSSL_NO_DES
1.210 + cipher=EVP_des_ede3_cbc();
1.211 +#endif
1.212 + apps_startup();
1.213 +
1.214 + if (bio_err == NULL)
1.215 + if ((bio_err=BIO_new(BIO_s_file())) != NULL)
1.216 + BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
1.217 +
1.218 +
1.219 + infile=NULL;
1.220 + outfile=NULL;
1.221 + informat=FORMAT_PEM;
1.222 + outformat=FORMAT_PEM;
1.223 +
1.224 + prog=argv[0];
1.225 + argc--;
1.226 + argv++;
1.227 + while (argc >= 1)
1.228 + {
1.229 + if (strcmp(*argv,"-inform") == 0)
1.230 + {
1.231 + if (--argc < 1) goto bad;
1.232 + informat=str2fmt(*(++argv));
1.233 + }
1.234 + else if (strcmp(*argv,"-outform") == 0)
1.235 + {
1.236 + if (--argc < 1) goto bad;
1.237 + outformat=str2fmt(*(++argv));
1.238 + }
1.239 +#ifndef OPENSSL_NO_ENGINE
1.240 + else if (strcmp(*argv,"-engine") == 0)
1.241 + {
1.242 + if (--argc < 1) goto bad;
1.243 + engine= *(++argv);
1.244 + }
1.245 +#endif
1.246 + else if (strcmp(*argv,"-key") == 0)
1.247 + {
1.248 + if (--argc < 1) goto bad;
1.249 + keyfile= *(++argv);
1.250 + }
1.251 + else if (strcmp(*argv,"-pubkey") == 0)
1.252 + {
1.253 + pubkey=1;
1.254 + }
1.255 + else if ((strcmp(*argv,"-new") == 0))
1.256 + {
1.257 + newreq=1;
1.258 + }
1.259 + else if (strcmp(*argv,"-config") == 0)
1.260 + {
1.261 + if (--argc < 1) goto bad;
1.262 + template= *(++argv);
1.263 + }
1.264 + else if (strcmp(*argv,"-keyform") == 0)
1.265 + {
1.266 + if (--argc < 1) goto bad;
1.267 + keyform=str2fmt(*(++argv));
1.268 + }
1.269 + else if (strcmp(*argv,"-in") == 0)
1.270 + {
1.271 + if (--argc < 1) goto bad;
1.272 + infile= *(++argv);
1.273 + }
1.274 + else if (strcmp(*argv,"-out") == 0)
1.275 + {
1.276 + if (--argc < 1) goto bad;
1.277 + outfile= *(++argv);
1.278 + }
1.279 + else if (strcmp(*argv,"-keyout") == 0)
1.280 + {
1.281 + if (--argc < 1) goto bad;
1.282 + keyout= *(++argv);
1.283 + }
1.284 + else if (strcmp(*argv,"-passin") == 0)
1.285 + {
1.286 + if (--argc < 1) goto bad;
1.287 + passargin= *(++argv);
1.288 + }
1.289 + else if (strcmp(*argv,"-passout") == 0)
1.290 + {
1.291 + if (--argc < 1) goto bad;
1.292 + passargout= *(++argv);
1.293 + }
1.294 + else if (strcmp(*argv,"-rand") == 0)
1.295 + {
1.296 + if (--argc < 1) goto bad;
1.297 + inrand= *(++argv);
1.298 + }
1.299 + else if (strcmp(*argv,"-newkey") == 0)
1.300 + {
1.301 + int is_numeric;
1.302 +
1.303 + if (--argc < 1) goto bad;
1.304 + p= *(++argv);
1.305 + is_numeric = p[0] >= '0' && p[0] <= '9';
1.306 + if (strncmp("rsa:",p,4) == 0 || is_numeric)
1.307 + {
1.308 + pkey_type=TYPE_RSA;
1.309 + if(!is_numeric)
1.310 + p+=4;
1.311 + newkey= atoi(p);
1.312 + }
1.313 + else
1.314 +#ifndef OPENSSL_NO_DSA
1.315 + if (strncmp("dsa:",p,4) == 0)
1.316 + {
1.317 + X509 *xtmp=NULL;
1.318 + EVP_PKEY *dtmp;
1.319 +
1.320 + pkey_type=TYPE_DSA;
1.321 + p+=4;
1.322 + if ((in=BIO_new_file(p,"r")) == NULL)
1.323 + {
1.324 + perror(p);
1.325 + goto end;
1.326 + }
1.327 + if ((dsa_params=PEM_read_bio_DSAparams(in,NULL,NULL,NULL)) == NULL)
1.328 + {
1.329 + ERR_clear_error();
1.330 + (void)BIO_reset(in);
1.331 + if ((xtmp=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
1.332 + {
1.333 + BIO_printf(bio_err,"unable to load DSA parameters from file\n");
1.334 + goto end;
1.335 + }
1.336 +
1.337 + if ((dtmp=X509_get_pubkey(xtmp)) == NULL) goto end;
1.338 + if (dtmp->type == EVP_PKEY_DSA)
1.339 + dsa_params=DSAparams_dup(dtmp->pkey.dsa);
1.340 + EVP_PKEY_free(dtmp);
1.341 + X509_free(xtmp);
1.342 + if (dsa_params == NULL)
1.343 + {
1.344 + BIO_printf(bio_err,"Certificate does not contain DSA parameters\n");
1.345 + goto end;
1.346 + }
1.347 + }
1.348 + BIO_free(in);
1.349 + in=NULL;
1.350 + newkey=BN_num_bits(dsa_params->p);
1.351 + }
1.352 + else
1.353 +#endif
1.354 +#ifndef OPENSSL_NO_ECDSA
1.355 + if (strncmp("ec:",p,3) == 0)
1.356 + {
1.357 + X509 *xtmp=NULL;
1.358 + EVP_PKEY *dtmp;
1.359 + EC_GROUP *group;
1.360 +
1.361 + pkey_type=TYPE_EC;
1.362 + p+=3;
1.363 + if ((in=BIO_new_file(p,"r")) == NULL)
1.364 + {
1.365 + perror(p);
1.366 + goto end;
1.367 + }
1.368 + if ((ec_params = EC_KEY_new()) == NULL)
1.369 + goto end;
1.370 + group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
1.371 + if (group == NULL)
1.372 + {
1.373 + EC_KEY_free(ec_params);
1.374 + ERR_clear_error();
1.375 + (void)BIO_reset(in);
1.376 + if ((xtmp=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
1.377 + {
1.378 + BIO_printf(bio_err,"unable to load EC parameters from file\n");
1.379 + goto end;
1.380 + }
1.381 +
1.382 + if ((dtmp=X509_get_pubkey(xtmp))==NULL)
1.383 + goto end;
1.384 + if (dtmp->type == EVP_PKEY_EC)
1.385 + ec_params = EC_KEY_dup(dtmp->pkey.ec);
1.386 + EVP_PKEY_free(dtmp);
1.387 + X509_free(xtmp);
1.388 + if (ec_params == NULL)
1.389 + {
1.390 + BIO_printf(bio_err,"Certificate does not contain EC parameters\n");
1.391 + goto end;
1.392 + }
1.393 + }
1.394 + else
1.395 + {
1.396 + if (EC_KEY_set_group(ec_params, group) == 0)
1.397 + goto end;
1.398 + EC_GROUP_free(group);
1.399 + }
1.400 +
1.401 + BIO_free(in);
1.402 + in=NULL;
1.403 + newkey = EC_GROUP_get_degree(EC_KEY_get0_group(ec_params));
1.404 + }
1.405 + else
1.406 +#endif
1.407 +#ifndef OPENSSL_NO_DH
1.408 + if (strncmp("dh:",p,4) == 0)
1.409 + {
1.410 + pkey_type=TYPE_DH;
1.411 + p+=3;
1.412 + }
1.413 + else
1.414 +#endif
1.415 + {
1.416 + goto bad;
1.417 + }
1.418 +
1.419 + newreq=1;
1.420 + }
1.421 + else if (strcmp(*argv,"-batch") == 0)
1.422 + batch=1;
1.423 + else if (strcmp(*argv,"-newhdr") == 0)
1.424 + newhdr=1;
1.425 + else if (strcmp(*argv,"-modulus") == 0)
1.426 + modulus=1;
1.427 + else if (strcmp(*argv,"-verify") == 0)
1.428 + verify=1;
1.429 + else if (strcmp(*argv,"-nodes") == 0)
1.430 + nodes=1;
1.431 + else if (strcmp(*argv,"-noout") == 0)
1.432 + noout=1;
1.433 + else if (strcmp(*argv,"-verbose") == 0)
1.434 + verbose=1;
1.435 + else if (strcmp(*argv,"-utf8") == 0)
1.436 + chtype = MBSTRING_UTF8;
1.437 + else if (strcmp(*argv,"-nameopt") == 0)
1.438 + {
1.439 + if (--argc < 1) goto bad;
1.440 + if (!set_name_ex(&nmflag, *(++argv))) goto bad;
1.441 + }
1.442 + else if (strcmp(*argv,"-reqopt") == 0)
1.443 + {
1.444 + if (--argc < 1) goto bad;
1.445 + if (!set_cert_ex(&reqflag, *(++argv))) goto bad;
1.446 + }
1.447 + else if (strcmp(*argv,"-subject") == 0)
1.448 + subject=1;
1.449 + else if (strcmp(*argv,"-text") == 0)
1.450 + text=1;
1.451 + else if (strcmp(*argv,"-x509") == 0)
1.452 + x509=1;
1.453 + else if (strcmp(*argv,"-asn1-kludge") == 0)
1.454 + kludge=1;
1.455 + else if (strcmp(*argv,"-no-asn1-kludge") == 0)
1.456 + kludge=0;
1.457 + else if (strcmp(*argv,"-subj") == 0)
1.458 + {
1.459 + if (--argc < 1) goto bad;
1.460 + subj= *(++argv);
1.461 + }
1.462 + else if (strcmp(*argv,"-multivalue-rdn") == 0)
1.463 + multirdn=1;
1.464 + else if (strcmp(*argv,"-days") == 0)
1.465 + {
1.466 + if (--argc < 1) goto bad;
1.467 + days= atoi(*(++argv));
1.468 + if (days == 0) days=30;
1.469 + }
1.470 + else if (strcmp(*argv,"-set_serial") == 0)
1.471 + {
1.472 + if (--argc < 1) goto bad;
1.473 + serial = s2i_ASN1_INTEGER(NULL, *(++argv));
1.474 + if (!serial) goto bad;
1.475 + }
1.476 + else if ((md_alg=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
1.477 + {
1.478 + /* ok */
1.479 + digest=md_alg;
1.480 + }
1.481 + else if (strcmp(*argv,"-extensions") == 0)
1.482 + {
1.483 + if (--argc < 1) goto bad;
1.484 + extensions = *(++argv);
1.485 + }
1.486 + else if (strcmp(*argv,"-reqexts") == 0)
1.487 + {
1.488 + if (--argc < 1) goto bad;
1.489 + req_exts = *(++argv);
1.490 + }
1.491 + else
1.492 + {
1.493 + BIO_printf(bio_err,"unknown option %s\n",*argv);
1.494 + badops=1;
1.495 + break;
1.496 + }
1.497 + argc--;
1.498 + argv++;
1.499 + }
1.500 +
1.501 + if (badops)
1.502 + {
1.503 +bad:
1.504 + BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
1.505 + BIO_printf(bio_err,"where options are\n");
1.506 + BIO_printf(bio_err," -inform arg input format - DER or PEM\n");
1.507 + BIO_printf(bio_err," -outform arg output format - DER or PEM\n");
1.508 + BIO_printf(bio_err," -in arg input file\n");
1.509 + BIO_printf(bio_err," -out arg output file\n");
1.510 + BIO_printf(bio_err," -text text form of request\n");
1.511 + BIO_printf(bio_err," -pubkey output public key\n");
1.512 + BIO_printf(bio_err," -noout do not output REQ\n");
1.513 + BIO_printf(bio_err," -verify verify signature on REQ\n");
1.514 + BIO_printf(bio_err," -modulus RSA modulus\n");
1.515 + BIO_printf(bio_err," -nodes don't encrypt the output key\n");
1.516 +#ifndef OPENSSL_NO_ENGINE
1.517 + BIO_printf(bio_err," -engine e use engine e, possibly a hardware device\n");
1.518 +#endif
1.519 + BIO_printf(bio_err," -subject output the request's subject\n");
1.520 + BIO_printf(bio_err," -passin private key password source\n");
1.521 + BIO_printf(bio_err," -key file use the private key contained in file\n");
1.522 + BIO_printf(bio_err," -keyform arg key file format\n");
1.523 + BIO_printf(bio_err," -keyout arg file to send the key to\n");
1.524 + BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
1.525 + BIO_printf(bio_err," load the file (or the files in the directory) into\n");
1.526 + BIO_printf(bio_err," the random number generator\n");
1.527 + BIO_printf(bio_err," -newkey rsa:bits generate a new RSA key of 'bits' in size\n");
1.528 + BIO_printf(bio_err," -newkey dsa:file generate a new DSA key, parameters taken from CA in 'file'\n");
1.529 +#ifndef OPENSSL_NO_ECDSA
1.530 + BIO_printf(bio_err," -newkey ec:file generate a new EC key, parameters taken from CA in 'file'\n");
1.531 +#endif
1.532 + BIO_printf(bio_err," -[digest] Digest to sign with (md5, sha1, md2, mdc2, md4)\n");
1.533 + BIO_printf(bio_err," -config file request template file.\n");
1.534 + BIO_printf(bio_err," -subj arg set or modify request subject\n");
1.535 + BIO_printf(bio_err," -multivalue-rdn enable support for multivalued RDNs\n");
1.536 + BIO_printf(bio_err," -new new request.\n");
1.537 + BIO_printf(bio_err," -batch do not ask anything during request generation\n");
1.538 + BIO_printf(bio_err," -x509 output a x509 structure instead of a cert. req.\n");
1.539 + BIO_printf(bio_err," -days number of days a certificate generated by -x509 is valid for.\n");
1.540 + BIO_printf(bio_err," -set_serial serial number to use for a certificate generated by -x509.\n");
1.541 + BIO_printf(bio_err," -newhdr output \"NEW\" in the header lines\n");
1.542 + BIO_printf(bio_err," -asn1-kludge Output the 'request' in a format that is wrong but some CA's\n");
1.543 + BIO_printf(bio_err," have been reported as requiring\n");
1.544 + BIO_printf(bio_err," -extensions .. specify certificate extension section (override value in config file)\n");
1.545 + BIO_printf(bio_err," -reqexts .. specify request extension section (override value in config file)\n");
1.546 + BIO_printf(bio_err," -utf8 input characters are UTF8 (default ASCII)\n");
1.547 + BIO_printf(bio_err," -nameopt arg - various certificate name options\n");
1.548 + BIO_printf(bio_err," -reqopt arg - various request text options\n\n");
1.549 + goto end;
1.550 + }
1.551 +
1.552 + ERR_load_crypto_strings();
1.553 + if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
1.554 + BIO_printf(bio_err, "Error getting passwords\n");
1.555 + goto end;
1.556 + }
1.557 +
1.558 +#ifndef MONOLITH /* else this has happened in openssl.c (global `config') */
1.559 + /* Lets load up our environment a little */
1.560 + p=getenv("OPENSSL_CONF");
1.561 + if (p == NULL)
1.562 + p=getenv("SSLEAY_CONF");
1.563 + if (p == NULL)
1.564 + p=to_free=make_config_name();
1.565 + default_config_file=p;
1.566 + config=NCONF_new(NULL);
1.567 + i=NCONF_load(config, p, &errline);
1.568 +#endif
1.569 +
1.570 + if (template != NULL)
1.571 + {
1.572 + long errline = -1;
1.573 +
1.574 + if( verbose )
1.575 + BIO_printf(bio_err,"Using configuration from %s\n",template);
1.576 + req_conf=NCONF_new(NULL);
1.577 + i=NCONF_load(req_conf,template,&errline);
1.578 + if (i == 0)
1.579 + {
1.580 + BIO_printf(bio_err,"error on line %ld of %s\n",errline,template);
1.581 + goto end;
1.582 + }
1.583 + }
1.584 + else
1.585 + {
1.586 + req_conf=config;
1.587 +
1.588 + if (req_conf == NULL)
1.589 + {
1.590 + BIO_printf(bio_err,"Unable to load config info from %s\n", default_config_file);
1.591 + if (newreq)
1.592 + goto end;
1.593 + }
1.594 + else if( verbose )
1.595 + BIO_printf(bio_err,"Using configuration from %s\n",
1.596 + default_config_file);
1.597 + }
1.598 +
1.599 + if (req_conf != NULL)
1.600 + {
1.601 + if (!load_config(bio_err, req_conf))
1.602 + goto end;
1.603 + p=NCONF_get_string(req_conf,NULL,"oid_file");
1.604 + if (p == NULL)
1.605 + ERR_clear_error();
1.606 + if (p != NULL)
1.607 + {
1.608 + BIO *oid_bio;
1.609 +
1.610 + oid_bio=BIO_new_file(p,"r");
1.611 + if (oid_bio == NULL)
1.612 + {
1.613 + /*
1.614 + BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
1.615 + ERR_print_errors(bio_err);
1.616 + */
1.617 + }
1.618 + else
1.619 + {
1.620 + OBJ_create_objects(oid_bio);
1.621 + BIO_free(oid_bio);
1.622 + }
1.623 + }
1.624 + }
1.625 + if(!add_oid_section(bio_err, req_conf)) goto end;
1.626 +
1.627 + if (md_alg == NULL)
1.628 + {
1.629 + p=NCONF_get_string(req_conf,SECTION,"default_md");
1.630 + if (p == NULL)
1.631 + ERR_clear_error();
1.632 + if (p != NULL)
1.633 + {
1.634 + if ((md_alg=EVP_get_digestbyname(p)) != NULL)
1.635 + digest=md_alg;
1.636 + }
1.637 + }
1.638 +
1.639 + if (!extensions)
1.640 + {
1.641 + extensions = NCONF_get_string(req_conf, SECTION, V3_EXTENSIONS);
1.642 + if (!extensions)
1.643 + ERR_clear_error();
1.644 + }
1.645 + if (extensions) {
1.646 + /* Check syntax of file */
1.647 + X509V3_CTX ctx;
1.648 + X509V3_set_ctx_test(&ctx);
1.649 + X509V3_set_nconf(&ctx, req_conf);
1.650 + if(!X509V3_EXT_add_nconf(req_conf, &ctx, extensions, NULL)) {
1.651 + BIO_printf(bio_err,
1.652 + "Error Loading extension section %s\n", extensions);
1.653 + goto end;
1.654 + }
1.655 + }
1.656 +
1.657 + if(!passin)
1.658 + {
1.659 + passin = NCONF_get_string(req_conf, SECTION, "input_password");
1.660 + if (!passin)
1.661 + ERR_clear_error();
1.662 + }
1.663 +
1.664 + if(!passout)
1.665 + {
1.666 + passout = NCONF_get_string(req_conf, SECTION, "output_password");
1.667 + if (!passout)
1.668 + ERR_clear_error();
1.669 + }
1.670 +
1.671 + p = NCONF_get_string(req_conf, SECTION, STRING_MASK);
1.672 + if (!p)
1.673 + ERR_clear_error();
1.674 +
1.675 + if(p && !ASN1_STRING_set_default_mask_asc(p)) {
1.676 + BIO_printf(bio_err, "Invalid global string mask setting %s\n", p);
1.677 + goto end;
1.678 + }
1.679 +
1.680 + if (chtype != MBSTRING_UTF8)
1.681 + {
1.682 + p = NCONF_get_string(req_conf, SECTION, UTF8_IN);
1.683 + if (!p)
1.684 + ERR_clear_error();
1.685 + else if (!strcmp(p, "yes"))
1.686 + chtype = MBSTRING_UTF8;
1.687 + }
1.688 +
1.689 +
1.690 + if(!req_exts)
1.691 + {
1.692 + req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS);
1.693 + if (!req_exts)
1.694 + ERR_clear_error();
1.695 + }
1.696 + if(req_exts) {
1.697 + /* Check syntax of file */
1.698 + X509V3_CTX ctx;
1.699 + X509V3_set_ctx_test(&ctx);
1.700 + X509V3_set_nconf(&ctx, req_conf);
1.701 + if(!X509V3_EXT_add_nconf(req_conf, &ctx, req_exts, NULL)) {
1.702 + BIO_printf(bio_err,
1.703 + "Error Loading request extension section %s\n",
1.704 + req_exts);
1.705 + goto end;
1.706 + }
1.707 + }
1.708 +
1.709 + in=BIO_new(BIO_s_file());
1.710 + out=BIO_new(BIO_s_file());
1.711 + if ((in == NULL) || (out == NULL))
1.712 + goto end;
1.713 +
1.714 +#ifndef OPENSSL_NO_ENGINE
1.715 + e = setup_engine(bio_err, engine, 0);
1.716 +#endif
1.717 +
1.718 + if (keyfile != NULL)
1.719 + {
1.720 + pkey = load_key(bio_err, keyfile, keyform, 0, passin, e,
1.721 + "Private Key");
1.722 + if (!pkey)
1.723 + {
1.724 + /* load_key() has already printed an appropriate
1.725 + message */
1.726 + goto end;
1.727 + }
1.728 + if (EVP_PKEY_type(pkey->type) == EVP_PKEY_DSA ||
1.729 + EVP_PKEY_type(pkey->type) == EVP_PKEY_EC)
1.730 + {
1.731 + char *randfile = NCONF_get_string(req_conf,SECTION,"RANDFILE");
1.732 + if (randfile == NULL)
1.733 + ERR_clear_error();
1.734 + app_RAND_load_file(randfile, bio_err, 0);
1.735 + }
1.736 + }
1.737 +
1.738 + if (newreq && (pkey == NULL))
1.739 + {
1.740 +#ifndef OPENSSL_NO_RSA
1.741 + BN_GENCB cb;
1.742 +#endif
1.743 + char *randfile = NCONF_get_string(req_conf,SECTION,"RANDFILE");
1.744 + if (randfile == NULL)
1.745 + ERR_clear_error();
1.746 + app_RAND_load_file(randfile, bio_err, 0);
1.747 + if (inrand)
1.748 + app_RAND_load_files(inrand);
1.749 +
1.750 + if (newkey <= 0)
1.751 + {
1.752 + if (!NCONF_get_number(req_conf,SECTION,BITS, &newkey))
1.753 + newkey=DEFAULT_KEY_LENGTH;
1.754 + }
1.755 +
1.756 + if (newkey < MIN_KEY_LENGTH && (pkey_type == TYPE_RSA || pkey_type == TYPE_DSA))
1.757 + {
1.758 + BIO_printf(bio_err,"private key length is too short,\n");
1.759 + BIO_printf(bio_err,"it needs to be at least %d bits, not %ld\n",MIN_KEY_LENGTH,newkey);
1.760 + goto end;
1.761 + }
1.762 + BIO_printf(bio_err,"Generating a %ld bit %s private key\n",
1.763 + newkey,(pkey_type == TYPE_RSA)?"RSA":
1.764 + (pkey_type == TYPE_DSA)?"DSA":"EC");
1.765 +
1.766 + if ((pkey=EVP_PKEY_new()) == NULL) goto end;
1.767 +
1.768 +#ifndef OPENSSL_NO_RSA
1.769 + BN_GENCB_set(&cb, req_cb, bio_err);
1.770 + if (pkey_type == TYPE_RSA)
1.771 + {
1.772 + RSA *rsa = RSA_new();
1.773 + BIGNUM *bn = BN_new();
1.774 + if(!bn || !rsa || !BN_set_word(bn, 0x10001) ||
1.775 + !RSA_generate_key_ex(rsa, newkey, bn, &cb) ||
1.776 + !EVP_PKEY_assign_RSA(pkey, rsa))
1.777 + {
1.778 + if(bn) BN_free(bn);
1.779 + if(rsa) RSA_free(rsa);
1.780 + goto end;
1.781 + }
1.782 + BN_free(bn);
1.783 + }
1.784 + else
1.785 +#endif
1.786 +#ifndef OPENSSL_NO_DSA
1.787 + if (pkey_type == TYPE_DSA)
1.788 + {
1.789 + if (!DSA_generate_key(dsa_params)) goto end;
1.790 + if (!EVP_PKEY_assign_DSA(pkey,dsa_params)) goto end;
1.791 + dsa_params=NULL;
1.792 + }
1.793 +#endif
1.794 +#ifndef OPENSSL_NO_ECDSA
1.795 + if (pkey_type == TYPE_EC)
1.796 + {
1.797 + if (!EC_KEY_generate_key(ec_params)) goto end;
1.798 + if (!EVP_PKEY_assign_EC_KEY(pkey, ec_params))
1.799 + goto end;
1.800 + ec_params = NULL;
1.801 + }
1.802 +#endif
1.803 +
1.804 + app_RAND_write_file(randfile, bio_err);
1.805 +
1.806 + if (pkey == NULL) goto end;
1.807 +
1.808 + if (keyout == NULL)
1.809 + {
1.810 + keyout=NCONF_get_string(req_conf,SECTION,KEYFILE);
1.811 + if (keyout == NULL)
1.812 + ERR_clear_error();
1.813 + }
1.814 +
1.815 + if (keyout == NULL)
1.816 + {
1.817 + BIO_printf(bio_err,"writing new private key to stdout\n");
1.818 + BIO_set_fp(out,stdout,BIO_NOCLOSE);
1.819 +
1.820 +#ifdef OPENSSL_SYS_VMS
1.821 + {
1.822 + BIO *tmpbio = BIO_new(BIO_f_linebuffer());
1.823 + out = BIO_push(tmpbio, out);
1.824 + }
1.825 +#endif
1.826 + }
1.827 + else
1.828 + {
1.829 + BIO_printf(bio_err,"writing new private key to '%s'\n",keyout);
1.830 + if (BIO_write_filename(out,keyout) <= 0)
1.831 + {
1.832 + perror(keyout);
1.833 + goto end;
1.834 + }
1.835 + }
1.836 +
1.837 + p=NCONF_get_string(req_conf,SECTION,"encrypt_rsa_key");
1.838 + if (p == NULL)
1.839 + {
1.840 + ERR_clear_error();
1.841 + p=NCONF_get_string(req_conf,SECTION,"encrypt_key");
1.842 + if (p == NULL)
1.843 + ERR_clear_error();
1.844 + }
1.845 + if ((p != NULL) && (strcmp(p,"no") == 0))
1.846 + cipher=NULL;
1.847 + if (nodes) cipher=NULL;
1.848 +
1.849 + i=0;
1.850 +loop:
1.851 + if (!PEM_write_bio_PrivateKey(out,pkey,cipher,
1.852 + NULL,0,NULL,passout))
1.853 + {
1.854 + if ((ERR_GET_REASON(ERR_peek_error()) ==
1.855 + PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3))
1.856 + {
1.857 + ERR_clear_error();
1.858 + i++;
1.859 + goto loop;
1.860 + }
1.861 + goto end;
1.862 + }
1.863 + BIO_printf(bio_err,"-----\n");
1.864 + }
1.865 +
1.866 + if (!newreq)
1.867 + {
1.868 + /* Since we are using a pre-existing certificate
1.869 + * request, the kludge 'format' info should not be
1.870 + * changed. */
1.871 + kludge= -1;
1.872 + if (infile == NULL)
1.873 + BIO_set_fp(in,stdin,BIO_NOCLOSE);
1.874 +
1.875 + else
1.876 + {
1.877 + if (BIO_read_filename(in,infile) <= 0)
1.878 + {
1.879 + perror(infile);
1.880 + goto end;
1.881 + }
1.882 + }
1.883 +
1.884 + if (informat == FORMAT_ASN1)
1.885 + req=d2i_X509_REQ_bio(in,NULL);
1.886 + else if (informat == FORMAT_PEM)
1.887 + req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL);
1.888 + else
1.889 + {
1.890 + BIO_printf(bio_err,"bad input format specified for X509 request\n");
1.891 + goto end;
1.892 + }
1.893 + if (req == NULL)
1.894 + {
1.895 + BIO_printf(bio_err,"unable to load X509 request\n");
1.896 + goto end;
1.897 + }
1.898 + }
1.899 +
1.900 + if (newreq || x509)
1.901 + {
1.902 + if (pkey == NULL)
1.903 + {
1.904 + BIO_printf(bio_err,"you need to specify a private key\n");
1.905 + goto end;
1.906 + }
1.907 +#ifndef OPENSSL_NO_DSA
1.908 + if (pkey->type == EVP_PKEY_DSA)
1.909 + digest=EVP_dss1();
1.910 +#endif
1.911 +#ifndef OPENSSL_NO_ECDSA
1.912 + if (pkey->type == EVP_PKEY_EC)
1.913 + digest=EVP_ecdsa();
1.914 +#endif
1.915 + if (req == NULL)
1.916 + {
1.917 + req=X509_REQ_new();
1.918 + if (req == NULL)
1.919 + {
1.920 + goto end;
1.921 + }
1.922 +
1.923 + i=make_REQ(req,pkey,subj,multirdn,!x509, chtype);
1.924 + subj=NULL; /* done processing '-subj' option */
1.925 + if ((kludge > 0) && !sk_X509_ATTRIBUTE_num(req->req_info->attributes))
1.926 + {
1.927 + sk_X509_ATTRIBUTE_free(req->req_info->attributes);
1.928 + req->req_info->attributes = NULL;
1.929 + }
1.930 + if (!i)
1.931 + {
1.932 + BIO_printf(bio_err,"problems making Certificate Request\n");
1.933 + goto end;
1.934 + }
1.935 + }
1.936 + if (x509)
1.937 + {
1.938 + EVP_PKEY *tmppkey;
1.939 + X509V3_CTX ext_ctx;
1.940 + if ((x509ss=X509_new()) == NULL) goto end;
1.941 +
1.942 + /* Set version to V3 */
1.943 + if(extensions && !X509_set_version(x509ss, 2)) goto end;
1.944 + if (serial)
1.945 + {
1.946 + if (!X509_set_serialNumber(x509ss, serial)) goto end;
1.947 + }
1.948 + else
1.949 + {
1.950 + if (!rand_serial(NULL,
1.951 + X509_get_serialNumber(x509ss)))
1.952 + goto end;
1.953 + }
1.954 +
1.955 + if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req))) goto end;
1.956 + if (!X509_gmtime_adj(X509_get_notBefore(x509ss),0)) goto end;
1.957 + if (!X509_gmtime_adj(X509_get_notAfter(x509ss), (long)60*60*24*days)) goto end;
1.958 + if (!X509_set_subject_name(x509ss, X509_REQ_get_subject_name(req))) goto end;
1.959 + tmppkey = X509_REQ_get_pubkey(req);
1.960 + if (!tmppkey || !X509_set_pubkey(x509ss,tmppkey)) goto end;
1.961 + EVP_PKEY_free(tmppkey);
1.962 +
1.963 + /* Set up V3 context struct */
1.964 +
1.965 + X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0);
1.966 + X509V3_set_nconf(&ext_ctx, req_conf);
1.967 +
1.968 + /* Add extensions */
1.969 + if(extensions && !X509V3_EXT_add_nconf(req_conf,
1.970 + &ext_ctx, extensions, x509ss))
1.971 + {
1.972 + BIO_printf(bio_err,
1.973 + "Error Loading extension section %s\n",
1.974 + extensions);
1.975 + goto end;
1.976 + }
1.977 +
1.978 + if (!(i=X509_sign(x509ss,pkey,digest)))
1.979 + goto end;
1.980 + }
1.981 + else
1.982 + {
1.983 + X509V3_CTX ext_ctx;
1.984 +
1.985 + /* Set up V3 context struct */
1.986 +
1.987 + X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0);
1.988 + X509V3_set_nconf(&ext_ctx, req_conf);
1.989 +
1.990 + /* Add extensions */
1.991 + if(req_exts && !X509V3_EXT_REQ_add_nconf(req_conf,
1.992 + &ext_ctx, req_exts, req))
1.993 + {
1.994 + BIO_printf(bio_err,
1.995 + "Error Loading extension section %s\n",
1.996 + req_exts);
1.997 + goto end;
1.998 + }
1.999 + if (!(i=X509_REQ_sign(req,pkey,digest)))
1.1000 + goto end;
1.1001 + }
1.1002 + }
1.1003 +
1.1004 + if (subj && x509)
1.1005 + {
1.1006 + BIO_printf(bio_err, "Cannot modifiy certificate subject\n");
1.1007 + goto end;
1.1008 + }
1.1009 +
1.1010 + if (subj && !x509)
1.1011 + {
1.1012 + if (verbose)
1.1013 + {
1.1014 + BIO_printf(bio_err, "Modifying Request's Subject\n");
1.1015 + print_name(bio_err, "old subject=", X509_REQ_get_subject_name(req), nmflag);
1.1016 + }
1.1017 +
1.1018 + if (build_subject(req, subj, chtype, multirdn) == 0)
1.1019 + {
1.1020 + BIO_printf(bio_err, "ERROR: cannot modify subject\n");
1.1021 + ex=1;
1.1022 + goto end;
1.1023 + }
1.1024 +
1.1025 + req->req_info->enc.modified = 1;
1.1026 +
1.1027 + if (verbose)
1.1028 + {
1.1029 + print_name(bio_err, "new subject=", X509_REQ_get_subject_name(req), nmflag);
1.1030 + }
1.1031 + }
1.1032 +
1.1033 + if (verify && !x509)
1.1034 + {
1.1035 + int tmp=0;
1.1036 +
1.1037 + if (pkey == NULL)
1.1038 + {
1.1039 + pkey=X509_REQ_get_pubkey(req);
1.1040 + tmp=1;
1.1041 + if (pkey == NULL) goto end;
1.1042 + }
1.1043 +
1.1044 + i=X509_REQ_verify(req,pkey);
1.1045 + if (tmp) {
1.1046 + EVP_PKEY_free(pkey);
1.1047 + pkey=NULL;
1.1048 + }
1.1049 +
1.1050 + if (i < 0)
1.1051 + {
1.1052 + goto end;
1.1053 + }
1.1054 + else if (i == 0)
1.1055 + {
1.1056 + BIO_printf(bio_err,"verify failure\n");
1.1057 + ERR_print_errors(bio_err);
1.1058 + }
1.1059 + else /* if (i > 0) */
1.1060 + BIO_printf(bio_err,"verify OK\n");
1.1061 + }
1.1062 +
1.1063 + if (noout && !text && !modulus && !subject && !pubkey)
1.1064 + {
1.1065 + ex=0;
1.1066 + goto end;
1.1067 + }
1.1068 +
1.1069 + if (outfile == NULL)
1.1070 + {
1.1071 + BIO_set_fp(out,stdout,BIO_NOCLOSE);
1.1072 +#ifdef OPENSSL_SYS_VMS
1.1073 + {
1.1074 + BIO *tmpbio = BIO_new(BIO_f_linebuffer());
1.1075 + out = BIO_push(tmpbio, out);
1.1076 + }
1.1077 +#endif
1.1078 + }
1.1079 + else
1.1080 + {
1.1081 + if ((keyout != NULL) && (strcmp(outfile,keyout) == 0))
1.1082 + i=(int)BIO_append_filename(out,outfile);
1.1083 + else
1.1084 + i=(int)BIO_write_filename(out,outfile);
1.1085 + if (!i)
1.1086 + {
1.1087 + perror(outfile);
1.1088 + goto end;
1.1089 + }
1.1090 + }
1.1091 +
1.1092 + if (pubkey)
1.1093 + {
1.1094 + EVP_PKEY *tpubkey;
1.1095 + tpubkey=X509_REQ_get_pubkey(req);
1.1096 + if (tpubkey == NULL)
1.1097 + {
1.1098 + BIO_printf(bio_err,"Error getting public key\n");
1.1099 + ERR_print_errors(bio_err);
1.1100 + goto end;
1.1101 + }
1.1102 + PEM_write_bio_PUBKEY(out, tpubkey);
1.1103 + EVP_PKEY_free(tpubkey);
1.1104 + }
1.1105 +
1.1106 + if (text)
1.1107 + {
1.1108 + if (x509)
1.1109 + X509_print_ex(out, x509ss, nmflag, reqflag);
1.1110 + else
1.1111 + X509_REQ_print_ex(out, req, nmflag, reqflag);
1.1112 + }
1.1113 +
1.1114 + if(subject)
1.1115 + {
1.1116 + if(x509)
1.1117 + print_name(out, "subject=", X509_get_subject_name(x509ss), nmflag);
1.1118 + else
1.1119 + print_name(out, "subject=", X509_REQ_get_subject_name(req), nmflag);
1.1120 + }
1.1121 +
1.1122 + if (modulus)
1.1123 + {
1.1124 + EVP_PKEY *tpubkey;
1.1125 +
1.1126 + if (x509)
1.1127 + tpubkey=X509_get_pubkey(x509ss);
1.1128 + else
1.1129 + tpubkey=X509_REQ_get_pubkey(req);
1.1130 + if (tpubkey == NULL)
1.1131 + {
1.1132 + fprintf(stdout,"Modulus=unavailable\n");
1.1133 + goto end;
1.1134 + }
1.1135 +
1.1136 + fprintf(stdout,"Modulus=");
1.1137 +
1.1138 +#ifndef OPENSSL_NO_RSA
1.1139 + if (tpubkey->type == EVP_PKEY_RSA)
1.1140 + BN_print(out,tpubkey->pkey.rsa->n);
1.1141 + else
1.1142 +#endif
1.1143 + fprintf(stdout,"Wrong Algorithm type");
1.1144 + EVP_PKEY_free(tpubkey);
1.1145 + fprintf(stdout,"\n");
1.1146 +
1.1147 + }
1.1148 +
1.1149 + if (!noout && !x509)
1.1150 + {
1.1151 + if (outformat == FORMAT_ASN1)
1.1152 + i=i2d_X509_REQ_bio(out,req);
1.1153 + else if (outformat == FORMAT_PEM) {
1.1154 + if(newhdr) i=PEM_write_bio_X509_REQ_NEW(out,req);
1.1155 + else i=PEM_write_bio_X509_REQ(out,req);
1.1156 + } else {
1.1157 + BIO_printf(bio_err,"bad output format specified for outfile\n");
1.1158 + goto end;
1.1159 + }
1.1160 + if (!i)
1.1161 + {
1.1162 + BIO_printf(bio_err,"unable to write X509 request\n");
1.1163 + goto end;
1.1164 + }
1.1165 + }
1.1166 + if (!noout && x509 && (x509ss != NULL))
1.1167 + {
1.1168 + if (outformat == FORMAT_ASN1)
1.1169 + i=i2d_X509_bio(out,x509ss);
1.1170 + else if (outformat == FORMAT_PEM)
1.1171 + i=PEM_write_bio_X509(out,x509ss);
1.1172 + else {
1.1173 + BIO_printf(bio_err,"bad output format specified for outfile\n");
1.1174 + goto end;
1.1175 + }
1.1176 + if (!i)
1.1177 + {
1.1178 + BIO_printf(bio_err,"unable to write X509 certificate\n");
1.1179 + goto end;
1.1180 + }
1.1181 + }
1.1182 + ex=0;
1.1183 +end:
1.1184 +#ifndef MONOLITH
1.1185 + if(to_free)
1.1186 + OPENSSL_free(to_free);
1.1187 +#endif
1.1188 + if (ex)
1.1189 + {
1.1190 + ERR_print_errors(bio_err);
1.1191 + }
1.1192 + if ((req_conf != NULL) && (req_conf != config)) NCONF_free(req_conf);
1.1193 + BIO_free(in);
1.1194 + BIO_free_all(out);
1.1195 + EVP_PKEY_free(pkey);
1.1196 + X509_REQ_free(req);
1.1197 + X509_free(x509ss);
1.1198 + ASN1_INTEGER_free(serial);
1.1199 + if(passargin && passin) OPENSSL_free(passin);
1.1200 + if(passargout && passout) OPENSSL_free(passout);
1.1201 + OBJ_cleanup();
1.1202 +#ifndef OPENSSL_NO_DSA
1.1203 + if (dsa_params != NULL) DSA_free(dsa_params);
1.1204 +#endif
1.1205 +#ifndef OPENSSL_NO_ECDSA
1.1206 + if (ec_params != NULL) EC_KEY_free(ec_params);
1.1207 +#endif
1.1208 + apps_shutdown();
1.1209 + OPENSSL_EXIT(ex);
1.1210 + }
1.1211 +
1.1212 +static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn,
1.1213 + int attribs, unsigned long chtype)
1.1214 + {
1.1215 + int ret=0,i;
1.1216 + char no_prompt = 0;
1.1217 + STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL;
1.1218 + char *tmp, *dn_sect,*attr_sect;
1.1219 +
1.1220 + tmp=NCONF_get_string(req_conf,SECTION,PROMPT);
1.1221 + if (tmp == NULL)
1.1222 + ERR_clear_error();
1.1223 + if((tmp != NULL) && !strcmp(tmp, "no")) no_prompt = 1;
1.1224 +
1.1225 + dn_sect=NCONF_get_string(req_conf,SECTION,DISTINGUISHED_NAME);
1.1226 + if (dn_sect == NULL)
1.1227 + {
1.1228 + BIO_printf(bio_err,"unable to find '%s' in config\n",
1.1229 + DISTINGUISHED_NAME);
1.1230 + goto err;
1.1231 + }
1.1232 + dn_sk=NCONF_get_section(req_conf,dn_sect);
1.1233 + if (dn_sk == NULL)
1.1234 + {
1.1235 + BIO_printf(bio_err,"unable to get '%s' section\n",dn_sect);
1.1236 + goto err;
1.1237 + }
1.1238 +
1.1239 + attr_sect=NCONF_get_string(req_conf,SECTION,ATTRIBUTES);
1.1240 + if (attr_sect == NULL)
1.1241 + {
1.1242 + ERR_clear_error();
1.1243 + attr_sk=NULL;
1.1244 + }
1.1245 + else
1.1246 + {
1.1247 + attr_sk=NCONF_get_section(req_conf,attr_sect);
1.1248 + if (attr_sk == NULL)
1.1249 + {
1.1250 + BIO_printf(bio_err,"unable to get '%s' section\n",attr_sect);
1.1251 + goto err;
1.1252 + }
1.1253 + }
1.1254 +
1.1255 + /* setup version number */
1.1256 + if (!X509_REQ_set_version(req,0L)) goto err; /* version 1 */
1.1257 +
1.1258 + if (no_prompt)
1.1259 + i = auto_info(req, dn_sk, attr_sk, attribs, chtype);
1.1260 + else
1.1261 + {
1.1262 + if (subj)
1.1263 + i = build_subject(req, subj, chtype, multirdn);
1.1264 + else
1.1265 + i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs, chtype);
1.1266 + }
1.1267 + if(!i) goto err;
1.1268 +
1.1269 + if (!X509_REQ_set_pubkey(req,pkey)) goto err;
1.1270 +
1.1271 + ret=1;
1.1272 +err:
1.1273 + return(ret);
1.1274 + }
1.1275 +
1.1276 +/*
1.1277 + * subject is expected to be in the format /type0=value0/type1=value1/type2=...
1.1278 + * where characters may be escaped by \
1.1279 + */
1.1280 +static int build_subject(X509_REQ *req, char *subject, unsigned long chtype, int multirdn)
1.1281 + {
1.1282 + X509_NAME *n;
1.1283 +
1.1284 + if (!(n = parse_name(subject, chtype, multirdn)))
1.1285 + return 0;
1.1286 +
1.1287 + if (!X509_REQ_set_subject_name(req, n))
1.1288 + {
1.1289 + X509_NAME_free(n);
1.1290 + return 0;
1.1291 + }
1.1292 + X509_NAME_free(n);
1.1293 + return 1;
1.1294 +}
1.1295 +
1.1296 +
1.1297 +static int prompt_info(X509_REQ *req,
1.1298 + STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect,
1.1299 + STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs,
1.1300 + unsigned long chtype)
1.1301 + {
1.1302 + int i;
1.1303 + char *p,*q;
1.1304 + char buf[100];
1.1305 + int nid, mval;
1.1306 + long n_min,n_max;
1.1307 + char *type, *value;
1.1308 + const char *def;
1.1309 + CONF_VALUE *v;
1.1310 + X509_NAME *subj;
1.1311 + subj = X509_REQ_get_subject_name(req);
1.1312 +
1.1313 + if(!batch)
1.1314 + {
1.1315 + BIO_printf(bio_err,"You are about to be asked to enter information that will be incorporated\n");
1.1316 + BIO_printf(bio_err,"into your certificate request.\n");
1.1317 + BIO_printf(bio_err,"What you are about to enter is what is called a Distinguished Name or a DN.\n");
1.1318 + BIO_printf(bio_err,"There are quite a few fields but you can leave some blank\n");
1.1319 + BIO_printf(bio_err,"For some fields there will be a default value,\n");
1.1320 + BIO_printf(bio_err,"If you enter '.', the field will be left blank.\n");
1.1321 + BIO_printf(bio_err,"-----\n");
1.1322 + }
1.1323 +
1.1324 +
1.1325 + if (sk_CONF_VALUE_num(dn_sk))
1.1326 + {
1.1327 + i= -1;
1.1328 +start: for (;;)
1.1329 + {
1.1330 + i++;
1.1331 + if (sk_CONF_VALUE_num(dn_sk) <= i) break;
1.1332 +
1.1333 + v=sk_CONF_VALUE_value(dn_sk,i);
1.1334 + p=q=NULL;
1.1335 + type=v->name;
1.1336 + if(!check_end(type,"_min") || !check_end(type,"_max") ||
1.1337 + !check_end(type,"_default") ||
1.1338 + !check_end(type,"_value")) continue;
1.1339 + /* Skip past any leading X. X: X, etc to allow for
1.1340 + * multiple instances
1.1341 + */
1.1342 + for(p = v->name; *p ; p++)
1.1343 + if ((*p == ':') || (*p == ',') ||
1.1344 + (*p == '.')) {
1.1345 + p++;
1.1346 + if(*p) type = p;
1.1347 + break;
1.1348 + }
1.1349 + if (*type == '+')
1.1350 + {
1.1351 + mval = -1;
1.1352 + type++;
1.1353 + }
1.1354 + else
1.1355 + mval = 0;
1.1356 + /* If OBJ not recognised ignore it */
1.1357 + if ((nid=OBJ_txt2nid(type)) == NID_undef) goto start;
1.1358 + if (BIO_snprintf(buf,sizeof buf,"%s_default",v->name)
1.1359 + >= (int)sizeof(buf))
1.1360 + {
1.1361 + BIO_printf(bio_err,"Name '%s' too long\n",v->name);
1.1362 + return 0;
1.1363 + }
1.1364 +
1.1365 + if ((def=NCONF_get_string(req_conf,dn_sect,buf)) == NULL)
1.1366 + {
1.1367 + ERR_clear_error();
1.1368 + def="";
1.1369 + }
1.1370 +
1.1371 + BIO_snprintf(buf,sizeof buf,"%s_value",v->name);
1.1372 + if ((value=NCONF_get_string(req_conf,dn_sect,buf)) == NULL)
1.1373 + {
1.1374 + ERR_clear_error();
1.1375 + value=NULL;
1.1376 + }
1.1377 +
1.1378 + BIO_snprintf(buf,sizeof buf,"%s_min",v->name);
1.1379 + if (!NCONF_get_number(req_conf,dn_sect,buf, &n_min))
1.1380 + {
1.1381 + ERR_clear_error();
1.1382 + n_min = -1;
1.1383 + }
1.1384 +
1.1385 + BIO_snprintf(buf,sizeof buf,"%s_max",v->name);
1.1386 + if (!NCONF_get_number(req_conf,dn_sect,buf, &n_max))
1.1387 + {
1.1388 + ERR_clear_error();
1.1389 + n_max = -1;
1.1390 + }
1.1391 +
1.1392 + if (!add_DN_object(subj,v->value,def,value,nid,
1.1393 + n_min,n_max, chtype, mval))
1.1394 + return 0;
1.1395 + }
1.1396 + if (X509_NAME_entry_count(subj) == 0)
1.1397 + {
1.1398 + BIO_printf(bio_err,"error, no objects specified in config file\n");
1.1399 + return 0;
1.1400 + }
1.1401 +
1.1402 + if (attribs)
1.1403 + {
1.1404 + if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0) && (!batch))
1.1405 + {
1.1406 + BIO_printf(bio_err,"\nPlease enter the following 'extra' attributes\n");
1.1407 + BIO_printf(bio_err,"to be sent with your certificate request\n");
1.1408 + }
1.1409 +
1.1410 + i= -1;
1.1411 +start2: for (;;)
1.1412 + {
1.1413 + i++;
1.1414 + if ((attr_sk == NULL) ||
1.1415 + (sk_CONF_VALUE_num(attr_sk) <= i))
1.1416 + break;
1.1417 +
1.1418 + v=sk_CONF_VALUE_value(attr_sk,i);
1.1419 + type=v->name;
1.1420 + if ((nid=OBJ_txt2nid(type)) == NID_undef)
1.1421 + goto start2;
1.1422 +
1.1423 + if (BIO_snprintf(buf,sizeof buf,"%s_default",type)
1.1424 + >= (int)sizeof(buf))
1.1425 + {
1.1426 + BIO_printf(bio_err,"Name '%s' too long\n",v->name);
1.1427 + return 0;
1.1428 + }
1.1429 +
1.1430 + if ((def=NCONF_get_string(req_conf,attr_sect,buf))
1.1431 + == NULL)
1.1432 + {
1.1433 + ERR_clear_error();
1.1434 + def="";
1.1435 + }
1.1436 +
1.1437 +
1.1438 + BIO_snprintf(buf,sizeof buf,"%s_value",type);
1.1439 + if ((value=NCONF_get_string(req_conf,attr_sect,buf))
1.1440 + == NULL)
1.1441 + {
1.1442 + ERR_clear_error();
1.1443 + value=NULL;
1.1444 + }
1.1445 +
1.1446 + BIO_snprintf(buf,sizeof buf,"%s_min",type);
1.1447 + if (!NCONF_get_number(req_conf,attr_sect,buf, &n_min))
1.1448 + n_min = -1;
1.1449 +
1.1450 + BIO_snprintf(buf,sizeof buf,"%s_max",type);
1.1451 + if (!NCONF_get_number(req_conf,attr_sect,buf, &n_max))
1.1452 + n_max = -1;
1.1453 +
1.1454 + if (!add_attribute_object(req,
1.1455 + v->value,def,value,nid,n_min,n_max, chtype))
1.1456 + return 0;
1.1457 + }
1.1458 + }
1.1459 + }
1.1460 + else
1.1461 + {
1.1462 + BIO_printf(bio_err,"No template, please set one up.\n");
1.1463 + return 0;
1.1464 + }
1.1465 +
1.1466 + return 1;
1.1467 +
1.1468 + }
1.1469 +
1.1470 +static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk,
1.1471 + STACK_OF(CONF_VALUE) *attr_sk, int attribs, unsigned long chtype)
1.1472 + {
1.1473 + int i;
1.1474 + char *p,*q;
1.1475 + char *type;
1.1476 + CONF_VALUE *v;
1.1477 + X509_NAME *subj;
1.1478 +
1.1479 + subj = X509_REQ_get_subject_name(req);
1.1480 +
1.1481 + for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++)
1.1482 + {
1.1483 + int mval;
1.1484 + v=sk_CONF_VALUE_value(dn_sk,i);
1.1485 + p=q=NULL;
1.1486 + type=v->name;
1.1487 + /* Skip past any leading X. X: X, etc to allow for
1.1488 + * multiple instances
1.1489 + */
1.1490 + for(p = v->name; *p ; p++)
1.1491 +#ifndef CHARSET_EBCDIC
1.1492 + if ((*p == ':') || (*p == ',') || (*p == '.')) {
1.1493 +#else
1.1494 + if ((*p == os_toascii[':']) || (*p == os_toascii[',']) || (*p == os_toascii['.'])) {
1.1495 +#endif
1.1496 + p++;
1.1497 + if(*p) type = p;
1.1498 + break;
1.1499 + }
1.1500 +#ifndef CHARSET_EBCDIC
1.1501 + if (*p == '+')
1.1502 +#else
1.1503 + if (*p == os_toascii['+'])
1.1504 +#endif
1.1505 + {
1.1506 + p++;
1.1507 + mval = -1;
1.1508 + }
1.1509 + else
1.1510 + mval = 0;
1.1511 + if (!X509_NAME_add_entry_by_txt(subj,type, chtype,
1.1512 + (unsigned char *) v->value,-1,-1,mval)) return 0;
1.1513 +
1.1514 + }
1.1515 +
1.1516 + if (!X509_NAME_entry_count(subj))
1.1517 + {
1.1518 + BIO_printf(bio_err,"error, no objects specified in config file\n");
1.1519 + return 0;
1.1520 + }
1.1521 + if (attribs)
1.1522 + {
1.1523 + for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++)
1.1524 + {
1.1525 + v=sk_CONF_VALUE_value(attr_sk,i);
1.1526 + if(!X509_REQ_add1_attr_by_txt(req, v->name, chtype,
1.1527 + (unsigned char *)v->value, -1)) return 0;
1.1528 + }
1.1529 + }
1.1530 + return 1;
1.1531 + }
1.1532 +
1.1533 +
1.1534 +static int add_DN_object(X509_NAME *n, char *text, const char *def, char *value,
1.1535 + int nid, int n_min, int n_max, unsigned long chtype, int mval)
1.1536 + {
1.1537 + int i,ret=0;
1.1538 + MS_STATIC char buf[1024];
1.1539 +start:
1.1540 + if (!batch) BIO_printf(bio_err,"%s [%s]:",text,def);
1.1541 + (void)BIO_flush(bio_err);
1.1542 + if(value != NULL)
1.1543 + {
1.1544 + BUF_strlcpy(buf,value,sizeof buf);
1.1545 + BUF_strlcat(buf,"\n",sizeof buf);
1.1546 + BIO_printf(bio_err,"%s\n",value);
1.1547 + }
1.1548 + else
1.1549 + {
1.1550 + buf[0]='\0';
1.1551 + if (!batch)
1.1552 + {
1.1553 + fgets(buf,sizeof buf,stdin);
1.1554 + }
1.1555 + else
1.1556 + {
1.1557 + buf[0] = '\n';
1.1558 + buf[1] = '\0';
1.1559 + }
1.1560 + }
1.1561 +
1.1562 + if (buf[0] == '\0') return(0);
1.1563 + else if (buf[0] == '\n')
1.1564 + {
1.1565 + if ((def == NULL) || (def[0] == '\0'))
1.1566 + return(1);
1.1567 + BUF_strlcpy(buf,def,sizeof buf);
1.1568 + BUF_strlcat(buf,"\n",sizeof buf);
1.1569 + }
1.1570 + else if ((buf[0] == '.') && (buf[1] == '\n')) return(1);
1.1571 +
1.1572 + i=strlen(buf);
1.1573 + if (buf[i-1] != '\n')
1.1574 + {
1.1575 + BIO_printf(bio_err,"weird input :-(\n");
1.1576 + return(0);
1.1577 + }
1.1578 + buf[--i]='\0';
1.1579 +#ifdef CHARSET_EBCDIC
1.1580 + ebcdic2ascii(buf, buf, i);
1.1581 +#endif
1.1582 + if(!req_check_len(i, n_min, n_max)) goto start;
1.1583 + if (!X509_NAME_add_entry_by_NID(n,nid, chtype,
1.1584 + (unsigned char *) buf, -1,-1,mval)) goto err;
1.1585 + ret=1;
1.1586 +err:
1.1587 + return(ret);
1.1588 + }
1.1589 +
1.1590 +static int add_attribute_object(X509_REQ *req, char *text, const char *def,
1.1591 + char *value, int nid, int n_min,
1.1592 + int n_max, unsigned long chtype)
1.1593 + {
1.1594 + int i;
1.1595 + static char buf[1024];
1.1596 +
1.1597 +start:
1.1598 + if (!batch) BIO_printf(bio_err,"%s [%s]:",text,def);
1.1599 + (void)BIO_flush(bio_err);
1.1600 + if (value != NULL)
1.1601 + {
1.1602 + BUF_strlcpy(buf,value,sizeof buf);
1.1603 + BUF_strlcat(buf,"\n",sizeof buf);
1.1604 + BIO_printf(bio_err,"%s\n",value);
1.1605 + }
1.1606 + else
1.1607 + {
1.1608 + buf[0]='\0';
1.1609 + if (!batch)
1.1610 + {
1.1611 + fgets(buf,sizeof buf,stdin);
1.1612 + }
1.1613 + else
1.1614 + {
1.1615 + buf[0] = '\n';
1.1616 + buf[1] = '\0';
1.1617 + }
1.1618 + }
1.1619 +
1.1620 + if (buf[0] == '\0') return(0);
1.1621 + else if (buf[0] == '\n')
1.1622 + {
1.1623 + if ((def == NULL) || (def[0] == '\0'))
1.1624 + return(1);
1.1625 + BUF_strlcpy(buf,def,sizeof buf);
1.1626 + BUF_strlcat(buf,"\n",sizeof buf);
1.1627 + }
1.1628 + else if ((buf[0] == '.') && (buf[1] == '\n')) return(1);
1.1629 +
1.1630 + i=strlen(buf);
1.1631 + if (buf[i-1] != '\n')
1.1632 + {
1.1633 + BIO_printf(bio_err,"weird input :-(\n");
1.1634 + return(0);
1.1635 + }
1.1636 + buf[--i]='\0';
1.1637 +#ifdef CHARSET_EBCDIC
1.1638 + ebcdic2ascii(buf, buf, i);
1.1639 +#endif
1.1640 + if(!req_check_len(i, n_min, n_max)) goto start;
1.1641 +
1.1642 + if(!X509_REQ_add1_attr_by_NID(req, nid, chtype,
1.1643 + (unsigned char *)buf, -1)) {
1.1644 + BIO_printf(bio_err, "Error adding attribute\n");
1.1645 + ERR_print_errors(bio_err);
1.1646 + goto err;
1.1647 + }
1.1648 +
1.1649 + return(1);
1.1650 +err:
1.1651 + return(0);
1.1652 + }
1.1653 +
1.1654 +#ifndef OPENSSL_NO_RSA
1.1655 +static int MS_CALLBACK req_cb(int p, int n, BN_GENCB *cb)
1.1656 + {
1.1657 + char c='*';
1.1658 +
1.1659 + if (p == 0) c='.';
1.1660 + if (p == 1) c='+';
1.1661 + if (p == 2) c='*';
1.1662 + if (p == 3) c='\n';
1.1663 + BIO_write(cb->arg,&c,1);
1.1664 + (void)BIO_flush(cb->arg);
1.1665 +#ifdef LINT
1.1666 + p=n;
1.1667 +#endif
1.1668 + return 1;
1.1669 + }
1.1670 +#endif
1.1671 +
1.1672 +static int req_check_len(int len, int n_min, int n_max)
1.1673 + {
1.1674 + if ((n_min > 0) && (len < n_min))
1.1675 + {
1.1676 + BIO_printf(bio_err,"string is too short, it needs to be at least %d bytes long\n",n_min);
1.1677 + return(0);
1.1678 + }
1.1679 + if ((n_max >= 0) && (len > n_max))
1.1680 + {
1.1681 + BIO_printf(bio_err,"string is too long, it needs to be less than %d bytes long\n",n_max);
1.1682 + return(0);
1.1683 + }
1.1684 + return(1);
1.1685 + }
1.1686 +
1.1687 +/* Check if the end of a string matches 'end' */
1.1688 +static int check_end(const char *str, const char *end)
1.1689 +{
1.1690 + int elen, slen;
1.1691 + const char *tmp;
1.1692 + elen = strlen(end);
1.1693 + slen = strlen(str);
1.1694 + if(elen > slen) return 1;
1.1695 + tmp = str + slen - elen;
1.1696 + return strcmp(tmp, end);
1.1697 +}