]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Adding session resume support to hq-interop
authorNeil Horman <nhorman@openssl.org>
Thu, 29 Aug 2024 17:52:58 +0000 (13:52 -0400)
committerNeil Horman <nhorman@openssl.org>
Fri, 13 Sep 2024 19:37:08 +0000 (15:37 -0400)
Reviewed-by: Sasa Nedvedicky <sashan@openssl.org>
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/25426)

demos/guide/quic-hq-interop.c
test/quic-openssl-docker/run_endpoint.sh

index 824eb96c9bb0341c9967bf22a55569b4e94ad810..d761ca5df29967d4dc6c2c7dd2853fe5711de26d 100644 (file)
@@ -21,6 +21,8 @@
 #include <openssl/ssl.h>
 #include <openssl/err.h>
 
+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;
 }
index 56a39d672cdb0a4362c2251e345d837710f2ec74..1c4d7c1d5b0849e23ea1a59d2cd113b44c3ec62b 100644 (file)
@@ -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