From 49ef33fa3463d6b6001009024c9aed09f814cb7c Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Sat, 29 Dec 2012 13:30:56 +0000 Subject: [PATCH] add SSL_CONF functions and documentation (backport from HEAD) --- CHANGES | 4 + doc/ssl/SSL_CONF_CTX_new.pod | 40 ++ doc/ssl/SSL_CONF_CTX_set1_prefix.pod | 49 +++ doc/ssl/SSL_CONF_CTX_set_flags.pod | 64 +++ doc/ssl/SSL_CONF_CTX_set_ssl_ctx.pod | 47 +++ doc/ssl/SSL_CONF_cmd.pod | 342 +++++++++++++++ doc/ssl/SSL_CONF_cmd_argv.pod | 42 ++ ssl/Makefile | 8 +- ssl/ssl.h | 26 ++ ssl/ssl_conf.c | 595 +++++++++++++++++++++++++++ ssl/ssl_err.c | 4 + ssl/ssl_lib.c | 14 + 12 files changed, 1231 insertions(+), 4 deletions(-) create mode 100644 doc/ssl/SSL_CONF_CTX_new.pod create mode 100644 doc/ssl/SSL_CONF_CTX_set1_prefix.pod create mode 100644 doc/ssl/SSL_CONF_CTX_set_flags.pod create mode 100644 doc/ssl/SSL_CONF_CTX_set_ssl_ctx.pod create mode 100644 doc/ssl/SSL_CONF_cmd.pod create mode 100644 doc/ssl/SSL_CONF_cmd_argv.pod create mode 100644 ssl/ssl_conf.c diff --git a/CHANGES b/CHANGES index 31f9834724..c6357393e3 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,10 @@ Changes between 1.0.1 and 1.0.2 [xx XXX xxxx] + *) SSL_CONF* functions. These provide a common framework for application + configuration using configuration files or command lines. + [Steve Henson] + *) SSL/TLS tracing code. This parses out SSL/TLS records using the message callback and prints the results. Needs compile time option "enable-ssl-trace". New options to s_client and s_server to enable diff --git a/doc/ssl/SSL_CONF_CTX_new.pod b/doc/ssl/SSL_CONF_CTX_new.pod new file mode 100644 index 0000000000..1ae4ac627e --- /dev/null +++ b/doc/ssl/SSL_CONF_CTX_new.pod @@ -0,0 +1,40 @@ +=pod + +=head1 NAME + +SSL_CONF_CTX_new, SSL_CONF_CTX_free - SSL configuration allocation functions + +=head1 SYNOPSIS + + #include + + SSL_CONF_CTX *SSL_CONF_CTX_new(void); + void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx); + +=head1 DESCRIPTION + +The function SSL_CONF_CTX_new() allocates and initialises an B +structure for use with the SSL_CONF functions. + +The function SSL_CONF_CTX_free() frees up the context B. + +=head1 RETURN VALUES + +SSL_CONF_CTX_new() returns either the newly allocated B structure +or B if an error occurs. + +SSL_CONF_CTX_free() does not return a value. + +=head1 SEE ALSO + +L, +L, +L, +L, +L + +=head1 HISTORY + +These functions were first added to OpenSSL 1.1.0 + +=cut diff --git a/doc/ssl/SSL_CONF_CTX_set1_prefix.pod b/doc/ssl/SSL_CONF_CTX_set1_prefix.pod new file mode 100644 index 0000000000..3b165db89b --- /dev/null +++ b/doc/ssl/SSL_CONF_CTX_set1_prefix.pod @@ -0,0 +1,49 @@ +=pod + +=head1 NAME + +SSL_CONF_CTX_set1_prefix - Set configuration context command prefix + +=head1 SYNOPSIS + + #include + + unsigned int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *prefix); + +=head1 DESCRIPTION + +The function SSL_CONF_CTX_set1_prefix() sets the command prefix of B +to B. If B is B it is restored to the default value. + +=head1 NOTES + +Command prefixes alter the commands recognised by subsequent SSL_CTX_cmd() +calls. For example for files, if the prefix "SSL" is set then command names +such as "SSLProtocol", "SSLOptions" etc. are recognised instead of "Protocol" +and "Options". Similarly for command lines if the prefix is "--ssl-" then +"--ssl-no_tls1_2" is recognised instead of "-no_tls1_2". + +If the B flag is set then prefix checks are case +sensitive and "-" is the default. In the unlikely even an application +explicitly wants to set no prefix it must be explicitly set to "". + +If the B flag is set then prefix checks are case +insensitive and no prefix is the default. + +=head1 RETURN VALUES + +SSL_CONF_CTX_set1_prefix() returns 1 for success and 0 for failure. + +=head1 SEE ALSO + +L, +L, +L, +L, +L + +=head1 HISTORY + +These functions were first added to OpenSSL 1.1.0 + +=cut diff --git a/doc/ssl/SSL_CONF_CTX_set_flags.pod b/doc/ssl/SSL_CONF_CTX_set_flags.pod new file mode 100644 index 0000000000..90d97e74f0 --- /dev/null +++ b/doc/ssl/SSL_CONF_CTX_set_flags.pod @@ -0,0 +1,64 @@ +=pod + +=head1 NAME + +SSL_CONF_CTX_set_flags, SSL_CONF_CTX_clear_flags - Set of clear SSL configuration context flags + +=head1 SYNOPSIS + + #include + + unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags); + unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags); + +=head1 DESCRIPTION + +The function SSL_CONF_CTX_set_flags() sets B in the context B. + +The function SSL_CONF_CTX_clear_flags() clears B in the context B. + +=head1 NOTES + +The flags set affect how subsequent calls to SSL_CONF_cmd() or +SSL_CONF_argv() behave. + +Currently the following B values are recognised: + +=over 4 + +=item SSL_CONF_FLAG_CMDLINE, SSL_CONF_FLAG_FILE + +recognise options intended for command line or configuration file use. At +least one of these flags must be set. + +=item SSL_CONF_FLAG_CLIENT, SSL_CONF_FLAG_SERVER + +recognise options intended for use in SSL/TLS clients or servers. One or +both of these flags must be set. + +=item SSL_CONF_FLAG_SHOW_ERRORS + +indicate errors relating to unrecognised options or missing arguments in +the error queue. If this option isn't set such errors are only reflected +in the return values of SSL_CONF_set_cmd() or SSL_CONF_set_argv() + +=back + +=head1 RETURN VALUES + +SSL_CONF_CTX_set_flags() and SSL_CONF_CTX_clear_flags() returns the new flags +value after setting or clearing flags. + +=head1 SEE ALSO + +L, +L, +L, +L, +L + +=head1 HISTORY + +These functions were first added to OpenSSL 1.1.0 + +=cut diff --git a/doc/ssl/SSL_CONF_CTX_set_ssl_ctx.pod b/doc/ssl/SSL_CONF_CTX_set_ssl_ctx.pod new file mode 100644 index 0000000000..cfb7cb2599 --- /dev/null +++ b/doc/ssl/SSL_CONF_CTX_set_ssl_ctx.pod @@ -0,0 +1,47 @@ +=pod + +=head1 NAME + +SSL_CONF_CTX_set_ssl_ctx, SSL_CONF_CTX_set_ssl - set context to configure + +=head1 SYNOPSIS + + #include + + void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx); + void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl); + +=head1 DESCRIPTION + +SSL_CONF_CTX_set_ssl_ctx() sets the context associated with B to the +B structure B. Any previos B or B associated with +B is cleared. Subsequent calls to SSL_CONF_cmd() will be sent to +B. + +SSL_CONF_CTX_set_ssl() sets the context associated with B to the +B structure B. Any previos B or B associated with +B is cleared. Subsequent calls to SSL_CONF_cmd() will be sent to +B. + +=head1 NOTES + +The context need not be set or it can be set to B in which case only +syntax checking of commands is performed, where possible. + +=head1 RETURN VALUES + +SSL_CONF_CTX_set_ssl_ctx() and SSL_CTX_set_ssl() do not return a value. + +=head1 SEE ALSO + +L, +L, +L, +L, +L + +=head1 HISTORY + +These functions were first added to OpenSSL 1.1.0 + +=cut diff --git a/doc/ssl/SSL_CONF_cmd.pod b/doc/ssl/SSL_CONF_cmd.pod new file mode 100644 index 0000000000..0fbf0d75df --- /dev/null +++ b/doc/ssl/SSL_CONF_cmd.pod @@ -0,0 +1,342 @@ +=pod + +=head1 NAME + +SSL_CONF_cmd - send configuration command + +=head1 SYNOPSIS + + #include + + int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value); + +=head1 DESCRIPTION + +The function SSL_CONF_cmd() performs configuration operation B with +optional parameter B on B. Its purpose is to simplify application +configuration of B or B structures by providing a common +framework for command line options or configuration files. + +=head1 SUPPORTED COMMAND LINE COMMANDS + +Currently supported B names for command lines (i.e. when the +flag B is set) are listed below. Note: all B names +and are case sensitive. Unless otherwise stated commands can be used by +both clients and servers and the B parameter is not used. The default +prefix for command line commands is B<-> and that is reflected below. + +=over 4 + +=item B<-sigalgs> + +This sets the supported signature algorithms for TLS v1.2. For clients this +value is used directly for the supported signature algorithms extension. For +servers it is used to determine which signature algorithms to support. + +The B argument should be a colon separated list of signature algorithms +in order of decreasing preference of the form B. B +is one of B, B or B and B is a supported algorithm +OID short name such as B, B, B, B of B. +Note: algorithm and hash names are case sensitive. + +If this option is not set then all signature algorithms supported by the +OpenSSL library are permissible. + +=item B<-client_sigalgs> + +This sets the supported signature algorithms associated with client +authentication for TLS v1.2. For servers the value is used in the supported +signature algorithms field of a certificate request. For clients it is +used to determine which signature algorithm to with the client certificate. +If a server does not request a certificate this option has no effect. + +The syntax of B is identical to B<-sigalgs>. If not set then +the value set for B<-sigalgs> will be used instead. + +=item B<-curves> + +This sets the supported elliptic curves. For clients the curves are +sent using the supported curves extension. For servers it is used +to determine which curve to use. This setting affects curves used for both +signatures and key exchange, if applicable. + +The B argument is a colon separated list of curves. The curve can be +either the B name (e.g. B) or an OpenSSL OID name (e.g +B). Curve names are case sensitive. + +=item B<-named_curve> + +This sets the temporary curve used for ephemeral ECDH modes. Only used by +servers + +The B argument is a curve name or the special value B which +picks an appropriate curve based on client and server preferences. The curve +can be either the B name (e.g. B) or an OpenSSL OID name +(e.g B). Curve names are case sensitive. + +=item B<-cipher> + +Sets the cipher suite list to B. Note: syntax checking of B is +currently not performed unless a B or B structure is +associated with B. + +=item B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2> + +Disables protocol support for SSLv2, SSLv3, TLS 1.0, TLS 1.1 or TLS 1.2 +by setting the corresponding options B, B, +B, B and B respectively. + +=item B<-bugs> + +Various bug workarounds are set, same as setting B. + +=item B<-no_comp> + +Disables support for SSL/TLS compression, same as setting B. + +=item B<-no_ticket> + +Disables support for session tickets, same as setting B. + +=item B<-serverpref> + +Use server and not client preference order when determining which cipher suite, +signature algorithm or elliptic curve to use for an incoming connection. +Equivalent to B. Only used by servers. + +=item B<-legacyrenegotiation> + +permits the use of unsafe legacy renegotiation. Equivalent to setting +B. + +=item B<-legacy_server_connect>, B<-no_legacy_server_connect> + +permits or prohibits the use of unsafe legacy renegotiation for OpenSSL +clients only. Equivalent to setting or clearing B. +Set by default. + +=item B<-strict> + +enables strict mode protocol handling. Equivalent to setting +B. + +=item B<-debug_broken_protocol> + +disables various checks and permits several kinds of broken protocol behaviour +for testing purposes: it should B be used in anything other than a test +environment. Only supported if OpenSSL is configured with +B<-DOPENSSL_SSL_DEBUG_BROKEN_PROTOCOL>. + +=back + +=head1 SUPPORTED CONFIGURATION FILE COMMANDS + +Currently supported B names for configuration files (i.e. when the +flag B is set) are listed below. All configuration file +B names and are case insensitive so B is recognised +as well as B. Unless otherwise stated the B names +are also case insensitive. + +Note: the command prefix (if set) alters the recognised B values. + +=over 4 + +=item B + +Sets the cipher suite list to B. Note: syntax checking of B is +currently not performed unless an B or B structure is +associated with B. + +=item B + +This sets the supported signature algorithms for TLS v1.2. For clients this +value is used directly for the supported signature algorithms extension. For +servers it is used to determine which signature algorithms to support. + +The B argument should be a colon separated list of signature algorithms +in order of decreasing preference of the form B. B +is one of B, B or B and B is a supported algorithm +OID short name such as B, B, B, B of B. +Note: algorithm and hash names are case sensitive. + +If this option is not set then all signature algorithms supported by the +OpenSSL library are permissible. + +=item B + +This sets the supported signature algorithms associated with client +authentication for TLS v1.2. For servers the value is used in the supported +signature algorithms field of a certificate request. For clients it is +used to determine which signature algorithm to with the client certificate. + +The syntax of B is identical to B. If not set then +the value set for B will be used instead. + +=item B + +This sets the supported elliptic curves. For clients the curves are +sent using the supported curves extension. For servers it is used +to determine which curve to use. This setting affects curves used for both +signatures and key exchange, if applicable. + +The B argument is a colon separated list of curves. The curve can be +either the B name (e.g. B) or an OpenSSL OID name (e.g +B). Curve names are case sensitive. + +=item B + +This sets the temporary curve used for ephemeral ECDH modes. Only used by +servers + +The B argument is a curve name or the special value B which +picks an appropriate curve based on client and server preferences. The curve +can be either the B name (e.g. B) or an OpenSSL OID name +(e.g B). Curve names are case sensitive. + +=item B + +The supported versions of the SSL or TLS protocol. + +The B argument is a comma separated list of supported protocols to +enable or disable. If an protocol is preceded by B<-> that version is disabled. +All versions are enabled by default, though applications may choose to +explicitly disable some. Currently supported protocol values are B, +B, B, B and B. The special value B refers +to all supported versions. + +=item B + +The B argument is a comma separated list of various flags to set. +If a flag string is preceded B<-> it is disabled. See the +B function for more details of individual options. + +Each option is listed below. Where an operation is enabled by default +the B<-flag> syntax is needed to disable it. + +B: session ticket support, enabled by default. Inverse of +B: that is B<-SessionTicket> is the same as setting +B. + +B: SSL/TLS compression support, enabled by default. Inverse +of B. + +B: use empty fragments as a countermeasure against a +SSL 3.0/TLS 1.0 protocol vulnerability affecting CBC ciphers. It +is set by default. Inverse of B. + +B: enable various bug workarounds. Same as B. + +B: enable single use DH keys, set by default. Inverse of +B. Only used by servers. + +B enable single use ECDH keys, set by default. Inverse of +B. Only used by servers. + +B use server and not client preference order when +determining which cipher suite, signature algorithm or elliptic curve +to use for an incoming connection. Equivalent to +B. Only used by servers. + +B permits the use of unsafe legacy renegotiation. +Equivalent to B. + +B permits the use of unsafe legacy renegotiation +for OpenSSL clients only. Equivalent to B. +Set by default. + +=back + +=head1 NOTES + +The order of operations is significant. This can be used to set either defaults +or values which cannot be overridden. For example if an application calls: + + SSL_CONF_cmd(ctx, "Protocol", "-SSLv2"); + SSL_CONF_cmd(ctx, userparam, uservalue); + +it will disable SSLv2 support by default but the user can override it. If +however the call sequence is: + + SSL_CONF_cmd(ctx, userparam, uservalue); + SSL_CONF_cmd(ctx, "Protocol", "-SSLv2"); + +SSLv2 is B disabled and attempt to override this by the user are +ignored. + +By checking the return code of SSL_CTX_cmd() it is possible to query if a +given B is recognised, this is useful is SSL_CTX_cmd() values are +mixed with additional application specific operations. + +For example an application might call SSL_CTX_cmd() and if it returns +-2 (unrecognised command) continue with processing of application specific +commands. + +Applications can also use SSL_CTX_cmd() to process command lines though the +utility function SSL_CTX_cmd_argv() is normally used instead. One way +to do this is to set the prefix to an appropriate value using +SSL_CONF_CTX_set1_prefix(), pass the current argument to B and the +following argument to B (which may be NULL). + +In this case if the return value is positive then it is used to skip that +number of arguments as they have been processed by SSL_CTX_cmd(). If -2 is +returned then B is not recognised and application specific arguments +can be checked instead. If -3 is returned a required argument is missing +and an error is indicated. If 0 is returned some other error occurred and +this can be reported back to the user. + +=head1 EXAMPLES + +Set supported signature algorithms: + + SSL_CONF_cmd(ctx, "SignatureAlgorithms", "ECDSA+SHA256:RSA+SHA256:DSA+SHA256"); + +Enable all protocols except SSLv3 and SSLv2: + + SSL_CONF_cmd(ctx, "Protocol", "ALL,-SSLv3,-SSLv2"); + +Only enable TLSv1.2: + + SSL_CONF_cmd(ctx, "Protocol", "-ALL,TLSv1.2"); + +Disable TLS session tickets: + + SSL_CONF_cmd(ctx, "Options", "-SessionTicket"); + +Set supported curves to P-256, P-384: + + SSL_CONF_cmd(ctx, "Curves", "P-256:P-384"); + +Set automatic support for any elliptic curve for key exchange: + + SSL_CONF_cmd(ctx, "ECDHParameters", "Automatic"); + +=head1 RETURN VALUES + +SSL_CONF_cmd() return 1 if the value of B is recognised and B is +B used and 2 if both B and B are used. In other words it +returns the number of arguments processed. This is useful when processing +command lines. + +A return value of -2 means B is not recognised. + +A return value of -3 means B is recognised and the command requires a +value but B is NULL. + +A return code of 0 indicates that both B and B are valid but an +error occurred attempting to perform the operation: for example due to an +error in the syntax of B in this case the error queue may provide +additional information. + +=head1 SEE ALSO + +L, +L, +L, +L, +L + +=head1 HISTORY + +SSL_CONF_cmd() was first added to OpenSSL 1.1.0 + +=cut diff --git a/doc/ssl/SSL_CONF_cmd_argv.pod b/doc/ssl/SSL_CONF_cmd_argv.pod new file mode 100644 index 0000000000..8d495ba5cb --- /dev/null +++ b/doc/ssl/SSL_CONF_cmd_argv.pod @@ -0,0 +1,42 @@ +=pod + +=head1 NAME + +SSL_CONF_cmd_argv - SSL configuration command line processing. + +=head1 SYNOPSIS + + #include + + int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv); + +=head1 DESCRIPTION + +The function SSL_CONF_cmd_argv() processes at most two command line +arguments from B and B. The values of B and B +are updated to reflect the number of command options procesed. The B +argument can be set to B is it is not used. + +=head1 RETURN VALUES + +SSL_CONF_cmd_argv() returns the number of command arguments processed: 0, 1, 2 +2 or a negative error code. + +If -2 is returned then an argument for a command is missing. + +If -1 is returned the command is recognised but couldn't be processed due +to an error: for example a syntax error in the argument. + +=head1 SEE ALSO + +L, +L, +L, +L, +L + +=head1 HISTORY + +These functions were first added to OpenSSL 1.1.0 + +=cut diff --git a/ssl/Makefile b/ssl/Makefile index 79541462b8..393dc7eaf6 100644 --- a/ssl/Makefile +++ b/ssl/Makefile @@ -29,8 +29,8 @@ LIBSRC= \ d1_both.c d1_enc.c d1_srtp.c \ ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \ ssl_ciph.c ssl_stat.c ssl_rsa.c \ - ssl_asn1.c ssl_txt.c ssl_algs.c \ - bio_ssl.c ssl_err.c kssl.c tls_srp.c t1_reneg.c t1_trce.c + ssl_asn1.c ssl_txt.c ssl_algs.c ssl_conf.c \ + bio_ssl.c ssl_err.c kssl.c t1_reneg.c tls_srp.c t1_trce.c LIBOBJ= \ s2_meth.o s2_srvr.o s2_clnt.o s2_lib.o s2_enc.o s2_pkt.o \ s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o \ @@ -40,8 +40,8 @@ LIBOBJ= \ d1_both.o d1_enc.o d1_srtp.o\ ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \ ssl_ciph.o ssl_stat.o ssl_rsa.o \ - ssl_asn1.o ssl_txt.o ssl_algs.o \ - bio_ssl.o ssl_err.o kssl.o tls_srp.o t1_reneg.o t1_trce.o + ssl_asn1.o ssl_txt.o ssl_algs.o ssl_conf.o \ + bio_ssl.o ssl_err.o kssl.o t1_reneg.o tls_srp.o t1_trce.o SRC= $(LIBSRC) diff --git a/ssl/ssl.h b/ssl/ssl.h index 09b5da00e2..e05077c2c5 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -367,6 +367,7 @@ typedef struct ssl_method_st SSL_METHOD; typedef struct ssl_cipher_st SSL_CIPHER; typedef struct ssl_session_st SSL_SESSION; typedef struct tls_sigalgs_st TLS_SIGALGS; +typedef struct ssl_conf_ctx_st SSL_CONF_CTX; DECLARE_STACK_OF(SSL_CIPHER) @@ -616,6 +617,9 @@ struct ssl_session_st #define SSL_OP_NO_TLSv1_2 0x08000000L #define SSL_OP_NO_TLSv1_1 0x10000000L +#define SSL_OP_NO_SSL_MASK (SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|\ + SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2) + /* These next two were never actually used for anything since SSLeay * zap so we have some more flags. */ @@ -693,6 +697,12 @@ struct ssl_session_st /* Cert chain suitable to Suite B */ #define CERT_PKEY_SUITEB 0x800 +#define SSL_CONF_FLAG_CMDLINE 0x1 +#define SSL_CONF_FLAG_FILE 0x2 +#define SSL_CONF_FLAG_CLIENT 0x4 +#define SSL_CONF_FLAG_SERVER 0x8 +#define SSL_CONF_FLAG_SHOW_ERRORS 0x10 + /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, * they cannot be used to clear bits. */ @@ -2254,6 +2264,18 @@ void SSL_set_debug(SSL *s, int debug); int SSL_cache_hit(SSL *s); int SSL_is_server(SSL *s); +SSL_CONF_CTX *SSL_CONF_CTX_new(void); +void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx); +unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags); +unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags); +int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre); + +void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl); +void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx); + +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); + #ifndef OPENSSL_NO_SSL_TRACE void SSL_trace(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg); @@ -2408,6 +2430,7 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL_CIPHER_STRENGTH_SORT 231 #define SSL_F_SSL_CLEAR 164 #define SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD 165 +#define SSL_F_SSL_CONF_CMD 334 #define SSL_F_SSL_CREATE_CIPHER_LIST 166 #define SSL_F_SSL_CTRL 232 #define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY 168 @@ -2548,6 +2571,7 @@ void ERR_load_SSL_strings(void); #define SSL_R_BAD_SSL_FILETYPE 124 #define SSL_R_BAD_SSL_SESSION_ID_LENGTH 125 #define SSL_R_BAD_STATE 126 +#define SSL_R_BAD_VALUE 384 #define SSL_R_BAD_WRITE_RETRY 127 #define SSL_R_BIO_NOT_SET 128 #define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 129 @@ -2603,6 +2627,7 @@ void ERR_load_SSL_strings(void); #define SSL_R_INVALID_CHALLENGE_LENGTH 158 #define SSL_R_INVALID_COMMAND 280 #define SSL_R_INVALID_COMPRESSION_ALGORITHM 341 +#define SSL_R_INVALID_NULL_CMD_NAME 385 #define SSL_R_INVALID_PURPOSE 278 #define SSL_R_INVALID_SRP_USERNAME 357 #define SSL_R_INVALID_STATUS_RESPONSE 328 @@ -2787,6 +2812,7 @@ void ERR_load_SSL_strings(void); #define SSL_R_UNKNOWN_CERTIFICATE_TYPE 247 #define SSL_R_UNKNOWN_CIPHER_RETURNED 248 #define SSL_R_UNKNOWN_CIPHER_TYPE 249 +#define SSL_R_UNKNOWN_CMD_NAME 386 #define SSL_R_UNKNOWN_DIGEST 368 #define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 250 #define SSL_R_UNKNOWN_PKEY_TYPE 251 diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c new file mode 100644 index 0000000000..437f385f05 --- /dev/null +++ b/ssl/ssl_conf.c @@ -0,0 +1,595 @@ +/*! \file ssl/ssl_conf.c + * \brief SSL configuration functions + */ +/* ==================================================================== + * Copyright (c) 2012 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifdef REF_CHECK +# include +#endif +#include +#include "ssl_locl.h" +#include +#include + +/* structure holding name tables. This is used for pemitted elements in + * lists such as TLSv1 and single command line switches such as no_tls1 + */ + +typedef struct + { + const char *name; + int namelen; + unsigned int name_flags; + unsigned long option_value; + } ssl_flag_tbl; + +/* Sense of name is inverted e.g. "TLSv1" will clear SSL_OP_NO_TLSv1 */ +#define SSL_TFLAG_INV 0x1 +/* Flags refers to cert_flags not options */ +#define SSL_TFLAG_CERT 0x2 +/* Option can only be used for clients */ +#define SSL_TFLAG_CLIENT SSL_CONF_FLAG_CLIENT +/* Option can only be used for servers */ +#define SSL_TFLAG_SERVER SSL_CONF_FLAG_SERVER +#define SSL_TFLAG_BOTH (SSL_TFLAG_CLIENT|SSL_TFLAG_SERVER) + +#define SSL_FLAG_TBL(str, flag) \ + {str, (int)(sizeof(str) - 1), SSL_TFLAG_BOTH, flag} +#define SSL_FLAG_TBL_SRV(str, flag) \ + {str, (int)(sizeof(str) - 1), SSL_TFLAG_SERVER, flag} +#define SSL_FLAG_TBL_CLI(str, flag) \ + {str, (int)(sizeof(str) - 1), SSL_TFLAG_CLIENT, flag} +#define SSL_FLAG_TBL_INV(str, flag) \ + {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_BOTH, flag} +#define SSL_FLAG_TBL_SRV_INV(str, flag) \ + {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_SERVER, flag} +#define SSL_FLAG_TBL_CERT(str, flag) \ + {str, (int)(sizeof(str) - 1), SSL_TFLAG_CERT|SSL_TFLAG_BOTH, flag} + +/* Opaque structure containing SSL configuration context. + */ + +struct ssl_conf_ctx_st + { + /* Various flags indicating (among other things) which options we + * will recognise. + */ + unsigned int flags; + /* Prefix and length of commands */ + char *prefix; + size_t prefixlen; + /* SSL_CTX or SSL structure to perform operations on */ + SSL_CTX *ctx; + SSL *ssl; + /* Pointer to SSL or SSL_CTX options field or NULL if none */ + unsigned long *poptions; + /* Pointer to SSL or SSL_CTX cert_flags or NULL if none */ + unsigned int *pcert_flags; + /* Current flag table being worked on */ + const ssl_flag_tbl *tbl; + /* Size of table */ + size_t ntbl; + }; + +static int ssl_match_option(SSL_CONF_CTX *cctx, const ssl_flag_tbl *tbl, + const char *name, int namelen, int onoff) + { + /* If name not relevant for context skip */ + if (!(cctx->flags & tbl->name_flags & SSL_TFLAG_BOTH)) + return 0; + if (namelen == -1) + { + if (strcmp(tbl->name, name)) + return 0; + } + else if (tbl->namelen != namelen || strncasecmp(tbl->name, name, namelen)) + return 0; + if (cctx->poptions) + { + if (tbl->name_flags & SSL_TFLAG_INV) + onoff ^= 1; + if (tbl->name_flags & SSL_TFLAG_CERT) + { + if (onoff) + *cctx->pcert_flags |= tbl->option_value; + else + *cctx->pcert_flags &= ~tbl->option_value; + } + else + { + if (onoff) + *cctx->poptions |= tbl->option_value; + else + *cctx->poptions &= ~tbl->option_value; + } + } + return 1; + } + +static int ssl_set_option_list(const char *elem, int len, void *usr) + { + SSL_CONF_CTX *cctx = usr; + size_t i; + const ssl_flag_tbl *tbl; + int onoff = 1; + /* len == -1 indicates not being called in list context, just for + * single command line switches, so don't allow +, -. + */ + if (len != -1) + { + if (*elem == '+') + { + elem++; + len--; + onoff = 1; + } + else if (*elem == '-') + { + elem++; + len--; + onoff = 0; + } + } + for (i = 0, tbl = cctx->tbl; i < cctx->ntbl; i++, tbl++) + { + if (ssl_match_option(cctx, tbl, elem, len, onoff)) + return 1; + } + return 0; + } + +/* Single command line switches with no argument e.g. -no_ssl3 */ +static int ctrl_str_option(SSL_CONF_CTX *cctx, const char *cmd) + { + static const ssl_flag_tbl ssl_option_single[] = + { + SSL_FLAG_TBL("no_ssl2", SSL_OP_NO_SSLv2), + SSL_FLAG_TBL("no_ssl3", SSL_OP_NO_SSLv3), + 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), +#ifndef OPENSSL_NO_TLSEXT + SSL_FLAG_TBL("no_ticket", SSL_OP_NO_TICKET), +#endif + SSL_FLAG_TBL_SRV("serverpref", SSL_OP_CIPHER_SERVER_PREFERENCE), + SSL_FLAG_TBL("legacy_renegotiation", SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION), + SSL_FLAG_TBL_SRV("legacy_server_connect", SSL_OP_LEGACY_SERVER_CONNECT), + SSL_FLAG_TBL_SRV_INV("no_legacy_server_connect", SSL_OP_LEGACY_SERVER_CONNECT), + SSL_FLAG_TBL_CERT("strict", SSL_CERT_FLAG_TLS_STRICT), +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + SSL_FLAG_TBL_CERT("debug_broken_protocol", SSL_CERT_FLAG_BROKEN_PROTOCOL), +#endif + }; + cctx->tbl = ssl_option_single; + cctx->ntbl = sizeof(ssl_option_single)/sizeof(ssl_flag_tbl); + return ssl_set_option_list(cmd, -1, cctx); + } + +/* Set supported signature algorithms */ +static int cmd_sigalgs(SSL_CONF_CTX *cctx, const char *value) + { + int rv; + if (cctx->ssl) + rv = SSL_set1_sigalgs_list(cctx->ssl, value); + /* NB: ctx == NULL performs syntax checking only */ + else + rv = SSL_CTX_set1_sigalgs_list(cctx->ctx, value); + return rv > 0; + } +/* Set supported client signature algorithms */ +static int cmd_client_sigalgs(SSL_CONF_CTX *cctx, const char *value) + { + int rv; + if (cctx->ssl) + rv = SSL_set1_client_sigalgs_list(cctx->ssl, value); + /* NB: ctx == NULL performs syntax checking only */ + else + rv = SSL_CTX_set1_client_sigalgs_list(cctx->ctx, value); + return rv > 0; + } + +static int cmd_curves(SSL_CONF_CTX *cctx, const char *value) + { + int rv; + if (cctx->ssl) + rv = SSL_set1_curves_list(cctx->ssl, value); + /* NB: ctx == NULL performs syntax checking only */ + else + rv = SSL_CTX_set1_curves_list(cctx->ctx, value); + return rv > 0; + } + +/* ECDH temporary parameters */ +static int cmd_ecdhparam(SSL_CONF_CTX *cctx, const char *value) + { + int onoff = -1, rv = 1; + if (!(cctx->flags & SSL_CONF_FLAG_SERVER)) + return -2; + if (cctx->flags & SSL_CONF_FLAG_FILE) + { + if (*value == '+') + { + onoff = 1; + value++; + } + if (*value == '-') + { + onoff = 0; + value++; + } + if (!strcasecmp(value, "automatic")) + { + if (onoff == -1) + onoff = 1; + } + else if (onoff != -1) + return 0; + } + else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) + { + if (!strcmp(value, "auto")) + onoff = 1; + } + + if (onoff != -1) + { + if (cctx->ctx) + rv = SSL_CTX_set_ecdh_auto(cctx->ctx, onoff); + else if (cctx->ssl) + rv = SSL_set_ecdh_auto(cctx->ssl, onoff); + } + else + { + EC_KEY *ecdh; + int nid; + nid = EC_curve_nist2nid(value); + if (nid == NID_undef) + nid = OBJ_sn2nid(value); + if (nid == 0) + return 0; + ecdh = EC_KEY_new_by_curve_name(nid); + if (!ecdh) + return 0; + if (cctx->ctx) + rv = SSL_CTX_set_tmp_ecdh(cctx->ctx, ecdh); + else if (cctx->ssl) + rv = SSL_set_tmp_ecdh(cctx->ssl, ecdh); + EC_KEY_free(ecdh); + } + + return rv > 0; + } + +static int cmd_cipher_list(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 > 0; + } + +static int cmd_protocol(SSL_CONF_CTX *cctx, const char *value) + { + static const ssl_flag_tbl ssl_protocol_list[] = + { + SSL_FLAG_TBL_INV("ALL", SSL_OP_NO_SSL_MASK), + SSL_FLAG_TBL_INV("SSLv2", SSL_OP_NO_SSLv2), + SSL_FLAG_TBL_INV("SSLv3", SSL_OP_NO_SSLv3), + SSL_FLAG_TBL_INV("TLSv1", SSL_OP_NO_TLSv1), + SSL_FLAG_TBL_INV("TLSv1.1", SSL_OP_NO_TLSv1_1), + SSL_FLAG_TBL_INV("TLSv1.2", SSL_OP_NO_TLSv1_2) + }; + if (!(cctx->flags & SSL_CONF_FLAG_FILE)) + return -2; + cctx->tbl = ssl_protocol_list; + cctx->ntbl = sizeof(ssl_protocol_list)/sizeof(ssl_flag_tbl); + return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx); + } + +static int cmd_options(SSL_CONF_CTX *cctx, const char *value) + { + static const ssl_flag_tbl ssl_option_list[] = + { + SSL_FLAG_TBL_INV("SessionTicket", SSL_OP_NO_TICKET), + SSL_FLAG_TBL_INV("EmptyFragments", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS), + SSL_FLAG_TBL("Bugs", SSL_OP_ALL), + SSL_FLAG_TBL_INV("Compression", SSL_OP_NO_COMPRESSION), + SSL_FLAG_TBL_SRV("ServerPreference", SSL_OP_CIPHER_SERVER_PREFERENCE), + SSL_FLAG_TBL_SRV("DHSingle", SSL_OP_SINGLE_DH_USE), + SSL_FLAG_TBL_SRV("ECDHSingle", SSL_OP_SINGLE_ECDH_USE), + SSL_FLAG_TBL("UnsafeLegacyRenegotiation", SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION), + }; + if (!(cctx->flags & SSL_CONF_FLAG_FILE)) + return -2; + if (value == NULL) + return -3; + cctx->tbl = ssl_option_list; + cctx->ntbl = sizeof(ssl_option_list)/sizeof(ssl_flag_tbl); + return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx); + } + +typedef struct + { + int (*cmd)(SSL_CONF_CTX *cctx, const char *value); + const char *str_file; + const char *str_cmdline; + } ssl_conf_cmd_tbl; + +/* Table of supported patameters */ + +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}, +}; + +int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value) + { + 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); + return 0; + } + /* If a prefix is set, check and skip */ + if (cctx->prefix) + { + if (strlen(cmd) <= cctx->prefixlen) + return -2; + if (cctx->flags & SSL_CONF_FLAG_CMDLINE && + strncmp(cmd, cctx->prefix, cctx->prefixlen)) + return -2; + if (cctx->flags & SSL_CONF_FLAG_FILE && + strncasecmp(cmd, cctx->prefix, cctx->prefixlen)) + return -2; + cmd += cctx->prefixlen; + } + else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) + { + if (*cmd != '-' || !cmd[1]) + return -2; + cmd++; + } + + /* Look for matching parameter name in table */ + for (i = 0, t = ssl_conf_cmds; + i < sizeof(ssl_conf_cmds)/sizeof(ssl_conf_cmd_tbl); i++, t++) + { + if (cctx->flags & SSL_CONF_FLAG_CMDLINE) + { + if (t->str_cmdline && !strcmp(t->str_cmdline, cmd)) + { + runcmd = t; + break; + } + } + if (cctx->flags & SSL_CONF_FLAG_FILE) + { + if (t->str_file && !strcasecmp(t->str_file, cmd)) + { + runcmd = t; + break; + } + } + } + + if (runcmd) + { + int rv; + if (value == NULL) + return -3; + rv = t->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_CMD, SSL_R_BAD_VALUE); + ERR_add_error_data(4, "cmd=", cmd, ", value=", value); + } + return 0; + } + + if (cctx->flags & SSL_CONF_FLAG_CMDLINE) + { + if (ctrl_str_option(cctx, cmd)) + return 1; + } + + if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) + { + SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_UNKNOWN_CMD_NAME); + ERR_add_error_data(2, "cmd=", cmd); + } + + return -2; + } + +int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv) + { + int rv; + const char *arg = NULL, *argn; + if (pargc && *pargc == 0) + return 0; + if (!pargc || *pargc > 0) + arg = **pargv; + if (arg == NULL) + return 0; + if (!pargc || *pargc > 1) + argn = (*pargv)[1]; + else + argn = NULL; + cctx->flags &= ~SSL_CONF_FLAG_FILE; + cctx->flags |= SSL_CONF_FLAG_CMDLINE; + rv = SSL_CONF_cmd(cctx, arg, argn); + if (rv > 0) + { + /* Success: update pargc, pargv */ + (*pargv) += rv; + if (pargc) + (*pargc) -= rv; + return rv; + } + /* Unknown swicth: indicate no arguments processed */ + if (rv == -2) + return 0; + /* Some error occurred processing command, return fatal error */ + if (rv == 0) + return -1; + return rv; + } + +SSL_CONF_CTX *SSL_CONF_CTX_new(void) + { + SSL_CONF_CTX *ret; + ret = OPENSSL_malloc(sizeof(SSL_CONF_CTX)); + if (ret) + { + ret->flags = 0; + ret->prefix = NULL; + ret->prefixlen = 0; + ret->ssl = NULL; + ret->ctx = NULL; + ret->poptions = NULL; + ret->pcert_flags = NULL; + ret->tbl = NULL; + ret->ntbl = 0; + } + return ret; + } + +void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx) + { + if (cctx) + { + if (cctx->prefix) + OPENSSL_free(cctx->prefix); + OPENSSL_free(cctx); + } + } + +unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags) + { + cctx->flags |= flags; + return cctx->flags; + } + +unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags) + { + cctx->flags &= ~flags; + return cctx->flags; + } + +int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre) + { + char *tmp = NULL; + if (pre) + { + tmp = BUF_strdup(pre); + if (tmp == NULL) + return 0; + } + if (cctx->prefix) + OPENSSL_free(cctx->prefix); + cctx->prefix = tmp; + if (tmp) + cctx->prefixlen = strlen(tmp); + else + cctx->prefixlen = 0; + return 1; + } + +void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl) + { + cctx->ssl = ssl; + cctx->ctx = NULL; + if (ssl) + { + cctx->poptions = &ssl->options; + cctx->pcert_flags = &ssl->cert->cert_flags; + } + else + { + cctx->poptions = NULL; + cctx->pcert_flags = NULL; + } + } + +void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx) + { + cctx->ctx = ctx; + cctx->ssl = NULL; + if (ctx) + { + cctx->poptions = &ctx->options; + cctx->pcert_flags = &ctx->cert->cert_flags; + } + else + { + cctx->poptions = NULL; + cctx->pcert_flags = NULL; + } + } diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index e21f6e5cb1..ed435c6a60 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -209,6 +209,7 @@ static ERR_STRING_DATA SSL_str_functs[]= {ERR_FUNC(SSL_F_SSL_CIPHER_STRENGTH_SORT), "SSL_CIPHER_STRENGTH_SORT"}, {ERR_FUNC(SSL_F_SSL_CLEAR), "SSL_clear"}, {ERR_FUNC(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD), "SSL_COMP_add_compression_method"}, +{ERR_FUNC(SSL_F_SSL_CONF_CMD), "SSL_CONF_cmd"}, {ERR_FUNC(SSL_F_SSL_CREATE_CIPHER_LIST), "ssl_create_cipher_list"}, {ERR_FUNC(SSL_F_SSL_CTRL), "SSL_ctrl"}, {ERR_FUNC(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY), "SSL_CTX_check_private_key"}, @@ -352,6 +353,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_BAD_SSL_FILETYPE) ,"bad ssl filetype"}, {ERR_REASON(SSL_R_BAD_SSL_SESSION_ID_LENGTH),"bad ssl session id length"}, {ERR_REASON(SSL_R_BAD_STATE) ,"bad state"}, +{ERR_REASON(SSL_R_BAD_VALUE) ,"bad value"}, {ERR_REASON(SSL_R_BAD_WRITE_RETRY) ,"bad write retry"}, {ERR_REASON(SSL_R_BIO_NOT_SET) ,"bio not set"}, {ERR_REASON(SSL_R_BLOCK_CIPHER_PAD_IS_WRONG),"block cipher pad is wrong"}, @@ -407,6 +409,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"}, {ERR_REASON(SSL_R_INVALID_COMMAND) ,"invalid command"}, {ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),"invalid compression algorithm"}, +{ERR_REASON(SSL_R_INVALID_NULL_CMD_NAME) ,"invalid null cmd name"}, {ERR_REASON(SSL_R_INVALID_PURPOSE) ,"invalid purpose"}, {ERR_REASON(SSL_R_INVALID_SRP_USERNAME) ,"invalid srp username"}, {ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE),"invalid status response"}, @@ -591,6 +594,7 @@ static ERR_STRING_DATA SSL_str_reasons[]= {ERR_REASON(SSL_R_UNKNOWN_CERTIFICATE_TYPE),"unknown certificate type"}, {ERR_REASON(SSL_R_UNKNOWN_CIPHER_RETURNED),"unknown cipher returned"}, {ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE) ,"unknown cipher type"}, +{ERR_REASON(SSL_R_UNKNOWN_CMD_NAME) ,"unknown cmd name"}, {ERR_REASON(SSL_R_UNKNOWN_DIGEST) ,"unknown digest"}, {ERR_REASON(SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE),"unknown key exchange type"}, {ERR_REASON(SSL_R_UNKNOWN_PKEY_TYPE) ,"unknown pkey type"}, diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 6e1b27c5fa..cf435d080c 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -1168,6 +1168,20 @@ LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx) long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd,long larg,void *parg) { long l; + /* For some cases with ctx == NULL perform syntax checks */ + if (ctx == NULL) + { + switch (cmd) + { + case SSL_CTRL_SET_CURVES_LIST: + return tls1_set_curves_list(NULL, NULL, parg); + case SSL_CTRL_SET_SIGALGS_LIST: + case SSL_CTRL_SET_CLIENT_SIGALGS_LIST: + return tls1_set_sigalgs_list(NULL, parg, 0); + default: + return 0; + } + } switch (cmd) { -- 2.40.0