00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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 #ifdef BLOCXX_HAVE_OPENSSL
00045 #include "blocxx/String.hpp"
00046 #include <openssl/crypto.h>
00047 #include <openssl/ssl.h>
00048 #include <openssl/bio.h>
00049 #define BLOCXX_SSLCTX_MAX_CN_LEN 256
00050 #define BLOCXX_SSL_RETRY_LIMIT 20
00051
00052 namespace BLOCXX_NAMESPACE
00053 {
00054
00061 typedef int (*certVerifyFuncPtr_t)(X509* cert, const String& hostName);
00062
00063
00064 class BLOCXX_COMMON_API SSLCtxMgr
00065 {
00066 public:
00070 static int pem_passwd_cb(char* buf, int size, int rwflag, void *userData);
00078 static bool checkClientCert(SSL* ssl, const String& hostName);
00086 static bool checkServerCert(SSL* ssl, const String& hostName);
00094 static void initClient(const String& certFile = String(), const String& keyFile = String());
00102 static void initServer(const String& certFile, const String& keyFile = String());
00107 static SSL_CTX* getSSLCtxServer()
00108 {
00109 return m_ctxServer;
00110 }
00115 static SSL_CTX* getSSLCtxClient()
00116 {
00117 return m_ctxClient;
00118 }
00127 static int sslRead(SSL* ssl, char* buf, int len);
00136 static int sslWrite(SSL* ssl, const char* buf, int len);
00141 static bool isClient() { return m_ctxClient != NULL; }
00146 static bool isServer() { return m_ctxServer != NULL; }
00152 static void setClientCertVerifyCallback(certVerifyFuncPtr_t cbfunc)
00153 { m_clientCertVerifyCB = cbfunc; }
00159 static void setServerCertVerifyCallback(certVerifyFuncPtr_t cbfunc)
00160 { m_serverCertVerifyCB = cbfunc; }
00161
00162 static void uninit();
00166 static void generateEphRSAKey(SSL_CTX* ctx);
00167
00168 static String getOpenSSLErrorDescription();
00169
00170 private:
00171
00172 friend class SSLCtxBase;
00173 static SSL_CTX* m_ctxClient;
00174 static SSL_CTX* m_ctxServer;
00175 static certVerifyFuncPtr_t m_clientCertVerifyCB;
00176 static certVerifyFuncPtr_t m_serverCertVerifyCB;
00180 static SSL_CTX* initCtx(const String& certfile, const String& keyfile);
00184 static void loadDHParams(SSL_CTX* ctx, const String& file);
00185 static void uninitServer();
00186 static void uninitClient();
00187
00188
00189 SSLCtxMgr();
00190 SSLCtxMgr(const SSLCtxMgr&);
00191 SSLCtxMgr& operator=(const SSLCtxMgr&);
00192
00196 static bool checkCert(SSL* ssl, const String& hostName, certVerifyFuncPtr_t cbFunc);
00197 };
00198
00200 struct BLOCXX_COMMON_API SSLOpts
00201 {
00202 SSLOpts();
00203 String certfile;
00204 String keyfile;
00205 String trustStore;
00206 enum VerifyMode_t
00207 {
00208 MODE_DISABLED,
00209 MODE_REQUIRED,
00210 MODE_OPTIONAL,
00211 MODE_AUTOUPDATE
00212 };
00213 VerifyMode_t verifyMode;
00214 };
00215
00216
00218 class BLOCXX_COMMON_API SSLCtxBase
00219 {
00220 public:
00221 SSL_CTX* getSSLCtx() const;
00222
00223 protected:
00224 SSLCtxBase(const SSLOpts& opts);
00225 virtual ~SSLCtxBase();
00226 SSL_CTX* m_ctx;
00227 };
00228
00230 class BLOCXX_COMMON_API SSLServerCtx : public SSLCtxBase, public IntrusiveCountableBase
00231 {
00232 public:
00233 SSLServerCtx(const SSLOpts& opts);
00234 static const int SSL_DATA_INDEX = 0;
00235 };
00236
00238 class BLOCXX_COMMON_API SSLClientCtx : public SSLCtxBase, public IntrusiveCountableBase
00239 {
00240 public:
00241 SSLClientCtx(const SSLOpts& opts = SSLOpts());
00242 };
00243
00244 typedef IntrusiveReference<SSLServerCtx> SSLServerCtxRef;
00245 typedef IntrusiveReference<SSLClientCtx> SSLClientCtxRef;
00246
00248 class BLOCXX_COMMON_API SSLTrustStore: public IntrusiveCountableBase
00249 {
00250 public:
00251 SSLTrustStore(const String& storeLocation);
00252 void addCertificate(X509* cert, const String& user, const String& uid);
00253 bool getUser(const String& certhash, String& user, String& uid);
00254
00255 static String getCertMD5Fingerprint(X509* cert);
00256 private:
00257 String m_store;
00258 String m_mapfile;
00259 struct UserInfo
00260 {
00261 String user;
00262 String uid;
00263 };
00264
00265 #ifdef BLOCXX_WIN32
00266 #pragma warning (push)
00267 #pragma warning (disable: 4251)
00268 #endif
00269
00270 Map<String, UserInfo> m_map;
00271
00272 #ifdef BLOCXX_WIN32
00273 #pragma warning (pop)
00274 #endif
00275
00276 void readMap();
00277 void writeMap();
00278
00279 };
00280
00281 typedef IntrusiveReference<SSLTrustStore> SSLTrustStoreRef;
00283
00284 struct BLOCXX_COMMON_API OWSSLContext
00285 {
00286 enum CertVerifyState_t
00287 {
00288 VERIFY_NONE,
00289 VERIFY_PASS,
00290 VERIFY_FAIL
00291 };
00292 OWSSLContext();
00293 ~OWSSLContext();
00294 CertVerifyState_t peerCertPassedVerify;
00295 };
00296
00298
00299
00300 #else // ifdef BLOCXX_HAVE_OPENSSL
00301
00302 namespace BLOCXX_NAMESPACE
00303 {
00304
00305 class BLOCXX_COMMON_API SSLServerCtx : public IntrusiveCountableBase
00306 {
00307 };
00308
00309 class BLOCXX_COMMON_API SSLClientCtx : public IntrusiveCountableBase
00310 {
00311 };
00312
00313 #endif // ifdef BLOCXX_HAVE_OPENSSL
00314
00315 typedef IntrusiveReference<SSLServerCtx> SSLServerCtxRef;
00316 typedef IntrusiveReference<SSLClientCtx> SSLClientCtxRef;
00317
00318 }
00319
00320
00321 #endif