From: Richard Levitte Date: Mon, 20 Feb 2017 01:47:56 +0000 (+0100) Subject: Adapt storeutl to allow search for specific objects X-Git-Tag: OpenSSL_1_1_1-pre2~18 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=511e4e0d6890d552eba77971bbcfb5df51e772e2 Adapt storeutl to allow search for specific objects Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/2688) --- diff --git a/apps/storeutl.c b/apps/storeutl.c index 6c2f3ca7f8..d40d263ef9 100644 --- a/apps/storeutl.c +++ b/apps/storeutl.c @@ -16,13 +16,17 @@ #include static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata, - int expected, - int text, int noout, int recursive, int indent, BIO *out); + int expected, int criterion, OSSL_STORE_SEARCH *search, + int text, int noout, int recursive, int indent, BIO *out, + const char *prog); typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ENGINE, OPT_OUT, OPT_PASSIN, OPT_NOOUT, OPT_TEXT, OPT_RECURSIVE, - OPT_SEARCHFOR_CERTS, OPT_SEARCHFOR_KEYS, OPT_SEARCHFOR_CRLS + OPT_SEARCHFOR_CERTS, OPT_SEARCHFOR_KEYS, OPT_SEARCHFOR_CRLS, + OPT_CRITERION_SUBJECT, OPT_CRITERION_ISSUER, OPT_CRITERION_SERIAL, + OPT_CRITERION_FINGERPRINT, OPT_CRITERION_ALIAS, + OPT_MD } OPTION_CHOICE; const OPTIONS storeutl_options[] = { @@ -35,6 +39,12 @@ const OPTIONS storeutl_options[] = { {"certs", OPT_SEARCHFOR_CERTS, '-', "Search for certificates only"}, {"keys", OPT_SEARCHFOR_KEYS, '-', "Search for keys only"}, {"crls", OPT_SEARCHFOR_CRLS, '-', "Search for CRLs only"}, + {"subject", OPT_CRITERION_SUBJECT, 's', "Search by subject"}, + {"issuer", OPT_CRITERION_ISSUER, 's', "Search by issuer and serial, issuer name"}, + {"serial", OPT_CRITERION_SERIAL, 's', "Search by issuer and serial, serial number"}, + {"fingerprint", OPT_CRITERION_FINGERPRINT, 's', "Search by public key fingerprint, given in hex"}, + {"alias", OPT_CRITERION_ALIAS, 's', "Search by alias"}, + {"", OPT_MD, '-', "Any supported digest"}, #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, #endif @@ -52,6 +62,14 @@ int storeutl_main(int argc, char *argv[]) char *prog = opt_init(argc, argv, storeutl_options); PW_CB_DATA pw_cb_data; int expected = 0; + int criterion = 0; + X509_NAME *subject = NULL, *issuer = NULL; + ASN1_INTEGER *serial = NULL; + unsigned char *fingerprint = NULL; + size_t fingerprintlen = 0; + char *alias = NULL; + OSSL_STORE_SEARCH *search = NULL; + const EVP_MD *digest = NULL; while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -111,9 +129,115 @@ int storeutl_main(int argc, char *argv[]) OPENSSL_assert(expected != 0); } break; + case OPT_CRITERION_SUBJECT: + if (criterion != 0) { + BIO_printf(bio_err, "%s: criterion already given.\n", + prog); + goto end; + } + criterion = OSSL_STORE_SEARCH_BY_NAME; + if (subject != NULL) { + BIO_printf(bio_err, "%s: subject already given.\n", + prog); + goto end; + } + if ((subject = parse_name(opt_arg(), MBSTRING_UTF8, 1)) == NULL) { + BIO_printf(bio_err, "%s: can't parse subject argument.\n", + prog); + goto end; + } + break; + case OPT_CRITERION_ISSUER: + if (criterion != 0 + || (criterion == OSSL_STORE_SEARCH_BY_ISSUER_SERIAL + && issuer != NULL)) { + BIO_printf(bio_err, "%s: criterion already given.\n", + prog); + goto end; + } + criterion = OSSL_STORE_SEARCH_BY_ISSUER_SERIAL; + if (issuer != NULL) { + BIO_printf(bio_err, "%s: issuer already given.\n", + prog); + goto end; + } + if ((issuer = parse_name(opt_arg(), MBSTRING_UTF8, 1)) == NULL) { + BIO_printf(bio_err, "%s: can't parse issuer argument.\n", + prog); + goto end; + } + break; + case OPT_CRITERION_SERIAL: + if (criterion != 0 + || (criterion == OSSL_STORE_SEARCH_BY_ISSUER_SERIAL + && serial != NULL)) { + BIO_printf(bio_err, "%s: criterion already given.\n", + prog); + goto end; + } + criterion = OSSL_STORE_SEARCH_BY_ISSUER_SERIAL; + if (serial != NULL) { + BIO_printf(bio_err, "%s: serial number already given.\n", + prog); + goto end; + } + if ((serial = s2i_ASN1_INTEGER(NULL, opt_arg())) == NULL) { + BIO_printf(bio_err, "%s: can't parse serial number argument.\n", + prog); + goto end; + } + break; + case OPT_CRITERION_FINGERPRINT: + if (criterion != 0 + || (criterion == OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT + && fingerprint != NULL)) { + BIO_printf(bio_err, "%s: criterion already given.\n", + prog); + goto end; + } + criterion = OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT; + if (fingerprint != NULL) { + BIO_printf(bio_err, "%s: fingerprint already given.\n", + prog); + goto end; + } + { + long tmplen = 0; + + if ((fingerprint = OPENSSL_hexstr2buf(opt_arg(), &tmplen)) + == NULL) { + BIO_printf(bio_err, + "%s: can't parse fingerprint argument.\n", + prog); + goto end; + } + fingerprintlen = (size_t)tmplen; + } + break; + case OPT_CRITERION_ALIAS: + if (criterion != 0) { + BIO_printf(bio_err, "%s: criterion already given.\n", + prog); + goto end; + } + criterion = OSSL_STORE_SEARCH_BY_ALIAS; + if (alias != NULL) { + BIO_printf(bio_err, "%s: alias already given.\n", + prog); + goto end; + } + if ((alias = OPENSSL_strdup(opt_arg())) == NULL) { + BIO_printf(bio_err, "%s: can't parse alias argument.\n", + prog); + goto end; + } + break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; + case OPT_MD: + if (!opt_md(opt_unknown(), &digest)) + goto opthelp; } } argc = opt_num_rest(); @@ -128,6 +252,45 @@ int storeutl_main(int argc, char *argv[]) goto opthelp; } + if (criterion != 0) { + switch (criterion) { + case OSSL_STORE_SEARCH_BY_NAME: + if ((search = OSSL_STORE_SEARCH_by_name(subject)) == NULL) { + ERR_print_errors(bio_err); + goto end; + } + break; + case OSSL_STORE_SEARCH_BY_ISSUER_SERIAL: + if (issuer == NULL || serial == NULL) { + BIO_printf(bio_err, + "%s: both -issuer and -serial must be given.\n", + prog); + goto end; + } + if ((search = OSSL_STORE_SEARCH_by_issuer_serial(issuer, serial)) + == NULL) { + ERR_print_errors(bio_err); + goto end; + } + break; + case OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT: + if ((search = OSSL_STORE_SEARCH_by_key_fingerprint(digest, + fingerprint, + fingerprintlen)) + == NULL) { + ERR_print_errors(bio_err); + goto end; + } + break; + case OSSL_STORE_SEARCH_BY_ALIAS: + if ((search = OSSL_STORE_SEARCH_by_alias(alias)) == NULL) { + ERR_print_errors(bio_err); + goto end; + } + break; + } + } + if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; @@ -140,10 +303,15 @@ int storeutl_main(int argc, char *argv[]) goto end; ret = process(argv[0], get_ui_method(), &pw_cb_data, - expected, - text, noout, recursive, 0, out); + expected, criterion, search, + text, noout, recursive, 0, out, prog); end: + OPENSSL_free(alias); + ASN1_INTEGER_free(serial); + X509_NAME_free(subject); + X509_NAME_free(issuer); + OSSL_STORE_SEARCH_free(search); BIO_free_all(out); OPENSSL_free(passin); release_engine(e); @@ -164,8 +332,9 @@ static int indent_printf(int indent, BIO *bio, const char *format, ...) } static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata, - int expected, - int text, int noout, int recursive, int indent, BIO *out) + int expected, int criterion, OSSL_STORE_SEARCH *search, + int text, int noout, int recursive, int indent, BIO *out, + const char *prog) { OSSL_STORE_CTX *store_ctx = NULL; int ret = 1, items = 0; @@ -184,6 +353,20 @@ static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata, } } + if (criterion != 0) { + if (!OSSL_STORE_supports_search(store_ctx, criterion)) { + BIO_printf(bio_err, + "%s: the store scheme doesn't support the given search criteria.\n", + prog); + goto end2; + } + + if (!OSSL_STORE_find(store_ctx, search)) { + ERR_print_errors(bio_err); + goto end2; + } + } + /* From here on, we count errors, and we'll return the count at the end */ ret = 0; @@ -236,8 +419,8 @@ static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata, if (recursive) { const char *suburi = OSSL_STORE_INFO_get0_NAME(info); ret += process(suburi, uimeth, uidata, - expected, - text, noout, recursive, indent + 2, out); + expected, criterion, search, + text, noout, recursive, indent + 2, out, prog); } break; case OSSL_STORE_INFO_PARAMS: