1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ssl/tsrc/BC/libcrypto/topenssl/src/x509.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1279 @@
1.4 +/* apps/x509.c */
1.5 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
1.6 + * All rights reserved.
1.7 + *
1.8 + * This package is an SSL implementation written
1.9 + * by Eric Young (eay@cryptsoft.com).
1.10 + * The implementation was written so as to conform with Netscapes SSL.
1.11 + *
1.12 + * This library is free for commercial and non-commercial use as long as
1.13 + * the following conditions are aheared to. The following conditions
1.14 + * apply to all code found in this distribution, be it the RC4, RSA,
1.15 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1.16 + * included with this distribution is covered by the same copyright terms
1.17 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1.18 + *
1.19 + * Copyright remains Eric Young's, and as such any Copyright notices in
1.20 + * the code are not to be removed.
1.21 + * If this package is used in a product, Eric Young should be given attribution
1.22 + * as the author of the parts of the library used.
1.23 + * This can be in the form of a textual message at program startup or
1.24 + * in documentation (online or textual) provided with the package.
1.25 + *
1.26 + * Redistribution and use in source and binary forms, with or without
1.27 + * modification, are permitted provided that the following conditions
1.28 + * are met:
1.29 + * 1. Redistributions of source code must retain the copyright
1.30 + * notice, this list of conditions and the following disclaimer.
1.31 + * 2. Redistributions in binary form must reproduce the above copyright
1.32 + * notice, this list of conditions and the following disclaimer in the
1.33 + * documentation and/or other materials provided with the distribution.
1.34 + * 3. All advertising materials mentioning features or use of this software
1.35 + * must display the following acknowledgement:
1.36 + * "This product includes cryptographic software written by
1.37 + * Eric Young (eay@cryptsoft.com)"
1.38 + * The word 'cryptographic' can be left out if the rouines from the library
1.39 + * being used are not cryptographic related :-).
1.40 + * 4. If you include any Windows specific code (or a derivative thereof) from
1.41 + * the apps directory (application code) you must include an acknowledgement:
1.42 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1.43 + *
1.44 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1.45 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.46 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1.47 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1.48 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1.49 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1.50 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1.52 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1.53 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1.54 + * SUCH DAMAGE.
1.55 + *
1.56 + * The licence and distribution terms for any publically available version or
1.57 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1.58 + * copied and put under another distribution licence
1.59 + * [including the GNU Public Licence.]
1.60 + */
1.61 +
1.62 +#include <assert.h>
1.63 +#include <stdio.h>
1.64 +#include <stdlib.h>
1.65 +#include <string.h>
1.66 +#ifdef OPENSSL_NO_STDIO
1.67 +#define APPS_WIN16
1.68 +#endif
1.69 +#include "apps.h"
1.70 +#include <openssl/bio.h>
1.71 +#include <openssl/asn1.h>
1.72 +#include <openssl/err.h>
1.73 +#include <openssl/bn.h>
1.74 +#include <openssl/evp.h>
1.75 +#include <openssl/x509.h>
1.76 +#include <openssl/x509v3.h>
1.77 +#include <openssl/objects.h>
1.78 +#include <openssl/pem.h>
1.79 +#ifndef OPENSSL_NO_RSA
1.80 +#include <openssl/rsa.h>
1.81 +#endif
1.82 +#ifndef OPENSSL_NO_DSA
1.83 +#include <openssl/dsa.h>
1.84 +#endif
1.85 +
1.86 +#undef PROG
1.87 +#define PROG x509_main
1.88 +
1.89 +#undef POSTFIX
1.90 +#define POSTFIX ".srl"
1.91 +#define DEF_DAYS 30
1.92 +
1.93 +static const char *x509_usage[]={
1.94 +"usage: x509 args\n",
1.95 +" -inform arg - input format - default PEM (one of DER, NET or PEM)\n",
1.96 +" -outform arg - output format - default PEM (one of DER, NET or PEM)\n",
1.97 +" -keyform arg - private key format - default PEM\n",
1.98 +" -CAform arg - CA format - default PEM\n",
1.99 +" -CAkeyform arg - CA key format - default PEM\n",
1.100 +" -in arg - input file - default stdin\n",
1.101 +" -out arg - output file - default stdout\n",
1.102 +" -passin arg - private key password source\n",
1.103 +" -serial - print serial number value\n",
1.104 +" -subject_hash - print subject hash value\n",
1.105 +" -issuer_hash - print issuer hash value\n",
1.106 +" -hash - synonym for -subject_hash\n",
1.107 +" -subject - print subject DN\n",
1.108 +" -issuer - print issuer DN\n",
1.109 +" -email - print email address(es)\n",
1.110 +" -startdate - notBefore field\n",
1.111 +" -enddate - notAfter field\n",
1.112 +" -purpose - print out certificate purposes\n",
1.113 +" -dates - both Before and After dates\n",
1.114 +" -modulus - print the RSA key modulus\n",
1.115 +" -pubkey - output the public key\n",
1.116 +" -fingerprint - print the certificate fingerprint\n",
1.117 +" -alias - output certificate alias\n",
1.118 +" -noout - no certificate output\n",
1.119 +" -ocspid - print OCSP hash values for the subject name and public key\n",
1.120 +" -trustout - output a \"trusted\" certificate\n",
1.121 +" -clrtrust - clear all trusted purposes\n",
1.122 +" -clrreject - clear all rejected purposes\n",
1.123 +" -addtrust arg - trust certificate for a given purpose\n",
1.124 +" -addreject arg - reject certificate for a given purpose\n",
1.125 +" -setalias arg - set certificate alias\n",
1.126 +" -days arg - How long till expiry of a signed certificate - def 30 days\n",
1.127 +" -checkend arg - check whether the cert expires in the next arg seconds\n",
1.128 +" exit 1 if so, 0 if not\n",
1.129 +" -signkey arg - self sign cert with arg\n",
1.130 +" -x509toreq - output a certification request object\n",
1.131 +" -req - input is a certificate request, sign and output.\n",
1.132 +" -CA arg - set the CA certificate, must be PEM format.\n",
1.133 +" -CAkey arg - set the CA key, must be PEM format\n",
1.134 +" missing, it is assumed to be in the CA file.\n",
1.135 +" -CAcreateserial - create serial number file if it does not exist\n",
1.136 +" -CAserial arg - serial file\n",
1.137 +" -set_serial - serial number to use\n",
1.138 +" -text - print the certificate in text form\n",
1.139 +" -C - print out C code forms\n",
1.140 +" -md2/-md5/-sha1/-mdc2 - digest to use\n",
1.141 +" -extfile - configuration file with X509V3 extensions to add\n",
1.142 +" -extensions - section from config file with X509V3 extensions to add\n",
1.143 +" -clrext - delete extensions before signing and input certificate\n",
1.144 +" -nameopt arg - various certificate name options\n",
1.145 +#ifndef OPENSSL_NO_ENGINE
1.146 +" -engine e - use engine e, possibly a hardware device.\n",
1.147 +#endif
1.148 +" -certopt arg - various certificate text options\n",
1.149 +NULL
1.150 +};
1.151 +
1.152 +static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx);
1.153 +static int sign (X509 *x, EVP_PKEY *pkey,int days,int clrext, const EVP_MD *digest,
1.154 + CONF *conf, char *section);
1.155 +static int x509_certify (X509_STORE *ctx,char *CAfile,const EVP_MD *digest,
1.156 + X509 *x,X509 *xca,EVP_PKEY *pkey,char *serial,
1.157 + int create,int days, int clrext, CONF *conf, char *section,
1.158 + ASN1_INTEGER *sno);
1.159 +static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt);
1.160 +static int reqfile=0;
1.161 +
1.162 +
1.163 +int MAIN(int, char **);
1.164 +
1.165 +int MAIN(int argc, char **argv)
1.166 + {
1.167 + ENGINE *e = NULL;
1.168 + int ret=1;
1.169 + X509_REQ *req=NULL;
1.170 + X509 *x=NULL,*xca=NULL;
1.171 + ASN1_OBJECT *objtmp;
1.172 + EVP_PKEY *Upkey=NULL,*CApkey=NULL;
1.173 + ASN1_INTEGER *sno = NULL;
1.174 + int i,num,badops=0;
1.175 + BIO *out=NULL;
1.176 + BIO *STDout=NULL;
1.177 + STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
1.178 + int informat,outformat,keyformat,CAformat,CAkeyformat;
1.179 + char *infile=NULL,*outfile=NULL,*keyfile=NULL,*CAfile=NULL;
1.180 + char *CAkeyfile=NULL,*CAserial=NULL;
1.181 + char *alias=NULL;
1.182 + int text=0,serial=0,subject=0,issuer=0,startdate=0,enddate=0;
1.183 + int next_serial=0;
1.184 + int subject_hash=0,issuer_hash=0,ocspid=0;
1.185 + int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0;
1.186 + int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0;
1.187 + int C=0;
1.188 + int x509req=0,days=DEF_DAYS,modulus=0,pubkey=0;
1.189 + int pprint = 0;
1.190 + const char **pp;
1.191 + X509_STORE *ctx=NULL;
1.192 + X509_REQ *rq=NULL;
1.193 + int fingerprint=0;
1.194 + char buf[256];
1.195 + const EVP_MD *md_alg,*digest=EVP_sha1();
1.196 + CONF *extconf = NULL;
1.197 + char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL;
1.198 + int need_rand = 0;
1.199 + int checkend=0,checkoffset=0;
1.200 + unsigned long nmflag = 0, certflag = 0;
1.201 +#ifndef OPENSSL_NO_ENGINE
1.202 + char *engine=NULL;
1.203 +#endif
1.204 +
1.205 + reqfile=0;
1.206 +
1.207 + apps_startup();
1.208 +
1.209 + if (bio_err == NULL)
1.210 +
1.211 + bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
1.212 + if (!load_config(bio_err, NULL))
1.213 + goto end;
1.214 + STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
1.215 +#ifdef OPENSSL_SYS_VMS
1.216 + {
1.217 + BIO *tmpbio = BIO_new(BIO_f_linebuffer());
1.218 + STDout = BIO_push(tmpbio, STDout);
1.219 + }
1.220 +#endif
1.221 +
1.222 + informat=FORMAT_PEM;
1.223 + outformat=FORMAT_PEM;
1.224 + keyformat=FORMAT_PEM;
1.225 + CAformat=FORMAT_PEM;
1.226 + CAkeyformat=FORMAT_PEM;
1.227 +
1.228 + ctx=X509_STORE_new();
1.229 + if (ctx == NULL) goto end;
1.230 + X509_STORE_set_verify_cb_func(ctx,callb);
1.231 +
1.232 + argc--;
1.233 + argv++;
1.234 + num=0;
1.235 + while (argc >= 1)
1.236 + {
1.237 + if (strcmp(*argv,"-inform") == 0)
1.238 + {
1.239 + if (--argc < 1) goto bad;
1.240 + informat=str2fmt(*(++argv));
1.241 + }
1.242 + else if (strcmp(*argv,"-outform") == 0)
1.243 + {
1.244 + if (--argc < 1) goto bad;
1.245 + outformat=str2fmt(*(++argv));
1.246 + }
1.247 + else if (strcmp(*argv,"-keyform") == 0)
1.248 + {
1.249 + if (--argc < 1) goto bad;
1.250 + keyformat=str2fmt(*(++argv));
1.251 + }
1.252 + else if (strcmp(*argv,"-req") == 0)
1.253 + {
1.254 + reqfile=1;
1.255 + need_rand = 1;
1.256 + }
1.257 + else if (strcmp(*argv,"-CAform") == 0)
1.258 + {
1.259 + if (--argc < 1) goto bad;
1.260 + CAformat=str2fmt(*(++argv));
1.261 + }
1.262 + else if (strcmp(*argv,"-CAkeyform") == 0)
1.263 + {
1.264 + if (--argc < 1) goto bad;
1.265 + CAkeyformat=str2fmt(*(++argv));
1.266 + }
1.267 + else if (strcmp(*argv,"-days") == 0)
1.268 + {
1.269 + if (--argc < 1) goto bad;
1.270 + days=atoi(*(++argv));
1.271 + if (days == 0)
1.272 + {
1.273 + BIO_printf(STDout,"bad number of days\n");
1.274 + goto bad;
1.275 + }
1.276 + }
1.277 + else if (strcmp(*argv,"-passin") == 0)
1.278 + {
1.279 + if (--argc < 1) goto bad;
1.280 + passargin= *(++argv);
1.281 + }
1.282 + else if (strcmp(*argv,"-extfile") == 0)
1.283 + {
1.284 + if (--argc < 1) goto bad;
1.285 + extfile= *(++argv);
1.286 + }
1.287 + else if (strcmp(*argv,"-extensions") == 0)
1.288 + {
1.289 + if (--argc < 1) goto bad;
1.290 + extsect= *(++argv);
1.291 + }
1.292 + else if (strcmp(*argv,"-in") == 0)
1.293 + {
1.294 + if (--argc < 1) goto bad;
1.295 + infile= *(++argv);
1.296 + }
1.297 + else if (strcmp(*argv,"-out") == 0)
1.298 + {
1.299 + if (--argc < 1) goto bad;
1.300 + outfile= *(++argv);
1.301 + }
1.302 + else if (strcmp(*argv,"-signkey") == 0)
1.303 + {
1.304 + if (--argc < 1) goto bad;
1.305 + keyfile= *(++argv);
1.306 + sign_flag= ++num;
1.307 + need_rand = 1;
1.308 + }
1.309 + else if (strcmp(*argv,"-CA") == 0)
1.310 + {
1.311 + if (--argc < 1) goto bad;
1.312 + CAfile= *(++argv);
1.313 + CA_flag= ++num;
1.314 + need_rand = 1;
1.315 + }
1.316 + else if (strcmp(*argv,"-CAkey") == 0)
1.317 + {
1.318 + if (--argc < 1) goto bad;
1.319 + CAkeyfile= *(++argv);
1.320 + }
1.321 + else if (strcmp(*argv,"-CAserial") == 0)
1.322 + {
1.323 + if (--argc < 1) goto bad;
1.324 + CAserial= *(++argv);
1.325 + }
1.326 + else if (strcmp(*argv,"-set_serial") == 0)
1.327 + {
1.328 + if (--argc < 1) goto bad;
1.329 + if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv))))
1.330 + goto bad;
1.331 + }
1.332 + else if (strcmp(*argv,"-addtrust") == 0)
1.333 + {
1.334 + if (--argc < 1) goto bad;
1.335 + if (!(objtmp = OBJ_txt2obj(*(++argv), 0)))
1.336 + {
1.337 + BIO_printf(bio_err,
1.338 + "Invalid trust object value %s\n", *argv);
1.339 + goto bad;
1.340 + }
1.341 + if (!trust) trust = sk_ASN1_OBJECT_new_null();
1.342 + sk_ASN1_OBJECT_push(trust, objtmp);
1.343 + trustout = 1;
1.344 + }
1.345 + else if (strcmp(*argv,"-addreject") == 0)
1.346 + {
1.347 + if (--argc < 1) goto bad;
1.348 + if (!(objtmp = OBJ_txt2obj(*(++argv), 0)))
1.349 + {
1.350 + BIO_printf(bio_err,
1.351 + "Invalid reject object value %s\n", *argv);
1.352 + goto bad;
1.353 + }
1.354 + if (!reject) reject = sk_ASN1_OBJECT_new_null();
1.355 + sk_ASN1_OBJECT_push(reject, objtmp);
1.356 + trustout = 1;
1.357 + }
1.358 + else if (strcmp(*argv,"-setalias") == 0)
1.359 + {
1.360 + if (--argc < 1) goto bad;
1.361 + alias= *(++argv);
1.362 + trustout = 1;
1.363 + }
1.364 + else if (strcmp(*argv,"-certopt") == 0)
1.365 + {
1.366 + if (--argc < 1) goto bad;
1.367 + if (!set_cert_ex(&certflag, *(++argv))) goto bad;
1.368 + }
1.369 + else if (strcmp(*argv,"-nameopt") == 0)
1.370 + {
1.371 + if (--argc < 1) goto bad;
1.372 + if (!set_name_ex(&nmflag, *(++argv))) goto bad;
1.373 + }
1.374 +#ifndef OPENSSL_NO_ENGINE
1.375 + else if (strcmp(*argv,"-engine") == 0)
1.376 + {
1.377 + if (--argc < 1) goto bad;
1.378 + engine= *(++argv);
1.379 + }
1.380 +#endif
1.381 + else if (strcmp(*argv,"-C") == 0)
1.382 + C= ++num;
1.383 + else if (strcmp(*argv,"-email") == 0)
1.384 + email= ++num;
1.385 + else if (strcmp(*argv,"-serial") == 0)
1.386 + serial= ++num;
1.387 + else if (strcmp(*argv,"-next_serial") == 0)
1.388 + next_serial= ++num;
1.389 + else if (strcmp(*argv,"-modulus") == 0)
1.390 + modulus= ++num;
1.391 + else if (strcmp(*argv,"-pubkey") == 0)
1.392 + pubkey= ++num;
1.393 + else if (strcmp(*argv,"-x509toreq") == 0)
1.394 + x509req= ++num;
1.395 + else if (strcmp(*argv,"-text") == 0)
1.396 + text= ++num;
1.397 + else if (strcmp(*argv,"-hash") == 0
1.398 + || strcmp(*argv,"-subject_hash") == 0)
1.399 + subject_hash= ++num;
1.400 + else if (strcmp(*argv,"-issuer_hash") == 0)
1.401 + issuer_hash= ++num;
1.402 + else if (strcmp(*argv,"-subject") == 0)
1.403 + subject= ++num;
1.404 + else if (strcmp(*argv,"-issuer") == 0)
1.405 + issuer= ++num;
1.406 + else if (strcmp(*argv,"-fingerprint") == 0)
1.407 + fingerprint= ++num;
1.408 + else if (strcmp(*argv,"-dates") == 0)
1.409 + {
1.410 + startdate= ++num;
1.411 + enddate= ++num;
1.412 + }
1.413 + else if (strcmp(*argv,"-purpose") == 0)
1.414 + pprint= ++num;
1.415 + else if (strcmp(*argv,"-startdate") == 0)
1.416 + startdate= ++num;
1.417 + else if (strcmp(*argv,"-enddate") == 0)
1.418 + enddate= ++num;
1.419 + else if (strcmp(*argv,"-checkend") == 0)
1.420 + {
1.421 + if (--argc < 1) goto bad;
1.422 + checkoffset=atoi(*(++argv));
1.423 + checkend=1;
1.424 + }
1.425 + else if (strcmp(*argv,"-noout") == 0)
1.426 + noout= ++num;
1.427 + else if (strcmp(*argv,"-trustout") == 0)
1.428 + trustout= 1;
1.429 + else if (strcmp(*argv,"-clrtrust") == 0)
1.430 + clrtrust= ++num;
1.431 + else if (strcmp(*argv,"-clrreject") == 0)
1.432 + clrreject= ++num;
1.433 + else if (strcmp(*argv,"-alias") == 0)
1.434 + aliasout= ++num;
1.435 + else if (strcmp(*argv,"-CAcreateserial") == 0)
1.436 + CA_createserial= ++num;
1.437 + else if (strcmp(*argv,"-clrext") == 0)
1.438 + clrext = 1;
1.439 +#if 1 /* stay backwards-compatible with 0.9.5; this should go away soon */
1.440 + else if (strcmp(*argv,"-crlext") == 0)
1.441 + {
1.442 + BIO_printf(bio_err,"use -clrext instead of -crlext\n");
1.443 + clrext = 1;
1.444 + }
1.445 +#endif
1.446 + else if (strcmp(*argv,"-ocspid") == 0)
1.447 + ocspid= ++num;
1.448 + else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
1.449 + {
1.450 + /* ok */
1.451 + digest=md_alg;
1.452 + }
1.453 + else
1.454 + {
1.455 + BIO_printf(bio_err,"unknown option %s\n",*argv);
1.456 + badops=1;
1.457 + break;
1.458 + }
1.459 + argc--;
1.460 + argv++;
1.461 + }
1.462 +
1.463 + if (badops)
1.464 + {
1.465 +bad:
1.466 + for (pp=x509_usage; (*pp != NULL); pp++)
1.467 + BIO_printf(bio_err,"%s",*pp);
1.468 + goto end;
1.469 + }
1.470 +
1.471 +#ifndef OPENSSL_NO_ENGINE
1.472 + e = setup_engine(bio_err, engine, 0);
1.473 +#endif
1.474 +
1.475 + if (need_rand)
1.476 + app_RAND_load_file(NULL, bio_err, 0);
1.477 +
1.478 + ERR_load_crypto_strings();
1.479 +
1.480 + if (!app_passwd(bio_err, passargin, NULL, &passin, NULL))
1.481 + {
1.482 + BIO_printf(bio_err, "Error getting password\n");
1.483 + goto end;
1.484 + }
1.485 +
1.486 + if (!X509_STORE_set_default_paths(ctx))
1.487 + {
1.488 + ERR_print_errors(bio_err);
1.489 + goto end;
1.490 + }
1.491 +
1.492 + if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM))
1.493 + { CAkeyfile=CAfile; }
1.494 + else if ((CA_flag) && (CAkeyfile == NULL))
1.495 + {
1.496 + BIO_printf(bio_err,"need to specify a CAkey if using the CA command\n");
1.497 + goto end;
1.498 + }
1.499 +
1.500 + if (extfile)
1.501 + {
1.502 + long errorline = -1;
1.503 + X509V3_CTX ctx2;
1.504 + extconf = NCONF_new(NULL);
1.505 + if (!NCONF_load(extconf, extfile,&errorline))
1.506 + {
1.507 + if (errorline <= 0)
1.508 + BIO_printf(bio_err,
1.509 + "error loading the config file '%s'\n",
1.510 + extfile);
1.511 + else
1.512 + BIO_printf(bio_err,
1.513 + "error on line %ld of config file '%s'\n"
1.514 + ,errorline,extfile);
1.515 + goto end;
1.516 + }
1.517 + if (!extsect)
1.518 + {
1.519 + extsect = NCONF_get_string(extconf, "default", "extensions");
1.520 + if (!extsect)
1.521 + {
1.522 + ERR_clear_error();
1.523 + extsect = "default";
1.524 + }
1.525 + }
1.526 + X509V3_set_ctx_test(&ctx2);
1.527 + X509V3_set_nconf(&ctx2, extconf);
1.528 + if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL))
1.529 + {
1.530 + BIO_printf(bio_err,
1.531 + "Error Loading extension section %s\n",
1.532 + extsect);
1.533 + ERR_print_errors(bio_err);
1.534 + goto end;
1.535 + }
1.536 + }
1.537 +
1.538 +
1.539 + if (reqfile)
1.540 + {
1.541 + EVP_PKEY *pkey;
1.542 + X509_CINF *ci;
1.543 + BIO *in;
1.544 +
1.545 + if (!sign_flag && !CA_flag)
1.546 + {
1.547 + BIO_printf(bio_err,"We need a private key to sign with\n");
1.548 + goto end;
1.549 + }
1.550 + in=BIO_new(BIO_s_file());
1.551 + if (in == NULL)
1.552 + {
1.553 + ERR_print_errors(bio_err);
1.554 + goto end;
1.555 + }
1.556 +
1.557 + if (infile == NULL)
1.558 + BIO_set_fp(in,stdin,BIO_NOCLOSE|BIO_FP_TEXT);
1.559 + else
1.560 + {
1.561 + if (BIO_read_filename(in,infile) <= 0)
1.562 + {
1.563 + perror(infile);
1.564 + BIO_free(in);
1.565 + goto end;
1.566 + }
1.567 + }
1.568 + req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL);
1.569 + BIO_free(in);
1.570 +
1.571 + if (req == NULL)
1.572 + {
1.573 + ERR_print_errors(bio_err);
1.574 + goto end;
1.575 + }
1.576 +
1.577 + if ( (req->req_info == NULL) ||
1.578 + (req->req_info->pubkey == NULL) ||
1.579 + (req->req_info->pubkey->public_key == NULL) ||
1.580 + (req->req_info->pubkey->public_key->data == NULL))
1.581 + {
1.582 + BIO_printf(bio_err,"The certificate request appears to corrupted\n");
1.583 + BIO_printf(bio_err,"It does not contain a public key\n");
1.584 + goto end;
1.585 + }
1.586 + if ((pkey=X509_REQ_get_pubkey(req)) == NULL)
1.587 + {
1.588 + BIO_printf(bio_err,"error unpacking public key\n");
1.589 + goto end;
1.590 + }
1.591 + i=X509_REQ_verify(req,pkey);
1.592 + EVP_PKEY_free(pkey);
1.593 + if (i < 0)
1.594 + {
1.595 + BIO_printf(bio_err,"Signature verification error\n");
1.596 + ERR_print_errors(bio_err);
1.597 + goto end;
1.598 + }
1.599 + if (i == 0)
1.600 + {
1.601 + BIO_printf(bio_err,"Signature did not match the certificate request\n");
1.602 + goto end;
1.603 + }
1.604 + else
1.605 + BIO_printf(bio_err,"Signature ok\n");
1.606 +
1.607 + print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), nmflag);
1.608 +
1.609 + if ((x=X509_new()) == NULL) goto end;
1.610 + ci=x->cert_info;
1.611 +
1.612 + if (sno == NULL)
1.613 + {
1.614 + sno = ASN1_INTEGER_new();
1.615 + if (!sno || !rand_serial(NULL, sno))
1.616 + goto end;
1.617 + if (!X509_set_serialNumber(x, sno))
1.618 + goto end;
1.619 + ASN1_INTEGER_free(sno);
1.620 + sno = NULL;
1.621 + }
1.622 + else if (!X509_set_serialNumber(x, sno))
1.623 + goto end;
1.624 +
1.625 + if (!X509_set_issuer_name(x,req->req_info->subject)) goto end;
1.626 + if (!X509_set_subject_name(x,req->req_info->subject)) goto end;
1.627 +
1.628 + X509_gmtime_adj(X509_get_notBefore(x),0);
1.629 + X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);
1.630 +
1.631 + pkey = X509_REQ_get_pubkey(req);
1.632 + X509_set_pubkey(x,pkey);
1.633 + EVP_PKEY_free(pkey);
1.634 + }
1.635 + else
1.636 + x=load_cert(bio_err,infile,informat,NULL,e,"Certificate");
1.637 +
1.638 + if (x == NULL) goto end;
1.639 + if (CA_flag)
1.640 + {
1.641 + xca=load_cert(bio_err,CAfile,CAformat,NULL,e,"CA Certificate");
1.642 + if (xca == NULL) goto end;
1.643 + }
1.644 +
1.645 + if (!noout || text || next_serial)
1.646 + {
1.647 + OBJ_create("2.99999.3",
1.648 + "SET.ex3","SET x509v3 extension 3");
1.649 +
1.650 + out=BIO_new(BIO_s_file());
1.651 + if (out == NULL)
1.652 + {
1.653 + ERR_print_errors(bio_err);
1.654 + goto end;
1.655 + }
1.656 + if (outfile == NULL)
1.657 + {
1.658 + BIO_set_fp(out,stdout,BIO_NOCLOSE);
1.659 +#ifdef OPENSSL_SYS_VMS
1.660 + {
1.661 + BIO *tmpbio = BIO_new(BIO_f_linebuffer());
1.662 + out = BIO_push(tmpbio, out);
1.663 + }
1.664 +#endif
1.665 + }
1.666 + else
1.667 + {
1.668 + if (BIO_write_filename(out,outfile) <= 0)
1.669 + {
1.670 + perror(outfile);
1.671 + goto end;
1.672 + }
1.673 + }
1.674 + }
1.675 +
1.676 + if (alias) X509_alias_set1(x, (unsigned char *)alias, -1);
1.677 +
1.678 + if (clrtrust) X509_trust_clear(x);
1.679 + if (clrreject) X509_reject_clear(x);
1.680 +
1.681 + if (trust)
1.682 + {
1.683 + for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++)
1.684 + {
1.685 + objtmp = sk_ASN1_OBJECT_value(trust, i);
1.686 + X509_add1_trust_object(x, objtmp);
1.687 + }
1.688 + }
1.689 +
1.690 + if (reject)
1.691 + {
1.692 + for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++)
1.693 + {
1.694 + objtmp = sk_ASN1_OBJECT_value(reject, i);
1.695 + X509_add1_reject_object(x, objtmp);
1.696 + }
1.697 + }
1.698 +
1.699 + if (num)
1.700 + {
1.701 + for (i=1; i<=num; i++)
1.702 + {
1.703 + if (issuer == i)
1.704 + {
1.705 + print_name(STDout, "issuer= ",
1.706 + X509_get_issuer_name(x), nmflag);
1.707 + }
1.708 + else if (subject == i)
1.709 + {
1.710 + print_name(STDout, "subject= ",
1.711 + X509_get_subject_name(x), nmflag);
1.712 + }
1.713 + else if (serial == i)
1.714 + {
1.715 + BIO_printf(STDout,"serial=");
1.716 + i2a_ASN1_INTEGER(STDout,
1.717 + X509_get_serialNumber(x));
1.718 + BIO_printf(STDout,"\n");
1.719 + }
1.720 + else if (next_serial == i)
1.721 + {
1.722 + BIGNUM *bnser;
1.723 + ASN1_INTEGER *ser;
1.724 + ser = X509_get_serialNumber(x);
1.725 + bnser = ASN1_INTEGER_to_BN(ser, NULL);
1.726 + if (!bnser)
1.727 + goto end;
1.728 + if (!BN_add_word(bnser, 1))
1.729 + goto end;
1.730 + ser = BN_to_ASN1_INTEGER(bnser, NULL);
1.731 + if (!ser)
1.732 + goto end;
1.733 + BN_free(bnser);
1.734 + i2a_ASN1_INTEGER(out, ser);
1.735 + ASN1_INTEGER_free(ser);
1.736 + BIO_puts(out, "\n");
1.737 + }
1.738 + else if (email == i)
1.739 + {
1.740 + int j;
1.741 + STACK *emlst;
1.742 + emlst = X509_get1_email(x);
1.743 + for (j = 0; j < sk_num(emlst); j++)
1.744 + BIO_printf(STDout, "%s\n", sk_value(emlst, j));
1.745 + X509_email_free(emlst);
1.746 + }
1.747 + else if (aliasout == i)
1.748 + {
1.749 + unsigned char *alstr;
1.750 + alstr = X509_alias_get0(x, NULL);
1.751 + if (alstr) BIO_printf(STDout,"%s\n", alstr);
1.752 + else BIO_puts(STDout,"<No Alias>\n");
1.753 + }
1.754 + else if (subject_hash == i)
1.755 + {
1.756 + BIO_printf(STDout,"%08lx\n",X509_subject_name_hash(x));
1.757 + }
1.758 + else if (issuer_hash == i)
1.759 + {
1.760 + BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash(x));
1.761 + }
1.762 + else if (pprint == i)
1.763 + {
1.764 + X509_PURPOSE *ptmp;
1.765 + int j;
1.766 + BIO_printf(STDout, "Certificate purposes:\n");
1.767 + for (j = 0; j < X509_PURPOSE_get_count(); j++)
1.768 + {
1.769 + ptmp = X509_PURPOSE_get0(j);
1.770 + purpose_print(STDout, x, ptmp);
1.771 + }
1.772 + }
1.773 + else
1.774 + if (modulus == i)
1.775 + {
1.776 + EVP_PKEY *pkey;
1.777 +
1.778 + pkey=X509_get_pubkey(x);
1.779 + if (pkey == NULL)
1.780 + {
1.781 + BIO_printf(bio_err,"Modulus=unavailable\n");
1.782 + ERR_print_errors(bio_err);
1.783 + goto end;
1.784 + }
1.785 + BIO_printf(STDout,"Modulus=");
1.786 +#ifndef OPENSSL_NO_RSA
1.787 + if (pkey->type == EVP_PKEY_RSA)
1.788 + BN_print(STDout,pkey->pkey.rsa->n);
1.789 + else
1.790 +#endif
1.791 +#ifndef OPENSSL_NO_DSA
1.792 + if (pkey->type == EVP_PKEY_DSA)
1.793 + BN_print(STDout,pkey->pkey.dsa->pub_key);
1.794 + else
1.795 +#endif
1.796 + BIO_printf(STDout,"Wrong Algorithm type");
1.797 + BIO_printf(STDout,"\n");
1.798 + EVP_PKEY_free(pkey);
1.799 + }
1.800 + else
1.801 + if (pubkey == i)
1.802 + {
1.803 + EVP_PKEY *pkey;
1.804 +
1.805 + pkey=X509_get_pubkey(x);
1.806 + if (pkey == NULL)
1.807 + {
1.808 + BIO_printf(bio_err,"Error getting public key\n");
1.809 + ERR_print_errors(bio_err);
1.810 + goto end;
1.811 + }
1.812 + PEM_write_bio_PUBKEY(STDout, pkey);
1.813 + EVP_PKEY_free(pkey);
1.814 + }
1.815 + else
1.816 + if (C == i)
1.817 + {
1.818 + unsigned char *d;
1.819 + char *m;
1.820 + int y,z;
1.821 +
1.822 + X509_NAME_oneline(X509_get_subject_name(x),
1.823 + buf,sizeof buf);
1.824 + BIO_printf(STDout,"/* subject:%s */\n",buf);
1.825 + m=X509_NAME_oneline(
1.826 + X509_get_issuer_name(x),buf,
1.827 + sizeof buf);
1.828 + BIO_printf(STDout,"/* issuer :%s */\n",buf);
1.829 +
1.830 + z=i2d_X509(x,NULL);
1.831 + m=OPENSSL_malloc(z);
1.832 +
1.833 + d=(unsigned char *)m;
1.834 + z=i2d_X509_NAME(X509_get_subject_name(x),&d);
1.835 + BIO_printf(STDout,"unsigned char XXX_subject_name[%d]={\n",z);
1.836 + d=(unsigned char *)m;
1.837 + for (y=0; y<z; y++)
1.838 + {
1.839 + BIO_printf(STDout,"0x%02X,",d[y]);
1.840 + if ((y & 0x0f) == 0x0f) BIO_printf(STDout,"\n");
1.841 + }
1.842 + if (y%16 != 0) BIO_printf(STDout,"\n");
1.843 + BIO_printf(STDout,"};\n");
1.844 +
1.845 + z=i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x),&d);
1.846 + BIO_printf(STDout,"unsigned char XXX_public_key[%d]={\n",z);
1.847 + d=(unsigned char *)m;
1.848 + for (y=0; y<z; y++)
1.849 + {
1.850 + BIO_printf(STDout,"0x%02X,",d[y]);
1.851 + if ((y & 0x0f) == 0x0f)
1.852 + BIO_printf(STDout,"\n");
1.853 + }
1.854 + if (y%16 != 0) BIO_printf(STDout,"\n");
1.855 + BIO_printf(STDout,"};\n");
1.856 +
1.857 + z=i2d_X509(x,&d);
1.858 + BIO_printf(STDout,"unsigned char XXX_certificate[%d]={\n",z);
1.859 + d=(unsigned char *)m;
1.860 + for (y=0; y<z; y++)
1.861 + {
1.862 + BIO_printf(STDout,"0x%02X,",d[y]);
1.863 + if ((y & 0x0f) == 0x0f)
1.864 + BIO_printf(STDout,"\n");
1.865 + }
1.866 + if (y%16 != 0) BIO_printf(STDout,"\n");
1.867 + BIO_printf(STDout,"};\n");
1.868 +
1.869 + OPENSSL_free(m);
1.870 + }
1.871 + else if (text == i)
1.872 + {
1.873 + X509_print_ex(out,x,nmflag, certflag);
1.874 + }
1.875 + else if (startdate == i)
1.876 + {
1.877 + BIO_puts(STDout,"notBefore=");
1.878 + ASN1_TIME_print(STDout,X509_get_notBefore(x));
1.879 + BIO_puts(STDout,"\n");
1.880 + }
1.881 + else if (enddate == i)
1.882 + {
1.883 + BIO_puts(STDout,"notAfter=");
1.884 + ASN1_TIME_print(STDout,X509_get_notAfter(x));
1.885 + BIO_puts(STDout,"\n");
1.886 + }
1.887 + else if (fingerprint == i)
1.888 + {
1.889 + int j;
1.890 + unsigned int n;
1.891 + unsigned char md[EVP_MAX_MD_SIZE];
1.892 +
1.893 + if (!X509_digest(x,digest,md,&n))
1.894 + {
1.895 + BIO_printf(bio_err,"out of memory\n");
1.896 + goto end;
1.897 + }
1.898 + BIO_printf(STDout,"%s Fingerprint=",
1.899 + OBJ_nid2sn(EVP_MD_type(digest)));
1.900 + for (j=0; j<(int)n; j++)
1.901 + {
1.902 + BIO_printf(STDout,"%02X%c",md[j],
1.903 + (j+1 == (int)n)
1.904 + ?'\n':':');
1.905 + }
1.906 + }
1.907 +
1.908 + /* should be in the library */
1.909 + else if ((sign_flag == i) && (x509req == 0))
1.910 + {
1.911 + BIO_printf(bio_err,"Getting Private key\n");
1.912 + if (Upkey == NULL)
1.913 + {
1.914 + Upkey=load_key(bio_err,
1.915 + keyfile, keyformat, 0,
1.916 + passin, e, "Private key");
1.917 + if (Upkey == NULL) goto end;
1.918 + }
1.919 +#ifndef OPENSSL_NO_DSA
1.920 + if (Upkey->type == EVP_PKEY_DSA)
1.921 + digest=EVP_dss1();
1.922 +#endif
1.923 +#ifndef OPENSSL_NO_ECDSA
1.924 + if (Upkey->type == EVP_PKEY_EC)
1.925 + digest=EVP_ecdsa();
1.926 +#endif
1.927 +
1.928 + assert(need_rand);
1.929 + if (!sign(x,Upkey,days,clrext,digest,
1.930 + extconf, extsect)) goto end;
1.931 + }
1.932 + else if (CA_flag == i)
1.933 + {
1.934 + BIO_printf(bio_err,"Getting CA Private Key\n");
1.935 + if (CAkeyfile != NULL)
1.936 + {
1.937 + CApkey=load_key(bio_err,
1.938 + CAkeyfile, CAkeyformat,
1.939 + 0, passin, e,
1.940 + "CA Private Key");
1.941 + if (CApkey == NULL) goto end;
1.942 + }
1.943 +#ifndef OPENSSL_NO_DSA
1.944 + if (CApkey->type == EVP_PKEY_DSA)
1.945 + digest=EVP_dss1();
1.946 +#endif
1.947 +#ifndef OPENSSL_NO_ECDSA
1.948 + if (CApkey->type == EVP_PKEY_EC)
1.949 + digest = EVP_ecdsa();
1.950 +#endif
1.951 +
1.952 + assert(need_rand);
1.953 + if (!x509_certify(ctx,CAfile,digest,x,xca,
1.954 + CApkey, CAserial,CA_createserial,days, clrext,
1.955 + extconf, extsect, sno))
1.956 + goto end;
1.957 + }
1.958 + else if (x509req == i)
1.959 + {
1.960 + EVP_PKEY *pk;
1.961 +
1.962 + BIO_printf(bio_err,"Getting request Private Key\n");
1.963 + if (keyfile == NULL)
1.964 + {
1.965 + BIO_printf(bio_err,"no request key file specified\n");
1.966 + goto end;
1.967 + }
1.968 + else
1.969 + {
1.970 + pk=load_key(bio_err,
1.971 + keyfile, FORMAT_PEM, 0,
1.972 + passin, e, "request key");
1.973 + if (pk == NULL) goto end;
1.974 + }
1.975 +
1.976 + BIO_printf(bio_err,"Generating certificate request\n");
1.977 +
1.978 +#ifndef OPENSSL_NO_DSA
1.979 + if (pk->type == EVP_PKEY_DSA)
1.980 + digest=EVP_dss1();
1.981 +#endif
1.982 +#ifndef OPENSSL_NO_ECDSA
1.983 + if (pk->type == EVP_PKEY_EC)
1.984 + digest=EVP_ecdsa();
1.985 +#endif
1.986 +
1.987 + rq=X509_to_X509_REQ(x,pk,digest);
1.988 + EVP_PKEY_free(pk);
1.989 + if (rq == NULL)
1.990 + {
1.991 + ERR_print_errors(bio_err);
1.992 + goto end;
1.993 + }
1.994 + if (!noout)
1.995 + {
1.996 + X509_REQ_print(out,rq);
1.997 + PEM_write_bio_X509_REQ(out,rq);
1.998 + }
1.999 + noout=1;
1.1000 + }
1.1001 + else if (ocspid == i)
1.1002 + {
1.1003 + X509_ocspid_print(out, x);
1.1004 + }
1.1005 + }
1.1006 + }
1.1007 +
1.1008 + if (checkend)
1.1009 + {
1.1010 + time_t tcheck=time(NULL) + checkoffset;
1.1011 +
1.1012 + if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0)
1.1013 + {
1.1014 + BIO_printf(out,"Certificate will expire\n");
1.1015 + ret=1;
1.1016 + }
1.1017 + else
1.1018 + {
1.1019 + BIO_printf(out,"Certificate will not expire\n");
1.1020 + ret=0;
1.1021 + }
1.1022 + goto end;
1.1023 + }
1.1024 +
1.1025 + if (noout)
1.1026 + {
1.1027 + ret=0;
1.1028 + goto end;
1.1029 + }
1.1030 +
1.1031 + if (outformat == FORMAT_ASN1)
1.1032 + i=i2d_X509_bio(out,x);
1.1033 + else if (outformat == FORMAT_PEM)
1.1034 + {
1.1035 + if (trustout) i=PEM_write_bio_X509_AUX(out,x);
1.1036 + else i=PEM_write_bio_X509(out,x);
1.1037 + }
1.1038 + else if (outformat == FORMAT_NETSCAPE)
1.1039 + {
1.1040 + ASN1_HEADER ah;
1.1041 + ASN1_OCTET_STRING os;
1.1042 +
1.1043 + os.data=(unsigned char *)NETSCAPE_CERT_HDR;
1.1044 + os.length=strlen(NETSCAPE_CERT_HDR);
1.1045 + ah.header= &os;
1.1046 + ah.data=(char *)x;
1.1047 + ah.meth=X509_asn1_meth();
1.1048 +
1.1049 + i=ASN1_i2d_bio_of(ASN1_HEADER,i2d_ASN1_HEADER,out,&ah);
1.1050 + }
1.1051 + else {
1.1052 + BIO_printf(bio_err,"bad output format specified for outfile\n");
1.1053 + goto end;
1.1054 + }
1.1055 + if (!i)
1.1056 + {
1.1057 + BIO_printf(bio_err,"unable to write certificate\n");
1.1058 + ERR_print_errors(bio_err);
1.1059 + goto end;
1.1060 + }
1.1061 + ret=0;
1.1062 +end:
1.1063 + if (need_rand)
1.1064 + app_RAND_write_file(NULL, bio_err);
1.1065 + OBJ_cleanup();
1.1066 + NCONF_free(extconf);
1.1067 + BIO_free_all(out);
1.1068 + BIO_free_all(STDout);
1.1069 + X509_STORE_free(ctx);
1.1070 + X509_REQ_free(req);
1.1071 + X509_free(x);
1.1072 + X509_free(xca);
1.1073 + EVP_PKEY_free(Upkey);
1.1074 + EVP_PKEY_free(CApkey);
1.1075 + X509_REQ_free(rq);
1.1076 + ASN1_INTEGER_free(sno);
1.1077 + sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
1.1078 + sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
1.1079 + if (passin) OPENSSL_free(passin);
1.1080 + apps_shutdown();
1.1081 + OPENSSL_EXIT(ret);
1.1082 + }
1.1083 +
1.1084 +static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile, int create)
1.1085 + {
1.1086 + char *buf = NULL, *p;
1.1087 + ASN1_INTEGER *bs = NULL;
1.1088 + BIGNUM *serial = NULL;
1.1089 + size_t len;
1.1090 +
1.1091 + len = ((serialfile == NULL)
1.1092 + ?(strlen(CAfile)+strlen(POSTFIX)+1)
1.1093 + :(strlen(serialfile)))+1;
1.1094 + buf=OPENSSL_malloc(len);
1.1095 + if (buf == NULL) { BIO_printf(bio_err,"out of mem\n"); goto end; }
1.1096 + if (serialfile == NULL)
1.1097 + {
1.1098 + BUF_strlcpy(buf,CAfile,len);
1.1099 + for (p=buf; *p; p++)
1.1100 + if (*p == '.')
1.1101 + {
1.1102 + *p='\0';
1.1103 + break;
1.1104 + }
1.1105 + BUF_strlcat(buf,POSTFIX,len);
1.1106 + }
1.1107 + else
1.1108 + BUF_strlcpy(buf,serialfile,len);
1.1109 +
1.1110 + serial = load_serial(buf, create, NULL);
1.1111 + if (serial == NULL) goto end;
1.1112 +
1.1113 + if (!BN_add_word(serial,1))
1.1114 + { BIO_printf(bio_err,"add_word failure\n"); goto end; }
1.1115 +
1.1116 + if (!save_serial(buf, NULL, serial, &bs)) goto end;
1.1117 +
1.1118 + end:
1.1119 + if (buf) OPENSSL_free(buf);
1.1120 + BN_free(serial);
1.1121 + return bs;
1.1122 + }
1.1123 +
1.1124 +static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
1.1125 + X509 *x, X509 *xca, EVP_PKEY *pkey, char *serialfile, int create,
1.1126 + int days, int clrext, CONF *conf, char *section, ASN1_INTEGER *sno)
1.1127 + {
1.1128 + int ret=0;
1.1129 + ASN1_INTEGER *bs=NULL;
1.1130 + X509_STORE_CTX xsc;
1.1131 + EVP_PKEY *upkey;
1.1132 +
1.1133 + upkey = X509_get_pubkey(xca);
1.1134 + EVP_PKEY_copy_parameters(upkey,pkey);
1.1135 + EVP_PKEY_free(upkey);
1.1136 +
1.1137 + if(!X509_STORE_CTX_init(&xsc,ctx,x,NULL))
1.1138 + {
1.1139 + BIO_printf(bio_err,"Error initialising X509 store\n");
1.1140 + goto end;
1.1141 + }
1.1142 + if (sno) bs = sno;
1.1143 + else if (!(bs = x509_load_serial(CAfile, serialfile, create)))
1.1144 + goto end;
1.1145 +
1.1146 +/* if (!X509_STORE_add_cert(ctx,x)) goto end;*/
1.1147 +
1.1148 + /* NOTE: this certificate can/should be self signed, unless it was
1.1149 + * a certificate request in which case it is not. */
1.1150 + X509_STORE_CTX_set_cert(&xsc,x);
1.1151 + if (!reqfile && !X509_verify_cert(&xsc))
1.1152 + goto end;
1.1153 +
1.1154 + if (!X509_check_private_key(xca,pkey))
1.1155 + {
1.1156 + BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
1.1157 + goto end;
1.1158 + }
1.1159 +
1.1160 + if (!X509_set_issuer_name(x,X509_get_subject_name(xca))) goto end;
1.1161 + if (!X509_set_serialNumber(x,bs)) goto end;
1.1162 +
1.1163 + if (X509_gmtime_adj(X509_get_notBefore(x),0L) == NULL)
1.1164 + goto end;
1.1165 +
1.1166 + /* hardwired expired */
1.1167 + if (X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days) == NULL)
1.1168 + goto end;
1.1169 +
1.1170 + if (clrext)
1.1171 + {
1.1172 + while (X509_get_ext_count(x) > 0) X509_delete_ext(x, 0);
1.1173 + }
1.1174 +
1.1175 + if (conf)
1.1176 + {
1.1177 + X509V3_CTX ctx2;
1.1178 + X509_set_version(x,2); /* version 3 certificate */
1.1179 + X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
1.1180 + X509V3_set_nconf(&ctx2, conf);
1.1181 + if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x)) goto end;
1.1182 + }
1.1183 +
1.1184 + if (!X509_sign(x,pkey,digest)) goto end;
1.1185 + ret=1;
1.1186 +end:
1.1187 + X509_STORE_CTX_cleanup(&xsc);
1.1188 + if (!ret)
1.1189 + ERR_print_errors(bio_err);
1.1190 + if (!sno) ASN1_INTEGER_free(bs);
1.1191 + return ret;
1.1192 + }
1.1193 +
1.1194 +static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx)
1.1195 + {
1.1196 + int err;
1.1197 + X509 *err_cert;
1.1198 +
1.1199 + /* it is ok to use a self signed certificate
1.1200 + * This case will catch both the initial ok == 0 and the
1.1201 + * final ok == 1 calls to this function */
1.1202 + err=X509_STORE_CTX_get_error(ctx);
1.1203 + if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
1.1204 + return 1;
1.1205 +
1.1206 + /* BAD we should have gotten an error. Normally if everything
1.1207 + * worked X509_STORE_CTX_get_error(ctx) will still be set to
1.1208 + * DEPTH_ZERO_SELF_.... */
1.1209 + if (ok)
1.1210 + {
1.1211 + BIO_printf(bio_err,"error with certificate to be certified - should be self signed\n");
1.1212 + return 0;
1.1213 + }
1.1214 + else
1.1215 + {
1.1216 + err_cert=X509_STORE_CTX_get_current_cert(ctx);
1.1217 + print_name(bio_err, NULL, X509_get_subject_name(err_cert),0);
1.1218 + BIO_printf(bio_err,"error with certificate - error %d at depth %d\n%s\n",
1.1219 + err,X509_STORE_CTX_get_error_depth(ctx),
1.1220 + X509_verify_cert_error_string(err));
1.1221 + return 1;
1.1222 + }
1.1223 + }
1.1224 +
1.1225 +/* self sign */
1.1226 +static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest,
1.1227 + CONF *conf, char *section)
1.1228 + {
1.1229 +
1.1230 + EVP_PKEY *pktmp;
1.1231 +
1.1232 + pktmp = X509_get_pubkey(x);
1.1233 + EVP_PKEY_copy_parameters(pktmp,pkey);
1.1234 + EVP_PKEY_save_parameters(pktmp,1);
1.1235 + EVP_PKEY_free(pktmp);
1.1236 +
1.1237 + if (!X509_set_issuer_name(x,X509_get_subject_name(x))) goto err;
1.1238 + if (X509_gmtime_adj(X509_get_notBefore(x),0) == NULL) goto err;
1.1239 +
1.1240 + /* Lets just make it 12:00am GMT, Jan 1 1970 */
1.1241 + /* memcpy(x->cert_info->validity->notBefore,"700101120000Z",13); */
1.1242 + /* 28 days to be certified */
1.1243 +
1.1244 + if (X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days) == NULL)
1.1245 + goto err;
1.1246 +
1.1247 + if (!X509_set_pubkey(x,pkey)) goto err;
1.1248 + if (clrext)
1.1249 + {
1.1250 + while (X509_get_ext_count(x) > 0) X509_delete_ext(x, 0);
1.1251 + }
1.1252 + if (conf)
1.1253 + {
1.1254 + X509V3_CTX ctx;
1.1255 + X509_set_version(x,2); /* version 3 certificate */
1.1256 + X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0);
1.1257 + X509V3_set_nconf(&ctx, conf);
1.1258 + if (!X509V3_EXT_add_nconf(conf, &ctx, section, x)) goto err;
1.1259 + }
1.1260 + if (!X509_sign(x,pkey,digest)) goto err;
1.1261 + return 1;
1.1262 +err:
1.1263 + ERR_print_errors(bio_err);
1.1264 + return 0;
1.1265 + }
1.1266 +
1.1267 +static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt)
1.1268 +{
1.1269 + int id, i, idret;
1.1270 + char *pname;
1.1271 + id = X509_PURPOSE_get_id(pt);
1.1272 + pname = X509_PURPOSE_get0_name(pt);
1.1273 + for (i = 0; i < 2; i++)
1.1274 + {
1.1275 + idret = X509_check_purpose(cert, id, i);
1.1276 + BIO_printf(bio, "%s%s : ", pname, i ? " CA" : "");
1.1277 + if (idret == 1) BIO_printf(bio, "Yes\n");
1.1278 + else if (idret == 0) BIO_printf(bio, "No\n");
1.1279 + else BIO_printf(bio, "Yes (WARNING code=%d)\n", idret);
1.1280 + }
1.1281 + return 1;
1.1282 +}