STORE 'file' scheme loader: refactor the treatment of matches
Sometimes, 'file_load' couldn't really distinguish if a file handler matched the data and produced an error or if it didn't match the data at all. Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/3542)
This commit is contained in:
parent
f95c439804
commit
6fc1d33c90
3 changed files with 145 additions and 62 deletions
|
@ -117,7 +117,7 @@ int storeutl_main(int argc, char *argv[])
|
||||||
if (OSSL_STORE_error(store_ctx)) {
|
if (OSSL_STORE_error(store_ctx)) {
|
||||||
ERR_print_errors(bio_err);
|
ERR_print_errors(bio_err);
|
||||||
ret++;
|
ret++;
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
BIO_printf(bio_err,
|
BIO_printf(bio_err,
|
||||||
|
|
|
@ -125,6 +125,11 @@ static int file_get_pem_pass(char *buf, int num, int w, void *data)
|
||||||
* THE HANDLER'S RESPONSIBILITY TO CREATE AND DESTROY
|
* THE HANDLER'S RESPONSIBILITY TO CREATE AND DESTROY
|
||||||
* THIS CONTEXT APPROPRIATELY, i.e. create on first call
|
* THIS CONTEXT APPROPRIATELY, i.e. create on first call
|
||||||
* and destroy when about to return NULL.
|
* and destroy when about to return NULL.
|
||||||
|
* matchcount: A pointer to an int to count matches for this data.
|
||||||
|
* Usually becomes 0 (no match) or 1 (match!), but may
|
||||||
|
* be higher in the (unlikely) event that the data matches
|
||||||
|
* more than one possibility. The int will always be
|
||||||
|
* zero when the function is called.
|
||||||
* ui_method: Application UI method for getting a password, pin
|
* ui_method: Application UI method for getting a password, pin
|
||||||
* or any other interactive data.
|
* or any other interactive data.
|
||||||
* ui_data: Application data to be passed to ui_method when
|
* ui_data: Application data to be passed to ui_method when
|
||||||
|
@ -136,6 +141,7 @@ typedef OSSL_STORE_INFO *(*file_try_decode_fn)(const char *pem_name,
|
||||||
const char *pem_header,
|
const char *pem_header,
|
||||||
const unsigned char *blob,
|
const unsigned char *blob,
|
||||||
size_t len, void **handler_ctx,
|
size_t len, void **handler_ctx,
|
||||||
|
int *matchcount,
|
||||||
const UI_METHOD *ui_method,
|
const UI_METHOD *ui_method,
|
||||||
void *ui_data);
|
void *ui_data);
|
||||||
/*
|
/*
|
||||||
|
@ -165,6 +171,7 @@ static OSSL_STORE_INFO *try_decode_PKCS12(const char *pem_name,
|
||||||
const char *pem_header,
|
const char *pem_header,
|
||||||
const unsigned char *blob,
|
const unsigned char *blob,
|
||||||
size_t len, void **pctx,
|
size_t len, void **pctx,
|
||||||
|
int *matchcount,
|
||||||
const UI_METHOD *ui_method,
|
const UI_METHOD *ui_method,
|
||||||
void *ui_data)
|
void *ui_data)
|
||||||
{
|
{
|
||||||
|
@ -187,6 +194,8 @@ static OSSL_STORE_INFO *try_decode_PKCS12(const char *pem_name,
|
||||||
X509 *cert = NULL;
|
X509 *cert = NULL;
|
||||||
STACK_OF(X509) *chain = NULL;
|
STACK_OF(X509) *chain = NULL;
|
||||||
|
|
||||||
|
*matchcount = 1;
|
||||||
|
|
||||||
if (PKCS12_verify_mac(p12, "", 0)
|
if (PKCS12_verify_mac(p12, "", 0)
|
||||||
|| PKCS12_verify_mac(p12, NULL, 0)) {
|
|| PKCS12_verify_mac(p12, NULL, 0)) {
|
||||||
pass = "";
|
pass = "";
|
||||||
|
@ -250,8 +259,10 @@ static OSSL_STORE_INFO *try_decode_PKCS12(const char *pem_name,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx != NULL)
|
if (ctx != NULL) {
|
||||||
|
*matchcount = 1;
|
||||||
store_info = sk_OSSL_STORE_INFO_shift(ctx);
|
store_info = sk_OSSL_STORE_INFO_shift(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
return store_info;
|
return store_info;
|
||||||
}
|
}
|
||||||
|
@ -280,6 +291,7 @@ static OSSL_STORE_INFO *try_decode_PKCS8Encrypted(const char *pem_name,
|
||||||
const char *pem_header,
|
const char *pem_header,
|
||||||
const unsigned char *blob,
|
const unsigned char *blob,
|
||||||
size_t len, void **pctx,
|
size_t len, void **pctx,
|
||||||
|
int *matchcount,
|
||||||
const UI_METHOD *ui_method,
|
const UI_METHOD *ui_method,
|
||||||
void *ui_data)
|
void *ui_data)
|
||||||
{
|
{
|
||||||
|
@ -293,12 +305,17 @@ static OSSL_STORE_INFO *try_decode_PKCS8Encrypted(const char *pem_name,
|
||||||
unsigned char *new_data = NULL;
|
unsigned char *new_data = NULL;
|
||||||
int new_data_len;
|
int new_data_len;
|
||||||
|
|
||||||
if (pem_name != NULL && strcmp(pem_name, PEM_STRING_PKCS8) != 0)
|
if (pem_name != NULL) {
|
||||||
return NULL;
|
if (strcmp(pem_name, PEM_STRING_PKCS8) != 0)
|
||||||
|
return NULL;
|
||||||
|
*matchcount = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if ((p8 = d2i_X509_SIG(NULL, &blob, len)) == NULL)
|
if ((p8 = d2i_X509_SIG(NULL, &blob, len)) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
*matchcount = 1;
|
||||||
|
|
||||||
if ((mem = BUF_MEM_new()) == NULL) {
|
if ((mem = BUF_MEM_new()) == NULL) {
|
||||||
OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED,
|
OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED,
|
||||||
ERR_R_MALLOC_FAILURE);
|
ERR_R_MALLOC_FAILURE);
|
||||||
|
@ -344,6 +361,7 @@ static OSSL_STORE_INFO *try_decode_PrivateKey(const char *pem_name,
|
||||||
const char *pem_header,
|
const char *pem_header,
|
||||||
const unsigned char *blob,
|
const unsigned char *blob,
|
||||||
size_t len, void **pctx,
|
size_t len, void **pctx,
|
||||||
|
int *matchcount,
|
||||||
const UI_METHOD *ui_method,
|
const UI_METHOD *ui_method,
|
||||||
void *ui_data)
|
void *ui_data)
|
||||||
{
|
{
|
||||||
|
@ -356,6 +374,7 @@ static OSSL_STORE_INFO *try_decode_PrivateKey(const char *pem_name,
|
||||||
PKCS8_PRIV_KEY_INFO *p8inf =
|
PKCS8_PRIV_KEY_INFO *p8inf =
|
||||||
d2i_PKCS8_PRIV_KEY_INFO(NULL, &blob, len);
|
d2i_PKCS8_PRIV_KEY_INFO(NULL, &blob, len);
|
||||||
|
|
||||||
|
*matchcount = 1;
|
||||||
if (p8inf != NULL)
|
if (p8inf != NULL)
|
||||||
pkey = EVP_PKCS82PKEY(p8inf);
|
pkey = EVP_PKCS82PKEY(p8inf);
|
||||||
PKCS8_PRIV_KEY_INFO_free(p8inf);
|
PKCS8_PRIV_KEY_INFO_free(p8inf);
|
||||||
|
@ -364,19 +383,35 @@ static OSSL_STORE_INFO *try_decode_PrivateKey(const char *pem_name,
|
||||||
|
|
||||||
if ((slen = pem_check_suffix(pem_name, "PRIVATE KEY")) > 0
|
if ((slen = pem_check_suffix(pem_name, "PRIVATE KEY")) > 0
|
||||||
&& (ameth = EVP_PKEY_asn1_find_str(NULL, pem_name,
|
&& (ameth = EVP_PKEY_asn1_find_str(NULL, pem_name,
|
||||||
slen)) != NULL)
|
slen)) != NULL) {
|
||||||
|
*matchcount = 1;
|
||||||
pkey = d2i_PrivateKey(ameth->pkey_id, NULL, &blob, len);
|
pkey = d2i_PrivateKey(ameth->pkey_id, NULL, &blob, len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
|
for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
|
||||||
|
EVP_PKEY *tmp_pkey = NULL;
|
||||||
|
const unsigned char *tmp_blob = blob;
|
||||||
|
|
||||||
ameth = EVP_PKEY_asn1_get0(i);
|
ameth = EVP_PKEY_asn1_get0(i);
|
||||||
if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
|
if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
|
||||||
continue;
|
continue;
|
||||||
pkey = d2i_PrivateKey(ameth->pkey_id, NULL, &blob, len);
|
|
||||||
if (pkey != NULL)
|
tmp_pkey = d2i_PrivateKey(ameth->pkey_id, NULL, &tmp_blob, len);
|
||||||
break;
|
if (tmp_pkey != NULL) {
|
||||||
|
if (pkey != NULL)
|
||||||
|
EVP_PKEY_free(tmp_pkey);
|
||||||
|
else
|
||||||
|
pkey = tmp_pkey;
|
||||||
|
(*matchcount)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*matchcount > 1) {
|
||||||
|
EVP_PKEY_free(pkey);
|
||||||
|
pkey = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pkey == NULL)
|
if (pkey == NULL)
|
||||||
|
@ -398,18 +433,24 @@ static OSSL_STORE_INFO *try_decode_PUBKEY(const char *pem_name,
|
||||||
const char *pem_header,
|
const char *pem_header,
|
||||||
const unsigned char *blob,
|
const unsigned char *blob,
|
||||||
size_t len, void **pctx,
|
size_t len, void **pctx,
|
||||||
|
int *matchcount,
|
||||||
const UI_METHOD *ui_method,
|
const UI_METHOD *ui_method,
|
||||||
void *ui_data)
|
void *ui_data)
|
||||||
{
|
{
|
||||||
OSSL_STORE_INFO *store_info = NULL;
|
OSSL_STORE_INFO *store_info = NULL;
|
||||||
EVP_PKEY *pkey = NULL;
|
EVP_PKEY *pkey = NULL;
|
||||||
|
|
||||||
if (pem_name != NULL && strcmp(pem_name, PEM_STRING_PUBLIC) != 0)
|
if (pem_name != NULL) {
|
||||||
/* No match */
|
if (strcmp(pem_name, PEM_STRING_PUBLIC) != 0)
|
||||||
return NULL;
|
/* No match */
|
||||||
|
return NULL;
|
||||||
|
*matchcount = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if ((pkey = d2i_PUBKEY(NULL, &blob, len)) != NULL)
|
if ((pkey = d2i_PUBKEY(NULL, &blob, len)) != NULL) {
|
||||||
|
*matchcount = 1;
|
||||||
store_info = OSSL_STORE_INFO_new_PKEY(pkey);
|
store_info = OSSL_STORE_INFO_new_PKEY(pkey);
|
||||||
|
}
|
||||||
|
|
||||||
return store_info;
|
return store_info;
|
||||||
}
|
}
|
||||||
|
@ -422,24 +463,29 @@ static OSSL_STORE_INFO *try_decode_params(const char *pem_name,
|
||||||
const char *pem_header,
|
const char *pem_header,
|
||||||
const unsigned char *blob,
|
const unsigned char *blob,
|
||||||
size_t len, void **pctx,
|
size_t len, void **pctx,
|
||||||
|
int *matchcount,
|
||||||
const UI_METHOD *ui_method,
|
const UI_METHOD *ui_method,
|
||||||
void *ui_data)
|
void *ui_data)
|
||||||
{
|
{
|
||||||
OSSL_STORE_INFO *store_info = NULL;
|
OSSL_STORE_INFO *store_info = NULL;
|
||||||
EVP_PKEY *pkey = EVP_PKEY_new();
|
int slen = 0;
|
||||||
|
EVP_PKEY *pkey = NULL;
|
||||||
const EVP_PKEY_ASN1_METHOD *ameth = NULL;
|
const EVP_PKEY_ASN1_METHOD *ameth = NULL;
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
|
|
||||||
if (pkey == NULL) {
|
if (pem_name != NULL) {
|
||||||
|
if ((slen = pem_check_suffix(pem_name, "PARAMETERS")) == 0)
|
||||||
|
return NULL;
|
||||||
|
*matchcount = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pkey = EVP_PKEY_new()) == NULL) {
|
||||||
OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PARAMS, ERR_R_EVP_LIB);
|
OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PARAMS, ERR_R_EVP_LIB);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pem_name != NULL) {
|
if (slen > 0) {
|
||||||
int slen;
|
if (EVP_PKEY_set_type_str(pkey, pem_name, slen)
|
||||||
|
|
||||||
if ((slen = pem_check_suffix(pem_name, "PARAMETERS")) > 0
|
|
||||||
&& EVP_PKEY_set_type_str(pkey, pem_name, slen)
|
|
||||||
&& (ameth = EVP_PKEY_get0_asn1(pkey)) != NULL
|
&& (ameth = EVP_PKEY_get0_asn1(pkey)) != NULL
|
||||||
&& ameth->param_decode != NULL
|
&& ameth->param_decode != NULL
|
||||||
&& ameth->param_decode(pkey, &blob, len))
|
&& ameth->param_decode(pkey, &blob, len))
|
||||||
|
@ -448,13 +494,16 @@ static OSSL_STORE_INFO *try_decode_params(const char *pem_name,
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
|
for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
|
||||||
|
const unsigned char *tmp_blob = blob;
|
||||||
|
|
||||||
ameth = EVP_PKEY_asn1_get0(i);
|
ameth = EVP_PKEY_asn1_get0(i);
|
||||||
if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
|
if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
|
||||||
continue;
|
continue;
|
||||||
if (EVP_PKEY_set_type(pkey, ameth->pkey_id)
|
if (EVP_PKEY_set_type(pkey, ameth->pkey_id)
|
||||||
&& (ameth = EVP_PKEY_get0_asn1(pkey)) != NULL
|
&& (ameth = EVP_PKEY_get0_asn1(pkey)) != NULL
|
||||||
&& ameth->param_decode != NULL
|
&& ameth->param_decode != NULL
|
||||||
&& ameth->param_decode(pkey, &blob, len)) {
|
&& ameth->param_decode(pkey, &tmp_blob, len)) {
|
||||||
|
(*matchcount)++;
|
||||||
ok = 1;
|
ok = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -477,6 +526,7 @@ static OSSL_STORE_INFO *try_decode_X509Certificate(const char *pem_name,
|
||||||
const char *pem_header,
|
const char *pem_header,
|
||||||
const unsigned char *blob,
|
const unsigned char *blob,
|
||||||
size_t len, void **pctx,
|
size_t len, void **pctx,
|
||||||
|
int *matchcount,
|
||||||
const UI_METHOD *ui_method,
|
const UI_METHOD *ui_method,
|
||||||
void *ui_data)
|
void *ui_data)
|
||||||
{
|
{
|
||||||
|
@ -499,11 +549,14 @@ static OSSL_STORE_INFO *try_decode_X509Certificate(const char *pem_name,
|
||||||
&& strcmp(pem_name, PEM_STRING_X509) != 0)
|
&& strcmp(pem_name, PEM_STRING_X509) != 0)
|
||||||
/* No match */
|
/* No match */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
*matchcount = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cert = d2i_X509_AUX(NULL, &blob, len)) != NULL
|
if ((cert = d2i_X509_AUX(NULL, &blob, len)) != NULL
|
||||||
|| (ignore_trusted && (cert = d2i_X509(NULL, &blob, len)) != NULL))
|
|| (ignore_trusted && (cert = d2i_X509(NULL, &blob, len)) != NULL)) {
|
||||||
|
*matchcount = 1;
|
||||||
store_info = OSSL_STORE_INFO_new_CERT(cert);
|
store_info = OSSL_STORE_INFO_new_CERT(cert);
|
||||||
|
}
|
||||||
|
|
||||||
if (store_info == NULL)
|
if (store_info == NULL)
|
||||||
X509_free(cert);
|
X509_free(cert);
|
||||||
|
@ -519,19 +572,24 @@ static OSSL_STORE_INFO *try_decode_X509CRL(const char *pem_name,
|
||||||
const char *pem_header,
|
const char *pem_header,
|
||||||
const unsigned char *blob,
|
const unsigned char *blob,
|
||||||
size_t len, void **pctx,
|
size_t len, void **pctx,
|
||||||
|
int *matchcount,
|
||||||
const UI_METHOD *ui_method,
|
const UI_METHOD *ui_method,
|
||||||
void *ui_data)
|
void *ui_data)
|
||||||
{
|
{
|
||||||
OSSL_STORE_INFO *store_info = NULL;
|
OSSL_STORE_INFO *store_info = NULL;
|
||||||
X509_CRL *crl = NULL;
|
X509_CRL *crl = NULL;
|
||||||
|
|
||||||
if (pem_name != NULL
|
if (pem_name != NULL) {
|
||||||
&& strcmp(pem_name, PEM_STRING_X509_CRL) != 0)
|
if (strcmp(pem_name, PEM_STRING_X509_CRL) != 0)
|
||||||
/* No match */
|
/* No match */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
*matchcount = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if ((crl = d2i_X509_CRL(NULL, &blob, len)) != NULL)
|
if ((crl = d2i_X509_CRL(NULL, &blob, len)) != NULL) {
|
||||||
|
*matchcount = 1;
|
||||||
store_info = OSSL_STORE_INFO_new_CRL(crl);
|
store_info = OSSL_STORE_INFO_new_CRL(crl);
|
||||||
|
}
|
||||||
|
|
||||||
if (store_info == NULL)
|
if (store_info == NULL)
|
||||||
X509_CRL_free(crl);
|
X509_CRL_free(crl);
|
||||||
|
@ -738,16 +796,14 @@ static OSSL_STORE_INFO *file_load_try_decode(OSSL_STORE_LOADER_CTX *ctx,
|
||||||
*matchcount = 0;
|
*matchcount = 0;
|
||||||
for (i = 0; i < OSSL_NELEM(file_handlers); i++) {
|
for (i = 0; i < OSSL_NELEM(file_handlers); i++) {
|
||||||
const FILE_HANDLER *handler = file_handlers[i];
|
const FILE_HANDLER *handler = file_handlers[i];
|
||||||
|
int try_matchcount = 0;
|
||||||
void *tmp_handler_ctx = NULL;
|
void *tmp_handler_ctx = NULL;
|
||||||
OSSL_STORE_INFO *tmp_result =
|
OSSL_STORE_INFO *tmp_result =
|
||||||
handler->try_decode(pem_name, pem_header, data, len,
|
handler->try_decode(pem_name, pem_header, data, len,
|
||||||
&tmp_handler_ctx, ui_method, ui_data);
|
&tmp_handler_ctx, &try_matchcount,
|
||||||
|
ui_method, ui_data);
|
||||||
|
|
||||||
if (tmp_result == NULL) {
|
if (try_matchcount > 0) {
|
||||||
OSSL_STOREerr(OSSL_STORE_F_FILE_LOAD_TRY_DECODE,
|
|
||||||
OSSL_STORE_R_IS_NOT_A);
|
|
||||||
ERR_add_error_data(1, handler->name);
|
|
||||||
} else {
|
|
||||||
if (matching_handlers)
|
if (matching_handlers)
|
||||||
matching_handlers[*matchcount] = handler;
|
matching_handlers[*matchcount] = handler;
|
||||||
|
|
||||||
|
@ -755,37 +811,24 @@ static OSSL_STORE_INFO *file_load_try_decode(OSSL_STORE_LOADER_CTX *ctx,
|
||||||
handler->destroy_ctx(&handler_ctx);
|
handler->destroy_ctx(&handler_ctx);
|
||||||
handler_ctx = tmp_handler_ctx;
|
handler_ctx = tmp_handler_ctx;
|
||||||
|
|
||||||
if (++*matchcount == 1) {
|
if ((*matchcount += try_matchcount) > 1) {
|
||||||
result = tmp_result;
|
|
||||||
tmp_result = NULL;
|
|
||||||
} else {
|
|
||||||
/* more than one match => ambiguous, kill any result */
|
/* more than one match => ambiguous, kill any result */
|
||||||
OSSL_STORE_INFO_free(result);
|
OSSL_STORE_INFO_free(result);
|
||||||
OSSL_STORE_INFO_free(tmp_result);
|
OSSL_STORE_INFO_free(tmp_result);
|
||||||
if (handler->destroy_ctx != NULL)
|
if (handler->destroy_ctx != NULL)
|
||||||
handler->destroy_ctx(&handler_ctx);
|
handler->destroy_ctx(&handler_ctx);
|
||||||
handler_ctx = NULL;
|
handler_ctx = NULL;
|
||||||
|
tmp_result = NULL;
|
||||||
result = NULL;
|
result = NULL;
|
||||||
}
|
}
|
||||||
|
if (result == NULL)
|
||||||
|
result = tmp_result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*matchcount > 1)
|
if (*matchcount == 1 && matching_handlers[0]->repeatable) {
|
||||||
OSSL_STOREerr(OSSL_STORE_F_FILE_LOAD_TRY_DECODE,
|
ctx->_.file.last_handler = matching_handlers[0];
|
||||||
OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE);
|
ctx->_.file.last_handler_ctx = handler_ctx;
|
||||||
if (*matchcount == 0)
|
|
||||||
OSSL_STOREerr(OSSL_STORE_F_FILE_LOAD_TRY_DECODE,
|
|
||||||
OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE);
|
|
||||||
else if (matching_handlers[0]->repeatable) {
|
|
||||||
if (ctx == NULL) {
|
|
||||||
OSSL_STOREerr(OSSL_STORE_F_FILE_LOAD_TRY_DECODE,
|
|
||||||
OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE);
|
|
||||||
OSSL_STORE_INFO_free(result);
|
|
||||||
result = NULL;
|
|
||||||
} else {
|
|
||||||
ctx->_.file.last_handler = matching_handlers[0];
|
|
||||||
ctx->_.file.last_handler_ctx = handler_ctx;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OPENSSL_free(matching_handlers);
|
OPENSSL_free(matching_handlers);
|
||||||
|
@ -818,11 +861,13 @@ static OSSL_STORE_INFO *file_load_try_repeat(OSSL_STORE_LOADER_CTX *ctx,
|
||||||
void *ui_data)
|
void *ui_data)
|
||||||
{
|
{
|
||||||
OSSL_STORE_INFO *result = NULL;
|
OSSL_STORE_INFO *result = NULL;
|
||||||
|
int try_matchcount = 0;
|
||||||
|
|
||||||
if (ctx->_.file.last_handler != NULL) {
|
if (ctx->_.file.last_handler != NULL) {
|
||||||
result =
|
result =
|
||||||
ctx->_.file.last_handler->try_decode(NULL, NULL, NULL, 0,
|
ctx->_.file.last_handler->try_decode(NULL, NULL, NULL, 0,
|
||||||
&ctx->_.file.last_handler_ctx,
|
&ctx->_.file.last_handler_ctx,
|
||||||
|
&try_matchcount,
|
||||||
ui_method, ui_data);
|
ui_method, ui_data);
|
||||||
|
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
|
@ -922,6 +967,9 @@ static OSSL_STORE_INFO *file_load(OSSL_STORE_LOADER_CTX *ctx,
|
||||||
{
|
{
|
||||||
OSSL_STORE_INFO *result = NULL;
|
OSSL_STORE_INFO *result = NULL;
|
||||||
|
|
||||||
|
ctx->errcnt = 0;
|
||||||
|
ERR_clear_error();
|
||||||
|
|
||||||
if (ctx->type == is_dir) {
|
if (ctx->type == is_dir) {
|
||||||
do {
|
do {
|
||||||
char *newname = NULL;
|
char *newname = NULL;
|
||||||
|
@ -969,7 +1017,7 @@ static OSSL_STORE_INFO *file_load(OSSL_STORE_LOADER_CTX *ctx,
|
||||||
if (result != NULL)
|
if (result != NULL)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (file_error(ctx))
|
if (file_eof(ctx))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -982,22 +1030,50 @@ static OSSL_STORE_INFO *file_load(OSSL_STORE_LOADER_CTX *ctx,
|
||||||
if (ctx->type == is_pem) {
|
if (ctx->type == is_pem) {
|
||||||
if (!file_read_pem(ctx->_.file.file, &pem_name, &pem_header,
|
if (!file_read_pem(ctx->_.file.file, &pem_name, &pem_header,
|
||||||
&data, &len, ui_method, ui_data)) {
|
&data, &len, ui_method, ui_data)) {
|
||||||
if (!file_eof(ctx))
|
ctx->errcnt++;
|
||||||
ctx->errcnt++;
|
goto endloop;
|
||||||
goto err;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!file_read_asn1(ctx->_.file.file, &data, &len)) {
|
if (!file_read_asn1(ctx->_.file.file, &data, &len)) {
|
||||||
if (!file_eof(ctx))
|
ctx->errcnt++;
|
||||||
ctx->errcnt++;
|
goto endloop;
|
||||||
goto err;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result = file_load_try_decode(ctx, pem_name, pem_header, data, len,
|
result = file_load_try_decode(ctx, pem_name, pem_header, data, len,
|
||||||
ui_method, ui_data, &matchcount);
|
ui_method, ui_data, &matchcount);
|
||||||
|
|
||||||
err:
|
if (result != NULL)
|
||||||
|
goto endloop;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a PEM name matches more than one handler, the handlers are
|
||||||
|
* badly coded.
|
||||||
|
*/
|
||||||
|
if (!ossl_assert(pem_name == NULL || matchcount <= 1)) {
|
||||||
|
ctx->errcnt++;
|
||||||
|
goto endloop;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matchcount > 1) {
|
||||||
|
OSSL_STOREerr(OSSL_STORE_F_FILE_LOAD,
|
||||||
|
OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE);
|
||||||
|
} else if (matchcount == 1) {
|
||||||
|
/*
|
||||||
|
* If there are other errors on the stack, they already show
|
||||||
|
* what the problem is.
|
||||||
|
*/
|
||||||
|
if (ERR_peek_error() == 0) {
|
||||||
|
OSSL_STOREerr(OSSL_STORE_F_FILE_LOAD,
|
||||||
|
OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE);
|
||||||
|
if (pem_name != NULL)
|
||||||
|
ERR_add_error_data(3, "PEM type is '", pem_name, "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (matchcount > 0)
|
||||||
|
ctx->errcnt++;
|
||||||
|
|
||||||
|
endloop:
|
||||||
OPENSSL_free(pem_name);
|
OPENSSL_free(pem_name);
|
||||||
OPENSSL_free(pem_header);
|
OPENSSL_free(pem_header);
|
||||||
OPENSSL_free(data);
|
OPENSSL_free(data);
|
||||||
|
|
|
@ -69,6 +69,8 @@ of data.
|
||||||
|
|
||||||
OSSL_STORE_error() takes a B<OSSL_STORE_CTX> and checks if an error occured in
|
OSSL_STORE_error() takes a B<OSSL_STORE_CTX> and checks if an error occured in
|
||||||
the last OSSL_STORE_load() call.
|
the last OSSL_STORE_load() call.
|
||||||
|
Note that it may still be meaningful to try and load more objects, unless
|
||||||
|
OSSL_STORE_eof() shows that the end of data has been reached.
|
||||||
|
|
||||||
OSSL_STORE_close() takes a B<OSSL_STORE_CTX>, closes the channel that was opened
|
OSSL_STORE_close() takes a B<OSSL_STORE_CTX>, closes the channel that was opened
|
||||||
by OSSL_STORE_open() and frees all other information that was stored in the
|
by OSSL_STORE_open() and frees all other information that was stored in the
|
||||||
|
@ -105,8 +107,13 @@ should be taken or not.
|
||||||
|
|
||||||
=head1 RETURN VALUES
|
=head1 RETURN VALUES
|
||||||
|
|
||||||
OSSL_STORE_open() and OSSL_STORE_load() return a pointer to a B<OSSL_STORE_CTX>
|
OSSL_STORE_open() returns a pointer to a B<OSSL_STORE_CTX> on success, or
|
||||||
on success, or B<NULL> on failure.
|
B<NULL> on failure.
|
||||||
|
|
||||||
|
OSSL_STORE_load() returns a pointer to a B<OSSL_STORE_INFO> on success, or
|
||||||
|
B<NULL> on error or when end of data is reached.
|
||||||
|
Use OSSL_STORE_error() and OSSL_STORE_eof() to determine the meaning of a
|
||||||
|
returned B<NULL>.
|
||||||
|
|
||||||
OSSL_STORE_eof() returns 1 if the end of data has been reached, otherwise
|
OSSL_STORE_eof() returns 1 if the end of data has been reached, otherwise
|
||||||
0.
|
0.
|
||||||
|
|
Loading…
Reference in a new issue