aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2017-03-30 12:16:22 +0900
committerKazuki Yamaguchi <k@rhe.jp>2017-03-30 12:16:22 +0900
commit43f2861453d31a1422f59d358f309237bb8917ed (patch)
tree5f5e1fcd6d32339f47e33d8515f8bfc9552ed570
parent3fd5ece39b59d938d0cc84b8e5148d19044d15cf (diff)
downloadopenssl-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.c24
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;
}