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