155714Skris/* apps/req.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 8296465Sdelphij * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15296465Sdelphij * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 22296465Sdelphij * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 37296465Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40296465Sdelphij * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 52296465Sdelphij * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 5855714Skris 59296465Sdelphij/* 60296465Sdelphij * Until the key-gen callbacks are modified to use newer prototypes, we allow 61296465Sdelphij * deprecated functions for openssl-internal code 62296465Sdelphij */ 63160814Ssimon#ifdef OPENSSL_NO_DEPRECATED 64296465Sdelphij# undef OPENSSL_NO_DEPRECATED 65160814Ssimon#endif 66160814Ssimon 6755714Skris#include <stdio.h> 6855714Skris#include <stdlib.h> 6955714Skris#include <time.h> 7055714Skris#include <string.h> 71109998Smarkm#ifdef OPENSSL_NO_STDIO 72296465Sdelphij# define APPS_WIN16 7355714Skris#endif 7455714Skris#include "apps.h" 7555714Skris#include <openssl/bio.h> 7655714Skris#include <openssl/evp.h> 7755714Skris#include <openssl/conf.h> 7855714Skris#include <openssl/err.h> 7955714Skris#include <openssl/asn1.h> 8055714Skris#include <openssl/x509.h> 8155714Skris#include <openssl/x509v3.h> 8255714Skris#include <openssl/objects.h> 8355714Skris#include <openssl/pem.h> 84160814Ssimon#include <openssl/bn.h> 85160814Ssimon#ifndef OPENSSL_NO_RSA 86296465Sdelphij# include <openssl/rsa.h> 87160814Ssimon#endif 88160814Ssimon#ifndef OPENSSL_NO_DSA 89296465Sdelphij# include <openssl/dsa.h> 90160814Ssimon#endif 9155714Skris 92296465Sdelphij#define SECTION "req" 9355714Skris 94296465Sdelphij#define BITS "default_bits" 95296465Sdelphij#define KEYFILE "default_keyfile" 96296465Sdelphij#define PROMPT "prompt" 97296465Sdelphij#define DISTINGUISHED_NAME "distinguished_name" 98296465Sdelphij#define ATTRIBUTES "attributes" 99296465Sdelphij#define V3_EXTENSIONS "x509_extensions" 100296465Sdelphij#define REQ_EXTENSIONS "req_extensions" 101296465Sdelphij#define STRING_MASK "string_mask" 102296465Sdelphij#define UTF8_IN "utf8" 10355714Skris 104296465Sdelphij#define DEFAULT_KEY_LENGTH 512 105296465Sdelphij#define MIN_KEY_LENGTH 384 10655714Skris 10755714Skris#undef PROG 108296465Sdelphij#define PROG req_main 10955714Skris 110296465Sdelphij/*- 111296465Sdelphij * -inform arg - input format - default PEM (DER or PEM) 11255714Skris * -outform arg - output format - default PEM 113296465Sdelphij * -in arg - input file - default stdin 114296465Sdelphij * -out arg - output file - default stdout 115296465Sdelphij * -verify - check request signature 116296465Sdelphij * -noout - don't print stuff out. 117296465Sdelphij * -text - print out human readable text. 118296465Sdelphij * -nodes - no des encryption 119296465Sdelphij * -config file - Load configuration file. 120296465Sdelphij * -key file - make a request using key in file (or use it for verification). 121296465Sdelphij * -keyform arg - key file format. 12268651Skris * -rand file(s) - load the file(s) into the PRNG. 123296465Sdelphij * -newkey - make a key and a request. 124296465Sdelphij * -modulus - print RSA modulus. 125296465Sdelphij * -pubkey - output Public Key. 126296465Sdelphij * -x509 - output a self signed X509 structure instead. 127296465Sdelphij * -asn1-kludge - output new certificate request in a format that some CA's 128296465Sdelphij * require. This format is wrong 12955714Skris */ 13055714Skris 131296465Sdelphijstatic int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *dn, int mutlirdn, 132296465Sdelphij int attribs, unsigned long chtype); 133160814Ssimonstatic int build_subject(X509_REQ *req, char *subj, unsigned long chtype, 134296465Sdelphij int multirdn); 13559191Skrisstatic int prompt_info(X509_REQ *req, 136296465Sdelphij STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect, 137296465Sdelphij STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, 138296465Sdelphij int attribs, unsigned long chtype); 13959191Skrisstatic int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *sk, 140296465Sdelphij STACK_OF(CONF_VALUE) *attr, int attribs, 141296465Sdelphij unsigned long chtype); 142160814Ssimonstatic int add_attribute_object(X509_REQ *req, char *text, const char *def, 143296465Sdelphij char *value, int nid, int n_min, int n_max, 144296465Sdelphij unsigned long chtype); 145296465Sdelphijstatic int add_DN_object(X509_NAME *n, char *text, const char *def, 146296465Sdelphij char *value, int nid, int n_min, int n_max, 147296465Sdelphij unsigned long chtype, int mval); 148109998Smarkm#ifndef OPENSSL_NO_RSA 149160814Ssimonstatic int MS_CALLBACK req_cb(int p, int n, BN_GENCB *cb); 15059191Skris#endif 151296465Sdelphijstatic int req_check_len(int len, int n_min, int n_max); 152160814Ssimonstatic int check_end(const char *str, const char *end); 15355714Skris#ifndef MONOLITH 154296465Sdelphijstatic char *default_config_file = NULL; 15555714Skris#endif 156296465Sdelphijstatic CONF *req_conf = NULL; 157296465Sdelphijstatic int batch = 0; 15855714Skris 159296465Sdelphij#define TYPE_RSA 1 160296465Sdelphij#define TYPE_DSA 2 161296465Sdelphij#define TYPE_DH 3 162296465Sdelphij#define TYPE_EC 4 16355714Skris 16459191Skrisint MAIN(int, char **); 16559191Skris 16655714Skrisint MAIN(int argc, char **argv) 167296465Sdelphij{ 168296465Sdelphij ENGINE *e = NULL; 169109998Smarkm#ifndef OPENSSL_NO_DSA 170296465Sdelphij DSA *dsa_params = NULL; 17155714Skris#endif 172160814Ssimon#ifndef OPENSSL_NO_ECDSA 173296465Sdelphij EC_KEY *ec_params = NULL; 174160814Ssimon#endif 175296465Sdelphij unsigned long nmflag = 0, reqflag = 0; 176296465Sdelphij int ex = 1, x509 = 0, days = 30; 177296465Sdelphij X509 *x509ss = NULL; 178296465Sdelphij X509_REQ *req = NULL; 179296465Sdelphij EVP_PKEY *pkey = NULL; 180296465Sdelphij int i = 0, badops = 0, newreq = 0, verbose = 0, pkey_type = TYPE_RSA; 181296465Sdelphij long newkey = -1; 182296465Sdelphij BIO *in = NULL, *out = NULL; 183296465Sdelphij int informat, outformat, verify = 0, noout = 0, text = 0, keyform = 184296465Sdelphij FORMAT_PEM; 185296465Sdelphij int nodes = 0, kludge = 0, newhdr = 0, subject = 0, pubkey = 0; 186296465Sdelphij char *infile, *outfile, *prog, *keyfile = NULL, *template = 187296465Sdelphij NULL, *keyout = NULL; 188111147Snectar#ifndef OPENSSL_NO_ENGINE 189296465Sdelphij char *engine = NULL; 190111147Snectar#endif 191296465Sdelphij char *extensions = NULL; 192296465Sdelphij char *req_exts = NULL; 193296465Sdelphij const EVP_CIPHER *cipher = NULL; 194296465Sdelphij ASN1_INTEGER *serial = NULL; 195296465Sdelphij int modulus = 0; 196296465Sdelphij char *inrand = NULL; 197296465Sdelphij char *passargin = NULL, *passargout = NULL; 198296465Sdelphij char *passin = NULL, *passout = NULL; 199296465Sdelphij char *p; 200296465Sdelphij char *subj = NULL; 201296465Sdelphij int multirdn = 0; 202296465Sdelphij const EVP_MD *md_alg = NULL, *digest = EVP_sha1(); 203296465Sdelphij unsigned long chtype = MBSTRING_ASC; 20455714Skris#ifndef MONOLITH 205296465Sdelphij char *to_free; 206296465Sdelphij long errline; 20755714Skris#endif 20855714Skris 209296465Sdelphij req_conf = NULL; 210109998Smarkm#ifndef OPENSSL_NO_DES 211296465Sdelphij cipher = EVP_des_ede3_cbc(); 21255714Skris#endif 213296465Sdelphij apps_startup(); 21455714Skris 215296465Sdelphij if (bio_err == NULL) 216296465Sdelphij if ((bio_err = BIO_new(BIO_s_file())) != NULL) 217296465Sdelphij BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); 21855714Skris 219296465Sdelphij infile = NULL; 220296465Sdelphij outfile = NULL; 221296465Sdelphij informat = FORMAT_PEM; 222296465Sdelphij outformat = FORMAT_PEM; 22355714Skris 224296465Sdelphij prog = argv[0]; 225296465Sdelphij argc--; 226296465Sdelphij argv++; 227296465Sdelphij while (argc >= 1) { 228296465Sdelphij if (strcmp(*argv, "-inform") == 0) { 229296465Sdelphij if (--argc < 1) 230296465Sdelphij goto bad; 231296465Sdelphij informat = str2fmt(*(++argv)); 232296465Sdelphij } else if (strcmp(*argv, "-outform") == 0) { 233296465Sdelphij if (--argc < 1) 234296465Sdelphij goto bad; 235296465Sdelphij outformat = str2fmt(*(++argv)); 236296465Sdelphij } 237111147Snectar#ifndef OPENSSL_NO_ENGINE 238296465Sdelphij else if (strcmp(*argv, "-engine") == 0) { 239296465Sdelphij if (--argc < 1) 240296465Sdelphij goto bad; 241296465Sdelphij engine = *(++argv); 242296465Sdelphij } 243111147Snectar#endif 244296465Sdelphij else if (strcmp(*argv, "-key") == 0) { 245296465Sdelphij if (--argc < 1) 246296465Sdelphij goto bad; 247296465Sdelphij keyfile = *(++argv); 248296465Sdelphij } else if (strcmp(*argv, "-pubkey") == 0) { 249296465Sdelphij pubkey = 1; 250296465Sdelphij } else if (strcmp(*argv, "-new") == 0) { 251296465Sdelphij newreq = 1; 252296465Sdelphij } else if (strcmp(*argv, "-config") == 0) { 253296465Sdelphij if (--argc < 1) 254296465Sdelphij goto bad; 255296465Sdelphij template = *(++argv); 256296465Sdelphij } else if (strcmp(*argv, "-keyform") == 0) { 257296465Sdelphij if (--argc < 1) 258296465Sdelphij goto bad; 259296465Sdelphij keyform = str2fmt(*(++argv)); 260296465Sdelphij } else if (strcmp(*argv, "-in") == 0) { 261296465Sdelphij if (--argc < 1) 262296465Sdelphij goto bad; 263296465Sdelphij infile = *(++argv); 264296465Sdelphij } else if (strcmp(*argv, "-out") == 0) { 265296465Sdelphij if (--argc < 1) 266296465Sdelphij goto bad; 267296465Sdelphij outfile = *(++argv); 268296465Sdelphij } else if (strcmp(*argv, "-keyout") == 0) { 269296465Sdelphij if (--argc < 1) 270296465Sdelphij goto bad; 271296465Sdelphij keyout = *(++argv); 272296465Sdelphij } else if (strcmp(*argv, "-passin") == 0) { 273296465Sdelphij if (--argc < 1) 274296465Sdelphij goto bad; 275296465Sdelphij passargin = *(++argv); 276296465Sdelphij } else if (strcmp(*argv, "-passout") == 0) { 277296465Sdelphij if (--argc < 1) 278296465Sdelphij goto bad; 279296465Sdelphij passargout = *(++argv); 280296465Sdelphij } else if (strcmp(*argv, "-rand") == 0) { 281296465Sdelphij if (--argc < 1) 282296465Sdelphij goto bad; 283296465Sdelphij inrand = *(++argv); 284296465Sdelphij } else if (strcmp(*argv, "-newkey") == 0) { 285296465Sdelphij int is_numeric; 28655714Skris 287296465Sdelphij if (--argc < 1) 288296465Sdelphij goto bad; 289296465Sdelphij p = *(++argv); 290296465Sdelphij is_numeric = p[0] >= '0' && p[0] <= '9'; 291296465Sdelphij if (strncmp("rsa:", p, 4) == 0 || is_numeric) { 292296465Sdelphij pkey_type = TYPE_RSA; 293296465Sdelphij if (!is_numeric) 294296465Sdelphij p += 4; 295296465Sdelphij newkey = atoi(p); 296296465Sdelphij } else 297109998Smarkm#ifndef OPENSSL_NO_DSA 298296465Sdelphij if (strncmp("dsa:", p, 4) == 0) { 299296465Sdelphij X509 *xtmp = NULL; 300296465Sdelphij EVP_PKEY *dtmp; 30155714Skris 302296465Sdelphij pkey_type = TYPE_DSA; 303296465Sdelphij p += 4; 304296465Sdelphij if ((in = BIO_new_file(p, "r")) == NULL) { 305296465Sdelphij perror(p); 306296465Sdelphij goto end; 307296465Sdelphij } 308296465Sdelphij if ((dsa_params = 309296465Sdelphij PEM_read_bio_DSAparams(in, NULL, NULL, NULL)) == NULL) { 310296465Sdelphij ERR_clear_error(); 311296465Sdelphij (void)BIO_reset(in); 312296465Sdelphij if ((xtmp = 313296465Sdelphij PEM_read_bio_X509(in, NULL, NULL, NULL)) == NULL) { 314296465Sdelphij BIO_printf(bio_err, 315296465Sdelphij "unable to load DSA parameters from file\n"); 316296465Sdelphij goto end; 317296465Sdelphij } 31855714Skris 319296465Sdelphij if ((dtmp = X509_get_pubkey(xtmp)) == NULL) 320296465Sdelphij goto end; 321296465Sdelphij if (dtmp->type == EVP_PKEY_DSA) 322296465Sdelphij dsa_params = DSAparams_dup(dtmp->pkey.dsa); 323296465Sdelphij EVP_PKEY_free(dtmp); 324296465Sdelphij X509_free(xtmp); 325296465Sdelphij if (dsa_params == NULL) { 326296465Sdelphij BIO_printf(bio_err, 327296465Sdelphij "Certificate does not contain DSA parameters\n"); 328296465Sdelphij goto end; 329296465Sdelphij } 330296465Sdelphij } 331296465Sdelphij BIO_free(in); 332296465Sdelphij in = NULL; 333296465Sdelphij newkey = BN_num_bits(dsa_params->p); 334296465Sdelphij } else 33555714Skris#endif 336160814Ssimon#ifndef OPENSSL_NO_ECDSA 337296465Sdelphij if (strncmp("ec:", p, 3) == 0) { 338296465Sdelphij X509 *xtmp = NULL; 339296465Sdelphij EVP_PKEY *dtmp; 340296465Sdelphij EC_GROUP *group; 341160814Ssimon 342296465Sdelphij pkey_type = TYPE_EC; 343296465Sdelphij p += 3; 344296465Sdelphij if ((in = BIO_new_file(p, "r")) == NULL) { 345296465Sdelphij perror(p); 346296465Sdelphij goto end; 347296465Sdelphij } 348296465Sdelphij if ((ec_params = EC_KEY_new()) == NULL) 349296465Sdelphij goto end; 350296465Sdelphij group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL); 351296465Sdelphij if (group == NULL) { 352296465Sdelphij EC_KEY_free(ec_params); 353296465Sdelphij ERR_clear_error(); 354296465Sdelphij (void)BIO_reset(in); 355296465Sdelphij if ((xtmp = 356296465Sdelphij PEM_read_bio_X509(in, NULL, NULL, NULL)) == NULL) { 357296465Sdelphij BIO_printf(bio_err, 358296465Sdelphij "unable to load EC parameters from file\n"); 359296465Sdelphij goto end; 360296465Sdelphij } 361160814Ssimon 362296465Sdelphij if ((dtmp = X509_get_pubkey(xtmp)) == NULL) 363296465Sdelphij goto end; 364296465Sdelphij if (dtmp->type == EVP_PKEY_EC) 365296465Sdelphij ec_params = EC_KEY_dup(dtmp->pkey.ec); 366296465Sdelphij EVP_PKEY_free(dtmp); 367296465Sdelphij X509_free(xtmp); 368296465Sdelphij if (ec_params == NULL) { 369296465Sdelphij BIO_printf(bio_err, 370296465Sdelphij "Certificate does not contain EC parameters\n"); 371296465Sdelphij goto end; 372296465Sdelphij } 373296465Sdelphij } else { 374296465Sdelphij if (EC_KEY_set_group(ec_params, group) == 0) 375296465Sdelphij goto end; 376296465Sdelphij EC_GROUP_free(group); 377296465Sdelphij } 378160814Ssimon 379296465Sdelphij BIO_free(in); 380296465Sdelphij in = NULL; 381296465Sdelphij newkey = EC_GROUP_get_degree(EC_KEY_get0_group(ec_params)); 382296465Sdelphij } else 383160814Ssimon#endif 384109998Smarkm#ifndef OPENSSL_NO_DH 385296465Sdelphij if (strncmp("dh:", p, 4) == 0) { 386296465Sdelphij pkey_type = TYPE_DH; 387296465Sdelphij p += 3; 388296465Sdelphij } else 38955714Skris#endif 390296465Sdelphij { 391296465Sdelphij goto bad; 392296465Sdelphij } 39355714Skris 394296465Sdelphij newreq = 1; 395296465Sdelphij } else if (strcmp(*argv, "-batch") == 0) 396296465Sdelphij batch = 1; 397296465Sdelphij else if (strcmp(*argv, "-newhdr") == 0) 398296465Sdelphij newhdr = 1; 399296465Sdelphij else if (strcmp(*argv, "-modulus") == 0) 400296465Sdelphij modulus = 1; 401296465Sdelphij else if (strcmp(*argv, "-verify") == 0) 402296465Sdelphij verify = 1; 403296465Sdelphij else if (strcmp(*argv, "-nodes") == 0) 404296465Sdelphij nodes = 1; 405296465Sdelphij else if (strcmp(*argv, "-noout") == 0) 406296465Sdelphij noout = 1; 407296465Sdelphij else if (strcmp(*argv, "-verbose") == 0) 408296465Sdelphij verbose = 1; 409296465Sdelphij else if (strcmp(*argv, "-utf8") == 0) 410296465Sdelphij chtype = MBSTRING_UTF8; 411296465Sdelphij else if (strcmp(*argv, "-nameopt") == 0) { 412296465Sdelphij if (--argc < 1) 413296465Sdelphij goto bad; 414296465Sdelphij if (!set_name_ex(&nmflag, *(++argv))) 415296465Sdelphij goto bad; 416296465Sdelphij } else if (strcmp(*argv, "-reqopt") == 0) { 417296465Sdelphij if (--argc < 1) 418296465Sdelphij goto bad; 419296465Sdelphij if (!set_cert_ex(&reqflag, *(++argv))) 420296465Sdelphij goto bad; 421296465Sdelphij } else if (strcmp(*argv, "-subject") == 0) 422296465Sdelphij subject = 1; 423296465Sdelphij else if (strcmp(*argv, "-text") == 0) 424296465Sdelphij text = 1; 425296465Sdelphij else if (strcmp(*argv, "-x509") == 0) 426296465Sdelphij x509 = 1; 427296465Sdelphij else if (strcmp(*argv, "-asn1-kludge") == 0) 428296465Sdelphij kludge = 1; 429296465Sdelphij else if (strcmp(*argv, "-no-asn1-kludge") == 0) 430296465Sdelphij kludge = 0; 431296465Sdelphij else if (strcmp(*argv, "-subj") == 0) { 432296465Sdelphij if (--argc < 1) 433296465Sdelphij goto bad; 434296465Sdelphij subj = *(++argv); 435296465Sdelphij } else if (strcmp(*argv, "-multivalue-rdn") == 0) 436296465Sdelphij multirdn = 1; 437296465Sdelphij else if (strcmp(*argv, "-days") == 0) { 438296465Sdelphij if (--argc < 1) 439296465Sdelphij goto bad; 440296465Sdelphij days = atoi(*(++argv)); 441296465Sdelphij if (days == 0) 442296465Sdelphij days = 30; 443296465Sdelphij } else if (strcmp(*argv, "-set_serial") == 0) { 444296465Sdelphij if (--argc < 1) 445296465Sdelphij goto bad; 446296465Sdelphij serial = s2i_ASN1_INTEGER(NULL, *(++argv)); 447296465Sdelphij if (!serial) 448296465Sdelphij goto bad; 449296465Sdelphij } else if ((md_alg = EVP_get_digestbyname(&((*argv)[1]))) != NULL) { 450296465Sdelphij /* ok */ 451296465Sdelphij digest = md_alg; 452296465Sdelphij } else if (strcmp(*argv, "-extensions") == 0) { 453296465Sdelphij if (--argc < 1) 454296465Sdelphij goto bad; 455296465Sdelphij extensions = *(++argv); 456296465Sdelphij } else if (strcmp(*argv, "-reqexts") == 0) { 457296465Sdelphij if (--argc < 1) 458296465Sdelphij goto bad; 459296465Sdelphij req_exts = *(++argv); 460296465Sdelphij } else { 461296465Sdelphij BIO_printf(bio_err, "unknown option %s\n", *argv); 462296465Sdelphij badops = 1; 463296465Sdelphij break; 464296465Sdelphij } 465296465Sdelphij argc--; 466296465Sdelphij argv++; 467296465Sdelphij } 46855714Skris 469296465Sdelphij if (badops) { 470296465Sdelphij bad: 471296465Sdelphij BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog); 472296465Sdelphij BIO_printf(bio_err, "where options are\n"); 473296465Sdelphij BIO_printf(bio_err, " -inform arg input format - DER or PEM\n"); 474296465Sdelphij BIO_printf(bio_err, " -outform arg output format - DER or PEM\n"); 475296465Sdelphij BIO_printf(bio_err, " -in arg input file\n"); 476296465Sdelphij BIO_printf(bio_err, " -out arg output file\n"); 477296465Sdelphij BIO_printf(bio_err, " -text text form of request\n"); 478296465Sdelphij BIO_printf(bio_err, " -pubkey output public key\n"); 479296465Sdelphij BIO_printf(bio_err, " -noout do not output REQ\n"); 480296465Sdelphij BIO_printf(bio_err, " -verify verify signature on REQ\n"); 481296465Sdelphij BIO_printf(bio_err, " -modulus RSA modulus\n"); 482296465Sdelphij BIO_printf(bio_err, " -nodes don't encrypt the output key\n"); 483111147Snectar#ifndef OPENSSL_NO_ENGINE 484296465Sdelphij BIO_printf(bio_err, 485296465Sdelphij " -engine e use engine e, possibly a hardware device\n"); 486111147Snectar#endif 487296465Sdelphij BIO_printf(bio_err, " -subject output the request's subject\n"); 488296465Sdelphij BIO_printf(bio_err, " -passin private key password source\n"); 489296465Sdelphij BIO_printf(bio_err, 490296465Sdelphij " -key file use the private key contained in file\n"); 491296465Sdelphij BIO_printf(bio_err, " -keyform arg key file format\n"); 492296465Sdelphij BIO_printf(bio_err, " -keyout arg file to send the key to\n"); 493296465Sdelphij BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, 494296465Sdelphij LIST_SEPARATOR_CHAR); 495296465Sdelphij BIO_printf(bio_err, 496296465Sdelphij " load the file (or the files in the directory) into\n"); 497296465Sdelphij BIO_printf(bio_err, " the random number generator\n"); 498296465Sdelphij BIO_printf(bio_err, 499296465Sdelphij " -newkey rsa:bits generate a new RSA key of 'bits' in size\n"); 500296465Sdelphij BIO_printf(bio_err, 501296465Sdelphij " -newkey dsa:file generate a new DSA key, parameters taken from CA in 'file'\n"); 502160814Ssimon#ifndef OPENSSL_NO_ECDSA 503296465Sdelphij BIO_printf(bio_err, 504296465Sdelphij " -newkey ec:file generate a new EC key, parameters taken from CA in 'file'\n"); 505160814Ssimon#endif 506296465Sdelphij BIO_printf(bio_err, 507296465Sdelphij " -[digest] Digest to sign with (md5, sha1, md2, mdc2, md4)\n"); 508296465Sdelphij BIO_printf(bio_err, " -config file request template file.\n"); 509296465Sdelphij BIO_printf(bio_err, 510296465Sdelphij " -subj arg set or modify request subject\n"); 511296465Sdelphij BIO_printf(bio_err, 512296465Sdelphij " -multivalue-rdn enable support for multivalued RDNs\n"); 513296465Sdelphij BIO_printf(bio_err, " -new new request.\n"); 514296465Sdelphij BIO_printf(bio_err, 515296465Sdelphij " -batch do not ask anything during request generation\n"); 516296465Sdelphij BIO_printf(bio_err, 517296465Sdelphij " -x509 output a x509 structure instead of a cert. req.\n"); 518296465Sdelphij BIO_printf(bio_err, 519296465Sdelphij " -days number of days a certificate generated by -x509 is valid for.\n"); 520296465Sdelphij BIO_printf(bio_err, 521296465Sdelphij " -set_serial serial number to use for a certificate generated by -x509.\n"); 522296465Sdelphij BIO_printf(bio_err, 523296465Sdelphij " -newhdr output \"NEW\" in the header lines\n"); 524296465Sdelphij BIO_printf(bio_err, 525296465Sdelphij " -asn1-kludge Output the 'request' in a format that is wrong but some CA's\n"); 526296465Sdelphij BIO_printf(bio_err, 527296465Sdelphij " have been reported as requiring\n"); 528296465Sdelphij BIO_printf(bio_err, 529296465Sdelphij " -extensions .. specify certificate extension section (override value in config file)\n"); 530296465Sdelphij BIO_printf(bio_err, 531296465Sdelphij " -reqexts .. specify request extension section (override value in config file)\n"); 532296465Sdelphij BIO_printf(bio_err, 533296465Sdelphij " -utf8 input characters are UTF8 (default ASCII)\n"); 534296465Sdelphij BIO_printf(bio_err, 535296465Sdelphij " -nameopt arg - various certificate name options\n"); 536296465Sdelphij BIO_printf(bio_err, 537296465Sdelphij " -reqopt arg - various request text options\n\n"); 538296465Sdelphij goto end; 539296465Sdelphij } 54055714Skris 541296465Sdelphij ERR_load_crypto_strings(); 542296465Sdelphij if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { 543296465Sdelphij BIO_printf(bio_err, "Error getting passwords\n"); 544296465Sdelphij goto end; 545296465Sdelphij } 546296465Sdelphij#ifndef MONOLITH /* else this has happened in openssl.c 547296465Sdelphij * (global `config') */ 548296465Sdelphij /* Lets load up our environment a little */ 549296465Sdelphij p = getenv("OPENSSL_CONF"); 550296465Sdelphij if (p == NULL) 551296465Sdelphij p = getenv("SSLEAY_CONF"); 552296465Sdelphij if (p == NULL) 553296465Sdelphij p = to_free = make_config_name(); 554296465Sdelphij default_config_file = p; 555296465Sdelphij config = NCONF_new(NULL); 556296465Sdelphij i = NCONF_load(config, p, &errline); 55755714Skris#endif 55855714Skris 559296465Sdelphij if (template != NULL) { 560296465Sdelphij long errline = -1; 56155714Skris 562296465Sdelphij if (verbose) 563296465Sdelphij BIO_printf(bio_err, "Using configuration from %s\n", template); 564296465Sdelphij req_conf = NCONF_new(NULL); 565296465Sdelphij i = NCONF_load(req_conf, template, &errline); 566296465Sdelphij if (i == 0) { 567296465Sdelphij BIO_printf(bio_err, "error on line %ld of %s\n", errline, 568296465Sdelphij template); 569296465Sdelphij goto end; 570296465Sdelphij } 571296465Sdelphij } else { 572296465Sdelphij req_conf = config; 573160814Ssimon 574296465Sdelphij if (req_conf == NULL) { 575296465Sdelphij BIO_printf(bio_err, "Unable to load config info from %s\n", 576296465Sdelphij default_config_file); 577296465Sdelphij if (newreq) 578296465Sdelphij goto end; 579296465Sdelphij } else if (verbose) 580296465Sdelphij BIO_printf(bio_err, "Using configuration from %s\n", 581296465Sdelphij default_config_file); 582296465Sdelphij } 58355714Skris 584296465Sdelphij if (req_conf != NULL) { 585296465Sdelphij if (!load_config(bio_err, req_conf)) 586296465Sdelphij goto end; 587296465Sdelphij p = NCONF_get_string(req_conf, NULL, "oid_file"); 588296465Sdelphij if (p == NULL) 589296465Sdelphij ERR_clear_error(); 590296465Sdelphij if (p != NULL) { 591296465Sdelphij BIO *oid_bio; 59255714Skris 593296465Sdelphij oid_bio = BIO_new_file(p, "r"); 594296465Sdelphij if (oid_bio == NULL) { 595296465Sdelphij /*- 596296465Sdelphij BIO_printf(bio_err,"problems opening %s for extra oid's\n",p); 597296465Sdelphij ERR_print_errors(bio_err); 598296465Sdelphij */ 599296465Sdelphij } else { 600296465Sdelphij OBJ_create_objects(oid_bio); 601296465Sdelphij BIO_free(oid_bio); 602296465Sdelphij } 603296465Sdelphij } 604296465Sdelphij } 605296465Sdelphij if (!add_oid_section(bio_err, req_conf)) 606296465Sdelphij goto end; 60755714Skris 608296465Sdelphij if (md_alg == NULL) { 609296465Sdelphij p = NCONF_get_string(req_conf, SECTION, "default_md"); 610296465Sdelphij if (p == NULL) 611296465Sdelphij ERR_clear_error(); 612296465Sdelphij if (p != NULL) { 613296465Sdelphij if ((md_alg = EVP_get_digestbyname(p)) != NULL) 614296465Sdelphij digest = md_alg; 615296465Sdelphij } 616296465Sdelphij } 61755714Skris 618296465Sdelphij if (!extensions) { 619296465Sdelphij extensions = NCONF_get_string(req_conf, SECTION, V3_EXTENSIONS); 620296465Sdelphij if (!extensions) 621296465Sdelphij ERR_clear_error(); 622296465Sdelphij } 623296465Sdelphij if (extensions) { 624296465Sdelphij /* Check syntax of file */ 625296465Sdelphij X509V3_CTX ctx; 626296465Sdelphij X509V3_set_ctx_test(&ctx); 627296465Sdelphij X509V3_set_nconf(&ctx, req_conf); 628296465Sdelphij if (!X509V3_EXT_add_nconf(req_conf, &ctx, extensions, NULL)) { 629296465Sdelphij BIO_printf(bio_err, 630296465Sdelphij "Error Loading extension section %s\n", extensions); 631296465Sdelphij goto end; 632296465Sdelphij } 633296465Sdelphij } 63455714Skris 635296465Sdelphij if (!passin) { 636296465Sdelphij passin = NCONF_get_string(req_conf, SECTION, "input_password"); 637296465Sdelphij if (!passin) 638296465Sdelphij ERR_clear_error(); 639296465Sdelphij } 64059191Skris 641296465Sdelphij if (!passout) { 642296465Sdelphij passout = NCONF_get_string(req_conf, SECTION, "output_password"); 643296465Sdelphij if (!passout) 644296465Sdelphij ERR_clear_error(); 645296465Sdelphij } 64659191Skris 647296465Sdelphij p = NCONF_get_string(req_conf, SECTION, STRING_MASK); 648296465Sdelphij if (!p) 649296465Sdelphij ERR_clear_error(); 65059191Skris 651296465Sdelphij if (p && !ASN1_STRING_set_default_mask_asc(p)) { 652296465Sdelphij BIO_printf(bio_err, "Invalid global string mask setting %s\n", p); 653296465Sdelphij goto end; 654296465Sdelphij } 655109998Smarkm 656296465Sdelphij if (chtype != MBSTRING_UTF8) { 657296465Sdelphij p = NCONF_get_string(req_conf, SECTION, UTF8_IN); 658296465Sdelphij if (!p) 659296465Sdelphij ERR_clear_error(); 660296465Sdelphij else if (!strcmp(p, "yes")) 661296465Sdelphij chtype = MBSTRING_UTF8; 662296465Sdelphij } 663109998Smarkm 664296465Sdelphij if (!req_exts) { 665296465Sdelphij req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS); 666296465Sdelphij if (!req_exts) 667296465Sdelphij ERR_clear_error(); 668296465Sdelphij } 669296465Sdelphij if (req_exts) { 670296465Sdelphij /* Check syntax of file */ 671296465Sdelphij X509V3_CTX ctx; 672296465Sdelphij X509V3_set_ctx_test(&ctx); 673296465Sdelphij X509V3_set_nconf(&ctx, req_conf); 674296465Sdelphij if (!X509V3_EXT_add_nconf(req_conf, &ctx, req_exts, NULL)) { 675296465Sdelphij BIO_printf(bio_err, 676296465Sdelphij "Error Loading request extension section %s\n", 677296465Sdelphij req_exts); 678296465Sdelphij goto end; 679296465Sdelphij } 680296465Sdelphij } 68159191Skris 682296465Sdelphij in = BIO_new(BIO_s_file()); 683296465Sdelphij out = BIO_new(BIO_s_file()); 684296465Sdelphij if ((in == NULL) || (out == NULL)) 685296465Sdelphij goto end; 68655714Skris 687111147Snectar#ifndef OPENSSL_NO_ENGINE 688296465Sdelphij e = setup_engine(bio_err, engine, 0); 689111147Snectar#endif 690109998Smarkm 691296465Sdelphij if (keyfile != NULL) { 692296465Sdelphij pkey = load_key(bio_err, keyfile, keyform, 0, passin, e, 693296465Sdelphij "Private Key"); 694296465Sdelphij if (!pkey) { 695296465Sdelphij /* 696296465Sdelphij * load_key() has already printed an appropriate message 697296465Sdelphij */ 698296465Sdelphij goto end; 699296465Sdelphij } else { 700296465Sdelphij char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE"); 701296465Sdelphij if (randfile == NULL) 702296465Sdelphij ERR_clear_error(); 703296465Sdelphij app_RAND_load_file(randfile, bio_err, 0); 704296465Sdelphij } 705296465Sdelphij } 70655714Skris 707296465Sdelphij if (newreq && (pkey == NULL)) { 708160814Ssimon#ifndef OPENSSL_NO_RSA 709296465Sdelphij BN_GENCB cb; 710160814Ssimon#endif 711296465Sdelphij char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE"); 712296465Sdelphij if (randfile == NULL) 713296465Sdelphij ERR_clear_error(); 714296465Sdelphij app_RAND_load_file(randfile, bio_err, 0); 715296465Sdelphij if (inrand) 716296465Sdelphij app_RAND_load_files(inrand); 71755714Skris 718296465Sdelphij if (newkey <= 0) { 719296465Sdelphij if (!NCONF_get_number(req_conf, SECTION, BITS, &newkey)) 720296465Sdelphij newkey = DEFAULT_KEY_LENGTH; 721296465Sdelphij } 72255714Skris 723296465Sdelphij if (newkey < MIN_KEY_LENGTH 724296465Sdelphij && (pkey_type == TYPE_RSA || pkey_type == TYPE_DSA)) { 725296465Sdelphij BIO_printf(bio_err, "private key length is too short,\n"); 726296465Sdelphij BIO_printf(bio_err, "it needs to be at least %d bits, not %ld\n", 727296465Sdelphij MIN_KEY_LENGTH, newkey); 728296465Sdelphij goto end; 729296465Sdelphij } 730296465Sdelphij BIO_printf(bio_err, "Generating a %ld bit %s private key\n", 731296465Sdelphij newkey, (pkey_type == TYPE_RSA) ? "RSA" : 732296465Sdelphij (pkey_type == TYPE_DSA) ? "DSA" : "EC"); 73355714Skris 734296465Sdelphij if ((pkey = EVP_PKEY_new()) == NULL) 735296465Sdelphij goto end; 736296465Sdelphij 737109998Smarkm#ifndef OPENSSL_NO_RSA 738296465Sdelphij BN_GENCB_set(&cb, req_cb, bio_err); 739296465Sdelphij if (pkey_type == TYPE_RSA) { 740296465Sdelphij RSA *rsa = RSA_new(); 741296465Sdelphij BIGNUM *bn = BN_new(); 742296465Sdelphij if (!bn || !rsa || !BN_set_word(bn, 0x10001) || 743296465Sdelphij !RSA_generate_key_ex(rsa, newkey, bn, &cb) || 744296465Sdelphij !EVP_PKEY_assign_RSA(pkey, rsa)) { 745296465Sdelphij if (bn) 746296465Sdelphij BN_free(bn); 747296465Sdelphij if (rsa) 748296465Sdelphij RSA_free(rsa); 749296465Sdelphij goto end; 750296465Sdelphij } 751296465Sdelphij BN_free(bn); 752296465Sdelphij } else 75355714Skris#endif 754109998Smarkm#ifndef OPENSSL_NO_DSA 755296465Sdelphij if (pkey_type == TYPE_DSA) { 756296465Sdelphij if (!DSA_generate_key(dsa_params)) 757296465Sdelphij goto end; 758296465Sdelphij if (!EVP_PKEY_assign_DSA(pkey, dsa_params)) 759296465Sdelphij goto end; 760296465Sdelphij dsa_params = NULL; 761296465Sdelphij } 76255714Skris#endif 763160814Ssimon#ifndef OPENSSL_NO_ECDSA 764296465Sdelphij if (pkey_type == TYPE_EC) { 765296465Sdelphij if (!EC_KEY_generate_key(ec_params)) 766296465Sdelphij goto end; 767296465Sdelphij if (!EVP_PKEY_assign_EC_KEY(pkey, ec_params)) 768296465Sdelphij goto end; 769296465Sdelphij ec_params = NULL; 770296465Sdelphij } 771160814Ssimon#endif 77255714Skris 773296465Sdelphij app_RAND_write_file(randfile, bio_err); 77455714Skris 775296465Sdelphij if (pkey == NULL) 776296465Sdelphij goto end; 77755714Skris 778296465Sdelphij if (keyout == NULL) { 779296465Sdelphij keyout = NCONF_get_string(req_conf, SECTION, KEYFILE); 780296465Sdelphij if (keyout == NULL) 781296465Sdelphij ERR_clear_error(); 782296465Sdelphij } 783296465Sdelphij 784296465Sdelphij if (keyout == NULL) { 785296465Sdelphij BIO_printf(bio_err, "writing new private key to stdout\n"); 786296465Sdelphij BIO_set_fp(out, stdout, BIO_NOCLOSE); 787109998Smarkm#ifdef OPENSSL_SYS_VMS 788296465Sdelphij { 789296465Sdelphij BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 790296465Sdelphij out = BIO_push(tmpbio, out); 791296465Sdelphij } 79268651Skris#endif 793296465Sdelphij } else { 794296465Sdelphij BIO_printf(bio_err, "writing new private key to '%s'\n", keyout); 795296465Sdelphij if (BIO_write_filename(out, keyout) <= 0) { 796296465Sdelphij perror(keyout); 797296465Sdelphij goto end; 798296465Sdelphij } 799296465Sdelphij } 80055714Skris 801296465Sdelphij p = NCONF_get_string(req_conf, SECTION, "encrypt_rsa_key"); 802296465Sdelphij if (p == NULL) { 803296465Sdelphij ERR_clear_error(); 804296465Sdelphij p = NCONF_get_string(req_conf, SECTION, "encrypt_key"); 805296465Sdelphij if (p == NULL) 806296465Sdelphij ERR_clear_error(); 807296465Sdelphij } 808296465Sdelphij if ((p != NULL) && (strcmp(p, "no") == 0)) 809296465Sdelphij cipher = NULL; 810296465Sdelphij if (nodes) 811296465Sdelphij cipher = NULL; 81255714Skris 813296465Sdelphij i = 0; 814296465Sdelphij loop: 815296465Sdelphij if (!PEM_write_bio_PrivateKey(out, pkey, cipher, 816296465Sdelphij NULL, 0, NULL, passout)) { 817296465Sdelphij if ((ERR_GET_REASON(ERR_peek_error()) == 818296465Sdelphij PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3)) { 819296465Sdelphij ERR_clear_error(); 820296465Sdelphij i++; 821296465Sdelphij goto loop; 822296465Sdelphij } 823296465Sdelphij goto end; 824296465Sdelphij } 825296465Sdelphij BIO_printf(bio_err, "-----\n"); 826296465Sdelphij } 82755714Skris 828296465Sdelphij if (!newreq) { 829296465Sdelphij /* 830296465Sdelphij * Since we are using a pre-existing certificate request, the kludge 831296465Sdelphij * 'format' info should not be changed. 832296465Sdelphij */ 833296465Sdelphij kludge = -1; 834296465Sdelphij if (infile == NULL) 835296465Sdelphij BIO_set_fp(in, stdin, BIO_NOCLOSE); 836296465Sdelphij else { 837296465Sdelphij if (BIO_read_filename(in, infile) <= 0) { 838296465Sdelphij perror(infile); 839296465Sdelphij goto end; 840296465Sdelphij } 841296465Sdelphij } 84255714Skris 843296465Sdelphij if (informat == FORMAT_ASN1) 844296465Sdelphij req = d2i_X509_REQ_bio(in, NULL); 845296465Sdelphij else if (informat == FORMAT_PEM) 846296465Sdelphij req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); 847296465Sdelphij else { 848296465Sdelphij BIO_printf(bio_err, 849296465Sdelphij "bad input format specified for X509 request\n"); 850296465Sdelphij goto end; 851296465Sdelphij } 852296465Sdelphij if (req == NULL) { 853296465Sdelphij BIO_printf(bio_err, "unable to load X509 request\n"); 854296465Sdelphij goto end; 855296465Sdelphij } 856296465Sdelphij } 857296465Sdelphij 858296465Sdelphij if (newreq || x509) { 859296465Sdelphij if (pkey == NULL) { 860296465Sdelphij BIO_printf(bio_err, "you need to specify a private key\n"); 861296465Sdelphij goto end; 862296465Sdelphij } 863109998Smarkm#ifndef OPENSSL_NO_DSA 864296465Sdelphij if (pkey->type == EVP_PKEY_DSA) 865296465Sdelphij digest = EVP_dss1(); 86672613Skris#endif 867160814Ssimon#ifndef OPENSSL_NO_ECDSA 868296465Sdelphij if (pkey->type == EVP_PKEY_EC) 869296465Sdelphij digest = EVP_ecdsa(); 870160814Ssimon#endif 871296465Sdelphij if (req == NULL) { 872296465Sdelphij req = X509_REQ_new(); 873296465Sdelphij if (req == NULL) { 874296465Sdelphij goto end; 875296465Sdelphij } 87655714Skris 877296465Sdelphij i = make_REQ(req, pkey, subj, multirdn, !x509, chtype); 878296465Sdelphij subj = NULL; /* done processing '-subj' option */ 879296465Sdelphij if ((kludge > 0) 880296465Sdelphij && !sk_X509_ATTRIBUTE_num(req->req_info->attributes)) { 881296465Sdelphij sk_X509_ATTRIBUTE_free(req->req_info->attributes); 882296465Sdelphij req->req_info->attributes = NULL; 883296465Sdelphij } 884296465Sdelphij if (!i) { 885296465Sdelphij BIO_printf(bio_err, "problems making Certificate Request\n"); 886296465Sdelphij goto end; 887296465Sdelphij } 888296465Sdelphij } 889296465Sdelphij if (x509) { 890296465Sdelphij EVP_PKEY *tmppkey; 891296465Sdelphij X509V3_CTX ext_ctx; 892296465Sdelphij if ((x509ss = X509_new()) == NULL) 893296465Sdelphij goto end; 89455714Skris 895296465Sdelphij /* Set version to V3 */ 896296465Sdelphij if (extensions && !X509_set_version(x509ss, 2)) 897296465Sdelphij goto end; 898296465Sdelphij if (serial) { 899296465Sdelphij if (!X509_set_serialNumber(x509ss, serial)) 900296465Sdelphij goto end; 901296465Sdelphij } else { 902296465Sdelphij if (!rand_serial(NULL, X509_get_serialNumber(x509ss))) 903296465Sdelphij goto end; 904296465Sdelphij } 90555714Skris 906296465Sdelphij if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req))) 907296465Sdelphij goto end; 908296465Sdelphij if (!X509_gmtime_adj(X509_get_notBefore(x509ss), 0)) 909296465Sdelphij goto end; 910296465Sdelphij if (!X509_gmtime_adj 911296465Sdelphij (X509_get_notAfter(x509ss), (long)60 * 60 * 24 * days)) 912296465Sdelphij goto end; 913296465Sdelphij if (!X509_set_subject_name 914296465Sdelphij (x509ss, X509_REQ_get_subject_name(req))) 915296465Sdelphij goto end; 916296465Sdelphij tmppkey = X509_REQ_get_pubkey(req); 917296465Sdelphij if (!tmppkey || !X509_set_pubkey(x509ss, tmppkey)) 918296465Sdelphij goto end; 919296465Sdelphij EVP_PKEY_free(tmppkey); 92055714Skris 921296465Sdelphij /* Set up V3 context struct */ 92255714Skris 923296465Sdelphij X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0); 924296465Sdelphij X509V3_set_nconf(&ext_ctx, req_conf); 92555714Skris 926296465Sdelphij /* Add extensions */ 927296465Sdelphij if (extensions && !X509V3_EXT_add_nconf(req_conf, 928296465Sdelphij &ext_ctx, extensions, 929296465Sdelphij x509ss)) { 930296465Sdelphij BIO_printf(bio_err, "Error Loading extension section %s\n", 931296465Sdelphij extensions); 932296465Sdelphij goto end; 933296465Sdelphij } 93459191Skris 935296465Sdelphij if (!(i = X509_sign(x509ss, pkey, digest))) 936296465Sdelphij goto end; 937296465Sdelphij } else { 938296465Sdelphij X509V3_CTX ext_ctx; 93959191Skris 940296465Sdelphij /* Set up V3 context struct */ 94159191Skris 942296465Sdelphij X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0); 943296465Sdelphij X509V3_set_nconf(&ext_ctx, req_conf); 94455714Skris 945296465Sdelphij /* Add extensions */ 946296465Sdelphij if (req_exts && !X509V3_EXT_REQ_add_nconf(req_conf, 947296465Sdelphij &ext_ctx, req_exts, 948296465Sdelphij req)) { 949296465Sdelphij BIO_printf(bio_err, "Error Loading extension section %s\n", 950296465Sdelphij req_exts); 951296465Sdelphij goto end; 952296465Sdelphij } 953296465Sdelphij if (!(i = X509_REQ_sign(req, pkey, digest))) 954296465Sdelphij goto end; 955296465Sdelphij } 956296465Sdelphij } 957109998Smarkm 958296465Sdelphij if (subj && x509) { 959296465Sdelphij BIO_printf(bio_err, "Cannot modifiy certificate subject\n"); 960296465Sdelphij goto end; 961296465Sdelphij } 962109998Smarkm 963296465Sdelphij if (subj && !x509) { 964296465Sdelphij if (verbose) { 965296465Sdelphij BIO_printf(bio_err, "Modifying Request's Subject\n"); 966296465Sdelphij print_name(bio_err, "old subject=", 967296465Sdelphij X509_REQ_get_subject_name(req), nmflag); 968296465Sdelphij } 969109998Smarkm 970296465Sdelphij if (build_subject(req, subj, chtype, multirdn) == 0) { 971296465Sdelphij BIO_printf(bio_err, "ERROR: cannot modify subject\n"); 972296465Sdelphij ex = 1; 973296465Sdelphij goto end; 974296465Sdelphij } 975109998Smarkm 976296465Sdelphij req->req_info->enc.modified = 1; 977109998Smarkm 978296465Sdelphij if (verbose) { 979296465Sdelphij print_name(bio_err, "new subject=", 980296465Sdelphij X509_REQ_get_subject_name(req), nmflag); 981296465Sdelphij } 982296465Sdelphij } 98355714Skris 984296465Sdelphij if (verify && !x509) { 985296465Sdelphij int tmp = 0; 98655714Skris 987296465Sdelphij if (pkey == NULL) { 988296465Sdelphij pkey = X509_REQ_get_pubkey(req); 989296465Sdelphij tmp = 1; 990296465Sdelphij if (pkey == NULL) 991296465Sdelphij goto end; 992296465Sdelphij } 99355714Skris 994296465Sdelphij i = X509_REQ_verify(req, pkey); 995296465Sdelphij if (tmp) { 996296465Sdelphij EVP_PKEY_free(pkey); 997296465Sdelphij pkey = NULL; 998296465Sdelphij } 99955714Skris 1000296465Sdelphij if (i < 0) { 1001296465Sdelphij goto end; 1002296465Sdelphij } else if (i == 0) { 1003296465Sdelphij BIO_printf(bio_err, "verify failure\n"); 1004296465Sdelphij ERR_print_errors(bio_err); 1005296465Sdelphij } else /* if (i > 0) */ 1006296465Sdelphij BIO_printf(bio_err, "verify OK\n"); 1007296465Sdelphij } 100855714Skris 1009296465Sdelphij if (noout && !text && !modulus && !subject && !pubkey) { 1010296465Sdelphij ex = 0; 1011296465Sdelphij goto end; 1012296465Sdelphij } 1013296465Sdelphij 1014296465Sdelphij if (outfile == NULL) { 1015296465Sdelphij BIO_set_fp(out, stdout, BIO_NOCLOSE); 1016109998Smarkm#ifdef OPENSSL_SYS_VMS 1017296465Sdelphij { 1018296465Sdelphij BIO *tmpbio = BIO_new(BIO_f_linebuffer()); 1019296465Sdelphij out = BIO_push(tmpbio, out); 1020296465Sdelphij } 102168651Skris#endif 1022296465Sdelphij } else { 1023296465Sdelphij if ((keyout != NULL) && (strcmp(outfile, keyout) == 0)) 1024296465Sdelphij i = (int)BIO_append_filename(out, outfile); 1025296465Sdelphij else 1026296465Sdelphij i = (int)BIO_write_filename(out, outfile); 1027296465Sdelphij if (!i) { 1028296465Sdelphij perror(outfile); 1029296465Sdelphij goto end; 1030296465Sdelphij } 1031296465Sdelphij } 103255714Skris 1033296465Sdelphij if (pubkey) { 1034296465Sdelphij EVP_PKEY *tpubkey; 1035296465Sdelphij tpubkey = X509_REQ_get_pubkey(req); 1036296465Sdelphij if (tpubkey == NULL) { 1037296465Sdelphij BIO_printf(bio_err, "Error getting public key\n"); 1038296465Sdelphij ERR_print_errors(bio_err); 1039296465Sdelphij goto end; 1040296465Sdelphij } 1041296465Sdelphij PEM_write_bio_PUBKEY(out, tpubkey); 1042296465Sdelphij EVP_PKEY_free(tpubkey); 1043296465Sdelphij } 1044109998Smarkm 1045296465Sdelphij if (text) { 1046296465Sdelphij if (x509) 1047296465Sdelphij X509_print_ex(out, x509ss, nmflag, reqflag); 1048296465Sdelphij else 1049296465Sdelphij X509_REQ_print_ex(out, req, nmflag, reqflag); 1050296465Sdelphij } 105155714Skris 1052296465Sdelphij if (subject) { 1053296465Sdelphij if (x509) 1054296465Sdelphij print_name(out, "subject=", X509_get_subject_name(x509ss), 1055296465Sdelphij nmflag); 1056296465Sdelphij else 1057296465Sdelphij print_name(out, "subject=", X509_REQ_get_subject_name(req), 1058296465Sdelphij nmflag); 1059296465Sdelphij } 1060109998Smarkm 1061296465Sdelphij if (modulus) { 1062296465Sdelphij EVP_PKEY *tpubkey; 106355714Skris 1064296465Sdelphij if (x509) 1065296465Sdelphij tpubkey = X509_get_pubkey(x509ss); 1066296465Sdelphij else 1067296465Sdelphij tpubkey = X509_REQ_get_pubkey(req); 1068296465Sdelphij if (tpubkey == NULL) { 1069296465Sdelphij fprintf(stdout, "Modulus=unavailable\n"); 1070296465Sdelphij goto end; 1071296465Sdelphij } 1072296465Sdelphij fprintf(stdout, "Modulus="); 1073109998Smarkm#ifndef OPENSSL_NO_RSA 1074296465Sdelphij if (tpubkey->type == EVP_PKEY_RSA) 1075296465Sdelphij BN_print(out, tpubkey->pkey.rsa->n); 1076296465Sdelphij else 107755714Skris#endif 1078296465Sdelphij fprintf(stdout, "Wrong Algorithm type"); 1079296465Sdelphij EVP_PKEY_free(tpubkey); 1080296465Sdelphij fprintf(stdout, "\n"); 1081296465Sdelphij } 108255714Skris 1083296465Sdelphij if (!noout && !x509) { 1084296465Sdelphij if (outformat == FORMAT_ASN1) 1085296465Sdelphij i = i2d_X509_REQ_bio(out, req); 1086296465Sdelphij else if (outformat == FORMAT_PEM) { 1087296465Sdelphij if (newhdr) 1088296465Sdelphij i = PEM_write_bio_X509_REQ_NEW(out, req); 1089296465Sdelphij else 1090296465Sdelphij i = PEM_write_bio_X509_REQ(out, req); 1091296465Sdelphij } else { 1092296465Sdelphij BIO_printf(bio_err, "bad output format specified for outfile\n"); 1093296465Sdelphij goto end; 1094296465Sdelphij } 1095296465Sdelphij if (!i) { 1096296465Sdelphij BIO_printf(bio_err, "unable to write X509 request\n"); 1097296465Sdelphij goto end; 1098296465Sdelphij } 1099296465Sdelphij } 1100296465Sdelphij if (!noout && x509 && (x509ss != NULL)) { 1101296465Sdelphij if (outformat == FORMAT_ASN1) 1102296465Sdelphij i = i2d_X509_bio(out, x509ss); 1103296465Sdelphij else if (outformat == FORMAT_PEM) 1104296465Sdelphij i = PEM_write_bio_X509(out, x509ss); 1105296465Sdelphij else { 1106296465Sdelphij BIO_printf(bio_err, "bad output format specified for outfile\n"); 1107296465Sdelphij goto end; 1108296465Sdelphij } 1109296465Sdelphij if (!i) { 1110296465Sdelphij BIO_printf(bio_err, "unable to write X509 certificate\n"); 1111296465Sdelphij goto end; 1112296465Sdelphij } 1113296465Sdelphij } 1114296465Sdelphij ex = 0; 1115296465Sdelphij end: 1116109998Smarkm#ifndef MONOLITH 1117296465Sdelphij if (to_free) 1118296465Sdelphij OPENSSL_free(to_free); 1119109998Smarkm#endif 1120296465Sdelphij if (ex) { 1121296465Sdelphij ERR_print_errors(bio_err); 1122296465Sdelphij } 1123296465Sdelphij if ((req_conf != NULL) && (req_conf != config)) 1124296465Sdelphij NCONF_free(req_conf); 1125296465Sdelphij BIO_free(in); 1126296465Sdelphij BIO_free_all(out); 1127296465Sdelphij EVP_PKEY_free(pkey); 1128296465Sdelphij X509_REQ_free(req); 1129296465Sdelphij X509_free(x509ss); 1130296465Sdelphij ASN1_INTEGER_free(serial); 1131296465Sdelphij if (passargin && passin) 1132296465Sdelphij OPENSSL_free(passin); 1133296465Sdelphij if (passargout && passout) 1134296465Sdelphij OPENSSL_free(passout); 1135296465Sdelphij OBJ_cleanup(); 1136109998Smarkm#ifndef OPENSSL_NO_DSA 1137296465Sdelphij if (dsa_params != NULL) 1138296465Sdelphij DSA_free(dsa_params); 113955714Skris#endif 1140160814Ssimon#ifndef OPENSSL_NO_ECDSA 1141296465Sdelphij if (ec_params != NULL) 1142296465Sdelphij EC_KEY_free(ec_params); 1143160814Ssimon#endif 1144296465Sdelphij apps_shutdown(); 1145296465Sdelphij OPENSSL_EXIT(ex); 1146296465Sdelphij} 114755714Skris 1148160814Ssimonstatic int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn, 1149296465Sdelphij int attribs, unsigned long chtype) 1150296465Sdelphij{ 1151296465Sdelphij int ret = 0, i; 1152296465Sdelphij char no_prompt = 0; 1153296465Sdelphij STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL; 1154296465Sdelphij char *tmp, *dn_sect, *attr_sect; 115559191Skris 1156296465Sdelphij tmp = NCONF_get_string(req_conf, SECTION, PROMPT); 1157296465Sdelphij if (tmp == NULL) 1158296465Sdelphij ERR_clear_error(); 1159296465Sdelphij if ((tmp != NULL) && !strcmp(tmp, "no")) 1160296465Sdelphij no_prompt = 1; 116159191Skris 1162296465Sdelphij dn_sect = NCONF_get_string(req_conf, SECTION, DISTINGUISHED_NAME); 1163296465Sdelphij if (dn_sect == NULL) { 1164296465Sdelphij BIO_printf(bio_err, "unable to find '%s' in config\n", 1165296465Sdelphij DISTINGUISHED_NAME); 1166296465Sdelphij goto err; 1167296465Sdelphij } 1168296465Sdelphij dn_sk = NCONF_get_section(req_conf, dn_sect); 1169296465Sdelphij if (dn_sk == NULL) { 1170296465Sdelphij BIO_printf(bio_err, "unable to get '%s' section\n", dn_sect); 1171296465Sdelphij goto err; 1172296465Sdelphij } 117355714Skris 1174296465Sdelphij attr_sect = NCONF_get_string(req_conf, SECTION, ATTRIBUTES); 1175296465Sdelphij if (attr_sect == NULL) { 1176296465Sdelphij ERR_clear_error(); 1177296465Sdelphij attr_sk = NULL; 1178296465Sdelphij } else { 1179296465Sdelphij attr_sk = NCONF_get_section(req_conf, attr_sect); 1180296465Sdelphij if (attr_sk == NULL) { 1181296465Sdelphij BIO_printf(bio_err, "unable to get '%s' section\n", attr_sect); 1182296465Sdelphij goto err; 1183296465Sdelphij } 1184296465Sdelphij } 118555714Skris 1186296465Sdelphij /* setup version number */ 1187296465Sdelphij if (!X509_REQ_set_version(req, 0L)) 1188296465Sdelphij goto err; /* version 1 */ 118955714Skris 1190296465Sdelphij if (no_prompt) 1191296465Sdelphij i = auto_info(req, dn_sk, attr_sk, attribs, chtype); 1192296465Sdelphij else { 1193296465Sdelphij if (subj) 1194296465Sdelphij i = build_subject(req, subj, chtype, multirdn); 1195296465Sdelphij else 1196296465Sdelphij i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs, 1197296465Sdelphij chtype); 1198296465Sdelphij } 1199296465Sdelphij if (!i) 1200296465Sdelphij goto err; 120159191Skris 1202296465Sdelphij if (!X509_REQ_set_pubkey(req, pkey)) 1203296465Sdelphij goto err; 120459191Skris 1205296465Sdelphij ret = 1; 1206296465Sdelphij err: 1207296465Sdelphij return (ret); 1208296465Sdelphij} 120959191Skris 1210109998Smarkm/* 1211109998Smarkm * subject is expected to be in the format /type0=value0/type1=value1/type2=... 1212109998Smarkm * where characters may be escaped by \ 1213109998Smarkm */ 1214296465Sdelphijstatic int build_subject(X509_REQ *req, char *subject, unsigned long chtype, 1215296465Sdelphij int multirdn) 1216296465Sdelphij{ 1217296465Sdelphij X509_NAME *n; 121859191Skris 1219296465Sdelphij if (!(n = parse_name(subject, chtype, multirdn))) 1220296465Sdelphij return 0; 1221109998Smarkm 1222296465Sdelphij if (!X509_REQ_set_subject_name(req, n)) { 1223296465Sdelphij X509_NAME_free(n); 1224296465Sdelphij return 0; 1225296465Sdelphij } 1226296465Sdelphij X509_NAME_free(n); 1227296465Sdelphij return 1; 1228109998Smarkm} 1229109998Smarkm 123059191Skrisstatic int prompt_info(X509_REQ *req, 1231296465Sdelphij STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect, 1232296465Sdelphij STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, 1233296465Sdelphij int attribs, unsigned long chtype) 1234296465Sdelphij{ 1235296465Sdelphij int i; 1236296465Sdelphij char *p, *q; 1237296465Sdelphij char buf[100]; 1238296465Sdelphij int nid, mval; 1239296465Sdelphij long n_min, n_max; 1240296465Sdelphij char *type, *value; 1241296465Sdelphij const char *def; 1242296465Sdelphij CONF_VALUE *v; 1243296465Sdelphij X509_NAME *subj; 1244296465Sdelphij subj = X509_REQ_get_subject_name(req); 124555714Skris 1246296465Sdelphij if (!batch) { 1247296465Sdelphij BIO_printf(bio_err, 1248296465Sdelphij "You are about to be asked to enter information that will be incorporated\n"); 1249296465Sdelphij BIO_printf(bio_err, "into your certificate request.\n"); 1250296465Sdelphij BIO_printf(bio_err, 1251296465Sdelphij "What you are about to enter is what is called a Distinguished Name or a DN.\n"); 1252296465Sdelphij BIO_printf(bio_err, 1253296465Sdelphij "There are quite a few fields but you can leave some blank\n"); 1254296465Sdelphij BIO_printf(bio_err, 1255296465Sdelphij "For some fields there will be a default value,\n"); 1256296465Sdelphij BIO_printf(bio_err, 1257296465Sdelphij "If you enter '.', the field will be left blank.\n"); 1258296465Sdelphij BIO_printf(bio_err, "-----\n"); 1259296465Sdelphij } 126055714Skris 1261296465Sdelphij if (sk_CONF_VALUE_num(dn_sk)) { 1262296465Sdelphij i = -1; 1263296465Sdelphij start:for (;;) { 1264296465Sdelphij i++; 1265296465Sdelphij if (sk_CONF_VALUE_num(dn_sk) <= i) 1266296465Sdelphij break; 1267109998Smarkm 1268296465Sdelphij v = sk_CONF_VALUE_value(dn_sk, i); 1269296465Sdelphij p = q = NULL; 1270296465Sdelphij type = v->name; 1271296465Sdelphij if (!check_end(type, "_min") || !check_end(type, "_max") || 1272296465Sdelphij !check_end(type, "_default") || !check_end(type, "_value")) 1273296465Sdelphij continue; 1274296465Sdelphij /* 1275296465Sdelphij * Skip past any leading X. X: X, etc to allow for multiple 1276296465Sdelphij * instances 1277296465Sdelphij */ 1278296465Sdelphij for (p = v->name; *p; p++) 1279296465Sdelphij if ((*p == ':') || (*p == ',') || (*p == '.')) { 1280296465Sdelphij p++; 1281296465Sdelphij if (*p) 1282296465Sdelphij type = p; 1283296465Sdelphij break; 1284296465Sdelphij } 1285296465Sdelphij if (*type == '+') { 1286296465Sdelphij mval = -1; 1287296465Sdelphij type++; 1288296465Sdelphij } else 1289296465Sdelphij mval = 0; 1290296465Sdelphij /* If OBJ not recognised ignore it */ 1291296465Sdelphij if ((nid = OBJ_txt2nid(type)) == NID_undef) 1292296465Sdelphij goto start; 1293296465Sdelphij if (BIO_snprintf(buf, sizeof buf, "%s_default", v->name) 1294296465Sdelphij >= (int)sizeof(buf)) { 1295296465Sdelphij BIO_printf(bio_err, "Name '%s' too long\n", v->name); 1296296465Sdelphij return 0; 1297296465Sdelphij } 129855714Skris 1299296465Sdelphij if ((def = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) { 1300296465Sdelphij ERR_clear_error(); 1301296465Sdelphij def = ""; 1302296465Sdelphij } 1303109998Smarkm 1304296465Sdelphij BIO_snprintf(buf, sizeof buf, "%s_value", v->name); 1305296465Sdelphij if ((value = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) { 1306296465Sdelphij ERR_clear_error(); 1307296465Sdelphij value = NULL; 1308296465Sdelphij } 130955714Skris 1310296465Sdelphij BIO_snprintf(buf, sizeof buf, "%s_min", v->name); 1311296465Sdelphij if (!NCONF_get_number(req_conf, dn_sect, buf, &n_min)) { 1312296465Sdelphij ERR_clear_error(); 1313296465Sdelphij n_min = -1; 1314296465Sdelphij } 131555714Skris 1316296465Sdelphij BIO_snprintf(buf, sizeof buf, "%s_max", v->name); 1317296465Sdelphij if (!NCONF_get_number(req_conf, dn_sect, buf, &n_max)) { 1318296465Sdelphij ERR_clear_error(); 1319296465Sdelphij n_max = -1; 1320296465Sdelphij } 132155714Skris 1322296465Sdelphij if (!add_DN_object(subj, v->value, def, value, nid, 1323296465Sdelphij n_min, n_max, chtype, mval)) 1324296465Sdelphij return 0; 1325296465Sdelphij } 1326296465Sdelphij if (X509_NAME_entry_count(subj) == 0) { 1327296465Sdelphij BIO_printf(bio_err, 1328296465Sdelphij "error, no objects specified in config file\n"); 1329296465Sdelphij return 0; 1330296465Sdelphij } 133155714Skris 1332296465Sdelphij if (attribs) { 1333296465Sdelphij if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0) 1334296465Sdelphij && (!batch)) { 1335296465Sdelphij BIO_printf(bio_err, 1336296465Sdelphij "\nPlease enter the following 'extra' attributes\n"); 1337296465Sdelphij BIO_printf(bio_err, 1338296465Sdelphij "to be sent with your certificate request\n"); 1339296465Sdelphij } 134055714Skris 1341296465Sdelphij i = -1; 1342296465Sdelphij start2: for (;;) { 1343296465Sdelphij i++; 1344296465Sdelphij if ((attr_sk == NULL) || (sk_CONF_VALUE_num(attr_sk) <= i)) 1345296465Sdelphij break; 134655714Skris 1347296465Sdelphij v = sk_CONF_VALUE_value(attr_sk, i); 1348296465Sdelphij type = v->name; 1349296465Sdelphij if ((nid = OBJ_txt2nid(type)) == NID_undef) 1350296465Sdelphij goto start2; 135155714Skris 1352296465Sdelphij if (BIO_snprintf(buf, sizeof buf, "%s_default", type) 1353296465Sdelphij >= (int)sizeof(buf)) { 1354296465Sdelphij BIO_printf(bio_err, "Name '%s' too long\n", v->name); 1355296465Sdelphij return 0; 1356296465Sdelphij } 1357109998Smarkm 1358296465Sdelphij if ((def = NCONF_get_string(req_conf, attr_sect, buf)) 1359296465Sdelphij == NULL) { 1360296465Sdelphij ERR_clear_error(); 1361296465Sdelphij def = ""; 1362296465Sdelphij } 136355714Skris 1364296465Sdelphij BIO_snprintf(buf, sizeof buf, "%s_value", type); 1365296465Sdelphij if ((value = NCONF_get_string(req_conf, attr_sect, buf)) 1366296465Sdelphij == NULL) { 1367296465Sdelphij ERR_clear_error(); 1368296465Sdelphij value = NULL; 1369296465Sdelphij } 137055714Skris 1371296465Sdelphij BIO_snprintf(buf, sizeof buf, "%s_min", type); 1372296465Sdelphij if (!NCONF_get_number(req_conf, attr_sect, buf, &n_min)) { 1373296465Sdelphij ERR_clear_error(); 1374296465Sdelphij n_min = -1; 1375296465Sdelphij } 137655714Skris 1377296465Sdelphij BIO_snprintf(buf, sizeof buf, "%s_max", type); 1378296465Sdelphij if (!NCONF_get_number(req_conf, attr_sect, buf, &n_max)) { 1379296465Sdelphij ERR_clear_error(); 1380296465Sdelphij n_max = -1; 1381296465Sdelphij } 138255714Skris 1383296465Sdelphij if (!add_attribute_object(req, 1384296465Sdelphij v->value, def, value, nid, n_min, 1385296465Sdelphij n_max, chtype)) 1386296465Sdelphij return 0; 1387296465Sdelphij } 1388296465Sdelphij } 1389296465Sdelphij } else { 1390296465Sdelphij BIO_printf(bio_err, "No template, please set one up.\n"); 1391296465Sdelphij return 0; 1392296465Sdelphij } 139355714Skris 1394296465Sdelphij return 1; 139555714Skris 1396296465Sdelphij} 1397296465Sdelphij 139859191Skrisstatic int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk, 1399296465Sdelphij STACK_OF(CONF_VALUE) *attr_sk, int attribs, 1400296465Sdelphij unsigned long chtype) 1401296465Sdelphij{ 1402296465Sdelphij int i; 1403296465Sdelphij char *p, *q; 1404296465Sdelphij char *type; 1405296465Sdelphij CONF_VALUE *v; 1406296465Sdelphij X509_NAME *subj; 140759191Skris 1408296465Sdelphij subj = X509_REQ_get_subject_name(req); 140959191Skris 1410296465Sdelphij for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) { 1411296465Sdelphij int mval; 1412296465Sdelphij v = sk_CONF_VALUE_value(dn_sk, i); 1413296465Sdelphij p = q = NULL; 1414296465Sdelphij type = v->name; 1415296465Sdelphij /* 1416296465Sdelphij * Skip past any leading X. X: X, etc to allow for multiple instances 1417296465Sdelphij */ 1418296465Sdelphij for (p = v->name; *p; p++) 141968651Skris#ifndef CHARSET_EBCDIC 1420296465Sdelphij if ((*p == ':') || (*p == ',') || (*p == '.')) { 142168651Skris#else 1422296465Sdelphij if ((*p == os_toascii[':']) || (*p == os_toascii[',']) 1423296465Sdelphij || (*p == os_toascii['.'])) { 142468651Skris#endif 1425296465Sdelphij p++; 1426296465Sdelphij if (*p) 1427296465Sdelphij type = p; 1428296465Sdelphij break; 1429296465Sdelphij } 1430160814Ssimon#ifndef CHARSET_EBCDIC 1431296465Sdelphij if (*p == '+') 1432160814Ssimon#else 1433296465Sdelphij if (*p == os_toascii['+']) 1434160814Ssimon#endif 1435296465Sdelphij { 1436296465Sdelphij p++; 1437296465Sdelphij mval = -1; 1438296465Sdelphij } else 1439296465Sdelphij mval = 0; 1440296465Sdelphij if (!X509_NAME_add_entry_by_txt(subj, type, chtype, 1441296465Sdelphij (unsigned char *)v->value, -1, -1, 1442296465Sdelphij mval)) 1443296465Sdelphij return 0; 144459191Skris 1445296465Sdelphij } 144659191Skris 1447296465Sdelphij if (!X509_NAME_entry_count(subj)) { 1448296465Sdelphij BIO_printf(bio_err, "error, no objects specified in config file\n"); 1449296465Sdelphij return 0; 1450296465Sdelphij } 1451296465Sdelphij if (attribs) { 1452296465Sdelphij for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) { 1453296465Sdelphij v = sk_CONF_VALUE_value(attr_sk, i); 1454296465Sdelphij if (!X509_REQ_add1_attr_by_txt(req, v->name, chtype, 1455296465Sdelphij (unsigned char *)v->value, -1)) 1456296465Sdelphij return 0; 1457296465Sdelphij } 1458296465Sdelphij } 1459296465Sdelphij return 1; 1460296465Sdelphij} 146159191Skris 1462296465Sdelphijstatic int add_DN_object(X509_NAME *n, char *text, const char *def, 1463296465Sdelphij char *value, int nid, int n_min, int n_max, 1464296465Sdelphij unsigned long chtype, int mval) 1465296465Sdelphij{ 1466296465Sdelphij int i, ret = 0; 1467296465Sdelphij MS_STATIC char buf[1024]; 1468296465Sdelphij start: 1469296465Sdelphij if (!batch) 1470296465Sdelphij BIO_printf(bio_err, "%s [%s]:", text, def); 1471296465Sdelphij (void)BIO_flush(bio_err); 1472296465Sdelphij if (value != NULL) { 1473296465Sdelphij BUF_strlcpy(buf, value, sizeof buf); 1474296465Sdelphij BUF_strlcat(buf, "\n", sizeof buf); 1475296465Sdelphij BIO_printf(bio_err, "%s\n", value); 1476296465Sdelphij } else { 1477296465Sdelphij buf[0] = '\0'; 1478296465Sdelphij if (!batch) { 1479296465Sdelphij if (!fgets(buf, sizeof buf, stdin)) 1480296465Sdelphij return 0; 1481296465Sdelphij } else { 1482296465Sdelphij buf[0] = '\n'; 1483296465Sdelphij buf[1] = '\0'; 1484296465Sdelphij } 1485296465Sdelphij } 148659191Skris 1487296465Sdelphij if (buf[0] == '\0') 1488296465Sdelphij return (0); 1489296465Sdelphij else if (buf[0] == '\n') { 1490296465Sdelphij if ((def == NULL) || (def[0] == '\0')) 1491296465Sdelphij return (1); 1492296465Sdelphij BUF_strlcpy(buf, def, sizeof buf); 1493296465Sdelphij BUF_strlcat(buf, "\n", sizeof buf); 1494296465Sdelphij } else if ((buf[0] == '.') && (buf[1] == '\n')) 1495296465Sdelphij return (1); 149655714Skris 1497296465Sdelphij i = strlen(buf); 1498296465Sdelphij if (buf[i - 1] != '\n') { 1499296465Sdelphij BIO_printf(bio_err, "weird input :-(\n"); 1500296465Sdelphij return (0); 1501296465Sdelphij } 1502296465Sdelphij buf[--i] = '\0'; 150355714Skris#ifdef CHARSET_EBCDIC 1504296465Sdelphij ebcdic2ascii(buf, buf, i); 150555714Skris#endif 1506296465Sdelphij if (!req_check_len(i, n_min, n_max)) { 1507296465Sdelphij if (batch || value) 1508296465Sdelphij return 0; 1509296465Sdelphij goto start; 1510296465Sdelphij } 1511267285Sjkim 1512296465Sdelphij if (!X509_NAME_add_entry_by_NID(n, nid, chtype, 1513296465Sdelphij (unsigned char *)buf, -1, -1, mval)) 1514296465Sdelphij goto err; 1515296465Sdelphij ret = 1; 1516296465Sdelphij err: 1517296465Sdelphij return (ret); 1518296465Sdelphij} 151955714Skris 1520160814Ssimonstatic int add_attribute_object(X509_REQ *req, char *text, const char *def, 1521296465Sdelphij char *value, int nid, int n_min, 1522296465Sdelphij int n_max, unsigned long chtype) 1523296465Sdelphij{ 1524296465Sdelphij int i; 1525296465Sdelphij static char buf[1024]; 152655714Skris 1527296465Sdelphij start: 1528296465Sdelphij if (!batch) 1529296465Sdelphij BIO_printf(bio_err, "%s [%s]:", text, def); 1530296465Sdelphij (void)BIO_flush(bio_err); 1531296465Sdelphij if (value != NULL) { 1532296465Sdelphij BUF_strlcpy(buf, value, sizeof buf); 1533296465Sdelphij BUF_strlcat(buf, "\n", sizeof buf); 1534296465Sdelphij BIO_printf(bio_err, "%s\n", value); 1535296465Sdelphij } else { 1536296465Sdelphij buf[0] = '\0'; 1537296465Sdelphij if (!batch) { 1538296465Sdelphij if (!fgets(buf, sizeof buf, stdin)) 1539296465Sdelphij return 0; 1540296465Sdelphij } else { 1541296465Sdelphij buf[0] = '\n'; 1542296465Sdelphij buf[1] = '\0'; 1543296465Sdelphij } 1544296465Sdelphij } 154555714Skris 1546296465Sdelphij if (buf[0] == '\0') 1547296465Sdelphij return (0); 1548296465Sdelphij else if (buf[0] == '\n') { 1549296465Sdelphij if ((def == NULL) || (def[0] == '\0')) 1550296465Sdelphij return (1); 1551296465Sdelphij BUF_strlcpy(buf, def, sizeof buf); 1552296465Sdelphij BUF_strlcat(buf, "\n", sizeof buf); 1553296465Sdelphij } else if ((buf[0] == '.') && (buf[1] == '\n')) 1554296465Sdelphij return (1); 155555714Skris 1556296465Sdelphij i = strlen(buf); 1557296465Sdelphij if (buf[i - 1] != '\n') { 1558296465Sdelphij BIO_printf(bio_err, "weird input :-(\n"); 1559296465Sdelphij return (0); 1560296465Sdelphij } 1561296465Sdelphij buf[--i] = '\0'; 156268651Skris#ifdef CHARSET_EBCDIC 1563296465Sdelphij ebcdic2ascii(buf, buf, i); 156468651Skris#endif 1565296465Sdelphij if (!req_check_len(i, n_min, n_max)) { 1566296465Sdelphij if (batch || value) 1567296465Sdelphij return 0; 1568296465Sdelphij goto start; 1569296465Sdelphij } 157055714Skris 1571296465Sdelphij if (!X509_REQ_add1_attr_by_NID(req, nid, chtype, 1572296465Sdelphij (unsigned char *)buf, -1)) { 1573296465Sdelphij BIO_printf(bio_err, "Error adding attribute\n"); 1574296465Sdelphij ERR_print_errors(bio_err); 1575296465Sdelphij goto err; 1576296465Sdelphij } 157755714Skris 1578296465Sdelphij return (1); 1579296465Sdelphij err: 1580296465Sdelphij return (0); 1581296465Sdelphij} 158255714Skris 1583109998Smarkm#ifndef OPENSSL_NO_RSA 1584160814Ssimonstatic int MS_CALLBACK req_cb(int p, int n, BN_GENCB *cb) 1585296465Sdelphij{ 1586296465Sdelphij char c = '*'; 158755714Skris 1588296465Sdelphij if (p == 0) 1589296465Sdelphij c = '.'; 1590296465Sdelphij if (p == 1) 1591296465Sdelphij c = '+'; 1592296465Sdelphij if (p == 2) 1593296465Sdelphij c = '*'; 1594296465Sdelphij if (p == 3) 1595296465Sdelphij c = '\n'; 1596296465Sdelphij BIO_write(cb->arg, &c, 1); 1597296465Sdelphij (void)BIO_flush(cb->arg); 1598296465Sdelphij# ifdef LINT 1599296465Sdelphij p = n; 1600296465Sdelphij# endif 1601296465Sdelphij return 1; 1602296465Sdelphij} 160355714Skris#endif 160455714Skris 1605109998Smarkmstatic int req_check_len(int len, int n_min, int n_max) 1606296465Sdelphij{ 1607296465Sdelphij if ((n_min > 0) && (len < n_min)) { 1608296465Sdelphij BIO_printf(bio_err, 1609296465Sdelphij "string is too short, it needs to be at least %d bytes long\n", 1610296465Sdelphij n_min); 1611296465Sdelphij return (0); 1612296465Sdelphij } 1613296465Sdelphij if ((n_max >= 0) && (len > n_max)) { 1614296465Sdelphij BIO_printf(bio_err, 1615296465Sdelphij "string is too long, it needs to be less than %d bytes long\n", 1616296465Sdelphij n_max); 1617296465Sdelphij return (0); 1618296465Sdelphij } 1619296465Sdelphij return (1); 1620296465Sdelphij} 162155714Skris 162255714Skris/* Check if the end of a string matches 'end' */ 1623160814Ssimonstatic int check_end(const char *str, const char *end) 162455714Skris{ 1625296465Sdelphij int elen, slen; 1626296465Sdelphij const char *tmp; 1627296465Sdelphij elen = strlen(end); 1628296465Sdelphij slen = strlen(str); 1629296465Sdelphij if (elen > slen) 1630296465Sdelphij return 1; 1631296465Sdelphij tmp = str + slen - elen; 1632296465Sdelphij return strcmp(tmp, end); 163355714Skris} 1634