X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=apps%2Fx509.c;h=361eca624e24756fd9658846a457b59968b46008;hp=294fc69573fe00b4325c278a4c3f37748d8000f1;hb=45da1efcdb822d8ff992e13d5a1600fa62c96c6d;hpb=a37e22d866294c25747b7546e6390bfe792fc3c5 diff --git a/apps/x509.c b/apps/x509.c index 294fc69573..361eca624e 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -73,8 +73,12 @@ #include #include #include +#ifndef OPENSSL_NO_RSA #include +#endif +#ifndef OPENSSL_NO_DSA #include +#endif #undef PROG #define PROG x509_main @@ -83,7 +87,7 @@ #define POSTFIX ".srl" #define DEF_DAYS 30 -static char *x509_usage[]={ +static const char *x509_usage[]={ "usage: x509 args\n", " -inform arg - input format - default PEM (one of DER, NET or PEM)\n", " -outform arg - output format - default PEM (one of DER, NET or PEM)\n", @@ -95,7 +99,13 @@ static char *x509_usage[]={ " -passin arg - private key password source\n", " -serial - print serial number value\n", " -subject_hash - print subject hash value\n", +#ifndef OPENSSL_NO_MD5 +" -subject_hash_old - print old-style (MD5) subject hash value\n", +#endif " -issuer_hash - print issuer hash value\n", +#ifndef OPENSSL_NO_MD5 +" -issuer_hash_old - print old-style (MD5) issuer hash value\n", +#endif " -hash - synonym for -subject_hash\n", " -subject - print subject DN\n", " -issuer - print issuer DN\n", @@ -110,6 +120,7 @@ static char *x509_usage[]={ " -alias - output certificate alias\n", " -noout - no certificate output\n", " -ocspid - print OCSP hash values for the subject name and public key\n", +" -ocsp_uri - print OCSP Responder URL(s)\n", " -trustout - output a \"trusted\" certificate\n", " -clrtrust - clear all trusted purposes\n", " -clrreject - clear all rejected purposes\n", @@ -146,9 +157,10 @@ 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, 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, CONF *conf, char *section, - ASN1_INTEGER *sno); + X509 *x,X509 *xca,EVP_PKEY *pkey, + STACK_OF(OPENSSL_STRING) *sigopts, + char *serial, 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; @@ -161,6 +173,7 @@ int MAIN(int argc, char **argv) X509_REQ *req=NULL; X509 *x=NULL,*xca=NULL; ASN1_OBJECT *objtmp; + STACK_OF(OPENSSL_STRING) *sigopts = NULL; EVP_PKEY *Upkey=NULL,*CApkey=NULL; ASN1_INTEGER *sno = NULL; int i,num,badops=0; @@ -174,22 +187,28 @@ int MAIN(int argc, char **argv) int text=0,serial=0,subject=0,issuer=0,startdate=0,enddate=0; int next_serial=0; int subject_hash=0,issuer_hash=0,ocspid=0; +#ifndef OPENSSL_NO_MD5 + int subject_hash_old=0,issuer_hash_old=0; +#endif int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0; + int ocsp_uri=0; int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0; int C=0; int x509req=0,days=DEF_DAYS,modulus=0,pubkey=0; int pprint = 0; - char **pp; + const char **pp; X509_STORE *ctx=NULL; X509_REQ *rq=NULL; int fingerprint=0; char buf[256]; - const EVP_MD *md_alg,*digest=EVP_md5(); + const EVP_MD *md_alg,*digest=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, certflag = 0; + unsigned char *checkhost = NULL, *checkemail = NULL; + char *checkip = NULL; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif @@ -219,7 +238,7 @@ int MAIN(int argc, char **argv) ctx=X509_STORE_new(); if (ctx == NULL) goto end; - X509_STORE_set_verify_cb_func(ctx,callb); + X509_STORE_set_verify_cb(ctx,callb); argc--; argv++; @@ -256,13 +275,22 @@ int MAIN(int argc, char **argv) if (--argc < 1) goto bad; CAkeyformat=str2fmt(*(++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,"-days") == 0) { if (--argc < 1) goto bad; days=atoi(*(++argv)); if (days == 0) { - BIO_printf(STDout,"bad number of days\n"); + BIO_printf(bio_err,"bad number of days\n"); goto bad; } } @@ -374,6 +402,8 @@ int MAIN(int argc, char **argv) C= ++num; else if (strcmp(*argv,"-email") == 0) email= ++num; + else if (strcmp(*argv,"-ocsp_uri") == 0) + ocsp_uri= ++num; else if (strcmp(*argv,"-serial") == 0) serial= ++num; else if (strcmp(*argv,"-next_serial") == 0) @@ -389,8 +419,16 @@ int MAIN(int argc, char **argv) else if (strcmp(*argv,"-hash") == 0 || strcmp(*argv,"-subject_hash") == 0) subject_hash= ++num; +#ifndef OPENSSL_NO_MD5 + else if (strcmp(*argv,"-subject_hash_old") == 0) + subject_hash_old= ++num; +#endif else if (strcmp(*argv,"-issuer_hash") == 0) issuer_hash= ++num; +#ifndef OPENSSL_NO_MD5 + else if (strcmp(*argv,"-issuer_hash_old") == 0) + issuer_hash_old= ++num; +#endif else if (strcmp(*argv,"-subject") == 0) subject= ++num; else if (strcmp(*argv,"-issuer") == 0) @@ -414,6 +452,21 @@ int MAIN(int argc, char **argv) checkoffset=atoi(*(++argv)); checkend=1; } + else if (strcmp(*argv,"-checkhost") == 0) + { + if (--argc < 1) goto bad; + checkhost=(unsigned char *)*(++argv); + } + else if (strcmp(*argv,"-checkemail") == 0) + { + if (--argc < 1) goto bad; + checkemail=(unsigned char *)*(++argv); + } + else if (strcmp(*argv,"-checkip") == 0) + { + if (--argc < 1) goto bad; + checkip=*(++argv); + } else if (strcmp(*argv,"-noout") == 0) noout= ++num; else if (strcmp(*argv,"-trustout") == 0) @@ -531,7 +584,6 @@ bad: if (reqfile) { EVP_PKEY *pkey; - X509_CINF *ci; BIO *in; if (!sign_flag && !CA_flag) @@ -599,7 +651,6 @@ bad: print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), nmflag); if ((x=X509_new()) == NULL) goto end; - ci=x->cert_info; if (sno == NULL) { @@ -618,7 +669,7 @@ bad: if (!X509_set_subject_name(x,req->req_info->subject)) goto end; X509_gmtime_adj(X509_get_notBefore(x),0); - X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days); + X509_time_adj_ex(X509_get_notAfter(x),days, 0, NULL); pkey = X509_REQ_get_pubkey(req); X509_set_pubkey(x,pkey); @@ -727,13 +778,17 @@ bad: ASN1_INTEGER_free(ser); BIO_puts(out, "\n"); } - else if (email == i) + else if ((email == i) || (ocsp_uri == i)) { int j; - STACK *emlst; - emlst = X509_get1_email(x); - for (j = 0; j < sk_num(emlst); j++) - BIO_printf(STDout, "%s\n", sk_value(emlst, j)); + STACK_OF(OPENSSL_STRING) *emlst; + if (email == i) + emlst = X509_get1_email(x); + else + emlst = X509_get1_ocsp(x); + for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++) + BIO_printf(STDout, "%s\n", + sk_OPENSSL_STRING_value(emlst, j)); X509_email_free(emlst); } else if (aliasout == i) @@ -747,10 +802,22 @@ bad: { BIO_printf(STDout,"%08lx\n",X509_subject_name_hash(x)); } +#ifndef OPENSSL_NO_MD5 + else if (subject_hash_old == i) + { + BIO_printf(STDout,"%08lx\n",X509_subject_name_hash_old(x)); + } +#endif else if (issuer_hash == i) { BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash(x)); } +#ifndef OPENSSL_NO_MD5 + else if (issuer_hash_old == i) + { + BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash_old(x)); + } +#endif else if (pprint == i) { X509_PURPOSE *ptmp; @@ -862,7 +929,7 @@ bad: } else if (text == i) { - X509_print_ex(out,x,nmflag, certflag); + X509_print_ex(STDout,x,nmflag, certflag); } else if (startdate == i) { @@ -881,14 +948,18 @@ bad: int j; unsigned int n; unsigned char md[EVP_MAX_MD_SIZE]; + const EVP_MD *fdig = digest; + + if (!fdig) + fdig = EVP_sha1(); - if (!X509_digest(x,digest,md,&n)) + if (!X509_digest(x,fdig,md,&n)) { BIO_printf(bio_err,"out of memory\n"); goto end; } BIO_printf(STDout,"%s Fingerprint=", - OBJ_nid2sn(EVP_MD_type(digest))); + OBJ_nid2sn(EVP_MD_type(fdig))); for (j=0; j<(int)n; j++) { BIO_printf(STDout,"%02X%c",md[j], @@ -908,14 +979,6 @@ bad: passin, e, "Private key"); if (Upkey == NULL) goto end; } -#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, @@ -932,18 +995,11 @@ bad: "CA Private Key"); if (CApkey == NULL) goto end; } -#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, + CApkey, sigopts, + CAserial,CA_createserial,days, clrext, extconf, extsect, sno)) goto end; } @@ -960,22 +1016,13 @@ bad: else { pk=load_key(bio_err, - keyfile, FORMAT_PEM, 0, + keyfile, keyformat, 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); if (rq == NULL) @@ -1014,6 +1061,8 @@ bad: goto end; } + print_cert_checks(STDout, x, checkhost, checkemail, checkip); + if (noout) { ret=0; @@ -1029,17 +1078,15 @@ bad: } else if (outformat == FORMAT_NETSCAPE) { - ASN1_HEADER ah; - ASN1_OCTET_STRING os; + NETSCAPE_X509 nx; + ASN1_OCTET_STRING hdr; - os.data=(unsigned char *)NETSCAPE_CERT_HDR; - os.length=strlen(NETSCAPE_CERT_HDR); - ah.header= &os; - ah.data=(char *)x; - ah.meth=X509_asn1_meth(); + hdr.data=(unsigned char *)NETSCAPE_CERT_HDR; + hdr.length=strlen(NETSCAPE_CERT_HDR); + nx.header= &hdr; + nx.cert=x; - /* no macro for this one yet */ - i=ASN1_i2d_bio(i2d_ASN1_HEADER,out,(unsigned char *)&ah); + i=ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509),out,&nx); } else { BIO_printf(bio_err,"bad output format specified for outfile\n"); @@ -1065,6 +1112,8 @@ end: X509_free(xca); EVP_PKEY_free(Upkey); EVP_PKEY_free(CApkey); + if (sigopts) + sk_OPENSSL_STRING_free(sigopts); X509_REQ_free(rq); ASN1_INTEGER_free(sno); sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free); @@ -1115,8 +1164,11 @@ static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile, int create } 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) + X509 *x, X509 *xca, EVP_PKEY *pkey, + STACK_OF(OPENSSL_STRING) *sigopts, + char *serialfile, int create, + int days, int clrext, CONF *conf, char *section, + ASN1_INTEGER *sno) { int ret=0; ASN1_INTEGER *bs=NULL; @@ -1141,7 +1193,8 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, /* NOTE: this certificate can/should be self signed, unless it was * a certificate request in which case it is not. */ X509_STORE_CTX_set_cert(&xsc,x); - if (!reqfile && !X509_verify_cert(&xsc)) + X509_STORE_CTX_set_flags(&xsc, X509_V_FLAG_CHECK_SS_SIGNATURE); + if (!reqfile && X509_verify_cert(&xsc) <= 0) goto end; if (!X509_check_private_key(xca,pkey)) @@ -1157,7 +1210,7 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, goto end; /* hardwired expired */ - if (X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days) == NULL) + if (X509_time_adj_ex(X509_get_notAfter(x),days, 0, NULL) == NULL) goto end; if (clrext) @@ -1174,7 +1227,8 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x)) goto end; } - if (!X509_sign(x,pkey,digest)) goto end; + if (!do_X509_sign(bio_err, x, pkey, digest, sigopts)) + goto end; ret=1; end: X509_STORE_CTX_cleanup(&xsc);