Add loaded dynamic ENGINEs to list.
[openssl.git] / ssl / ssl_conf.c
index 940d5a8..419400a 100644 (file)
@@ -62,6 +62,9 @@
 #include "ssl_locl.h"
 #include <openssl/conf.h>
 #include <openssl/objects.h>
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
 
 /* structure holding name tables. This is used for pemitted elements in
  * lists such as TLSv1 and single command line switches such as no_tls1
@@ -200,9 +203,9 @@ static int ctrl_str_option(SSL_CONF_CTX *cctx, const char *cmd)
                SSL_FLAG_TBL("no_tls1", SSL_OP_NO_TLSv1),
                SSL_FLAG_TBL("no_tls1_1", SSL_OP_NO_TLSv1_1),
                SSL_FLAG_TBL("no_tls1_2", SSL_OP_NO_TLSv1_2),
-               SSL_FLAG_TBL("no_tls1_2", SSL_OP_NO_TLSv1_2),
                SSL_FLAG_TBL("bugs", SSL_OP_ALL),
                SSL_FLAG_TBL("no_comp", SSL_OP_NO_COMPRESSION),
+               SSL_FLAG_TBL_SRV("ecdh_single", SSL_OP_SINGLE_ECDH_USE),
 #ifndef OPENSSL_NO_TLSEXT
                SSL_FLAG_TBL("no_ticket", SSL_OP_NO_TICKET),
 #endif
@@ -221,7 +224,7 @@ static int ctrl_str_option(SSL_CONF_CTX *cctx, const char *cmd)
        }
 
 /* Set supported signature algorithms */
-static int cmd_sigalgs(SSL_CONF_CTX *cctx, const char *value)
+static int cmd_SignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value)
        {
        int rv;
        if (cctx->ssl)
@@ -232,7 +235,7 @@ static int cmd_sigalgs(SSL_CONF_CTX *cctx, const char *value)
        return rv > 0;
        }
 /* Set supported client signature algorithms */
-static int cmd_client_sigalgs(SSL_CONF_CTX *cctx, const char *value)
+static int cmd_ClientSignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value)
        {
        int rv;
        if (cctx->ssl)
@@ -243,7 +246,7 @@ static int cmd_client_sigalgs(SSL_CONF_CTX *cctx, const char *value)
        return rv > 0;
        }
 
-static int cmd_curves(SSL_CONF_CTX *cctx, const char *value)
+static int cmd_Curves(SSL_CONF_CTX *cctx, const char *value)
        {
        int rv;
        if (cctx->ssl)
@@ -253,9 +256,9 @@ static int cmd_curves(SSL_CONF_CTX *cctx, const char *value)
                rv = SSL_CTX_set1_curves_list(cctx->ctx, value);
        return rv > 0;
        }
-
+#ifndef OPENSSL_NO_ECDH
 /* ECDH temporary parameters */
-static int cmd_ecdhparam(SSL_CONF_CTX *cctx, const char *value)
+static int cmd_ECDHParameters(SSL_CONF_CTX *cctx, const char *value)
        {
        int onoff = -1, rv = 1;
        if (!(cctx->flags & SSL_CONF_FLAG_SERVER))
@@ -274,7 +277,7 @@ static int cmd_ecdhparam(SSL_CONF_CTX *cctx, const char *value)
                        }
                if (!strcasecmp(value, "automatic"))
                        {
-                       if (onoff != -1)
+                       if (onoff == -1)
                                onoff = 1;
                        }
                else if (onoff != -1)
@@ -314,8 +317,8 @@ static int cmd_ecdhparam(SSL_CONF_CTX *cctx, const char *value)
 
        return rv > 0;
        }
-
-static int cmd_cipher_list(SSL_CONF_CTX *cctx, const char *value)
+#endif
+static int cmd_CipherString(SSL_CONF_CTX *cctx, const char *value)
        {
        int rv = 1;
        if (cctx->ctx)
@@ -325,7 +328,7 @@ static int cmd_cipher_list(SSL_CONF_CTX *cctx, const char *value)
        return rv > 0;
        }
 
-static int cmd_protocol(SSL_CONF_CTX *cctx, const char *value)
+static int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value)
        {
        static const ssl_flag_tbl ssl_protocol_list[] =
                {
@@ -343,7 +346,7 @@ static int cmd_protocol(SSL_CONF_CTX *cctx, const char *value)
        return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
        }
 
-static int cmd_options(SSL_CONF_CTX *cctx, const char *value)
+static int cmd_Options(SSL_CONF_CTX *cctx, const char *value)
        {
        static const ssl_flag_tbl ssl_option_list[] =
                {
@@ -365,53 +368,141 @@ static int cmd_options(SSL_CONF_CTX *cctx, const char *value)
        return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
        }
 
+static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value)
+       {
+       int rv = 1;
+       if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
+               return -2;
+       if (cctx->ctx)
+               rv = SSL_CTX_use_certificate_chain_file(cctx->ctx, value);
+       if (cctx->ssl)
+               rv = SSL_use_certificate_file(cctx->ssl, value, SSL_FILETYPE_PEM);
+       return rv > 0;
+       }
+
+static int cmd_PrivateKey(SSL_CONF_CTX *cctx, const char *value)
+       {
+       int rv = 1;
+       if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
+               return -2;
+       if (cctx->ctx)
+               rv = SSL_CTX_use_PrivateKey_file(cctx->ctx, value, SSL_FILETYPE_PEM);
+       if (cctx->ssl)
+               rv = SSL_use_PrivateKey_file(cctx->ssl, value, SSL_FILETYPE_PEM);
+       return rv > 0;
+       }
+
+static int cmd_ServerInfoFile(SSL_CONF_CTX *cctx, const char *value)
+       {
+       int rv = 1;
+       if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
+               return -2;
+       if (!(cctx->flags & SSL_CONF_FLAG_SERVER))
+               return -2;
+       if (cctx->ctx)
+               rv = SSL_CTX_use_serverinfo_file(cctx->ctx, value);
+       return rv > 0;
+       }
+
+#ifndef OPENSSL_NO_DH
+static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value)
+       {
+       int rv = 0;
+       DH *dh = NULL;
+       BIO *in = NULL;
+       if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
+               return -2;
+       if (cctx->ctx || cctx->ssl)
+               {
+               in = BIO_new(BIO_s_file_internal());
+               if (!in)
+                       goto end;
+               if (BIO_read_filename(in, value) <= 0)
+                       goto end;
+               dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
+               if (!dh)
+                       goto end;
+               }
+       else
+               return 1;
+       if (cctx->ctx)
+               rv = SSL_CTX_set_tmp_dh(cctx->ctx, dh);
+       if (cctx->ssl)
+               rv = SSL_set_tmp_dh(cctx->ssl, dh);
+       end:
+       if (dh)
+               DH_free(dh);
+       if (in)
+               BIO_free(in);
+       return rv > 0;
+       }
+#endif
 typedef struct
        {
        int (*cmd)(SSL_CONF_CTX *cctx, const char *value);
        const char *str_file;
        const char *str_cmdline;
+       unsigned int value_type;
        } ssl_conf_cmd_tbl;
 
-/* Table of supported patameters */
+/* Table of supported parameters */
+
+#define SSL_CONF_CMD(name, cmdopt, type) \
+       {cmd_##name, #name, cmdopt, type}
 
-static ssl_conf_cmd_tbl ssl_conf_cmds[] = {
-       {cmd_sigalgs,           "SignatureAlgorithms", "sigalgs"},
-       {cmd_client_sigalgs,    "ClientSignatureAlgorithms", "client_sigalgs"},
-       {cmd_curves,            "Curves", "curves"},
-       {cmd_ecdhparam,         "ECDHParameters", "named_curve"},
-       {cmd_cipher_list,       "CipherString", "cipher"},
-       {cmd_protocol,          "Protocol", NULL},
-       {cmd_options,           "Options", NULL},
+#define SSL_CONF_CMD_STRING(name, cmdopt) \
+       SSL_CONF_CMD(name, cmdopt, SSL_CONF_TYPE_STRING)
+
+static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
+       SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs"),
+       SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs"),
+       SSL_CONF_CMD_STRING(Curves, "curves"),
+#ifndef OPENSSL_NO_ECDH
+       SSL_CONF_CMD_STRING(ECDHParameters, "named_curve"),
+#endif
+       SSL_CONF_CMD_STRING(CipherString, "cipher"),
+       SSL_CONF_CMD_STRING(Protocol, NULL),
+       SSL_CONF_CMD_STRING(Options, NULL),
+       SSL_CONF_CMD(Certificate, "cert", SSL_CONF_TYPE_FILE),
+       SSL_CONF_CMD(PrivateKey, "key", SSL_CONF_TYPE_FILE),
+       SSL_CONF_CMD(ServerInfoFile, NULL, SSL_CONF_TYPE_FILE),
+#ifndef OPENSSL_NO_DH
+       SSL_CONF_CMD(DHParameters, "dhparam", SSL_CONF_TYPE_FILE)
+#endif
 };
 
-int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value)
+static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd)
        {
-       ssl_conf_cmd_tbl *t, *runcmd = NULL;
-       size_t i;
-       if (cmd == NULL)
-               {
-               SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_INVALID_NULL_CMD_NAME);
+       if (!pcmd || !*pcmd)
                return 0;
-               }
        /* If a prefix is set, check and skip */
        if (cctx->prefix)
                {
-               if (strlen(cmd) <= cctx->prefixlen)
-                       return -2;
+               if (strlen(*pcmd) <= cctx->prefixlen)
+                       return 0;
                if (cctx->flags & SSL_CONF_FLAG_CMDLINE &&
-                       strncmp(cmd, cctx->prefix, cctx->prefixlen))
-                       return -2;
+                       strncmp(*pcmd, cctx->prefix, cctx->prefixlen))
+                       return 0;
                if (cctx->flags & SSL_CONF_FLAG_FILE &&
-                       strncasecmp(cmd, cctx->prefix, cctx->prefixlen))
-                       return -2;
-               cmd += cctx->prefixlen;
+                       strncasecmp(*pcmd, cctx->prefix, cctx->prefixlen))
+                       return 0;
+               *pcmd += cctx->prefixlen;
                }
        else if (cctx->flags & SSL_CONF_FLAG_CMDLINE)
                {
-               if (*cmd != '-' || !cmd[1])
-                       return -2;
-               cmd++;
+               if (**pcmd != '-' || !(*pcmd)[1])
+                       return 0;
+               *pcmd += 1;
                }
+       return 1;
+       }
+
+static const ssl_conf_cmd_tbl *ssl_conf_cmd_lookup(SSL_CONF_CTX *cctx, const char *cmd)
+       {
+       const ssl_conf_cmd_tbl *t;
+       size_t i;
+       if (cmd == NULL)
+               return NULL;
 
        /* Look for matching parameter name in table */
        for (i = 0, t = ssl_conf_cmds;
@@ -420,27 +511,37 @@ int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value)
                if (cctx->flags & SSL_CONF_FLAG_CMDLINE)
                        {
                        if (t->str_cmdline && !strcmp(t->str_cmdline, cmd))
-                               {
-                               runcmd = t;
-                               break;
-                               }
+                               return t;
                        }
                if (cctx->flags & SSL_CONF_FLAG_FILE)
                        {
                        if (t->str_file && !strcasecmp(t->str_file, cmd))
-                               {
-                               runcmd = t;
-                               break;
-                               }
+                               return t;
                        }
                }
+       return NULL;
+       }
+
+int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value)
+       {
+       const ssl_conf_cmd_tbl *runcmd;
+       if (cmd == NULL)
+               {
+               SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_INVALID_NULL_CMD_NAME);
+               return 0;
+               }
+
+       if (!ssl_conf_cmd_skip_prefix(cctx, &cmd))
+               return -2;
+
+       runcmd = ssl_conf_cmd_lookup(cctx, cmd);
 
        if (runcmd)
                {
                int rv;
                if (value == NULL)
                        return -3;
-               rv = t->cmd(cctx, value);
+               rv = runcmd->cmd(cctx, value);
                if (rv > 0)
                        return 2;
                if (rv == -2)
@@ -493,7 +594,7 @@ int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv)
                        (*pargc) -= rv;
                return rv;
                }
-       /* Unknown swicth: indicate no arguments processed */
+       /* Unknown switch: indicate no arguments processed */
        if (rv == -2)
                return 0;
        /* Some error occurred processing command, return fatal error */
@@ -502,6 +603,18 @@ int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv)
        return rv;
        }
 
+int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd)
+       {
+       if (ssl_conf_cmd_skip_prefix(cctx, &cmd))
+               {
+               const ssl_conf_cmd_tbl *runcmd;
+               runcmd = ssl_conf_cmd_lookup(cctx, cmd);
+               if (runcmd)
+                       return runcmd->value_type;
+               }
+       return SSL_CONF_TYPE_UNKNOWN;
+       }
+
 SSL_CONF_CTX *SSL_CONF_CTX_new(void)
        {
        SSL_CONF_CTX *ret;
@@ -521,6 +634,11 @@ SSL_CONF_CTX *SSL_CONF_CTX_new(void)
        return ret;
        }
 
+int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx)
+       {
+       return 1;
+       }
+
 void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx)
        {
        if (cctx)