patch: clear global openssl error state

This commit is contained in:
Alfred E. Heggestad 2014-05-17 14:47:15 +00:00
parent d7f720ad21
commit 4e4827870c
2 changed files with 26 additions and 9 deletions

View file

@ -137,6 +137,7 @@ int tls_alloc(struct tls **tlsp, enum tls_method method, const char *keyfile,
}
if (!tls->ctx) {
ERR_clear_error();
err = ENOMEM;
goto out;
}
@ -164,6 +165,7 @@ int tls_alloc(struct tls **tlsp, enum tls_method method, const char *keyfile,
if (r <= 0) {
DEBUG_WARNING("Can't read certificate file: %s (%d)\n",
keyfile, r);
ERR_clear_error();
err = EINVAL;
goto out;
}
@ -173,6 +175,7 @@ int tls_alloc(struct tls **tlsp, enum tls_method method, const char *keyfile,
if (r <= 0) {
DEBUG_WARNING("Can't read key file: %s (%d)\n",
keyfile, r);
ERR_clear_error();
err = EINVAL;
goto out;
}
@ -205,6 +208,7 @@ int tls_add_ca(struct tls *tls, const char *capath)
/* Load the CAs we trust */
if (!(SSL_CTX_load_verify_locations(tls->ctx, capath, 0))) {
DEBUG_WARNING("Can't read CA list: %s\n", capath);
ERR_clear_error();
return EINVAL;
}
@ -224,6 +228,7 @@ int tls_add_ca(struct tls *tls, const char *capath)
int tls_verify_cert(struct tls_conn *tc, char *cn, size_t cn_size)
{
X509 *peer;
int n;
if (!tc || !cn || !cn_size)
return EINVAL;
@ -239,11 +244,14 @@ int tls_verify_cert(struct tls_conn *tc, char *cn, size_t cn_size)
}
/* Get the common name */
X509_NAME_get_text_by_NID(X509_get_subject_name(peer),
NID_commonName, cn, (int)cn_size);
n = X509_NAME_get_text_by_NID(X509_get_subject_name(peer),
NID_commonName, cn, (int)cn_size);
if (n < 0)
cn[0] = '\0';
/* todo get valid start/end date */
X509_free(peer);
if (SSL_get_verify_result(tc->ssl) != X509_V_OK) {
DEBUG_WARNING("Certificate doesn't verify\n");
@ -268,18 +276,25 @@ static const EVP_MD *type2evp(const char *type)
int tls_get_remote_fingerprint(const struct tls_conn *tc, const char *type,
struct tls_fingerprint *fp)
{
const EVP_MD *evp;
X509 *x;
int n;
if (!tc || !fp)
return EINVAL;
evp = type2evp(type);
if (!evp)
return ENOTSUP;
x = SSL_get_peer_certificate(tc->ssl);
if (!x)
return EPROTO;
fp->len = sizeof(fp->md);
if (1 != X509_digest(x, type2evp(type), fp->md, &fp->len))
return ENOENT;
n = X509_digest(x, evp, fp->md, &fp->len);
return 0;
X509_free(x);
return (n == 1) ? 0 : ENOENT;
}

View file

@ -40,7 +40,10 @@ static void destructor(void *arg)
struct tls_conn *tc = arg;
if (tc->ssl) {
(void)SSL_shutdown(tc->ssl);
int r = SSL_shutdown(tc->ssl);
if (r <= 0)
ERR_clear_error();
SSL_free(tc->ssl);
}
mem_deref(tc->th);
@ -238,7 +241,7 @@ static bool recv_handler(int *err, struct mbuf *mb, bool *estab, void *arg)
}
n = SSL_read(tc->ssl, mbuf_buf(mb), (int)mbuf_get_space(mb));
if (n < 0) {
if (n <= 0) {
const int ssl_err = SSL_get_error(tc->ssl, n);
ERR_clear_error();
@ -255,8 +258,6 @@ static bool recv_handler(int *err, struct mbuf *mb, bool *estab, void *arg)
break;
}
else if (n == 0)
break;
mb->pos += n;
}
@ -320,6 +321,7 @@ int tls_start_tcp(struct tls_conn **ptc, struct tls *tls, struct tcp_conn *tcp,
tc->ssl = SSL_new(tls->ctx);
if (!tc->ssl) {
DEBUG_WARNING("alloc: SSL_new() failed (ctx=%p)\n", tls->ctx);
ERR_clear_error();
goto out;
}