c-从来没有调用过Openssl API客户端Hello回调函数



我正在尝试使用opensslapi在个人项目上实现JA3方法(TLS指纹识别方法(。要做到这一点,我需要获得一些关于客户端Hello数据包的信息,我正在尝试使用opensslapi来实现这一点https://www.openssl.org/docs/man1.1.1/man3/。首先,我下载了一个代码,该代码在我的计算机和网站之间建立了TLS连接,并检索了证书信息。这个程序运行良好,tls连接使用tls 1.3,certificat信息正常。然后我尝试检索Client Hello数据包,开始实现JA3方法。经过几项研究,我发现了许多功能,可以让我获得我需要的信息:https://www.openssl.org/docs/man1.1.1/man3/SSL_client_hello_cb_fn.html。所有这些函数只能在客户端hello回调函数上调用。由于SSL_CTX_set_client_hello_cb函数,可以调用此函数。但在我的情况下,我的函数从未被调用。我开始绝望了,这就是为什么我需要你的帮助。我真的搜索了很多来调试它,但我没有找到一个可以允许回调函数或类似功能的标志。这是程序:

#include <sys/socket.h>
#include <resolv.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
int create_socket(char[], BIO *);
int callback(SSL *s, int *al, void *arg)
{
int * number = arg;
*number = (*number) + 1;
printf("nWe are in the callback function !n");
return SSL_CLIENT_HELLO_SUCCESS;
}
int main() {
char           dest_url[] = "https://www.hp.com";
BIO              *certbio = NULL;
BIO               *outbio = NULL;
X509                *cert = NULL;
X509_NAME       *certname = NULL;
const SSL_METHOD *method;
SSL_CTX *ctx;
struct ssl_st *ssl;
int server = 0;
OpenSSL_add_all_algorithms();
ERR_load_BIO_strings();
ERR_load_crypto_strings();
SSL_load_error_strings();
certbio = BIO_new(BIO_s_file());
outbio  = BIO_new_fp(stdout, BIO_NOCLOSE);
if(SSL_library_init() < 0)
BIO_printf(outbio, "Could not initialize the OpenSSL library !n");
method = TLS_client_method();
if ( (ctx = SSL_CTX_new(method)) == NULL)
BIO_printf(outbio, "Unable to create a new SSL context structure.n");
int hope = 12;
SSL_CTX_set_client_hello_cb(ctx, &callback, (void *)&hope);
ssl = SSL_new(ctx);

server = create_socket(dest_url, outbio);
if(server != 0)
BIO_printf(outbio, "Successfully made the TCP connection to: %s.n", dest_url);
SSL_set_fd(ssl, server);
if ( SSL_connect(ssl) != 1 )
BIO_printf(outbio, "Error: Could not build a SSL session to: %s.n", dest_url);
else
BIO_printf(outbio, "Successfully enabled SSL/TLS session to: %s.n", dest_url);

cert = SSL_get_peer_certificate(ssl);
if (cert == NULL)
BIO_printf(outbio, "Error: Could not get a certificate from: %s.n", dest_url);
else
BIO_printf(outbio, "Retrieved the server's certificate from: %s.n", dest_url);
certname = X509_NAME_new();
certname = X509_get_subject_name(cert);
BIO_printf(outbio, "Displaying the certificate subject data:n");
X509_NAME_print_ex(outbio, certname, 0, 0);
BIO_printf(outbio, "n");
SSL_free(ssl);
close(server);
X509_free(cert);
SSL_CTX_free(ctx);
BIO_printf(outbio, "Finished SSL/TLS connection with server: %s.n", dest_url);
printf("Hope value : %d n", hope);
return(0);
}
int create_socket(char url_str[], BIO *out) {
int sockfd;
char hostname[256] = "";
char    portnum[6] = "443";
char      proto[6] = "";
char      *tmp_ptr = NULL;
int           port;
struct hostent *host;
struct sockaddr_in dest_addr;
if(url_str[strlen(url_str)] == '/')
url_str[strlen(url_str)] = '';
strncpy(proto, url_str, (strchr(url_str, ':')-url_str));
strncpy(hostname, strstr(url_str, "://")+3, sizeof(hostname));
if(strchr(hostname, ':')) {
tmp_ptr = strchr(hostname, ':');
/* the last : starts the port number, if avail, i.e. 8443 */
strncpy(portnum, tmp_ptr+1,  sizeof(portnum));
*tmp_ptr = '';
}
port = atoi(portnum);
if ( (host = gethostbyname(hostname)) == NULL ) {
BIO_printf(out, "Error: Cannot resolve hostname %s.n",  hostname);
abort();
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
dest_addr.sin_family=AF_INET;
dest_addr.sin_port=htons(port);
dest_addr.sin_addr.s_addr = *(long*)(host->h_addr);
memset(&(dest_addr.sin_zero), '', 8);
tmp_ptr = inet_ntoa(dest_addr.sin_addr);
if ( connect(sockfd, (struct sockaddr *) &dest_addr,
sizeof(struct sockaddr)) == -1 ) {
BIO_printf(out, "Error: Cannot connect to host %s [%s] on port %d.n",
hostname, tmp_ptr, port);
}
return sockfd;
}

我在等你们的答复,谢谢。

出现问题的提示来自您链接到的文档中描述的第一行:

SSL_CTX_set_client_hello_cb((设置回调函数,该函数在服务器上ClientHello处理的早期阶段自动调用。

在处理收到的ClientHello时,服务器会调用。你已经写了一个客户,因此它永远不会被调用。

作为替代方案,我建议您查看SSL_CTX_set_msg_callback((:

https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_msg_callback.html

来自文档:

SSL_CTX_set_msg_callback((或SSL_set_msg_call back((可用于定义消息回调函数cb,用于观察接收或发送的所有SSL/TLS协议消息(如握手消息(以及处理过程中发生的其他事件。

最新更新