diff options
author | Pauli <paul.dale@oracle.com> | 2018-09-04 07:35:45 +1000 |
---|---|---|
committer | Pauli <paul.dale@oracle.com> | 2018-09-04 07:35:45 +1000 |
commit | fc196a5eb97dc3a5465c37a6761428ddd81b023d (patch) | |
tree | 47b5116217bcab42d2b3e6fa1084cd67d7332480 | |
parent | 2d28a42f899c2f5e03b0e49a660ed3c1f744e7a3 (diff) |
Make OBJ_NAME case insensitive.
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/7089)
-rw-r--r-- | crypto/include/internal/lhash.h | 15 | ||||
-rw-r--r-- | crypto/lhash/lhash.c | 23 | ||||
-rw-r--r-- | crypto/objects/o_names.c | 29 | ||||
-rw-r--r-- | test/recipes/30-test_evp.t | 3 | ||||
-rw-r--r-- | test/recipes/30-test_evp_data/evpcase.txt | 54 |
5 files changed, 108 insertions, 16 deletions
diff --git a/crypto/include/internal/lhash.h b/crypto/include/internal/lhash.h new file mode 100644 index 0000000000..200ba8685d --- /dev/null +++ b/crypto/include/internal/lhash.h @@ -0,0 +1,15 @@ +/* + * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (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 INTERNAL_LHASH_H +# define INTERNAL_LHASH_H + +unsigned long openssl_lh_strcasehash(const char *); + +#endif diff --git a/crypto/lhash/lhash.c b/crypto/lhash/lhash.c index f7ac9d02f5..8d9f933df3 100644 --- a/crypto/lhash/lhash.c +++ b/crypto/lhash/lhash.c @@ -13,6 +13,8 @@ #include <openssl/crypto.h> #include <openssl/lhash.h> #include <openssl/err.h> +#include "internal/ctype.h" +#include "internal/lhash.h" #include "lhash_lcl.h" /* @@ -349,6 +351,27 @@ unsigned long OPENSSL_LH_strhash(const char *c) return (ret >> 16) ^ ret; } +unsigned long openssl_lh_strcasehash(const char *c) +{ + unsigned long ret = 0; + long n; + unsigned long v; + int r; + + if (c == NULL || *c == '\0') + return ret; + + for (n = 0x100; *c != '\0'; n += 0x100) { + v = n | ossl_tolower(*c); + r = (int)((v >> 2) ^ v) & 0x0f; + ret = (ret << r) | (ret >> (32 - r)); + ret &= 0xFFFFFFFFL; + ret ^= v * v; + c++; + } + return (ret >> 16) ^ ret; +} + unsigned long OPENSSL_LH_num_items(const OPENSSL_LHASH *lh) { return lh ? lh->num_items : 0; diff --git a/crypto/objects/o_names.c b/crypto/objects/o_names.c index 8f7bc79346..c4355370cb 100644 --- a/crypto/objects/o_names.c +++ b/crypto/objects/o_names.c @@ -17,26 +17,25 @@ #include <openssl/safestack.h> #include <openssl/e_os2.h> #include "internal/thread_once.h" +#include "internal/lhash.h" #include "obj_lcl.h" +#include "e_os.h" /* * We define this wrapper for two reasons. Firstly, later versions of * DEC C add linkage information to certain functions, which makes it * tricky to use them as values to regular function pointers. - * Secondly, in the EDK2 build environment, the strcmp function is - * actually an external function (AsciiStrCmp) with the Microsoft ABI, - * so we can't transparently assign function pointers to it. - * Arguably the latter is a stupidity of the UEFI environment, but - * since the wrapper solves the DEC C issue too, let's just use the - * same solution. + * Secondly, in the EDK2 build environment, the strcasecmp function is + * actually an external function with the Microsoft ABI, so we can't + * transparently assign function pointers to it. */ #if defined(OPENSSL_SYS_VMS_DECC) || defined(OPENSSL_SYS_UEFI) -static int obj_strcmp(const char *a, const char *b) +static int obj_strcasecmp(const char *a, const char *b) { - return strcmp(a, b); + return strcasecmp(a, b); } #else -#define obj_strcmp strcmp +#define obj_strcasecmp strcasecmp #endif /* @@ -111,8 +110,8 @@ int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *), ret = 0; goto out; } - name_funcs->hash_func = OPENSSL_LH_strhash; - name_funcs->cmp_func = obj_strcmp; + name_funcs->hash_func = openssl_lh_strcasehash; + name_funcs->cmp_func = obj_strcasecmp; CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); push = sk_NAME_FUNCS_push(name_funcs_stack, name_funcs); @@ -149,7 +148,7 @@ static int obj_name_cmp(const OBJ_NAME *a, const OBJ_NAME *b) ret = sk_NAME_FUNCS_value(name_funcs_stack, a->type)->cmp_func(a->name, b->name); } else - ret = strcmp(a->name, b->name); + ret = strcasecmp(a->name, b->name); } return ret; } @@ -164,7 +163,7 @@ static unsigned long obj_name_hash(const OBJ_NAME *a) sk_NAME_FUNCS_value(name_funcs_stack, a->type)->hash_func(a->name); } else { - ret = OPENSSL_LH_strhash(a->name); + ret = openssl_lh_strcasehash(a->name); } ret ^= a->type; return ret; @@ -214,8 +213,6 @@ int OBJ_NAME_add(const char *name, int type, const char *data) if (!OBJ_NAME_init()) return 0; - CRYPTO_THREAD_write_lock(obj_lock); - alias = type & OBJ_NAME_ALIAS; type &= ~OBJ_NAME_ALIAS; @@ -230,6 +227,8 @@ int OBJ_NAME_add(const char *name, int type, const char *data) onp->type = type; onp->data = data; + CRYPTO_THREAD_write_lock(obj_lock); + ret = lh_OBJ_NAME_insert(names_lh, onp); if (ret != NULL) { /* free things */ diff --git a/test/recipes/30-test_evp.t b/test/recipes/30-test_evp.t index 4fca366271..d8e11e2505 100644 --- a/test/recipes/30-test_evp.t +++ b/test/recipes/30-test_evp.t @@ -15,7 +15,8 @@ use OpenSSL::Test qw/:DEFAULT data_file/; setup("test_evp"); my @files = ( "evpciph.txt", "evpdigest.txt", "evpencod.txt", "evpkdf.txt", - "evpmac.txt", "evppbe.txt", "evppkey.txt", "evppkey_ecc.txt" ); + "evpmac.txt", "evppbe.txt", "evppkey.txt", "evppkey_ecc.txt", + "evpcase.txt" ); plan tests => scalar(@files); diff --git a/test/recipes/30-test_evp_data/evpcase.txt b/test/recipes/30-test_evp_data/evpcase.txt new file mode 100644 index 0000000000..69828eec51 --- /dev/null +++ b/test/recipes/30-test_evp_data/evpcase.txt @@ -0,0 +1,54 @@ +# +# Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the OpenSSL license (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 + +# Tests start with one of these keywords +# Cipher Decrypt Derive Digest Encoding KDF MAC PBE +# PrivPubKeyPair Sign Verify VerifyRecover +# and continue until a blank line. Lines starting with a pound sign, +# like this prolog, are ignored. + +# These tests exercise the case insensitive handling of object names. +# They are contrived + +Title = Case insensitive AES tests + +Cipher = Aes-128-eCb +Key = 2B7E151628AED2A6ABF7158809CF4F3C +Plaintext = 6BC1BEE22E409F96E93D7E117393172A +Ciphertext = 3AD77BB40D7A3660A89ECAF32466EF97 + +Cipher = AeS-128-cbC +Key = 2B7E151628AED2A6ABF7158809CF4F3C +IV = 73BED6B8E3C1743B7116E69E22229516 +Plaintext = F69F2445DF4F9B17AD2B417BE66C3710 +Ciphertext = 3FF1CAA1681FAC09120ECA307586E1A7 + +Cipher = aES-128-CTR +Key = AE6852F8121067CC4BF7A5765577F39E +IV = 00000030000000000000000000000001 +Operation = ENCRYPT +Plaintext = 53696E676C6520626C6F636B206D7367 +Ciphertext = E4095D4FB7A7B3792D6175A3261311B8 + +Cipher = AES-128-GcM +Key = 00000000000000000000000000000000 +IV = 000000000000000000000000 +AAD = +Tag = ab6e47d42cec13bdf53a67b21257bddf +Plaintext = 00000000000000000000000000000000 +Ciphertext = 0388dace60b6a392f328c2b971b2fe78 + +Title = Case insensitive digest tests + +Digest = Sha3-256 +Input = "" +Output = A7FFC6F8BF1ED76651C14756A061D662F580FF4DE43B49FA82D80A4B80F8434A + +Digest = shA512 +Input = "abc" +Output = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f |