X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=apps%2Fx509.c;h=8e4462dae765282310e234932452a0dc2344b37a;hp=b86352e2fbd8eaa923f35bbd1c7cfb7ddabbafb2;hb=06b7c8d5baa8be9300b5a038f4d967c06a3a73f9;hpb=61f175f4ba3d90de1fac060080c99aa193764665 diff --git a/apps/x509.c b/apps/x509.c index b86352e2fb..8e4462dae7 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -60,7 +60,7 @@ #include #include #include -#ifdef NO_STDIO +#ifdef OPENSSL_NO_STDIO #define APPS_WIN16 #endif #include "apps.h" @@ -105,6 +105,7 @@ static char *x509_usage[]={ " -fingerprint - print the certificate fingerprint\n", " -alias - output certificate alias\n", " -noout - no certificate output\n", +" -ocspid - print OCSP hash values for the subject name and public key\n", " -trustout - output a \"trusted\" certificate\n", " -clrtrust - clear all trusted purposes\n", " -clrreject - clear all rejected purposes\n", @@ -121,7 +122,8 @@ static char *x509_usage[]={ " -CAkey arg - set the CA key, must be PEM format\n", " missing, it is assumed to be in the CA file.\n", " -CAcreateserial - create serial number file if it does not exist\n", -" -CAserial - serial file\n", +" -CAserial arg - serial file\n", +" -set_serial - serial number to use\n", " -text - print the certificate in text form\n", " -C - print out C code forms\n", " -md2/-md5/-sha1/-mdc2 - digest to use\n", @@ -129,15 +131,18 @@ static char *x509_usage[]={ " -extensions - section from config file with X509V3 extensions to add\n", " -clrext - delete extensions before signing and input certificate\n", " -nameopt arg - various certificate name options\n", +" -engine e - use engine e, possibly a hardware device.\n", +" -certopt arg - various certificate text options\n", NULL }; static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx); static int sign (X509 *x, EVP_PKEY *pkey,int days,int clrext, const EVP_MD *digest, - LHASH *conf, char *section); + CONF *conf, char *section); static int x509_certify (X509_STORE *ctx,char *CAfile,const EVP_MD *digest, X509 *x,X509 *xca,EVP_PKEY *pkey,char *serial, - int create,int days, int clrext, LHASH *conf, char *section); + int create,int days, int clrext, CONF *conf, char *section, + ASN1_INTEGER *sno); static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt); static int reqfile=0; @@ -145,11 +150,13 @@ int MAIN(int, char **); int MAIN(int argc, char **argv) { + ENGINE *e = NULL; int ret=1; X509_REQ *req=NULL; X509 *x=NULL,*xca=NULL; ASN1_OBJECT *objtmp; EVP_PKEY *Upkey=NULL,*CApkey=NULL; + ASN1_INTEGER *sno = NULL; int i,num,badops=0; BIO *out=NULL; BIO *STDout=NULL; @@ -159,6 +166,7 @@ int MAIN(int argc, char **argv) char *CAkeyfile=NULL,*CAserial=NULL; char *alias=NULL; int text=0,serial=0,hash=0,subject=0,issuer=0,startdate=0,enddate=0; + int ocspid=0; int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0; int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0; int C=0; @@ -170,11 +178,12 @@ int MAIN(int argc, char **argv) int fingerprint=0; char buf[256]; const EVP_MD *md_alg,*digest=EVP_md5(); - LHASH *extconf = NULL; + CONF *extconf = NULL; char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL; int need_rand = 0; int checkend=0,checkoffset=0; - unsigned long nmflag = 0; + unsigned long nmflag = 0, certflag = 0; + char *engine=NULL; reqfile=0; @@ -182,7 +191,16 @@ int MAIN(int argc, char **argv) if (bio_err == NULL) bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); + + if (!load_config(bio_err, NULL)) + goto end; STDout=BIO_new_fp(stdout,BIO_NOCLOSE); +#ifdef OPENSSL_SYS_VMS + { + BIO *tmpbio = BIO_new(BIO_f_linebuffer()); + STDout = BIO_push(tmpbio, STDout); + } +#endif informat=FORMAT_PEM; outformat=FORMAT_PEM; @@ -227,7 +245,7 @@ int MAIN(int argc, char **argv) else if (strcmp(*argv,"-CAkeyform") == 0) { if (--argc < 1) goto bad; - CAformat=str2fmt(*(++argv)); + CAkeyformat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-days") == 0) { @@ -288,6 +306,12 @@ int MAIN(int argc, char **argv) if (--argc < 1) goto bad; CAserial= *(++argv); } + else if (strcmp(*argv,"-set_serial") == 0) + { + if (--argc < 1) goto bad; + if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv)))) + goto bad; + } else if (strcmp(*argv,"-addtrust") == 0) { if (--argc < 1) goto bad; @@ -320,6 +344,11 @@ int MAIN(int argc, char **argv) alias= *(++argv); trustout = 1; } + else if (strcmp(*argv,"-certopt") == 0) + { + if (--argc < 1) goto bad; + if (!set_cert_ex(&certflag, *(++argv))) goto bad; + } else if (strcmp(*argv,"-nameopt") == 0) { if (--argc < 1) goto bad; @@ -331,6 +360,11 @@ int MAIN(int argc, char **argv) alias= *(++argv); trustout = 1; } + else if (strcmp(*argv,"-engine") == 0) + { + if (--argc < 1) goto bad; + engine= *(++argv); + } else if (strcmp(*argv,"-C") == 0) C= ++num; else if (strcmp(*argv,"-email") == 0) @@ -391,6 +425,8 @@ int MAIN(int argc, char **argv) clrext = 1; } #endif + else if (strcmp(*argv,"-ocspid") == 0) + ocspid= ++num; else if ((md_alg=EVP_get_digestbyname(*argv + 1))) { /* ok */ @@ -410,10 +446,12 @@ int MAIN(int argc, char **argv) { bad: for (pp=x509_usage; (*pp != NULL); pp++) - BIO_printf(bio_err,*pp); + BIO_printf(bio_err,"%s",*pp); goto end; } + e = setup_engine(bio_err, engine, 0); + if (need_rand) app_RAND_load_file(NULL, bio_err, 0); @@ -441,9 +479,10 @@ bad: if (extfile) { - long errorline; + long errorline = -1; X509V3_CTX ctx2; - if (!(extconf=CONF_load(NULL,extfile,&errorline))) + extconf = NCONF_new(NULL); + if (!NCONF_load(extconf, extfile,&errorline)) { if (errorline <= 0) BIO_printf(bio_err, @@ -455,11 +494,18 @@ bad: ,errorline,extfile); goto end; } - if (!extsect && !(extsect = CONF_get_string(extconf, "default", - "extensions"))) extsect = "default"; + if (!extsect) + { + extsect = NCONF_get_string(extconf, "default", "extensions"); + if (!extsect) + { + ERR_clear_error(); + extsect = "default"; + } + } X509V3_set_ctx_test(&ctx2); - X509V3_set_conf_lhash(&ctx2, extconf); - if (!X509V3_EXT_add_conf(extconf, &ctx2, extsect, NULL)) + X509V3_set_nconf(&ctx2, extconf); + if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) { BIO_printf(bio_err, "Error Loading extension section %s\n", @@ -543,7 +589,12 @@ bad: if ((x=X509_new()) == NULL) goto end; ci=x->cert_info; - if (!ASN1_INTEGER_set(X509_get_serialNumber(x),0)) goto end; + if (sno) + { + if (!X509_set_serialNumber(x, sno)) + goto end; + } + else if (!ASN1_INTEGER_set(X509_get_serialNumber(x),0)) goto end; if (!X509_set_issuer_name(x,req->req_info->subject)) goto end; if (!X509_set_subject_name(x,req->req_info->subject)) goto end; @@ -555,12 +606,12 @@ bad: EVP_PKEY_free(pkey); } else - x=load_cert(bio_err,infile,informat); + x=load_cert(bio_err,infile,informat,NULL,e,"Certificate"); if (x == NULL) goto end; if (CA_flag) { - xca=load_cert(bio_err,CAfile,CAformat); + xca=load_cert(bio_err,CAfile,CAformat,NULL,e,"CA Certificate"); if (xca == NULL) goto end; } @@ -576,7 +627,15 @@ bad: goto end; } if (outfile == NULL) + { BIO_set_fp(out,stdout,BIO_NOCLOSE); +#ifdef OPENSSL_SYS_VMS + { + BIO *tmpbio = BIO_new(BIO_f_linebuffer()); + out = BIO_push(tmpbio, out); + } +#endif + } else { if (BIO_write_filename(out,outfile) <= 0) @@ -674,12 +733,12 @@ bad: goto end; } BIO_printf(STDout,"Modulus="); -#ifndef NO_RSA +#ifndef OPENSSL_NO_RSA if (pkey->type == EVP_PKEY_RSA) BN_print(STDout,pkey->pkey.rsa->n); else #endif -#ifndef NO_DSA +#ifndef OPENSSL_NO_DSA if (pkey->type == EVP_PKEY_DSA) BN_print(STDout,pkey->pkey.dsa->pub_key); else @@ -760,7 +819,7 @@ bad: } else if (text == i) { - X509_print(out,x); + X509_print_ex(out,x,nmflag, certflag); } else if (startdate == i) { @@ -802,13 +861,18 @@ bad: if (Upkey == NULL) { Upkey=load_key(bio_err, - keyfile,keyformat, passin); + keyfile, keyformat, 0, + passin, e, "Private key"); if (Upkey == NULL) goto end; } -#ifndef NO_DSA +#ifndef OPENSSL_NO_DSA if (Upkey->type == EVP_PKEY_DSA) digest=EVP_dss1(); #endif +#ifndef OPENSSL_NO_ECDSA + if (Upkey->type == EVP_PKEY_EC) + digest=EVP_ecdsa(); +#endif assert(need_rand); if (!sign(x,Upkey,days,clrext,digest, @@ -820,18 +884,24 @@ bad: if (CAkeyfile != NULL) { CApkey=load_key(bio_err, - CAkeyfile,CAkeyformat, passin); + CAkeyfile, CAkeyformat, + 0, passin, e, + "CA Private Key"); if (CApkey == NULL) goto end; } -#ifndef NO_DSA +#ifndef OPENSSL_NO_DSA if (CApkey->type == EVP_PKEY_DSA) digest=EVP_dss1(); #endif +#ifndef OPENSSL_NO_ECDSA + if (CApkey->type == EVP_PKEY_EC) + digest = EVP_ecdsa(); +#endif assert(need_rand); if (!x509_certify(ctx,CAfile,digest,x,xca, CApkey, CAserial,CA_createserial,days, clrext, - extconf, extsect)) + extconf, extsect, sno)) goto end; } else if (x509req == i) @@ -847,14 +917,21 @@ bad: else { pk=load_key(bio_err, - keyfile,FORMAT_PEM, passin); + keyfile, FORMAT_PEM, 0, + passin, e, "request key"); if (pk == NULL) goto end; } BIO_printf(bio_err,"Generating certificate request\n"); +#ifndef OPENSSL_NO_DSA if (pk->type == EVP_PKEY_DSA) digest=EVP_dss1(); +#endif +#ifndef OPENSSL_NO_ECDSA + if (pk->type == EVP_PKEY_EC) + digest=EVP_ecdsa(); +#endif rq=X509_to_X509_REQ(x,pk,digest); EVP_PKEY_free(pk); @@ -870,6 +947,10 @@ bad: } noout=1; } + else if (ocspid == i) + { + X509_ocspid_print(out, x); + } } } @@ -932,9 +1013,9 @@ end: if (need_rand) app_RAND_write_file(NULL, bio_err); OBJ_cleanup(); - CONF_free(extconf); - BIO_free(out); - BIO_free(STDout); + NCONF_free(extconf); + BIO_free_all(out); + BIO_free_all(STDout); X509_STORE_free(ctx); X509_REQ_free(req); X509_free(x); @@ -942,32 +1023,23 @@ end: EVP_PKEY_free(Upkey); EVP_PKEY_free(CApkey); X509_REQ_free(rq); + ASN1_INTEGER_free(sno); sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free); sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free); if (passin) OPENSSL_free(passin); + apps_shutdown(); EXIT(ret); } -static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, - X509 *x, X509 *xca, EVP_PKEY *pkey, char *serialfile, int create, - int days, int clrext, LHASH *conf, char *section) +static ASN1_INTEGER *load_serial(char *CAfile, char *serialfile, int create) { - int ret=0; - BIO *io=NULL; + char *buf = NULL, *p; MS_STATIC char buf2[1024]; - char *buf=NULL,*p; - BIGNUM *serial=NULL; - ASN1_INTEGER *bs=NULL,bs2; - X509_STORE_CTX xsc; - EVP_PKEY *upkey; + ASN1_INTEGER *bs = NULL, *bs2 = NULL; + BIO *io = NULL; + BIGNUM *serial = NULL; - upkey = X509_get_pubkey(xca); - EVP_PKEY_copy_parameters(upkey,pkey); - EVP_PKEY_free(upkey); - - X509_STORE_CTX_init(&xsc,ctx,x,NULL); - buf=OPENSSL_malloc(EVP_PKEY_size(pkey)*2+ - ((serialfile == NULL) + buf=OPENSSL_malloc( ((serialfile == NULL) ?(strlen(CAfile)+strlen(POSTFIX)+1) :(strlen(serialfile)))+1); if (buf == NULL) { BIO_printf(bio_err,"out of mem\n"); goto end; } @@ -1033,20 +1105,55 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, if (!BN_add_word(serial,1)) { BIO_printf(bio_err,"add_word failure\n"); goto end; } - bs2.data=(unsigned char *)buf2; - bs2.length=BN_bn2bin(serial,bs2.data); - + if (!(bs2 = BN_to_ASN1_INTEGER(serial, NULL))) + { BIO_printf(bio_err,"error converting bn 2 asn1_integer\n"); goto end; } if (BIO_write_filename(io,buf) <= 0) { BIO_printf(bio_err,"error attempting to write serial number file\n"); perror(buf); goto end; } - i2a_ASN1_INTEGER(io,&bs2); + i2a_ASN1_INTEGER(io,bs2); BIO_puts(io,"\n"); + BIO_free(io); + if (buf) OPENSSL_free(buf); + ASN1_INTEGER_free(bs2); + BN_free(serial); io=NULL; - + return bs; + + end: + if (buf) OPENSSL_free(buf); + BIO_free(io); + ASN1_INTEGER_free(bs); + BN_free(serial); + return NULL; + + } + +static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, + X509 *x, X509 *xca, EVP_PKEY *pkey, char *serialfile, int create, + int days, int clrext, CONF *conf, char *section, ASN1_INTEGER *sno) + { + int ret=0; + ASN1_INTEGER *bs=NULL; + X509_STORE_CTX xsc; + EVP_PKEY *upkey; + + upkey = X509_get_pubkey(xca); + EVP_PKEY_copy_parameters(upkey,pkey); + EVP_PKEY_free(upkey); + + if(!X509_STORE_CTX_init(&xsc,ctx,x,NULL)) + { + BIO_printf(bio_err,"Error initialising X509 store\n"); + goto end; + } + if (sno) bs = sno; + else if (!(bs = load_serial(CAfile, serialfile, create))) + goto end; + if (!X509_STORE_add_cert(ctx,x)) goto end; /* NOTE: this certificate can/should be self signed, unless it was @@ -1081,8 +1188,8 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, X509V3_CTX ctx2; X509_set_version(x,2); /* version 3 certificate */ X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0); - X509V3_set_conf_lhash(&ctx2, conf); - if (!X509V3_EXT_add_conf(conf, &ctx2, section, x)) goto end; + X509V3_set_nconf(&ctx2, conf); + if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x)) goto end; } if (!X509_sign(x,pkey,digest)) goto end; @@ -1091,10 +1198,7 @@ end: X509_STORE_CTX_cleanup(&xsc); if (!ret) ERR_print_errors(bio_err); - if (buf != NULL) OPENSSL_free(buf); - if (bs != NULL) ASN1_INTEGER_free(bs); - if (io != NULL) BIO_free(io); - if (serial != NULL) BN_free(serial); + if (!sno) ASN1_INTEGER_free(bs); return ret; } @@ -1131,7 +1235,7 @@ static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx) /* self sign */ static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest, - LHASH *conf, char *section) + CONF *conf, char *section) { EVP_PKEY *pktmp; @@ -1161,8 +1265,8 @@ static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *dig X509V3_CTX ctx; X509_set_version(x,2); /* version 3 certificate */ X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0); - X509V3_set_conf_lhash(&ctx, conf); - if (!X509V3_EXT_add_conf(conf, &ctx, section, x)) goto err; + X509V3_set_nconf(&ctx, conf); + if (!X509V3_EXT_add_nconf(conf, &ctx, section, x)) goto err; } if (!X509_sign(x,pkey,digest)) goto err; return 1; @@ -1187,6 +1291,3 @@ static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt) } return 1; } - - -