Add and use HAS_CASE_PREFIX(), CHECK_AND_SKIP_CASE_PREFIX(), and HAS_CASE_SUFFIX()
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>
Thu, 24 Jun 2021 08:29:37 +0000 (10:29 +0200)
committerDr. David von Oheimb <David.von.Oheimb@siemens.com>
Wed, 17 Nov 2021 14:48:37 +0000 (15:48 +0100)
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15847)

apps/cmp.c
apps/include/engine_loader.h
apps/lib/apps.c
apps/lib/engine_loader.c
apps/rehash.c
crypto/x509/v3_utl.c
engines/e_loader_attic.c
engines/e_ossltest.c
include/internal/cryptlib.h
providers/implementations/storemgmt/file_store.c
test/evp_test.c

index ae3488553ab96f2c30f495a91453572b350233c9..589cce126650fa1cbb733bcefbda24e3e0ffb907 100644 (file)
@@ -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') {
index 11598639a5f6882e16a38afe8cd8cbbc7951382e..97c176c6c83554573f41448d263b9f6105a08167 100644 (file)
@@ -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);
index 2c4c292b94373a933c2b32e6bb43c55efa01a94d..01feedaf3f5043eee9377e9bd4dbb80c64fd8cca 100644 (file)
@@ -680,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;
     }
index 2b4480000cc640934ca5fb2de8ed1b9a4301ed2c..7ea05943f380d08b7758592af961334de81f84e2 100644 (file)
@@ -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, ':');
index 7fe01de11c0b6ccff81f617f7f51d08dc0e03417..e0cdc9bc622f99282cc78cf6f8d1a4e7c6a95116 100644 (file)
@@ -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);
index a70917a39bde0370b701f40080ae846c9b610f16..5704820e504eb0b63719dadb16a09f2bd2da04cb 100644 (file)
@@ -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] == '.') {
index 74f297400b420329ee6dd8a25ca7d1c687662bd7..e5557df627adf2309faa3bdd520f40c391dbb875 100644 (file)
@@ -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>
 
 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
@@ -945,6 +940,7 @@ static int file_find_type(OSSL_STORE_LOADER_CTX *ctx)
     return 1;
 }
 
+/* This function has quite some overlap with providers/implementations/storemgmt/file_store.c */
 static OSSL_STORE_LOADER_CTX *file_open_ex
     (const OSSL_STORE_LOADER *loader, const char *uri,
      OSSL_LIB_CTX *libctx, const char *propq,
@@ -957,7 +953,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 +962,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 +982,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]);
 
index df0805b1970d7d02efbd197ef76d7a39385d5a4b..5b25a0eaf18c8b6a50cccdb116c4822f630b1333 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include "internal/cryptlib.h"
 
 #include <openssl/engine.h>
 #include <openssl/sha.h>
 
 #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);
index 1b700639d9776a0af71cbd59012ee63ec5f02b44..00d156f34ddadcf1f37d5a3bd55e9040b1f055c0 100644 (file)
@@ -13,6 +13,7 @@
 
 # include <stdlib.h>
 # include <string.h>
+# include "../../e_os.h" /* To get strncasecmp() on Windows */
 
 # ifdef OPENSSL_USE_APPLINK
 #  define BIO_FLAGS_UPLINK_INTERNAL 0x8000
@@ -45,11 +46,20 @@ __owur static ossl_inline int ossl_assert_int(int expr, const char *exprstr,
 
 #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 the str ptr past the prefix */
-# define CHECK_AND_SKIP_PREFIX(str, pre) \
+/* 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
index 1059c1217d9503b16e3324816c59a4b4d5201112..59d4e084ce5566d7a2491c5685c457bfc28263ad 100644 (file)
@@ -169,6 +169,7 @@ static struct file_ctx_st *file_open_stream(BIO *source, const char *uri,
     return NULL;
 }
 
+/* This function has quite some overlap with engines/e_loader_attic.c */
 static void *file_open_dir(const char *path, const char *uri, void *provctx)
 {
     struct file_ctx_st *ctx;
@@ -203,7 +204,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,19 +216,19 @@ 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 (CHECK_AND_SKIP_PREFIX(p, "//")) {
+    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(p, "localhost/", 10) == 0) {
-                p += sizeof("localhost") - 1;
-            } else if (*p != '/') {
+            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);
                 return NULL;
@@ -236,7 +237,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]);
 
index 71a54422b802c18d30b0e540f2026a7bfa0ee3da..70996195f0cbb32d862514694233547f541e5530 100644 (file)
@@ -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>
@@ -3821,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
@@ -3865,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;
@@ -3882,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;
@@ -3903,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;
@@ -3912,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;