SSPCPP-641 - add ability to set SSL cipher suites
authorScott Cantor <cantor.2@osu.edu>
Thu, 12 May 2016 23:35:22 +0000 (19:35 -0400)
committerScott Cantor <cantor.2@osu.edu>
Thu, 12 May 2016 23:35:22 +0000 (19:35 -0400)
https://issues.shibboleth.net/jira/browse/SSPCPP-641

Also bumps library version.

Projects/vc10/xmltooling/xmltooling.vcxproj
config_win32.h
configure.ac
xmltooling/Makefile.am
xmltooling/soap/OpenSSLSOAPTransport.h
xmltooling/soap/impl/CURLSOAPTransport.cpp
xmltooling/version.h
xmltooling/xmltooling.rc

index b4db45e..f69f937 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>\r
+<?xml version="1.0" encoding="utf-8"?>\r
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
   <ItemGroup Label="ProjectConfigurations">\r
     <ProjectConfiguration Include="Debug|Win32">\r
     <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
     <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />\r
     <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />\r
-    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)1_5D</TargetName>\r
-    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)1_5D</TargetName>\r
-    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectName)1_5</TargetName>\r
-    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectName)1_5</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)1_6D</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)1_6D</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectName)1_6</TargetName>\r
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectName)1_6</TargetName>\r
   </PropertyGroup>\r
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
     <ClCompile>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
   <ImportGroup Label="ExtensionTargets">\r
   </ImportGroup>\r
-</Project>\r
+</Project>
\ No newline at end of file
index ac42e36..6db3930 100644 (file)
 /* Define to 1 if you have the `curl_off_t' type. */
 #define HAVE_CURL_OFF_T 1
 
+/* Define to 1 if you have support for the CURLINFO_TLS_SSL_PTR feature. */
+#define HAVE_CURLINFO_TLS_SSL_PTR 1
+
 /* Name of package */
 #define PACKAGE "xmltooling"
 
 #define PACKAGE_NAME "xmltooling"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "xmltooling 1.5.6"
+#define PACKAGE_STRING "xmltooling 1.6.0"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "xmltooling"
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "1.5.6"
+#define PACKAGE_VERSION "1.6.0"
 
 /* Define to the necessary symbol if this constant uses a non-standard name on
    your system. */
 /* #undef TM_IN_SYS_TIME */
 
 /* Version number of package */
-#define VERSION "1.5.6"
+#define VERSION "1.6.0"
 
 /* Define if you wish to disable XML-Security-dependent features. */
 /* #undef XMLTOOLING_NO_XMLSEC */
index d501226..9f3684d 100644 (file)
@@ -1,6 +1,6 @@
 # Process this file with autoreconf
 AC_PREREQ([2.50])
-AC_INIT([xmltooling],[1.5.6],[https://issues.shibboleth.net/],[xmltooling])
+AC_INIT([xmltooling],[1.6.0],[https://issues.shibboleth.net/],[xmltooling])
 AC_CONFIG_SRCDIR(xmltooling)
 AC_CONFIG_AUX_DIR(build-aux)
 AC_CONFIG_MACRO_DIR(m4)
@@ -388,6 +388,9 @@ int i = 0;
         [AC_MSG_RESULT(yes)],
         [AC_MSG_ERROR([need libcurl that supports CURLOPT_SSL_CTX_FUNCTION])])
     AC_CHECK_TYPE([curl_off_t],[AC_DEFINE([HAVE_CURL_OFF_T],[1],[Define to 1 if you have the 'curl_off_t' type.])],,[[#include <curl/curl.h>]])
+    AC_MSG_CHECKING([for CURLINFO_TLS_SSL_PTR in curl.h])
+    AC_EGREP_HEADER([CURLINFO_TLS_SSL_PTR], [curl/curl.h],
+        [AC_DEFINE([HAVE_CURLINFO_TLS_SSL_PTR],[1],[Define to 1 if you have support for the CURLINFO_TLS_SSL_PTR feature.])])
     
     # restore master libs
     LIBS="$save_LIBS"
index fa907dd..c9d14a9 100644 (file)
@@ -177,7 +177,7 @@ common_sources = \
        Namespace.cpp \
        QName.cpp \
        unicode.cpp \
-    version.cpp \
+       version.cpp \
        XMLObjectBuilder.cpp \
        XMLToolingConfig.cpp \
        impl/AnyElement.cpp \
@@ -204,13 +204,13 @@ common_sources = \
 libxmltooling_lite_la_SOURCES = \
        ${common_sources}
 libxmltooling_lite_la_CPPFLAGS = -DXMLTOOLING_LITE
-libxmltooling_lite_la_LDFLAGS = -version-info 6:6:0
+libxmltooling_lite_la_LDFLAGS = -version-info 7:0:0
 
 if BUILD_XMLSEC
 libxmltooling_la_SOURCES = \
        ${common_sources} \
        ${xmlsec_sources}
-libxmltooling_la_LDFLAGS = $(XMLSEC_LIBS) -version-info 6:6:0
+libxmltooling_la_LDFLAGS = $(XMLSEC_LIBS) -version-info 7:0:0
 endif
 
 install-exec-hook:
index a5cd6c5..cee45bc 100644 (file)
@@ -47,7 +47,7 @@ namespace xmltooling {
         typedef bool (*ssl_ctx_callback_fn)(OpenSSLSOAPTransport* transport, SSL_CTX* ssl_ctx, void* userptr);
 
         /**
-         * Sets a callback function to invoke against the SSL_CTX before the handshake.
+         * Set a callback function to invoke against the SSL_CTX before the handshake.
          * 
          * @param fn        callback function
          * @param userptr   a caller-supplied value to pass to the callback function
@@ -56,7 +56,15 @@ namespace xmltooling {
         virtual bool setSSLCallback(ssl_ctx_callback_fn fn, void* userptr=nullptr)=0;
         
         /**
-         * Sets indicator that the transport peer has been authenticated.
+         * Set an expression identifying the cipher suites to enable using OpenSSL syntax.
+         *
+         * @param cipherlist cipher suite expression/list
+         * @return true iff the ciphers were set
+         */
+        virtual bool setCipherSuites(const char* cipherlist)=0;
+
+        /**
+         * Set indicator that the transport peer has been authenticated.
          * 
          * @param auth    flag to set
          */
index f9fbe11..3238962 100644 (file)
@@ -73,6 +73,9 @@ namespace xmltooling {
         CURLSOAPTransport(const Address& addr)
             : m_sender(addr.m_from ? addr.m_from : ""), m_peerName(addr.m_to ? addr.m_to : ""), m_endpoint(addr.m_endpoint),
                 m_handle(nullptr), m_keepHandle(false), m_headers(nullptr),
+#ifdef HAVE_CURLINFO_TLS_SSL_PTR
+                    m_cipherLogged(false),
+#endif
 #ifndef XMLTOOLING_NO_XMLSEC
                     m_cred(nullptr), m_trustEngine(nullptr), m_peerResolver(nullptr), m_mandatory(false),
 #endif
@@ -208,6 +211,10 @@ namespace xmltooling {
             return true;
         }
 
+        bool setCipherSuites(const char* cipherlist) {
+            return (curl_easy_setopt(m_handle,CURLOPT_SSL_CIPHER_LIST,cipherlist)==CURLE_OK);
+        }
+
     private:
         // per-call state
         string m_sender,m_peerName,m_endpoint,m_simplecreds;
@@ -218,6 +225,9 @@ namespace xmltooling {
                string m_useragent;
         map<string,vector<string> > m_response_headers;
         vector<string> m_saved_options;
+#ifdef HAVE_CURLINFO_TLS_SSL_PTR
+        bool m_cipherLogged;
+#endif
 #ifndef XMLTOOLING_NO_XMLSEC
         const OpenSSLCredential* m_cred;
         const OpenSSLTrustEngine* m_trustEngine;
@@ -569,6 +579,7 @@ void CURLSOAPTransport::send(istream* in)
     // Make the call.
     log.debug("sending SOAP message to %s", m_endpoint.c_str());
     CURLcode code = curl_easy_perform(m_handle);
+
     if (code != CURLE_OK) {
         if (code == CURLE_SSL_CIPHER) {
             log.error("on Red Hat 6+, make sure libcurl used is built with OpenSSL");
@@ -592,10 +603,27 @@ void CURLSOAPTransport::send(istream* in)
 // callback to buffer headers from server
 size_t xmltooling::curl_header_hook(void* ptr, size_t size, size_t nmemb, void* stream)
 {
+    CURLSOAPTransport* ctx = reinterpret_cast<CURLSOAPTransport*>(stream);
+
+#ifdef HAVE_CURLINFO_TLS_SSL_PTR
+    if (!ctx->m_cipherLogged) {
+        Category& log = Category::getInstance(XMLTOOLING_LOGCAT ".SOAPTransport.CURL");
+        if (log.isDebugEnabled()) {
+            struct curl_tlssessioninfo* tlsinfo = nullptr;
+            CURLcode infocode = curl_easy_getinfo(ctx->m_handle, CURLINFO_TLS_SSL_PTR, &tlsinfo);
+            if (infocode == CURLE_OK && tlsinfo && tlsinfo->backend == CURLSSLBACKEND_OPENSSL && tlsinfo->internals) {
+                SSL* ssl = reinterpret_cast<SSL*>(tlsinfo->internals);
+                const SSL_CIPHER* cipher = SSL_get_current_cipher(ssl);
+                log.debug("SSL version: %s, cipher: %s", SSL_get_version(ssl), cipher ? SSL_CIPHER_get_name(cipher) : "unknown");
+            }
+        }
+        ctx->m_cipherLogged = true;
+#endif
+    }
+
     // only handle single-byte data
     if (size!=1)
         return 0;
-    CURLSOAPTransport* ctx = reinterpret_cast<CURLSOAPTransport*>(stream);
     char* buf = (char*)malloc(nmemb + 1);
     if (buf) {
         memset(buf,0,nmemb + 1);
@@ -648,7 +676,22 @@ int xmltooling::curl_debug_hook(CURL* handle, curl_infotype type, char* data, si
 int xmltooling::verify_callback(X509_STORE_CTX* x509_ctx, void* arg)
 {
     Category& log=Category::getInstance(XMLTOOLING_LOGCAT ".SOAPTransport.CURL");
-    log.debug("invoking custom X.509 verify callback");
+    if (log.isDebugEnabled()) {
+        log.debug("invoking custom X.509 verify callback");
+        SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx()));
+        if (ssl) {
+            CategoryStream logstr = log.debugStream();
+            logstr << "ciphers offered by client";
+            for (int i = 0;; ++i) {
+                const char* p = SSL_get_cipher_list(ssl, i);
+                if (!p)
+                    break;
+                logstr << ':' << p;
+            }
+            logstr << eol;
+        }
+    }
+
 #if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
     CURLSOAPTransport* ctx = reinterpret_cast<CURLSOAPTransport*>(arg);
 #else
index c34f8b8..60288a7 100644 (file)
@@ -43,8 +43,8 @@
  */
 
 #define XMLTOOLING_VERSION_MAJOR 1
-#define XMLTOOLING_VERSION_MINOR 5
-#define XMLTOOLING_VERSION_REVISION 6
+#define XMLTOOLING_VERSION_MINOR 6
+#define XMLTOOLING_VERSION_REVISION 0
 
 /** DO NOT MODIFY BELOW THIS LINE */
 
index 4ba5d73..d8973cb 100644 (file)
@@ -28,8 +28,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 //\r
 \r
 VS_VERSION_INFO VERSIONINFO\r
- FILEVERSION 1,5,6,1\r
- PRODUCTVERSION 2,5,5,0\r
+ FILEVERSION 1,6,0,0\r
+ PRODUCTVERSION 2,6,0,0\r
  FILEFLAGSMASK 0x3fL\r
 #ifdef _DEBUG\r
  FILEFLAGS 0x1L\r
@@ -51,38 +51,38 @@ BEGIN
 #else\r
             VALUE "FileDescription", "OpenSAML XMLTooling Library\0"\r
 #endif\r
-            VALUE "FileVersion", "1, 5, 6, 1\0"\r
+            VALUE "FileVersion", "1, 6, 0, 0\0"\r
 #ifdef XMLTOOLING_LITE\r
 #ifdef _DEBUG\r
-            VALUE "InternalName", "xmltooling-lite1_5D\0"\r
+            VALUE "InternalName", "xmltooling-lite1_6D\0"\r
 #else\r
-            VALUE "InternalName", "xmltooling-lite1_5\0"\r
+            VALUE "InternalName", "xmltooling-lite1_6\0"\r
 #endif\r
 #else\r
 #ifdef _DEBUG\r
-            VALUE "InternalName", "xmltooling1_5D\0"\r
+            VALUE "InternalName", "xmltooling1_6D\0"\r
 #else\r
-            VALUE "InternalName", "xmltooling1_5\0"\r
+            VALUE "InternalName", "xmltooling1_6\0"\r
 #endif\r
 #endif\r
             VALUE "LegalCopyright", "Copyright © 2016 UCAID\0"\r
             VALUE "LegalTrademarks", "\0"\r
 #ifdef XMLTOOLING_LITE\r
 #ifdef _DEBUG\r
-            VALUE "OriginalFilename", "xmltooling-lite1_5D.dll\0"\r
+            VALUE "OriginalFilename", "xmltooling-lite1_6D.dll\0"\r
 #else\r
-            VALUE "OriginalFilename", "xmltooling-lite1_5.dll\0"\r
+            VALUE "OriginalFilename", "xmltooling-lite1_6.dll\0"\r
 #endif\r
 #else\r
 #ifdef _DEBUG\r
-            VALUE "OriginalFilename", "xmltooling1_5D.dll\0"\r
+            VALUE "OriginalFilename", "xmltooling1_6.dll\0"\r
 #else\r
-            VALUE "OriginalFilename", "xmltooling1_5.dll\0"\r
+            VALUE "OriginalFilename", "xmltooling1_6.dll\0"\r
 #endif\r
 #endif\r
             VALUE "PrivateBuild", "\0"\r
-            VALUE "ProductName", "OpenSAML 2.5.5\0"\r
-            VALUE "ProductVersion", "2, 5, 5, 0\0"\r
+            VALUE "ProductName", "OpenSAML 2.6.0\0"\r
+            VALUE "ProductVersion", "2, 6, 0, 0\0"\r
             VALUE "SpecialBuild", "\0"\r
         END\r
     END\r