summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Antonuk <alan.antonuk@gmail.com>2015-10-20 23:02:31 -0700
committerAlan Antonuk <alan.antonuk@gmail.com>2015-10-20 23:19:37 -0700
commit667ee721a72d52799c2f443fa13d4f00003d36f8 (patch)
tree03c2c7110b21042cdc0e9fc374019e13e39a88e9
parent70d7c2d611ad7cf7905fe284c4a95274c613fda2 (diff)
downloadrabbitmq-c-tls_version.tar.gz
Lib: add amqp_ssl_socket_set_versions fntls_version
Add amqp_ssl_socket_versions function which allows a user to specify the acceptable range of TLS versions they want to connect to the broker with.
-rw-r--r--librabbitmq/amqp.h4
-rw-r--r--librabbitmq/amqp_api.c3
-rw-r--r--librabbitmq/amqp_openssl.c60
-rw-r--r--librabbitmq/amqp_ssl_socket.h30
4 files changed, 95 insertions, 2 deletions
diff --git a/librabbitmq/amqp.h b/librabbitmq/amqp.h
index 5121097..ed5f35a 100644
--- a/librabbitmq/amqp.h
+++ b/librabbitmq/amqp.h
@@ -726,7 +726,9 @@ typedef enum amqp_status_enum_
AMQP_STATUS_BROKER_UNSUPPORTED_SASL_METHOD = -0x0013, /**< Broker does not
support the requested
SASL mechanism */
- _AMQP_STATUS_NEXT_VALUE = -0x0014, /**< Internal value */
+ AMQP_STATUS_UNSUPPORTED = -0x0014, /**< Parameter is unsupported
+ in this version */
+ _AMQP_STATUS_NEXT_VALUE = -0x0015, /**< Internal value */
AMQP_STATUS_TCP_ERROR = -0x0100, /**< A generic TCP error
occurred */
diff --git a/librabbitmq/amqp_api.c b/librabbitmq/amqp_api.c
index f0c805e..9556ec5 100644
--- a/librabbitmq/amqp_api.c
+++ b/librabbitmq/amqp_api.c
@@ -82,7 +82,8 @@ static const char *base_error_strings[] = {
"unexpected protocol state", /* AMQP_STATUS_UNEXPECTED STATE -0x0010 */
"socket is closed", /* AMQP_STATUS_SOCKET_CLOSED -0x0011 */
"socket already open", /* AMQP_STATUS_SOCKET_INUSE -0x0012 */
- "unsupported sasl method requested" /* AMQP_STATUS_BROKER_UNSUPPORTED_SASL_METHOD -0x0013 */
+ "unsupported sasl method requested", /* AMQP_STATUS_BROKER_UNSUPPORTED_SASL_METHOD -0x0013 */
+ "parameter value is unsupported" /* AMQP_STATUS_UNSUPPORTED -0x0014 */
};
static const char *tcp_error_strings[] = {
diff --git a/librabbitmq/amqp_openssl.c b/librabbitmq/amqp_openssl.c
index f385bfd..bbb16e8 100644
--- a/librabbitmq/amqp_openssl.c
+++ b/librabbitmq/amqp_openssl.c
@@ -585,6 +585,66 @@ void amqp_ssl_socket_set_verify_hostname(amqp_socket_t *base,
self->verify_hostname = verify;
}
+int amqp_ssl_socket_set_ssl_versions(amqp_socket_t *base,
+ amqp_tls_version_t min,
+ amqp_tls_version_t max) {
+ struct amqp_ssl_socket_t *self;
+ if (base->klass != &amqp_ssl_socket_class) {
+ amqp_abort("<%p> is not of type amqp_ssl_socket_t", base);
+ }
+ self = (struct amqp_ssl_socket_t *)base;
+
+ {
+ long clear_options;
+ long set_options = 0;
+#if defined(SSL_OP_NO_TLSv1_2)
+ amqp_tls_version_t max_supported = AMQP_TLSv1_2;
+ clear_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2;
+#elif defined(SSL_OP_NO_TLSv1_1)
+ amqp_tls_version_t max_supported = AMQP_TLSv1_1;
+ clear_options = SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1;
+#elif defined(SSL_OP_NO_TLSv1)
+ amqp_tls_version_t max_supported = AMQP_TLSv1;
+ clear_options = SSL_OP_NO_TLSv1;
+#else
+# error "Need a version of OpenSSL that can support TLSv1 or greater."
+#endif
+
+ if (AMQP_TLSvLATEST == max) {
+ max = max_supported;
+ }
+ if (AMQP_TLSvLATEST == min) {
+ min = max_supported;
+ }
+
+ if (min > max) {
+ return AMQP_STATUS_INVALID_PARAMETER;
+ }
+
+ if (max > max_supported || min > max_supported) {
+ return AMQP_STATUS_UNSUPPORTED;
+ }
+
+ if (min > AMQP_TLSv1) {
+ set_options |= SSL_OP_NO_TLSv1;
+ }
+#ifdef SSL_OP_NO_TLSv1_1
+ if (min > AMQP_TLSv1_1 || max < AMQP_TLSv1_1) {
+ set_options |= SSL_OP_NO_TLSv1_1;
+ }
+#endif
+#ifdef SSL_OP_NO_TLSv1_2
+ if (max < AMQP_TLSv1_2) {
+ set_options |= SSL_OP_NO_TLSv1_2;
+ }
+#endif
+ SSL_CTX_clear_options(self->ctx, clear_options);
+ SSL_CTX_set_options(self->ctx, set_options);
+ }
+
+ return AMQP_STATUS_OK;
+}
+
void
amqp_set_initialize_ssl_library(amqp_boolean_t do_initialize)
{
diff --git a/librabbitmq/amqp_ssl_socket.h b/librabbitmq/amqp_ssl_socket.h
index 47b5ad1..45dcf5b 100644
--- a/librabbitmq/amqp_ssl_socket.h
+++ b/librabbitmq/amqp_ssl_socket.h
@@ -168,6 +168,36 @@ void
AMQP_CALL
amqp_ssl_socket_set_verify_hostname(amqp_socket_t *self, amqp_boolean_t verify);
+typedef enum {
+ AMQP_TLSv1 = 1,
+ AMQP_TLSv1_1 = 2,
+ AMQP_TLSv1_2 = 3,
+ AMQP_TLSvLATEST = 0xFFFF
+} amqp_tls_version_t;
+
+/**
+ * Set min and max TLS versions.
+ *
+ * Set the oldest and newest acceptable TLS versions that are acceptable when
+ * connecting to the broker. Set min == max to restrict to just that
+ * version.
+ *
+ * \param [in,out] self An SSL/TLS socket object.
+ * \param [in] min the minimum acceptable TLS version
+ * \param [in] max the maxmium acceptable TLS version
+ * \returns AMQP_STATUS_OK on success, AMQP_STATUS_UNSUPPORTED if OpenSSL does
+ * not support the requested TLS version, AMQP_STATUS_INVALID_PARAMETER if an
+ * invalid combination of parameters is passed.
+ *
+ * \since v0.8.0
+ */
+AMQP_PUBLIC_FUNCTION
+int
+AMQP_CALL
+amqp_ssl_socket_set_ssl_versions(amqp_socket_t *self,
+ amqp_tls_version_t min,
+ amqp_tls_version_t max);
+
/**
* Sets whether rabbitmq-c initializes the underlying SSL library.
*