3

我正在编写一个客户端/服务器应用程序,我们将使用 SSL 通信。我很难弄清楚为什么外部缓存不起作用。我不想使用内部缓存,因为我想将会话存储在数据库中。虽然我已经注册了一个 callabckSSL_CTX_sess_set_get_cb并且SSL_CTX_sess_set_new_cb, SSL_CTX_sess_set_get_cb不会在服务器端被调用,并且在每次连接时都会创建一个新的 SSL_SESSION 。客户端似乎没有在握手时发送 session_id 但我不确定并且不知道如何测试它。在客户端,我使用 SSL_set_session 将会话附加到 SSL 连接,并且我在 Ubuntu 上使用 openSSL 0.9.8。

//for server side
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_INTERNAL | SSL_SESS_CACHE_NO_AUTO_CLEAR );

//for client side
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL | SSL_SESS_CACHE_NO_AUTO_CLEAR );

基本上客户端和服务器的流程都是这样的。为了清楚起见,我删除了错误处理。如果成功,应用程序将通过所有这些。

SSL_library_init();
SSL_load_error_strings();

ctx = SSL_CTX_new( SSLv23_method() );

SSL_CTX_set_info_callback(ctx, &apps_ssl_info_callback );
SSL_CTX_load_verify_locations( ctx,calist_file, calist_path );
SSL_CTX_set_default_verify_paths(ctx);
SSL_CTX_use_certificate_file(ctx,certfile,SSL_FILETYPE_PEM);
SSL_CTX_set_default_passwd_cb(ctx,password_cb);
SSL_CTX_set_default_passwd_cb_userdata(ctx, password );
SSL_CTX_use_PrivateKey_file(ctx,keyfile,SSL_FILETYPE_PEM);
SSL_CTX_check_private_key(ctx) );
SSL_CTX_set_default_passwd_cb(ctx,password_cb);
SSL_CTX_set_default_passwd_cb_userdata(ctx, password );
SSL_CTX_use_PrivateKey_file(ctx,keyfile,SSL_FILETYPE_PEM);
SSL_CTX_check_private_key(ctx);
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, verify_callback);
SSL_CTX_set_client_CA_list( ctx, SSL_load_client_CA_file( calist_file ) );
SSL_CTX_set_verify_depth(ctx,2);

/我处理获取 DH 参数并创建 RSA 临时密钥和随机性的例程/

RAND_load_file( random, SIZE );
load_dh_params(ctx,DHFILE); 
generate_eph_rsa_key(ctx);

SSL_CTX_set_session_id_context(ctx,(void*)&s_server_session_id_context,sizeof (s_server_session_id_context) );
mydata_index = SSL_get_ex_new_index(0, "mydata index", NULL, NULL, NULL);

SSL_CTX_set_session_cache_mode(ctx, (ctx, SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_INTERNAL |  SSL_SESS_CACHE_NO_AUTO_CLEAR );
SSL_CTX_sess_set_get_cb(ctx, get_session_cb);
SSL_CTX_sess_set_new_cb(ctx, new_session_cb );
SSL_CTX_sess_set_remove_cb(ctx, remove_session_cb );

我想要的是当客户端连接时应该调用 get_session_cb 并且在那里我将根据一些标准选择会话 id(将来会话 id 将具有某种意义(主机 id)不仅仅是随机数但这部分不是立即实施)。如果没有符合我标准的会话,那么应用程序将通过 new_session_cb 创建一个会话。服务器应该具有相同的行为,首先将尝试在其会话池中查找会话,如果查找不成功,则仅创建一个新会话。

我不确定我想要的客户是否真的可能。所以这就是我什至尝试获取一个会话并通过 SSL_set_session(ssl, session) 手动设置它的方式。

谢谢,

4

1 回答 1

4

如果没有在您的代码中看到所有其他 OpenSSL 调用,很难说,我们真的需要一个自包含的示例来展示该问题。话虽如此,这听起来像是使用会话票证扩展的RFC 5077服务器无状态会话恢复可能会出现问题。关闭它可以避免我在外部会话中遇到的一些问题:

SSL_CTX_set_options(sslctx, SSL_OP_NO_TICKET);

但是,如果您想走服务器无状态会话恢复之路,则完全可以预期在服务器端没有调用您的外部会话缓存——这正是没有服务器状态的会话恢复点。

于 2013-01-18T13:01:49.280 回答