📄 tls_openssl.c
字号:
} ERR_clear_error(); free(passwd); SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL); if (!SSL_check_private_key(conn->ssl)) { wpa_printf(MSG_INFO, "SSL: Private key failed " "verification: %s", ERR_error_string(ERR_get_error(), NULL)); return -1; } return 0;}int tls_global_private_key(void *_ssl_ctx, const char *private_key, const char *private_key_passwd){ SSL_CTX *ssl_ctx = _ssl_ctx; char *passwd; if (private_key == NULL) return 0; if (private_key_passwd) { passwd = strdup(private_key_passwd); if (passwd == NULL) return -1; } else passwd = NULL; SSL_CTX_set_default_passwd_cb(ssl_ctx, tls_passwd_cb); SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, passwd); if (SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key, SSL_FILETYPE_ASN1) != 1 && SSL_CTX_use_PrivateKey_file(ssl_ctx, private_key, SSL_FILETYPE_PEM) != 1 && tls_read_pkcs12(ssl_ctx, NULL, private_key, passwd)) { wpa_printf(MSG_INFO, "SSL: Failed to load private key: %s", ERR_error_string(ERR_get_error(), NULL)); free(passwd); ERR_clear_error(); return -1; } free(passwd); ERR_clear_error(); SSL_CTX_set_default_passwd_cb(ssl_ctx, NULL); if (!SSL_CTX_check_private_key(ssl_ctx)) { wpa_printf(MSG_INFO, "SSL: Private key failed " "verification: %s", ERR_error_string(ERR_get_error(), NULL)); return -1; } return 0;}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 */}int tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn, struct tls_keys *keys){ SSL *ssl; if (conn == NULL || keys == NULL) return -1; ssl = conn->ssl; if (ssl == NULL || ssl->s3 == NULL || ssl->session == NULL) return -1; keys->master_key = ssl->session->master_key; keys->master_key_len = ssl->session->master_key_length; keys->client_random = ssl->s3->client_random; keys->client_random_len = SSL3_RANDOM_SIZE; keys->server_random = ssl->s3->server_random; keys->server_random_len = SSL3_RANDOM_SIZE; return 0;}u8 * tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn, const u8 *in_data, size_t in_len, size_t *out_len){ int res; u8 *out_data; if (in_data && BIO_write(conn->ssl_in, in_data, in_len) < 0) { wpa_printf(MSG_INFO, "TLS: Handshake failed - BIO_write: %s", ERR_error_string(ERR_get_error(), NULL)); return NULL; } res = SSL_connect(conn->ssl); if (res != 1) { int err = SSL_get_error(conn->ssl, res); if (err == SSL_ERROR_WANT_READ) wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want " "more data"); else if (err == SSL_ERROR_WANT_WRITE) wpa_printf(MSG_DEBUG, "SSL: SSL_connect - want to " "write"); else { wpa_printf(MSG_INFO, "SSL: SSL_connect: %s", ERR_error_string(ERR_get_error(), NULL)); conn->failed++; } } res = BIO_ctrl_pending(conn->ssl_out); wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res); out_data = malloc(res == 0 ? 1 : res); if (out_data == NULL) { wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for " "handshake output (%d bytes)", res); BIO_reset(conn->ssl_out); *out_len = 0; return NULL; } res = res == 0 ? 0 : BIO_read(conn->ssl_out, out_data, res); if (res < 0) { wpa_printf(MSG_INFO, "TLS: Handshake failed - BIO_read: %s", ERR_error_string(ERR_get_error(), NULL)); BIO_reset(conn->ssl_out); *out_len = 0; return NULL; } *out_len = res; return out_data;}u8 * tls_connection_server_handshake(void *ssl_ctx, struct tls_connection *conn, const u8 *in_data, size_t in_len, size_t *out_len){ int res; u8 *out_data; char buf[10]; if (in_data && BIO_write(conn->ssl_in, in_data, in_len) < 0) { wpa_printf(MSG_INFO, "TLS: Handshake failed - BIO_write: %s", ERR_error_string(ERR_get_error(), NULL)); return NULL; } res = SSL_read(conn->ssl, buf, sizeof(buf)); if (res >= 0) { wpa_printf(MSG_DEBUG, "SSL: Unexpected data from SSL_read " "(res=%d)", res); } res = BIO_ctrl_pending(conn->ssl_out); wpa_printf(MSG_DEBUG, "SSL: %d bytes pending from ssl_out", res); out_data = malloc(res == 0 ? 1 : res); if (out_data == NULL) { wpa_printf(MSG_DEBUG, "SSL: Failed to allocate memory for " "handshake output (%d bytes)", res); BIO_reset(conn->ssl_out); *out_len = 0; return NULL; } res = res == 0 ? 0 : BIO_read(conn->ssl_out, out_data, res); if (res < 0) { wpa_printf(MSG_INFO, "TLS: Handshake failed - BIO_read: %s", ERR_error_string(ERR_get_error(), NULL)); BIO_reset(conn->ssl_out); *out_len = 0; return NULL; } *out_len = res; return out_data;}int tls_connection_encrypt(void *ssl_ctx, struct tls_connection *conn, u8 *in_data, size_t in_len, u8 *out_data, size_t out_len){ int res; if (conn == NULL) return -1; BIO_reset(conn->ssl_in); BIO_reset(conn->ssl_out); res = SSL_write(conn->ssl, in_data, in_len); if (res < 0) { wpa_printf(MSG_INFO, "TLS: Encryption failed - SSL_write: %s", ERR_error_string(ERR_get_error(), NULL)); return res; } res = BIO_read(conn->ssl_out, out_data, out_len); if (res < 0) { wpa_printf(MSG_INFO, "TLS: Encryption failed - BIO_read: %s", ERR_error_string(ERR_get_error(), NULL)); return res; } return res;}int tls_connection_decrypt(void *ssl_ctx, struct tls_connection *conn, u8 *in_data, size_t in_len, u8 *out_data, size_t out_len){ int res; res = BIO_write(conn->ssl_in, in_data, in_len); if (res < 0) { wpa_printf(MSG_INFO, "TLS: Decryption failed - BIO_write: %s", ERR_error_string(ERR_get_error(), NULL)); return res; } BIO_reset(conn->ssl_out); res = SSL_read(conn->ssl, out_data, out_len); if (res < 0) { wpa_printf(MSG_INFO, "TLS: Decryption failed - SSL_read: %s", ERR_error_string(ERR_get_error(), NULL)); return res; } return res;}int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn){ return conn ? conn->ssl->hit : 0;}int tls_connection_set_master_key(void *ssl_ctx, struct tls_connection *conn, const u8 *key, size_t key_len){ SSL *ssl; if (conn == NULL || key == NULL || key_len > SSL_MAX_MASTER_KEY_LENGTH) return -1; ssl = conn->ssl; if (ssl == NULL || ssl->session == NULL) return -1; memcpy(ssl->session->master_key, key, key_len); ssl->session->master_key_length = key_len; return 0;}int tls_connection_set_anon_dh(void *ssl_ctx, struct tls_connection *conn){ if (conn == NULL || conn->ssl == NULL) return -1; if (SSL_set_cipher_list(conn->ssl, "ADH-AES128-SHA") != 1) { wpa_printf(MSG_INFO, "TLS: Anon DH configuration failed - %s", ERR_error_string(ERR_get_error(), NULL)); return -1; } return 0;}int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn, char *buf, size_t buflen){ const char *name; if (conn == NULL || conn->ssl == NULL) return -1; name = SSL_get_cipher(conn->ssl); if (name == NULL) return -1; snprintf(buf, buflen, "%s", name); return 0;}int tls_connection_enable_workaround(void *ssl_ctx, struct tls_connection *conn){ SSL_set_options(conn->ssl, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); return 0;}#ifdef EAP_FAST/* ClientHello TLS extensions require a patch to openssl, so this function is * commented out unless explicitly needed for EAP-FAST in order to be able to * build this file with unmodified openssl. */int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn, int ext_type, const u8 *data, size_t data_len){ struct tls_ext_hdr { u16 extensions_len; u16 extension_type; u16 extension_len; } *hdr; if (conn == NULL || conn->ssl == NULL) return -1; OPENSSL_free(conn->ssl->hello_extension); if (data == NULL) { conn->ssl->hello_extension = NULL; conn->ssl->hello_extension_len = 0; return 0; } if (data_len == 0) { conn->ssl->hello_extension = OPENSSL_malloc(1); conn->ssl->hello_extension_len = 0; return 0; } conn->ssl->hello_extension = OPENSSL_malloc(sizeof(*hdr) + data_len); if (conn->ssl->hello_extension == NULL) return -1; hdr = (struct tls_ext_hdr *) conn->ssl->hello_extension; hdr->extensions_len = host_to_be16(sizeof(*hdr) - 2 + data_len); hdr->extension_type = host_to_be16(ext_type); hdr->extension_len = host_to_be16(data_len); memcpy(hdr + 1, data, data_len); conn->ssl->hello_extension_len = sizeof(*hdr) + data_len; return 0;}#endif /* EAP_FAST */int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn){ if (conn == NULL) return -1; return conn->failed;}int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn){ if (conn == NULL) return -1; return conn->read_alerts;}int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn){ if (conn == NULL) return -1; return conn->write_alerts;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -