2
0
Эх сурвалжийг харах

Merge pull request #481 from kamailio/tmp/hpw_curl_improvements

curl: Add various curl and TLS options to curl module
- client key/certificate
- cacert
- sslversion
- cipher suites
- verify_host and verify_peer
Hugh Waite 9 жил өмнө
parent
commit
1b6fe67edf

+ 19 - 17
modules/curl/curl.c

@@ -74,13 +74,16 @@ MODULE_VERSION
 /* Module parameter variables */
 unsigned int	default_connection_timeout = 4;
 char		*default_tls_cacert = NULL;		/*!< File name: Default CA cert to use for curl TLS connection */
-char		*default_tls_clientcert = NULL;		/*!< File name: Default client certificate to use for curl TLS connection */
-char		*default_tls_clientkey = NULL;		/*!< File name: Key in PEM format that belongs to client cert */
-unsigned int	default_tls_verifyserver = 1;		/*!< 0 = Do not verify TLS server cert. 1 = Verify TLS cert (default) */
+str		default_tls_clientcert = STR_NULL;		/*!< File name: Default client certificate to use for curl TLS connection */
+str		default_tls_clientkey = STR_NULL;		/*!< File name: Key in PEM format that belongs to client cert */
+str		default_cipher_suite_list = STR_NULL;		/*!< List of allowed cipher suites */
+unsigned int	default_tls_version = 0;		/*!< 0 = Use libcurl default */
+unsigned int	default_tls_verify_peer = 1;		/*!< 0 = Do not verify TLS server cert. 1 = Verify TLS cert (default) */
+unsigned int	default_tls_verify_host = 2;		/*!< 0 = Do not verify TLS server CN/SAN  2 = Verify TLS server CN/SAN (default) */
 char 		*default_http_proxy = NULL;		/*!< Default HTTP proxy to use */
 unsigned int	default_http_proxy_port = 0;		/*!< Default HTTP proxy port to use */
 unsigned int	default_http_follow_redirect = 0;	/*!< Follow HTTP redirects CURLOPT_FOLLOWLOCATION */
-char 		*default_useragent = CURL_USER_AGENT;	/*!< Default CURL useragent. Default "Kamailio Curl " */
+str 		default_useragent = { CURL_USER_AGENT, CURL_USER_AGENT_LEN };	/*!< Default CURL useragent. Default "Kamailio Curl " */
 unsigned int	default_maxdatasize = 0;		/*!< Default download size. 0=disabled */
 
 static curl_version_info_data *curl_info;
@@ -137,24 +140,20 @@ static param_export_t params[] = {
     	{"connection_timeout", PARAM_INT, &default_connection_timeout},
 	{"curlcon",  PARAM_STRING|USE_FUNC_PARAM, (void*)curl_con_param},
 	{"tlscacert", PARAM_STRING,  &default_tls_cacert },
-	{"tlsclientcert", PARAM_STRING, &default_tls_clientcert },
-	{"tlsclientkey", PARAM_STRING, &default_tls_clientkey },
-	{"tlsverifyserver", PARAM_INT, &default_tls_verifyserver },
+	{"tlsclientcert", PARAM_STR, &default_tls_clientcert },
+	{"tlsclientkey", PARAM_STR, &default_tls_clientkey },
+	{"tlscipherlist", PARAM_STR, &default_cipher_suite_list },
+	{"tlsversion", PARAM_INT, &default_tls_version },
+	{"tlsverifypeer", PARAM_INT, &default_tls_verify_peer },
+	{"tlsverifyhost", PARAM_INT, &default_tls_verify_host },
 	{"httpproxyport", PARAM_INT, &default_http_proxy_port },
 	{"httpproxy", PARAM_STRING, &default_http_proxy},
 	{"httpredirect", PARAM_INT, &default_http_follow_redirect },
-	{"useragent", PARAM_STRING,  &default_useragent },
+	{"useragent", PARAM_STR,  &default_useragent },
 	{"maxdatasize", PARAM_INT,  &default_maxdatasize },
     	{0, 0, 0}
 };
 
-//		str	default_tls_clientcert;			/*!< File name: Default client certificate to use for curl TLS connection */
-//		str	default_tls_clientkey;			/*!< File name: Key in PEM format that belongs to client cert */
-//		int	default_tls_verifyserver = 1;		/*!< 0 = Do not verify TLS server cert. 1 = Verify TLS cert (default) */
-//		str	default_http_proxy;			/*!< Default HTTP proxy to use */
-//		int	default_http_proxy_port;		/*!< Default HTTP proxy port to use */
-//		int	default_http_follow_redirect = 0;	/*!< Follow HTTP redirects CURLOPT_FOLLOWLOCATION */
-//		str	default_useragent;			/*!< Default CURL useragent. Default "Kamailio Curl " */
 
 /*!
  * \brief Exported Pseudo variables
@@ -249,10 +248,13 @@ static int mod_init(void)
 
 	LM_DBG("**** init curl module done. Curl version: %s SSL %s\n", curl_info->version, curl_info->ssl_version);
 	LM_DBG("**** init curl: Number of connection objects: %d \n", curl_connection_count());
-	LM_DBG("**** init curl: User Agent: %s \n", default_useragent);
+	LM_DBG("**** init curl: User Agent: %.*s \n", default_useragent.len, default_useragent.s);
 	LM_DBG("**** init curl: HTTPredirect: %d \n", default_http_follow_redirect);
-	LM_DBG("**** init curl: Client Cert: %s Key %s\n", default_tls_clientcert, default_tls_clientkey);
+	LM_DBG("**** init curl: Client Cert: %.*s Key %.*s\n", default_tls_clientcert.len, default_tls_clientcert.s, default_tls_clientkey.len, default_tls_clientkey.s);
 	LM_DBG("**** init curl: CA Cert: %s \n", default_tls_cacert);
+	LM_DBG("**** init curl: Cipher Suites: %.*s \n", default_cipher_suite_list.len, default_cipher_suite_list.s);
+	LM_DBG("**** init curl: SSL Version: %d \n", default_tls_version);
+	LM_DBG("**** init curl: verifypeer: %d verifyhost: %d\n", default_tls_verify_peer, default_tls_verify_host);
 	LM_DBG("**** init curl: HTTP Proxy: %s Port %d\n", default_http_proxy, default_http_proxy_port);
 
 	LM_DBG("Extra: Curl supports %s %s %s \n",

+ 17 - 10
modules/curl/curl.h

@@ -37,13 +37,16 @@
 
 extern unsigned int	default_connection_timeout;
 extern char	*default_tls_cacert;			/*!< File name: Default CA cert to use for curl TLS connection */
-extern char	*default_tls_clientcert;		/*!< File name: Default client certificate to use for curl TLS connection */
-extern char	*default_tls_clientkey;			/*!< File name: Key in PEM format that belongs to client cert */
-extern unsigned int	default_tls_verifyserver;		/*!< 0 = Do not verify TLS server cert. 1 = Verify TLS cert (default) */
+extern str	default_tls_clientcert;		/*!< File name: Default client certificate to use for curl TLS connection */
+extern str	default_tls_clientkey;			/*!< File name: Key in PEM format that belongs to client cert */
+extern str	default_cipher_suite_list;			/*!< List of allowed cipher suites */
+extern unsigned int	default_tls_version;		/*!< 0 = Use libcurl default */
+extern unsigned int	default_tls_verify_peer;	/*!< 0 = Do not verify TLS server cert. 1 = Verify TLS cert (default) */
+extern unsigned int	default_tls_verify_host;	/*!< 0 = Do not verify TLS server CN/SAN. 2 = Verify TLS server CN/SAN (default) */
 extern char 	*default_http_proxy;			/*!< Default HTTP proxy to use */
 extern unsigned int	default_http_proxy_port;		/*!< Default HTTP proxy port to use */
 extern unsigned int	default_http_follow_redirect;	/*!< Follow HTTP redirects CURLOPT_FOLLOWLOCATION */
-extern char 	*default_useragent;			/*!< Default CURL useragent. Default "Kamailio Curl " */
+extern str 	default_useragent;			/*!< Default CURL useragent. Default "Kamailio Curl " */
 extern unsigned int	default_maxdatasize;			/*!< Default Maximum download size */
 
 extern counter_handle_t connections;	/* Number of connection definitions */
@@ -66,13 +69,17 @@ typedef struct _curl_con
 	unsigned int conid;		/*!< Connection ID */
 	str url;			/*!< The URL without schema (host + base URL)*/
 	str schema;			/*!< The URL schema */
-	str username;			/*!< The username to use for auth */
-	str password;			/*!< The password to use for auth */
+	char *username;			/*!< The username to use for auth */
+	char *password;			/*!< The password to use for auth */
 	str failover;			/*!< Another connection to use if this one fails */
-	str cacert;			/*!< File name of CA cert to use */
-	str clientcert;			/*!< File name of CA client cert */
-	str useragent;			/*!< Useragent to use for this connection */
-	int tls_verifyserver;		/*!< TRUE if server cert needs to be verified */
+	char *useragent;		/*!< Useragent to use for this connection */
+	char *cacert;			/*!< File name of CA cert to use */
+	char *clientcert;		/*!< File name of CA client cert */
+	char *clientkey;		/*!< File name of CA client key */
+	char *ciphersuites;		/*!< List of allowed cipher suites */
+	unsigned int sslversion;	/*!< SSL/TLS version to use */
+	unsigned int verify_peer;	/*!< TRUE if server cert to be verified */
+	unsigned int verify_host;	/*!< TRUE if server CN/SAN to be verified */
 	int http_follow_redirect;	/*!< TRUE if we should follow HTTP 302 redirects */
 	unsigned int port;		/*!< The port to connect to */
 	int timeout;			/*!< Timeout for this connection */

+ 70 - 10
modules/curl/curlcon.c

@@ -26,6 +26,8 @@
  * \ingroup curl
  */
 
+#include <curl/curl.h>
+
 #include "../../hashes.h"
 #include "../../dprint.h"
 #include "../../parser/parse_param.h"
@@ -96,6 +98,8 @@ curl_con_t* curl_get_connection(str *name)
  *		useragent
  *		failover
  *		maxdatasize
+ *		verifypeer
+ *		verifyhost
  *
  */
 int curl_parse_param(char *val)
@@ -108,10 +112,17 @@ int curl_parse_param(char *val)
 	str params	= STR_NULL;
 	str failover	= STR_NULL;
 
+	str client_cert  = default_tls_clientcert;
+	str client_key   = default_tls_clientkey;
+	str ciphersuites = default_cipher_suite_list;
+	str useragent    = default_useragent;
+
 	unsigned int maxdatasize = default_maxdatasize;
 	unsigned int timeout	= default_connection_timeout;
-	str useragent   = { default_useragent, strlen(default_useragent) };
 	unsigned int http_follow_redirect = default_http_follow_redirect;
+	unsigned int verify_peer = default_tls_verify_peer;
+	unsigned int verify_host = default_tls_verify_host;
+	unsigned int sslversion = default_tls_version;
 
 	str in;
 	char *p;
@@ -119,8 +130,6 @@ int curl_parse_param(char *val)
 	param_t *conparams = NULL;
 	curl_con_t *cc;
 
-	username.len = 0;
-	password.len = 0;
 	LM_INFO("curl modparam parsing starting\n");
 	LM_DBG("modparam curlcon: %s\n", val);
 
@@ -300,6 +309,47 @@ int curl_parse_param(char *val)
 					maxdatasize = default_maxdatasize;
 				}
 				LM_DBG("curl [%.*s] - timeout [%d]\n", pit->name.len, pit->name.s, maxdatasize);
+			} else if(pit->name.len==10 && strncmp(pit->name.s, "verifypeer", 10)==0) {
+				if(str2int(&tok, &verify_peer)!=0) {
+					/* Bad integer */
+					LM_DBG("curl connection [%.*s]: verifypeer bad value. Using default\n", name.len, name.s);
+					verify_peer = default_tls_verify_peer;
+				}
+				if (verify_peer != 0 && verify_peer != 1) {
+					LM_DBG("curl connection [%.*s]: verifypeer bad value. Using default\n", name.len, name.s);
+					verify_peer = default_tls_verify_peer;
+				}
+				LM_DBG("curl [%.*s] - verifypeer [%d]\n", pit->name.len, pit->name.s, verify_peer);
+			} else if(pit->name.len==10 && strncmp(pit->name.s, "verifyhost", 10)==0) {
+				if(str2int(&tok, &verify_host)!=0) {
+					/* Bad integer */
+					LM_DBG("curl connection [%.*s]: verifyhost bad value. Using default\n", name.len, name.s);
+					verify_host = default_tls_verify_host;
+				}
+				LM_DBG("curl [%.*s] - verifyhost [%d]\n", pit->name.len, pit->name.s, verify_host);
+			} else if(pit->name.len==10 && strncmp(pit->name.s, "sslversion", 10)==0) {
+				if(str2int(&tok, &sslversion)!=0) {
+					/* Bad integer */
+					LM_DBG("curl connection [%.*s]: sslversion bad value. Using default\n", name.len, name.s);
+					sslversion = default_tls_version;
+				}
+				if (sslversion >= CURL_SSLVERSION_LAST) {
+					LM_DBG("curl connection [%.*s]: sslversion bad value. Using default\n", name.len, name.s);
+					sslversion = default_tls_version;
+				}
+				LM_DBG("curl [%.*s] - sslversion [%d]\n", pit->name.len, pit->name.s, sslversion);
+			} else if(pit->name.len==10 && strncmp(pit->name.s, "clientcert", 10)==0) {
+				client_cert = tok;
+				LM_DBG("curl [%.*s] - clientcert [%.*s]\n", pit->name.len, pit->name.s,
+						client_cert.len, client_cert.s);
+			} else if(pit->name.len==9 && strncmp(pit->name.s, "clientkey", 9)==0) {
+				client_key = tok;
+				LM_DBG("curl [%.*s] - clientkey [%.*s]\n", pit->name.len, pit->name.s,
+						client_key.len, client_key.s);
+			} else if(pit->name.len==12 && strncmp(pit->name.s, "ciphersuites", 12)==0) {
+				ciphersuites = tok;
+				LM_DBG("curl [%.*s] - ciphersuites [%.*s]\n", pit->name.len, pit->name.s,
+						ciphersuites.len, ciphersuites.s);
 			} else {
 				LM_ERR("curl Unknown parameter [%.*s] \n", pit->name.len, pit->name.s);
 			}
@@ -308,10 +358,6 @@ int curl_parse_param(char *val)
 
 	/* The URL ends either with nothing or parameters. Parameters start with ; */
 
-	LM_DBG("cname: [%.*s] url: [%.*s] username [%.*s] password [%.*s] failover [%.*s] timeout [%d] useragent [%.*s] maxdatasize [%d]\n", 
-			name.len, name.s, url.len, url.s, username.len, username.s,
-			password.len, password.s, failover.len, failover.s, timeout, useragent.len, useragent.s, maxdatasize);
-
 	if(conparams != NULL) {
 		free_params(conparams);
 	}
@@ -320,15 +366,29 @@ int curl_parse_param(char *val)
 	if (cc == NULL) {
 		return -1;
 	}
-	cc->username = username;
-	cc->password = password;
+
+	cc->username = username.s ? as_asciiz(&username) : NULL;
+	cc->password = password.s ? as_asciiz(&password) : NULL;
 	cc->schema = schema;
 	cc->failover = failover;
-	cc->useragent = useragent;
+	cc->useragent = as_asciiz(&useragent);
 	cc->url = url;
+	cc->clientcert = client_cert.s ? as_asciiz(&client_cert) : NULL;
+	cc->clientkey = client_key.s ? as_asciiz(&client_key) : NULL;
+	cc->ciphersuites = ciphersuites.s ? as_asciiz(&ciphersuites) : NULL;
+	cc->sslversion = sslversion;
+	cc->verify_peer = verify_peer;
+	cc->verify_host = verify_host;
 	cc->timeout = timeout;
 	cc->maxdatasize = maxdatasize;
 	cc->http_follow_redirect = http_follow_redirect;
+
+	LM_DBG("cname: [%.*s] url: [%.*s] username [%s] password [%s] failover [%.*s] timeout [%d] useragent [%s] maxdatasize [%d]\n", 
+			name.len, name.s, cc->url.len, cc->url.s, cc->username ? cc->username : "", cc->password ? cc->password : "",
+			cc->failover.len, cc->failover.s, cc->timeout, cc->useragent, cc->maxdatasize);
+	LM_DBG("cname: [%.*s] client_cert [%s] client_key [%s] ciphersuites [%s] sslversion [%d] verify_peer [%d] verify_host [%d]\n",
+			name.len, name.s, cc->clientcert, cc->clientkey, cc->ciphersuites, cc->sslversion, cc->verify_peer, cc->verify_host);
+
 	return 0;
 
 error:

+ 64 - 5
modules/curl/doc/curl_admin.xml

@@ -223,8 +223,30 @@ modparam("curl", "tlscacert", "/var/certs/ca/edvina-sip-ca.pem")
 				</programlisting>
 			</example>
 		</section>
-		<section id="curl.p.tlsverifyserver">
-			<title><varname>tlsverifyserver</varname> (int)</title>
+		<section id="curl.p.tlscipherlist">
+			<title><varname>tlscipherlist</varname> (string)</title>
+			<para>
+			List of allowed cipher suites.
+			See http://curl.haxx.se/libcurl/c/CURLOPT_SSL_CIPHER_LIST.html for details
+			of the cipher list curl option.
+			</para>
+			<para>
+			<emphasis>
+				Default value is empty string, i.e.
+				the default list of ciphers in libcurl will be used.
+			</emphasis>
+			</para>
+			<example>
+			<title>Set <varname>tlscipherlist</varname> parameter</title>
+				<programlisting format="linespecific">
+...
+modparam("curl", "tlscipherlist", "ecdhe_ecdsa_aes_128_gcm_sha_256,rsa_aes_128_gcm_sha_256")
+...
+				</programlisting>
+			</example>
+		</section>
+		<section id="curl.p.tlsverifypeer">
+			<title><varname>tlsverifypeer</varname> (int)</title>
 			<para>
 			If set to 0, TLS verification of the server certificate
 			is disabled. This means that the connection will get 
@@ -233,17 +255,45 @@ modparam("curl", "tlscacert", "/var/certs/ca/edvina-sip-ca.pem")
 			that is meant to receive data.
 			</para>
 			<para>
-			IF set to 1, default setting, and one or more CA certificates
+			If set to 1, default setting, and one or more CA certificates
 			is configured, the server TLS certificate will be validated.
 			If validation fails, the connection fails.
 			</para>
 			<para>
+			See the curl documenation for more details.
+			http://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html
 			</para>
 			<example>
-			<title>Set <varname>tlsverifyserver</varname> parameter</title>
+			<title>Set <varname>tlsverifypeer</varname> parameter</title>
 				<programlisting format="linespecific">
 ...
-modparam("curl", "tlsverifyserver", 1)
+modparam("curl", "tlsverifypeer", 1)
+...
+				</programlisting>
+			</example>
+		</section>
+		<section id="curl.p.tlsverifyhost">
+			<title><varname>tlsverifyhost</varname> (int)</title>
+			<para>
+			If set to 0, domain verification of the server certificate
+			is disabled. This means that the connection will get 
+			encrypted but there is no check that data will be sent to the
+			host that is meant to receive it. Disable with caution.
+			</para>
+			<para>
+			If set to 2, default setting, the hostname in the URL will
+			be verified against the Common Name or Subject Alt Name
+			in the certificate. If validation fails, the connection fails.
+			</para>
+			<para>
+			See the curl documentation for more details.
+			http://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html
+			</para>
+			<example>
+			<title>Set <varname>tlsverifyhost</varname> parameter</title>
+				<programlisting format="linespecific">
+...
+modparam("curl", "tlsverifyhost", 2)
 ...
 				</programlisting>
 			</example>
@@ -286,6 +336,15 @@ modparam("curl", "tlsverifyserver", 1)
 				<emphasis>useragent</emphasis> Useragent used for HTTP requests. Overrides
 				useragent modparam.
 				</para></listitem>
+				<listitem><para>
+				<emphasis>verifypeer</emphasis> Set to 1 to enable or 0 to disable server
+				certificate verification.
+				Overrides tlsverifypeer modparam.
+				</para></listitem>
+				<emphasis>verifyhost</emphasis> Set to 2 to enable or 0 to disable server
+				hostname verification.
+				Overrides tlsverifyhost modparam.
+				</para></listitem>
 			</itemizedlist>
 			</para>
 			<example>

+ 98 - 39
modules/curl/functions.c

@@ -45,10 +45,27 @@
 #include "curl.h"
 #include "curlcon.h"
 
+
+typedef struct {
+    char *username;
+    char *secret;
+    char *contenttype;
+    char *post;
+    char *clientcert;
+    char *clientkey;
+    char *cacert;
+    char *ciphersuites;
+    unsigned int sslversion;
+    unsigned int verify_peer;
+    unsigned int verify_host;
+    unsigned int timeout;
+    unsigned int http_follow_redirect;
+    unsigned int oneline;
+    unsigned int maxdatasize;
+} curl_query_t;
+
 /* Forward declaration */
-static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const char *username,
-		const char *secret, const char *contenttype, const char* _post, const unsigned int timeout,
-		unsigned int http_follow_redirect, unsigned int oneline, unsigned int maxdatasize);
+static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const curl_query_t * const query_params);
 
 /* 
  * curl write function that saves received data as zero terminated
@@ -86,7 +103,7 @@ size_t write_function( void *ptr, size_t size, size_t nmemb, void *stream_ptr)
 
 /*! Send query to server, optionally post data.
  */
-static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const char *_username, const char *_secret, const char *contenttype, const char* _post, unsigned int timeout, unsigned int http_follow_redirect, unsigned int oneline, unsigned int maxdatasize)
+static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const curl_query_t * const params)
 {
     CURL *curl;
     CURLcode res;  
@@ -99,7 +116,7 @@ static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const
     struct curl_slist *headerlist = NULL;
 
     memset(&stream, 0, sizeof(curl_res_stream_t));
-    stream.max_size = (size_t) maxdatasize;
+    stream.max_size = (size_t) params->maxdatasize;
 
     curl = curl_easy_init();
     if (curl == NULL) {
@@ -110,11 +127,11 @@ static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const
     LM_DBG("****** ##### CURL URL [%s] \n", _url);
     res = curl_easy_setopt(curl, CURLOPT_URL, _url);
 
-    if (_post) {
+    if (params->post) {
 	char ctype[256];
 
 	ctype[0] = '\0';
-	snprintf(ctype, sizeof(ctype), "Content-Type: %s", contenttype);
+	snprintf(ctype, sizeof(ctype), "Content-Type: %s", params->contenttype);
 
         /* Now specify we want to POST data */ 
 	res |= curl_easy_setopt(curl, CURLOPT_POST, 1L);
@@ -124,28 +141,51 @@ static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const
 
 	/* Tell CURL we want to upload using POST */
 
- 	res |= curl_easy_setopt(curl, CURLOPT_POSTFIELDS, _post);
+	res |= curl_easy_setopt(curl, CURLOPT_POSTFIELDS, params->post);
 
     }
 
-    if (maxdatasize) {
+    if (params->maxdatasize) {
 	/* Maximum data size to download - we always download full response, but
 	   cut it off before moving to pvar */
-    	LM_DBG("****** ##### CURL Max datasize %u\n", maxdatasize);
+	LM_DBG("****** ##### CURL Max datasize %u\n", params->maxdatasize);
     }
 
-    if (_username) {
- 	res |= curl_easy_setopt(curl, CURLOPT_USERNAME, _username);
+    if (params->username) {
+	res |= curl_easy_setopt(curl, CURLOPT_USERNAME, params->username);
 	res |= curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (CURLAUTH_DIGEST|CURLAUTH_BASIC));
     }
-    if (_secret) {
- 	res |= curl_easy_setopt(curl, CURLOPT_PASSWORD, _secret);
+    if (params->secret) {
+	res |= curl_easy_setopt(curl, CURLOPT_PASSWORD, params->secret);
+    }
+
+    /* Client certificate */
+    if (params->clientcert != NULL && params->clientkey != NULL) {
+        res |= curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM");
+        res |= curl_easy_setopt(curl, CURLOPT_SSLCERT, params->clientcert);
+
+        res |= curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM");
+        res |= curl_easy_setopt(curl, CURLOPT_SSLKEY, params->clientkey);
+    }
+
+    if (params->cacert != NULL) {
+        res |= curl_easy_setopt(curl, CURLOPT_CAINFO, params->cacert);
+    }
+
+    if (params->sslversion != CURL_SSLVERSION_DEFAULT) {
+        res |= curl_easy_setopt(curl, CURLOPT_SSLVERSION, (long) params->sslversion);
+    }
+
+    if (params->ciphersuites != NULL) {
+        res |= curl_easy_setopt(curl, CURLOPT_SSL_CIPHER_LIST, params->ciphersuites);
     }
 
+    res |= curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, (long) params->verify_peer);
+    res |= curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, (long) params->verify_host?2:0);
 
     res |= curl_easy_setopt(curl, CURLOPT_NOSIGNAL, (long) 1);
-    res |= curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long) timeout);
-    res |= curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, (long) http_follow_redirect);
+    res |= curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long) params->timeout);
+    res |= curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, (long) params->http_follow_redirect);
 
 
     res |= curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_function);
@@ -201,16 +241,16 @@ static int curL_query_url(struct sip_msg* _m, const char* _url, str* _dst, const
 
 	if (download_size > 0) {
 
-	if (oneline) {
+	if (params->oneline) {
 		/* search for line feed */
 		at = memchr(stream.buf, (char)10, download_size);
 		datasize = (double) (at - stream.buf);
 		LM_DBG("  -- curl download size cut to first line: %d \n", (int) datasize);
 	}
 	if (at == NULL) {
-		if (maxdatasize && ((unsigned int) download_size) > maxdatasize) {
+		if (params->maxdatasize && ((unsigned int) download_size) > params->maxdatasize) {
 			/* Limit at maximum data size */
-			datasize = (double) maxdatasize;
+			datasize = (double) params->maxdatasize;
 			LM_DBG("  -- curl download size cut to maxdatasize : %d \n", (int) datasize);
 		} else {
 			/* Limit at actual downloaded data size */
@@ -250,9 +290,8 @@ int curl_con_query_url(struct sip_msg* _m, const str *connection, const str* url
 {
 	curl_con_t *conn = NULL;
 	char *urlbuf = NULL;
-	char *username_str = NULL;
-	char *password_str = NULL;
 	char *postdata = NULL;
+	curl_query_t query_params;
 
 	unsigned int maxdatasize = default_maxdatasize;
 	int res;
@@ -269,14 +308,6 @@ int curl_con_query_url(struct sip_msg* _m, const str *connection, const str* url
 		return -1;
 	}
 	LM_DBG("******** CURL Connection found %.*s\n", connection->len, connection->s);
-	if (conn->username.s != NULL && conn->username.len > 0)
-	{
-		username_str = as_asciiz(&conn->username);
-	}
-	if (conn->password.s != NULL && conn->password.len > 0)
-	{
-		password_str = as_asciiz(&conn->password);
-	}
 	maxdatasize = conn->maxdatasize;
 
 
@@ -319,20 +350,30 @@ int curl_con_query_url(struct sip_msg* _m, const str *connection, const str* url
 		LM_DBG("***** #### ***** CURL POST data: %s Content-type %s\n", postdata, contenttype);
 	}
 
-	res = curL_query_url(_m, urlbuf, result, username_str, password_str, (contenttype ? contenttype : "text/plain"), postdata,
-		conn->timeout, conn->http_follow_redirect, 0, (unsigned int) maxdatasize );
+	memset(&query_params, 0, sizeof(curl_query_t));
+	query_params.username = conn->username;
+	query_params.secret = conn->password;
+	query_params.contenttype = contenttype ? (char*)contenttype : "text/plain";
+	query_params.post = postdata;
+	query_params.clientcert = conn->clientcert;
+	query_params.clientkey = conn->clientkey;
+	query_params.cacert = default_tls_cacert;
+	query_params.ciphersuites = conn->ciphersuites;
+	query_params.sslversion = conn->sslversion;
+	query_params.verify_peer = conn->verify_peer;
+	query_params.verify_host = conn->verify_host;
+	query_params.timeout = conn->timeout;
+	query_params.http_follow_redirect = conn->http_follow_redirect;
+	query_params.oneline = 0;
+	query_params.maxdatasize = maxdatasize;
+
+	res = curL_query_url(_m, urlbuf, result, &query_params);
 
 	LM_DBG("***** #### ***** CURL DONE : %s \n", urlbuf);
 error:
 	if (urlbuf != NULL) {
 		pkg_free(urlbuf);
 	}
-	if (username_str != NULL) {
-		pkg_free(username_str);
-	}
-	if (password_str != NULL) {
-		pkg_free(password_str);
-	}
 	if (postdata != NULL) {
 		pkg_free(postdata);
 	}
@@ -348,8 +389,26 @@ error:
 int http_query(struct sip_msg* _m, char* _url, str* _dst, char* _post)
 {
 	int res;
-
-	res =  curL_query_url(_m, _url, _dst, NULL, NULL, "text/plain", _post, default_connection_timeout, default_http_follow_redirect, 1, 0);
+	curl_query_t query_params;
+
+	memset(&query_params, 0, sizeof(curl_query_t));
+	query_params.username = NULL;
+	query_params.secret = NULL;
+	query_params.contenttype = "text/plain";
+	query_params.post = _post;
+	query_params.clientcert = NULL;
+	query_params.clientkey = NULL;
+	query_params.cacert = NULL;
+	query_params.ciphersuites = NULL;
+	query_params.sslversion = default_tls_version;
+	query_params.verify_peer = default_tls_verify_peer;
+	query_params.verify_host = default_tls_verify_host;
+	query_params.timeout = default_connection_timeout;
+	query_params.http_follow_redirect = default_http_follow_redirect;
+	query_params.oneline = 1;
+	query_params.maxdatasize = 0;
+
+	res =  curL_query_url(_m, _url, _dst, &query_params);
 
 	return res;
 }