diff options
author | Rich Salz <rsalz@openssl.org> | 2015-04-24 15:26:15 -0400 |
---|---|---|
committer | Rich Salz <rsalz@openssl.org> | 2015-04-24 15:26:15 -0400 |
commit | 7e1b7485706c2b11091b5fa897fe496a2faa56cc (patch) | |
tree | d008e38fda900d081a2496023625184c5c89a5ff /apps/x509.c | |
parent | 53dd4ddf71ad79a64be934ca19445b1cf560adab (diff) | |
download | openssl-7e1b7485706c2b11091b5fa897fe496a2faa56cc.tar.gz |
Big apps cleanup (option-parsing, etc)
This is merges the old "rsalz-monolith" branch over to master. The biggest
change is that option parsing switch from cascasding 'else if strcmp("-foo")'
to a utility routine and somethin akin to getopt. Also, an error in the
command line no longer prints the full summary; use -help (or --help :)
for that. There have been many other changes and code-cleanup, see
bullet list below.
Special thanks to Matt for the long and detailed code review.
TEMPORARY:
For now, comment out CRYPTO_mem_leaks() at end of main
Tickets closed:
RT3515: Use 3DES in pkcs12 if built with no-rc2
RT1766: s_client -reconnect and -starttls broke
RT2932: Catch write errors
RT2604: port should be 'unsigned short'
RT2983: total_bytes undeclared #ifdef RENEG
RT1523: Add -nocert to fix output in x509 app
RT3508: Remove unused variable introduced by b09eb24
RT3511: doc fix; req default serial is random
RT1325,2973: Add more extensions to c_rehash
RT2119,3407: Updated to dgst.pod
RT2379: Additional typo fix
RT2693: Extra include of string.h
RT2880: HFS is case-insensitive filenames
RT3246: req command prints version number wrong
Other changes; incompatibilities marked with *:
Add SCSV support
Add -misalign to speed command
Make dhparam, dsaparam, ecparam, x509 output C in proper style
Make some internal ocsp.c functions void
Only display cert usages with -help in verify
Use global bio_err, remove "BIO*err" parameter from functions
For filenames, - always means stdin (or stdout as appropriate)
Add aliases for -des/aes "wrap" ciphers.
*Remove support for IISSGC (server gated crypto)
*The undocumented OCSP -header flag is now "-header name=value"
*Documented the OCSP -header flag
Reviewed-by: Matt Caswell <matt@openssl.org>
Diffstat (limited to 'apps/x509.c')
-rw-r--r-- | apps/x509.c | 883 |
1 files changed, 405 insertions, 478 deletions
diff --git a/apps/x509.c b/apps/x509.c index 380f0f0be7..903e6b94b9 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -1,4 +1,3 @@ -/* apps/x509.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -77,82 +76,10 @@ # include <openssl/dsa.h> #endif -#undef PROG -#define PROG x509_main - #undef POSTFIX #define POSTFIX ".srl" #define DEF_DAYS 30 -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", - " -keyform arg - private key format - default PEM\n", - " -CAform arg - CA format - default PEM\n", - " -CAkeyform arg - CA key format - default PEM\n", - " -in arg - input file - default stdin\n", - " -out arg - output file - default stdout\n", - " -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", - " -email - print email address(es)\n", - " -startdate - notBefore field\n", - " -enddate - notAfter field\n", - " -purpose - print out certificate purposes\n", - " -dates - both Before and After dates\n", - " -modulus - print the RSA key modulus\n", - " -pubkey - output the public key\n", - " -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", - " -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", - " -addtrust arg - trust certificate for a given purpose\n", - " -addreject arg - reject certificate for a given purpose\n", - " -setalias arg - set certificate alias\n", - " -days arg - How long till expiry of a signed certificate - def 30 days\n", - " -checkend arg - check whether the cert expires in the next arg seconds\n", - " exit 1 if so, 0 if not\n", - " -signkey arg - self sign cert with arg\n", - " -x509toreq - output a certification request object\n", - " -req - input is a certificate request, sign and output.\n", - " -CA arg - set the CA certificate, must be PEM format.\n", - " -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 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", - " -extfile - configuration file with X509V3 extensions to add\n", - " -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", -#ifndef OPENSSL_NO_ENGINE - " -engine e - use engine e, possibly a hardware device.\n", -#endif - " -certopt arg - various certificate text options\n", - " -checkhost host - check certificate matches \"host\"\n", - " -checkemail email - check certificate matches \"email\"\n", - " -checkip ipaddr - check certificate matches \"ipaddr\"\n", - NULL -}; - static int 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); @@ -160,347 +87,425 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, 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); + char *section, ASN1_INTEGER *sno, int reqfile); static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt); -static int reqfile = 0; + #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL static int force_version = 2; #endif -int MAIN(int, char **); +typedef enum OPTION_choice { + OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, + OPT_INFORM, OPT_OUTFORM, OPT_KEYFORM, OPT_REQ, OPT_CAFORM, + OPT_CAKEYFORM, OPT_SIGOPT, OPT_DAYS, OPT_PASSIN, OPT_EXTFILE, + OPT_EXTENSIONS, OPT_IN, OPT_OUT, OPT_SIGNKEY, OPT_CA, + OPT_CAKEY, OPT_CASERIAL, OPT_SET_SERIAL, OPT_FORCE_PUBKEY, + OPT_ADDTRUST, OPT_ADDREJECT, OPT_SETALIAS, OPT_CERTOPT, OPT_NAMEOPT, + OPT_C, OPT_EMAIL, OPT_OCSP_URI, OPT_SERIAL, OPT_NEXT_SERIAL, + OPT_MODULUS, OPT_PUBKEY, OPT_X509TOREQ, OPT_TEXT, OPT_HASH, + OPT_ISSUER_HASH, OPT_SUBJECT, OPT_ISSUER, OPT_FINGERPRINT, OPT_DATES, + OPT_PURPOSE, OPT_STARTDATE, OPT_ENDDATE, OPT_CHECKEND, OPT_CHECKHOST, + OPT_CHECKEMAIL, OPT_CHECKIP, OPT_NOOUT, OPT_TRUSTOUT, OPT_CLRTRUST, + OPT_CLRREJECT, OPT_ALIAS, OPT_CACREATESERIAL, OPT_CLREXT, OPT_OCSPID, +#ifndef OPENSSL_NO_MD5 + OPT_SUBJECT_HASH_OLD, + OPT_ISSUER_HASH_OLD, +#endif +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + OPT_FORCE_VERSION, +#endif + OPT_BADSIG, OPT_MD, OPT_ENGINE, OPT_NOCERT +} OPTION_CHOICE; + +OPTIONS x509_options[] = { + {"help", OPT_HELP, '-', "Display this summary"}, + {"inform", OPT_INFORM, 'f', + "Input format - default PEM (one of DER, NET or PEM)"}, + {"in", OPT_IN, '<', "Input file - default stdin"}, + {"outform", OPT_OUTFORM, 'f', + "Output format - default PEM (one of DER, NET or PEM)"}, + {"out", OPT_OUT, '>', "Output file - default stdout"}, + {"keyform", OPT_KEYFORM, 'F', "Private key format - default PEM"}, + {"passin", OPT_PASSIN, 's', "Private key password source"}, + {"serial", OPT_SERIAL, '-', "Print serial number value"}, + {"subject_hash", OPT_HASH, '-', "Print subject hash value"}, + {"issuer_hash", OPT_ISSUER_HASH, '-', "Print issuer hash value"}, +#ifndef OPENSSL_NO_MD5 + {"subject_hash_old", OPT_SUBJECT_HASH_OLD, '-', + "Print old-style (MD5) issuer hash value"}, + {"issuer_hash_old", OPT_ISSUER_HASH_OLD, '-', + "Print old-style (MD5) subject hash value"}, +#endif + {"hash", OPT_HASH, '-', "Synonym for -subject_hash"}, + {"subject", OPT_SUBJECT, '-', "Print subject DN"}, + {"issuer", OPT_ISSUER, '-', "Print issuer DN"}, + {"email", OPT_EMAIL, '-', "Print email address(es)"}, + {"startdate", OPT_STARTDATE, '-', "Set notBefore field"}, + {"enddate", OPT_ENDDATE, '-', "Set notAfter field"}, + {"purpose", OPT_PURPOSE, '-', "Print out certificate purposes"}, + {"dates", OPT_DATES, '-', "Both Before and After dates"}, + {"modulus", OPT_MODULUS, '-', "Print the RSA key modulus"}, + {"pubkey", OPT_PUBKEY, '-', "Output the public key"}, + {"fingerprint", OPT_FINGERPRINT, '-', + "Print the certificate fingerprint"}, + {"alias", OPT_ALIAS, '-', "Output certificate alias"}, + {"noout", OPT_NOOUT, '-', "No output, just status"}, + {"nocert", OPT_NOCERT, '-', "No certificate output"}, + {"ocspid", OPT_OCSPID, '-', + "Print OCSP hash values for the subject name and public key"}, + {"ocsp_uri", OPT_OCSP_URI, '-', "Print OCSP Responder URL(s)"}, + {"trustout", OPT_TRUSTOUT, '-', "Output a trusted certificate"}, + {"clrtrust", OPT_CLRTRUST, '-', "Clear all trusted purposes"}, + {"clrext", OPT_CLREXT, '-', "Clear all rejected purposes"}, + {"addtrust", OPT_ADDTRUST, 's', "Trust certificate for a given purpose"}, + {"addreject", OPT_ADDREJECT, 's', + "Reject certificate for a given purpose"}, + {"setalias", OPT_SETALIAS, 's', "Set certificate alias"}, + {"days", OPT_DAYS, 'n', + "How long till expiry of a signed certificate - def 30 days"}, + {"checkend", OPT_CHECKEND, 'p', + "Check whether the cert expires in the next arg seconds"}, + {OPT_MORE_STR, 1, 1, "Exit 1 if so, 0 if not"}, + {"signkey", OPT_SIGNKEY, '<', "Self sign cert with arg"}, + {"x509toreq", OPT_X509TOREQ, '-', + "Output a certification request object"}, + {"req", OPT_REQ, '-', "Input is a certificate request, sign and output"}, + {"CA", OPT_CA, '<', "Set the CA certificate, must be PEM format"}, + {"CAkey", OPT_CAKEY, '<', + "The CA key, must be PEM format; if not in CAfile"}, + {"CAcreateserial", OPT_CACREATESERIAL, '-', + "Create serial number file if it does not exist"}, + {"CAserial", OPT_CASERIAL, '<', "Serial file"}, + {"set_serial", OPT_SET_SERIAL, 's', "Serial number to use"}, + {"text", OPT_TEXT, '-', "Print the certificate in text form"}, + {"C", OPT_C, '-', "Print out C code forms"}, + {"extfile", OPT_EXTFILE, '<', "File with X509V3 extensions to add"}, + {"extensions", OPT_EXTENSIONS, 's', "Section from config file to use"}, + {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"}, + {"certopt", OPT_CERTOPT, 's', "Various certificate text options"}, + {"checkhost", OPT_CHECKHOST, 's', "Check certificate matches host"}, + {"checkemail", OPT_CHECKEMAIL, 's', "Check certificate matches email"}, + {"checkip", OPT_CHECKIP, 's', "Check certificate matches ipaddr"}, + {"CAform", OPT_CAFORM, 'F', "CA format - default PEM"}, + {"CAkeyform", OPT_CAKEYFORM, 'F', "CA key format - default PEM"}, + {"sigopt", OPT_SIGOPT, 's'}, + {"force_pubkey", OPT_FORCE_PUBKEY, '<'}, + {"next_serial", OPT_NEXT_SERIAL, '-'}, + {"clrreject", OPT_CLRREJECT, '-'}, + {"badsig", OPT_BADSIG, '-'}, + {"", OPT_MD, '-', "Any supported digest"}, +#ifndef OPENSSL_NO_ENGINE + {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, +#endif +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + {"force_version", OPT_FORCE_VERSION, 'p'}, +#endif + {NULL} +}; -int MAIN(int argc, char **argv) +int x509_main(int argc, char **argv) { - ENGINE *e = NULL; - int ret = 1; - X509_REQ *req = NULL; - X509 *x = NULL, *xca = NULL; - ASN1_OBJECT *objtmp; - STACK_OF(OPENSSL_STRING) *sigopts = NULL; - EVP_PKEY *Upkey = NULL, *CApkey = NULL, *fkey = NULL; ASN1_INTEGER *sno = NULL; - int i, num, badops = 0, badsig = 0; + ASN1_OBJECT *objtmp; BIO *out = NULL; - BIO *STDout = NULL; + CONF *extconf = NULL; + EVP_PKEY *Upkey = NULL, *CApkey = NULL, *fkey = NULL; STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL; - int informat, outformat, keyformat, CAformat, CAkeyformat; + STACK_OF(OPENSSL_STRING) *sigopts = NULL; + X509 *x = NULL, *xca = NULL; + X509_REQ *req = NULL, *rq = NULL; + X509_STORE *ctx = NULL; + const EVP_MD *digest = NULL; + char *CAkeyfile = NULL, *CAserial = NULL, *fkeyfile = NULL, *alias = NULL; + char *checkhost = NULL, *checkemail = NULL, *checkip = NULL; + char *extsect = NULL, *extfile = NULL, *passin = NULL, *passinarg = NULL; char *infile = NULL, *outfile = NULL, *keyfile = NULL, *CAfile = NULL; - char *CAkeyfile = NULL, *CAserial = NULL; - char *fkeyfile = NULL; - char *alias = NULL; + char buf[256]; + char *engine = NULL, *prog; + int C = 0, x509req = 0, days = DEF_DAYS, modulus = 0, pubkey = 0, pprint = + 0; + int CAformat = FORMAT_PEM, CAkeyformat = FORMAT_PEM; + int fingerprint = 0, reqfile = 0, need_rand = 0, checkend = + 0, checkoffset = 0; + int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM; + int next_serial = 0, subject_hash = 0, issuer_hash = 0, ocspid = 0; + int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0, email = 0; + int ocsp_uri = 0, trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0; + int ret = 1, i, num = 0, badsig = 0, clrext = 0, nocert = 0; 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; - const char **pp; - X509_STORE *ctx = NULL; - X509_REQ *rq = NULL; - int fingerprint = 0; - char buf[256]; - 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; - char *checkhost = NULL; - char *checkemail = NULL; - char *checkip = NULL; + OPTION_CHOICE o; #ifndef OPENSSL_NO_ENGINE - char *engine = NULL; + ENGINE *e = NULL; #endif - - reqfile = 0; - - apps_startup(); - - 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); - } +#ifndef OPENSSL_NO_MD5 + int subject_hash_old = 0, issuer_hash_old = 0; #endif - informat = FORMAT_PEM; - outformat = FORMAT_PEM; - keyformat = FORMAT_PEM; - CAformat = FORMAT_PEM; - CAkeyformat = FORMAT_PEM; - ctx = X509_STORE_new(); if (ctx == NULL) goto end; X509_STORE_set_verify_cb(ctx, callb); - argc--; - argv++; - num = 0; - while (argc >= 1) { - if (strcmp(*argv, "-inform") == 0) { - if (--argc < 1) - goto bad; - informat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-outform") == 0) { - if (--argc < 1) - goto bad; - outformat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-keyform") == 0) { - if (--argc < 1) - goto bad; - keyformat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-req") == 0) { - reqfile = 1; - need_rand = 1; - } else if (strcmp(*argv, "-CAform") == 0) { - if (--argc < 1) - goto bad; - CAformat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-CAkeyform") == 0) { - if (--argc < 1) - goto bad; - CAkeyformat = str2fmt(*(++argv)); - } else if (strcmp(*argv, "-sigopt") == 0) { - if (--argc < 1) - goto bad; + prog = opt_init(argc, argv, x509_options); + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_EOF: + case OPT_ERR: + opthelp: + BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); + goto end; + case OPT_HELP: + opt_help(x509_options); + ret = 0; + goto end; + case OPT_INFORM: + if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat)) + goto opthelp; + break; + case OPT_IN: + infile = opt_arg(); + break; + case OPT_OUTFORM: + if (!opt_format(opt_arg(), OPT_FMT_ANY, &outformat)) + goto opthelp; + break; + case OPT_KEYFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat)) + goto opthelp; + break; + case OPT_CAFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &CAformat)) + goto opthelp; + break; + case OPT_CAKEYFORM: + if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &CAkeyformat)) + goto opthelp; + break; + case OPT_OUT: + outfile = opt_arg(); + break; + case OPT_REQ: + reqfile = need_rand = 1; + break; + + case OPT_SIGOPT: if (!sigopts) sigopts = sk_OPENSSL_STRING_new_null(); - if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv))) - goto bad; - } + if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) + goto opthelp; + break; #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - else if (strcmp(*argv, "-force_version") == 0) { - if (--argc < 1) - goto bad; - force_version = atoi(*(++argv)) - 1; - } + case OPT_FORCE_VERSION: + force_version = atoi(opt_arg()) - 1; + break; #endif - else if (strcmp(*argv, "-days") == 0) { - if (--argc < 1) - goto bad; - days = atoi(*(++argv)); - if (days == 0) { - BIO_printf(bio_err, "bad number of days\n"); - goto bad; - } - } else if (strcmp(*argv, "-passin") == 0) { - if (--argc < 1) - goto bad; - passargin = *(++argv); - } else if (strcmp(*argv, "-extfile") == 0) { - if (--argc < 1) - goto bad; - extfile = *(++argv); - } else if (strcmp(*argv, "-extensions") == 0) { - if (--argc < 1) - goto bad; - extsect = *(++argv); - } else if (strcmp(*argv, "-in") == 0) { - if (--argc < 1) - goto bad; - infile = *(++argv); - } else if (strcmp(*argv, "-out") == 0) { - if (--argc < 1) - goto bad; - outfile = *(++argv); - } else if (strcmp(*argv, "-signkey") == 0) { - if (--argc < 1) - goto bad; - keyfile = *(++argv); + case OPT_DAYS: + days = atoi(opt_arg()); + break; + case OPT_PASSIN: + passinarg = opt_arg(); + break; + case OPT_EXTFILE: + extfile = opt_arg(); + break; + case OPT_EXTENSIONS: + extsect = opt_arg(); + break; + case OPT_SIGNKEY: + keyfile = opt_arg(); sign_flag = ++num; need_rand = 1; - } else if (strcmp(*argv, "-CA") == 0) { - if (--argc < 1) - goto bad; - CAfile = *(++argv); + break; + case OPT_CA: + CAfile = opt_arg(); CA_flag = ++num; need_rand = 1; - } else if (strcmp(*argv, "-CAkey") == 0) { - if (--argc < 1) - goto bad; - CAkeyfile = *(++argv); - } else if (strcmp(*argv, "-CAserial") == 0) { - 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, "-force_pubkey") == 0) { - if (--argc < 1) - goto bad; - fkeyfile = *(++argv); - } else if (strcmp(*argv, "-addtrust") == 0) { - if (--argc < 1) - goto bad; - if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) { - BIO_printf(bio_err, "Invalid trust object value %s\n", *argv); - goto bad; + break; + case OPT_CAKEY: + CAkeyfile = opt_arg(); + break; + case OPT_CASERIAL: + CAserial = opt_arg(); + break; + case OPT_SET_SERIAL: + if ((sno = s2i_ASN1_INTEGER(NULL, opt_arg())) == NULL) + goto opthelp; + break; + case OPT_FORCE_PUBKEY: + fkeyfile = opt_arg(); + break; + case OPT_ADDTRUST: + if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) { + BIO_printf(bio_err, + "%s: Invalid trust object value %s\n", + prog, opt_arg()); + goto opthelp; } - if (!trust) - trust = sk_ASN1_OBJECT_new_null(); + if (trust == NULL && (trust = sk_ASN1_OBJECT_new_null()) == NULL) + goto end; sk_ASN1_OBJECT_push(trust, objtmp); trustout = 1; - } else if (strcmp(*argv, "-addreject") == 0) { - if (--argc < 1) - goto bad; - if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) { + break; + case OPT_ADDREJECT: + if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) { BIO_printf(bio_err, - "Invalid reject object value %s\n", *argv); - goto bad; + "%s: Invalid reject object value %s\n", + prog, opt_arg()); + goto opthelp; } - if (!reject) - reject = sk_ASN1_OBJECT_new_null(); + if (reject == NULL + && (reject = sk_ASN1_OBJECT_new_null()) == NULL) + goto end; sk_ASN1_OBJECT_push(reject, objtmp); trustout = 1; - } else if (strcmp(*argv, "-setalias") == 0) { - if (--argc < 1) - goto bad; - alias = *(++argv); + break; + case OPT_SETALIAS: + alias = opt_arg(); 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; - if (!set_name_ex(&nmflag, *(++argv))) - goto bad; - } -#ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine = *(++argv); - } -#endif - else if (strcmp(*argv, "-C") == 0) + break; + case OPT_CERTOPT: + if (!set_cert_ex(&certflag, opt_arg())) + goto opthelp; + break; + case OPT_NAMEOPT: + if (!set_name_ex(&nmflag, opt_arg())) + goto opthelp; + break; + case OPT_ENGINE: + engine = opt_arg(); + break; + case OPT_C: C = ++num; - else if (strcmp(*argv, "-email") == 0) + break; + case OPT_EMAIL: email = ++num; - else if (strcmp(*argv, "-ocsp_uri") == 0) + break; + case OPT_OCSP_URI: ocsp_uri = ++num; - else if (strcmp(*argv, "-serial") == 0) + break; + case OPT_SERIAL: serial = ++num; - else if (strcmp(*argv, "-next_serial") == 0) + break; + case OPT_NEXT_SERIAL: next_serial = ++num; - else if (strcmp(*argv, "-modulus") == 0) + break; + case OPT_MODULUS: modulus = ++num; - else if (strcmp(*argv, "-pubkey") == 0) + break; + case OPT_PUBKEY: pubkey = ++num; - else if (strcmp(*argv, "-x509toreq") == 0) + break; + case OPT_X509TOREQ: x509req = ++num; - else if (strcmp(*argv, "-text") == 0) + break; + case OPT_TEXT: text = ++num; - 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) + break; + case OPT_SUBJECT: subject = ++num; - else if (strcmp(*argv, "-issuer") == 0) + break; + case OPT_ISSUER: issuer = ++num; - else if (strcmp(*argv, "-fingerprint") == 0) + break; + case OPT_FINGERPRINT: fingerprint = ++num; - else if (strcmp(*argv, "-dates") == 0) { - startdate = ++num; - enddate = ++num; - } else if (strcmp(*argv, "-purpose") == 0) + break; + case OPT_HASH: + subject_hash = ++num; + break; + case OPT_ISSUER_HASH: + issuer_hash = ++num; + break; + case OPT_PURPOSE: pprint = ++num; - else if (strcmp(*argv, "-startdate") == 0) + break; + case OPT_STARTDATE: startdate = ++num; - else if (strcmp(*argv, "-enddate") == 0) + break; + case OPT_ENDDATE: enddate = ++num; - else if (strcmp(*argv, "-checkend") == 0) { - if (--argc < 1) - goto bad; - checkoffset = atoi(*(++argv)); - checkend = 1; - } else if (strcmp(*argv, "-checkhost") == 0) { - if (--argc < 1) - goto bad; - checkhost = *(++argv); - } else if (strcmp(*argv, "-checkemail") == 0) { - if (--argc < 1) - goto bad; - checkemail = *(++argv); - } else if (strcmp(*argv, "-checkip") == 0) { - if (--argc < 1) - goto bad; - checkip = *(++argv); - } else if (strcmp(*argv, "-noout") == 0) + break; + case OPT_NOOUT: noout = ++num; - else if (strcmp(*argv, "-trustout") == 0) + break; + case OPT_NOCERT: + nocert = 1; + break; + case OPT_TRUSTOUT: trustout = 1; - else if (strcmp(*argv, "-clrtrust") == 0) + break; + case OPT_CLRTRUST: clrtrust = ++num; - else if (strcmp(*argv, "-clrreject") == 0) + break; + case OPT_CLRREJECT: clrreject = ++num; - else if (strcmp(*argv, "-alias") == 0) + break; + case OPT_ALIAS: aliasout = ++num; - else if (strcmp(*argv, "-CAcreateserial") == 0) + break; + case OPT_CACREATESERIAL: CA_createserial = ++num; - else if (strcmp(*argv, "-clrext") == 0) + break; + case OPT_CLREXT: clrext = 1; - else if (strcmp(*argv, "-ocspid") == 0) + break; + case OPT_OCSPID: ocspid = ++num; - else if (strcmp(*argv, "-badsig") == 0) + break; + case OPT_BADSIG: badsig = 1; - else if ((md_alg = EVP_get_digestbyname(*argv + 1))) { - /* ok */ - digest = md_alg; - } else { - BIO_printf(bio_err, "unknown option %s\n", *argv); - badops = 1; break; +#ifndef OPENSSL_NO_MD5 + case OPT_SUBJECT_HASH_OLD: + subject_hash_old = ++num; + break; + case OPT_ISSUER_HASH_OLD: + issuer_hash_old = ++num; + break; +#endif + case OPT_DATES: + startdate = ++num; + enddate = ++num; + break; + case OPT_CHECKEND: + checkoffset = atoi(opt_arg()); + checkend = 1; + break; + case OPT_CHECKHOST: + checkhost = opt_arg(); + break; + case OPT_CHECKEMAIL: + checkemail = opt_arg(); + break; + case OPT_CHECKIP: + checkip = opt_arg(); + break; + case OPT_MD: + if (!opt_md(opt_unknown(), &digest)) + goto opthelp; } - argc--; - argv++; + } + argc = opt_num_rest(); + argv = opt_rest(); + if (argc != 0) { + BIO_printf(bio_err, "%s: Unknown parameter %s\n", prog, argv[0]); + goto opthelp; } - if (badops) { - bad: - for (pp = x509_usage; (*pp != NULL); pp++) - BIO_printf(bio_err, "%s", *pp); + out = bio_open_default(outfile, "w"); + if (out == NULL) goto end; - } + #ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine, 0); + e = setup_engine(engine, 0); #endif if (need_rand) - app_RAND_load_file(NULL, bio_err, 0); - - ERR_load_crypto_strings(); + app_RAND_load_file(NULL, 0); - if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { + if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } @@ -511,8 +516,7 @@ int MAIN(int argc, char **argv) } if (fkeyfile) { - fkey = load_pubkey(bio_err, fkeyfile, keyformat, 0, - NULL, e, "Forced key"); + fkey = load_pubkey(fkeyfile, keyformat, 0, NULL, e, "Forced key"); if (fkey == NULL) goto end; } @@ -564,21 +568,9 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "We need a private key to sign with\n"); goto end; } - in = BIO_new(BIO_s_file()); - if (in == NULL) { - ERR_print_errors(bio_err); + in = bio_open_default(infile, "r"); + if (in == NULL) goto end; - } - - if (infile == NULL) - BIO_set_fp(in, stdin, BIO_NOCLOSE | BIO_FP_TEXT); - else { - if (BIO_read_filename(in, infile) <= 0) { - perror(infile); - BIO_free(in); - goto end; - } - } req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); BIO_free(in); @@ -646,12 +638,12 @@ int MAIN(int argc, char **argv) EVP_PKEY_free(pkey); } } else - x = load_cert(bio_err, infile, informat, NULL, e, "Certificate"); + x = load_cert(infile, informat, NULL, e, "Certificate"); if (x == NULL) goto end; if (CA_flag) { - xca = load_cert(bio_err, CAfile, CAformat, NULL, e, "CA Certificate"); + xca = load_cert(CAfile, CAformat, NULL, e, "CA Certificate"); if (xca == NULL) goto end; } @@ -659,25 +651,6 @@ int MAIN(int argc, char **argv) if (!noout || text || next_serial) { OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3"); - out = BIO_new(BIO_s_file()); - if (out == NULL) { - ERR_print_errors(bio_err); - 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) { - perror(outfile); - goto end; - } - } } if (alias) @@ -705,15 +678,14 @@ int MAIN(int argc, char **argv) if (num) { for (i = 1; i <= num; i++) { if (issuer == i) { - print_name(STDout, "issuer= ", - X509_get_issuer_name(x), nmflag); + print_name(out, "issuer= ", X509_get_issuer_name(x), nmflag); } else if (subject == i) { - print_name(STDout, "subject= ", + print_name(out, "subject= ", X509_get_subject_name(x), nmflag); } else if (serial == i) { - BIO_printf(STDout, "serial="); - i2a_ASN1_INTEGER(STDout, X509_get_serialNumber(x)); - BIO_printf(STDout, "\n"); + BIO_printf(out, "serial="); + i2a_ASN1_INTEGER(out, X509_get_serialNumber(x)); + BIO_printf(out, "\n"); } else if (next_serial == i) { BIGNUM *bnser; ASN1_INTEGER *ser; @@ -738,39 +710,39 @@ int MAIN(int argc, char **argv) else emlst = X509_get1_ocsp(x); for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++) - BIO_printf(STDout, "%s\n", + BIO_printf(out, "%s\n", sk_OPENSSL_STRING_value(emlst, j)); X509_email_free(emlst); } else if (aliasout == i) { unsigned char *alstr; alstr = X509_alias_get0(x, NULL); if (alstr) - BIO_printf(STDout, "%s\n", alstr); + BIO_printf(out, "%s\n", alstr); else - BIO_puts(STDout, "<No Alias>\n"); + BIO_puts(out, "<No Alias>\n"); } else if (subject_hash == i) { - BIO_printf(STDout, "%08lx\n", X509_subject_name_hash(x)); + BIO_printf(out, "%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)); + BIO_printf(out, "%08lx\n", X509_subject_name_hash_old(x)); } #endif else if (issuer_hash == i) { - BIO_printf(STDout, "%08lx\n", X509_issuer_name_hash(x)); + BIO_printf(out, "%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)); + BIO_printf(out, "%08lx\n", X509_issuer_name_hash_old(x)); } #endif else if (pprint == i) { X509_PURPOSE *ptmp; int j; - BIO_printf(STDout, "Certificate purposes:\n"); + BIO_printf(out, "Certificate purposes:\n"); for (j = 0; j < X509_PURPOSE_get_count(); j++) { ptmp = X509_PURPOSE_get0(j); - purpose_print(STDout, x, ptmp); + purpose_print(out, x, ptmp); } } else if (modulus == i) { EVP_PKEY *pkey; @@ -781,19 +753,19 @@ int MAIN(int argc, char **argv) ERR_print_errors(bio_err); goto end; } - BIO_printf(STDout, "Modulus="); + BIO_printf(out, "Modulus="); #ifndef OPENSSL_NO_RSA if (pkey->type == EVP_PKEY_RSA) - BN_print(STDout, pkey->pkey.rsa->n); + BN_print(out, pkey->pkey.rsa->n); else #endif #ifndef OPENSSL_NO_DSA if (pkey->type == EVP_PKEY_DSA) - BN_print(STDout, pkey->pkey.dsa->pub_key); + BN_print(out, pkey->pkey.dsa->pub_key); else #endif - BIO_printf(STDout, "Wrong Algorithm type"); - BIO_printf(STDout, "\n"); + BIO_printf(out, "Wrong Algorithm type"); + BIO_printf(out, "\n"); EVP_PKEY_free(pkey); } else if (pubkey == i) { EVP_PKEY *pkey; @@ -804,77 +776,48 @@ int MAIN(int argc, char **argv) ERR_print_errors(bio_err); goto end; } - PEM_write_bio_PUBKEY(STDout, pkey); + PEM_write_bio_PUBKEY(out, pkey); EVP_PKEY_free(pkey); } else if (C == i) { unsigned char *d; char *m; - int y, z; + int len; X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof buf); - BIO_printf(STDout, "/* subject:%s */\n", buf); - m = X509_NAME_oneline(X509_get_issuer_name(x), buf, - sizeof buf); - BIO_printf(STDout, "/* issuer :%s */\n", buf); + BIO_printf(out, "/*\n" + " * Subject: %s\n", buf); + + m = X509_NAME_oneline(X509_get_issuer_name(x), buf, sizeof buf); + BIO_printf(out, " * Issuer: %s\n" + " */\n", buf); - z = i2d_X509(x, NULL); - m = OPENSSL_malloc(z); + len = i2d_X509(x, NULL); + m = OPENSSL_malloc(len); if (!m) { BIO_printf(bio_err, "Out of memory\n"); - ERR_print_errors(bio_err); goto end; } d = (unsigned char *)m; - z = i2d_X509_NAME(X509_get_subject_name(x), &d); - BIO_printf(STDout, "unsigned char XXX_subject_name[%d]={\n", - z); - d = (unsigned char *)m; - for (y = 0; y < z; y++) { - BIO_printf(STDout, "0x%02X,", d[y]); - if ((y & 0x0f) == 0x0f) - BIO_printf(STDout, "\n"); - } - if (y % 16 != 0) - BIO_printf(STDout, "\n"); - BIO_printf(STDout, "};\n"); - - z = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d); - BIO_printf(STDout, "unsigned char XXX_public_key[%d]={\n", z); + len = i2d_X509_NAME(X509_get_subject_name(x), &d); + print_array(out, "the_subject_name", len, (unsigned char *)m); d = (unsigned char *)m; - for (y = 0; y < z; y++) { - BIO_printf(STDout, "0x%02X,", d[y]); - if ((y & 0x0f) == 0x0f) - BIO_printf(STDout, "\n"); - } - if (y % 16 != 0) - BIO_printf(STDout, "\n"); - BIO_printf(STDout, "};\n"); - - z = i2d_X509(x, &d); - BIO_printf(STDout, "unsigned char XXX_certificate[%d]={\n", - z); + len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d); + print_array(out, "the_public_key", len, (unsigned char *)m); d = (unsigned char *)m; - for (y = 0; y < z; y++) { - BIO_printf(STDout, "0x%02X,", d[y]); - if ((y & 0x0f) == 0x0f) - BIO_printf(STDout, "\n"); - } - if (y % 16 != 0) - BIO_printf(STDout, "\n"); - BIO_printf(STDout, "};\n"); - + len = i2d_X509(x, &d); + print_array(out, "the_certificate", len, (unsigned char *)m); OPENSSL_free(m); } else if (text == i) { - X509_print_ex(STDout, x, nmflag, certflag); + X509_print_ex(out, x, nmflag, certflag); } else if (startdate == i) { - BIO_puts(STDout, "notBefore="); - ASN1_TIME_print(STDout, X509_get_notBefore(x)); - BIO_puts(STDout, "\n"); + BIO_puts(out, "notBefore="); + ASN1_TIME_print(out, X509_get_notBefore(x)); + BIO_puts(out, "\n"); } else if (enddate == i) { - BIO_puts(STDout, "notAfter="); - ASN1_TIME_print(STDout, X509_get_notAfter(x)); - BIO_puts(STDout, "\n"); + BIO_puts(out, "notAfter="); + ASN1_TIME_print(out, X509_get_notAfter(x)); + BIO_puts(out, "\n"); } else if (fingerprint == i) { int j; unsigned int n; @@ -888,10 +831,10 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "out of memory\n"); goto end; } - BIO_printf(STDout, "%s Fingerprint=", + BIO_printf(out, "%s Fingerprint=", OBJ_nid2sn(EVP_MD_type(fdig))); for (j = 0; j < (int)n; j++) { - BIO_printf(STDout, "%02X%c", md[j], (j + 1 == (int)n) + BIO_printf(out, "%02X%c", md[j], (j + 1 == (int)n) ? '\n' : ':'); } } @@ -900,8 +843,7 @@ int MAIN(int argc, char **argv) else if ((sign_flag == i) && (x509req == 0)) { BIO_printf(bio_err, "Getting Private key\n"); if (Upkey == NULL) { - Upkey = load_key(bio_err, - keyfile, keyformat, 0, + Upkey = load_key(keyfile, keyformat, 0, passin, e, "Private key"); if (Upkey == NULL) goto end; @@ -913,8 +855,7 @@ int MAIN(int argc, char **argv) } else if (CA_flag == i) { BIO_printf(bio_err, "Getting CA Private Key\n"); if (CAkeyfile != NULL) { - CApkey = load_key(bio_err, - CAkeyfile, CAkeyformat, + CApkey = load_key(CAkeyfile, CAkeyformat, 0, passin, e, "CA Private Key"); if (CApkey == NULL) goto end; @@ -924,7 +865,7 @@ int MAIN(int argc, char **argv) if (!x509_certify(ctx, CAfile, digest, x, xca, CApkey, sigopts, CAserial, CA_createserial, days, clrext, - extconf, extsect, sno)) + extconf, extsect, sno, reqfile)) goto end; } else if (x509req == i) { EVP_PKEY *pk; @@ -934,8 +875,7 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "no request key file specified\n"); goto end; } else { - pk = load_key(bio_err, - keyfile, keyformat, 0, + pk = load_key(keyfile, keyformat, 0, passin, e, "request key"); if (pk == NULL) goto end; @@ -973,9 +913,9 @@ int MAIN(int argc, char **argv) goto end; } - print_cert_checks(STDout, x, checkhost, checkemail, checkip); + print_cert_checks(out, x, checkhost, checkemail, checkip); - if (noout) { + if (noout || nocert) { ret = 0; goto end; } @@ -1012,11 +952,10 @@ int MAIN(int argc, char **argv) ret = 0; end: if (need_rand) - app_RAND_write_file(NULL, bio_err); + app_RAND_write_file(NULL); OBJ_cleanup(); NCONF_free(extconf); BIO_free_all(out); - BIO_free_all(STDout); X509_STORE_free(ctx); X509_REQ_free(req); X509_free(x); @@ -1032,8 +971,7 @@ int MAIN(int argc, char **argv) sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free); if (passin) OPENSSL_free(passin); - apps_shutdown(); - OPENSSL_EXIT(ret); + return (ret); } static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile, @@ -1087,7 +1025,7 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, STACK_OF(OPENSSL_STRING) *sigopts, char *serialfile, int create, int days, int clrext, CONF *conf, char *section, - ASN1_INTEGER *sno) + ASN1_INTEGER *sno, int reqfile) { int ret = 0; ASN1_INTEGER *bs = NULL; @@ -1154,7 +1092,7 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest, goto end; } - if (!do_X509_sign(bio_err, x, pkey, digest, sigopts)) + if (!do_X509_sign(x, pkey, digest, sigopts)) goto end; ret = 1; end: @@ -1204,22 +1142,11 @@ static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest, CONF *conf, char *section) { - EVP_PKEY *pktmp; - - pktmp = X509_get_pubkey(x); - EVP_PKEY_copy_parameters(pktmp, pkey); - EVP_PKEY_save_parameters(pktmp, 1); - EVP_PKEY_free(pktmp); - if (!X509_set_issuer_name(x, X509_get_subject_name(x))) goto err; if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL) goto err; - /* Lets just make it 12:00am GMT, Jan 1 1970 */ - /* memcpy(x->cert_info->validity->notBefore,"700101120000Z",13); */ - /* 28 days to be certified */ - if (X509_gmtime_adj(X509_get_notAfter(x), (long)60 * 60 * 24 * days) == NULL) goto err; |