diff options
Diffstat (limited to 'src/lib/libtls/tls_client.c')
-rw-r--r-- | src/lib/libtls/tls_client.c | 58 |
1 files changed, 37 insertions, 21 deletions
diff --git a/src/lib/libtls/tls_client.c b/src/lib/libtls/tls_client.c index 81e47da0e1..fb7f3a6f75 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.25 2015/09/09 19:49:07 jsing Exp $ */ | 1 | /* $OpenBSD: tls_client.c,v 1.26 2015/09/10 10:14:20 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> |
4 | * | 4 | * |
@@ -166,20 +166,23 @@ tls_connect_fds(struct tls *ctx, int fd_read, int fd_write, | |||
166 | const char *servername) | 166 | const char *servername) |
167 | { | 167 | { |
168 | union { struct in_addr ip4; struct in6_addr ip6; } addrbuf; | 168 | union { struct in_addr ip4; struct in6_addr ip6; } addrbuf; |
169 | X509 *cert = NULL; | 169 | int rv = -1; |
170 | int ret, err; | ||
171 | 170 | ||
172 | if ((ctx->flags & TLS_CLIENT) == 0) { | 171 | if ((ctx->flags & TLS_CLIENT) == 0) { |
173 | tls_set_errorx(ctx, "not a client context"); | 172 | tls_set_errorx(ctx, "not a client context"); |
174 | goto err; | 173 | goto err; |
175 | } | 174 | } |
176 | 175 | ||
177 | if (ctx->state & TLS_STATE_CONNECTING) | ||
178 | goto connecting; | ||
179 | |||
180 | if (fd_read < 0 || fd_write < 0) { | 176 | if (fd_read < 0 || fd_write < 0) { |
181 | tls_set_errorx(ctx, "invalid file descriptors"); | 177 | tls_set_errorx(ctx, "invalid file descriptors"); |
182 | return (-1); | 178 | goto err; |
179 | } | ||
180 | |||
181 | if (servername != NULL) { | ||
182 | if ((ctx->servername = strdup(servername)) == NULL) { | ||
183 | tls_set_errorx(ctx, "out of memory"); | ||
184 | goto err; | ||
185 | } | ||
183 | } | 186 | } |
184 | 187 | ||
185 | if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) { | 188 | if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) { |
@@ -230,16 +233,28 @@ tls_connect_fds(struct tls *ctx, int fd_read, int fd_write, | |||
230 | } | 233 | } |
231 | } | 234 | } |
232 | 235 | ||
233 | connecting: | 236 | rv = 0; |
234 | if ((ret = SSL_connect(ctx->ssl_conn)) != 1) { | 237 | |
235 | err = tls_ssl_error(ctx, ctx->ssl_conn, ret, "connect"); | 238 | err: |
236 | if (err == TLS_READ_AGAIN || err == TLS_WRITE_AGAIN) { | 239 | return (rv); |
237 | ctx->state |= TLS_STATE_CONNECTING; | 240 | } |
238 | return (err); | 241 | |
239 | } | 242 | int |
243 | tls_handshake_client(struct tls *ctx) | ||
244 | { | ||
245 | X509 *cert = NULL; | ||
246 | int ssl_ret; | ||
247 | int rv = -1; | ||
248 | |||
249 | if ((ctx->flags & TLS_CLIENT) == 0) { | ||
250 | tls_set_errorx(ctx, "not a client context"); | ||
251 | goto err; | ||
252 | } | ||
253 | |||
254 | if ((ssl_ret = SSL_connect(ctx->ssl_conn)) != 1) { | ||
255 | rv = tls_ssl_error(ctx, ctx->ssl_conn, ssl_ret, "handshake"); | ||
240 | goto err; | 256 | goto err; |
241 | } | 257 | } |
242 | ctx->state &= ~TLS_STATE_CONNECTING; | ||
243 | 258 | ||
244 | if (ctx->config->verify_name) { | 259 | if (ctx->config->verify_name) { |
245 | cert = SSL_get_peer_certificate(ctx->ssl_conn); | 260 | cert = SSL_get_peer_certificate(ctx->ssl_conn); |
@@ -247,19 +262,20 @@ tls_connect_fds(struct tls *ctx, int fd_read, int fd_write, | |||
247 | tls_set_errorx(ctx, "no server certificate"); | 262 | tls_set_errorx(ctx, "no server certificate"); |
248 | goto err; | 263 | goto err; |
249 | } | 264 | } |
250 | if ((ret = tls_check_servername(ctx, cert, servername)) != 0) { | 265 | if ((rv = tls_check_servername(ctx, cert, |
251 | if (ret != -2) | 266 | ctx->servername)) != 0) { |
267 | if (rv != -2) | ||
252 | tls_set_errorx(ctx, "name `%s' not present in" | 268 | tls_set_errorx(ctx, "name `%s' not present in" |
253 | " server certificate", servername); | 269 | " server certificate", ctx->servername); |
254 | goto err; | 270 | goto err; |
255 | } | 271 | } |
256 | X509_free(cert); | ||
257 | } | 272 | } |
258 | 273 | ||
259 | return (0); | 274 | ctx->state |= TLS_HANDSHAKE_COMPLETE; |
275 | rv = 0; | ||
260 | 276 | ||
261 | err: | 277 | err: |
262 | X509_free(cert); | 278 | X509_free(cert); |
263 | 279 | ||
264 | return (-1); | 280 | return (rv); |
265 | } | 281 | } |