static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value) { int rv = 0; DH *dh = NULL; BIO *in = NULL; if (cctx->ctx || cctx->ssl) { in = BIO_new(BIO_s_file()); if (in == NULL) goto end; if (BIO_read_filename(in, value) <= 0) goto end; dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); if (dh == NULL) goto end; } else return 1; if (cctx->ctx) rv = SSL_CTX_set_tmp_dh(cctx->ctx, dh); if (cctx->ssl) rv = SSL_set_tmp_dh(cctx->ssl, dh); end: DH_free(dh); BIO_free(in); return rv > 0; }
static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value) { int rv = 0; DH *dh = NULL; BIO *in = NULL; if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE)) return -2; if (cctx->ctx || cctx->ssl) { in = BIO_new(BIO_s_file_internal()); if (!in) goto end; if (BIO_read_filename(in, value) <= 0) goto end; dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); if (!dh) goto end; } else return 1; if (cctx->ctx) rv = SSL_CTX_set_tmp_dh(cctx->ctx, dh); if (cctx->ssl) rv = SSL_set_tmp_dh(cctx->ssl, dh); end: if (dh) DH_free(dh); if (in) BIO_free(in); return rv > 0; }
wi_boolean_t wi_socket_accept_tls(wi_socket_t *socket, wi_socket_tls_t *tls, wi_time_interval_t timeout) { wi_socket_state_t state; int err, result; wi_boolean_t blocking; socket->ssl = SSL_new(tls->ssl_ctx); if(!socket->ssl) { wi_error_set_openssl_error(); return false; } if(SSL_set_fd(socket->ssl, socket->sd) != 1) { wi_error_set_openssl_error(); return false; } if(!tls->private_key && tls->dh) { if(SSL_set_tmp_dh(socket->ssl, tls->dh) != 1) { wi_error_set_openssl_error(); return false; } } if(timeout > 0.0) { blocking = wi_socket_blocking(socket); if(blocking) wi_socket_set_blocking(socket, false); result = SSL_accept(socket->ssl); if(result != 1) { do { err = SSL_get_error(socket->ssl, result); if(err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) { wi_error_set_openssl_ssl_error_with_result(socket->ssl, result); return false; } state = wi_socket_wait_descriptor(socket->sd, 1.0, (err == SSL_ERROR_WANT_READ), (err == SSL_ERROR_WANT_WRITE)); if(state == WI_SOCKET_ERROR) break; else if(state == WI_SOCKET_READY) { result = SSL_accept(socket->ssl); if(result == 1) break; } timeout -= 1.0; } while(timeout >= 0.0); if(state == WI_SOCKET_ERROR) return false; if(timeout <= 0.0) { wi_error_set_errno(ETIMEDOUT); return false; } } if(blocking) wi_socket_set_blocking(socket, true); } else { result = SSL_accept(socket->ssl); if(result != 1) { wi_error_set_openssl_ssl_error_with_result(socket->ssl, result); return false; } } return true; }
int tls_connection_dh(void *ssl_ctx, struct tls_connection *conn, const char *dh_file) { #ifdef OPENSSL_NO_DH if (dh_file == NULL) return 0; wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but " "dh_file specified"); return -1; #else /* OPENSSL_NO_DH */ DH *dh; BIO *bio; if (dh_file == NULL) return 0; if (conn == NULL) return -1; bio = BIO_new_file(dh_file, "r"); if (bio == NULL) { wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s", dh_file, ERR_error_string(ERR_get_error(), NULL)); return -1; } dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); BIO_free(bio); #ifndef OPENSSL_NO_DSA while (dh == NULL) { DSA *dsa; wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -" " trying to parse as DSA params", dh_file, ERR_error_string(ERR_get_error(), NULL)); bio = BIO_new_file(dh_file, "r"); if (bio == NULL) break; dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL); BIO_free(bio); if (!dsa) { wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file " "'%s': %s", dh_file, ERR_error_string(ERR_get_error(), NULL)); break; } wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format"); dh = DSA_dup_DH(dsa); DSA_free(dsa); if (dh == NULL) { wpa_printf(MSG_INFO, "TLS: Failed to convert DSA " "params into DH params"); break; } break; } #endif /* !OPENSSL_NO_DSA */ if (dh == NULL) { wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file " "'%s'", dh_file); return -1; } if (SSL_set_tmp_dh(conn->ssl, dh) != 1) { wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': " "%s", dh_file, ERR_error_string(ERR_get_error(), NULL)); DH_free(dh); return -1; } DH_free(dh); return 0; #endif /* OPENSSL_NO_DH */ }
wi_socket_t * wi_socket_accept(wi_socket_t *accept_socket, wi_socket_context_t *context, wi_time_interval_t timeout, wi_address_t **address) { wi_socket_t *socket; #ifdef WI_SSL SSL *ssl = NULL; #endif struct sockaddr_storage ss; socklen_t length; int sd; length = sizeof(ss); sd = accept(accept_socket->sd, (struct sockaddr *) &ss, &length); *address = (length > 0) ? wi_autorelease(wi_address_init_with_sa(wi_address_alloc(), (struct sockaddr *) &ss)) : NULL; if(sd < 0) { wi_error_set_errno(errno); goto err; } #ifdef WI_SSL if(context && context->ssl_ctx) { ssl = SSL_new(context->ssl_ctx); if(!ssl) { wi_error_set_ssl_error(); goto err; } if(SSL_set_fd(ssl, sd) != 1) { wi_error_set_ssl_error(); goto err; } if(!context->certificate && context->dh) { if(SSL_set_tmp_dh(ssl, context->dh) != 1) { wi_error_set_ssl_error(); goto err; } } if(timeout > 0.0) { if(wi_socket_wait_descriptor(sd, timeout, true, false) <= 0) goto err; } if(SSL_accept(ssl) != 1) { wi_error_set_ssl_error(); goto err; } } #endif socket = wi_socket_init_with_descriptor(wi_socket_alloc(), sd); socket->close = true; socket->address = wi_retain(*address); socket->type = accept_socket->type; socket->direction = WI_SOCKET_READ; socket->interactive = accept_socket->interactive; #ifdef WI_SSL socket->ssl = ssl; #endif return wi_autorelease(socket); err: #ifdef WI_SSL if(ssl) SSL_free(ssl); #endif if(sd >= 0) close(sd); return NULL; }