THRIFT-2258:Add TLS v1.1/1.2 support to TSSLSocket.cpp
authorjfarrell <jfarrell@apache.org>
Tue, 1 Apr 2014 03:58:32 +0000 (23:58 -0400)
committerjfarrell <jfarrell@apache.org>
Tue, 1 Apr 2014 03:58:32 +0000 (23:58 -0400)
Client: cpp
Patch:  Chris Stylianou

Enables TSSLSocketFactory to set the required protocol.

lib/cpp/src/thrift/transport/TSSLSocket.cpp
lib/cpp/src/thrift/transport/TSSLSocket.h

index ce971d3..25c5610 100644 (file)
@@ -55,14 +55,45 @@ static bool matchName(const char* host, const char* pattern, int size);
 static char uppercase(char c);
 
 // SSLContext implementation
-SSLContext::SSLContext() {
-  ctx_ = SSL_CTX_new(TLSv1_method());
+SSLContext::SSLContext(const SSLProtocol& protocol) {
+  if(protocol == SSLTLS)
+  {
+    ctx_ = SSL_CTX_new(SSLv23_method());
+  }
+  else if(protocol == SSLv3)
+  {
+    ctx_ = SSL_CTX_new(SSLv3_method());
+  }
+  else if(protocol == TLSv1_0)
+  {
+    ctx_ = SSL_CTX_new(TLSv1_method());
+  }
+  else if(protocol == TLSv1_1)
+  {
+    ctx_ = SSL_CTX_new(TLSv1_1_method());
+  }
+  else if(protocol == TLSv1_2)
+  {
+    ctx_ = SSL_CTX_new(TLSv1_2_method());
+  }
+  else
+  {
+    /// UNKNOWN PROTOCOL!
+    throw TSSLException("SSL_CTX_new: Unknown protocol");
+  }
+
   if (ctx_ == NULL) {
     string errors;
     buildErrors(errors);
     throw TSSLException("SSL_CTX_new: " + errors);
   }
   SSL_CTX_set_mode(ctx_, SSL_MODE_AUTO_RETRY);
+
+  // Disable horribly insecure SSLv2!
+  if(protocol == SSLTLS)
+  {
+    SSL_CTX_set_options(ctx_, SSL_OP_NO_SSLv2);
+  }
 }
 
 SSLContext::~SSLContext() {
@@ -350,14 +381,14 @@ bool     TSSLSocketFactory::initialized = false;
 uint64_t TSSLSocketFactory::count_ = 0;
 Mutex    TSSLSocketFactory::mutex_;
 
-TSSLSocketFactory::TSSLSocketFactory(): server_(false) {
+TSSLSocketFactory::TSSLSocketFactory(const SSLProtocol& protocol): server_(false) {
   Guard guard(mutex_);
   if (count_ == 0) {
     initializeOpenSSL();
     randomize();
   }
   count_++;
-  ctx_ = boost::shared_ptr<SSLContext>(new SSLContext);
+  ctx_ = boost::shared_ptr<SSLContext>(new SSLContext(protocol));
 }
 
 TSSLSocketFactory::~TSSLSocketFactory() {
index b379d23..168390e 100644 (file)
@@ -30,6 +30,16 @@ namespace apache { namespace thrift { namespace transport {
 
 class AccessManager;
 class SSLContext;
+enum SSLProtocol {
+       SSLTLS          = 0,    // Supports SSLv3 and TLSv1.
+       //SSLv2         = 1,    // HORRIBLY INSECURE!
+       SSLv3           = 2,    // Supports SSLv3 only.
+       TLSv1_0         = 3,    // Supports TLSv1_0 only.
+       TLSv1_1         = 4,    // Supports TLSv1_1 only.
+       TLSv1_2         = 5     // Supports TLSv1_2 only.
+};
+
 
 /**
  * OpenSSL implementation for SSL socket interface.
@@ -108,8 +118,10 @@ class TSSLSocketFactory {
  public:
   /**
    * Constructor/Destructor
+   *
+   * @param protocol The SSL/TLS protocol to use.
    */
-  TSSLSocketFactory();
+  TSSLSocketFactory(const SSLProtocol& protocol = SSLTLS);
   virtual ~TSSLSocketFactory();
   /**
    * Create an instance of TSSLSocket with a fresh new socket.
@@ -234,7 +246,7 @@ class TSSLException: public TTransportException {
  */
 class SSLContext {
  public:
-  SSLContext();
+  SSLContext(const SSLProtocol& protocol = SSLTLS);
   virtual ~SSLContext();
   SSL* createSSL();
   SSL_CTX* get() { return ctx_; }