diff options
Diffstat (limited to 'src/lib/libtls/tls.c')
-rw-r--r-- | src/lib/libtls/tls.c | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/src/lib/libtls/tls.c b/src/lib/libtls/tls.c index 6b9834565c..fe5bc964e2 100644 --- a/src/lib/libtls/tls.c +++ b/src/lib/libtls/tls.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: tls.c,v 1.19 2015/09/09 19:49:07 jsing Exp $ */ | 1 | /* $OpenBSD: tls.c,v 1.20 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 | * |
@@ -315,6 +315,9 @@ tls_reset(struct tls *ctx) | |||
315 | ctx->socket = -1; | 315 | ctx->socket = -1; |
316 | ctx->state = 0; | 316 | ctx->state = 0; |
317 | 317 | ||
318 | free(ctx->servername); | ||
319 | ctx->servername = NULL; | ||
320 | |||
318 | free(ctx->errmsg); | 321 | free(ctx->errmsg); |
319 | ctx->errmsg = NULL; | 322 | ctx->errmsg = NULL; |
320 | ctx->errnum = 0; | 323 | ctx->errnum = 0; |
@@ -367,6 +370,20 @@ tls_ssl_error(struct tls *ctx, SSL *ssl_conn, int ssl_ret, const char *prefix) | |||
367 | } | 370 | } |
368 | 371 | ||
369 | int | 372 | int |
373 | tls_handshake(struct tls *ctx) | ||
374 | { | ||
375 | int rv = -1; | ||
376 | |||
377 | if ((ctx->flags & TLS_CLIENT) != 0) | ||
378 | rv = tls_handshake_client(ctx); | ||
379 | else if ((ctx->flags & TLS_SERVER_CONN) != 0) | ||
380 | rv = tls_handshake_server(ctx); | ||
381 | |||
382 | errno = 0; | ||
383 | return (rv); | ||
384 | } | ||
385 | |||
386 | int | ||
370 | tls_read(struct tls *ctx, void *buf, size_t buflen, size_t *outlen) | 387 | tls_read(struct tls *ctx, void *buf, size_t buflen, size_t *outlen) |
371 | { | 388 | { |
372 | int ssl_ret; | 389 | int ssl_ret; |
@@ -374,13 +391,17 @@ tls_read(struct tls *ctx, void *buf, size_t buflen, size_t *outlen) | |||
374 | 391 | ||
375 | *outlen = 0; | 392 | *outlen = 0; |
376 | 393 | ||
394 | if ((ctx->state & TLS_HANDSHAKE_COMPLETE) == 0) { | ||
395 | if ((rv = tls_handshake(ctx)) != 0) | ||
396 | goto out; | ||
397 | } | ||
398 | |||
377 | if (buflen > INT_MAX) { | 399 | if (buflen > INT_MAX) { |
378 | tls_set_errorx(ctx, "buflen too long"); | 400 | tls_set_errorx(ctx, "buflen too long"); |
379 | goto out; | 401 | goto out; |
380 | } | 402 | } |
381 | 403 | ||
382 | ssl_ret = SSL_read(ctx->ssl_conn, buf, buflen); | 404 | if ((ssl_ret = SSL_read(ctx->ssl_conn, buf, buflen)) > 0) { |
383 | if (ssl_ret > 0) { | ||
384 | *outlen = (size_t)ssl_ret; | 405 | *outlen = (size_t)ssl_ret; |
385 | rv = 0; | 406 | rv = 0; |
386 | goto out; | 407 | goto out; |
@@ -400,13 +421,17 @@ tls_write(struct tls *ctx, const void *buf, size_t buflen, size_t *outlen) | |||
400 | 421 | ||
401 | *outlen = 0; | 422 | *outlen = 0; |
402 | 423 | ||
424 | if ((ctx->state & TLS_HANDSHAKE_COMPLETE) == 0) { | ||
425 | if ((rv = tls_handshake(ctx)) != 0) | ||
426 | goto out; | ||
427 | } | ||
428 | |||
403 | if (buflen > INT_MAX) { | 429 | if (buflen > INT_MAX) { |
404 | tls_set_errorx(ctx, "buflen too long"); | 430 | tls_set_errorx(ctx, "buflen too long"); |
405 | goto out; | 431 | goto out; |
406 | } | 432 | } |
407 | 433 | ||
408 | ssl_ret = SSL_write(ctx->ssl_conn, buf, buflen); | 434 | if ((ssl_ret = SSL_write(ctx->ssl_conn, buf, buflen)) > 0) { |
409 | if (ssl_ret > 0) { | ||
410 | *outlen = (size_t)ssl_ret; | 435 | *outlen = (size_t)ssl_ret; |
411 | rv = 0; | 436 | rv = 0; |
412 | goto out; | 437 | goto out; |