diff --git a/tests/api.c b/tests/api.c index a1fb0165b..43798fa50 100644 --- a/tests/api.c +++ b/tests/api.c @@ -46604,9 +46604,117 @@ static void test_EVP_blake2() AssertIntEQ(XSTRNCMP(md, "BLAKE2S256", XSTRLEN("BLAKE2S256")), 0); #endif printf(resultFmt, passed); - #endif } + +#if defined(OPENSSL_EXTRA) +static void list_md_fn(const EVP_MD* m, const char* from, + const char* to, void* arg) +{ + const char* mn; + BIO *bio; + + (void) from; + (void) to; + (void) arg; + (void) mn; + (void) bio; + + if (!m) { + /* alias */ + AssertNull(m); + AssertNotNull(to); + } + else { + AssertNotNull(m); + AssertNull(to); + } + + AssertNotNull(from); + +#if !defined(NO_FILESYSTEM) && defined(DEBUG_WOLFSSL_VERBOSE) + mn = EVP_get_digestbyname(from); + /* print to stdout */ + AssertNotNull(arg); + + bio = BIO_new(BIO_s_file()); + BIO_set_fp(bio, arg, BIO_NOCLOSE); + BIO_printf(bio, "Use %s message digest algorithm\n", mn); + BIO_free(bio); +#endif +} +#endif + +static void test_EVP_MD_do_all() +{ +#if defined(OPENSSL_EXTRA) + printf(testingFmt, "test_EVP_MD_do_all"); + + EVP_MD_do_all(NULL, stdout); + /* to confirm previous call gives no harm */ + AssertTrue(1); + + + EVP_MD_do_all(list_md_fn, stdout); + /* to confirm previous call gives no harm */ + AssertTrue(1); + + printf(resultFmt, passed); +#endif +} + +#if defined(OPENSSL_EXTRA) +static void obj_name_t(const OBJ_NAME* nm, void* arg) +{ + (void)arg; + (void)nm; + + AssertIntGT(nm->type, OBJ_NAME_TYPE_UNDEF); + +#if !defined(NO_FILESYSTEM) && defined(DEBUG_WOLFSSL_VERBOSE) + /* print to stdout */ + AssertNotNull(arg); + + bio = BIO_new(BIO_s_file()); + BIO_set_fp(bio, arg, BIO_NOCLOSE); + BIO_printf(bio, "%s\n", mn); + BIO_free(bio); +#endif +} + +#endif +static void test_OBJ_NAME_do_all() +{ +#if defined(OPENSSL_EXTRA) + printf(testingFmt, "test_OBJ_NAME_do_all"); + + OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, NULL, NULL); + /* to confirm previous call gives no harm */ + AssertTrue(1); + + OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, NULL, stdout); + /* to confirm previous call gives no harm */ + AssertTrue(1); + + OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, obj_name_t, stdout); + AssertTrue(1); + OBJ_NAME_do_all(OBJ_NAME_TYPE_PKEY_METH, obj_name_t, stdout); + AssertTrue(1); + OBJ_NAME_do_all(OBJ_NAME_TYPE_COMP_METH, obj_name_t, stdout); + AssertTrue(1); + OBJ_NAME_do_all(OBJ_NAME_TYPE_NUM, obj_name_t, stdout); + AssertTrue(1); + OBJ_NAME_do_all(OBJ_NAME_TYPE_UNDEF, obj_name_t, stdout); + AssertTrue(1); + OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, obj_name_t, stdout); + AssertTrue(1); + OBJ_NAME_do_all(-1, obj_name_t, stdout); + AssertTrue(1); + + printf(resultFmt, passed); +#endif +} + /*----------------------------------------------------------------------------* | Main *----------------------------------------------------------------------------*/ @@ -46631,6 +46739,8 @@ void ApiTest(void) test_wolfSSL_EVP_shake128(); test_wolfSSL_EVP_shake256(); test_EVP_blake2(); + test_EVP_MD_do_all(); + test_OBJ_NAME_do_all(); test_wolfSSL_CTX_use_certificate_file(); AssertIntEQ(test_wolfSSL_CTX_use_certificate_buffer(), WOLFSSL_SUCCESS); test_wolfSSL_CTX_use_PrivateKey_file(); diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index afaf7dd85..acd217bba 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -3540,25 +3540,20 @@ int wolfSSL_EVP_Digest(const unsigned char* in, int inSz, unsigned char* out, return WOLFSSL_SUCCESS; } +static const struct alias { + const char *name; + const char *alias; +} alias_tbl[] = +{ + {"MD4", "ssl3-md4"}, + {"MD5", "ssl3-md5"}, + {"SHA1", "ssl3-sha1"}, + {"SHA1", "SHA"}, + { NULL, NULL} +}; + const WOLFSSL_EVP_MD *wolfSSL_EVP_get_digestbyname(const char *name) { - static const struct alias { - const char *name; - const char *alias; - } alias_tbl[] = - { - {"MD4", "ssl3-md4"}, - {"MD5", "ssl3-md5"}, - {"SHA1", "ssl3-sha1"}, - {"SHA1", "SHA"}, -#ifdef HAVE_BLAKE2 - {"BLAKE2b512", "blake2b512"}, -#endif -#ifdef HAVE_BLAKE2S - {"BLAKE2s256", "blake2s256"}, -#endif - { NULL, NULL} - }; char nameUpper[15]; /* 15 bytes should be enough for any name */ size_t i; @@ -3968,7 +3963,112 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) } return (WOLFSSL_EVP_MD *)NULL; } - + + /* return alias name if has + * @param n message digest type name + * @return alias name, otherwise NULL + */ + static const char* hasAliasName(const char* n) + { + + const char* aliasnm = NULL; + const struct alias *al; + + for (al = alias_tbl; al->name != NULL; al++) + if(XSTRNCMP(n, al->name, XSTRLEN(al->name)+1) == 0) { + aliasnm = al->alias; + break; + } + + return aliasnm; + } + + + struct do_all_md { + void *arg; + void (*fn) (const WOLFSSL_EVP_MD *m, + const char* from, const char* to, void *arg); + }; + + /* do all md algorithm + * @param nm a pointer to WOLFSSL_OBJ_NAME + * @param arg arguments to pass to the callback + * @return none + */ + static void md_do_all_func(const WOLFSSL_OBJ_NAME* nm, void* arg) + { + struct do_all_md *md = (struct do_all_md*)arg; + + const char* alias = NULL; + const struct s_ent *ent; + + /* sanity check */ + if (md == NULL || nm == NULL || md->fn == NULL || + nm->type != WOLFSSL_OBJ_NAME_TYPE_MD_METH) + return; + + /* loop all md */ + for (ent = md_tbl; ent->name != NULL; ent++){ + /* check if the md has alias */ + if((alias = hasAliasName(ent->name)) != NULL) { + md->fn(NULL, ent->name, ent->name, md->arg); + } + else { + md->fn(ent->name, ent->name, NULL, md->arg); + } + } + } + + /* call md_do_all function to do all md algorithm via a callback function + * @param fn a callback function to be called with all 'md' + * @param args arguments to pass to the callback + * @return none + */ + void wolfSSL_EVP_MD_do_all(void (*fn) (const WOLFSSL_EVP_MD *m, + const char* from, const char* to, void* xx), void* args) + { + struct do_all_md md; + + md.fn = fn; + md.arg = args; + + wolfSSL_OBJ_NAME_do_all(WOLFSSL_OBJ_NAME_TYPE_MD_METH, + md_do_all_func, &md); + } + + /* call "fn" based on OBJ_NAME type + * @param type OBJ_NAME type + * @param fn a callback function + * @param args arguments to pass to the callback + * @return none + */ + void wolfSSL_OBJ_NAME_do_all(int type, + void (*fn)(const WOLFSSL_OBJ_NAME*, void* arg), void* arg) + { + WOLFSSL_OBJ_NAME objnm; + + /* sanity check */ + if (!fn) + return; + + objnm.type = type; + + switch(type) { + case WOLFSSL_OBJ_NAME_TYPE_MD_METH: + fn(&objnm, arg); + break; + case WOLFSSL_OBJ_NAME_TYPE_CIPHER_METH: + case WOLFSSL_OBJ_NAME_TYPE_PKEY_METH: + case WOLFSSL_OBJ_NAME_TYPE_COMP_METH: + case WOLFSSL_OBJ_NAME_TYPE_NUM: + WOLFSSL_MSG("not implemented"); + FALL_THROUGH; + case WOLFSSL_OBJ_NAME_TYPE_UNDEF: + default: + break; + } + } + #ifndef NO_AES #ifdef HAVE_AES_CBC diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 4137f63c0..49491f417 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -694,6 +694,10 @@ WOLFSSL_API int wolfSSL_PKCS5_PBKDF2_HMAC(const char *pass, int passlen, WOLFSSL_LOCAL int wolfSSL_EVP_get_hashinfo(const WOLFSSL_EVP_MD* evp, int* pHash, int* pHashSz); +WOLFSSL_API void wolfSSL_EVP_MD_do_all(void (*fn) (const WOLFSSL_EVP_MD *md, + const char* from, const char* to, + void* xx), void* args); + #define EVP_CIPH_STREAM_CIPHER WOLFSSL_EVP_CIPH_STREAM_CIPHER #define EVP_CIPH_ECB_MODE WOLFSSL_EVP_CIPH_ECB_MODE #define EVP_CIPH_CBC_MODE WOLFSSL_EVP_CIPH_CBC_MODE @@ -1025,6 +1029,7 @@ typedef WOLFSSL_ASN1_PCTX ASN1_PCTX; #define EVP_blake2b512 wolfSSL_EVP_blake2b512 #define EVP_blake2s256 wolfSSL_EVP_blake2s256 +#define EVP_MD_do_all wolfSSL_EVP_MD_do_all WOLFSSL_API void printPKEY(WOLFSSL_EVP_PKEY *k); diff --git a/wolfssl/openssl/objects.h b/wolfssl/openssl/objects.h index 3f975432b..ba79c48b4 100644 --- a/wolfssl/openssl/objects.h +++ b/wolfssl/openssl/objects.h @@ -34,6 +34,14 @@ extern "C" { #endif +#define OBJ_NAME_TYPE_UNDEF WOLFSSL_OBJ_NAME_TYPE_UNDEF +#define OBJ_NAME_TYPE_MD_METH WOLFSSL_OBJ_NAME_TYPE_MD_METH +#define OBJ_NAME_TYPE_CIPHER_METH WOLFSSL_OBJ_NAME_TYPE_CIPHER_METH +#define OBJ_NAME_TYPE_PKEY_METH WOLFSSL_OBJ_NAME_TYPE_PKEY_METH +#define OBJ_NAME_TYPE_COMP_METH WOLFSSL_OBJ_NAME_TYPE_COMP_METH +#define OBJ_NAME_TYPE_NUM WOLFSSL_OBJ_NAME_TYPE_NUM +#define OBJ_NAME_ALIAS WOLFSSL_OBJ_NAME_ALIAS + #define OBJ_nid2sn wolfSSL_OBJ_nid2sn #define OBJ_obj2nid wolfSSL_OBJ_obj2nid #define OBJ_sn2nid wolfSSL_OBJ_sn2nid @@ -47,6 +55,7 @@ #define OBJ_cmp wolfSSL_OBJ_cmp #define OBJ_create wolfSSL_OBJ_create #define ASN1_OBJECT_free wolfSSL_ASN1_OBJECT_free +#define OBJ_NAME_do_all wolfSSL_OBJ_NAME_do_all /* not required for wolfSSL */ #define OPENSSL_load_builtin_modules() diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 0c0e73418..14843fd2b 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -111,6 +111,7 @@ typedef WOLFSSL_dynlock_value CRYPTO_dynlock_value; typedef WOLFSSL_BUF_MEM BUF_MEM; typedef WOLFSSL_GENERAL_NAMES GENERAL_NAMES; typedef WOLFSSL_GENERAL_NAME GENERAL_NAME; +typedef WOLFSSL_OBJ_NAME OBJ_NAME; #define X509_L_FILE_LOAD WOLFSSL_X509_L_FILE_LOAD #define X509_L_ADD_DIR WOLFSSL_X509_L_ADD_DIR diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 600a426c6..290737337 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -197,6 +197,7 @@ typedef struct WOLFSSL_ASN1_OBJECT WOLFSSL_ASN1_OBJECT; typedef struct WOLFSSL_ASN1_OTHERNAME WOLFSSL_ASN1_OTHERNAME; typedef struct WOLFSSL_X509V3_CTX WOLFSSL_X509V3_CTX; typedef struct WOLFSSL_v3_ext_method WOLFSSL_v3_ext_method; +typedef struct WOLFSSL_OBJ_NAME WOLFSSL_OBJ_NAME; typedef struct WOLFSSL_ASN1_STRING WOLFSSL_ASN1_STRING; typedef struct WOLFSSL_dynlock_value WOLFSSL_dynlock_value; @@ -217,6 +218,10 @@ typedef struct WOLFSSL_CONF_CTX WOLFSSL_CONF_CTX; #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) +struct WOLFSSL_OBJ_NAME { + int type; +}; + struct WOLFSSL_AUTHORITY_KEYID { WOLFSSL_ASN1_STRING *keyid; WOLFSSL_ASN1_OBJECT *issuer; @@ -3692,6 +3697,18 @@ WOLFSSL_API int wolfSSL_OBJ_create(const char *oid, const char *sn, const char * #ifdef HAVE_ECC WOLFSSL_LOCAL int NIDToEccEnum(int n); #endif + +#define WOLFSSL_OBJ_NAME_TYPE_UNDEF 0x00 +#define WOLFSSL_OBJ_NAME_TYPE_MD_METH 0x01 +#define WOLFSSL_OBJ_NAME_TYPE_CIPHER_METH 0x02 +#define WOLFSSL_OBJ_NAME_TYPE_PKEY_METH 0x03 +#define WOLFSSL_OBJ_NAME_TYPE_COMP_METH 0x04 +#define WOLFSSL_OBJ_NAME_TYPE_NUM 0x05 +#define WOLFSSL_OBJ_NAME_ALIAS 0x8000 + +WOLFSSL_API void wolfSSL_OBJ_NAME_do_all(int type, + void (*fn) (const WOLFSSL_OBJ_NAME* , void *arg), + void* arg); /* end of object functions */ WOLFSSL_API unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line);