blocxx

SSLCtxMgr.hpp

Go to the documentation of this file.
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