add SSL_CONF functions and documentation (backport from HEAD)
authorDr. Stephen Henson <steve@openssl.org>
Sat, 29 Dec 2012 13:30:56 +0000 (13:30 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sat, 29 Dec 2012 13:30:56 +0000 (13:30 +0000)
12 files changed:
CHANGES
doc/ssl/SSL_CONF_CTX_new.pod [new file with mode: 0644]
doc/ssl/SSL_CONF_CTX_set1_prefix.pod [new file with mode: 0644]
doc/ssl/SSL_CONF_CTX_set_flags.pod [new file with mode: 0644]
doc/ssl/SSL_CONF_CTX_set_ssl_ctx.pod [new file with mode: 0644]
doc/ssl/SSL_CONF_cmd.pod [new file with mode: 0644]
doc/ssl/SSL_CONF_cmd_argv.pod [new file with mode: 0644]
ssl/Makefile
ssl/ssl.h
ssl/ssl_conf.c [new file with mode: 0644]
ssl/ssl_err.c
ssl/ssl_lib.c

diff --git a/CHANGES b/CHANGES
index 31f983472440ae68734a2145bc618247af9c596b..c6357393e3b21297a2c3e604474fe6d2d401dbea 100644 (file)
--- 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 (file)
index 0000000..1ae4ac6
--- /dev/null
@@ -0,0 +1,40 @@
+=pod
+
+=head1 NAME
+
+SSL_CONF_CTX_new, SSL_CONF_CTX_free - SSL configuration allocation functions
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ 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<SSL_CONF_CTX>
+structure for use with the SSL_CONF functions.
+
+The function SSL_CONF_CTX_free() frees up the context B<cctx>.
+
+=head1 RETURN VALUES
+
+SSL_CONF_CTX_new() returns either the newly allocated B<SSL_CONF_CTX> structure
+or B<NULL> if an error occurs.
+
+SSL_CONF_CTX_free() does not return a value.
+
+=head1 SEE ALSO
+
+L<SSL_CONF_CTX_set_flags(3)|SSL_CONF_CTX_set_flags(3)>,
+L<SSL_CONF_CTX_set_ssl_ctx(3)|SSL_CONF_CTX_set_ssl_ctx(3)>,
+L<SSL_CONF_CTX_set1_prefix(3)|SSL_CONF_CTX_set1_prefix(3)>,
+L<SSL_CONF_cmd(3)|SSL_CONF_cmd(3)>,
+L<SSL_CONF_cmd_argv(3)|SSL_CONF_cmd_argv(3)>
+
+=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 (file)
index 0000000..3b165db
--- /dev/null
@@ -0,0 +1,49 @@
+=pod
+
+=head1 NAME
+
+SSL_CONF_CTX_set1_prefix - Set configuration context command prefix
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ 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<cctx>
+to B<prefix>. If B<prefix> is B<NULL> 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<SSL_CONF_FLAG_CMDLINE> 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<SSL_CONF_FLAG_FILE> 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<SSL_CONF_CTX_new(3)|SSL_CONF_CTX_new(3)>,
+L<SSL_CONF_CTX_set_flags(3)|SSL_CONF_CTX_set_flags(3)>,
+L<SSL_CONF_CTX_set_ssl_ctx(3)|SSL_CONF_CTX_set_ssl_ctx(3)>,
+L<SSL_CONF_cmd(3)|SSL_CONF_cmd(3)>,
+L<SSL_CONF_cmd_argv(3)|SSL_CONF_cmd_argv(3)>
+
+=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 (file)
index 0000000..90d97e7
--- /dev/null
@@ -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 <openssl/ssl.h>
+
+ 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<flags> in the context B<cctx>.
+
+The function SSL_CONF_CTX_clear_flags() clears B<flags> in the context B<cctx>.
+
+=head1 NOTES
+
+The flags set affect how subsequent calls to SSL_CONF_cmd() or
+SSL_CONF_argv() behave.
+
+Currently the following B<flags> 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<SSL_CONF_CTX_new(3)|SSL_CONF_CTX_new(3)>,
+L<SSL_CONF_CTX_set_ssl_ctx(3)|SSL_CONF_CTX_set_ssl_ctx(3)>,
+L<SSL_CONF_CTX_set1_prefix(3)|SSL_CONF_CTX_set1_prefix(3)>,
+L<SSL_CONF_cmd(3)|SSL_CONF_cmd(3)>,
+L<SSL_CONF_cmd_argv(3)|SSL_CONF_cmd_argv(3)>
+
+=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 (file)
index 0000000..cfb7cb2
--- /dev/null
@@ -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 <openssl/ssl.h>
+
+ 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<cctx> to the
+B<SSL_CTX> structure B<ctx>. Any previos B<SSL> or B<SSL_CTX> associated with
+B<cctx> is cleared. Subsequent calls to SSL_CONF_cmd() will be sent to
+B<ctx>.
+
+SSL_CONF_CTX_set_ssl() sets the context associated with B<cctx> to the
+B<SSL> structure B<ssl>. Any previos B<SSL> or B<SSL_CTX> associated with
+B<cctx> is cleared. Subsequent calls to SSL_CONF_cmd() will be sent to
+B<ssl>.
+
+=head1 NOTES
+
+The context need not be set or it can be set to B<NULL> 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<SSL_CONF_CTX_new(3)|SSL_CONF_CTX_new(3)>,
+L<SSL_CONF_CTX_set_flags(3)|SSL_CONF_CTX_set_flags(3)>,
+L<SSL_CONF_CTX_set1_prefix(3)|SSL_CONF_CTX_set1_prefix(3)>,
+L<SSL_CONF_cmd(3)|SSL_CONF_cmd(3)>,
+L<SSL_CONF_cmd_argv(3)|SSL_CONF_cmd_argv(3)>
+
+=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 (file)
index 0000000..0fbf0d7
--- /dev/null
@@ -0,0 +1,342 @@
+=pod
+
+=head1 NAME
+
+SSL_CONF_cmd - send configuration command
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ 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<cmd> with
+optional parameter B<value> on B<ctx>. Its purpose is to simplify application
+configuration of B<SSL_CTX> or B<SSL> structures by providing a common
+framework for command line options or configuration files.
+
+=head1 SUPPORTED COMMAND LINE COMMANDS
+
+Currently supported B<cmd> names for command lines (i.e. when the
+flag B<SSL_CONF_CMDLINE> is set) are listed below. Note: all B<cmd> names
+and are case sensitive. Unless otherwise stated commands can be used by
+both clients and servers and the B<value> 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<value> argument should be a colon separated list of signature algorithms
+in order of decreasing preference of the form B<algorithm+hash>. B<algorithm>
+is one of B<RSA>, B<DSA> or B<ECDSA> and B<hash> is a supported algorithm
+OID short name such as B<SHA1>, B<SHA224>, B<SHA256>, B<SHA384> of B<SHA512>.
+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<value> 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<value> argument is a colon separated list of curves. The curve can be
+either the B<NIST> name (e.g. B<P-256>) or an OpenSSL OID name (e.g
+B<prime256v1>). 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<value> argument is a curve name or the special value B<auto> which
+picks an appropriate curve based on client and server preferences. The curve
+can be either the B<NIST> name (e.g. B<P-256>) or an OpenSSL OID name
+(e.g B<prime256v1>). Curve names are case sensitive.
+
+=item B<-cipher>
+
+Sets the cipher suite list to B<value>. Note: syntax checking of B<value> is
+currently not performed unless a B<SSL> or B<SSL_CTX> structure is 
+associated with B<cctx>.
+
+=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<SSL_OP_NO_SSL2>, B<SSL_OP_NO_SSL3>,
+B<SSL_OP_NO_TLS1>, B<SSL_OP_NO_TLS1_1> and B<SSL_OP_NO_TLS1_2> respectively.
+
+=item B<-bugs>
+
+Various bug workarounds are set, same as setting B<SSL_OP_ALL>.
+
+=item B<-no_comp>
+
+Disables support for SSL/TLS compression, same as setting B<SSL_OP_NO_COMPRESS>.
+
+=item B<-no_ticket>
+
+Disables support for session tickets, same as setting B<SSL_OP_NO_TICKET>.
+
+=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<SSL_OP_CIPHER_SERVER_PREFERENCE>. Only used by servers.
+
+=item B<-legacyrenegotiation>
+
+permits the use of unsafe legacy renegotiation. Equivalent to setting
+B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION>.
+
+=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<SSL_OP_LEGACY_SERVER_CONNECT>.
+Set by default.
+
+=item B<-strict>
+
+enables strict mode protocol handling. Equivalent to setting
+B<SSL_CERT_FLAG_TLS_STRICT>.
+
+=item B<-debug_broken_protocol>
+
+disables various checks and permits several kinds of broken protocol behaviour
+for testing purposes: it should B<NEVER> 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<cmd> names for configuration files (i.e. when the
+flag B<SSL_CONF_FLAG_FILE> is set) are listed below. All configuration file
+B<cmd> names and are case insensitive so B<signaturealgorithms> is recognised
+as well as B<SignatureAlgorithms>. Unless otherwise stated the B<value> names
+are also case insensitive.
+
+Note: the command prefix (if set) alters the recognised B<cmd> values.
+
+=over 4
+
+=item B<CipherString>
+
+Sets the cipher suite list to B<value>. Note: syntax checking of B<value> is
+currently not performed unless an B<SSL> or B<SSL_CTX> structure is 
+associated with B<cctx>.
+
+=item B<SignatureAlgorithms>
+
+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<value> argument should be a colon separated list of signature algorithms
+in order of decreasing preference of the form B<algorithm+hash>. B<algorithm>
+is one of B<RSA>, B<DSA> or B<ECDSA> and B<hash> is a supported algorithm
+OID short name such as B<SHA1>, B<SHA224>, B<SHA256>, B<SHA384> of B<SHA512>.
+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<ClientSignatureAlgorithms>
+
+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<value> is identical to B<SignatureAlgorithms>. If not set then
+the value set for B<SignatureAlgorithms> 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<value> argument is a colon separated list of curves. The curve can be
+either the B<NIST> name (e.g. B<P-256>) or an OpenSSL OID name (e.g
+B<prime256v1>). Curve names are case sensitive.
+
+=item B<ECDHParameters>
+
+This sets the temporary curve used for ephemeral ECDH modes. Only used by 
+servers
+
+The B<value> argument is a curve name or the special value B<Automatic> which
+picks an appropriate curve based on client and server preferences. The curve
+can be either the B<NIST> name (e.g. B<P-256>) or an OpenSSL OID name
+(e.g B<prime256v1>). Curve names are case sensitive.
+
+=item B<Protocol>
+
+The supported versions of the SSL or TLS protocol.
+
+The B<value> 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<SSLv2>,
+B<SSLv3>, B<TLSv1>, B<TLSv1.1> and B<TLSv1.2>. The special value B<ALL> refers
+to all supported versions.
+
+=item B<Options>
+
+The B<value> argument is a comma separated list of various flags to set.
+If a flag string is preceded B<-> it is disabled. See the
+B<SSL_CTX_set_options> 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<SessionTicket>: session ticket support, enabled by default. Inverse of
+B<SSL_OP_NO_TICKET>: that is B<-SessionTicket> is the same as setting
+B<SSL_OP_NO_TICKET>.
+
+B<Compression>: SSL/TLS compression support, enabled by default. Inverse
+of B<SSL_OP_NO_COMPRESSION>.
+
+B<EmptyFragments>: 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<SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS>.
+
+B<Bugs>: enable various bug workarounds. Same as B<SSL_OP_ALL>.
+
+B<DHSingle>: enable single use DH keys, set by default. Inverse of
+B<SSL_OP_DH_SINGLE>. Only used by servers.
+
+B<ECDHSingle> enable single use ECDH keys, set by default. Inverse of
+B<SSL_OP_ECDH_SINGLE>. Only used by servers.
+
+B<ServerPreference> 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<SSL_OP_CIPHER_SERVER_PREFERENCE>. Only used by servers.
+
+B<UnsafeLegacyRenegotiation> permits the use of unsafe legacy renegotiation.
+Equivalent to B<SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION>.
+
+B<UnsafeLegacyServerConnect> permits the use of unsafe legacy renegotiation
+for OpenSSL clients only. Equivalent to B<SSL_OP_LEGACY_SERVER_CONNECT>.
+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<always> 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<cmd> 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<cmd> and the
+following argument to B<value> (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<cmd> 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<cmd> is recognised and B<value> is
+B<NOT> used and 2 if both B<cmd> and B<value> 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<cmd> is not recognised.
+
+A return value of -3 means B<cmd> is recognised and the command requires a
+value but B<value> is NULL.
+
+A return code of 0 indicates that both B<cmd> and B<value> are valid but an
+error occurred attempting to perform the operation: for example due to an
+error in the syntax of B<value> in this case the error queue may provide
+additional information.
+
+=head1 SEE ALSO
+
+L<SSL_CONF_CTX_new(3)|SSL_CONF_CTX_new(3)>,
+L<SSL_CONF_CTX_set_flags(3)|SSL_CONF_CTX_set_flags(3)>,
+L<SSL_CONF_CTX_set1_prefix(3)|SSL_CONF_CTX_set1_prefix(3)>,
+L<SSL_CONF_CTX_set_ssl_ctx(3)|SSL_CONF_CTX_set_ssl_ctx(3)>,
+L<SSL_CONF_cmd_argv(3)|SSL_CONF_cmd_argv(3)>
+
+=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 (file)
index 0000000..8d495ba
--- /dev/null
@@ -0,0 +1,42 @@
+=pod
+
+=head1 NAME
+
+SSL_CONF_cmd_argv - SSL configuration command line processing.
+
+=head1 SYNOPSIS
+
+ #include <openssl/ssl.h>
+
+ 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<pargv> and B<pargc>. The values of B<pargv> and B<pargc>
+are updated to reflect the number of command options procesed. The B<pargc>
+argument can be set to B<NULL> 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<SSL_CONF_CTX_new(3)|SSL_CONF_CTX_new(3)>,
+L<SSL_CONF_CTX_set_flags(3)|SSL_CONF_CTX_set_flags(3)>,
+L<SSL_CONF_CTX_set1_prefix(3)|SSL_CONF_CTX_set1_prefix(3)>,
+L<SSL_CONF_CTX_set_ssl_ctx(3)|SSL_CONF_CTX_set_ssl_ctx(3)>,
+L<SSL_CONF_cmd(3)|SSL_CONF_cmd(3)>
+
+=head1 HISTORY
+
+These functions were first added to OpenSSL 1.1.0
+
+=cut
index 79541462b8e8c0061dcdfbd1bd62eb024a8a045a..393dc7eaf67c6b2d244d5b1fa0d9dc855317b794 100644 (file)
@@ -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)
 
index 09b5da00e2d18db7a29633e56c9bc3350259702b..e05077c2c568f704ee0a4c4d7f013afa17d3142e 100644 (file)
--- 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 (file)
index 0000000..437f385
--- /dev/null
@@ -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 <assert.h>
+#endif
+#include <stdio.h>
+#include "ssl_locl.h"
+#include <openssl/conf.h>
+#include <openssl/objects.h>
+
+/* 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;
+               }
+       }
index e21f6e5cb11c7cfae7538883f8ccf04e59006110..ed435c6a6030053f018e3fc014b5ff63e5706081 100644 (file)
@@ -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"},
index 6e1b27c5fae8a2904b7db63a40745883f37e4449..cf435d080c5e259507424d57b6de0800e75b4efa 100644 (file)
@@ -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)
                {