Add an explicit load_config() call so any added algorithms are
[openssl.git] / apps / openssl.c
index 7edd9e3132fdd752f56a5f44be192098c545a8ae..a9f3df0955687f2177e9e413c319baffa86078b1 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 #define OPENSSL_C /* tells apps.h to use complete apps_startup() */
+#include "apps.h"
 #include <openssl/bio.h>
 #include <openssl/crypto.h>
 #include <openssl/lhash.h>
 #include <openssl/x509.h>
 #include <openssl/pem.h>
 #include <openssl/ssl.h>
+#ifndef OPENSSL_NO_ENGINE
 #include <openssl/engine.h>
+#endif
 #define USE_SOCKETS /* needed for the _O_BINARY defs in the MS world */
-#include "apps.h"
 #include "progs.h"
 #include "s_apps.h"
 #include <openssl/err.h>
@@ -139,11 +141,12 @@ static unsigned long MS_CALLBACK hash(const void *a_void);
 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[]);
-CONF *config=NULL;
+static void list_pkey(BIO *out);
 char *default_config_file=NULL;
 
 /* Make sure there is only one when MONOLITH is defined */
 #ifdef MONOLITH
+CONF *config=NULL;
 BIO *bio_err=NULL;
 #endif
 
@@ -161,7 +164,7 @@ static void lock_dbg_cb(int mode, int type, const char *file, int line)
                goto err;
                }
 
-       if (type < 0 || type > CRYPTO_NUM_LOCKS)
+       if (type < 0 || type >= CRYPTO_NUM_LOCKS)
                {
                errstr = "type out of bounds";
                goto err;
@@ -215,10 +218,12 @@ static void lock_dbg_cb(int mode, int type, const char *file, int line)
 int main(int Argc, char *Argv[])
        {
        ARGS arg;
-#define PROG_NAME_SIZE 16
-       char pname[PROG_NAME_SIZE];
+#define PROG_NAME_SIZE 39
+       char pname[PROG_NAME_SIZE+1];
        FUNCTION f,*fp;
-       MS_STATIC char *prompt,buf[1024],config_name[256];
+       MS_STATIC const char *prompt;
+       MS_STATIC char buf[1024];
+       char *to_free=NULL;
        int n,i,ret=0;
        int argc;
        char **argv,*p;
@@ -228,6 +233,10 @@ int main(int Argc, char *Argv[])
        arg.data=NULL;
        arg.count=0;
 
+       if (bio_err == NULL)
+               if ((bio_err=BIO_new(BIO_s_file())) != NULL)
+                       BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
+
        if (getenv("OPENSSL_DEBUG_MEMORY") != NULL) /* if not defined, use compiled-in library defaults */
                {
                if (!(0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))
@@ -252,34 +261,28 @@ int main(int Argc, char *Argv[])
 
        apps_startup();
 
-       if (bio_err == NULL)
-               if ((bio_err=BIO_new(BIO_s_file())) != NULL)
-                       BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
-
        /* Lets load up our environment a little */
        p=getenv("OPENSSL_CONF");
        if (p == NULL)
                p=getenv("SSLEAY_CONF");
        if (p == NULL)
-               {
-               strcpy(config_name,X509_get_default_cert_area());
-#ifndef OPENSSL_SYS_VMS
-               strcat(config_name,"/");
-#endif
-               strcat(config_name,OPENSSL_CONF);
-               p=config_name;
-               }
+               p=to_free=make_config_name();
 
        default_config_file=p;
 
        config=NCONF_new(NULL);
        i=NCONF_load(config,p,&errline);
-       if (i == 0) ERR_clear_error();
+       if (i == 0)
+               {
+               NCONF_free(config);
+               config = NULL;
+               ERR_clear_error();
+               }
 
        prog=prog_init();
 
        /* first check the program name */
-       program_name(Argv[0],pname,PROG_NAME_SIZE);
+       program_name(Argv[0],pname,sizeof pname);
 
        f.name=pname;
        fp=(FUNCTION *)lh_retrieve(prog,&f);
@@ -307,7 +310,7 @@ int main(int Argc, char *Argv[])
                {
                ret=0;
                p=buf;
-               n=1024;
+               n=sizeof buf;
                i=0;
                for (;;)
                        {
@@ -341,6 +344,8 @@ int main(int Argc, char *Argv[])
        BIO_printf(bio_err,"bad exit\n");
        ret=1;
 end:
+       if (to_free)
+               OPENSSL_free(to_free);
        if (config != NULL)
                {
                NCONF_free(config);
@@ -357,12 +362,13 @@ end:
                BIO_free(bio_err);
                bio_err=NULL;
                }
-       EXIT(ret);
+       OPENSSL_EXIT(ret);
        }
 
 #define LIST_STANDARD_COMMANDS "list-standard-commands"
 #define LIST_MESSAGE_DIGEST_COMMANDS "list-message-digest-commands"
 #define LIST_CIPHER_COMMANDS "list-cipher-commands"
+#define LIST_PUBLIC_KEY_ALGORITHMS "list-public-key-algorithms"
 
 static int do_cmd(LHASH *prog, int argc, char *argv[])
        {
@@ -405,7 +411,8 @@ 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_CIPHER_COMMANDS) == 0))
+               (strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0) ||
+               (strcmp(argv[0],LIST_PUBLIC_KEY_ALGORITHMS) == 0))
                {
                int list_type;
                BIO *bio_stdout;
@@ -414,6 +421,8 @@ 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_PUBLIC_KEY_ALGORITHMS) == 0)
+                       list_type = FUNC_TYPE_PKEY;
                else /* strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0 */
                        list_type = FUNC_TYPE_CIPHER;
                bio_stdout = BIO_new_fp(stdout,BIO_NOCLOSE);
@@ -423,10 +432,19 @@ static int do_cmd(LHASH *prog, int argc, char *argv[])
                bio_stdout = BIO_push(tmpbio, bio_stdout);
                }
 #endif
-               
-               for (fp=functions; fp->name != NULL; fp++)
-                       if (fp->type == list_type)
-                               BIO_printf(bio_stdout, "%s\n", fp->name);
+
+               if (!load_config(bio_err, NULL))
+                       goto end;
+
+               if (list_type == FUNC_TYPE_PKEY)
+                       list_pkey(bio_stdout);  
+               else
+                       {
+                       for (fp=functions; fp->name != NULL; fp++)
+                               if (fp->type == list_type)
+                                       BIO_printf(bio_stdout, "%s\n",
+                                                               fp->name);
+                       }
                BIO_free_all(bio_stdout);
                ret=0;
                goto end;
@@ -481,11 +499,44 @@ static int SortFnByName(const void *_f1,const void *_f2)
     return strcmp(f1->name,f2->name);
     }
 
+static void list_pkey(BIO *out)
+       {
+       int i;
+       for (i = 0; i < EVP_PKEY_asn1_get_count(); i++)
+               {
+               const EVP_PKEY_ASN1_METHOD *ameth;
+               int pkey_id, pkey_base_id, pkey_flags;
+               const char *pinfo, *pem_str;
+               ameth = EVP_PKEY_asn1_get0(i);
+               EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags,
+                                               &pinfo, &pem_str, ameth);
+               if (pkey_flags & ASN1_PKEY_ALIAS)
+                       {
+                       BIO_printf(out, "Name: %s\n", 
+                                       OBJ_nid2ln(pkey_id));
+                       BIO_printf(out, "\tType: Alias to %s\n",
+                                       OBJ_nid2ln(pkey_base_id));
+                       }
+               else
+                       {
+                       BIO_printf(out, "Name: %s\n", pinfo);
+                       BIO_printf(out, "\tType: %s Algorithm\n", 
+                               pkey_flags & ASN1_PKEY_DYNAMIC ?
+                                       "External" : "Builtin");
+                       BIO_printf(out, "\tOID: %s\n", OBJ_nid2ln(pkey_id));
+                       if (pem_str == NULL)
+                               pem_str = "(none)";
+                       BIO_printf(out, "\tPEM string: %s\n", pem_str);
+                       }
+                                       
+               }
+       }
+
 static LHASH *prog_init(void)
        {
        LHASH *ret;
        FUNCTION *f;
-       int i;
+       size_t i;
 
        /* Purely so it looks nice when the user hits ? */
        for(i=0,f=functions ; f->name != NULL ; ++f,++i)
@@ -503,12 +554,12 @@ static LHASH *prog_init(void)
 /* static int MS_CALLBACK cmp(FUNCTION *a, FUNCTION *b) */
 static int MS_CALLBACK cmp(const void *a_void, const void *b_void)
        {
-       return(strncmp(((FUNCTION *)a_void)->name,
-                       ((FUNCTION *)b_void)->name,8));
+       return(strncmp(((const FUNCTION *)a_void)->name,
+                       ((const FUNCTION *)b_void)->name,8));
        }
 
 /* static unsigned long MS_CALLBACK hash(FUNCTION *a) */
 static unsigned long MS_CALLBACK hash(const void *a_void)
        {
-       return(lh_strhash(((FUNCTION *)a_void)->name));
+       return(lh_strhash(((const FUNCTION *)a_void)->name));
        }