[openssl] master update

dev at ddvo.net dev at ddvo.net
Wed Nov 17 15:47:38 UTC 2021


The branch master has been updated
       via  af16097febcd4fa31cd5fcd05ad09cf8b53659ea (commit)
       via  747adb6a0134e3b707fbc47d0f0c52d6ff9c4223 (commit)
       via  2ff286c26c29b69b02ca99656d26d2f8cfd54682 (commit)
      from  a6838c8d52087f2b0494bbab8486e10944aff7f7 (commit)


- Log -----------------------------------------------------------------
commit af16097febcd4fa31cd5fcd05ad09cf8b53659ea
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Thu Jun 24 11:13:51 2021 +0200

    Move more general parts of internal/cryptlib.h to new internal/common.h
    
    Reviewed-by: Paul Dale <pauli at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/15847)

commit 747adb6a0134e3b707fbc47d0f0c52d6ff9c4223
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Thu Jun 24 10:29:37 2021 +0200

    Add and use HAS_CASE_PREFIX(), CHECK_AND_SKIP_CASE_PREFIX(), and HAS_CASE_SUFFIX()
    
    Reviewed-by: Paul Dale <pauli at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/15847)

commit 2ff286c26c29b69b02ca99656d26d2f8cfd54682
Author: Dr. David von Oheimb <David.von.Oheimb at siemens.com>
Date:   Mon Jun 21 08:55:50 2021 +0200

    Add and use HAS_PREFIX() and CHECK_AND_SKIP_PREFIX() for checking if string has literal prefix
    
    Reviewed-by: Paul Dale <pauli at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/15847)

-----------------------------------------------------------------------

Summary of changes:
 apps/cmp.c                                       |   3 +-
 apps/fipsinstall.c                               |   5 +-
 apps/include/apps.h                              |   1 +
 apps/include/engine_loader.h                     |   2 +-
 apps/lib/apps.c                                  |  32 +++----
 apps/lib/engine_loader.c                         |   4 +-
 apps/lib/http_server.c                           |  17 ++--
 apps/openssl.c                                   |   6 +-
 apps/rehash.c                                    |   7 +-
 apps/s_client.c                                  |   4 +-
 apps/s_server.c                                  |  24 ++---
 apps/speed.c                                     |  47 ++++-----
 crypto/asn1/a_strnid.c                           |   6 +-
 crypto/asn1/asn1_gen.c                           |  10 +-
 crypto/asn1/asn_mime.c                           |   9 +-
 crypto/cmp/cmp_http.c                            |   1 -
 crypto/cmp/cmp_util.c                            |   3 +-
 crypto/conf/conf_def.c                           |   8 +-
 crypto/http/http_client.c                        |  13 ++-
 crypto/params_from_text.c                        |   7 +-
 crypto/pem/pem_lib.c                             |  41 ++++----
 crypto/punycode.c                                |   4 +-
 crypto/store/store_lib.c                         |   2 +-
 crypto/x509/v3_conf.c                            |   9 +-
 crypto/x509/v3_cpols.c                           |  12 +--
 crypto/x509/v3_crld.c                            |   2 +-
 crypto/x509/v3_ncons.c                           |   4 +-
 crypto/x509/v3_pci.c                             |  13 +--
 crypto/x509/v3_utl.c                             |   4 +-
 engines/e_loader_attic.c                         |  27 ++----
 engines/e_ossltest.c                             |   8 +-
 include/internal/common.h                        | 115 +++++++++++++++++++++++
 include/internal/cryptlib.h                      |  87 +----------------
 providers/implementations/storemgmt/file_store.c |  20 ++--
 ssl/record/ssl3_record.c                         |  10 +-
 ssl/ssl_ciph.c                                   |  16 ++--
 ssl/ssl_local.h                                  |   2 +-
 ssl/ssl_rsa.c                                    |  13 +--
 test/dtls_mtu_test.c                             |   2 +-
 test/evp_test.c                                  |  88 ++++++++---------
 test/helpers/handshake.c                         |   4 +-
 test/http_test.c                                 |  16 ++--
 test/ssl_old_test.c                              |   2 +-
 test/testutil.h                                  |   1 +
 test/testutil/stanza.c                           |   2 +-
 45 files changed, 342 insertions(+), 371 deletions(-)
 create mode 100644 include/internal/common.h

diff --git a/apps/cmp.c b/apps/cmp.c
index ae3488553a..589cce1266 100644
--- a/apps/cmp.c
+++ b/apps/cmp.c
@@ -1710,11 +1710,10 @@ static int handle_opt_geninfo(OSSL_CMP_CTX *ctx)
     valptr[0] = '\0';
     valptr++;
 
-    if (strncasecmp(valptr, "int:", 4) != 0) {
+    if (!CHECK_AND_SKIP_CASE_PREFIX(valptr, "int:")) {
         CMP_err("missing 'int:' in -geninfo option");
         return 0;
     }
-    valptr += 4;
 
     value = strtol(valptr, &endstr, 10);
     if (endstr == valptr || *endstr != '\0') {
diff --git a/apps/fipsinstall.c b/apps/fipsinstall.c
index d0efdf7643..363631112e 100644
--- a/apps/fipsinstall.c
+++ b/apps/fipsinstall.c
@@ -7,7 +7,6 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include <string.h>
 #include <openssl/evp.h>
 #include <openssl/err.h>
 #include <openssl/provider.h>
@@ -368,9 +367,9 @@ opthelp:
         case OPT_MACOPT:
             if (!sk_OPENSSL_STRING_push(opts, opt_arg()))
                 goto opthelp;
-            if (strncmp(opt_arg(), "hexkey:", 7) == 0)
+            if (HAS_PREFIX(opt_arg(), "hexkey:"))
                 gotkey = 1;
-            else if (strncmp(opt_arg(), "digest:", 7) == 0)
+            else if (HAS_PREFIX(opt_arg(), "digest:"))
                 gotdigest = 1;
             break;
         case OPT_VERIFY:
diff --git a/apps/include/apps.h b/apps/include/apps.h
index 6018a83ca4..f95238ae1b 100644
--- a/apps/include/apps.h
+++ b/apps/include/apps.h
@@ -11,6 +11,7 @@
 # define OSSL_APPS_H
 
 # include "e_os.h" /* struct timeval for DTLS */
+# include "internal/common.h" /* for HAS_PREFIX */
 # include "internal/nelem.h"
 # include "internal/sockets.h" /* for openssl_fdset() */
 # include <assert.h>
diff --git a/apps/include/engine_loader.h b/apps/include/engine_loader.h
index 11598639a5..97c176c6c8 100644
--- a/apps/include/engine_loader.h
+++ b/apps/include/engine_loader.h
@@ -13,7 +13,7 @@
 
 /* this is a private URI scheme */
 # define ENGINE_SCHEME          "org.openssl.engine"
-# define ENGINE_SCHEME_COLON    (ENGINE_SCHEME ":")
+# define ENGINE_SCHEME_COLON    ENGINE_SCHEME ":"
 
 int setup_engine_loader(void);
 void destroy_engine_loader(void);
diff --git a/apps/lib/apps.c b/apps/lib/apps.c
index 82eeaea249..01feedaf3f 100644
--- a/apps/lib/apps.c
+++ b/apps/lib/apps.c
@@ -260,21 +260,21 @@ static char *app_get_pass(const char *arg, int keepbio)
     int i;
 
     /* PASS_SOURCE_SIZE_MAX = max number of chars before ':' in below strings */
-    if (strncmp(arg, "pass:", 5) == 0)
-        return OPENSSL_strdup(arg + 5);
-    if (strncmp(arg, "env:", 4) == 0) {
-        tmp = getenv(arg + 4);
+    if (CHECK_AND_SKIP_PREFIX(arg, "pass:"))
+        return OPENSSL_strdup(arg);
+    if (CHECK_AND_SKIP_PREFIX(arg, "env:")) {
+        tmp = getenv(arg);
         if (tmp == NULL) {
-            BIO_printf(bio_err, "No environment variable %s\n", arg + 4);
+            BIO_printf(bio_err, "No environment variable %s\n", arg);
             return NULL;
         }
         return OPENSSL_strdup(tmp);
     }
     if (!keepbio || pwdbio == NULL) {
-        if (strncmp(arg, "file:", 5) == 0) {
-            pwdbio = BIO_new_file(arg + 5, "r");
+        if (CHECK_AND_SKIP_PREFIX(arg, "file:")) {
+            pwdbio = BIO_new_file(arg, "r");
             if (pwdbio == NULL) {
-                BIO_printf(bio_err, "Can't open file %s\n", arg + 5);
+                BIO_printf(bio_err, "Can't open file %s\n", arg);
                 return NULL;
             }
 #if !defined(_WIN32)
@@ -286,13 +286,13 @@ static char *app_get_pass(const char *arg, int keepbio)
              * on real Windows descriptors, such as those obtained
              * with CreateFile.
              */
-        } else if (strncmp(arg, "fd:", 3) == 0) {
+        } else if (CHECK_AND_SKIP_PREFIX(arg, "fd:")) {
             BIO *btmp;
-            i = atoi(arg + 3);
+            i = atoi(arg);
             if (i >= 0)
                 pwdbio = BIO_new_fd(i, BIO_NOCLOSE);
             if ((i < 0) || !pwdbio) {
-                BIO_printf(bio_err, "Can't access file descriptor %s\n", arg + 3);
+                BIO_printf(bio_err, "Can't access file descriptor %s\n", arg);
                 return NULL;
             }
             /*
@@ -450,10 +450,8 @@ CONF *app_load_config_modules(const char *configfile)
     return conf;
 }
 
-#define IS_HTTP(uri) ((uri) != NULL \
-        && strncmp(uri, OSSL_HTTP_PREFIX, strlen(OSSL_HTTP_PREFIX)) == 0)
-#define IS_HTTPS(uri) ((uri) != NULL \
-        && strncmp(uri, OSSL_HTTPS_PREFIX, strlen(OSSL_HTTPS_PREFIX)) == 0)
+#define IS_HTTP(uri) ((uri) != NULL  && HAS_PREFIX(uri, OSSL_HTTP_PREFIX))
+#define IS_HTTPS(uri) ((uri) != NULL && HAS_PREFIX(uri, OSSL_HTTPS_PREFIX))
 
 X509 *load_cert_pass(const char *uri, int format, int maybe_stdin,
                      const char *pass, const char *desc)
@@ -682,8 +680,8 @@ int load_cert_certs(const char *uri,
     int ret = 0;
     char *pass_string;
 
-    if (exclude_http && (strncasecmp(uri, "http://", 7) == 0
-                         || strncasecmp(uri, "https://", 8) == 0)) {
+    if (exclude_http && (HAS_CASE_PREFIX(uri, "http://")
+                         || HAS_CASE_PREFIX(uri, "https://"))) {
         BIO_printf(bio_err, "error: HTTP retrieval not allowed for %s\n", desc);
         return ret;
     }
diff --git a/apps/lib/engine_loader.c b/apps/lib/engine_loader.c
index 2b4480000c..7ea05943f3 100644
--- a/apps/lib/engine_loader.c
+++ b/apps/lib/engine_loader.c
@@ -71,10 +71,8 @@ static OSSL_STORE_LOADER_CTX *engine_open(const OSSL_STORE_LOADER *loader,
     char *keyid = NULL;
     OSSL_STORE_LOADER_CTX *ctx = NULL;
 
-    if (strncasecmp(p, ENGINE_SCHEME_COLON, sizeof(ENGINE_SCHEME_COLON) - 1)
-        != 0)
+    if (!CHECK_AND_SKIP_CASE_PREFIX(p, ENGINE_SCHEME_COLON))
         return NULL;
-    p += sizeof(ENGINE_SCHEME_COLON) - 1;
 
     /* Look for engine ID */
     q = strchr(p, ':');
diff --git a/apps/lib/http_server.c b/apps/lib/http_server.c
index 03faac7707..8f654660b4 100644
--- a/apps/lib/http_server.c
+++ b/apps/lib/http_server.c
@@ -17,7 +17,6 @@
 # define _POSIX_C_SOURCE 2
 #endif
 
-#include <string.h>
 #include <ctype.h>
 #include "http_server.h"
 #include "internal/sockets.h"
@@ -37,6 +36,7 @@ static int verbosity = LOG_INFO;
 #define HTTP_VERSION_PATT "1." /* allow 1.x */
 #define HTTP_PREFIX_VERSION HTTP_PREFIX""HTTP_VERSION_PATT
 #define HTTP_1_0 HTTP_PREFIX_VERSION"0" /* "HTTP/1.0" */
+#define HTTP_VERSION_STR " "HTTP_PREFIX_VERSION
 
 #ifdef HTTP_DAEMON
 
@@ -336,15 +336,12 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
         *end = '\0';
     log_message(prog, LOG_INFO, "Received request, 1st line: %s", reqbuf);
 
-    meth = reqbuf;
-    url = meth + 3;
-    if ((accept_get && strncmp(meth, "GET ", 4) == 0)
-            || (url++, strncmp(meth, "POST ", 5) == 0)) {
-        static const char http_version_str[] = " "HTTP_PREFIX_VERSION;
-        static const size_t http_version_str_len = sizeof(http_version_str) - 1;
+    url = meth = reqbuf;
+    if ((accept_get && CHECK_AND_SKIP_PREFIX(url, "GET "))
+            || CHECK_AND_SKIP_PREFIX(url, "POST ")) {
 
         /* Expecting (GET|POST) {sp} /URL {sp} HTTP/1.x */
-        *(url++) = '\0';
+        url[-1] = '\0';
         while (*url == ' ')
             url++;
         if (*url != '/') {
@@ -360,7 +357,7 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
         for (end = url; *end != '\0'; end++)
             if (*end == ' ')
                 break;
-        if (strncmp(end, http_version_str, http_version_str_len) != 0) {
+        if (!HAS_PREFIX(end, HTTP_VERSION_STR)) {
             log_message(prog, LOG_WARNING,
                         "Invalid %s -- bad HTTP/version string: %s",
                         meth, end + 1);
@@ -370,7 +367,7 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
         *end = '\0';
         /* above HTTP 1.0, connection persistence is the default */
         if (found_keep_alive != NULL)
-            *found_keep_alive = end[http_version_str_len] > '0';
+            *found_keep_alive = end[sizeof(HTTP_VERSION_STR) - 1] > '0';
 
         /*-
          * Skip "GET / HTTP..." requests often used by load-balancers.
diff --git a/apps/openssl.c b/apps/openssl.c
index e20661277e..d61acbbc54 100644
--- a/apps/openssl.c
+++ b/apps/openssl.c
@@ -8,8 +8,8 @@
  */
 
 #include <stdio.h>
-#include <string.h>
 #include <stdlib.h>
+#include "internal/common.h"
 #include <openssl/bio.h>
 #include <openssl/crypto.h>
 #include <openssl/trace.h>
@@ -417,12 +417,12 @@ static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[])
             warn_deprecated(fp);
         return fp->func(argc, argv);
     }
-    if ((strncmp(argv[0], "no-", 3)) == 0) {
+    f.name = argv[0];
+    if (CHECK_AND_SKIP_PREFIX(f.name, "no-")) {
         /*
          * User is asking if foo is unsupported, by trying to "run" the
          * no-foo command.  Strange.
          */
-        f.name = argv[0] + 3;
         if (lh_FUNCTION_retrieve(prog, &f) == NULL) {
             BIO_printf(bio_out, "%s\n", argv[0]);
             return 0;
diff --git a/apps/rehash.c b/apps/rehash.c
index 7fe01de11c..e0cdc9bc62 100644
--- a/apps/rehash.c
+++ b/apps/rehash.c
@@ -206,11 +206,10 @@ static int handle_symlink(const char *filename, const char *fullpath)
     }
     if (filename[i++] != '.')
         return -1;
-    for (type = OSSL_NELEM(suffixes) - 1; type > 0; type--) {
-        const char *suffix = suffixes[type];
-        if (strncasecmp(suffix, &filename[i], strlen(suffix)) == 0)
+    for (type = OSSL_NELEM(suffixes) - 1; type > 0; type--)
+        if (strncasecmp(&filename[i],
+                        suffixes[type], strlen(suffixes[type])) == 0)
             break;
-    }
     i += strlen(suffixes[type]);
 
     id = strtoul(&filename[i], &endptr, 10);
diff --git a/apps/s_client.c b/apps/s_client.c
index 46cecb9a82..d40f7c948f 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -2530,7 +2530,7 @@ int s_client_main(int argc, char **argv)
                  */
                 if (mbuf_len > 1 && mbuf[0] == '"') {
                     make_uppercase(mbuf);
-                    if (strncmp(mbuf, "\"STARTTLS\"", 10) == 0)
+                    if (HAS_PREFIX(mbuf, "\"STARTTLS\""))
                         foundit = 1;
                 }
             } while (mbuf_len > 1 && mbuf[0] == '"');
@@ -2558,7 +2558,7 @@ int s_client_main(int argc, char **argv)
              */
             strncpy(sbuf, mbuf, 2);
             make_uppercase(sbuf);
-            if (strncmp(sbuf, "OK", 2) != 0) {
+            if (!HAS_PREFIX(sbuf, "OK")) {
                 BIO_printf(bio_err, "STARTTLS not supported: %s", mbuf);
                 goto shut;
             }
diff --git a/apps/s_server.c b/apps/s_server.c
index 27c7db80a7..13d59faf14 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -2985,7 +2985,7 @@ static void print_connection_info(SSL *con)
 
 static int www_body(int s, int stype, int prot, unsigned char *context)
 {
-    char *buf = NULL;
+    char *buf = NULL, *p;
     int ret = 1;
     int i, j, k, dot;
     SSL *con;
@@ -3001,7 +3001,7 @@ static int www_body(int s, int stype, int prot, unsigned char *context)
     /* Set width for a select call if needed */
     width = s + 1;
 
-    buf = app_malloc(bufsize, "server www buffer");
+    p = buf = app_malloc(bufsize, "server www buffer");
     io = BIO_new(BIO_f_buffer());
     ssl_bio = BIO_new(BIO_f_ssl());
     if ((io == NULL) || (ssl_bio == NULL))
@@ -3093,15 +3093,14 @@ static int www_body(int s, int stype, int prot, unsigned char *context)
         }
 
         /* else we have data */
-        if (((www == 1) && (strncmp("GET ", buf, 4) == 0)) ||
-            ((www == 2) && (strncmp("GET /stats ", buf, 11) == 0))) {
-            char *p;
+        if ((www == 1 && HAS_PREFIX(buf, "GET "))
+             || (www == 2 && HAS_PREFIX(buf, "GET /stats "))) {
             X509 *peer = NULL;
             STACK_OF(SSL_CIPHER) *sk;
             static const char *space = "                          ";
 
-            if (www == 1 && strncmp("GET /reneg", buf, 10) == 0) {
-                if (strncmp("GET /renegcert", buf, 14) == 0)
+            if (www == 1 && HAS_PREFIX(buf, "GET /reneg")) {
+                if (HAS_PREFIX(buf, "GET /renegcert"))
                     SSL_set_verify(con,
                                    SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE,
                                    NULL);
@@ -3142,6 +3141,7 @@ static int www_body(int s, int stype, int prot, unsigned char *context)
             BIO_puts(io, "\n");
             for (i = 0; i < local_argc; i++) {
                 const char *myp;
+
                 for (myp = local_argv[i]; *myp; myp++)
                     switch (*myp) {
                     case '<':
@@ -3221,16 +3221,12 @@ static int www_body(int s, int stype, int prot, unsigned char *context)
             }
             BIO_puts(io, "</pre></BODY></HTML>\r\n\r\n");
             break;
-        } else if ((www == 2 || www == 3)
-                   && (strncmp("GET /", buf, 5) == 0)) {
+        } else if ((www == 2 || www == 3) && HAS_PREFIX(p, "GET /")) {
             BIO *file;
-            char *p, *e;
+            char *e;
             static const char *text =
                 "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
 
-            /* skip the '/' */
-            p = &(buf[5]);
-
             dot = 1;
             for (e = p; *e != '\0'; e++) {
                 if (e[0] == ' ')
@@ -3523,7 +3519,7 @@ static int rev_body(int s, int stype, int prot, unsigned char *context)
                 p--;
                 i--;
             }
-            if (!s_ign_eof && (i == 5) && (strncmp(buf, "CLOSE", 5) == 0)) {
+            if (!s_ign_eof && i == 5 && HAS_PREFIX(buf, "CLOSE")) {
                 ret = 1;
                 BIO_printf(bio_err, "CONNECTION CLOSED\n");
                 goto end;
diff --git a/apps/speed.c b/apps/speed.c
index ada559228d..0ee7347f5b 100644
--- a/apps/speed.c
+++ b/apps/speed.c
@@ -1638,8 +1638,8 @@ int speed_main(int argc, char **argv)
         if (strcmp(algo, "openssl") == 0) /* just for compatibility */
             continue;
 #endif
-        if (strncmp(algo, "rsa", 3) == 0) {
-            if (algo[3] == '\0') {
+        if (HAS_PREFIX(algo, "rsa")) {
+            if (algo[sizeof("rsa") - 1] == '\0') {
                 memset(rsa_doit, 1, sizeof(rsa_doit));
                 continue;
             }
@@ -1649,8 +1649,8 @@ int speed_main(int argc, char **argv)
             }
         }
 #ifndef OPENSSL_NO_DH
-        if (strncmp(algo, "ffdh", 4) == 0) {
-            if (algo[4] == '\0') {
+        if (HAS_PREFIX(algo, "ffdh")) {
+            if (algo[sizeof("ffdh") - 1] == '\0') {
                 memset(ffdh_doit, 1, sizeof(ffdh_doit));
                 continue;
             }
@@ -1660,8 +1660,8 @@ int speed_main(int argc, char **argv)
             }
         }
 #endif
-        if (strncmp(algo, "dsa", 3) == 0) {
-            if (algo[3] == '\0') {
+        if (HAS_PREFIX(algo, "dsa")) {
+            if (algo[sizeof("dsa") - 1] == '\0') {
                 memset(dsa_doit, 1, sizeof(dsa_doit));
                 continue;
             }
@@ -1678,8 +1678,8 @@ int speed_main(int argc, char **argv)
             doit[D_CBC_128_CML] = doit[D_CBC_192_CML] = doit[D_CBC_256_CML] = 1;
             continue;
         }
-        if (strncmp(algo, "ecdsa", 5) == 0) {
-            if (algo[5] == '\0') {
+        if (HAS_PREFIX(algo, "ecdsa")) {
+            if (algo[sizeof("ecdsa") - 1] == '\0') {
                 memset(ecdsa_doit, 1, sizeof(ecdsa_doit));
                 continue;
             }
@@ -1688,8 +1688,8 @@ int speed_main(int argc, char **argv)
                 continue;
             }
         }
-        if (strncmp(algo, "ecdh", 4) == 0) {
-            if (algo[4] == '\0') {
+        if (HAS_PREFIX(algo, "ecdh")) {
+            if (algo[sizeof("ecdh") - 1] == '\0') {
                 memset(ecdh_doit, 1, sizeof(ecdh_doit));
                 continue;
             }
@@ -3458,20 +3458,19 @@ static int do_multi(int multi, int size_num)
                 continue;
             }
             printf("Got: %s from %d\n", buf, n);
-            if (strncmp(buf, "+F:", 3) == 0) {
+            p = buf;
+            if (CHECK_AND_SKIP_PREFIX(p, "+F:")) {
                 int alg;
                 int j;
 
-                p = buf + 3;
                 alg = atoi(sstrsep(&p, sep));
                 sstrsep(&p, sep);
                 for (j = 0; j < size_num; ++j)
                     results[alg][j] += atof(sstrsep(&p, sep));
-            } else if (strncmp(buf, "+F2:", 4) == 0) {
+            } else if (CHECK_AND_SKIP_PREFIX(p, "+F2:")) {
                 int k;
                 double d;
 
-                p = buf + 4;
                 k = atoi(sstrsep(&p, sep));
                 sstrsep(&p, sep);
 
@@ -3480,11 +3479,10 @@ static int do_multi(int multi, int size_num)
 
                 d = atof(sstrsep(&p, sep));
                 rsa_results[k][1] += d;
-            } else if (strncmp(buf, "+F3:", 4) == 0) {
+            } else if (CHECK_AND_SKIP_PREFIX(p, "+F3:")) {
                 int k;
                 double d;
 
-                p = buf + 4;
                 k = atoi(sstrsep(&p, sep));
                 sstrsep(&p, sep);
 
@@ -3493,11 +3491,10 @@ static int do_multi(int multi, int size_num)
 
                 d = atof(sstrsep(&p, sep));
                 dsa_results[k][1] += d;
-            } else if (strncmp(buf, "+F4:", 4) == 0) {
+            } else if (CHECK_AND_SKIP_PREFIX(p, "+F4:")) {
                 int k;
                 double d;
 
-                p = buf + 4;
                 k = atoi(sstrsep(&p, sep));
                 sstrsep(&p, sep);
 
@@ -3506,21 +3503,19 @@ static int do_multi(int multi, int size_num)
 
                 d = atof(sstrsep(&p, sep));
                 ecdsa_results[k][1] += d;
-            } else if (strncmp(buf, "+F5:", 4) == 0) {
+            } else if (CHECK_AND_SKIP_PREFIX(p, "+F5:")) {
                 int k;
                 double d;
 
-                p = buf + 4;
                 k = atoi(sstrsep(&p, sep));
                 sstrsep(&p, sep);
 
                 d = atof(sstrsep(&p, sep));
                 ecdh_results[k][0] += d;
-            } else if (strncmp(buf, "+F6:", 4) == 0) {
+            } else if (CHECK_AND_SKIP_PREFIX(p, "+F6:")) {
                 int k;
                 double d;
 
-                p = buf + 4;
                 k = atoi(sstrsep(&p, sep));
                 sstrsep(&p, sep);
                 sstrsep(&p, sep);
@@ -3531,11 +3526,10 @@ static int do_multi(int multi, int size_num)
                 d = atof(sstrsep(&p, sep));
                 eddsa_results[k][1] += d;
 # ifndef OPENSSL_NO_SM2
-            } else if (strncmp(buf, "+F7:", 4) == 0) {
+            } else if (CHECK_AND_SKIP_PREFIX(p, "+F7:")) {
                 int k;
                 double d;
 
-                p = buf + 4;
                 k = atoi(sstrsep(&p, sep));
                 sstrsep(&p, sep);
                 sstrsep(&p, sep);
@@ -3547,18 +3541,17 @@ static int do_multi(int multi, int size_num)
                 sm2_results[k][1] += d;
 # endif /* OPENSSL_NO_SM2 */
 # ifndef OPENSSL_NO_DH
-            } else if (strncmp(buf, "+F8:", 4) == 0) {
+            } else if (CHECK_AND_SKIP_PREFIX(p, "+F8:")) {
                 int k;
                 double d;
 
-                p = buf + 4;
                 k = atoi(sstrsep(&p, sep));
                 sstrsep(&p, sep);
 
                 d = atof(sstrsep(&p, sep));
                 ffdh_results[k][0] += d;
 # endif /* OPENSSL_NO_DH */
-            } else if (strncmp(buf, "+H:", 3) == 0) {
+            } else if (HAS_PREFIX(buf, "+H:")) {
                 ;
             } else {
                 BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf,
diff --git a/crypto/asn1/a_strnid.c b/crypto/asn1/a_strnid.c
index 9e54db9292..2c6cb919f7 100644
--- a/crypto/asn1/a_strnid.c
+++ b/crypto/asn1/a_strnid.c
@@ -50,10 +50,10 @@ int ASN1_STRING_set_default_mask_asc(const char *p)
     unsigned long mask;
     char *end;
 
-    if (strncmp(p, "MASK:", 5) == 0) {
-        if (p[5] == '\0')
+    if (CHECK_AND_SKIP_PREFIX(p, "MASK:")) {
+        if (*p == '\0')
             return 0;
-        mask = strtoul(p + 5, &end, 0);
+        mask = strtoul(p, &end, 0);
         if (*end)
             return 0;
     } else if (strcmp(p, "nombstr") == 0)
diff --git a/crypto/asn1/asn1_gen.c b/crypto/asn1/asn1_gen.c
index ecff2be02e..bb0dcb2e09 100644
--- a/crypto/asn1/asn1_gen.c
+++ b/crypto/asn1/asn1_gen.c
@@ -325,13 +325,13 @@ static int asn1_cb(const char *elem, int len, void *bitstr)
             ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_FORMAT);
             return -1;
         }
-        if (strncmp(vstart, "ASCII", 5) == 0)
+        if (HAS_PREFIX(vstart, "ASCII"))
             arg->format = ASN1_GEN_FORMAT_ASCII;
-        else if (strncmp(vstart, "UTF8", 4) == 0)
+        else if (HAS_PREFIX(vstart, "UTF8"))
             arg->format = ASN1_GEN_FORMAT_UTF8;
-        else if (strncmp(vstart, "HEX", 3) == 0)
+        else if (HAS_PREFIX(vstart, "HEX"))
             arg->format = ASN1_GEN_FORMAT_HEX;
-        else if (strncmp(vstart, "BITLIST", 7) == 0)
+        else if (HAS_PREFIX(vstart, "BITLIST"))
             arg->format = ASN1_GEN_FORMAT_BITLIST;
         else {
             ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_FORMAT);
@@ -765,7 +765,7 @@ static int mask_cb(const char *elem, int len, void *arg)
     int tag;
     if (elem == NULL)
         return 0;
-    if ((len == 3) && (strncmp(elem, "DIR", 3) == 0)) {
+    if (len == 3 && HAS_PREFIX(elem, "DIR")) {
         *pmask |= B_ASN1_DIRECTORYSTRING;
         return 1;
     }
diff --git a/crypto/asn1/asn_mime.c b/crypto/asn1/asn_mime.c
index 1b8ac34106..a05e485c47 100644
--- a/crypto/asn1/asn_mime.c
+++ b/crypto/asn1/asn_mime.c
@@ -972,13 +972,8 @@ static int mime_bound_check(char *line, int linelen, const char *bound, int blen
     if (blen + 2 > linelen)
         return 0;
     /* Check for part boundary */
-    if ((strncmp(line, "--", 2) == 0)
-        && strncmp(line + 2, bound, blen) == 0) {
-        if (strncmp(line + blen + 2, "--", 2) == 0)
-            return 2;
-        else
-            return 1;
-    }
+    if ((CHECK_AND_SKIP_PREFIX(line, "--")) && strncmp(line, bound, blen) == 0)
+        return HAS_PREFIX(line + blen, "--") ? 2 : 1;
     return 0;
 }
 
diff --git a/crypto/cmp/cmp_http.c b/crypto/cmp/cmp_http.c
index 6ac4212db7..43c2acb4a5 100644
--- a/crypto/cmp/cmp_http.c
+++ b/crypto/cmp/cmp_http.c
@@ -14,7 +14,6 @@
 
 #include <openssl/asn1t.h>
 #include <openssl/http.h>
-#include "internal/sockets.h"
 
 #include <openssl/cmp.h>
 #include "cmp_local.h"
diff --git a/crypto/cmp/cmp_util.c b/crypto/cmp/cmp_util.c
index ed611d64dd..b8e4558e0d 100644
--- a/crypto/cmp/cmp_util.c
+++ b/crypto/cmp/cmp_util.c
@@ -53,8 +53,7 @@ static OSSL_CMP_severity parse_level(const char *level)
     if (end_level == NULL)
         return -1;
 
-    if (strncmp(level, OSSL_CMP_LOG_PREFIX,
-                strlen(OSSL_CMP_LOG_PREFIX)) == 0)
+    if (HAS_PREFIX(level, OSSL_CMP_LOG_PREFIX))
         level += strlen(OSSL_CMP_LOG_PREFIX);
     len = end_level - level;
     if (len > max_level_len)
diff --git a/crypto/conf/conf_def.c b/crypto/conf/conf_def.c
index c05c3c6b10..26764dad00 100644
--- a/crypto/conf/conf_def.c
+++ b/crypto/conf/conf_def.c
@@ -389,8 +389,8 @@ static int def_load_bio(CONF *conf, BIO *in, long *line)
                 psection = section;
             }
             p = eat_ws(conf, end);
-            if (strncmp(pname, ".pragma", 7) == 0
-                && (p != pname + 7 || *p == '=')) {
+            if (CHECK_AND_SKIP_PREFIX(pname, ".pragma")
+                && (p != pname || *p == '=')) {
                 char *pval;
 
                 if (*p == '=') {
@@ -435,8 +435,8 @@ static int def_load_bio(CONF *conf, BIO *in, long *line)
                  * We *ignore* any unknown pragma.
                  */
                 continue;
-            } else if (strncmp(pname, ".include", 8) == 0
-                && (p != pname + 8 || *p == '=')) {
+            } else if (CHECK_AND_SKIP_PREFIX(pname, ".include")
+                && (p != pname || *p == '=')) {
                 char *include = NULL;
                 BIO *next;
                 const char *include_dir = ossl_safe_getenv("OPENSSL_CONF_INCLUDE");
diff --git a/crypto/http/http_client.c b/crypto/http/http_client.c
index bb80836cd1..6be3e642e1 100644
--- a/crypto/http/http_client.c
+++ b/crypto/http/http_client.c
@@ -21,9 +21,8 @@
 #include <openssl/buffer.h>
 #include <openssl/http.h>
 #include "internal/sockets.h"
-#include "internal/cryptlib.h" /* for ossl_assert() */
+#include "internal/common.h" /* for ossl_assert() */
 
-#define HAS_PREFIX(str, prefix) (strncmp(str, prefix, sizeof(prefix) - 1) == 0)
 #define HTTP_PREFIX "HTTP/"
 #define HTTP_VERSION_PATT "1." /* allow 1.x */
 #define HTTP_VERSION_STR_LEN sizeof(HTTP_VERSION_PATT) /* == strlen("1.0") */
@@ -377,10 +376,10 @@ static int parse_http_line1(char *line, int *found_keep_alive)
     int i, retcode;
     char *code, *reason, *end;
 
-    if (!HAS_PREFIX(line, HTTP_PREFIX_VERSION))
+    if (!CHECK_AND_SKIP_PREFIX(line, HTTP_PREFIX_VERSION))
         goto err;
     /* above HTTP 1.0, connection persistence is the default */
-    *found_keep_alive = line[strlen(HTTP_PREFIX_VERSION)] > '0';
+    *found_keep_alive = *line > '0';
 
     /* Skip to first whitespace (past protocol info) */
     for (code = line; *code != '\0' && !ossl_isspace(*code); code++)
@@ -1297,15 +1296,15 @@ int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port,
             continue;
 
         /* Check for HTTP/1.x */
-        if (!HAS_PREFIX(mbuf, HTTP_PREFIX) != 0) {
+        mbufp = mbuf;
+        if (!HAS_PREFIX(mbufp, HTTP_PREFIX)) {
             ERR_raise(ERR_LIB_HTTP, HTTP_R_HEADER_PARSE_ERROR);
             BIO_printf(bio_err, "%s: HTTP CONNECT failed, non-HTTP response\n",
                        prog);
             /* Wrong protocol, not even HTTP, so stop reading headers */
             goto end;
         }
-        mbufp = mbuf + strlen(HTTP_PREFIX);
-        if (!HAS_PREFIX(mbufp, HTTP_VERSION_PATT) != 0) {
+        if (!HAS_PREFIX(mbufp, HTTP_VERSION_PATT)) {
             ERR_raise(ERR_LIB_HTTP, HTTP_R_RECEIVED_WRONG_HTTP_VERSION);
             BIO_printf(bio_err,
                        "%s: HTTP CONNECT failed, bad HTTP version %.*s\n",
diff --git a/crypto/params_from_text.c b/crypto/params_from_text.c
index 50f48fdb7e..84851edc47 100644
--- a/crypto/params_from_text.c
+++ b/crypto/params_from_text.c
@@ -8,7 +8,7 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include <string.h>
+#include "internal/common.h" /* for HAS_PREFIX */
 #include <openssl/ebcdic.h>
 #include <openssl/err.h>
 #include <openssl/params.h>
@@ -35,10 +35,7 @@ static int prepare_from_text(const OSSL_PARAM *paramdefs, const char *key,
      * ishex is used to translate legacy style string controls in hex format
      * to octet string parameters.
      */
-    *ishex = strncmp(key, "hex", 3) == 0;
-
-    if (*ishex)
-        key += 3;
+    *ishex = CHECK_AND_SKIP_PREFIX(key, "hex");
 
     p = *paramdef = OSSL_PARAM_locate_const(paramdefs, key);
     if (found != NULL)
diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c
index 3948021702..3d7e2f36a5 100644
--- a/crypto/pem/pem_lib.c
+++ b/crypto/pem/pem_lib.c
@@ -484,11 +484,11 @@ int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
  * presumably we also parse rfc822-style headers for S/MIME, so a common
  * abstraction might well be more generally useful.
  */
+#define PROC_TYPE "Proc-Type:"
+#define ENCRYPTED "ENCRYPTED"
+#define DEK_INFO "DEK-Info:"
 int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
 {
-    static const char ProcType[] = "Proc-Type:";
-    static const char ENCRYPTED[] = "ENCRYPTED";
-    static const char DEKInfo[] = "DEK-Info:";
     const EVP_CIPHER *enc = NULL;
     int ivlen;
     char *dekinfostart, c;
@@ -498,11 +498,10 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
     if ((header == NULL) || (*header == '\0') || (*header == '\n'))
         return 1;
 
-    if (strncmp(header, ProcType, sizeof(ProcType)-1) != 0) {
+    if (!CHECK_AND_SKIP_PREFIX(header, PROC_TYPE)) {
         ERR_raise(ERR_LIB_PEM, PEM_R_NOT_PROC_TYPE);
         return 0;
     }
-    header += sizeof(ProcType)-1;
     header += strspn(header, " \t");
 
     if (*header++ != '4' || *header++ != ',')
@@ -510,12 +509,11 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
     header += strspn(header, " \t");
 
     /* We expect "ENCRYPTED" followed by optional white-space + line break */
-    if (strncmp(header, ENCRYPTED, sizeof(ENCRYPTED)-1) != 0 ||
-        strspn(header+sizeof(ENCRYPTED)-1, " \t\r\n") == 0) {
+    if (!CHECK_AND_SKIP_PREFIX(header, ENCRYPTED) ||
+        strspn(header, " \t\r\n") == 0) {
         ERR_raise(ERR_LIB_PEM, PEM_R_NOT_ENCRYPTED);
         return 0;
     }
-    header += sizeof(ENCRYPTED)-1;
     header += strspn(header, " \t\r");
     if (*header++ != '\n') {
         ERR_raise(ERR_LIB_PEM, PEM_R_SHORT_HEADER);
@@ -526,11 +524,10 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
      * https://tools.ietf.org/html/rfc1421#section-4.6.1.3
      * We expect "DEK-Info: algo[,hex-parameters]"
      */
-    if (strncmp(header, DEKInfo, sizeof(DEKInfo)-1) != 0) {
+    if (!CHECK_AND_SKIP_PREFIX(header, DEK_INFO)) {
         ERR_raise(ERR_LIB_PEM, PEM_R_NOT_DEK_INFO);
         return 0;
     }
-    header += sizeof(DEKInfo)-1;
     header += strspn(header, " \t");
 
     /*
@@ -733,12 +730,12 @@ static int sanitize_line(char *linebuf, int len, unsigned int flags, int first_c
 
 #define LINESIZE 255
 /* Note trailing spaces for begin and end. */
-static const char beginstr[] = "-----BEGIN ";
-static const char endstr[] = "-----END ";
-static const char tailstr[] = "-----\n";
-#define BEGINLEN ((int)(sizeof(beginstr) - 1))
-#define ENDLEN ((int)(sizeof(endstr) - 1))
-#define TAILLEN ((int)(sizeof(tailstr) - 1))
+#define BEGINSTR "-----BEGIN "
+#define ENDSTR "-----END "
+#define TAILSTR "-----\n"
+#define BEGINLEN ((int)(sizeof(BEGINSTR) - 1))
+#define ENDLEN ((int)(sizeof(ENDSTR) - 1))
+#define TAILLEN ((int)(sizeof(TAILSTR) - 1))
 static int get_name(BIO *bp, char **name, unsigned int flags)
 {
     char *linebuf;
@@ -769,9 +766,9 @@ static int get_name(BIO *bp, char **name, unsigned int flags)
         first_call = 0;
 
         /* Allow leading empty or non-matching lines. */
-    } while (strncmp(linebuf, beginstr, BEGINLEN) != 0
+    } while (!HAS_PREFIX(linebuf, BEGINSTR)
              || len < TAILLEN
-             || strncmp(linebuf + len - TAILLEN, tailstr, TAILLEN) != 0);
+             || !HAS_PREFIX(linebuf + len - TAILLEN, TAILSTR));
     linebuf[len - TAILLEN] = '\0';
     len = len - BEGINLEN - TAILLEN + 1;
     *name = pem_malloc(len, flags);
@@ -844,7 +841,7 @@ static int get_header_and_data(BIO *bp, BIO **header, BIO **data, char *name,
             if (memchr(linebuf, ':', len) != NULL)
                 got_header = IN_HEADER;
         }
-        if (!strncmp(linebuf, endstr, ENDLEN) || got_header == IN_HEADER)
+        if (HAS_PREFIX(linebuf, ENDSTR) || got_header == IN_HEADER)
             flags_mask &= ~PEM_FLAG_ONLY_B64;
         len = sanitize_line(linebuf, len, flags & flags_mask, 0);
 
@@ -867,11 +864,11 @@ static int get_header_and_data(BIO *bp, BIO **header, BIO **data, char *name,
         }
 
         /* Check for end of stream (which means there is no header). */
-        if (strncmp(linebuf, endstr, ENDLEN) == 0) {
-            p = linebuf + ENDLEN;
+        p = linebuf;
+        if (CHECK_AND_SKIP_PREFIX(p, ENDSTR)) {
             namelen = strlen(name);
             if (strncmp(p, name, namelen) != 0 ||
-                strncmp(p + namelen, tailstr, TAILLEN) != 0) {
+                !HAS_PREFIX(p + namelen, TAILSTR)) {
                 ERR_raise(ERR_LIB_PEM, PEM_R_BAD_END_LINE);
                 goto err;
             }
diff --git a/crypto/punycode.c b/crypto/punycode.c
index 385b4b1df4..f6d7ff7960 100644
--- a/crypto/punycode.c
+++ b/crypto/punycode.c
@@ -8,10 +8,10 @@
  */
 
 #include <stddef.h>
-#include <string.h>
 #include <stdio.h>
 #include <openssl/e_os2.h>
 #include "crypto/punycode.h"
+#include "internal/common.h" /* for HAS_PREFIX */
 
 static const unsigned int base = 36;
 static const unsigned int tmin = 1;
@@ -266,7 +266,7 @@ int ossl_a2ulabel(const char *in, char *out, size_t *outlen)
         char *tmpptr = strchr(inptr, '.');
         size_t delta = (tmpptr) ? (size_t)(tmpptr - inptr) : strlen(inptr);
 
-        if (strncmp(inptr, "xn--", 4) != 0) {
+        if (!HAS_PREFIX(inptr, "xn--")) {
             size += delta + 1;
 
             if (size >= *outlen - 1)
diff --git a/crypto/store/store_lib.c b/crypto/store/store_lib.c
index 833ec8ff9a..42722a2560 100644
--- a/crypto/store/store_lib.c
+++ b/crypto/store/store_lib.c
@@ -94,7 +94,7 @@ OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq,
     if ((p = strchr(scheme_copy, ':')) != NULL) {
         *p++ = '\0';
         if (strcasecmp(scheme_copy, "file") != 0) {
-            if (strncmp(p, "//", 2) == 0)
+            if (HAS_PREFIX(p, "//"))
                 schemes_n--;         /* Invalidate the file scheme */
             schemes[schemes_n++] = scheme_copy;
         }
diff --git a/crypto/x509/v3_conf.c b/crypto/x509/v3_conf.c
index b95c652468..8201ba0d86 100644
--- a/crypto/x509/v3_conf.c
+++ b/crypto/x509/v3_conf.c
@@ -200,9 +200,8 @@ static int v3_check_critical(const char **value)
 {
     const char *p = *value;
 
-    if ((strlen(p) < 9) || strncmp(p, "critical,", 9))
+    if (!CHECK_AND_SKIP_PREFIX(p, "critical,"))
         return 0;
-    p += 9;
     while (ossl_isspace(*p))
         p++;
     *value = p;
@@ -215,11 +214,9 @@ static int v3_check_generic(const char **value)
     int gen_type = 0;
     const char *p = *value;
 
-    if ((strlen(p) >= 4) && strncmp(p, "DER:", 4) == 0) {
-        p += 4;
+    if (CHECK_AND_SKIP_PREFIX(p, "DER:")) {
         gen_type = 1;
-    } else if ((strlen(p) >= 5) && strncmp(p, "ASN1:", 5) == 0) {
-        p += 5;
+    } else if (CHECK_AND_SKIP_PREFIX(p, "ASN1:")) {
         gen_type = 2;
     } else
         return 0;
diff --git a/crypto/x509/v3_cpols.c b/crypto/x509/v3_cpols.c
index 5353a69167..65fab71406 100644
--- a/crypto/x509/v3_cpols.c
+++ b/crypto/x509/v3_cpols.c
@@ -261,17 +261,17 @@ static int displaytext_str2tag(const char *tagstr, unsigned int *tag_len)
     if (len == -1)
         return V_ASN1_VISIBLESTRING;
     *tag_len = len;
-    if (len == sizeof("UTF8") - 1 && strncmp(tagstr, "UTF8", len) == 0)
+    if (len == sizeof("UTF8") - 1 && HAS_PREFIX(tagstr, "UTF8"))
         return V_ASN1_UTF8STRING;
-    if (len == sizeof("UTF8String") - 1 && strncmp(tagstr, "UTF8String", len) == 0)
+    if (len == sizeof("UTF8String") - 1 && HAS_PREFIX(tagstr, "UTF8String"))
         return V_ASN1_UTF8STRING;
-    if (len == sizeof("BMP") - 1 && strncmp(tagstr, "BMP", len) == 0)
+    if (len == sizeof("BMP") - 1 && HAS_PREFIX(tagstr, "BMP"))
         return V_ASN1_BMPSTRING;
-    if (len == sizeof("BMPSTRING") - 1 && strncmp(tagstr, "BMPSTRING", len) == 0)
+    if (len == sizeof("BMPSTRING") - 1 && HAS_PREFIX(tagstr, "BMPSTRING"))
         return V_ASN1_BMPSTRING;
-    if (len == sizeof("VISIBLE") - 1 && strncmp(tagstr, "VISIBLE", len) == 0)
+    if (len == sizeof("VISIBLE") - 1 && HAS_PREFIX(tagstr, "VISIBLE"))
         return V_ASN1_VISIBLESTRING;
-    if (len == sizeof("VISIBLESTRING") - 1 && strncmp(tagstr, "VISIBLESTRING", len) == 0)
+    if (len == sizeof("VISIBLESTRING") - 1 && HAS_PREFIX(tagstr, "VISIBLESTRING"))
         return V_ASN1_VISIBLESTRING;
     *tag_len = 0;
     return V_ASN1_VISIBLESTRING;
diff --git a/crypto/x509/v3_crld.c b/crypto/x509/v3_crld.c
index bc755f5f0d..b831f775db 100644
--- a/crypto/x509/v3_crld.c
+++ b/crypto/x509/v3_crld.c
@@ -70,7 +70,7 @@ static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
     STACK_OF(GENERAL_NAME) *fnm = NULL;
     STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
 
-    if (strncmp(cnf->name, "fullname", 9) == 0) {
+    if (HAS_PREFIX(cnf->name, "fullname")) {
         fnm = gnames_from_sectname(ctx, cnf->value);
         if (!fnm)
             goto err;
diff --git a/crypto/x509/v3_ncons.c b/crypto/x509/v3_ncons.c
index c9e66a0f3b..7ffb88c4c0 100644
--- a/crypto/x509/v3_ncons.c
+++ b/crypto/x509/v3_ncons.c
@@ -138,10 +138,10 @@ static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
         goto memerr;
     for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
         val = sk_CONF_VALUE_value(nval, i);
-        if (strncmp(val->name, "permitted", 9) == 0 && val->name[9]) {
+        if (HAS_PREFIX(val->name, "permitted") && val->name[9]) {
             ptree = &ncons->permittedSubtrees;
             tval.name = val->name + 10;
-        } else if (strncmp(val->name, "excluded", 8) == 0 && val->name[8]) {
+        } else if (HAS_PREFIX(val->name, "excluded") && val->name[8]) {
             ptree = &ncons->excludedSubtrees;
             tval.name = val->name + 9;
         } else {
diff --git a/crypto/x509/v3_pci.c b/crypto/x509/v3_pci.c
index a931e01a9c..79fe76d042 100644
--- a/crypto/x509/v3_pci.c
+++ b/crypto/x509/v3_pci.c
@@ -112,6 +112,7 @@ static int process_pci_value(CONF_VALUE *val,
             return 0;
         }
     } else if (strcmp(val->name, "policy") == 0) {
+        char *valp = val->value;
         unsigned char *tmp_data = NULL;
         long val_len;
 
@@ -124,9 +125,9 @@ static int process_pci_value(CONF_VALUE *val,
             }
             free_policy = 1;
         }
-        if (strncmp(val->value, "hex:", 4) == 0) {
+        if (CHECK_AND_SKIP_PREFIX(valp, "hex:")) {
             unsigned char *tmp_data2 =
-                OPENSSL_hexstr2buf(val->value + 4, &val_len);
+                OPENSSL_hexstr2buf(valp, &val_len);
 
             if (!tmp_data2) {
                 X509V3_conf_err(val);
@@ -155,10 +156,10 @@ static int process_pci_value(CONF_VALUE *val,
                 goto err;
             }
             OPENSSL_free(tmp_data2);
-        } else if (strncmp(val->value, "file:", 5) == 0) {
+        } else if (CHECK_AND_SKIP_PREFIX(valp, "file:")) {
             unsigned char buf[2048];
             int n;
-            BIO *b = BIO_new_file(val->value + 5, "r");
+            BIO *b = BIO_new_file(valp, "r");
             if (!b) {
                 ERR_raise(ERR_LIB_X509V3, ERR_R_BIO_LIB);
                 X509V3_conf_err(val);
@@ -194,8 +195,8 @@ static int process_pci_value(CONF_VALUE *val,
                 X509V3_conf_err(val);
                 goto err;
             }
-        } else if (strncmp(val->value, "text:", 5) == 0) {
-            val_len = strlen(val->value + 5);
+        } else if (CHECK_AND_SKIP_PREFIX(valp, "text:")) {
+            val_len = strlen(valp);
             tmp_data = OPENSSL_realloc((*policy)->data,
                                        (*policy)->length + val_len + 1);
             if (tmp_data) {
diff --git a/crypto/x509/v3_utl.c b/crypto/x509/v3_utl.c
index a70917a39b..5704820e50 100644
--- a/crypto/x509/v3_utl.c
+++ b/crypto/x509/v3_utl.c
@@ -704,7 +704,7 @@ static int wildcard_match(const unsigned char *prefix, size_t prefix_len,
     }
     /* IDNA labels cannot match partial wildcards */
     if (!allow_idna &&
-        subject_len >= 4 && strncasecmp((char *)subject, "xn--", 4) == 0)
+        subject_len >= 4 && HAS_CASE_PREFIX((const char *)subject, "xn--"))
         return 0;
     /* The wildcard may match a literal '*' */
     if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*')
@@ -764,7 +764,7 @@ static const unsigned char *valid_star(const unsigned char *p, size_t len,
                    || ('A' <= p[i] && p[i] <= 'Z')
                    || ('0' <= p[i] && p[i] <= '9')) {
             if ((state & LABEL_START) != 0
-                && len - i >= 4 && strncasecmp((char *)&p[i], "xn--", 4) == 0)
+                && len - i >= 4 && HAS_CASE_PREFIX((const char *)&p[i], "xn--"))
                 state |= LABEL_IDNA;
             state &= ~(LABEL_HYPHEN | LABEL_START);
         } else if (p[i] == '.') {
diff --git a/engines/e_loader_attic.c b/engines/e_loader_attic.c
index 74f297400b..59f19d329f 100644
--- a/engines/e_loader_attic.c
+++ b/engines/e_loader_attic.c
@@ -14,7 +14,7 @@
 /* We need to use some engine deprecated APIs */
 #define OPENSSL_SUPPRESS_DEPRECATED
 
-/* #include "e_os.h" */
+#include "../e_os.h" /* for stat and strncasecmp */
 #include <string.h>
 #include <sys/stat.h>
 #include <ctype.h>
@@ -42,11 +42,6 @@
 
 DEFINE_STACK_OF(OSSL_STORE_INFO)
 
-#ifdef _WIN32
-# define stat _stat
-# define strncasecmp _strnicmp
-#endif
-
 #ifndef S_ISDIR
 # define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR)
 #endif
@@ -957,7 +952,7 @@ static OSSL_STORE_LOADER_CTX *file_open_ex
         unsigned int check_absolute:1;
     } path_data[2];
     size_t path_data_n = 0, i;
-    const char *path;
+    const char *path, *p = uri, *q;
 
     /*
      * First step, just take the URI as is.
@@ -966,20 +961,18 @@ static OSSL_STORE_LOADER_CTX *file_open_ex
     path_data[path_data_n++].path = uri;
 
     /*
-     * Second step, if the URI appears to start with the 'file' scheme,
+     * Second step, if the URI appears to start with the "file" scheme,
      * extract the path and make that the second path to check.
      * There's a special case if the URI also contains an authority, then
      * the full URI shouldn't be used as a path anywhere.
      */
-    if (strncasecmp(uri, "file:", 5) == 0) {
-        const char *p = &uri[5];
-
-        if (strncmp(&uri[5], "//", 2) == 0) {
+    if (CHECK_AND_SKIP_CASE_PREFIX(p, "file:")) {
+        q = p;
+        if (CHECK_AND_SKIP_PREFIX(q, "//")) {
             path_data_n--;           /* Invalidate using the full URI */
-            if (strncasecmp(&uri[7], "localhost/", 10) == 0) {
-                p = &uri[16];
-            } else if (uri[7] == '/') {
-                p = &uri[7];
+            if (CHECK_AND_SKIP_CASE_PREFIX(q, "localhost/")
+                    || CHECK_AND_SKIP_PREFIX(q, "/")) {
+                p = q - 1;
             } else {
                 ATTICerr(0, ATTIC_R_URI_AUTHORITY_UNSUPPORTED);
                 return NULL;
@@ -988,7 +981,7 @@ static OSSL_STORE_LOADER_CTX *file_open_ex
 
         path_data[path_data_n].check_absolute = 1;
 #ifdef _WIN32
-        /* Windows file: URIs with a drive letter start with a / */
+        /* Windows "file:" URIs with a drive letter start with a '/' */
         if (p[0] == '/' && p[2] == ':' && p[3] == '/') {
             char c = tolower(p[1]);
 
diff --git a/engines/e_ossltest.c b/engines/e_ossltest.c
index df0805b197..19dda64d1f 100644
--- a/engines/e_ossltest.c
+++ b/engines/e_ossltest.c
@@ -27,6 +27,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include "internal/common.h" /* for CHECK_AND_SKIP_CASE_PREFIX */
 
 #include <openssl/engine.h>
 #include <openssl/sha.h>
@@ -42,10 +43,6 @@
 
 #include "e_ossltest_err.c"
 
-#ifdef _WIN32
-# define strncasecmp _strnicmp
-#endif
-
 /* Engine Id and Name */
 static const char *engine_ossltest_id = "ossltest";
 static const char *engine_ossltest_name = "OpenSSL Test engine support";
@@ -383,9 +380,8 @@ static EVP_PKEY *load_key(ENGINE *eng, const char *key_id, int pub,
     BIO *in;
     EVP_PKEY *key;
 
-    if (strncasecmp(key_id, "ot:", 3) != 0)
+    if (!CHECK_AND_SKIP_CASE_PREFIX(key_id, "ot:"))
         return NULL;
-    key_id += 3;
 
     fprintf(stderr, "[ossltest]Loading %s key %s\n",
             pub ? "Public" : "Private", key_id);
diff --git a/include/internal/common.h b/include/internal/common.h
new file mode 100644
index 0000000000..44224f3ba8
--- /dev/null
+++ b/include/internal/common.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef OSSL_INTERNAL_COMMON_H
+# define OSSL_INTERNAL_COMMON_H
+# pragma once
+
+# include <stdlib.h>
+# include <string.h>
+# include "../../e_os.h" /* To get strncasecmp() on Windows */
+
+# include "internal/nelem.h"
+
+#ifdef NDEBUG
+# define ossl_assert(x) ((x) != 0)
+#else
+__owur static ossl_inline int ossl_assert_int(int expr, const char *exprstr,
+                                              const char *file, int line)
+{
+    if (!expr)
+        OPENSSL_die(exprstr, file, line);
+
+    return expr;
+}
+
+# define ossl_assert(x) ossl_assert_int((x) != 0, "Assertion failed: "#x, \
+                                         __FILE__, __LINE__)
+
+#endif
+
+/* Check if |pre|, which must be a string literal, is a prefix of |str| */
+#define HAS_PREFIX(str, pre) (strncmp(str, pre "", sizeof(pre) - 1) == 0)
+/* As before, and if check succeeds, advance |str| past the prefix |pre| */
+#define CHECK_AND_SKIP_PREFIX(str, pre) \
+    (HAS_PREFIX(str, pre) ? ((str) += sizeof(pre) - 1, 1) : 0)
+/* Check if the string literal |p| is a case-insensitive prefix of |s| */
+#define HAS_CASE_PREFIX(s, p) (strncasecmp(s, p "", sizeof(p) - 1) == 0)
+/* As before, and if check succeeds, advance |str| past the prefix |pre| */
+#define CHECK_AND_SKIP_CASE_PREFIX(str, pre) \
+    (HAS_CASE_PREFIX(str, pre) ? ((str) += sizeof(pre) - 1, 1) : 0)
+/* Check if the string literal |suffix| is a case-insensitive suffix of |str| */
+#define HAS_CASE_SUFFIX(str, suffix) (strlen(str) < sizeof(suffix) - 1 ? 0 : \
+    strcasecmp(str + strlen(str) - sizeof(suffix) + 1, suffix "") == 0)
+
+/*
+ * Use this inside a union with the field that needs to be aligned to a
+ * reasonable boundary for the platform.  The most pessimistic alignment
+ * of the listed types will be used by the compiler.
+ */
+# define OSSL_UNION_ALIGN       \
+    double align;               \
+    ossl_uintmax_t align_int;   \
+    void *align_ptr
+
+# define OPENSSL_CONF             "openssl.cnf"
+
+# ifndef OPENSSL_SYS_VMS
+#  define X509_CERT_AREA          OPENSSLDIR
+#  define X509_CERT_DIR           OPENSSLDIR "/certs"
+#  define X509_CERT_FILE          OPENSSLDIR "/cert.pem"
+#  define X509_PRIVATE_DIR        OPENSSLDIR "/private"
+#  define CTLOG_FILE              OPENSSLDIR "/ct_log_list.cnf"
+# else
+#  define X509_CERT_AREA          "OSSL$DATAROOT:[000000]"
+#  define X509_CERT_DIR           "OSSL$DATAROOT:[CERTS]"
+#  define X509_CERT_FILE          "OSSL$DATAROOT:[000000]cert.pem"
+#  define X509_PRIVATE_DIR        "OSSL$DATAROOT:[PRIVATE]"
+#  define CTLOG_FILE              "OSSL$DATAROOT:[000000]ct_log_list.cnf"
+# endif
+
+# define X509_CERT_DIR_EVP        "SSL_CERT_DIR"
+# define X509_CERT_FILE_EVP       "SSL_CERT_FILE"
+# define CTLOG_FILE_EVP           "CTLOG_FILE"
+
+/* size of string representations */
+# define DECIMAL_SIZE(type)      ((sizeof(type)*8+2)/3+1)
+# define HEX_SIZE(type)          (sizeof(type)*2)
+
+static ossl_inline int ossl_ends_with_dirsep(const char *path)
+{
+    if (*path != '\0')
+        path += strlen(path) - 1;
+# if defined __VMS
+    if (*path == ']' || *path == '>' || *path == ':')
+        return 1;
+# elif defined _WIN32
+    if (*path == '\\')
+        return 1;
+# endif
+    return *path == '/';
+}
+
+static ossl_inline int ossl_is_absolute_path(const char *path)
+{
+# if defined __VMS
+    if (strchr(path, ':') != NULL
+        || ((path[0] == '[' || path[0] == '<')
+            && path[1] != '.' && path[1] != '-'
+            && path[1] != ']' && path[1] != '>'))
+        return 1;
+# elif defined _WIN32
+    if (path[0] == '\\'
+        || (path[0] != '\0' && path[1] == ':'))
+        return 1;
+# endif
+    return path[0] == '/';
+}
+
+#endif
diff --git a/include/internal/cryptlib.h b/include/internal/cryptlib.h
index 1291299b6e..c017d06483 100644
--- a/include/internal/cryptlib.h
+++ b/include/internal/cryptlib.h
@@ -11,9 +11,6 @@
 # define OSSL_INTERNAL_CRYPTLIB_H
 # pragma once
 
-# include <stdlib.h>
-# include <string.h>
-
 # ifdef OPENSSL_USE_APPLINK
 #  define BIO_FLAGS_UPLINK_INTERNAL 0x8000
 #  include "ms/uplink.h"
@@ -21,39 +18,13 @@
 #  define BIO_FLAGS_UPLINK_INTERNAL 0
 # endif
 
+# include "internal/common.h"
+
 # include <openssl/crypto.h>
 # include <openssl/buffer.h>
 # include <openssl/bio.h>
 # include <openssl/asn1.h>
 # include <openssl/err.h>
-# include "internal/nelem.h"
-
-#ifdef NDEBUG
-# define ossl_assert(x) ((x) != 0)
-#else
-__owur static ossl_inline int ossl_assert_int(int expr, const char *exprstr,
-                                              const char *file, int line)
-{
-    if (!expr)
-        OPENSSL_die(exprstr, file, line);
-
-    return expr;
-}
-
-# define ossl_assert(x) ossl_assert_int((x) != 0, "Assertion failed: "#x, \
-                                         __FILE__, __LINE__)
-
-#endif
-
-/*
- * Use this inside a union with the field that needs to be aligned to a
- * reasonable boundary for the platform.  The most pessimistic alignment
- * of the listed types will be used by the compiler.
- */
-# define OSSL_UNION_ALIGN       \
-    double align;               \
-    ossl_uintmax_t align_int;   \
-    void *align_ptr
 
 typedef struct ex_callback_st EX_CALLBACK;
 DEFINE_STACK_OF(EX_CALLBACK)
@@ -61,30 +32,6 @@ DEFINE_STACK_OF(EX_CALLBACK)
 typedef struct mem_st MEM;
 DEFINE_LHASH_OF(MEM);
 
-# define OPENSSL_CONF             "openssl.cnf"
-
-# ifndef OPENSSL_SYS_VMS
-#  define X509_CERT_AREA          OPENSSLDIR
-#  define X509_CERT_DIR           OPENSSLDIR "/certs"
-#  define X509_CERT_FILE          OPENSSLDIR "/cert.pem"
-#  define X509_PRIVATE_DIR        OPENSSLDIR "/private"
-#  define CTLOG_FILE              OPENSSLDIR "/ct_log_list.cnf"
-# else
-#  define X509_CERT_AREA          "OSSL$DATAROOT:[000000]"
-#  define X509_CERT_DIR           "OSSL$DATAROOT:[CERTS]"
-#  define X509_CERT_FILE          "OSSL$DATAROOT:[000000]cert.pem"
-#  define X509_PRIVATE_DIR        "OSSL$DATAROOT:[PRIVATE]"
-#  define CTLOG_FILE              "OSSL$DATAROOT:[000000]ct_log_list.cnf"
-# endif
-
-# define X509_CERT_DIR_EVP        "SSL_CERT_DIR"
-# define X509_CERT_FILE_EVP       "SSL_CERT_FILE"
-# define CTLOG_FILE_EVP           "CTLOG_FILE"
-
-/* size of string representations */
-# define DECIMAL_SIZE(type)      ((sizeof(type)*8+2)/3+1)
-# define HEX_SIZE(type)          (sizeof(type)*2)
-
 void OPENSSL_cpuid_setup(void);
 #if defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
     defined(__x86_64) || defined(__x86_64__) || \
@@ -228,34 +175,4 @@ char *ossl_buf2hexstr_sep(const unsigned char *buf, long buflen, char sep);
 unsigned char *ossl_hexstr2buf_sep(const char *str, long *buflen,
                                    const char sep);
 
-static ossl_inline int ossl_ends_with_dirsep(const char *path)
-{
-    if (*path != '\0')
-        path += strlen(path) - 1;
-# if defined __VMS
-    if (*path == ']' || *path == '>' || *path == ':')
-        return 1;
-# elif defined _WIN32
-    if (*path == '\\')
-        return 1;
-# endif
-    return *path == '/';
-}
-
-static ossl_inline int ossl_is_absolute_path(const char *path)
-{
-# if defined __VMS
-    if (strchr(path, ':') != NULL
-        || ((path[0] == '[' || path[0] == '<')
-            && path[1] != '.' && path[1] != '-'
-            && path[1] != ']' && path[1] != '>'))
-        return 1;
-# elif defined _WIN32
-    if (path[0] == '\\'
-        || (path[0] != '\0' && path[1] == ':'))
-        return 1;
-# endif
-    return path[0] == '/';
-}
-
 #endif
diff --git a/providers/implementations/storemgmt/file_store.c b/providers/implementations/storemgmt/file_store.c
index 34cb70fdf8..340b01bd2c 100644
--- a/providers/implementations/storemgmt/file_store.c
+++ b/providers/implementations/storemgmt/file_store.c
@@ -203,7 +203,7 @@ static void *file_open(void *provctx, const char *uri)
         unsigned int check_absolute:1;
     } path_data[2];
     size_t path_data_n = 0, i;
-    const char *path;
+    const char *path, *p = uri, *q;
     BIO *bio;
 
     ERR_set_mark();
@@ -215,20 +215,18 @@ static void *file_open(void *provctx, const char *uri)
     path_data[path_data_n++].path = uri;
 
     /*
-     * Second step, if the URI appears to start with the 'file' scheme,
+     * Second step, if the URI appears to start with the "file" scheme,
      * extract the path and make that the second path to check.
      * There's a special case if the URI also contains an authority, then
      * the full URI shouldn't be used as a path anywhere.
      */
-    if (strncasecmp(uri, "file:", 5) == 0) {
-        const char *p = &uri[5];
-
-        if (strncmp(&uri[5], "//", 2) == 0) {
+    if (CHECK_AND_SKIP_CASE_PREFIX(p, "file:")) {
+        q = p;
+        if (CHECK_AND_SKIP_CASE_PREFIX(q, "//")) {
             path_data_n--;           /* Invalidate using the full URI */
-            if (strncasecmp(&uri[7], "localhost/", 10) == 0) {
-                p = &uri[16];
-            } else if (uri[7] == '/') {
-                p = &uri[7];
+            if (CHECK_AND_SKIP_CASE_PREFIX(q, "localhost/")
+                    || CHECK_AND_SKIP_CASE_PREFIX(q, "/")) {
+                p = q - 1;
             } else {
                 ERR_clear_last_mark();
                 ERR_raise(ERR_LIB_PROV, PROV_R_URI_AUTHORITY_UNSUPPORTED);
@@ -238,7 +236,7 @@ static void *file_open(void *provctx, const char *uri)
 
         path_data[path_data_n].check_absolute = 1;
 #ifdef _WIN32
-        /* Windows file: URIs with a drive letter start with a / */
+        /* Windows "file:" URIs with a drive letter start with a '/' */
         if (p[0] == '/' && p[2] == ':' && p[3] == '/') {
             char c = tolower(p[1]);
 
diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c
index c713f231ca..55b5e99f24 100644
--- a/ssl/record/ssl3_record.c
+++ b/ssl/record/ssl3_record.c
@@ -338,13 +338,13 @@ int ssl3_get_record(SSL *s)
                         /* Go back to start of packet, look at the five bytes
                          * that we have. */
                         p = RECORD_LAYER_get_packet(&s->rlayer);
-                        if (strncmp((char *)p, "GET ", 4) == 0 ||
-                            strncmp((char *)p, "POST ", 5) == 0 ||
-                            strncmp((char *)p, "HEAD ", 5) == 0 ||
-                            strncmp((char *)p, "PUT ", 4) == 0) {
+                        if (HAS_PREFIX((char *)p, "GET ") ||
+                            HAS_PREFIX((char *)p, "POST ") ||
+                            HAS_PREFIX((char *)p, "HEAD ") ||
+                            HAS_PREFIX((char *)p, "PUT ")) {
                             SSLfatal(s, SSL_AD_NO_ALERT, SSL_R_HTTP_REQUEST);
                             return -1;
-                        } else if (strncmp((char *)p, "CONNE", 5) == 0) {
+                        } else if (HAS_PREFIX((char *)p, "CONNE")) {
                             SSLfatal(s, SSL_AD_NO_ALERT,
                                      SSL_R_HTTPS_PROXY_REQUEST);
                             return -1;
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index c396f69c3a..e38e1c27e6 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -1216,10 +1216,10 @@ static int ssl_cipher_process_rulestr(const char *rule_str,
          */
         if (rule == CIPHER_SPECIAL) { /* special command */
             ok = 0;
-            if ((buflen == 8) && strncmp(buf, "STRENGTH", 8) == 0) {
+            if ((buflen == 8) && HAS_PREFIX(buf, "STRENGTH")) {
                 ok = ssl_cipher_strength_sort(head_p, tail_p);
-            } else if (buflen == 10 && strncmp(buf, "SECLEVEL=", 9) == 0) {
-                int level = buf[9] - '0';
+            } else if (buflen == 10 && CHECK_AND_SKIP_PREFIX(buf, "SECLEVEL=")) {
+                int level = *buf - '0';
                 if (level < 0 || level > 5) {
                     ERR_raise(ERR_LIB_SSL, SSL_R_INVALID_COMMAND);
                 } else {
@@ -1259,14 +1259,14 @@ static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c,
                                     const char **prule_str)
 {
     unsigned int suiteb_flags = 0, suiteb_comb2 = 0;
-    if (strncmp(*prule_str, "SUITEB128ONLY", 13) == 0) {
+    if (HAS_PREFIX(*prule_str, "SUITEB128ONLY")) {
         suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS_ONLY;
-    } else if (strncmp(*prule_str, "SUITEB128C2", 11) == 0) {
+    } else if (HAS_PREFIX(*prule_str, "SUITEB128C2")) {
         suiteb_comb2 = 1;
         suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS;
-    } else if (strncmp(*prule_str, "SUITEB128", 9) == 0) {
+    } else if (HAS_PREFIX(*prule_str, "SUITEB128")) {
         suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS;
-    } else if (strncmp(*prule_str, "SUITEB192", 9) == 0) {
+    } else if (HAS_PREFIX(*prule_str, "SUITEB192")) {
         suiteb_flags = SSL_CERT_FLAG_SUITEB_192_LOS;
     }
 
@@ -1601,7 +1601,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(SSL_CTX *ctx,
      */
     ok = 1;
     rule_p = rule_str;
-    if (strncmp(rule_str, "DEFAULT", 7) == 0) {
+    if (HAS_PREFIX(rule_str, "DEFAULT")) {
         ok = ssl_cipher_process_rulestr(OSSL_default_cipher_list(),
                                         &head, &tail, ca_list, c);
         rule_p += 7;
diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h
index ce93049180..9b88140a28 100644
--- a/ssl/ssl_local.h
+++ b/ssl/ssl_local.h
@@ -15,8 +15,8 @@
 # include "e_os.h"              /* struct timeval for DTLS */
 # include <stdlib.h>
 # include <time.h>
-# include <string.h>
 # include <errno.h>
+# include "internal/common.h" /* for HAS_PREFIX */
 
 # include <openssl/buffer.h>
 # include <openssl/comp.h>
diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c
index cf410d6d87..5509389aa2 100644
--- a/ssl/ssl_rsa.c
+++ b/ssl/ssl_rsa.c
@@ -25,6 +25,9 @@ static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
                              | SSL_EXT_TLS1_2_SERVER_HELLO \
                              | SSL_EXT_IGNORE_ON_RESUMPTION)
 
+#define NAME_PREFIX1 "SERVERINFO FOR "
+#define NAME_PREFIX2 "SERVERINFOV2 FOR "
+
 int SSL_use_certificate(SSL *ssl, X509 *x)
 {
     int rv;
@@ -760,8 +763,6 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file)
     long extension_length = 0;
     char *name = NULL;
     char *header = NULL;
-    static const char namePrefix1[] = "SERVERINFO FOR ";
-    static const char namePrefix2[] = "SERVERINFOV2 FOR ";
     unsigned int name_len;
     int ret = 0;
     BIO *bin = NULL;
@@ -798,18 +799,18 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file)
         }
         /* Check that PEM name starts with "BEGIN SERVERINFO FOR " */
         name_len = strlen(name);
-        if (name_len < sizeof(namePrefix1) - 1) {
+        if (name_len < sizeof(NAME_PREFIX1) - 1) {
             ERR_raise(ERR_LIB_SSL, SSL_R_PEM_NAME_TOO_SHORT);
             goto end;
         }
-        if (strncmp(name, namePrefix1, sizeof(namePrefix1) - 1) == 0) {
+        if (HAS_PREFIX(name, NAME_PREFIX1)) {
             version = SSL_SERVERINFOV1;
         } else {
-            if (name_len < sizeof(namePrefix2) - 1) {
+            if (name_len < sizeof(NAME_PREFIX2) - 1) {
                 ERR_raise(ERR_LIB_SSL, SSL_R_PEM_NAME_TOO_SHORT);
                 goto end;
             }
-            if (strncmp(name, namePrefix2, sizeof(namePrefix2) - 1) != 0) {
+            if (!HAS_PREFIX(name, NAME_PREFIX2)) {
                 ERR_raise(ERR_LIB_SSL, SSL_R_PEM_NAME_BAD_PREFIX);
                 goto end;
             }
diff --git a/test/dtls_mtu_test.c b/test/dtls_mtu_test.c
index 612b76a3bc..b3ea3cf44c 100644
--- a/test/dtls_mtu_test.c
+++ b/test/dtls_mtu_test.c
@@ -168,7 +168,7 @@ static int run_mtu_tests(void)
         const char *cipher_name = SSL_CIPHER_get_name(cipher);
 
         /* As noted above, only one test for each enc/mac variant. */
-        if (strncmp(cipher_name, "PSK-", 4) != 0)
+        if (!HAS_PREFIX(cipher_name, "PSK-"))
             continue;
 
         if (!TEST_int_gt(ret = mtu_test(ctx, cipher_name, 0), 0))
diff --git a/test/evp_test.c b/test/evp_test.c
index 819371cc42..70996195f0 100644
--- a/test/evp_test.c
+++ b/test/evp_test.c
@@ -12,7 +12,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <ctype.h>
-#include "../e_os.h" /* strcasecmp */
+#include "../e_os.h" /* strcasecmp and strncasecmp */
 #include <openssl/evp.h>
 #include <openssl/pem.h>
 #include <openssl/err.h>
@@ -2382,33 +2382,27 @@ static int rand_test_parse(EVP_TEST *t,
         if (n > rdata->n)
             rdata->n = n;
         item = rdata->data + n;
-        if (strncmp(keyword, "Entropy.", sizeof("Entropy")) == 0)
+        if (HAS_PREFIX(keyword, "Entropy."))
             return parse_bin(value, &item->entropy, &item->entropy_len);
-        if (strncmp(keyword, "ReseedEntropy.", sizeof("ReseedEntropy")) == 0)
+        if (HAS_PREFIX(keyword, "ReseedEntropy."))
             return parse_bin(value, &item->reseed_entropy,
                              &item->reseed_entropy_len);
-        if (strncmp(keyword, "Nonce.", sizeof("Nonce")) == 0)
+        if (HAS_PREFIX(keyword, "Nonce."))
             return parse_bin(value, &item->nonce, &item->nonce_len);
-        if (strncmp(keyword, "PersonalisationString.",
-                    sizeof("PersonalisationString")) == 0)
+        if (HAS_PREFIX(keyword, "PersonalisationString."))
             return parse_bin(value, &item->pers, &item->pers_len);
-        if (strncmp(keyword, "ReseedAdditionalInput.",
-                    sizeof("ReseedAdditionalInput")) == 0)
+        if (HAS_PREFIX(keyword, "ReseedAdditionalInput."))
             return parse_bin(value, &item->reseed_addin,
                              &item->reseed_addin_len);
-        if (strncmp(keyword, "AdditionalInputA.",
-                    sizeof("AdditionalInputA")) == 0)
+        if (HAS_PREFIX(keyword, "AdditionalInputA."))
             return parse_bin(value, &item->addinA, &item->addinA_len);
-        if (strncmp(keyword, "AdditionalInputB.",
-                    sizeof("AdditionalInputB")) == 0)
+        if (HAS_PREFIX(keyword, "AdditionalInputB."))
             return parse_bin(value, &item->addinB, &item->addinB_len);
-        if (strncmp(keyword, "EntropyPredictionResistanceA.",
-                    sizeof("EntropyPredictionResistanceA")) == 0)
+        if (HAS_PREFIX(keyword, "EntropyPredictionResistanceA."))
             return parse_bin(value, &item->pr_entropyA, &item->pr_entropyA_len);
-        if (strncmp(keyword, "EntropyPredictionResistanceB.",
-                    sizeof("EntropyPredictionResistanceB")) == 0)
+        if (HAS_PREFIX(keyword, "EntropyPredictionResistanceB."))
             return parse_bin(value, &item->pr_entropyB, &item->pr_entropyB_len);
-        if (strncmp(keyword, "Output.", sizeof("Output")) == 0)
+        if (HAS_PREFIX(keyword, "Output."))
             return parse_bin(value, &item->output, &item->output_len);
     } else {
         if (strcmp(keyword, "Cipher") == 0)
@@ -2656,7 +2650,7 @@ static int kdf_test_parse(EVP_TEST *t,
 
     if (strcmp(keyword, "Output") == 0)
         return parse_bin(value, &kdata->output, &kdata->output_len);
-    if (strncmp(keyword, "Ctrl", 4) == 0)
+    if (HAS_PREFIX(keyword, "Ctrl"))
         return kdf_test_ctrl(t, kdata->ctx, value);
     return 0;
 }
@@ -2756,7 +2750,7 @@ static int pkey_kdf_test_parse(EVP_TEST *t,
 
     if (strcmp(keyword, "Output") == 0)
         return parse_bin(value, &kdata->output, &kdata->output_len);
-    if (strncmp(keyword, "Ctrl", 4) == 0)
+    if (HAS_PREFIX(keyword, "Ctrl"))
         return pkey_test_ctrl(t, kdata->ctx, value);
     return 0;
 }
@@ -3827,14 +3821,10 @@ void cleanup_tests(void)
     OSSL_LIB_CTX_free(libctx);
 }
 
-#define STR_STARTS_WITH(str, pre) strncasecmp(pre, str, strlen(pre)) == 0
-#define STR_ENDS_WITH(str, pre)                                                \
-strlen(str) < strlen(pre) ? 0 : (strcasecmp(pre, str + strlen(str) - strlen(pre)) == 0)
-
 static int is_digest_disabled(const char *name)
 {
 #ifdef OPENSSL_NO_BLAKE2
-    if (STR_STARTS_WITH(name, "BLAKE"))
+    if (HAS_CASE_PREFIX(name, "BLAKE"))
         return 1;
 #endif
 #ifdef OPENSSL_NO_MD2
@@ -3871,15 +3861,15 @@ static int is_digest_disabled(const char *name)
 static int is_pkey_disabled(const char *name)
 {
 #ifdef OPENSSL_NO_EC
-    if (STR_STARTS_WITH(name, "EC"))
+    if (HAS_CASE_PREFIX(name, "EC"))
         return 1;
 #endif
 #ifdef OPENSSL_NO_DH
-    if (STR_STARTS_WITH(name, "DH"))
+    if (HAS_CASE_PREFIX(name, "DH"))
         return 1;
 #endif
 #ifdef OPENSSL_NO_DSA
-    if (STR_STARTS_WITH(name, "DSA"))
+    if (HAS_CASE_PREFIX(name, "DSA"))
         return 1;
 #endif
     return 0;
@@ -3888,20 +3878,20 @@ static int is_pkey_disabled(const char *name)
 static int is_mac_disabled(const char *name)
 {
 #ifdef OPENSSL_NO_BLAKE2
-    if (STR_STARTS_WITH(name, "BLAKE2BMAC")
-        || STR_STARTS_WITH(name, "BLAKE2SMAC"))
+    if (HAS_CASE_PREFIX(name, "BLAKE2BMAC")
+        || HAS_CASE_PREFIX(name, "BLAKE2SMAC"))
         return 1;
 #endif
 #ifdef OPENSSL_NO_CMAC
-    if (STR_STARTS_WITH(name, "CMAC"))
+    if (HAS_CASE_PREFIX(name, "CMAC"))
         return 1;
 #endif
 #ifdef OPENSSL_NO_POLY1305
-    if (STR_STARTS_WITH(name, "Poly1305"))
+    if (HAS_CASE_PREFIX(name, "Poly1305"))
         return 1;
 #endif
 #ifdef OPENSSL_NO_SIPHASH
-    if (STR_STARTS_WITH(name, "SipHash"))
+    if (HAS_CASE_PREFIX(name, "SipHash"))
         return 1;
 #endif
     return 0;
@@ -3909,7 +3899,7 @@ static int is_mac_disabled(const char *name)
 static int is_kdf_disabled(const char *name)
 {
 #ifdef OPENSSL_NO_SCRYPT
-    if (STR_ENDS_WITH(name, "SCRYPT"))
+    if (HAS_CASE_SUFFIX(name, "SCRYPT"))
         return 1;
 #endif
     return 0;
@@ -3918,65 +3908,65 @@ static int is_kdf_disabled(const char *name)
 static int is_cipher_disabled(const char *name)
 {
 #ifdef OPENSSL_NO_ARIA
-    if (STR_STARTS_WITH(name, "ARIA"))
+    if (HAS_CASE_PREFIX(name, "ARIA"))
         return 1;
 #endif
 #ifdef OPENSSL_NO_BF
-    if (STR_STARTS_WITH(name, "BF"))
+    if (HAS_CASE_PREFIX(name, "BF"))
         return 1;
 #endif
 #ifdef OPENSSL_NO_CAMELLIA
-    if (STR_STARTS_WITH(name, "CAMELLIA"))
+    if (HAS_CASE_PREFIX(name, "CAMELLIA"))
         return 1;
 #endif
 #ifdef OPENSSL_NO_CAST
-    if (STR_STARTS_WITH(name, "CAST"))
+    if (HAS_CASE_PREFIX(name, "CAST"))
         return 1;
 #endif
 #ifdef OPENSSL_NO_CHACHA
-    if (STR_STARTS_WITH(name, "CHACHA"))
+    if (HAS_CASE_PREFIX(name, "CHACHA"))
         return 1;
 #endif
 #ifdef OPENSSL_NO_POLY1305
-    if (STR_ENDS_WITH(name, "Poly1305"))
+    if (HAS_CASE_SUFFIX(name, "Poly1305"))
         return 1;
 #endif
 #ifdef OPENSSL_NO_DES
-    if (STR_STARTS_WITH(name, "DES"))
+    if (HAS_CASE_PREFIX(name, "DES"))
         return 1;
-    if (STR_ENDS_WITH(name, "3DESwrap"))
+    if (HAS_CASE_SUFFIX(name, "3DESwrap"))
         return 1;
 #endif
 #ifdef OPENSSL_NO_OCB
-    if (STR_ENDS_WITH(name, "OCB"))
+    if (HAS_CASE_SUFFIX(name, "OCB"))
         return 1;
 #endif
 #ifdef OPENSSL_NO_IDEA
-    if (STR_STARTS_WITH(name, "IDEA"))
+    if (HAS_CASE_PREFIX(name, "IDEA"))
         return 1;
 #endif
 #ifdef OPENSSL_NO_RC2
-    if (STR_STARTS_WITH(name, "RC2"))
+    if (HAS_CASE_PREFIX(name, "RC2"))
         return 1;
 #endif
 #ifdef OPENSSL_NO_RC4
-    if (STR_STARTS_WITH(name, "RC4"))
+    if (HAS_CASE_PREFIX(name, "RC4"))
         return 1;
 #endif
 #ifdef OPENSSL_NO_RC5
-    if (STR_STARTS_WITH(name, "RC5"))
+    if (HAS_CASE_PREFIX(name, "RC5"))
         return 1;
 #endif
 #ifdef OPENSSL_NO_SEED
-    if (STR_STARTS_WITH(name, "SEED"))
+    if (HAS_CASE_PREFIX(name, "SEED"))
         return 1;
 #endif
 #ifdef OPENSSL_NO_SIV
-    if (STR_ENDS_WITH(name, "SIV"))
+    if (HAS_CASE_SUFFIX(name, "SIV"))
         return 1;
 #endif
 #ifdef OPENSSL_NO_SM4
-    if (STR_STARTS_WITH(name, "SM4"))
+    if (HAS_CASE_PREFIX(name, "SM4"))
         return 1;
 #endif
     return 0;
diff --git a/test/helpers/handshake.c b/test/helpers/handshake.c
index 780a71b21b..7171f90473 100644
--- a/test/helpers/handshake.c
+++ b/test/helpers/handshake.c
@@ -174,7 +174,7 @@ static int client_hello_select_server_ctx(SSL *s, void *arg, int ignore)
     remaining = len;
     servername = (const char *)p;
 
-    if (len == strlen("server2") && strncmp(servername, "server2", len) == 0) {
+    if (len == strlen("server2") && HAS_PREFIX(servername, "server2")) {
         SSL_CTX *new_ctx = arg;
         SSL_set_SSL_CTX(s, new_ctx);
         /*
@@ -188,7 +188,7 @@ static int client_hello_select_server_ctx(SSL *s, void *arg, int ignore)
         ex_data->servername = SSL_TEST_SERVERNAME_SERVER2;
         return 1;
     } else if (len == strlen("server1") &&
-               strncmp(servername, "server1", len) == 0) {
+               HAS_PREFIX(servername, "server1")) {
         ex_data->servername = SSL_TEST_SERVERNAME_SERVER1;
         return 1;
     } else if (ignore) {
diff --git a/test/http_test.c b/test/http_test.c
index edf995eb03..d684c5eb18 100644
--- a/test/http_test.c
+++ b/test/http_test.c
@@ -41,15 +41,12 @@ static int mock_http_server(BIO *in, BIO *out, char version, int keep_alive,
     const char *req, *path;
     long count = BIO_get_mem_data(in, (unsigned char **)&req);
     const char *hdr = (char *)req;
-    int is_get = count >= 4 && strncmp(hdr, "GET ", 4) == 0;
     int len;
+    int is_get = count >= 4 && CHECK_AND_SKIP_PREFIX(hdr, "GET ");
 
     /* first line should contain "(GET|POST) <path> HTTP/1.x" */
-    if (is_get)
-        hdr += 4;
-    else if (TEST_true(count >= 5 && strncmp(hdr, "POST ", 5) == 0))
-        hdr += 5;
-    else
+    if (!is_get
+            && !(TEST_true(count >= 5 && CHECK_AND_SKIP_PREFIX(hdr, "POST "))))
         return 0;
 
     path = hdr;
@@ -69,7 +66,7 @@ static int mock_http_server(BIO *in, BIO *out, char version, int keep_alive,
     if (count < 0 || out == NULL)
         return 0;
 
-    if (strncmp(path, RPATH, strlen(RPATH)) != 0) {
+    if (!HAS_PREFIX(path, RPATH)) {
         if (!is_get)
             return 0;
         return BIO_printf(out, "HTTP/1.%c 301 Moved Permanently\r\n"
@@ -94,10 +91,9 @@ static int mock_http_server(BIO *in, BIO *out, char version, int keep_alive,
             return BIO_puts(out, txt);
         return ASN1_item_i2d_bio(it, out, rsp);
     } else {
-        len = strlen("Connection: ");
-        if (strncmp(hdr, "Connection: ", len) == 0) {
+        if (CHECK_AND_SKIP_PREFIX(hdr, "Connection: ")) {
             /* skip req Connection header */
-            hdr = strstr(hdr + len, "\r\n");
+            hdr = strstr(hdr, "\r\n");
             if (hdr == NULL)
                 return 0;
             hdr += 2;
diff --git a/test/ssl_old_test.c b/test/ssl_old_test.c
index adeb010201..e7ac6dfba4 100644
--- a/test/ssl_old_test.c
+++ b/test/ssl_old_test.c
@@ -1009,7 +1009,7 @@ int main(int argc, char *argv[])
             dtls12 = 1;
         } else if (strcmp(*argv, "-dtls") == 0) {
             dtls = 1;
-        } else if (strncmp(*argv, "-num", 4) == 0) {
+        } else if (HAS_PREFIX(*argv, "-num")) {
             if (--argc < 1)
                 goto bad;
             number = atoi(*(++argv));
diff --git a/test/testutil.h b/test/testutil.h
index c28df702cc..52fb17c3c6 100644
--- a/test/testutil.h
+++ b/test/testutil.h
@@ -11,6 +11,7 @@
 # define OSSL_TESTUTIL_H
 
 # include <stdarg.h>
+# include "internal/common.h" /* for HAS_PREFIX */
 
 # include <openssl/provider.h>
 # include <openssl/err.h>
diff --git a/test/testutil/stanza.c b/test/testutil/stanza.c
index ba62f84517..a3f833a543 100644
--- a/test/testutil/stanza.c
+++ b/test/testutil/stanza.c
@@ -54,7 +54,7 @@ static int read_key(STANZA *s)
         s->curr++;
         if (!TEST_int_gt(BIO_puts(s->key, tmpbuf), 0))
             return 0;
-        if (strncmp(tmpbuf, "-----END", 8) == 0)
+        if (HAS_PREFIX(tmpbuf, "-----END"))
             return 1;
     }
     TEST_error("Can't find key end");


More information about the openssl-commits mailing list