diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2017-03-30 12:16:22 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2017-03-30 12:16:22 +0900 |
commit | 43f2861453d31a1422f59d358f309237bb8917ed (patch) | |
tree | 5f5e1fcd6d32339f47e33d8515f8bfc9552ed570 | |
parent | 3fd5ece39b59d938d0cc84b8e5148d19044d15cf (diff) | |
download | openssl-topic/X509_load_cert_crl_file-errorleakfix.tar.gz |
Have X509_load_cert_crl_file() clear error queuetopic/X509_load_cert_crl_file-errorleakfix
Handle the return value from X509_STORE_add_{cert,crl}() appropriately
so that no errors leak on the OpenSSL error queue on a successful
return.
A specific error "cert already in hash table" from these functions is
ignored as there's software expecting it to skip already-loaded
certificates.
-rw-r--r-- | crypto/x509/by_file.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/crypto/x509/by_file.c b/crypto/x509/by_file.c index 4376bed834..b253d420c9 100644 --- a/crypto/x509/by_file.c +++ b/crypto/x509/by_file.c @@ -191,7 +191,9 @@ int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) STACK_OF(X509_INFO) *inf; X509_INFO *itmp; BIO *in; - int i, count = 0; + int i, ret = 0, count = 0; + unsigned long error; + if (type != X509_FILETYPE_PEM) return X509_load_cert_file(ctx, file, type); in = BIO_new_file(file, "r"); @@ -208,14 +210,28 @@ int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) for (i = 0; i < sk_X509_INFO_num(inf); i++) { itmp = sk_X509_INFO_value(inf, i); if (itmp->x509) { - X509_STORE_add_cert(ctx->store_ctx, itmp->x509); + if (!X509_STORE_add_cert(ctx->store_ctx, itmp->x509)) { + error = ERR_peek_last_error(); + if (ERR_GET_LIB(error) != ERR_LIB_X509 || + ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE) + goto err; + ERR_clear_error(); + } count++; } if (itmp->crl) { - X509_STORE_add_crl(ctx->store_ctx, itmp->crl); + if (!X509_STORE_add_crl(ctx->store_ctx, itmp->crl)) { + error = ERR_peek_last_error(); + if (ERR_GET_LIB(error) != ERR_LIB_X509 || + ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE) + goto err; + ERR_clear_error(); + } count++; } } + ret = count; +err: sk_X509_INFO_pop_free(inf, X509_INFO_free); - return count; + return ret; } |