summaryrefslogtreecommitdiff
path: root/src/lib/libtls/tls_client.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/libtls/tls_client.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/src/lib/libtls/tls_client.c b/src/lib/libtls/tls_client.c
index 79b1baf648..c6117c3292 100644
--- a/src/lib/libtls/tls_client.c
+++ b/src/lib/libtls/tls_client.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls_client.c,v 1.7 2015/01/02 16:38:07 bluhm Exp $ */ 1/* $OpenBSD: tls_client.c,v 1.8 2015/01/13 17:35:35 bluhm Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -135,7 +135,10 @@ tls_connect_fds(struct tls *ctx, int fd_read, int fd_write,
135{ 135{
136 union { struct in_addr ip4; struct in6_addr ip6; } addrbuf; 136 union { struct in_addr ip4; struct in6_addr ip6; } addrbuf;
137 X509 *cert = NULL; 137 X509 *cert = NULL;
138 int ret; 138 int ret, ssl_err;
139
140 if (ctx->flags & TLS_CONNECTING)
141 goto connecting;
139 142
140 if ((ctx->flags & TLS_CLIENT) == 0) { 143 if ((ctx->flags & TLS_CLIENT) == 0) {
141 tls_set_error(ctx, "not a client context"); 144 tls_set_error(ctx, "not a client context");
@@ -198,11 +201,22 @@ tls_connect_fds(struct tls *ctx, int fd_read, int fd_write,
198 } 201 }
199 } 202 }
200 203
204 connecting:
201 if ((ret = SSL_connect(ctx->ssl_conn)) != 1) { 205 if ((ret = SSL_connect(ctx->ssl_conn)) != 1) {
202 tls_set_error(ctx, "SSL connect failed: %i", 206 ssl_err = SSL_get_error(ctx->ssl_conn, ret);
203 SSL_get_error(ctx->ssl_conn, ret)); 207 switch (ssl_err) {
204 goto err; 208 case SSL_ERROR_WANT_READ:
209 ctx->flags |= TLS_CONNECTING;
210 return (TLS_READ_AGAIN);
211 case SSL_ERROR_WANT_WRITE:
212 ctx->flags |= TLS_CONNECTING;
213 return (TLS_WRITE_AGAIN);
214 default:
215 tls_set_error(ctx, "SSL connect failed: %i", ssl_err);
216 goto err;
217 }
205 } 218 }
219 ctx->flags &= ~TLS_CONNECTING;
206 220
207 if (ctx->config->verify_host) { 221 if (ctx->config->verify_host) {
208 cert = SSL_get_peer_certificate(ctx->ssl_conn); 222 cert = SSL_get_peer_certificate(ctx->ssl_conn);