From: Neil Horman Date: Thu, 29 Aug 2024 17:52:58 +0000 (-0400) Subject: Adding session resume support to hq-interop X-Git-Tag: openssl-3.5.0-alpha1~1125 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d978e5fb06387fe923b564875714ff9bebdcc6e9;p=thirdparty%2Fopenssl.git Adding session resume support to hq-interop Reviewed-by: Sasa Nedvedicky Reviewed-by: Viktor Dukhovni Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/25426) --- diff --git a/demos/guide/quic-hq-interop.c b/demos/guide/quic-hq-interop.c index 824eb96c9bb..d761ca5df29 100644 --- a/demos/guide/quic-hq-interop.c +++ b/demos/guide/quic-hq-interop.c @@ -21,6 +21,8 @@ #include #include +static BIO *session_bio = NULL; + /* Helper function to create a BIO connected to the server */ static BIO *create_socket_bio(const char *hostname, const char *port, int family, BIO_ADDR **peer_addr) @@ -260,6 +262,71 @@ int set_keylog_file(SSL_CTX *ctx, const char *keylog_file) return 0; } +static int session_cached = 0; +static int cache_new_session(struct ssl_st *ssl, SSL_SESSION *sess) +{ + + if (session_cached == 1) + return 0; + + /* Just write the new session to our bio */ + if (!PEM_write_bio_SSL_SESSION(session_bio, sess)) + return 0; + + fprintf(stderr, "Writing a new session to the cache\n"); + (void)BIO_flush(session_bio); + /* only cache one session */ + session_cached = 1; + return 1; +} + +static int setup_session_cache(SSL *ssl, SSL_CTX *ctx, const char *filename) +{ + + SSL_SESSION *sess = NULL; + int rc = 0; + int new_cache = 0; + + /* make sure caching is enabled */ + if (!SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH)) + return rc; + + /* Don't use stateless session tickets */ + if (!SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET)) + return rc; + + /* open our cache file */ + session_bio = BIO_new_file(filename, "r+"); + if (session_bio == NULL) { + /* file might need to be created */ + session_bio = BIO_new_file(filename, "w+"); + if (session_bio == NULL) + return rc; + new_cache = 1; + } + + if (new_cache == 0) { + /* read in our cached session */ + if (PEM_read_bio_SSL_SESSION(session_bio, &sess, NULL, NULL)) { + if (!SSL_CTX_add_session(ctx, sess)) + goto err; + /* set our session */ + if (!SSL_set_session(ssl, sess)) + goto err; + } + } else { + /* Set the callback to store new sessions */ + SSL_CTX_sess_set_new_cb(ctx, cache_new_session); + } + + rc = 1; + +err: + if (rc == 0) + BIO_free(session_bio); + return rc; +} + /* * Simple application to send a basic HTTP/1.0 request to a server and * print the response on the screen. Note that HTTP/1.0 over QUIC is @@ -373,6 +440,13 @@ int main(int argc, char *argv[]) goto end; } + if (getenv("SSL_SESSION_FILE") != NULL) { + if (!setup_session_cache(ssl, ctx, getenv("SSL_SESSION_FILE"))) { + fprintf(stderr, "Unable to setup session cache\n"); + goto end; + } + } + /* * Create the underlying transport socket/BIO and associate it with the * connection. @@ -542,5 +616,6 @@ int main(int argc, char *argv[]) BIO_ADDR_free(peer_addr); OPENSSL_free(reqnames); BIO_free(req_bio); + BIO_free(session_bio); return res; } diff --git a/test/quic-openssl-docker/run_endpoint.sh b/test/quic-openssl-docker/run_endpoint.sh index 56a39d672cd..1c4d7c1d5b0 100644 --- a/test/quic-openssl-docker/run_endpoint.sh +++ b/test/quic-openssl-docker/run_endpoint.sh @@ -36,14 +36,10 @@ if [ "$ROLE" == "client" ]; then case "$TESTCASE" in "http3") - echo -e "--verbose\n--parallel" >> $CURLRC - generate_outputs_http3 - dump_curlrc - SSL_CERT_FILE=/certs/ca.pem curl --config $CURLRC - if [ $? -ne 0 ] - then - exit 1 - fi + echo -e "--verbose\n--parallel" >> $CURLRC + generate_outputs_http3 + dump_curlrc + SSL_CERT_FILE=/certs/ca.pem curl --config $CURLRC || exit 1 exit 0 ;; "handshake"|"transfer"|"retry") @@ -53,18 +49,25 @@ if [ "$ROLE" == "client" ]; then OUTFILE=$(basename $req) if [ "$HOSTNAME" == "none" ] then - HOSTNAME=$(echo $req | sed -e"s/\(^https:\/\/\)\(.*\)\(:.*$\)/\2/") - HOSTPORT=$(echo $req | sed -e"s/\(^https:\/\/\)\(.*:\)\(.*\)\(\/.*$\)/\3/") + HOSTNAME=$(printf "%s\n" "$req" | sed -ne 's,^https://\([^/:]*\).*,\1,p') + HOSTPORT=$(printf "%s\n" "$req" | sed -ne 's,^https://[^:/]*:\([^/]*\).*,\1,p') fi echo -n "$OUTFILE " >> ./reqfile.txt done - SSLKEYLOGFILE=/logs/keys.log SSL_CERT_FILE=/certs/ca.pem SSL_CERT_DIR=/certs quic-hq-interop $HOSTNAME $HOSTPORT ./reqfile.txt - if [ $? -ne 0 ] - then - exit 1 - fi + SSLKEYLOGFILE=/logs/keys.log SSL_CERT_FILE=/certs/ca.pem SSL_CERT_DIR=/certs quic-hq-interop $HOSTNAME $HOSTPORT ./reqfile.txt || exit 1 exit 0 ;; + "resumption") + for req in $REQUESTS + do + OUTFILE=$(basename $req) + echo -n "$OUTFILE " > ./reqfile.txt + HOSTNAME=$(printf "%s\n" "$req" | sed -ne 's,^https://\([^/:]*\).*,\1,p') + HOSTPORT=$(printf "%s\n" "$req" | sed -ne 's,^https://[^:/]*:\([^/]*\).*,\1,p') + SSL_SESSION_FILE=./session.db SSLKEYLOGFILE=/logs/keys.log SSL_CERT_FILE=/certs/ca.pem SSL_CERT_DIR=/certs quic-hq-interop $HOSTNAME $HOSTPORT ./reqfile.txt || exit 1 + done + exit 0 + ;; "chacha20") OUTFILE=$(basename $REQUESTS) SSL_CERT_FILE=/certs/ca.pem curl --verbose --tlsv1.3 --tls13-ciphers TLS_CHACHA20_POLY1305_SHA256 --http3 -o /downloads/$OUTFILE $REQUESTS || exit 1