Ignore empty ALPN elements in CLI args
authorViktor Dukhovni <openssl-users@dukhovni.org>
Fri, 11 Oct 2019 21:52:19 +0000 (17:52 -0400)
committerViktor Dukhovni <openssl-users@dukhovni.org>
Sat, 12 Oct 2019 00:19:18 +0000 (20:19 -0400)
Reviewed-by: Matt Caswell <matt@openssl.org>
apps/apps.c

index 7177c5d982661229437ee807394b58f39f4a0cb7..c06241abb97580294a766e818240f0d46bec0cd4 100644 (file)
@@ -1962,26 +1962,46 @@ unsigned char *next_protos_parse(size_t *outlen, const char *in)
     size_t len;
     unsigned char *out;
     size_t i, start = 0;
+    size_t skipped = 0;
 
     len = strlen(in);
-    if (len >= 65535)
+    if (len == 0 || len >= 65535)
         return NULL;
 
-    out = app_malloc(strlen(in) + 1, "NPN buffer");
+    out = app_malloc(len + 1, "NPN buffer");
     for (i = 0; i <= len; ++i) {
         if (i == len || in[i] == ',') {
+            /*
+             * Zero-length ALPN elements are invalid on the wire, we could be
+             * strict and reject the entire string, but just ignoring extra
+             * commas seems harmless and more friendly.
+             *
+             * Every comma we skip in this way puts the input buffer another
+             * byte ahead of the output buffer, so all stores into the output
+             * buffer need to be decremented by the number commas skipped.
+             */
+            if (i == start) {
+                ++start;
+                ++skipped;
+                continue;
+            }
             if (i - start > 255) {
                 OPENSSL_free(out);
                 return NULL;
             }
-            out[start] = (unsigned char)(i - start);
+            out[start-skipped] = (unsigned char)(i - start);
             start = i + 1;
         } else {
-            out[i + 1] = in[i];
+            out[i + 1 - skipped] = in[i];
         }
     }
 
-    *outlen = len + 1;
+    if (len <= skipped) {
+        OPENSSL_free(out);
+        return NULL;
+    }
+
+    *outlen = len + 1 - skipped;
     return out;
 }