blocxx
|
00001 /******************************************************************************* 00002 * Copyright (C) 2001-2004 Vintela, Inc. All rights reserved. 00003 * Copyright (C) 2004 Novell, Inc. All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * - Redistributions of source code must retain the above copyright notice, 00009 * this list of conditions and the following disclaimer. 00010 * 00011 * - Redistributions in binary form must reproduce the above copyright notice, 00012 * this list of conditions and the following disclaimer in the documentation 00013 * and/or other materials provided with the distribution. 00014 * 00015 * - Neither the name of Vintela, Inc. nor the names of its 00016 * contributors may be used to endorse or promote products derived from this 00017 * software without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' 00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00022 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS 00023 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00024 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00025 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00026 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00027 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00029 * POSSIBILITY OF SUCH DAMAGE. 00030 *******************************************************************************/ 00031 00037 #ifndef BLOCXX_SSLCtxMgr_HPP_INCLUDE_GUARD_ 00038 #define BLOCXX_SSLCtxMgr_HPP_INCLUDE_GUARD_ 00039 #include "blocxx/BLOCXX_config.h" 00040 #include "blocxx/SSLException.hpp" 00041 #include "blocxx/IntrusiveCountableBase.hpp" 00042 #include "blocxx/IntrusiveReference.hpp" 00043 #include "blocxx/Map.hpp" 00044 #include "blocxx/Bool.hpp" 00045 #ifdef BLOCXX_HAVE_OPENSSL 00046 #include "blocxx/String.hpp" 00047 #include <openssl/crypto.h> 00048 #include <openssl/ssl.h> 00049 #include <openssl/bio.h> 00050 #define BLOCXX_SSLCTX_MAX_CN_LEN 256 00051 #define BLOCXX_SSL_RETRY_LIMIT 20 00052 00053 namespace BLOCXX_NAMESPACE 00054 { 00055 00062 typedef int (*certVerifyFuncPtr_t)(X509* cert, const String& hostName); 00063 00064 // TODO: Make this class be a singleton. 00065 class BLOCXX_COMMON_API SSLCtxMgr 00066 { 00067 public: 00071 static int pem_passwd_cb(char* buf, int size, int rwflag, void *userData); 00079 static bool checkClientCert(SSL* ssl, const String& hostName); 00087 static bool checkServerCert(SSL* ssl, const String& hostName); 00095 static void initClient(const String& certFile = String(), const String& keyFile = String()); 00103 static void initServer(const String& certFile, const String& keyFile = String()); 00108 static SSL_CTX* getSSLCtxServer() 00109 { 00110 return m_ctxServer; 00111 } 00116 static SSL_CTX* getSSLCtxClient() 00117 { 00118 return m_ctxClient; 00119 } 00128 static int sslRead(SSL* ssl, char* buf, int len); 00137 static int sslWrite(SSL* ssl, const char* buf, int len); 00142 static bool isClient() { return m_ctxClient != NULL; } 00147 static bool isServer() { return m_ctxServer != NULL; } 00153 static void setClientCertVerifyCallback(certVerifyFuncPtr_t cbfunc) 00154 { m_clientCertVerifyCB = cbfunc; } 00160 static void setServerCertVerifyCallback(certVerifyFuncPtr_t cbfunc) 00161 { m_serverCertVerifyCB = cbfunc; } 00162 // set type to NOT_INIT and free memory. 00163 static void uninit(); 00167 static void generateEphRSAKey(SSL_CTX* ctx); 00168 00169 static String getOpenSSLErrorDescription(); 00170 00180 static void disableSSLInit(); 00189 static void disableLocks(); 00190 00191 static Bool getSSLInitDisabled(); 00192 static Bool getSSLLocksDisabled(); 00193 00194 private: 00195 00196 friend class SSLCtxBase; 00197 00198 static SSL_CTX* m_ctxClient; 00199 static SSL_CTX* m_ctxServer; 00200 static certVerifyFuncPtr_t m_clientCertVerifyCB; 00201 static certVerifyFuncPtr_t m_serverCertVerifyCB; 00202 00206 static SSL_CTX* initCtx(const String& certfile, const String& keyfile, 00207 EVP_PKEY* pkey = 0); 00211 static void loadDHParams(SSL_CTX* ctx, const String& file); 00212 static void uninitServer(); 00213 static void uninitClient(); 00214 00215 // don't allow instantiation 00216 SSLCtxMgr(); 00217 SSLCtxMgr(const SSLCtxMgr&); 00218 SSLCtxMgr& operator=(const SSLCtxMgr&); 00219 00223 static bool checkCert(SSL* ssl, const String& hostName, certVerifyFuncPtr_t cbFunc); 00224 }; 00225 00227 struct BLOCXX_COMMON_API SSLOpts 00228 { 00229 SSLOpts(); 00230 ~SSLOpts(); 00231 String certfile; 00232 String keyfile; 00233 String trustStore; 00234 enum VerifyMode_t 00235 { 00236 MODE_DISABLED, 00237 MODE_REQUIRED, 00238 MODE_OPTIONAL, 00239 MODE_AUTOUPDATE 00240 }; 00241 VerifyMode_t verifyMode; 00242 EVP_PKEY* pkey; 00243 }; 00244 00245 00247 class BLOCXX_COMMON_API SSLCtxBase 00248 { 00249 public: 00250 SSL_CTX* getSSLCtx() const; 00251 00252 protected: 00253 SSLCtxBase(const SSLOpts& opts); 00254 virtual ~SSLCtxBase(); 00255 SSL_CTX* m_ctx; 00256 }; 00257 00259 class BLOCXX_COMMON_API SSLServerCtx : public SSLCtxBase, public IntrusiveCountableBase 00260 { 00261 public: 00262 SSLServerCtx(const SSLOpts& opts); 00263 static const int SSL_DATA_INDEX = 0; 00264 }; 00265 00267 class BLOCXX_COMMON_API SSLClientCtx : public SSLCtxBase, public IntrusiveCountableBase 00268 { 00269 public: 00270 SSLClientCtx(const SSLOpts& opts = SSLOpts()); 00271 }; 00272 00274 class BLOCXX_COMMON_API SSLTrustStore: public IntrusiveCountableBase 00275 { 00276 public: 00277 SSLTrustStore(const String& storeLocation); 00278 void addCertificate(X509* cert, const String& user, const String& uid); 00279 bool getUser(const String& certhash, String& user, String& uid); 00280 00281 static String getCertMD5Fingerprint(X509* cert); 00282 private: 00283 String m_store; 00284 String m_mapfile; 00285 struct UserInfo 00286 { 00287 String user; 00288 String uid; 00289 }; 00290 00291 #ifdef BLOCXX_WIN32 00292 #pragma warning (push) 00293 #pragma warning (disable: 4251) 00294 #endif 00295 00296 Map<String, UserInfo> m_map; 00297 00298 #ifdef BLOCXX_WIN32 00299 #pragma warning (pop) 00300 #endif 00301 00302 void readMap(); 00303 void writeMap(); 00304 00305 }; 00306 00308 00309 struct BLOCXX_COMMON_API OWSSLContext 00310 { 00311 enum CertVerifyState_t 00312 { 00313 VERIFY_NONE, 00314 VERIFY_PASS, 00315 VERIFY_FAIL 00316 }; 00317 OWSSLContext(); 00318 ~OWSSLContext(); 00319 CertVerifyState_t peerCertPassedVerify; 00320 }; 00321 00323 00324 00325 #else // ifdef BLOCXX_HAVE_OPENSSL 00326 00327 namespace BLOCXX_NAMESPACE 00328 { 00329 00330 class BLOCXX_COMMON_API SSLServerCtx : public IntrusiveCountableBase 00331 { 00332 }; 00333 00334 class BLOCXX_COMMON_API SSLClientCtx : public IntrusiveCountableBase 00335 { 00336 }; 00337 00338 #endif // ifdef BLOCXX_HAVE_OPENSSL 00339 00340 } // end namespace BLOCXX_NAMESPACE 00341 00342 00343 #endif