diff --git a/CHANGES b/CHANGES index 21ec6437c58311bbff8eda2b1808c935d6927c97..b89c2c96c06e926a84120283ec8bdd2fce71fee3 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,12 @@ Changes between 0.9.8b and 0.9.9 [xx XXX xxxx] + *) New functions EVP_CIPHER_do_all(), EVP_CIPHER_do_all_sorted(), + EVP_MD_do_all() and EVP_MD_do_all_sorted() to enumerate internal + digest and cipher tables. New options added to openssl utility: + list-message-digest-algorithms and list-cipher-algorithms. + [Steve Henson] + *) In addition to the numerical (unsigned long) thread ID, provide for a pointer (void *) thread ID. This helps accomodate systems that do not provide an unsigned long thread ID. OpenSSL assumes diff --git a/apps/openssl.c b/apps/openssl.c index f996bb3e184efb6ce5a9753a2ee75c10982f4123..4d5c95f640469114d9fdf3a3760961beff419f96 100644 --- a/apps/openssl.c +++ b/apps/openssl.c @@ -142,6 +142,8 @@ static int MS_CALLBACK cmp(const void *a_void,const void *b_void); static LHASH *prog_init(void ); static int do_cmd(LHASH *prog,int argc,char *argv[]); static void list_pkey(BIO *out); +static void list_cipher(BIO *out); +static void list_md(BIO *out); char *default_config_file=NULL; /* Make sure there is only one when MONOLITH is defined */ @@ -367,9 +369,12 @@ end: #define LIST_STANDARD_COMMANDS "list-standard-commands" #define LIST_MESSAGE_DIGEST_COMMANDS "list-message-digest-commands" +#define LIST_MESSAGE_DIGEST_ALGORITHMS "list-message-digest-algorithms" #define LIST_CIPHER_COMMANDS "list-cipher-commands" +#define LIST_CIPHER_ALGORITHMS "list-cipher-algorithms" #define LIST_PUBLIC_KEY_ALGORITHMS "list-public-key-algorithms" + static int do_cmd(LHASH *prog, int argc, char *argv[]) { FUNCTION f,*fp; @@ -411,7 +416,9 @@ static int do_cmd(LHASH *prog, int argc, char *argv[]) } else if ((strcmp(argv[0],LIST_STANDARD_COMMANDS) == 0) || (strcmp(argv[0],LIST_MESSAGE_DIGEST_COMMANDS) == 0) || + (strcmp(argv[0],LIST_MESSAGE_DIGEST_ALGORITHMS) == 0) || (strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0) || + (strcmp(argv[0],LIST_CIPHER_ALGORITHMS) == 0) || (strcmp(argv[0],LIST_PUBLIC_KEY_ALGORITHMS) == 0)) { int list_type; @@ -421,8 +428,12 @@ static int do_cmd(LHASH *prog, int argc, char *argv[]) list_type = FUNC_TYPE_GENERAL; else if (strcmp(argv[0],LIST_MESSAGE_DIGEST_COMMANDS) == 0) list_type = FUNC_TYPE_MD; + else if (strcmp(argv[0],LIST_MESSAGE_DIGEST_ALGORITHMS) == 0) + list_type = FUNC_TYPE_MD_ALG; else if (strcmp(argv[0],LIST_PUBLIC_KEY_ALGORITHMS) == 0) list_type = FUNC_TYPE_PKEY; + else if (strcmp(argv[0],LIST_CIPHER_ALGORITHMS) == 0) + list_type = FUNC_TYPE_CIPHER_ALG; else /* strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0 */ list_type = FUNC_TYPE_CIPHER; bio_stdout = BIO_new_fp(stdout,BIO_NOCLOSE); @@ -438,6 +449,10 @@ static int do_cmd(LHASH *prog, int argc, char *argv[]) if (list_type == FUNC_TYPE_PKEY) list_pkey(bio_stdout); + if (list_type == FUNC_TYPE_MD_ALG) + list_md(bio_stdout); + if (list_type == FUNC_TYPE_CIPHER_ALG) + list_cipher(bio_stdout); else { for (fp=functions; fp->name != NULL; fp++) @@ -540,6 +555,46 @@ static void list_pkey(BIO *out) } } +static void list_cipher_fn(const EVP_CIPHER *c, + const char *from, const char *to, void *arg) + { + if (c) + BIO_printf(arg, "%s\n", EVP_CIPHER_name(c)); + else + { + if (!from) + from = ""; + if (!to) + to = ""; + BIO_printf(arg, "%s => %s\n", from, to); + } + } + +static void list_cipher(BIO *out) + { + EVP_CIPHER_do_all_sorted(list_cipher_fn, out); + } + +static void list_md_fn(const EVP_MD *m, + const char *from, const char *to, void *arg) + { + if (m) + BIO_printf(arg, "%s\n", EVP_MD_name(m)); + else + { + if (!from) + from = ""; + if (!to) + to = ""; + BIO_printf(arg, "%s => %s\n", from, to); + } + } + +static void list_md(BIO *out) + { + EVP_MD_do_all_sorted(list_md_fn, out); + } + static LHASH *prog_init(void) { LHASH *ret; diff --git a/apps/progs.h b/apps/progs.h index a1a421ac406f939cc1a349e881d80216ee7824ea..b0fa703ddcca7dc7a10afd21c3f2f56390cfd2da 100644 --- a/apps/progs.h +++ b/apps/progs.h @@ -50,6 +50,8 @@ extern int ts_main(int argc,char *argv[]); #define FUNC_TYPE_MD 2 #define FUNC_TYPE_CIPHER 3 #define FUNC_TYPE_PKEY 4 +#define FUNC_TYPE_MD_ALG 5 +#define FUNC_TYPE_CIPHER_ALG 6 typedef struct { int type; diff --git a/apps/progs.pl b/apps/progs.pl index 02381087aeebe3f50f065a88db0f7185e26df1c5..9b1c7244f71eafc3d14f213d2ab759323d379baa 100644 --- a/apps/progs.pl +++ b/apps/progs.pl @@ -14,6 +14,8 @@ print <<'EOF'; #define FUNC_TYPE_MD 2 #define FUNC_TYPE_CIPHER 3 #define FUNC_TYPE_PKEY 4 +#define FUNC_TYPE_MD_ALG 5 +#define FUNC_TYPE_CIPHER_ALG 6 typedef struct { int type; diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h index 59460fb27782e073ff2e29667c8ef268eedb5f7c..509f8579af2a40d66c7ea97e67c077eab1c032df 100644 --- a/crypto/evp/evp.h +++ b/crypto/evp/evp.h @@ -782,6 +782,16 @@ const EVP_CIPHER *EVP_get_cipherbyname(const char *name); const EVP_MD *EVP_get_digestbyname(const char *name); void EVP_cleanup(void); +void EVP_CIPHER_do_all(void (*fn)(const EVP_CIPHER *ciph, + const char *from, const char *to, void *x), void *arg); +void EVP_CIPHER_do_all_sorted(void (*fn)(const EVP_CIPHER *ciph, + const char *from, const char *to, void *x), void *arg); + +void EVP_MD_do_all(void (*fn)(const EVP_MD *ciph, + const char *from, const char *to, void *x), void *arg); +void EVP_MD_do_all_sorted(void (*fn)(const EVP_MD *ciph, + const char *from, const char *to, void *x), void *arg); + int EVP_PKEY_decrypt_old(unsigned char *dec_key, const unsigned char *enc_key,int enc_key_len, EVP_PKEY *private_key); diff --git a/crypto/evp/names.c b/crypto/evp/names.c index 348df71cba23f1bfee15b147c200ebe6ea3e7a74..7fd67fa87012470b272cca1358e171d8ce060482 100644 --- a/crypto/evp/names.c +++ b/crypto/evp/names.c @@ -76,6 +76,7 @@ int EVP_add_cipher(const EVP_CIPHER *c) return(r); } + int EVP_add_digest(const EVP_MD *md) { int r; @@ -132,3 +133,71 @@ void EVP_cleanup(void) OBJ_cleanup(); } } + +struct doall_cipher + { + void *arg; + void (*fn)(const EVP_CIPHER *ciph, + const char *from, const char *to, void *arg); + }; + +static void do_all_cipher_fn(const OBJ_NAME *nm, void *arg) + { + struct doall_cipher *dc = arg; + if (nm->alias) + dc->fn(NULL, nm->name, nm->data, dc->arg); + else + dc->fn((const EVP_CIPHER *)nm->data, NULL, NULL, dc->arg); + } + +void EVP_CIPHER_do_all(void (*fn)(const EVP_CIPHER *ciph, + const char *from, const char *to, void *x), void *arg) + { + struct doall_cipher dc; + dc.fn = fn; + dc.arg = arg; + OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc); + } + +void EVP_CIPHER_do_all_sorted(void (*fn)(const EVP_CIPHER *ciph, + const char *from, const char *to, void *x), void *arg) + { + struct doall_cipher dc; + dc.fn = fn; + dc.arg = arg; + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn,&dc); + } + +struct doall_md + { + void *arg; + void (*fn)(const EVP_MD *ciph, + const char *from, const char *to, void *arg); + }; + +static void do_all_md_fn(const OBJ_NAME *nm, void *arg) + { + struct doall_md *dc = arg; + if (nm->alias) + dc->fn(NULL, nm->name, nm->data, dc->arg); + else + dc->fn((const EVP_MD *)nm->data, NULL, NULL, dc->arg); + } + +void EVP_MD_do_all(void (*fn)(const EVP_MD *md, + const char *from, const char *to, void *x), void *arg) + { + struct doall_md dc; + dc.fn = fn; + dc.arg = arg; + OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc); + } + +void EVP_MD_do_all_sorted(void (*fn)(const EVP_MD *md, + const char *from, const char *to, void *x), void *arg) + { + struct doall_md dc; + dc.fn = fn; + dc.arg = arg; + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc); + } diff --git a/crypto/lhash/lhash.c b/crypto/lhash/lhash.c index 55cb05579bc786600ddeb963ddf6a2106b5a7981..373c72dcb6f301c473cb1e35eae327dc3b1bd917 100644 --- a/crypto/lhash/lhash.c +++ b/crypto/lhash/lhash.c @@ -273,6 +273,9 @@ static void doall_util_fn(LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func, int i; LHASH_NODE *a,*n; + if (lh == NULL) + return; + /* reverse the order so we search from 'top to bottom' * We were having memory leaks otherwise */ for (i=lh->num_nodes-1; i>=0; i--)