- apps_startup();
-
- X509V3_add_standard_extensions();
-
- preserve=0;
- if (bio_err == NULL)
- if ((bio_err=BIO_new(BIO_s_file())) != NULL)
- BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
-
- argc--;
- argv++;
- while (argc >= 1)
- {
- if (strcmp(*argv,"-verbose") == 0)
- verbose=1;
- else if (strcmp(*argv,"-config") == 0)
- {
- if (--argc < 1) goto bad;
- configfile= *(++argv);
- }
- else if (strcmp(*argv,"-name") == 0)
- {
- if (--argc < 1) goto bad;
- section= *(++argv);
- }
- else if (strcmp(*argv,"-startdate") == 0)
- {
- if (--argc < 1) goto bad;
- startdate= *(++argv);
- }
- else if (strcmp(*argv,"-days") == 0)
- {
- if (--argc < 1) goto bad;
- days=atoi(*(++argv));
- }
- else if (strcmp(*argv,"-md") == 0)
- {
- if (--argc < 1) goto bad;
- md= *(++argv);
- }
- else if (strcmp(*argv,"-policy") == 0)
- {
- if (--argc < 1) goto bad;
- policy= *(++argv);
- }
- else if (strcmp(*argv,"-keyfile") == 0)
- {
- if (--argc < 1) goto bad;
- keyfile= *(++argv);
- }
- else if (strcmp(*argv,"-key") == 0)
- {
- if (--argc < 1) goto bad;
- key= *(++argv);
- }
- else if (strcmp(*argv,"-cert") == 0)
- {
- if (--argc < 1) goto bad;
- certfile= *(++argv);
- }
- else if (strcmp(*argv,"-in") == 0)
- {
- if (--argc < 1) goto bad;
- infile= *(++argv);
- req=1;
- }
- else if (strcmp(*argv,"-out") == 0)
- {
- if (--argc < 1) goto bad;
- outfile= *(++argv);
- }
- else if (strcmp(*argv,"-outdir") == 0)
- {
- if (--argc < 1) goto bad;
- outdir= *(++argv);
- }
- else if (strcmp(*argv,"-batch") == 0)
- batch=1;
- else if (strcmp(*argv,"-preserveDN") == 0)
- preserve=1;
- else if (strcmp(*argv,"-gencrl") == 0)
- gencrl=1;
- else if (strcmp(*argv,"-msie_hack") == 0)
- msie_hack=1;
- else if (strcmp(*argv,"-crldays") == 0)
- {
- if (--argc < 1) goto bad;
- crldays= atol(*(++argv));
- }
- else if (strcmp(*argv,"-crlhours") == 0)
- {
- if (--argc < 1) goto bad;
- crlhours= atol(*(++argv));
- }
- else if (strcmp(*argv,"-infiles") == 0)
- {
- argc--;
- argv++;
- req=1;
- break;
- }
- else if (strcmp(*argv, "-ss_cert") == 0)
- {
- if (--argc < 1) goto bad;
- ss_cert_file = *(++argv);
- req=1;
- }
- else if (strcmp(*argv, "-spkac") == 0)
- {
- if (--argc < 1) goto bad;
- spkac_file = *(++argv);
- req=1;
- }
- else if (strcmp(*argv,"-revoke") == 0)
- {
- if (--argc < 1) goto bad;
- infile= *(++argv);
- dorevoke=1;
- }
- else
- {
-bad:
- BIO_printf(bio_err,"unknown option %s\n",*argv);
- badops=1;
- break;
- }
- argc--;
- argv++;
- }
-
- if (badops)
- {
- for (pp=ca_usage; (*pp != NULL); pp++)
- BIO_printf(bio_err,*pp);
- goto err;
- }
-
- ERR_load_crypto_strings();
-
- /*****************************************************************/
- if (configfile == NULL)
- {
- /* We will just use 'buf[0]' as a temporary buffer. */
- strncpy(buf[0],X509_get_default_cert_area(),
- sizeof(buf[0])-2-sizeof(CONFIG_FILE));
- strcat(buf[0],"/");
- strcat(buf[0],CONFIG_FILE);
- configfile=buf[0];
- }
-
- BIO_printf(bio_err,"Using configuration from %s\n",configfile);
- if ((conf=CONF_load(NULL,configfile,&errorline)) == NULL)
- {
- if (errorline <= 0)
- BIO_printf(bio_err,"error loading the config file '%s'\n",
- configfile);
- else
- BIO_printf(bio_err,"error on line %ld of config file '%s'\n"
- ,errorline,configfile);
- goto err;
- }
-
- /* Lets get the config section we are using */
- if (section == NULL)
- {
- section=CONF_get_string(conf,BASE_SECTION,ENV_DEFAULT_CA);
- if (section == NULL)
- {
- lookup_fail(BASE_SECTION,ENV_DEFAULT_CA);
- goto err;
- }
- }
-
- if (conf != NULL)
- {
- p=CONF_get_string(conf,NULL,"oid_file");
- if (p != NULL)
- {
- BIO *oid_bio;
-
- oid_bio=BIO_new_file(p,"r");
- if (oid_bio == NULL)
- {
- /*
- BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
- ERR_print_errors(bio_err);
- */
- ERR_clear_error();
- }
- else
- {
- OBJ_create_objects(oid_bio);
- BIO_free(oid_bio);
- }
- }
- }
- if(!add_oid_section(conf)) {
- ERR_print_errors(bio_err);
- goto err;
- }
-
- in=BIO_new(BIO_s_file());
- out=BIO_new(BIO_s_file());
- Sout=BIO_new(BIO_s_file());
- Cout=BIO_new(BIO_s_file());
- if ((in == NULL) || (out == NULL) || (Sout == NULL) || (Cout == NULL))
- {
- ERR_print_errors(bio_err);
- goto err;
- }
-
- /*****************************************************************/
- /* we definitly need an public key, so lets get it */
-
- if ((keyfile == NULL) && ((keyfile=CONF_get_string(conf,
- section,ENV_PRIVATE_KEY)) == NULL))
- {
- lookup_fail(section,ENV_PRIVATE_KEY);
- goto err;
- }
- if (BIO_read_filename(in,keyfile) <= 0)
- {
- perror(keyfile);
- BIO_printf(bio_err,"trying to load CA private key\n");
- goto err;
- }
- if (key == NULL)
- pkey=PEM_read_bio_PrivateKey(in,NULL,NULL);
- else
- {
- pkey=PEM_read_bio_PrivateKey(in,NULL,key_callback);
- memset(key,0,strlen(key));
- }
- if (pkey == NULL)
- {
- BIO_printf(bio_err,"unable to load CA private key\n");
- goto err;
- }
-
- /*****************************************************************/
- /* we need a certificate */
- if ((certfile == NULL) && ((certfile=CONF_get_string(conf,
- section,ENV_CERTIFICATE)) == NULL))
- {
- lookup_fail(section,ENV_CERTIFICATE);
- goto err;
- }
- if (BIO_read_filename(in,certfile) <= 0)
- {
- perror(certfile);
- BIO_printf(bio_err,"trying to load CA certificate\n");
- goto err;
- }
- x509=PEM_read_bio_X509(in,NULL,NULL);
- if (x509 == NULL)
- {
- BIO_printf(bio_err,"unable to load CA certificate\n");
- goto err;
- }
-
- if (!X509_check_private_key(x509,pkey))
- {
- BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
- goto err;
- }
-
- f=CONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
- if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
- preserve=1;
- f=CONF_get_string(conf,BASE_SECTION,ENV_MSIE_HACK);
- if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
- msie_hack=1;
-
- /*****************************************************************/
- /* lookup where to write new certificates */
- if ((outdir == NULL) && (req))
- {
- struct stat sb;
-
- if ((outdir=CONF_get_string(conf,section,ENV_NEW_CERTS_DIR))
- == NULL)
- {
- BIO_printf(bio_err,"there needs to be defined a directory for new certificate to be placed in\n");
- goto err;
- }
- if (access(outdir,R_OK|W_OK|X_OK) != 0)
- {
- BIO_printf(bio_err,"I am unable to acces the %s directory\n",outdir);
- perror(outdir);
- goto err;
- }
-
- if (stat(outdir,&sb) != 0)
- {
- BIO_printf(bio_err,"unable to stat(%s)\n",outdir);
- perror(outdir);
- goto err;
- }
- if (!(sb.st_mode & S_IFDIR))
- {
- BIO_printf(bio_err,"%s need to be a directory\n",outdir);
- perror(outdir);
- goto err;
- }
- }
-
- /*****************************************************************/
- /* we need to load the database file */
- if ((dbfile=CONF_get_string(conf,section,ENV_DATABASE)) == NULL)
- {
- lookup_fail(section,ENV_DATABASE);
- goto err;
- }
- if (BIO_read_filename(in,dbfile) <= 0)
- {
- perror(dbfile);
- BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
- goto err;
- }
- db=TXT_DB_read(in,DB_NUMBER);
- if (db == NULL) goto err;
-
- /* Lets check some fields */
- for (i=0; i<sk_num(db->data); i++)
- {
- pp=(char **)sk_value(db->data,i);
- if ((pp[DB_type][0] != DB_TYPE_REV) &&
- (pp[DB_rev_date][0] != '\0'))
- {
- BIO_printf(bio_err,"entry %d: not revoked yet, but has a revocation date\n",i+1);
- goto err;
- }
- if ((pp[DB_type][0] == DB_TYPE_REV) &&
- !check_time_format(pp[DB_rev_date]))
- {
- BIO_printf(bio_err,"entry %d: invalid revocation date\n",
- i+1);
- goto err;
- }
- if (!check_time_format(pp[DB_exp_date]))
- {
- BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
- goto err;
- }
- p=pp[DB_serial];
- j=strlen(p);
- if ((j&1) || (j < 2))
- {
- BIO_printf(bio_err,"entry %d: bad serial number length (%d)\n",i+1,j);
- goto err;
- }
- while (*p)
- {
- if (!( ((*p >= '0') && (*p <= '9')) ||
- ((*p >= 'A') && (*p <= 'F')) ||
- ((*p >= 'a') && (*p <= 'f'))) )
- {
- BIO_printf(bio_err,"entry %d: bad serial number characters, char pos %ld, char is '%c'\n",i+1,(long)(p-pp[DB_serial]),*p);
- goto err;
- }
- p++;
- }
- }
- if (verbose)
- {
- BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
- TXT_DB_write(out,db);
- BIO_printf(bio_err,"%d entries loaded from the database\n",
- db->data->num);
- BIO_printf(bio_err,"generating indexs\n");
- }
-
- if (!TXT_DB_create_index(db,DB_serial,NULL,index_serial_hash,
- index_serial_cmp))
- {
- BIO_printf(bio_err,"error creating serial number index:(%ld,%ld,%ld)\n",db->error,db->arg1,db->arg2);
- goto err;
- }
-
- if (!TXT_DB_create_index(db,DB_name,index_name_qual,index_name_hash,
- index_name_cmp))
- {
- BIO_printf(bio_err,"error creating name index:(%ld,%ld,%ld)\n",
- db->error,db->arg1,db->arg2);
- goto err;
- }
-
- /*****************************************************************/
- if (req || gencrl)
- {
- if (outfile != NULL)
- {
-
- if (BIO_write_filename(Sout,outfile) <= 0)
- {
- perror(outfile);
- goto err;
- }
- }
- else
- BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
- }
-
- if (req)
- {
- if ((md == NULL) && ((md=CONF_get_string(conf,
- section,ENV_DEFAULT_MD)) == NULL))
- {
- lookup_fail(section,ENV_DEFAULT_MD);
- goto err;
- }
- if ((dgst=EVP_get_digestbyname(md)) == NULL)
- {
- BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
- goto err;
- }
- if (verbose)
- BIO_printf(bio_err,"message digest is %s\n",
- OBJ_nid2ln(dgst->type));
- if ((policy == NULL) && ((policy=CONF_get_string(conf,
- section,ENV_POLICY)) == NULL))
- {
- lookup_fail(section,ENV_POLICY);
- goto err;
- }
- if (verbose)
- BIO_printf(bio_err,"policy is %s\n",policy);
-
- if ((serialfile=CONF_get_string(conf,section,ENV_SERIAL))
- == NULL)
- {
- lookup_fail(section,ENV_SERIAL);
- goto err;
- }
-
- extensions=CONF_get_string(conf,section,ENV_EXTENSIONS);
- if(extensions) {
- /* Check syntax of file */
- X509V3_CTX ctx;
- X509V3_set_ctx_test(&ctx);
- X509V3_set_conf_lhash(&ctx, conf);
- if(!X509V3_EXT_add_conf(conf, &ctx, extensions, NULL)) {
- BIO_printf(bio_err,
- "Error Loading extension section %s\n",
- extensions);
- ret = 1;
- goto err;
- }
- }
-
- if (startdate == NULL)
- {
- startdate=(char *)CONF_get_string(conf,section,
- ENV_DEFAULT_STARTDATE);
- if (startdate == NULL)
- startdate="today";
- else
- {
- if (!ASN1_UTCTIME_set_string(NULL,startdate))
- {
- BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSS\n");
- goto err;
- }
- }
- }
-
- if (days == 0)
- {
- days=(int)CONF_get_number(conf,section,
- ENV_DEFAULT_DAYS);
- }
- if (days == 0)
- {
- BIO_printf(bio_err,"cannot lookup how many days to certify for\n");
- goto err;
- }
-
- if ((serial=load_serial(serialfile)) == NULL)
- {
- BIO_printf(bio_err,"error while loading serial number\n");
- goto err;
- }
- if (verbose)
- {
- if ((f=BN_bn2hex(serial)) == NULL) goto err;
- BIO_printf(bio_err,"next serial number is %s\n",f);
- Free(f);
- }
-
- if ((attribs=CONF_get_section(conf,policy)) == NULL)
- {
- BIO_printf(bio_err,"unable to find 'section' for %s\n",policy);
- goto err;
- }
-
- if ((cert_sk=sk_new_null()) == NULL)
- {
- BIO_printf(bio_err,"Malloc failure\n");
- goto err;
- }
- if (spkac_file != NULL)
- {
- total++;
- j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
- serial,startdate,days,extensions,conf,verbose);
- if (j < 0) goto err;
- if (j > 0)
- {
- total_done++;
- BIO_printf(bio_err,"\n");
- if (!BN_add_word(serial,1)) goto err;
- if (!sk_push(cert_sk,(char *)x))
- {
- BIO_printf(bio_err,"Malloc failure\n");
- goto err;
- }
- if (outfile)
- {
- output_der = 1;
- batch = 1;
- }
- }
- }
- if (ss_cert_file != NULL)
- {
- total++;
- j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
- db,serial,startdate,days,batch,
- extensions,conf,verbose);
- if (j < 0) goto err;
- if (j > 0)
- {
- total_done++;
- BIO_printf(bio_err,"\n");
- if (!BN_add_word(serial,1)) goto err;
- if (!sk_push(cert_sk,(char *)x))
- {
- BIO_printf(bio_err,"Malloc failure\n");
- goto err;
- }
- }
- }
- if (infile != NULL)
- {
- total++;
- j=certify(&x,infile,pkey,x509,dgst,attribs,db,
- serial,startdate,days,batch,
- extensions,conf,verbose);
- if (j < 0) goto err;
- if (j > 0)
- {
- total_done++;
- BIO_printf(bio_err,"\n");
- if (!BN_add_word(serial,1)) goto err;
- if (!sk_push(cert_sk,(char *)x))
- {
- BIO_printf(bio_err,"Malloc failure\n");
- goto err;
- }
- }
- }
- for (i=0; i<argc; i++)
- {
- total++;
- j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
- serial,startdate,days,batch,
- extensions,conf,verbose);
- if (j < 0) goto err;
- if (j > 0)
- {
- total_done++;
- BIO_printf(bio_err,"\n");
- if (!BN_add_word(serial,1)) goto err;
- if (!sk_push(cert_sk,(char *)x))
- {
- BIO_printf(bio_err,"Malloc failure\n");
- goto err;
- }
- }
- }
- /* we have a stack of newly certified certificates
- * and a data base and serial number that need
- * updating */
-
- if (sk_num(cert_sk) > 0)
- {
- if (!batch)
- {
- BIO_printf(bio_err,"\n%d out of %d certificate requests certified, commit? [y/n]",total_done,total);
- BIO_flush(bio_err);
- buf[0][0]='\0';
- fgets(buf[0],10,stdin);
- if ((buf[0][0] != 'y') && (buf[0][0] != 'Y'))
- {
- BIO_printf(bio_err,"CERTIFICATION CANCELED\n");
- ret=0;
- goto err;
- }
- }
-
- BIO_printf(bio_err,"Write out database with %d new entries\n",sk_num(cert_sk));
-
- strncpy(buf[0],serialfile,BSIZE-4);
- strcat(buf[0],".new");
-
- if (!save_serial(buf[0],serial)) goto err;
-
- strncpy(buf[1],dbfile,BSIZE-4);
- strcat(buf[1],".new");
- if (BIO_write_filename(out,buf[1]) <= 0)
- {
- perror(dbfile);
- BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
- goto err;
- }
- l=TXT_DB_write(out,db);
- if (l <= 0) goto err;
- }
-
- if (verbose)
- BIO_printf(bio_err,"writing new certificates\n");
- for (i=0; i<sk_num(cert_sk); i++)
- {
- int k;
- unsigned char *n;
-
- x=(X509 *)sk_value(cert_sk,i);
-
- j=x->cert_info->serialNumber->length;
- p=(char *)x->cert_info->serialNumber->data;
-
- strncpy(buf[2],outdir,BSIZE-(j*2)-6);
- strcat(buf[2],"/");
- n=(unsigned char *)&(buf[2][strlen(buf[2])]);
- if (j > 0)
- {
- for (k=0; k<j; k++)
- {
- sprintf((char *)n,"%02X",(unsigned char)*(p++));
- n+=2;
- }
- }
- else
- {
- *(n++)='0';
- *(n++)='0';
- }
- *(n++)='.'; *(n++)='p'; *(n++)='e'; *(n++)='m';
- *n='\0';
- if (verbose)
- BIO_printf(bio_err,"writing %s\n",buf[2]);
-
- if (BIO_write_filename(Cout,buf[2]) <= 0)
- {
- perror(buf[2]);
- goto err;
- }
- write_new_certificate(Cout,x, 0);
- write_new_certificate(Sout,x, output_der);
- }
-
- if (sk_num(cert_sk))
- {
- /* Rename the database and the serial file */
- strncpy(buf[2],serialfile,BSIZE-4);
- strcat(buf[2],".old");
- BIO_free(in);
- BIO_free(out);
- in=NULL;
- out=NULL;
- if (rename(serialfile,buf[2]) < 0)
- {
- BIO_printf(bio_err,"unabel to rename %s to %s\n",
- serialfile,buf[2]);
- perror("reason");
- goto err;
- }
- if (rename(buf[0],serialfile) < 0)
- {
- BIO_printf(bio_err,"unabel to rename %s to %s\n",
- buf[0],serialfile);
- perror("reason");
- rename(buf[2],serialfile);
- goto err;
- }
-
- strncpy(buf[2],dbfile,BSIZE-4);
- strcat(buf[2],".old");
- if (rename(dbfile,buf[2]) < 0)
- {
- BIO_printf(bio_err,"unabel to rename %s to %s\n",
- dbfile,buf[2]);
- perror("reason");
- goto err;
- }
- if (rename(buf[1],dbfile) < 0)
- {
- BIO_printf(bio_err,"unabel to rename %s to %s\n",
- buf[1],dbfile);
- perror("reason");
- rename(buf[2],dbfile);
- goto err;
- }
- BIO_printf(bio_err,"Data Base Updated\n");
- }
- }
-
- /*****************************************************************/
- if (gencrl)
- {
- crl_ext=CONF_get_string(conf,section,ENV_CRLEXT);
- if(crl_ext) {
- /* Check syntax of file */
- X509V3_CTX ctx;
- X509V3_set_ctx_test(&ctx);
- X509V3_set_conf_lhash(&ctx, conf);
- if(!X509V3_EXT_add_conf(conf, &ctx, crl_ext, NULL)) {
- BIO_printf(bio_err,
- "Error Loading CRL extension section %s\n",
- crl_ext);
- ret = 1;
- goto err;
- }
- }
- if ((hex=BIO_new(BIO_s_mem())) == NULL) goto err;
-
- if (!crldays && !crlhours)
- {
- crldays=CONF_get_number(conf,section,
- ENV_DEFAULT_CRL_DAYS);
- crlhours=CONF_get_number(conf,section,
- ENV_DEFAULT_CRL_HOURS);
- }
- if ((crldays == 0) && (crlhours == 0))
- {
- BIO_printf(bio_err,"cannot lookup how long until the next CRL is issuer\n");
- goto err;
- }
-
- if (verbose) BIO_printf(bio_err,"making CRL\n");
- if ((crl=X509_CRL_new()) == NULL) goto err;
- ci=crl->crl;
- X509_NAME_free(ci->issuer);
- ci->issuer=X509_NAME_dup(x509->cert_info->subject);
- if (ci->issuer == NULL) goto err;
-
- X509_gmtime_adj(ci->lastUpdate,0);
- if (ci->nextUpdate == NULL)
- ci->nextUpdate=ASN1_UTCTIME_new();
- X509_gmtime_adj(ci->nextUpdate,(crldays*24+crlhours)*60*60);
-
- for (i=0; i<sk_num(db->data); i++)
- {
- pp=(char **)sk_value(db->data,i);
- if (pp[DB_type][0] == DB_TYPE_REV)
- {
- if ((r=X509_REVOKED_new()) == NULL) goto err;
- ASN1_STRING_set((ASN1_STRING *)
- r->revocationDate,
- (unsigned char *)pp[DB_rev_date],
- strlen(pp[DB_rev_date]));
- /* strcpy(r->revocationDate,pp[DB_rev_date]);*/
-
- BIO_reset(hex);
- if (!BIO_puts(hex,pp[DB_serial]))
- goto err;
- if (!a2i_ASN1_INTEGER(hex,r->serialNumber,
- buf[0],BSIZE)) goto err;
-
- sk_push(ci->revoked,(char *)r);
- }
- }
- /* sort the data so it will be written in serial
- * number order */
- sk_find(ci->revoked,NULL);
- for (i=0; i<sk_num(ci->revoked); i++)
- {
- r=(X509_REVOKED *)sk_value(ci->revoked,i);
- r->sequence=i;
- }
-
- /* we now have a CRL */
- if (verbose) BIO_printf(bio_err,"signing CRL\n");
- if (md != NULL)
- {
- if ((dgst=EVP_get_digestbyname(md)) == NULL)
- {
- BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
- goto err;
- }
- }
- else
- {
-#ifndef NO_DSA
- if (pkey->type == EVP_PKEY_DSA)
- dgst=EVP_dss1();
- else
+ apps_startup();
+
+ conf = NULL;
+ key = NULL;
+ section = NULL;
+
+ preserve = 0;
+ msie_hack = 0;
+ if (bio_err == NULL)
+ if ((bio_err = BIO_new(BIO_s_file())) != NULL)
+ BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
+
+ argc--;
+ argv++;
+ while (argc >= 1) {
+ if (strcmp(*argv, "-verbose") == 0)
+ verbose = 1;
+ else if (strcmp(*argv, "-config") == 0) {
+ if (--argc < 1)
+ goto bad;
+ configfile = *(++argv);
+ } else if (strcmp(*argv, "-name") == 0) {
+ if (--argc < 1)
+ goto bad;
+ section = *(++argv);
+ } else if (strcmp(*argv, "-subj") == 0) {
+ if (--argc < 1)
+ goto bad;
+ subj = *(++argv);
+ /* preserve=1; */
+ } else if (strcmp(*argv, "-utf8") == 0)
+ chtype = MBSTRING_UTF8;
+ else if (strcmp(*argv, "-create_serial") == 0)
+ create_ser = 1;
+ else if (strcmp(*argv, "-multivalue-rdn") == 0)
+ multirdn = 1;
+ else if (strcmp(*argv, "-startdate") == 0) {
+ if (--argc < 1)
+ goto bad;
+ startdate = *(++argv);
+ } else if (strcmp(*argv, "-enddate") == 0) {
+ if (--argc < 1)
+ goto bad;
+ enddate = *(++argv);
+ } else if (strcmp(*argv, "-days") == 0) {
+ if (--argc < 1)
+ goto bad;
+ days = atoi(*(++argv));
+ } else if (strcmp(*argv, "-md") == 0) {
+ if (--argc < 1)
+ goto bad;
+ md = *(++argv);
+ } else if (strcmp(*argv, "-policy") == 0) {
+ if (--argc < 1)
+ goto bad;
+ policy = *(++argv);
+ } else if (strcmp(*argv, "-keyfile") == 0) {
+ if (--argc < 1)
+ goto bad;
+ keyfile = *(++argv);
+ } else if (strcmp(*argv, "-keyform") == 0) {
+ if (--argc < 1)
+ goto bad;
+ keyform = str2fmt(*(++argv));
+ } else if (strcmp(*argv, "-passin") == 0) {
+ if (--argc < 1)
+ goto bad;
+ passargin = *(++argv);
+ } else if (strcmp(*argv, "-key") == 0) {
+ if (--argc < 1)
+ goto bad;
+ key = *(++argv);
+ } else if (strcmp(*argv, "-cert") == 0) {
+ if (--argc < 1)
+ goto bad;
+ certfile = *(++argv);
+ } else if (strcmp(*argv, "-selfsign") == 0)
+ selfsign = 1;
+ else if (strcmp(*argv, "-in") == 0) {
+ if (--argc < 1)
+ goto bad;
+ infile = *(++argv);
+ req = 1;
+ } else if (strcmp(*argv, "-out") == 0) {
+ if (--argc < 1)
+ goto bad;
+ outfile = *(++argv);
+ } else if (strcmp(*argv, "-outdir") == 0) {
+ if (--argc < 1)
+ goto bad;
+ outdir = *(++argv);
+ } else if (strcmp(*argv, "-sigopt") == 0) {
+ if (--argc < 1)
+ goto bad;
+ if (!sigopts)
+ sigopts = sk_OPENSSL_STRING_new_null();
+ if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
+ goto bad;
+ } else if (strcmp(*argv, "-notext") == 0)
+ notext = 1;
+ else if (strcmp(*argv, "-batch") == 0)
+ batch = 1;
+ else if (strcmp(*argv, "-preserveDN") == 0)
+ preserve = 1;
+ else if (strcmp(*argv, "-noemailDN") == 0)
+ email_dn = 0;
+ else if (strcmp(*argv, "-gencrl") == 0)
+ gencrl = 1;
+ else if (strcmp(*argv, "-msie_hack") == 0)
+ msie_hack = 1;
+ else if (strcmp(*argv, "-crldays") == 0) {
+ if (--argc < 1)
+ goto bad;
+ crldays = atol(*(++argv));
+ } else if (strcmp(*argv, "-crlhours") == 0) {
+ if (--argc < 1)
+ goto bad;
+ crlhours = atol(*(++argv));
+ } else if (strcmp(*argv, "-crlsec") == 0) {
+ if (--argc < 1)
+ goto bad;
+ crlsec = atol(*(++argv));
+ } else if (strcmp(*argv, "-infiles") == 0) {
+ argc--;
+ argv++;
+ req = 1;
+ break;
+ } else if (strcmp(*argv, "-ss_cert") == 0) {
+ if (--argc < 1)
+ goto bad;
+ ss_cert_file = *(++argv);
+ req = 1;
+ } else if (strcmp(*argv, "-spkac") == 0) {
+ if (--argc < 1)
+ goto bad;
+ spkac_file = *(++argv);
+ req = 1;
+ } else if (strcmp(*argv, "-revoke") == 0) {
+ if (--argc < 1)
+ goto bad;
+ infile = *(++argv);
+ dorevoke = 1;
+ } else if (strcmp(*argv, "-valid") == 0) {
+ if (--argc < 1)
+ goto bad;
+ infile = *(++argv);
+ dorevoke = 2;
+ } else if (strcmp(*argv, "-extensions") == 0) {
+ if (--argc < 1)
+ goto bad;
+ extensions = *(++argv);
+ } else if (strcmp(*argv, "-extfile") == 0) {
+ if (--argc < 1)
+ goto bad;
+ extfile = *(++argv);
+ } else if (strcmp(*argv, "-status") == 0) {
+ if (--argc < 1)
+ goto bad;
+ ser_status = *(++argv);
+ } else if (strcmp(*argv, "-updatedb") == 0) {
+ doupdatedb = 1;
+ } else if (strcmp(*argv, "-crlexts") == 0) {
+ if (--argc < 1)
+ goto bad;
+ crl_ext = *(++argv);
+ } else if (strcmp(*argv, "-crl_reason") == 0) {
+ if (--argc < 1)
+ goto bad;
+ rev_arg = *(++argv);
+ rev_type = REV_CRL_REASON;
+ } else if (strcmp(*argv, "-crl_hold") == 0) {
+ if (--argc < 1)
+ goto bad;
+ rev_arg = *(++argv);
+ rev_type = REV_HOLD;
+ } else if (strcmp(*argv, "-crl_compromise") == 0) {
+ if (--argc < 1)
+ goto bad;
+ rev_arg = *(++argv);
+ rev_type = REV_KEY_COMPROMISE;
+ } else if (strcmp(*argv, "-crl_CA_compromise") == 0) {
+ if (--argc < 1)
+ goto bad;
+ rev_arg = *(++argv);
+ rev_type = REV_CA_COMPROMISE;
+ }
+#ifndef OPENSSL_NO_ENGINE
+ else if (strcmp(*argv, "-engine") == 0) {
+ if (--argc < 1)
+ goto bad;
+ engine = *(++argv);
+ }
+#endif
+ else {
+ bad:
+ BIO_printf(bio_err, "unknown option %s\n", *argv);
+ badops = 1;
+ break;
+ }
+ argc--;
+ argv++;
+ }
+
+ if (badops) {
+ const char **pp2;
+
+ for (pp2 = ca_usage; (*pp2 != NULL); pp2++)
+ BIO_printf(bio_err, "%s", *pp2);
+ goto err;
+ }
+
+ ERR_load_crypto_strings();
+
+ /*****************************************************************/
+ tofree = NULL;
+ if (configfile == NULL)
+ configfile = getenv("OPENSSL_CONF");
+ if (configfile == NULL)
+ configfile = getenv("SSLEAY_CONF");
+ if (configfile == NULL) {
+ const char *s = X509_get_default_cert_area();
+ size_t len;
+
+#ifdef OPENSSL_SYS_VMS
+ len = strlen(s) + sizeof(CONFIG_FILE);
+ tofree = OPENSSL_malloc(len);
+ if(!tofree) {
+ BIO_printf(bio_err, "Out of memory\n");
+ goto err;
+ }
+ strcpy(tofree, s);
+#else
+ len = strlen(s) + sizeof(CONFIG_FILE) + 1;
+ tofree = OPENSSL_malloc(len);
+ if(!tofree) {
+ BIO_printf(bio_err, "Out of memory\n");
+ goto err;
+ }
+ BUF_strlcpy(tofree, s, len);
+ BUF_strlcat(tofree, "/", len);
+#endif
+ BUF_strlcat(tofree, CONFIG_FILE, len);
+ configfile = tofree;
+ }
+
+ BIO_printf(bio_err, "Using configuration from %s\n", configfile);
+ conf = NCONF_new(NULL);
+ if (NCONF_load(conf, configfile, &errorline) <= 0) {
+ if (errorline <= 0)
+ BIO_printf(bio_err, "error loading the config file '%s'\n",
+ configfile);
+ else
+ BIO_printf(bio_err, "error on line %ld of config file '%s'\n",
+ errorline, configfile);
+ goto err;
+ }
+ if (tofree) {
+ OPENSSL_free(tofree);
+ tofree = NULL;
+ }
+
+ if (!load_config(bio_err, conf))
+ goto err;
+
+#ifndef OPENSSL_NO_ENGINE
+ e = setup_engine(bio_err, engine, 0);