X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssl_conf.c;h=419400aa2408f6757784f3301c92105955600287;hp=20e43a8d9b4e6976d84cdfb4b148d8076978bf5e;hb=cb2182676bdf652070bc272a3896d957763a4324;hpb=3db935a9e5e62fcbde719b2a03ce8941bb13514a diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c index 20e43a8d9b..419400aa24 100644 --- a/ssl/ssl_conf.c +++ b/ssl/ssl_conf.c @@ -62,6 +62,9 @@ #include "ssl_locl.h" #include #include +#ifndef OPENSSL_NO_DH +#include +#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,11 +246,9 @@ 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->flags & SSL_CONF_FLAG_CLIENT)) - return -2; if (cctx->ssl) rv = SSL_set1_curves_list(cctx->ssl, value); /* NB: ctx == NULL performs syntax checking only */ @@ -255,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 +275,12 @@ static int cmd_ecdhparam(SSL_CONF_CTX *cctx, const char *value) onoff = 0; value++; } - if (strcasecmp(value, "automatic")) + if (!strcasecmp(value, "automatic")) + { + if (onoff == -1) + onoff = 1; + } + else if (onoff != -1) return 0; } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) @@ -311,18 +317,18 @@ 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) rv = SSL_CTX_set_cipher_list(cctx->ctx, value); if (cctx->ssl) rv = SSL_set_cipher_list(cctx->ssl, value); - return rv; + 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[] = { @@ -340,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[] = { @@ -362,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_CTX_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; @@ -417,33 +511,47 @@ 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; - if (t->cmd(cctx, value)) + rv = runcmd->cmd(cctx, value); + if (rv > 0) return 2; + if (rv == -2) + return -2; if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) { - SSLerr(SSL_F_SSL_CONF_CTX_CMD, SSL_R_BAD_VALUE); + SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_BAD_VALUE); ERR_add_error_data(4, "cmd=", cmd, ", value=", value); } - return -1; + return 0; } if (cctx->flags & SSL_CONF_FLAG_CMDLINE) @@ -454,7 +562,7 @@ int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value) if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) { - SSLerr(SSL_F_SSL_CONF_CTX_CMD, SSL_R_UNKNOWN_CMD_NAME); + SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_UNKNOWN_CMD_NAME); ERR_add_error_data(2, "cmd=", cmd); } @@ -464,7 +572,7 @@ int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value) int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv) { int rv; - const char *arg, *argn; + const char *arg = NULL, *argn; if (pargc && *pargc == 0) return 0; if (!pargc || *pargc > 0) @@ -486,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 */ @@ -495,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; @@ -514,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)