[openssl-commits] [openssl] master update
Richard Levitte
levitte at openssl.org
Fri Feb 23 06:43:17 UTC 2018
The branch master has been updated
via 0764e4131243e72b54c86486462975d066cd9453 (commit)
via a75831f9cc608e4f4502f86f6ab35ef742762e85 (commit)
via 6ab6deccd95c97a6235f345b371664afb65f77c7 (commit)
via 511e4e0d6890d552eba77971bbcfb5df51e772e2 (commit)
via 93d2f9fa4a5d03ac227a54f5c0f2f9b23f1121b6 (commit)
via fac8673b8aed77231e23d51d78cd8eb995d21f5c (commit)
via 7622baf8a7c3e9084f97a4f41406a29ef5d04fc3 (commit)
via ce9586b98c792288a57620035b7f5824563389ce (commit)
via 9511d973444d19e1d492762c5f28473cbd31a5a9 (commit)
via 6541d9e2646d693b3879ce438a2e9b8d290907fc (commit)
via 072bfcc90b6f7c206e39339da519567c4460250c (commit)
via 4eefdbda815c2cd76d788049c839e90a5ac6b843 (commit)
from d5927344207e0d5d9ee5c862631fdc292e65e7e6 (commit)
- Log -----------------------------------------------------------------
commit 0764e4131243e72b54c86486462975d066cd9453
Author: Richard Levitte <levitte at openssl.org>
Date: Thu Feb 22 05:45:18 2018 +0100
Add a note in CHANGES
[extended tests]
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2688)
commit a75831f9cc608e4f4502f86f6ab35ef742762e85
Author: Richard Levitte <levitte at openssl.org>
Date: Mon Feb 20 02:49:13 2017 +0100
Test the storeutl searching options
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2688)
commit 6ab6deccd95c97a6235f345b371664afb65f77c7
Author: Richard Levitte <levitte at openssl.org>
Date: Wed Jul 5 19:17:40 2017 +0200
STORE: Add documentation on search criteria
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2688)
commit 511e4e0d6890d552eba77971bbcfb5df51e772e2
Author: Richard Levitte <levitte at openssl.org>
Date: Mon Feb 20 02:47:56 2017 +0100
Adapt storeutl to allow search for specific objects
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2688)
commit 93d2f9fa4a5d03ac227a54f5c0f2f9b23f1121b6
Author: Richard Levitte <levitte at openssl.org>
Date: Mon Feb 20 02:39:52 2017 +0100
STORE 'file' scheme loader: Add search capibility
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2688)
commit fac8673b8aed77231e23d51d78cd8eb995d21f5c
Author: Richard Levitte <levitte at openssl.org>
Date: Sun Feb 19 12:24:19 2017 +0100
STORE: Add the possibility to search for specific information
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2688)
commit 7622baf8a7c3e9084f97a4f41406a29ef5d04fc3
Author: Richard Levitte <levitte at openssl.org>
Date: Sat Feb 11 04:02:32 2017 +0100
Test the storeutl expectation options
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2688)
commit ce9586b98c792288a57620035b7f5824563389ce
Author: Richard Levitte <levitte at openssl.org>
Date: Wed Jul 5 16:15:48 2017 +0200
STORE: Add documentation on expecting specific infos
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2688)
commit 9511d973444d19e1d492762c5f28473cbd31a5a9
Author: Richard Levitte <levitte at openssl.org>
Date: Sat Feb 11 03:20:45 2017 +0100
Adapt storeutl to allow looking for a specific info type
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2688)
commit 6541d9e2646d693b3879ce438a2e9b8d290907fc
Author: Richard Levitte <levitte at openssl.org>
Date: Sat Feb 11 02:27:31 2017 +0100
STORE 'file' scheme loader: Add info type expectation
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2688)
commit 072bfcc90b6f7c206e39339da519567c4460250c
Author: Richard Levitte <levitte at openssl.org>
Date: Sat Feb 11 02:33:18 2017 +0100
STORE: Add the possibility to specify an expected info type
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2688)
commit 4eefdbda815c2cd76d788049c839e90a5ac6b843
Author: Richard Levitte <levitte at openssl.org>
Date: Sat Feb 11 02:50:50 2017 +0100
STORE: In preparation for coming work, mark when loading is started
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2688)
-----------------------------------------------------------------------
Summary of changes:
CHANGES | 6 +
apps/storeutl.c | 246 +++++++++++++++++++++++++++++++++++++++--
crypto/err/openssl.txt | 16 +++
crypto/store/loader_file.c | 123 ++++++++++++++++++++-
crypto/store/store_err.c | 25 ++++-
crypto/store/store_lib.c | 188 ++++++++++++++++++++++++++++++-
crypto/store/store_locl.h | 32 +++++-
crypto/store/store_register.c | 14 +++
doc/man1/storeutl.pod | 50 ++++++++-
doc/man3/OSSL_STORE_LOADER.pod | 45 +++++++-
doc/man3/OSSL_STORE_SEARCH.pod | 193 ++++++++++++++++++++++++++++++++
doc/man3/OSSL_STORE_expect.pod | 79 +++++++++++++
doc/man7/ossl_store.pod | 6 +-
include/openssl/ossl_typ.h | 1 +
include/openssl/store.h | 56 ++++++++++
include/openssl/storeerr.h | 12 ++
test/recipes/90-test_store.t | 72 ++++++++++--
util/libcrypto.num | 16 +++
util/private.num | 3 +
19 files changed, 1157 insertions(+), 26 deletions(-)
create mode 100644 doc/man3/OSSL_STORE_SEARCH.pod
create mode 100644 doc/man3/OSSL_STORE_expect.pod
diff --git a/CHANGES b/CHANGES
index 5abfbad..e08644a 100644
--- a/CHANGES
+++ b/CHANGES
@@ -9,6 +9,12 @@
Changes between 1.1.0g and 1.1.1 [xx XXX xxxx]
+ *) Extend OSSL_STORE with capabilities to search and to narrow the set of
+ objects loaded. This adds the functions OSSL_STORE_expect() and
+ OSSL_STORE_find() as well as needed tools to construct searches and
+ get the search data out of them.
+ [Richard Levitte]
+
*) Support for TLSv1.3 added. Note that users upgrading from an earlier
version of OpenSSL should review their configuration settings to ensure
that they are still appropriate for TLSv1.3. In particular if no TLSv1.3
diff --git a/apps/storeutl.c b/apps/storeutl.c
index 326c2af..d40d263 100644
--- a/apps/storeutl.c
+++ b/apps/storeutl.c
@@ -16,11 +16,17 @@
#include <openssl/store.h>
static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata,
- 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_NOOUT, OPT_TEXT, OPT_RECURSIVE,
+ 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[] = {
@@ -30,6 +36,15 @@ const OPTIONS storeutl_options[] = {
{"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
{"text", OPT_TEXT, '-', "Print a text form of the objects"},
{"noout", OPT_NOOUT, '-', "No PEM output, just status"},
+ {"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
@@ -46,6 +61,15 @@ int storeutl_main(int argc, char *argv[])
OPTION_CHOICE o;
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) {
@@ -73,9 +97,147 @@ int storeutl_main(int argc, char *argv[])
case OPT_RECURSIVE:
recursive = 1;
break;
+ case OPT_SEARCHFOR_CERTS:
+ case OPT_SEARCHFOR_KEYS:
+ case OPT_SEARCHFOR_CRLS:
+ if (expected != 0) {
+ BIO_printf(bio_err, "%s: only one search type can be given.\n",
+ prog);
+ goto end;
+ }
+ {
+ static const struct {
+ enum OPTION_choice choice;
+ int type;
+ } map[] = {
+ {OPT_SEARCHFOR_CERTS, OSSL_STORE_INFO_CERT},
+ {OPT_SEARCHFOR_KEYS, OSSL_STORE_INFO_PKEY},
+ {OPT_SEARCHFOR_CRLS, OSSL_STORE_INFO_CRL},
+ };
+ size_t i;
+
+ for (i = 0; i < OSSL_NELEM(map); i++) {
+ if (o == map[i].choice) {
+ expected = map[i].type;
+ break;
+ }
+ }
+ /*
+ * If expected wasn't set at this point, it means the map
+ * isn't syncronised with the possible options leading here.
+ */
+ 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();
@@ -90,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;
@@ -101,10 +302,16 @@ int storeutl_main(int argc, char *argv[])
if (out == NULL)
goto end;
- ret = process(argv[0], get_ui_method(), &pw_cb_data, text, noout, recursive,
- 0, out);
+ ret = process(argv[0], get_ui_method(), &pw_cb_data,
+ 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);
@@ -125,7 +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 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;
@@ -137,6 +346,27 @@ static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata,
return ret;
}
+ if (expected != 0) {
+ if (!OSSL_STORE_expect(store_ctx, expected)) {
+ ERR_print_errors(bio_err);
+ goto end2;
+ }
+ }
+
+ 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;
@@ -188,8 +418,9 @@ static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata,
case OSSL_STORE_INFO_NAME:
if (recursive) {
const char *suburi = OSSL_STORE_INFO_get0_NAME(info);
- ret += process(suburi, uimeth, uidata, text, noout, recursive,
- indent + 2, out);
+ ret += process(suburi, uimeth, uidata,
+ expected, criterion, search,
+ text, noout, recursive, indent + 2, out, prog);
}
break;
case OSSL_STORE_INFO_PARAMS:
@@ -230,6 +461,7 @@ static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata,
}
indent_printf(indent, out, "Total found: %d\n", items);
+ end2:
if (!OSSL_STORE_close(store_ctx)) {
ERR_print_errors(bio_err);
ret++;
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 9b8a03a..e406bec 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -751,14 +751,17 @@ OCSP_F_OCSP_REQUEST_VERIFY:116:OCSP_request_verify
OCSP_F_OCSP_RESPONSE_GET1_BASIC:111:OCSP_response_get1_basic
OCSP_F_PARSE_HTTP_LINE1:118:parse_http_line1
OSSL_STORE_F_FILE_CTRL:129:file_ctrl
+OSSL_STORE_F_FILE_FIND:138:file_find
OSSL_STORE_F_FILE_GET_PASS:118:file_get_pass
OSSL_STORE_F_FILE_LOAD:119:file_load
OSSL_STORE_F_FILE_LOAD_TRY_DECODE:124:file_load_try_decode
OSSL_STORE_F_FILE_NAME_TO_URI:126:file_name_to_uri
OSSL_STORE_F_FILE_OPEN:120:file_open
OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO:127:ossl_store_attach_pem_bio
+OSSL_STORE_F_OSSL_STORE_EXPECT:130:OSSL_STORE_expect
OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT:128:\
ossl_store_file_attach_pem_bio_int
+OSSL_STORE_F_OSSL_STORE_FIND:131:OSSL_STORE_find
OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT:100:ossl_store_get0_loader_int
OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT:101:OSSL_STORE_INFO_get1_CERT
OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL:102:OSSL_STORE_INFO_get1_CRL
@@ -780,6 +783,12 @@ OSSL_STORE_F_OSSL_STORE_LOADER_NEW:113:OSSL_STORE_LOADER_new
OSSL_STORE_F_OSSL_STORE_OPEN:114:OSSL_STORE_open
OSSL_STORE_F_OSSL_STORE_OPEN_INT:115:*
OSSL_STORE_F_OSSL_STORE_REGISTER_LOADER_INT:117:ossl_store_register_loader_int
+OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ALIAS:132:OSSL_STORE_SEARCH_by_alias
+OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ISSUER_SERIAL:133:\
+ OSSL_STORE_SEARCH_by_issuer_serial
+OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT:136:\
+ OSSL_STORE_SEARCH_by_key_fingerprint
+OSSL_STORE_F_OSSL_STORE_SEARCH_BY_NAME:137:OSSL_STORE_SEARCH_by_name
OSSL_STORE_F_OSSL_STORE_UNREGISTER_LOADER_INT:116:\
ossl_store_unregister_loader_int
OSSL_STORE_F_TRY_DECODE_PARAMS:121:try_decode_params
@@ -2146,9 +2155,12 @@ OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE:129:unsupported requestorname type
OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE:107:ambiguous content type
OSSL_STORE_R_BAD_PASSWORD_READ:115:bad password read
OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC:113:error verifying pkcs12 mac
+OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST:121:\
+ fingerprint size does not match digest
OSSL_STORE_R_INVALID_SCHEME:106:invalid scheme
OSSL_STORE_R_IS_NOT_A:112:is not a
OSSL_STORE_R_LOADER_INCOMPLETE:116:loader incomplete
+OSSL_STORE_R_LOADING_STARTED:117:loading started
OSSL_STORE_R_NOT_A_CERTIFICATE:100:not a certificate
OSSL_STORE_R_NOT_A_CRL:101:not a crl
OSSL_STORE_R_NOT_A_KEY:102:not a key
@@ -2156,10 +2168,14 @@ OSSL_STORE_R_NOT_A_NAME:103:not a name
OSSL_STORE_R_NOT_PARAMETERS:104:not parameters
OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR:114:passphrase callback error
OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE:108:path must be absolute
+OSSL_STORE_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES:119:\
+ search only supported for directories
OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED:109:\
ui process interrupted or cancelled
OSSL_STORE_R_UNREGISTERED_SCHEME:105:unregistered scheme
OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE:110:unsupported content type
+OSSL_STORE_R_UNSUPPORTED_OPERATION:118:unsupported operation
+OSSL_STORE_R_UNSUPPORTED_SEARCH_TYPE:120:unsupported search type
OSSL_STORE_R_URI_AUTHORITY_UNSUPPORTED:111:uri authority unsupported
PEM_R_BAD_BASE64_DECODE:100:bad base64 decode
PEM_R_BAD_DECRYPT:101:bad decrypt
diff --git a/crypto/store/loader_file.c b/crypto/store/loader_file.c
index 588a581..ea1b321 100644
--- a/crypto/store/loader_file.c
+++ b/crypto/store/loader_file.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -10,6 +10,7 @@
#include "e_os.h"
#include <string.h>
#include <sys/stat.h>
+#include <ctype.h>
#include <assert.h>
#include <openssl/bio.h>
@@ -713,6 +714,13 @@ struct ossl_store_loader_ctx_st {
char *uri;
/*
+ * When a search expression is given, these are filled in.
+ * |search_name| contains the file basename to look for.
+ * The string is exactly 8 characters long.
+ */
+ char search_name[9];
+
+ /*
* The directory reading utility we have combines opening with
* reading the first name. To make sure we can detect the end
* at the right time, we read early and cache the name.
@@ -721,6 +729,9 @@ struct ossl_store_loader_ctx_st {
int last_errno;
} dir;
} _;
+
+ /* Expected object type. May be unspecified */
+ int expected_type;
};
static void OSSL_STORE_LOADER_CTX_free(OSSL_STORE_LOADER_CTX *ctx)
@@ -908,6 +919,43 @@ static int file_ctrl(OSSL_STORE_LOADER_CTX *ctx, int cmd, va_list args)
return ret;
}
+static int file_expect(OSSL_STORE_LOADER_CTX *ctx, int expected)
+{
+ ctx->expected_type = expected;
+ return 1;
+}
+
+static int file_find(OSSL_STORE_LOADER_CTX *ctx, OSSL_STORE_SEARCH *search)
+{
+ /*
+ * If ctx == NULL, the library is looking to know if this loader supports
+ * the given search type.
+ */
+
+ if (OSSL_STORE_SEARCH_get_type(search) == OSSL_STORE_SEARCH_BY_NAME) {
+ unsigned long hash = 0;
+
+ if (ctx == NULL)
+ return 1;
+
+ if (ctx->type != is_dir) {
+ OSSL_STOREerr(OSSL_STORE_F_FILE_FIND,
+ OSSL_STORE_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES);
+ return 0;
+ }
+
+ hash = X509_NAME_hash(OSSL_STORE_SEARCH_get0_name(search));
+ BIO_snprintf(ctx->_.dir.search_name, sizeof(ctx->_.dir.search_name),
+ "%08lx", hash);
+ return 1;
+ }
+
+ if (ctx != NULL)
+ OSSL_STOREerr(OSSL_STORE_F_FILE_FIND,
+ OSSL_STORE_R_UNSUPPORTED_SEARCH_TYPE);
+ return 0;
+}
+
/* Internal function to decode an already opened PEM file */
OSSL_STORE_LOADER_CTX *ossl_store_file_attach_pem_bio_int(BIO *bp)
{
@@ -1128,6 +1176,68 @@ static int file_name_to_uri(OSSL_STORE_LOADER_CTX *ctx, const char *name,
return 1;
}
+static int file_name_check(OSSL_STORE_LOADER_CTX *ctx, const char *name)
+{
+ const char *p = NULL;
+
+ /* If there are no search criteria, all names are accepted */
+ if (ctx->_.dir.search_name[0] == '\0')
+ return 1;
+
+ /* If the expected type isn't supported, no name is accepted */
+ if (ctx->expected_type != 0
+ && ctx->expected_type != OSSL_STORE_INFO_CERT
+ && ctx->expected_type != OSSL_STORE_INFO_CRL)
+ return 0;
+
+ /*
+ * First, check the basename
+ */
+ if (strncasecmp(name, ctx->_.dir.search_name,
+ sizeof(ctx->_.dir.search_name) - 1) != 0
+ || name[sizeof(ctx->_.dir.search_name) - 1] != '.')
+ return 0;
+ p = &name[sizeof(ctx->_.dir.search_name)];
+
+ /*
+ * Then, if the expected type is a CRL, check that the extension starts
+ * with 'r'
+ */
+ if (*p == 'r') {
+ p++;
+ if (ctx->expected_type != 0
+ && ctx->expected_type != OSSL_STORE_INFO_CRL)
+ return 0;
+ } else if (ctx->expected_type == OSSL_STORE_INFO_CRL) {
+ return 0;
+ }
+
+ /*
+ * Last, check that the rest of the extension is a decimal number, at
+ * least one digit long.
+ */
+ if (!isdigit(*p))
+ return 0;
+ while (isdigit(*p))
+ p++;
+
+# ifdef __VMS
+ /*
+ * One extra step here, check for a possible generation number.
+ */
+ if (*p == ';')
+ for (p++; *p != '\0'; p++)
+ if (!isdigit(*p))
+ break;
+# endif
+
+ /*
+ * If we've reached the end of the string at this point, we've successfully
+ * found a fitting file name.
+ */
+ return *p == '\0';
+}
+
static int file_eof(OSSL_STORE_LOADER_CTX *ctx);
static int file_error(OSSL_STORE_LOADER_CTX *ctx);
static OSSL_STORE_INFO *file_load(OSSL_STORE_LOADER_CTX *ctx,
@@ -1156,6 +1266,7 @@ static OSSL_STORE_INFO *file_load(OSSL_STORE_LOADER_CTX *ctx,
}
if (ctx->_.dir.last_entry[0] != '.'
+ && file_name_check(ctx, ctx->_.dir.last_entry)
&& !file_name_to_uri(ctx, ctx->_.dir.last_entry, &newname))
return NULL;
@@ -1181,6 +1292,7 @@ static OSSL_STORE_INFO *file_load(OSSL_STORE_LOADER_CTX *ctx,
} else {
int matchcount = -1;
+ again:
result = file_load_try_repeat(ctx, ui_method, ui_data);
if (result != NULL)
return result;
@@ -1251,6 +1363,13 @@ static OSSL_STORE_INFO *file_load(OSSL_STORE_LOADER_CTX *ctx,
/* We bail out on ambiguity */
if (matchcount > 1)
return NULL;
+
+ if (result != NULL
+ && ctx->expected_type != 0
+ && ctx->expected_type != OSSL_STORE_INFO_get_type(result)) {
+ OSSL_STORE_INFO_free(result);
+ goto again;
+ }
}
return result;
@@ -1295,6 +1414,8 @@ static OSSL_STORE_LOADER file_loader =
NULL,
file_open,
file_ctrl,
+ file_expect,
+ file_find,
file_load,
file_eof,
file_error,
diff --git a/crypto/store/store_err.c b/crypto/store/store_err.c
index c78b3899..5a8a840 100644
--- a/crypto/store/store_err.c
+++ b/crypto/store/store_err.c
@@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -15,6 +15,7 @@
static const ERR_STRING_DATA OSSL_STORE_str_functs[] = {
{ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_CTRL, 0), "file_ctrl"},
+ {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_FIND, 0), "file_find"},
{ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_GET_PASS, 0),
"file_get_pass"},
{ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_LOAD, 0), "file_load"},
@@ -25,8 +26,12 @@ static const ERR_STRING_DATA OSSL_STORE_str_functs[] = {
{ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_OPEN, 0), "file_open"},
{ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO, 0),
"ossl_store_attach_pem_bio"},
+ {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_EXPECT, 0),
+ "OSSL_STORE_expect"},
{ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT, 0),
"ossl_store_file_attach_pem_bio_int"},
+ {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_FIND, 0),
+ "OSSL_STORE_find"},
{ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT, 0),
"ossl_store_get0_loader_int"},
{ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT, 0),
@@ -64,6 +69,14 @@ static const ERR_STRING_DATA OSSL_STORE_str_functs[] = {
{ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_OPEN_INT, 0), ""},
{ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_REGISTER_LOADER_INT, 0),
"ossl_store_register_loader_int"},
+ {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ALIAS, 0),
+ "OSSL_STORE_SEARCH_by_alias"},
+ {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ISSUER_SERIAL, 0),
+ "OSSL_STORE_SEARCH_by_issuer_serial"},
+ {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT, 0),
+ "OSSL_STORE_SEARCH_by_key_fingerprint"},
+ {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_SEARCH_BY_NAME, 0),
+ "OSSL_STORE_SEARCH_by_name"},
{ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_UNREGISTER_LOADER_INT, 0),
"ossl_store_unregister_loader_int"},
{ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_TRY_DECODE_PARAMS, 0),
@@ -82,11 +95,15 @@ static const ERR_STRING_DATA OSSL_STORE_str_reasons[] = {
"bad password read"},
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC),
"error verifying pkcs12 mac"},
+ {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST),
+ "fingerprint size does not match digest"},
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_INVALID_SCHEME),
"invalid scheme"},
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_IS_NOT_A), "is not a"},
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_LOADER_INCOMPLETE),
"loader incomplete"},
+ {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_LOADING_STARTED),
+ "loading started"},
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_CERTIFICATE),
"not a certificate"},
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_CRL), "not a crl"},
@@ -98,12 +115,18 @@ static const ERR_STRING_DATA OSSL_STORE_str_reasons[] = {
"passphrase callback error"},
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE),
"path must be absolute"},
+ {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES),
+ "search only supported for directories"},
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED),
"ui process interrupted or cancelled"},
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_UNREGISTERED_SCHEME),
"unregistered scheme"},
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE),
"unsupported content type"},
+ {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_UNSUPPORTED_OPERATION),
+ "unsupported operation"},
+ {ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_UNSUPPORTED_SEARCH_TYPE),
+ "unsupported search type"},
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_URI_AUTHORITY_UNSUPPORTED),
"uri authority unsupported"},
{0, NULL}
diff --git a/crypto/store/store_lib.c b/crypto/store/store_lib.c
index 24876a3..1c43547 100644
--- a/crypto/store/store_lib.c
+++ b/crypto/store/store_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -10,6 +10,10 @@
#include "e_os.h"
#include <stdlib.h>
#include <string.h>
+#include <assert.h>
+
+#include "e_os.h"
+
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/store.h>
@@ -24,6 +28,10 @@ struct ossl_store_ctx_st {
void *ui_data;
OSSL_STORE_post_process_info_fn post_process;
void *post_process_data;
+ int expected_type;
+
+ /* 0 before the first STORE_load(), 1 otherwise */
+ int loading;
};
OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, const UI_METHOD *ui_method,
@@ -125,10 +133,41 @@ int OSSL_STORE_vctrl(OSSL_STORE_CTX *ctx, int cmd, va_list args)
return 0;
}
+int OSSL_STORE_expect(OSSL_STORE_CTX *ctx, int expected_type)
+{
+ if (ctx->loading) {
+ OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_EXPECT,
+ OSSL_STORE_R_LOADING_STARTED);
+ return 0;
+ }
+
+ ctx->expected_type = expected_type;
+ if (ctx->loader->expect != NULL)
+ return ctx->loader->expect(ctx->loader_ctx, expected_type);
+ return 1;
+}
+
+int OSSL_STORE_find(OSSL_STORE_CTX *ctx, OSSL_STORE_SEARCH *search)
+{
+ if (ctx->loading) {
+ OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_FIND,
+ OSSL_STORE_R_LOADING_STARTED);
+ return 0;
+ }
+ if (ctx->loader->find == NULL) {
+ OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_FIND,
+ OSSL_STORE_R_UNSUPPORTED_OPERATION);
+ return 0;
+ }
+
+ return ctx->loader->find(ctx->loader_ctx, search);
+}
+
OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx)
{
OSSL_STORE_INFO *v = NULL;
+ ctx->loading = 1;
again:
if (OSSL_STORE_eof(ctx))
return NULL;
@@ -146,6 +185,24 @@ OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx)
goto again;
}
+ if (v != NULL && ctx->expected_type != 0) {
+ int returned_type = OSSL_STORE_INFO_get_type(v);
+
+ if (returned_type != OSSL_STORE_INFO_NAME && returned_type != 0) {
+ /*
+ * Soft assert here so those who want to harsly weed out faulty
+ * loaders can do so using a debugging version of libcrypto.
+ */
+ if (ctx->loader->expect != NULL)
+ assert(ctx->expected_type == returned_type);
+
+ if (ctx->expected_type != returned_type) {
+ OSSL_STORE_INFO_free(v);
+ goto again;
+ }
+ }
+ }
+
return v;
}
@@ -411,6 +468,135 @@ void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info)
}
}
+int OSSL_STORE_supports_search(OSSL_STORE_CTX *ctx, int search_type)
+{
+ OSSL_STORE_SEARCH tmp_search;
+
+ if (ctx->loader->find == NULL)
+ return 0;
+ tmp_search.search_type = search_type;
+ return ctx->loader->find(NULL, &tmp_search);
+}
+
+/* Search term constructors */
+OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_name(X509_NAME *name)
+{
+ OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search));
+
+ if (search == NULL) {
+ OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_NAME,
+ ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ search->search_type = OSSL_STORE_SEARCH_BY_NAME;
+ search->name = name;
+ return search;
+}
+
+OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_issuer_serial(X509_NAME *name,
+ const ASN1_INTEGER *serial)
+{
+ OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search));
+
+ if (search == NULL) {
+ OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ISSUER_SERIAL,
+ ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ search->search_type = OSSL_STORE_SEARCH_BY_ISSUER_SERIAL;
+ search->name = name;
+ search->serial = serial;
+ return search;
+}
+
+OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_key_fingerprint(const EVP_MD *digest,
+ const unsigned char
+ *bytes, size_t len)
+{
+ OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search));
+
+ if (search == NULL) {
+ OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT,
+ ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ if (digest != NULL && len != (size_t)EVP_MD_size(digest)) {
+ char buf1[20], buf2[20];
+
+ BIO_snprintf(buf1, sizeof(buf1), "%d", EVP_MD_size(digest));
+ BIO_snprintf(buf2, sizeof(buf2), "%zu", len);
+ OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT,
+ OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST);
+ ERR_add_error_data(5, EVP_MD_name(digest), " size is ", buf1,
+ ", fingerprint size is ", buf2);
+ }
+
+ search->search_type = OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT;
+ search->digest = digest;
+ search->string = bytes;
+ search->stringlength = len;
+ return search;
+}
+
+OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_alias(const char *alias)
+{
+ OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search));
+
+ if (search == NULL) {
+ OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ALIAS,
+ ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ search->search_type = OSSL_STORE_SEARCH_BY_ALIAS;
+ search->string = (const unsigned char *)alias;
+ search->stringlength = strlen(alias);
+ return search;
+}
+
+/* Search term destructor */
+void OSSL_STORE_SEARCH_free(OSSL_STORE_SEARCH *search)
+{
+ OPENSSL_free(search);
+}
+
+/* Search term accessors */
+int OSSL_STORE_SEARCH_get_type(const OSSL_STORE_SEARCH *criterion)
+{
+ return criterion->search_type;
+}
+
+X509_NAME *OSSL_STORE_SEARCH_get0_name(OSSL_STORE_SEARCH *criterion)
+{
+ return criterion->name;
+}
+
+const ASN1_INTEGER *OSSL_STORE_SEARCH_get0_serial(const OSSL_STORE_SEARCH
+ *criterion)
+{
+ return criterion->serial;
+}
+
+const unsigned char *OSSL_STORE_SEARCH_get0_bytes(const OSSL_STORE_SEARCH
+ *criterion, size_t *length)
+{
+ *length = criterion->stringlength;
+ return criterion->string;
+}
+
+const char *OSSL_STORE_SEARCH_get0_string(const OSSL_STORE_SEARCH *criterion)
+{
+ return (const char *)criterion->string;
+}
+
+const EVP_MD *OSSL_STORE_SEARCH_get0_digest(const OSSL_STORE_SEARCH *criterion)
+{
+ return criterion->digest;
+}
+
/* Internal functions */
OSSL_STORE_INFO *ossl_store_info_new_EMBEDDED(const char *new_pem_name,
BUF_MEM *embedded)
diff --git a/crypto/store/store_locl.h b/crypto/store/store_locl.h
index 789d332..369dcb3 100644
--- a/crypto/store/store_locl.h
+++ b/crypto/store/store_locl.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -62,6 +62,34 @@ BUF_MEM *ossl_store_info_get0_EMBEDDED_buffer(OSSL_STORE_INFO *info);
char *ossl_store_info_get0_EMBEDDED_pem_name(OSSL_STORE_INFO *info);
/*-
+ * OSSL_STORE_SEARCH stuff
+ * -----------------------
+ */
+
+struct ossl_store_search_st {
+ int search_type;
+
+ /*
+ * Used by OSSL_STORE_SEARCH_BY_NAME and
+ * OSSL_STORE_SEARCH_BY_ISSUER_SERIAL
+ */
+ X509_NAME *name;
+
+ /* Used by OSSL_STORE_SEARCH_BY_ISSUER_SERIAL */
+ const ASN1_INTEGER *serial;
+
+ /* Used by OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT */
+ const EVP_MD *digest;
+
+ /*
+ * Used by OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT and
+ * OSSL_STORE_SEARCH_BY_ALIAS
+ */
+ const unsigned char *string;
+ size_t stringlength;
+};
+
+/*-
* OSSL_STORE_LOADER stuff
* -----------------------
*/
@@ -75,6 +103,8 @@ struct ossl_store_loader_st {
ENGINE *engine;
OSSL_STORE_open_fn open;
OSSL_STORE_ctrl_fn ctrl;
+ OSSL_STORE_expect_fn expect;
+ OSSL_STORE_find_fn find;
OSSL_STORE_load_fn load;
OSSL_STORE_eof_fn eof;
OSSL_STORE_error_fn error;
diff --git a/crypto/store/store_register.c b/crypto/store/store_register.c
index 855c28e..e68cb3c 100644
--- a/crypto/store/store_register.c
+++ b/crypto/store/store_register.c
@@ -78,6 +78,20 @@ int OSSL_STORE_LOADER_set_ctrl(OSSL_STORE_LOADER *loader,
return 1;
}
+int OSSL_STORE_LOADER_set_expect(OSSL_STORE_LOADER *loader,
+ OSSL_STORE_expect_fn expect_function)
+{
+ loader->expect = expect_function;
+ return 1;
+}
+
+int OSSL_STORE_LOADER_set_find(OSSL_STORE_LOADER *loader,
+ OSSL_STORE_find_fn find_function)
+{
+ loader->find = find_function;
+ return 1;
+}
+
int OSSL_STORE_LOADER_set_load(OSSL_STORE_LOADER *loader,
OSSL_STORE_load_fn load_function)
{
diff --git a/doc/man1/storeutl.pod b/doc/man1/storeutl.pod
index 74361a7..3f26ab5 100644
--- a/doc/man1/storeutl.pod
+++ b/doc/man1/storeutl.pod
@@ -15,6 +15,15 @@ B<openssl> B<storeutl>
[B<-text arg>]
[B<-engine id>]
[B<-r>]
+[B<-certs>]
+[B<-keys>]
+[B<-crls>]
+[B<-subject arg>]
+[B<-issuer arg>]
+[B<-serial arg>]
+[B<-alias arg>]
+[B<-fingerprint arg>]
+[B<-I<digest>>]
B<uri> ...
=head1 DESCRIPTION
@@ -60,6 +69,45 @@ The engine will then be set as the default for all available algorithms.
Fetch objects recursively when possible.
+=item B<-certs>
+
+=item B<-keys>
+
+=item B<-crls>
+
+Only select the certificates, keys or CRLs from the given URI.
+However, if this URI would return a set of names (URIs), those are always
+returned.
+
+=item B<-subject arg>
+
+Search for an object having the subject name B<arg>.
+The arg must be formatted as I</type0=value0/type1=value1/type2=...>,
+characters may be escaped by \ (backslash), no spaces are skipped.
+
+=item B<-issuer arg>
+
+=item B<-serial arg>
+
+Search for an object having the given issuer name and serial number.
+These two options I<must> be used together.
+The issuer arg must be formatted as I</type0=value0/type1=value1/type2=...>,
+characters may be escaped by \ (backslash), no spaces are skipped.
+The serial arg may be specified as a decimal value or a hex value if preceded
+by B<0x>.
+
+=item B<-alias arg>
+
+Search for an object having the given alias.
+
+=item B<-fingerprint arg>
+
+Search for an object having the given fingerprint.
+
+=item B<-I<digest>>
+
+The digest that was used to compute the fingerprint given with B<-fingerprint>.
+
=back
=head1 SEE ALSO
@@ -72,7 +120,7 @@ B<openssl> B<storeutl> was added to OpenSSL 1.1.1.
=head1 COPYRIGHT
-Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the OpenSSL license (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
diff --git a/doc/man3/OSSL_STORE_LOADER.pod b/doc/man3/OSSL_STORE_LOADER.pod
index 0bdd112..e827434 100644
--- a/doc/man3/OSSL_STORE_LOADER.pod
+++ b/doc/man3/OSSL_STORE_LOADER.pod
@@ -5,10 +5,12 @@
OSSL_STORE_LOADER, OSSL_STORE_LOADER_CTX, OSSL_STORE_LOADER_new,
OSSL_STORE_LOADER_get0_engine, OSSL_STORE_LOADER_get0_scheme,
OSSL_STORE_LOADER_set_open, OSSL_STORE_LOADER_set_ctrl,
+OSSL_STORE_LOADER_set_expect, OSSL_STORE_LOADER_set_find,
OSSL_STORE_LOADER_set_load, OSSL_STORE_LOADER_set_eof,
OSSL_STORE_LOADER_set_error, OSSL_STORE_LOADER_set_close,
OSSL_STORE_LOADER_free, OSSL_STORE_register_loader,
OSSL_STORE_unregister_loader, OSSL_STORE_open_fn, OSSL_STORE_ctrl_fn,
+OSSL_STORE_expect_fn, OSSL_STORE_find_fn,
OSSL_STORE_load_fn, OSSL_STORE_eof_fn, OSSL_STORE_error_fn,
OSSL_STORE_close_fn - Types and functions to manipulate, register and
unregister STORE loaders for different URI schemes
@@ -37,6 +39,13 @@ unregister STORE loaders for different URI schemes
va_list args);
int OSSL_STORE_LOADER_set_ctrl(OSSL_STORE_LOADER *store_loader,
OSSL_STORE_ctrl_fn store_ctrl_function);
+ typedef int (*OSSL_STORE_expect_fn)(OSSL_STORE_LOADER_CTX *ctx, int expected);
+ int OSSL_STORE_LOADER_set_expect(OSSL_STORE_LOADER *loader,
+ OSSL_STORE_expect_fn expect_function);
+ typedef int (*OSSL_STORE_find_fn)(OSSL_STORE_LOADER_CTX *ctx,
+ OSSL_STORE_SEARCH *criteria);
+ int OSSL_STORE_LOADER_set_find(OSSL_STORE_LOADER *loader,
+ OSSL_STORE_find_fn find_function);
typedef OSSL_STORE_INFO *(*OSSL_STORE_load_fn)(OSSL_STORE_LOADER_CTX *ctx,
UI_METHOD *ui_method,
void *ui_data);
@@ -71,9 +80,10 @@ OSSL_STORE_close() for this scheme.
B<OSSL_STORE_LOADER_CTX> is a type template, to be defined by each loader
using B<struct ossl_store_loader_ctx_st { ... }>.
-B<OSSL_STORE_open_fn>, B<OSSL_STORE_ctrl_fn>, B<OSSL_STORE_load_fn>,
-B<OSSL_STORE_eof_fn> and B<OSSL_STORE_close_fn> are the function pointer
-types used within a STORE loader.
+B<OSSL_STORE_open_fn>, B<OSSL_STORE_ctrl_fn>, B<OSSL_STORE_expect_fn>,
+B<OSSL_STORE_find_fn>, B<OSSL_STORE_load_fn>, B<OSSL_STORE_eof_fn>,
+and B<OSSL_STORE_close_fn>
+are the function pointer types used within a STORE loader.
The functions pointed at define the functionality of the given loader.
=over 4
@@ -108,6 +118,27 @@ numbers.
This function is expected to return 1 on success, 0 on error.
+=item B<OSSL_STORE_expect_fn>
+
+This function takes a B<OSSL_STORE_LOADER_CTX> pointer and a B<OSSL_STORE_INFO>
+identity B<expected>, and is used to tell the loader what object type is
+expected.
+B<expected> may be zero to signify that no specific object type is expected.
+
+This function is expected to return 1 on success, 0 on error.
+
+=item B<OSSL_STORE_find_fn>
+
+This function takes a B<OSSL_STORE_LOADER_CTX> pointer and a
+B<OSSL_STORE_SEARCH> search criterion, and is used to tell the loader what
+to search for.
+
+When called with the loader context being B<NULL>, this function is expected
+to return 1 if the loader supports the criterion, otherwise 0.
+
+When called with the loader context being something other than B<NULL>, this
+function is expected to return 1 on success, 0 on error.
+
=item B<OSSL_STORE_load_fn>
This function takes a B<OSSL_STORE_LOADER_CTX> pointer and a B<UI_METHOD>
@@ -161,6 +192,9 @@ B<store_loader>.
OSSL_STORE_LOADER_set_ctrl() sets the control function for the
B<store_loader>.
+OSSL_STORE_LOADER_set_expect() sets the expect function for the
+B<store_loader>.
+
OSSL_STORE_LOADER_set_load() sets the loader function for the
B<store_loader>.
@@ -186,9 +220,10 @@ The B<file:> scheme has built in support.
=head1 RETURN VALUES
The functions with the types B<OSSL_STORE_open_fn>, B<OSSL_STORE_ctrl_fn>,
+B<OSSL_STORE_expect_fn>,
B<OSSL_STORE_load_fn>, B<OSSL_STORE_eof_fn> and B<OSSL_STORE_close_fn> have the
-same return values as OSSL_STORE_open(), OSSL_STORE_load(), OSSL_STORE_eof() and
-OSSL_STORE_close(), respectively.
+same return values as OSSL_STORE_open(), OSSL_STORE_ctrl(), OSSL_STORE_expect(),
+OSSL_STORE_load(), OSSL_STORE_eof() and OSSL_STORE_close(), respectively.
OSSL_STORE_LOADER_new() returns a pointer to a B<OSSL_STORE_LOADER> on success,
or B<NULL> on failure.
diff --git a/doc/man3/OSSL_STORE_SEARCH.pod b/doc/man3/OSSL_STORE_SEARCH.pod
new file mode 100644
index 0000000..411664d
--- /dev/null
+++ b/doc/man3/OSSL_STORE_SEARCH.pod
@@ -0,0 +1,193 @@
+=pod
+
+=head1 NAME
+
+OSSL_STORE_SEARCH,
+OSSL_STORE_SEARCH_by_name,
+OSSL_STORE_SEARCH_by_issuer_serial,
+OSSL_STORE_SEARCH_by_key_fingerprint,
+OSSL_STORE_SEARCH_by_alias,
+OSSL_STORE_SEARCH_free,
+OSSL_STORE_SEARCH_get_type,
+OSSL_STORE_SEARCH_get0_name,
+OSSL_STORE_SEARCH_get0_serial,
+OSSL_STORE_SEARCH_get0_bytes,
+OSSL_STORE_SEARCH_get0_string,
+OSSL_STORE_SEARCH_get0_digest
+- Type and functions to create OSSL_STORE search criteria
+
+=head1 SYNOPSIS
+
+ #include <openssl/store.h>
+
+ typedef struct ossl_store_search_st OSSL_STORE_SEARCH;
+
+ OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_name(X509_NAME *name);
+ OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_issuer_serial(X509_NAME *name,
+ const ASN1_INTEGER
+ *serial);
+ OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_key_fingerprint(const EVP_MD *digest,
+ const unsigned char
+ *bytes, int len);
+ OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_alias(const char *alias);
+
+ void OSSL_STORE_SEARCH_free(OSSL_STORE_SEARCH *search);
+
+ int OSSL_STORE_SEARCH_get_type(const OSSL_STORE_SEARCH *criterion);
+ X509_NAME *OSSL_STORE_SEARCH_get0_name(OSSL_STORE_SEARCH *criterion);
+ const ASN1_INTEGER *OSSL_STORE_SEARCH_get0_serial(const OSSL_STORE_SEARCH
+ *criterion);
+ const unsigned char *OSSL_STORE_SEARCH_get0_bytes(const OSSL_STORE_SEARCH
+ *criterion, size_t *length);
+ const char *OSSL_STORE_SEARCH_get0_string(const OSSL_STORE_SEARCH *criterion);
+ const EVP_MD *OSSL_STORE_SEARCH_get0_digest(const OSSL_STORE_SEARCH
+ *criterion);
+
+=head1 DESCRIPTION
+
+These functions are use to specify search criteria to help search for specific
+objects through other names than just the URI that's given to OSSL_STORE_open().
+For example, this can be useful for an application that has received a URI
+and then wants to add on search criteria in a uniform and supported manner.
+
+=head2 Types
+
+B<OSSL_STORE_SEARCH> is an opaque type that holds the constructed search
+criterion, and that can be given to an OSSL_STORE context with
+OSSL_STORE_find().
+
+The calling application owns the allocation of an B<OSSL_STORE_SEARCH> at all
+times, and should therefore be careful not to deallocate it before
+OSSL_STORE_close() has been called for the OSSL_STORE context it was given
+to.
+
+=head2 Application Functions
+
+OSSL_STORE_SEARCH_by_name(),
+OSSL_STORE_SEARCH_by_issuer_serial(),
+OSSL_STORE_SEARCH_by_key_fingerprint(),
+and OSSL_STORE_SEARCH_by_alias()
+are used to create an B<OSSL_STORE_SEARCH> from a subject name, an issuer name
+and serial number pair, a key fingerprint, and an alias (for example a friendly
+name).
+The parameters that are provided are not copied, only referred to in a
+criterion, so they must have at least the same life time as the created
+B<OSSL_STORE_SEARCH>.
+
+OSSL_STORE_SEARCH_free() is used to free the B<OSSL_STORE_SEARCH>.
+
+=head2 Loader Functions
+
+OSSL_STORE_SEARCH_get_type() returns the criterion type for the given
+B<OSSL_STORE_SEARCH>.
+
+OSSL_STORE_SEARCH_get0_name(), OSSL_STORE_SEARCH_get0_serial(),
+OSSL_STORE_SEARCH_get0_bytes(), OSSL_STORE_SEARCH_get0_string(),
+and OSSL_STORE_SEARCH_get0_digest()
+are used to retrieve different data from a B<OSSL_STORE_SEARCH>, as
+available for each type.
+For more information, see L</SUPPORTED CRITERION TYPES> below.
+
+=head1 SUPPORTED CRITERION TYPES
+
+Currently supported criterion types are:
+
+=over 4
+
+=item OSSL_STORE_SEARCH_BY_NAME
+
+This criterion supports a search by exact match of subject name.
+The subject name itself is a B<X509_NAME> pointer.
+A criterion of this type is created with OSSL_STORE_SEARCH_by_name(),
+and the actual subject name is retrieved with OSSL_STORE_SEARCH_get0_name().
+
+=item OSSL_STORE_SEARCH_BY_ISSUER_SERIAL
+
+This criterion supports a search by exact match of both issuer name and serial
+number.
+The issuer name itself is a B<X509_NAME> pointer, and the serial number is
+a B<ASN1_INTEGER> pointer.
+A criterion of this type is created with OSSL_STORE_SEARCH_by_issuer_serial()
+and the actual issuer name and serial number are retrieved with
+OSSL_STORE_SEARCH_get0_name() and OSSL_STORE_SEARCH_get0_serial().
+
+=item OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT
+
+This criterion supports a search by exact match of key fingerprint.
+The key fingerprint in itself is a string of bytes and its length, as
+well as the algorithm that was used to compute the fingerprint.
+The digest may be left unspecified (NULL), and in that case, the
+loader has to decide on a default digest and compare fingerprints
+accordingly.
+A criterion of this type is created with OSSL_STORE_SEARCH_by_key_fingerprint()
+and the actual fingerprint and its length can be retrieved with
+OSSL_STORE_SEARCH_get0_bytes().
+The digest can be retreived with OSSL_STORE_SEARCH_get0_digest().
+
+=item OSSL_STORE_SEARCH_BY_ALIAS
+
+This criterion supports a search by match of an alias of some kind.
+The alias in itself is a simple C string.
+A criterion of this type is created with OSSL_STORE_SEARCH_by_alias()
+and the actual alias is retrieved with OSSL_STORE_SEARCH_get0_string().
+
+=back
+
+=head1 RETURN VALUES
+
+OSSL_STORE_SEARCH_by_name(),
+OSSL_STORE_SEARCH_by_issuer_serial(),
+OSSL_STORE_SEARCH_by_key_fingerprint(),
+and OSSL_STORE_SEARCH_by_alias()
+return a B<OSSL_STORE_SEARCH> pointer on success, or B<NULL> on failure.
+
+OSSL_STORE_SEARCH_get_type() returns the criterion type of the given
+B<OSSL_STORE_SEARCH>.
+There is no error value.
+
+OSSL_STORE_SEARCH_get0_name() returns a B<X509_NAME> pointer on success,
+or B<NULL> when the given B<OSSL_STORE_SEARCH> was of a different type.
+
+OSSL_STORE_SEARCH_get0_serial() returns a B<ASN1_INTEGER> pointer on success,
+or B<NULL> when the given B<OSSL_STORE_SEARCH> was of a different type.
+
+OSSL_STORE_SEARCH_get0_bytes() returns a B<const unsigned char> pointer and
+sets B<*length> to the strings length on success, or B<NULL> when the given
+B<OSSL_STORE_SEARCH> was of a different type.
+
+OSSL_STORE_SEARCH_get0_string() returns a B<const char> pointer on success,
+or B<NULL> when the given B<OSSL_STORE_SEARCH> was of a different type.
+
+OSSL_STORE_SEARCH_get0_digest() returns a B<const EVP_MD> pointer.
+B<NULL> is a valid value and means that the store loader default will
+be used when applicable.
+
+=head1 SEE ALSO
+
+L<ossl_store(7)>, L<OSSL_STORE_supports_search(3)>, L<OSSL_STORE_find(3)>
+
+=head1 HISTORY
+
+B<OSSL_STORE_SEARCH>,
+OSSL_STORE_SEARCH_by_name(),
+OSSL_STORE_SEARCH_by_issuer_serial(),
+OSSL_STORE_SEARCH_by_key_fingerprint(),
+OSSL_STORE_SEARCH_by_alias(),
+OSSL_STORE_SEARCH_free(),
+OSSL_STORE_SEARCH_get_type(),
+OSSL_STORE_SEARCH_get0_name(),
+OSSL_STORE_SEARCH_get0_serial(),
+OSSL_STORE_SEARCH_get0_bytes(),
+and OSSL_STORE_SEARCH_get0_string()
+were added to OpenSSL 1.1.1.
+
+=head1 COPYRIGHT
+
+Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the OpenSSL license (the "License"). You may not use
+this file except in compliance with the License. You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man3/OSSL_STORE_expect.pod b/doc/man3/OSSL_STORE_expect.pod
new file mode 100644
index 0000000..ab0e878
--- /dev/null
+++ b/doc/man3/OSSL_STORE_expect.pod
@@ -0,0 +1,79 @@
+=pod
+
+=head1 NAME
+
+OSSL_STORE_expect,
+OSSL_STORE_supports_search,
+OSSL_STORE_find
+- Specify what object type is expected
+
+=head1 SYNOPSIS
+
+ #include <openssl/store.h>
+
+ int OSSL_STORE_expect(OSSL_STORE_CTX *ctx, int expected_type);
+
+ int OSSL_STORE_supports_search(OSSL_STORE_CTX *ctx, int criterion_type);
+
+ int OSSL_STORE_find(OSSL_STORE_CTX *ctx, OSSL_STORE_SEARCH *search);
+
+=head1 DESCRIPTION
+
+OSSL_STORE_expect() helps applications filter what OSSL_STORE_load() returns
+by specifying a B<OSSL_STORE_INFO> type.
+For example, if C<file:/foo/bar/store.pem> contains several different objects
+and only the certificates are interesting, the application can simply say
+that it expects the type B<OSSL_STORE_INFO_CERT>.
+All known object types (see L<OSSL_STORE_INFO(3)/SUPPORTED OBJECTS>)
+except for B<OSSL_STORE_INFO_NAME> are supported.
+
+OSSL_STORE_find() helps applications specify a criterion for a more fine
+grained search of objects.
+
+OSSL_STORE_supports_search() checks if the loader of the given OSSL_STORE
+context supports the given search type.
+See L<OSSL_STORE_SEARCH/SUPPORED CRITERION TYPES> for information on the
+supported search criterion types.
+
+OSSL_STORE_expect() and OSSL_STORE_find I<must> be called before the first
+OSSL_STORE_load() of a given session, or they will fail.
+
+=head1 NOTES
+
+If a more elaborate filter is required by the application, a better choice
+would be to use a post-processing function.
+See L<OSSL_STORE_open(3)> for more information.
+
+However, some loaders may take advantage of the knowledge of an expected type
+to make object retrieval more efficient, so if a single type is expected, this
+method is usually preferable.
+
+=head1 RETURN VALUES
+
+OSSL_STORE_expect() returns 1 on success, or 0 on failure.
+
+OSSL_STORE_supports_search() returns 1 if the criterion is supported, or 0
+otherwise.
+
+OSSL_STORE_find() returns 1 on success, or 0 on failure.
+
+=head1 SEE ALSO
+
+L<ossl_store(7)>, L<OSSL_STORE_INFO(3)>, L<OSSL_STORE_SEARCH(3)>,
+L<OSSL_STORE_load(3)>
+
+=head1 HISTORY
+
+OSSL_STORE_expect(), OSSL_STORE_supports_search() and OSSL_STORE_find()
+were added to OpenSSL 1.1.1.
+
+=head1 COPYRIGHT
+
+Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the OpenSSL license (the "License"). You may not use
+this file except in compliance with the License. You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man7/ossl_store.pod b/doc/man7/ossl_store.pod
index 71cb27d..98cc04f 100644
--- a/doc/man7/ossl_store.pod
+++ b/doc/man7/ossl_store.pod
@@ -86,11 +86,13 @@ only).
=head1 SEE ALSO
-L<OSSL_STORE_open(3)>, L<OSSL_STORE_INFO(3)>, L<OSSL_STORE_LOADER(3)>
+L<OSSL_STORE_INFO(3)>, L<OSSL_STORE_LOADER(3)>,
+L<OSSL_STORE_open(3)>, L<OSSL_STORE_expect(3)>,
+L<OSSL_STORE_SEARCH(3)>
=head1 COPYRIGHT
-Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the OpenSSL license (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
diff --git a/include/openssl/ossl_typ.h b/include/openssl/ossl_typ.h
index f5214ab..2f242f1 100644
--- a/include/openssl/ossl_typ.h
+++ b/include/openssl/ossl_typ.h
@@ -174,6 +174,7 @@ typedef struct ctlog_store_st CTLOG_STORE;
typedef struct ct_policy_eval_ctx_st CT_POLICY_EVAL_CTX;
typedef struct ossl_store_info_st OSSL_STORE_INFO;
+typedef struct ossl_store_search_st OSSL_STORE_SEARCH;
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && \
defined(INTMAX_MAX) && defined(UINTMAX_MAX)
diff --git a/include/openssl/store.h b/include/openssl/store.h
index ff42953..7b43e8b 100644
--- a/include/openssl/store.h
+++ b/include/openssl/store.h
@@ -153,6 +153,55 @@ void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info);
/*-
+ * Functions to construct a search URI from a base URI and search criteria
+ * -----------------------------------------------------------------------
+ */
+
+/* OSSL_STORE search types */
+# define OSSL_STORE_SEARCH_BY_NAME 1 /* subject in certs, issuer in CRLs */
+# define OSSL_STORE_SEARCH_BY_ISSUER_SERIAL 2
+# define OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT 3
+# define OSSL_STORE_SEARCH_BY_ALIAS 4
+
+/* To check what search types the scheme handler supports */
+int OSSL_STORE_supports_search(OSSL_STORE_CTX *ctx, int search_type);
+
+/* Search term constructors */
+/*
+ * The input is considered to be owned by the caller, and must therefore
+ * remain present throughout the lifetime of the returned OSSL_STORE_SEARCH
+ */
+OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_name(X509_NAME *name);
+OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_issuer_serial(X509_NAME *name,
+ const ASN1_INTEGER
+ *serial);
+OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_key_fingerprint(const EVP_MD *digest,
+ const unsigned char
+ *bytes, size_t len);
+OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_alias(const char *alias);
+
+/* Search term destructor */
+void OSSL_STORE_SEARCH_free(OSSL_STORE_SEARCH *search);
+
+/* Search term accessors */
+int OSSL_STORE_SEARCH_get_type(const OSSL_STORE_SEARCH *criterion);
+X509_NAME *OSSL_STORE_SEARCH_get0_name(OSSL_STORE_SEARCH *criterion);
+const ASN1_INTEGER *OSSL_STORE_SEARCH_get0_serial(const OSSL_STORE_SEARCH
+ *criterion);
+const unsigned char *OSSL_STORE_SEARCH_get0_bytes(const OSSL_STORE_SEARCH
+ *criterion, size_t *length);
+const char *OSSL_STORE_SEARCH_get0_string(const OSSL_STORE_SEARCH *criterion);
+const EVP_MD *OSSL_STORE_SEARCH_get0_digest(const OSSL_STORE_SEARCH *criterion);
+
+/*
+ * Add search criterion and expected return type (which can be unspecified)
+ * to the loading channel. This MUST happen before the first OSSL_STORE_load().
+ */
+int OSSL_STORE_expect(OSSL_STORE_CTX *ctx, int expected_type);
+int OSSL_STORE_find(OSSL_STORE_CTX *ctx, OSSL_STORE_SEARCH *search);
+
+
+/*-
* Function to register a loader for the given URI scheme.
* -------------------------------------------------------
*
@@ -177,6 +226,13 @@ typedef int (*OSSL_STORE_ctrl_fn)(OSSL_STORE_LOADER_CTX *ctx, int cmd,
va_list args);
int OSSL_STORE_LOADER_set_ctrl(OSSL_STORE_LOADER *loader,
OSSL_STORE_ctrl_fn ctrl_function);
+typedef int (*OSSL_STORE_expect_fn)(OSSL_STORE_LOADER_CTX *ctx, int expected);
+int OSSL_STORE_LOADER_set_expect(OSSL_STORE_LOADER *loader,
+ OSSL_STORE_expect_fn expect_function);
+typedef int (*OSSL_STORE_find_fn)(OSSL_STORE_LOADER_CTX *ctx,
+ OSSL_STORE_SEARCH *criteria);
+int OSSL_STORE_LOADER_set_find(OSSL_STORE_LOADER *loader,
+ OSSL_STORE_find_fn find_function);
typedef OSSL_STORE_INFO *(*OSSL_STORE_load_fn)(OSSL_STORE_LOADER_CTX *ctx,
const UI_METHOD *ui_method,
void *ui_data);
diff --git a/include/openssl/storeerr.h b/include/openssl/storeerr.h
index 5476d00..33d0ab7 100644
--- a/include/openssl/storeerr.h
+++ b/include/openssl/storeerr.h
@@ -20,13 +20,16 @@ int ERR_load_OSSL_STORE_strings(void);
* OSSL_STORE function codes.
*/
# define OSSL_STORE_F_FILE_CTRL 129
+# define OSSL_STORE_F_FILE_FIND 138
# define OSSL_STORE_F_FILE_GET_PASS 118
# define OSSL_STORE_F_FILE_LOAD 119
# define OSSL_STORE_F_FILE_LOAD_TRY_DECODE 124
# define OSSL_STORE_F_FILE_NAME_TO_URI 126
# define OSSL_STORE_F_FILE_OPEN 120
# define OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO 127
+# define OSSL_STORE_F_OSSL_STORE_EXPECT 130
# define OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT 128
+# define OSSL_STORE_F_OSSL_STORE_FIND 131
# define OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT 100
# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT 101
# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL 102
@@ -46,6 +49,10 @@ int ERR_load_OSSL_STORE_strings(void);
# define OSSL_STORE_F_OSSL_STORE_OPEN 114
# define OSSL_STORE_F_OSSL_STORE_OPEN_INT 115
# define OSSL_STORE_F_OSSL_STORE_REGISTER_LOADER_INT 117
+# define OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ALIAS 132
+# define OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ISSUER_SERIAL 133
+# define OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT 136
+# define OSSL_STORE_F_OSSL_STORE_SEARCH_BY_NAME 137
# define OSSL_STORE_F_OSSL_STORE_UNREGISTER_LOADER_INT 116
# define OSSL_STORE_F_TRY_DECODE_PARAMS 121
# define OSSL_STORE_F_TRY_DECODE_PKCS12 122
@@ -57,9 +64,11 @@ int ERR_load_OSSL_STORE_strings(void);
# define OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE 107
# define OSSL_STORE_R_BAD_PASSWORD_READ 115
# define OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC 113
+# define OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST 121
# define OSSL_STORE_R_INVALID_SCHEME 106
# define OSSL_STORE_R_IS_NOT_A 112
# define OSSL_STORE_R_LOADER_INCOMPLETE 116
+# define OSSL_STORE_R_LOADING_STARTED 117
# define OSSL_STORE_R_NOT_A_CERTIFICATE 100
# define OSSL_STORE_R_NOT_A_CRL 101
# define OSSL_STORE_R_NOT_A_KEY 102
@@ -67,9 +76,12 @@ int ERR_load_OSSL_STORE_strings(void);
# define OSSL_STORE_R_NOT_PARAMETERS 104
# define OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR 114
# define OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE 108
+# define OSSL_STORE_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES 119
# define OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED 109
# define OSSL_STORE_R_UNREGISTERED_SCHEME 105
# define OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE 110
+# define OSSL_STORE_R_UNSUPPORTED_OPERATION 118
+# define OSSL_STORE_R_UNSUPPORTED_SEARCH_TYPE 120
# define OSSL_STORE_R_URI_AUTHORITY_UNSUPPORTED 111
#endif
diff --git a/test/recipes/90-test_store.t b/test/recipes/90-test_store.t
index 83ec012..2a6414b 100644
--- a/test/recipes/90-test_store.t
+++ b/test/recipes/90-test_store.t
@@ -1,12 +1,12 @@
#! /usr/bin/env perl
-# Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the OpenSSL license (the "License"). You may not use
# this file except in compliance with the License. You can obtain a copy
# in the file LICENSE in the source distribution or at
# https://www.openssl.org/source/license.html
-use File::Spec;
+use File::Spec::Functions;
use File::Copy;
use MIME::Base64;
use OpenSSL::Test qw(:DEFAULT srctop_file srctop_dir bldtop_file data_file);
@@ -69,13 +69,13 @@ my @noexist_file_files =
( "file:blahdiblah.pem",
"file:test/blahdibleh.der" );
-
my $n = (3 * scalar @noexist_files)
+ (6 * scalar @src_files)
+ (4 * scalar @generated_files)
+ (scalar keys %generated_file_files)
+ (scalar @noexist_file_files)
- + 4;
+ + 3
+ + 11;
plan tests => $n;
@@ -84,9 +84,7 @@ indir "store_$$" => sub {
{
skip "failed initialisation", $n unless init();
- # test PEM_read_bio_PrivateKey
- ok(run(app(["openssl", "rsa", "-in", "rsa-key-pkcs8-pbes2-sha256.pem",
- "-passin", "pass:password"])));
+ my $rehash = init_rehash();
foreach (@noexist_files) {
my $file = srctop_file($_);
@@ -152,6 +150,55 @@ indir "store_$$" => sub {
ok(run(app(["openssl", "storeutl", to_abs_file_uri($dir, 1)])));
}
}
+
+ ok(!run(app(['openssl', 'storeutl',
+ '-subject', '/C=AU/ST=QLD/CN=SSLeay\/rsa test cert',
+ srctop_file('test', 'testx509.pem')])),
+ "Checking that -subject can't be used with a single file");
+
+ ok(run(app(['openssl', 'storeutl', '-certs',
+ srctop_file('test', 'testx509.pem')])),
+ "Checking that -certs returns 1 object on a certificate file");
+ ok(run(app(['openssl', 'storeutl', '-certs',
+ srctop_file('test', 'testcrl.pem')])),
+ "Checking that -certs returns 0 objects on a CRL file");
+
+ ok(run(app(['openssl', 'storeutl', '-crls',
+ srctop_file('test', 'testx509.pem')])),
+ "Checking that -crls returns 0 objects on a certificate file");
+ ok(run(app(['openssl', 'storeutl', '-crls',
+ srctop_file('test', 'testcrl.pem')])),
+ "Checking that -crls returns 1 object on a CRL file");
+
+ SKIP: {
+ skip "failed rehash initialisation", 6 unless $rehash;
+
+ # subject from testx509.pem:
+ # '/C=AU/ST=QLD/CN=SSLeay\/rsa test cert'
+ # issuer from testcrl.pem:
+ # '/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority'
+ ok(run(app(['openssl', 'storeutl',
+ '-subject', '/C=AU/ST=QLD/CN=SSLeay\/rsa test cert',
+ catdir(curdir(), 'rehash')])));
+ ok(run(app(['openssl', 'storeutl',
+ '-subject',
+ '/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority',
+ catdir(curdir(), 'rehash')])));
+ ok(run(app(['openssl', 'storeutl', '-certs',
+ '-subject', '/C=AU/ST=QLD/CN=SSLeay\/rsa test cert',
+ catdir(curdir(), 'rehash')])));
+ ok(run(app(['openssl', 'storeutl', '-crls',
+ '-subject', '/C=AU/ST=QLD/CN=SSLeay\/rsa test cert',
+ catdir(curdir(), 'rehash')])));
+ ok(run(app(['openssl', 'storeutl', '-certs',
+ '-subject',
+ '/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority',
+ catdir(curdir(), 'rehash')])));
+ ok(run(app(['openssl', 'storeutl', '-crls',
+ '-subject',
+ '/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority',
+ catdir(curdir(), 'rehash')])));
+ }
}
}, create => 1, cleanup => 1;
@@ -350,6 +397,17 @@ sub init {
);
}
+sub init_rehash {
+ return (
+ mkdir(catdir(curdir(), 'rehash'))
+ && copy(srctop_file('test', 'testx509.pem'),
+ catdir(curdir(), 'rehash'))
+ && copy(srctop_file('test', 'testcrl.pem'),
+ catdir(curdir(), 'rehash'))
+ && run(app(['openssl', 'rehash', catdir(curdir(), 'rehash')]))
+ );
+}
+
sub runall {
my ($function, @items) = @_;
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 0049eab..bd94e27 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4505,3 +4505,19 @@ RAND_DRBG_secure_new 4446 1_1_1 EXIST::FUNCTION:
OSSL_STORE_vctrl 4447 1_1_1 EXIST::FUNCTION:
X509_get0_authority_key_id 4448 1_1_0h EXIST::FUNCTION:
BIO_bind 4449 1_1_1 EXIST::FUNCTION:SOCK
+OSSL_STORE_LOADER_set_expect 4450 1_1_1 EXIST::FUNCTION:
+OSSL_STORE_expect 4451 1_1_1 EXIST::FUNCTION:
+OSSL_STORE_SEARCH_by_key_fingerprint 4452 1_1_1 EXIST::FUNCTION:
+OSSL_STORE_SEARCH_get0_serial 4453 1_1_1 EXIST::FUNCTION:
+OSSL_STORE_SEARCH_by_name 4454 1_1_1 EXIST::FUNCTION:
+OSSL_STORE_supports_search 4455 1_1_1 EXIST::FUNCTION:
+OSSL_STORE_find 4456 1_1_1 EXIST::FUNCTION:
+OSSL_STORE_SEARCH_get_type 4457 1_1_1 EXIST::FUNCTION:
+OSSL_STORE_SEARCH_get0_bytes 4458 1_1_1 EXIST::FUNCTION:
+OSSL_STORE_SEARCH_get0_string 4459 1_1_1 EXIST::FUNCTION:
+OSSL_STORE_SEARCH_by_issuer_serial 4460 1_1_1 EXIST::FUNCTION:
+OSSL_STORE_SEARCH_get0_name 4461 1_1_1 EXIST::FUNCTION:
+OSSL_STORE_SEARCH_by_alias 4462 1_1_1 EXIST::FUNCTION:
+OSSL_STORE_LOADER_set_find 4463 1_1_1 EXIST::FUNCTION:
+OSSL_STORE_SEARCH_free 4464 1_1_1 EXIST::FUNCTION:
+OSSL_STORE_SEARCH_get0_digest 4465 1_1_1 EXIST::FUNCTION:
diff --git a/util/private.num b/util/private.num
index 099a4f7..c106e60 100644
--- a/util/private.num
+++ b/util/private.num
@@ -31,8 +31,11 @@ OSSL_STORE_CTX datatype
OSSL_STORE_INFO datatype
OSSL_STORE_LOADER datatype
OSSL_STORE_LOADER_CTX datatype
+OSSL_STORE_SEARCH datatype
OSSL_STORE_close_fn datatype
OSSL_STORE_ctrl_fn datatype
+OSSL_STORE_expect_fn datatype
+OSSL_STORE_find_fn datatype
OSSL_STORE_eof_fn datatype
OSSL_STORE_error_fn datatype
OSSL_STORE_load_fn datatype
More information about the openssl-commits
mailing list