(linenum→info "unix/slp.c:2238")

openssl/0.9.8g/apps/req.c

    1: /* apps/req.c */
    2: /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
    3:  * All rights reserved.
    4:  *
    5:  * This package is an SSL implementation written
    6:  * by Eric Young (eay@cryptsoft.com).
    7:  * The implementation was written so as to conform with Netscapes SSL.
    8:  * 
    9:  * This library is free for commercial and non-commercial use as long as
   10:  * the following conditions are aheared to.  The following conditions
   11:  * apply to all code found in this distribution, be it the RC4, RSA,
   12:  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
   13:  * included with this distribution is covered by the same copyright terms
   14:  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
   15:  * 
   16:  * Copyright remains Eric Young's, and as such any Copyright notices in
   17:  * the code are not to be removed.
   18:  * If this package is used in a product, Eric Young should be given attribution
   19:  * as the author of the parts of the library used.
   20:  * This can be in the form of a textual message at program startup or
   21:  * in documentation (online or textual) provided with the package.
   22:  * 
   23:  * Redistribution and use in source and binary forms, with or without
   24:  * modification, are permitted provided that the following conditions
   25:  * are met:
   26:  * 1. Redistributions of source code must retain the copyright
   27:  *    notice, this list of conditions and the following disclaimer.
   28:  * 2. Redistributions in binary form must reproduce the above copyright
   29:  *    notice, this list of conditions and the following disclaimer in the
   30:  *    documentation and/or other materials provided with the distribution.
   31:  * 3. All advertising materials mentioning features or use of this software
   32:  *    must display the following acknowledgement:
   33:  *    "This product includes cryptographic software written by
   34:  *     Eric Young (eay@cryptsoft.com)"
   35:  *    The word 'cryptographic' can be left out if the rouines from the library
   36:  *    being used are not cryptographic related :-).
   37:  * 4. If you include any Windows specific code (or a derivative thereof) from 
   38:  *    the apps directory (application code) you must include an acknowledgement:
   39:  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
   40:  * 
   41:  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
   42:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   43:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   44:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   45:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   46:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   47:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   48:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   49:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   50:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   51:  * SUCH DAMAGE.
   52:  * 
   53:  * The licence and distribution terms for any publically available version or
   54:  * derivative of this code cannot be changed.  i.e. this code cannot simply be
   55:  * copied and put under another distribution licence
   56:  * [including the GNU Public Licence.]
   57:  */
   58: 
   59: /* Until the key-gen callbacks are modified to use newer prototypes, we allow
   60:  * deprecated functions for openssl-internal code */
   61: #ifdef OPENSSL_NO_DEPRECATED
   62: #undef OPENSSL_NO_DEPRECATED
   63: #endif
   64: 
   65: #include <stdio.h>
   66: #include <stdlib.h>
   67: #include <time.h>
   68: #include <string.h>
   69: #ifdef OPENSSL_NO_STDIO
   70: #define APPS_WIN16
   71: #endif
   72: #include "apps.h"
   73: #include <openssl/bio.h>
   74: #include <openssl/evp.h>
   75: #include <openssl/conf.h>
   76: #include <openssl/err.h>
   77: #include <openssl/asn1.h>
   78: #include <openssl/x509.h>
   79: #include <openssl/x509v3.h>
   80: #include <openssl/objects.h>
   81: #include <openssl/pem.h>
   82: #include <openssl/bn.h>
   83: #ifndef OPENSSL_NO_RSA
   84: #include <openssl/rsa.h>
   85: #endif
   86: #ifndef OPENSSL_NO_DSA
   87: #include <openssl/dsa.h>
   88: #endif
   89: 
   90: #define SECTION         "req"
   91: 
   92: #define BITS            "default_bits"
   93: #define KEYFILE         "default_keyfile"
   94: #define PROMPT          "prompt"
   95: #define DISTINGUISHED_NAME      "distinguished_name"
   96: #define ATTRIBUTES      "attributes"
   97: #define V3_EXTENSIONS   "x509_extensions"
   98: #define REQ_EXTENSIONS  "req_extensions"
   99: #define STRING_MASK     "string_mask"
  100: #define UTF8_IN         "utf8"
  101: 
  102: #define DEFAULT_KEY_LENGTH      512
  103: #define MIN_KEY_LENGTH          384
  104: 
  105: #undef PROG
  106: #define PROG    req_main
  107: 
  108: /* -inform arg  - input format - default PEM (DER or PEM)
  109:  * -outform arg - output format - default PEM
  110:  * -in arg      - input file - default stdin
  111:  * -out arg     - output file - default stdout
  112:  * -verify      - check request signature
  113:  * -noout       - don't print stuff out.
  114:  * -text        - print out human readable text.
  115:  * -nodes       - no des encryption
  116:  * -config file - Load configuration file.
  117:  * -key file    - make a request using key in file (or use it for verification).
  118:  * -keyform arg - key file format.
  119:  * -rand file(s) - load the file(s) into the PRNG.
  120:  * -newkey      - make a key and a request.
  121:  * -modulus     - print RSA modulus.
  122:  * -pubkey      - output Public Key.
  123:  * -x509        - output a self signed X509 structure instead.
  124:  * -asn1-kludge - output new certificate request in a format that some CA's
  125:  *                require.  This format is wrong
  126:  */
  127: 
  128: static int make_REQ(X509_REQ *req,EVP_PKEY *pkey,char *dn,int mutlirdn,
  129:                 int attribs,unsigned long chtype);
  130: static int build_subject(X509_REQ *req, char *subj, unsigned long chtype,
  131:                 int multirdn);
  132: static int prompt_info(X509_REQ *req,
  133:                 STACK_OF(CONF_VALUE) *dn_sk, char *dn_sect,
  134:                 STACK_OF(CONF_VALUE) *attr_sk, char *attr_sect, int attribs,
  135:                 unsigned long chtype);
  136: static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *sk,
  137:                                 STACK_OF(CONF_VALUE) *attr, int attribs,
  138:                                 unsigned long chtype);
  139: static int add_attribute_object(X509_REQ *req, char *text, const char *def,
  140:                                 char *value, int nid, int n_min,
  141:                                 int n_max, unsigned long chtype);
  142: static int add_DN_object(X509_NAME *n, char *text, const char *def, char *value,
  143:         int nid,int n_min,int n_max, unsigned long chtype, int mval);
  144: #ifndef OPENSSL_NO_RSA
  145: static int MS_CALLBACK req_cb(int p, int n, BN_GENCB *cb);
  146: #endif
  147: static int req_check_len(int len,int n_min,int n_max);
  148: static int check_end(const char *str, const char *end);
  149: #ifndef MONOLITH
  150: static char *default_config_file=NULL;
  151: #endif
  152: static CONF *req_conf=NULL;
  153: static int batch=0;
  154: 
  155: #define TYPE_RSA        1
  156: #define TYPE_DSA        2
  157: #define TYPE_DH         3
  158: #define TYPE_EC         4
  159: 
  160: int MAIN(int, char **);
  161: 
  162: int MAIN(int argc, char **argv)
  163:         {
  164:         ENGINE *e = NULL;
  165: #ifndef OPENSSL_NO_DSA
  166:         DSA *dsa_params=NULL;
  167: #endif
  168: #ifndef OPENSSL_NO_ECDSA
  169:         EC_KEY *ec_params = NULL;
  170: #endif
  171:         unsigned long nmflag = 0, reqflag = 0;
  172:         int ex=1,x509=0,days=30;
  173:         X509 *x509ss=NULL;
  174:         X509_REQ *req=NULL;
  175:         EVP_PKEY *pkey=NULL;
  176:         int i=0,badops=0,newreq=0,verbose=0,pkey_type=TYPE_RSA;
  177:         long newkey = -1;
  178:         BIO *in=NULL,*out=NULL;
  179:         int informat,outformat,verify=0,noout=0,text=0,keyform=FORMAT_PEM;
  180:         int nodes=0,kludge=0,newhdr=0,subject=0,pubkey=0;
  181:         char *infile,*outfile,*prog,*keyfile=NULL,*template=NULL,*keyout=NULL;
  182: #ifndef OPENSSL_NO_ENGINE
  183:         char *engine=NULL;
  184: #endif
  185:         char *extensions = NULL;
  186:         char *req_exts = NULL;
  187:         const EVP_CIPHER *cipher=NULL;
  188:         ASN1_INTEGER *serial = NULL;
  189:         int modulus=0;
  190:         char *inrand=NULL;
  191:         char *passargin = NULL, *passargout = NULL;
  192:         char *passin = NULL, *passout = NULL;
  193:         char *p;
  194:         char *subj = NULL;
  195:         int multirdn = 0;
  196:         const EVP_MD *md_alg=NULL,*digest=EVP_sha1();
  197:         unsigned long chtype = MBSTRING_ASC;
  198: #ifndef MONOLITH
  199:         char *to_free;
  200:         long errline;
  201: #endif
  202: 
  203:         req_conf = NULL;
  204: #ifndef OPENSSL_NO_DES
  205:         cipher=EVP_des_ede3_cbc();
  206: #endif
  207:         apps_startup();
  208: 
  209:         if (bio_err == NULL)
  210:                 if ((bio_err=BIO_new(BIO_s_file())) != NULL)
  211:                         BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
  212: 
  213:         infile=NULL;
  214:         outfile=NULL;
  215:         informat=FORMAT_PEM;
  216:         outformat=FORMAT_PEM;
  217: 
  218:         prog=argv[0];
  219:         argc--;
  220:         argv++;
  221:         while (argc >= 1)
  222:                 {
  223:                 if    (strcmp(*argv,"-inform") == 0)
  224:                         {
  225:                         if (--argc < 1) goto bad;
  226:                         informat=str2fmt(*(++argv));
  227:                         }
  228:                 else if (strcmp(*argv,"-outform") == 0)
  229:                         {
  230:                         if (--argc < 1) goto bad;
  231:                         outformat=str2fmt(*(++argv));
  232:                         }
  233: #ifndef OPENSSL_NO_ENGINE
  234:                 else if (strcmp(*argv,"-engine") == 0)
  235:                         {
  236:                         if (--argc < 1) goto bad;
  237:                         engine= *(++argv);
  238:                         }
  239: #endif
  240:                 else if (strcmp(*argv,"-key") == 0)
  241:                         {
  242:                         if (--argc < 1) goto bad;
  243:                         keyfile= *(++argv);
  244:                         }
  245:                 else if (strcmp(*argv,"-pubkey") == 0)
  246:                         {
  247:                         pubkey=1;
  248:                         }
  249:                 else if (strcmp(*argv,"-new") == 0)
  250:                         {
  251:                         newreq=1;
  252:                         }
  253:                 else if (strcmp(*argv,"-config") == 0)
  254:                         {    
  255:                         if (--argc < 1) goto bad;
  256:                         template= *(++argv);
  257:                         }
  258:                 else if (strcmp(*argv,"-keyform") == 0)
  259:                         {
  260:                         if (--argc < 1) goto bad;
  261:                         keyform=str2fmt(*(++argv));
  262:                         }
  263:                 else if (strcmp(*argv,"-in") == 0)
  264:                         {
  265:                         if (--argc < 1) goto bad;
  266:                         infile= *(++argv);
  267:                         }
  268:                 else if (strcmp(*argv,"-out") == 0)
  269:                         {
  270:                         if (--argc < 1) goto bad;
  271:                         outfile= *(++argv);
  272:                         }
  273:                 else if (strcmp(*argv,"-keyout") == 0)
  274:                         {
  275:                         if (--argc < 1) goto bad;
  276:                         keyout= *(++argv);
  277:                         }
  278:                 else if (strcmp(*argv,"-passin") == 0)
  279:                         {
  280:                         if (--argc < 1) goto bad;
  281:                         passargin= *(++argv);
  282:                         }
  283:                 else if (strcmp(*argv,"-passout") == 0)
  284:                         {
  285:                         if (--argc < 1) goto bad;
  286:                         passargout= *(++argv);
  287:                         }
  288:                 else if (strcmp(*argv,"-rand") == 0)
  289:                         {
  290:                         if (--argc < 1) goto bad;
  291:                         inrand= *(++argv);
  292:                         }
  293:                 else if (strcmp(*argv,"-newkey") == 0)
  294:                         {
  295:                         int is_numeric;
  296: 
  297:                         if (--argc < 1) goto bad;
  298:                         p= *(++argv);
  299:                         is_numeric = p[0] >= '0' && p[0] <= '9';
  300:                         if (strncmp("rsa:",p,4) == 0 || is_numeric)
  301:                                 {
  302:                                 pkey_type=TYPE_RSA;
  303:                                 if(!is_numeric)
  304:                                     p+=4;
  305:                                 newkey= atoi(p);
  306:                                 }
  307:                         else
  308: #ifndef OPENSSL_NO_DSA
  309:                                 if (strncmp("dsa:",p,4) == 0)
  310:                                 {
  311:                                 X509 *xtmp=NULL;
  312:                                 EVP_PKEY *dtmp;
  313: 
  314:                                 pkey_type=TYPE_DSA;
  315:                                 p+=4;
  316:                                 if ((in=BIO_new_file(p,"r")) == NULL)
  317:                                         {
  318:                                         perror(p);
  319:                                         goto end;
  320:                                         }
  321:                                 if ((dsa_params=PEM_read_bio_DSAparams(in,NULL,NULL,NULL)) == NULL)
  322:                                         {
  323:                                         ERR_clear_error();
  324:                                         (void)BIO_reset(in);
  325:                                         if ((xtmp=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
  326:                                                 {
  327:                                                 BIO_printf(bio_err,"unable to load DSA parameters from file\n");
  328:                                                 goto end;
  329:                                                 }
  330: 
  331:                                         if ((dtmp=X509_get_pubkey(xtmp)) == NULL) goto end;
  332:                                         if (dtmp->type == EVP_PKEY_DSA)
  333:                                                 dsa_params=DSAparams_dup(dtmp->pkey.dsa);
  334:                                         EVP_PKEY_free(dtmp);
  335:                                         X509_free(xtmp);
  336:                                         if (dsa_params == NULL)
  337:                                                 {
  338:                                                 BIO_printf(bio_err,"Certificate does not contain DSA parameters\n");
  339:                                                 goto end;
  340:                                                 }
  341:                                         }
  342:                                 BIO_free(in);
  343:                                 in=NULL;
  344:                                 newkey=BN_num_bits(dsa_params->p);
  345:                                 }
  346:                         else 
  347: #endif
  348: #ifndef OPENSSL_NO_ECDSA
  349:                                 if (strncmp("ec:",p,3) == 0)
  350:                                 {
  351:                                 X509 *xtmp=NULL;
  352:                                 EVP_PKEY *dtmp;
  353:                                 EC_GROUP *group;
  354: 
  355:                                 pkey_type=TYPE_EC;
  356:                                 p+=3;
  357:                                 if ((in=BIO_new_file(p,"r")) == NULL)
  358:                                         {
  359:                                         perror(p);
  360:                                         goto end;
  361:                                         }
  362:                                 if ((ec_params = EC_KEY_new()) == NULL)
  363:                                         goto end;
  364:                                 group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
  365:                                 if (group == NULL)
  366:                                         {
  367:                                         EC_KEY_free(ec_params);
  368:                                         ERR_clear_error();
  369:                                         (void)BIO_reset(in);
  370:                                         if ((xtmp=PEM_read_bio_X509(in,NULL,NULL,NULL)) == NULL)
  371:                                                 { 
  372:                                                 BIO_printf(bio_err,"unable to load EC parameters from file\n");
  373:                                                 goto end;
  374:                                                 }
  375: 
  376:                                         if ((dtmp=X509_get_pubkey(xtmp))==NULL)
  377:                                                 goto end;
  378:                                         if (dtmp->type == EVP_PKEY_EC)
  379:                                                 ec_params = EC_KEY_dup(dtmp->pkey.ec);
  380:                                         EVP_PKEY_free(dtmp);
  381:                                         X509_free(xtmp);
  382:                                         if (ec_params == NULL)
  383:                                                 {
  384:                                                 BIO_printf(bio_err,"Certificate does not contain EC parameters\n");
  385:                                                 goto end;
  386:                                                 }
  387:                                         }
  388:                                 else
  389:                                         {
  390:                                         if (EC_KEY_set_group(ec_params, group) == 0)
  391:                                                 goto end;
  392:                                         EC_GROUP_free(group);
  393:                                         }
  394: 
  395:                                 BIO_free(in);
  396:                                 in=NULL;
  397:                                 newkey = EC_GROUP_get_degree(EC_KEY_get0_group(ec_params));
  398:                                 }
  399:                         else
  400: #endif
  401: #ifndef OPENSSL_NO_DH
  402:                                 if (strncmp("dh:",p,4) == 0)
  403:                                 {
  404:                                 pkey_type=TYPE_DH;
  405:                                 p+=3;
  406:                                 }
  407:                         else
  408: #endif
  409:                                 {
  410:                                 goto bad;
  411:                                 }
  412: 
  413:                         newreq=1;
  414:                         }
  415:                 else if (strcmp(*argv,"-batch") == 0)
  416:                         batch=1;
  417:                 else if (strcmp(*argv,"-newhdr") == 0)
  418:                         newhdr=1;
  419:                 else if (strcmp(*argv,"-modulus") == 0)
  420:                         modulus=1;
  421:                 else if (strcmp(*argv,"-verify") == 0)
  422:                         verify=1;
  423:                 else if (strcmp(*argv,"-nodes") == 0)
  424:                         nodes=1;
  425:                 else if (strcmp(*argv,"-noout") == 0)
  426:                         noout=1;
  427:                 else if (strcmp(*argv,"-verbose") == 0)
  428:                         verbose=1;
  429:                 else if (strcmp(*argv,"-utf8") == 0)
  430:                         chtype = MBSTRING_UTF8;
  431:                 else if (strcmp(*argv,"-nameopt") == 0)
  432:                         {
  433:                         if (--argc < 1) goto bad;
  434:                         if (!set_name_ex(&nmflag, *(++argv))) goto bad;
  435:                         }
  436:                 else if (strcmp(*argv,"-reqopt") == 0)
  437:                         {
  438:                         if (--argc < 1) goto bad;
  439:                         if (!set_cert_ex(&reqflag, *(++argv))) goto bad;
  440:                         }
  441:                 else if (strcmp(*argv,"-subject") == 0)
  442:                         subject=1;
  443:                 else if (strcmp(*argv,"-text") == 0)
  444:                         text=1;
  445:                 else if (strcmp(*argv,"-x509") == 0)
  446:                         x509=1;
  447:                 else if (strcmp(*argv,"-asn1-kludge") == 0)
  448:                         kludge=1;
  449:                 else if (strcmp(*argv,"-no-asn1-kludge") == 0)
  450:                         kludge=0;
  451:                 else if (strcmp(*argv,"-subj") == 0)
  452:                         {
  453:                         if (--argc < 1) goto bad;
  454:                         subj= *(++argv);
  455:                         }
  456:                 else if (strcmp(*argv,"-multivalue-rdn") == 0)
  457:                         multirdn=1;
  458:                 else if (strcmp(*argv,"-days") == 0)
  459:                         {
  460:                         if (--argc < 1) goto bad;
  461:                         days= atoi(*(++argv));
  462:                         if (days == 0) days=30;
  463:                         }
  464:                 else if (strcmp(*argv,"-set_serial") == 0)
  465:                         {
  466:                         if (--argc < 1) goto bad;
  467:                         serial = s2i_ASN1_INTEGER(NULL, *(++argv));
  468:                         if (!serial) goto bad;
  469:                         }
  470:                 else if ((md_alg=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
  471:                         {
  472:                         /* ok */
  473:                         digest=md_alg;
  474:                         }
  475:                 else if (strcmp(*argv,"-extensions") == 0)
  476:                         {
  477:                         if (--argc < 1) goto bad;
  478:                         extensions = *(++argv);
  479:                         }
  480:                 else if (strcmp(*argv,"-reqexts") == 0)
  481:                         {
  482:                         if (--argc < 1) goto bad;
  483:                         req_exts = *(++argv);
  484:                         }
  485:                 else
  486:                         {
  487:                         BIO_printf(bio_err,"unknown option %s\n",*argv);
  488:                         badops=1;
  489:                         break;
  490:                         }
  491:                 argc--;
  492:                 argv++;
  493:                 }
  494: 
  495:         if (badops)
  496:                 {
  497: bad:
  498:                 BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog);
  499:                 BIO_printf(bio_err,"where options  are\n");
  500:                 BIO_printf(bio_err," -inform arg    input format - DER or PEM\n");
  501:                 BIO_printf(bio_err," -outform arg   output format - DER or PEM\n");
  502:                 BIO_printf(bio_err," -in arg        input file\n");
  503:                 BIO_printf(bio_err," -out arg       output file\n");
  504:                 BIO_printf(bio_err," -text          text form of request\n");
  505:                 BIO_printf(bio_err," -pubkey        output public key\n");
  506:                 BIO_printf(bio_err," -noout         do not output REQ\n");
  507:                 BIO_printf(bio_err," -verify        verify signature on REQ\n");
  508:                 BIO_printf(bio_err," -modulus       RSA modulus\n");
  509:                 BIO_printf(bio_err," -nodes         don't encrypt the output key\n");
  510: #ifndef OPENSSL_NO_ENGINE
  511:                 BIO_printf(bio_err," -engine e      use engine e, possibly a hardware device\n");
  512: #endif
  513:                 BIO_printf(bio_err," -subject       output the request's subject\n");
  514:                 BIO_printf(