Implement a human readable state function for the record layer
authorMatt Caswell <matt@openssl.org>
Fri, 22 Jul 2022 14:38:26 +0000 (15:38 +0100)
committerMatt Caswell <matt@openssl.org>
Thu, 18 Aug 2022 15:38:13 +0000 (16:38 +0100)
This allows querying of the record layer to get a human readable state
string out. This resolves two outstanding TODO comments and enables us
to remove the rstate variable from s->rlayer.

Reviewed-by: Hugo Landau <hlandau@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18132)

ssl/record/methods/dtls_meth.c
ssl/record/methods/ktls_meth.c
ssl/record/methods/recmethod_local.h
ssl/record/methods/tls_common.c
ssl/record/rec_layer_s3.c
ssl/record/record.h
ssl/record/recordmethod.h

index 2609724b9e21ff31c7d556a53a7525d469d92fa4..3366a3e558242925132a8ba854173fa3dce25091 100644 (file)
@@ -728,5 +728,6 @@ const OSSL_RECORD_METHOD ossl_dtls_record_method = {
     NULL,
     tls_set_first_handshake,
     tls_set_max_pipelines,
-    dtls_set_in_init
+    dtls_set_in_init,
+    tls_get_state
 };
index 036e46f8e946619f60f45f9f7d31af8edec32a73..241558600dbc53df7f42883e31be1ff56841a09f 100644 (file)
@@ -542,5 +542,6 @@ const OSSL_RECORD_METHOD ossl_ktls_record_method = {
     tls_set_plain_alerts,
     tls_set_first_handshake,
     tls_set_max_pipelines,
-    NULL
+    NULL,
+    tls_get_state
 };
index 5f3bc6bf6a846ccebe9b27c360d4e86b2b6ed3c9..2b0fe26827b62437c3e64b33026961a18ba95ca4 100644 (file)
@@ -284,4 +284,6 @@ int tls_set_protocol_version(OSSL_RECORD_LAYER *rl, int version);
 void tls_set_plain_alerts(OSSL_RECORD_LAYER *rl, int allow);
 void tls_set_first_handshake(OSSL_RECORD_LAYER *rl, int first);
 void tls_set_max_pipelines(OSSL_RECORD_LAYER *rl, size_t max_pipelines);
+void tls_get_state(OSSL_RECORD_LAYER *rl, const char **shortstr,
+                   const char **longstr);
 int rlayer_setup_read_buffer(OSSL_RECORD_LAYER *rl);
index 34497f4cc05d95c13b5a4aafa04732e9108bb631..8dace6c21a73a4b99bba062d45570b0c0fa1fec3 100644 (file)
@@ -1341,6 +1341,29 @@ void tls_set_max_pipelines(OSSL_RECORD_LAYER *rl, size_t max_pipelines)
         rl->read_ahead = 1;
 }
 
+void tls_get_state(OSSL_RECORD_LAYER *rl, const char **shortstr,
+                   const char **longstr)
+{
+    const char *shrt, *lng;
+    switch (rl->rstate) {
+    case SSL_ST_READ_HEADER:
+        shrt = "RH";
+        lng = "read header";
+        break;
+    case SSL_ST_READ_BODY:
+        shrt = "RB";
+        lng = "read body";
+        break;
+    default:
+        shrt = lng = "unknown";
+        break;
+    }
+    if (shortstr != NULL)
+        *shortstr = shrt;
+    if (longstr != NULL)
+        *longstr = lng;
+}
+
 const OSSL_RECORD_METHOD ossl_tls_record_method = {
     tls_new_record_layer,
     tls_free,
@@ -1361,5 +1384,6 @@ const OSSL_RECORD_METHOD ossl_tls_record_method = {
     tls_set_plain_alerts,
     tls_set_first_handshake,
     tls_set_max_pipelines,
-    NULL
+    NULL,
+    tls_get_state
 };
index 16247031bb19679856f588099554c2ab0e43803f..041e069a88958d28dbb979060cfb7342f7cf2ee1 100644 (file)
@@ -34,8 +34,6 @@ void RECORD_LAYER_init(RECORD_LAYER *rl, SSL_CONNECTION *s)
 
 void RECORD_LAYER_clear(RECORD_LAYER *rl)
 {
-    rl->rstate = SSL_ST_READ_HEADER;
-
     rl->wnum = 0;
     memset(rl->handshake_fragment, 0, sizeof(rl->handshake_fragment));
     rl->handshake_fragment_len = 0;
@@ -141,43 +139,34 @@ void SSL_set_default_read_buffer_len(SSL *s, size_t len)
 const char *SSL_rstate_string_long(const SSL *s)
 {
     const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
+    const char *lng;
 
     if (sc == NULL)
         return NULL;
 
-    /* TODO(RECLAYER): Fix me */
-    switch (sc->rlayer.rstate) {
-    case SSL_ST_READ_HEADER:
-        return "read header";
-    case SSL_ST_READ_BODY:
-        return "read body";
-    case SSL_ST_READ_DONE:
-        return "read done";
-    default:
+    if (sc->rlayer.rrlmethod == NULL || sc->rlayer.rrl == NULL)
         return "unknown";
-    }
+
+    sc->rlayer.rrlmethod->get_state(sc->rlayer.rrl, NULL, &lng);
+
+    return lng;
 }
 
 const char *SSL_rstate_string(const SSL *s)
 {
     const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s);
+    const char *shrt;
 
     if (sc == NULL)
         return NULL;
 
-    /* TODO(RECLAYER): Fix me */
-    switch (sc->rlayer.rstate) {
-    case SSL_ST_READ_HEADER:
-        return "RH";
-    case SSL_ST_READ_BODY:
-        return "RB";
-    case SSL_ST_READ_DONE:
-        return "RD";
-    default:
+    if (sc->rlayer.rrlmethod == NULL || sc->rlayer.rrl == NULL)
         return "unknown";
-    }
-}
 
+    sc->rlayer.rrlmethod->get_state(sc->rlayer.rrl, &shrt, NULL);
+
+    return shrt;
+}
 
 /*
  * Call this to write data in records of type 'type' It will return <= 0 if
index b75d8c86f37a08a6442af6c6f0a49b9494a73eed..8facdb27cee14f7ed86da73d1c6568ddc683a59f 100644 (file)
@@ -163,8 +163,6 @@ typedef struct record_layer_st {
      * non-blocking reads)
      */
     int read_ahead;
-    /* where we are when reading */
-    int rstate;
     /* How many pipelines can be used to write data */
     size_t numwpipes;
     /* write IO goes into here */
index 95732cae2ca55496d670b49b9b83aef00983c742..f2579b6cf4aa8cc9ec2b25b24086a28968118087 100644 (file)
@@ -314,6 +314,12 @@ struct ossl_record_method_st {
      * not. Default at creation of the record layer is "yes".
      */
     void (*set_in_init)(OSSL_RECORD_LAYER *rl, int in_init);
+
+    /*
+     * Get a short or long human readable description of the record layer state
+     */
+    void (*get_state)(OSSL_RECORD_LAYER *rl, const char **shortstr,
+                      const char **longstr);
 };