X-Git-Url: http://sjero.net/git/?p=wget;a=blobdiff_plain;f=src%2Fopenssl.c;h=7c92ac0bcb1c80908abb5ea2fce91e49335227dc;hp=3924e41ea19e9cf7af2c7b0e6296206753d1e789;hb=320cfdcb658e8d6556ae9dfd902c2db1db866a6b;hpb=321b5dce853e856df342cc8bddea0dab1f7193b2 diff --git a/src/openssl.c b/src/openssl.c index 3924e41e..7c92ac0b 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -194,6 +194,7 @@ ssl_init (void) case secure_protocol_sslv3: meth = SSLv3_client_method (); break; + case secure_protocol_pfs: case secure_protocol_tlsv1: meth = TLSv1_client_method (); break; @@ -207,6 +208,12 @@ ssl_init (void) if (!ssl_ctx) goto error; + /* OpenSSL ciphers: https://www.openssl.org/docs/apps/ciphers.html + * Since we want a good protection, we also use HIGH (that excludes MD4 ciphers and some more) + */ + if (opt.secure_protocol == secure_protocol_pfs) + SSL_CTX_set_cipher_list (ssl_ctx, "HIGH:MEDIUM:!RC4:!SRP:!PSK:!RSA:!aNULL@STRENGTH"); + SSL_CTX_set_default_verify_paths (ssl_ctx); SSL_CTX_load_verify_locations (ssl_ctx, opt.ca_cert, opt.ca_directory); @@ -251,24 +258,50 @@ ssl_init (void) return false; } -struct openssl_transport_context { +struct openssl_transport_context +{ SSL *conn; /* SSL connection handle */ char *last_error; /* last error printed with openssl_errstr */ }; -static int -openssl_read (int fd, char *buf, int bufsize, void *arg) +struct openssl_read_args { - int ret; - struct openssl_transport_context *ctx = arg; + int fd; + struct openssl_transport_context *ctx; + char *buf; + int bufsize; + int retval; +}; + +static void openssl_read_callback(void *arg) +{ + struct openssl_read_args *args = (struct openssl_read_args *) arg; + struct openssl_transport_context *ctx = args->ctx; SSL *conn = ctx->conn; + char *buf = args->buf; + int bufsize = args->bufsize; + int ret; + do ret = SSL_read (conn, buf, bufsize); - while (ret == -1 - && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL + while (ret == -1 && SSL_get_error (conn, ret) == SSL_ERROR_SYSCALL && errno == EINTR); + args->retval = ret; +} - return ret; +static int +openssl_read (int fd, char *buf, int bufsize, void *arg) +{ + struct openssl_read_args args; + args.fd = fd; + args.buf = buf; + args.bufsize = bufsize; + args.ctx = (struct openssl_transport_context*) arg; + + if (run_with_timeout(opt.read_timeout, openssl_read_callback, &args)) { + return -1; + } + return args.retval; } static int @@ -386,6 +419,19 @@ static struct transport_implementation openssl_transport = { openssl_peek, openssl_errstr, openssl_close }; +struct scwt_context +{ + SSL *ssl; + int result; +}; + +static void +ssl_connect_with_timeout_callback(void *arg) +{ + struct scwt_context *ctx = (struct scwt_context *)arg; + ctx->result = SSL_connect(ctx->ssl); +} + /* Perform the SSL handshake on file descriptor FD, which is assumed to be connected to an SSL server. The SSL handle provided by OpenSSL is registered with the file descriptor FD using @@ -398,6 +444,7 @@ bool ssl_connect_wget (int fd, const char *hostname) { SSL *conn; + struct scwt_context scwt_ctx; struct openssl_transport_context *ctx; DEBUGP (("Initiating SSL handshake.\n")); @@ -425,7 +472,14 @@ ssl_connect_wget (int fd, const char *hostname) if (!SSL_set_fd (conn, FD_TO_SOCKET (fd))) goto error; SSL_set_connect_state (conn); - if (SSL_connect (conn) <= 0 || conn->state != SSL_ST_OK) + + scwt_ctx.ssl = conn; + if (run_with_timeout(opt.read_timeout, ssl_connect_with_timeout_callback, + &scwt_ctx)) { + DEBUGP (("SSL handshake timed out.\n")); + goto timeout; + } + if (scwt_ctx.result <= 0 || conn->state != SSL_ST_OK) goto error; ctx = xnew0 (struct openssl_transport_context); @@ -441,6 +495,7 @@ ssl_connect_wget (int fd, const char *hostname) error: DEBUGP (("SSL handshake failed.\n")); print_errors (); + timeout: if (conn) SSL_free (conn); return false;