-
Notifications
You must be signed in to change notification settings - Fork 868
add support for openssl1.1.1 session cache resumption #2088
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
… api to the the new_session callback. also set the context and explicit client session behavior when creating new ossl CTXs. Fixes 50reverse-proxy-session-resumption.t when linking against openssl-1.1.1
…k->ssl. Also adjust style.
…to asserting on sock. retain style
a451f24 to
f556558
Compare
kazuho
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for working on this PR. I've left my comments. Please let me know what you think.
lib/common/socket.c
Outdated
| { | ||
| sock->ssl->ossl = SSL_new(sock->ssl->ssl_ctx); | ||
| /* set app data to be used in h2o_socket_ssl_new_session_cb */ | ||
| assert(SSL_set_app_data(sock->ssl->ossl, sock)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you need to split assert and the call to SSL_set_app_data. Otherwise, the call to the OpenSSL function will be eliminated when NBEGUG is set.
lib/common/socket.c
Outdated
|
|
||
| SSL_SESSION *session = NULL; | ||
| if (!SSL_is_server(s) && sock->ssl->handshake.client.session_cache != NULL) { | ||
| session = SSL_get_session(sock->ssl->ossl); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if it is correct to use SSL_get_session here.
sock->ssl->handshake.client.session_cache is our client-side session cache, and the lifetime of the objects that are registered to the cache should be incremented before they are added to the cache. The h2o_socket_ssl_destroy_session_cache_entry function destroys the entries in the cache when they are to be evicted, by decrementing the reference count.
If there is a concern in using SSL_get1_session here, I think what we should be doing is call i2d_SSL_SESSION and store the serialized form of the resumption token in our session cache.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review! Based on your concern here, I think we can use get1_session here and return 0 with the same effect, as openssl is concerned.
Will push a commit soon which will address the other two as well. 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I'm not sure get1_session would make any difference. Looking at how the new session cb is called in openssl, and it looks like the ref count is incremented before the cb is invoked:
if (s->session_ctx->new_session_cb != NULL) {
SSL_SESSION_up_ref(s->session);
if (!s->session_ctx->new_session_cb(s, s->session))
SSL_SESSION_free(s->session);
}
https://github.com/openssl/openssl/blob/master/ssl/ssl_lib.c#L3569
It looks like the current behavior is sound? Please let me me know if this works for you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for checking.
Actually, now it seems to me that there is no need to call SSL_get_session at all.
I think we can simply use sess (the argument passed to this function)? And return 1 if we called h2o_cache_set. Does that make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah yeah 😄the get_session is really unnecessary there will push the change. thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes and your observation points to a bug in the function: within the ifdef is_resumable may still set the session variable, but not store in the cache, which will leak the sess. Will fix that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe 0a077f3 addresses the concerns. Could you please confirm that h2o_cache_set always add the new value even if the key already exists (in which case the function returns 1).
heh hope there is no path in which we destroy the cache without decrementing the SSL ref too, btw.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please confirm that
h2o_cache_setalways add the new value even if the key already exists (in which case the function returns 1).
Yes. The function guarantees that the new value to be always added.
| SSL_CTX_set_options(ctx, options); | ||
| SSL_CTX_set_session_id_context(ctx, (const uint8_t*)"h2o", sizeof("h2o") - 1); | ||
| SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE); | ||
| SSL_CTX_sess_set_new_cb(ctx, h2o_socket_ssl_new_session_cb); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes look good.
The only suggestion I have is to define a macro for the arguments of SSL_CTX_set_session_id_context, possibily declaring them in include/h2o/socket.h, and using them throughout this PR.
…nt if inserted in cache
|
Thank you for your efforts! Merged. |
hi, this PR enables ossl-1.1.1 session cache resumption support by moving from the get1 session api to the the new_session callback. Also sets the session cache context and the explicit client session behavior when creating new ossl CTXs (proxy).
this should make
t/50reverse-proxy-session-resumption.thappy when linking against openssl-1.1.0 and openssl1.1.1Note that Dockerfile has changed and the CI image will need an update to install openssl-1.1.1c in
/opt/openssl-1.1.1