diff options
author | Daniel Stenberg <daniel@haxx.se> | 2013-06-10 23:42:48 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2013-06-10 23:42:48 +0200 |
commit | 7b97f03f09537fb488cbeda28767aa478618745c (patch) | |
tree | f4f95c13bd387d9f23949afaa9ab33ebc5f7b7c8 | |
parent | ce362e8eb9c6fe8600058c7b88f40a83b0af1794 (diff) | |
download | gnurl-7b97f03f09537fb488cbeda28767aa478618745c.tar.gz gnurl-7b97f03f09537fb488cbeda28767aa478618745c.tar.bz2 gnurl-7b97f03f09537fb488cbeda28767aa478618745c.zip |
cert_stuff: avoid double free in the PKCS12 code
In the pkcs12 code, we get a list of x509 records returned from
PKCS12_parse but when iterating over the list and passing each to
SSL_CTX_add_extra_chain_cert() we didn't also properly remove them from
the "stack", which made them get freed twice (both in sk_X509_pop_free()
and then later in SSL_CTX_free).
This isn't really documented anywhere...
Bug: http://curl.haxx.se/bug/view.cgi?id=1236
Reported-by: Nikaiw
-rw-r--r-- | lib/ssluse.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/lib/ssluse.c b/lib/ssluse.c index e9ae45ae0..1bb732785 100644 --- a/lib/ssluse.c +++ b/lib/ssluse.c @@ -464,11 +464,22 @@ int cert_stuff(struct connectdata *conn, /* Set Certificate Verification chain */ if(ca && sk_X509_num(ca)) { for(i = 0; i < sk_X509_num(ca); i++) { - if(!SSL_CTX_add_extra_chain_cert(ctx, sk_X509_value(ca, i))) { + /* + * Note that sk_X509_pop() is used below to make sure the cert is + * removed from the stack properly before getting passed to + * SSL_CTX_add_extra_chain_cert(). Previously we used + * sk_X509_value() instead, but then we'd clean it in the subsequent + * sk_X509_pop_free() call. + */ + X509 *x = sk_X509_pop(ca); + if(!SSL_CTX_add_extra_chain_cert(ctx, x)) { failf(data, "cannot add certificate to certificate chain"); goto fail; } - if(!SSL_CTX_add_client_CA(ctx, sk_X509_value(ca, i))) { + /* SSL_CTX_add_client_CA() seems to work with either sk_* function, + * presumably because it duplicates what we pass to it. + */ + if(!SSL_CTX_add_client_CA(ctx, x)) { failf(data, "cannot add certificate to client CA list"); goto fail; } |