=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/openssl/spkac.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- src/usr.bin/openssl/spkac.c 2014/08/28 14:23:52 1.2 +++ src/usr.bin/openssl/spkac.c 2015/01/08 11:08:50 1.3 @@ -1,4 +1,4 @@ -/* $OpenBSD: spkac.c,v 1.2 2014/08/28 14:23:52 jsing Exp $ */ +/* $OpenBSD: spkac.c,v 1.3 2015/01/08 11:08:50 doug Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 1999. Based on an original idea by Massimiliano Pala * (madwolf@openca.org). @@ -72,121 +72,156 @@ #include #include -/* -in arg - input file - default stdin - * -out arg - output file - default stdout - */ +static struct { + char *challenge; +#ifndef OPENSSL_NO_ENGINE + char *engine; +#endif + char *infile; + char *keyfile; + int noout; + char *outfile; + char *passargin; + int pubkey; + char *spkac; + char *spksect; + int verify; +} spkac_config; -int spkac_main(int, char **); +static struct option spkac_options[] = { + { + .name = "challenge", + .argname = "string", + .desc = "Specify challenge string if SPKAC is generated", + .type = OPTION_ARG, + .opt.arg = &spkac_config.challenge, + }, +#ifndef OPENSSL_NO_ENGINE + { + .name = "engine", + .argname = "id", + .desc = "Use the engine specified by the given identifier", + .type = OPTION_ARG, + .opt.arg = &spkac_config.engine, + }, +#endif + { + .name = "in", + .argname = "file", + .desc = "Input file (default stdin)", + .type = OPTION_ARG, + .opt.arg = &spkac_config.infile, + }, + { + .name = "key", + .argname = "file", + .desc = "Create SPKAC using private key file", + .type = OPTION_ARG, + .opt.arg = &spkac_config.keyfile, + }, + { + .name = "noout", + .desc = "Do not print text version of SPKAC", + .type = OPTION_FLAG, + .opt.flag = &spkac_config.noout, + }, + { + .name = "out", + .argname = "file", + .desc = "Output file (default stdout)", + .type = OPTION_ARG, + .opt.arg = &spkac_config.outfile, + }, + { + .name = "passin", + .argname = "src", + .desc = "Input file passphrase source", + .type = OPTION_ARG, + .opt.arg = &spkac_config.passargin, + }, + { + .name = "pubkey", + .desc = "Output public key of an SPKAC (not used if creating)", + .type = OPTION_FLAG, + .opt.flag = &spkac_config.pubkey, + }, + { + .name = "spkac", + .argname = "name", + .desc = "SPKAC name (default \"SPKAC\")", + .type = OPTION_ARG, + .opt.arg = &spkac_config.spkac, + }, + { + .name = "spksect", + .argname = "name", + .desc = "Name of the section containing SPKAC (default" + " \"default\")", + .type = OPTION_ARG, + .opt.arg = &spkac_config.spksect, + }, + { + .name = "verify", + .desc = "Verify digital signature on supplied SPKAC", + .type = OPTION_FLAG, + .opt.flag = &spkac_config.verify, + }, + { NULL } +}; +static void +spkac_usage(void) +{ + fprintf(stderr, + "usage: spkac [-challenge string] [-engine id] [-in file] " + "[-key file] [-noout]\n" + " [-out file] [-passin src] [-pubkey] [-spkac name] " + "[-spksect section]\n" + " [-verify]\n\n"); + options_usage(spkac_options); +} + int spkac_main(int argc, char **argv) { ENGINE *e = NULL; - int i, badops = 0, ret = 1; + int i, ret = 1; BIO *in = NULL, *out = NULL; - int verify = 0, noout = 0, pubkey = 0; - char *infile = NULL, *outfile = NULL, *prog; - char *passargin = NULL, *passin = NULL; - const char *spkac = "SPKAC", *spksect = "default"; + char *passin = NULL; char *spkstr = NULL; - char *challenge = NULL, *keyfile = NULL; CONF *conf = NULL; NETSCAPE_SPKI *spki = NULL; EVP_PKEY *pkey = NULL; -#ifndef OPENSSL_NO_ENGINE - char *engine = NULL; -#endif - prog = argv[0]; - argc--; - argv++; - while (argc >= 1) { - 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, "-passin") == 0) { - if (--argc < 1) - goto bad; - passargin = *(++argv); - } else if (strcmp(*argv, "-key") == 0) { - if (--argc < 1) - goto bad; - keyfile = *(++argv); - } else if (strcmp(*argv, "-challenge") == 0) { - if (--argc < 1) - goto bad; - challenge = *(++argv); - } else if (strcmp(*argv, "-spkac") == 0) { - if (--argc < 1) - goto bad; - spkac = *(++argv); - } else if (strcmp(*argv, "-spksect") == 0) { - if (--argc < 1) - goto bad; - spksect = *(++argv); - } -#ifndef OPENSSL_NO_ENGINE - else if (strcmp(*argv, "-engine") == 0) { - if (--argc < 1) - goto bad; - engine = *(++argv); - } -#endif - else if (strcmp(*argv, "-noout") == 0) - noout = 1; - else if (strcmp(*argv, "-pubkey") == 0) - pubkey = 1; - else if (strcmp(*argv, "-verify") == 0) - verify = 1; - else - badops = 1; - argc--; - argv++; - } + memset(&spkac_config, 0, sizeof(spkac_config)); + spkac_config.spkac = "SPKAC"; + spkac_config.spksect = "default"; - if (badops) { -bad: - BIO_printf(bio_err, "%s [options]\n", prog); - BIO_printf(bio_err, "where options are\n"); - BIO_printf(bio_err, " -in arg input file\n"); - BIO_printf(bio_err, " -out arg output file\n"); - BIO_printf(bio_err, " -key arg create SPKAC using private key\n"); - BIO_printf(bio_err, " -passin arg input file pass phrase source\n"); - BIO_printf(bio_err, " -challenge arg challenge string\n"); - BIO_printf(bio_err, " -spkac arg alternative SPKAC name\n"); - BIO_printf(bio_err, " -noout don't print SPKAC\n"); - BIO_printf(bio_err, " -pubkey output public key\n"); - BIO_printf(bio_err, " -verify verify SPKAC signature\n"); -#ifndef OPENSSL_NO_ENGINE - BIO_printf(bio_err, " -engine e use engine e, possibly a hardware device.\n"); -#endif - goto end; + if (options_parse(argc, argv, spkac_options, NULL, NULL) != 0) { + spkac_usage(); + return (1); } - if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { + if (!app_passwd(bio_err, spkac_config.passargin, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } #ifndef OPENSSL_NO_ENGINE - e = setup_engine(bio_err, engine, 0); + e = setup_engine(bio_err, spkac_config.engine, 0); #endif - if (keyfile) { + if (spkac_config.keyfile) { pkey = load_key(bio_err, - strcmp(keyfile, "-") ? keyfile : NULL, - FORMAT_PEM, 1, passin, e, "private key"); + strcmp(spkac_config.keyfile, "-") ? spkac_config.keyfile + : NULL, FORMAT_PEM, 1, passin, e, "private key"); if (!pkey) { goto end; } spki = NETSCAPE_SPKI_new(); - if (challenge) + if (spkac_config.challenge) ASN1_STRING_set(spki->spkac->challenge, - challenge, (int) strlen(challenge)); + spkac_config.challenge, + (int) strlen(spkac_config.challenge)); NETSCAPE_SPKI_set_pubkey(spki, pkey); NETSCAPE_SPKI_sign(spki, pkey, EVP_md5()); spkstr = NETSCAPE_SPKI_b64_encode(spki); @@ -196,8 +231,8 @@ goto end; } - if (outfile) - out = BIO_new_file(outfile, "w"); + if (spkac_config.outfile) + out = BIO_new_file(spkac_config.outfile, "w"); else out = BIO_new_fp(stdout, BIO_NOCLOSE); @@ -211,8 +246,8 @@ free(spkstr); goto end; } - if (infile) - in = BIO_new_file(infile, "r"); + if (spkac_config.infile) + in = BIO_new_file(spkac_config.infile, "r"); else in = BIO_new_fp(stdin, BIO_NOCLOSE); @@ -229,10 +264,12 @@ ERR_print_errors(bio_err); goto end; } - spkstr = NCONF_get_string(conf, spksect, spkac); + spkstr = NCONF_get_string(conf, spkac_config.spksect, + spkac_config.spkac); if (!spkstr) { - BIO_printf(bio_err, "Can't find SPKAC called \"%s\"\n", spkac); + BIO_printf(bio_err, "Can't find SPKAC called \"%s\"\n", + spkac_config.spkac); ERR_print_errors(bio_err); goto end; } @@ -243,8 +280,8 @@ ERR_print_errors(bio_err); goto end; } - if (outfile) - out = BIO_new_file(outfile, "w"); + if (spkac_config.outfile) + out = BIO_new_file(spkac_config.outfile, "w"); else { out = BIO_new_fp(stdout, BIO_NOCLOSE); } @@ -254,10 +291,10 @@ ERR_print_errors(bio_err); goto end; } - if (!noout) + if (!spkac_config.noout) NETSCAPE_SPKI_print(out, spki); pkey = NETSCAPE_SPKI_get_pubkey(spki); - if (verify) { + if (spkac_config.verify) { i = NETSCAPE_SPKI_verify(spki, pkey); if (i > 0) BIO_printf(bio_err, "Signature OK\n"); @@ -267,7 +304,7 @@ goto end; } } - if (pubkey) + if (spkac_config.pubkey) PEM_write_bio_PUBKEY(out, pkey); ret = 0;