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);
00092 static void initClient(const String& keyFile = String());
00098 static void initServer(const String& keyFile);
00103 static SSL_CTX* getSSLCtxServer()
00104 {
00105 return m_ctxServer;
00106 }
00111 static SSL_CTX* getSSLCtxClient()
00112 {
00113 return m_ctxClient;
00114 }
00123 static int sslRead(SSL* ssl, char* buf, int len);
00132 static int sslWrite(SSL* ssl, const char* buf, int len);
00137 static bool isClient() { return m_ctxClient != NULL; }
00142 static bool isServer() { return m_ctxServer != NULL; }
00148 static void setClientCertVerifyCallback(certVerifyFuncPtr_t cbfunc)
00149 { m_clientCertVerifyCB = cbfunc; }
00155 static void setServerCertVerifyCallback(certVerifyFuncPtr_t cbfunc)
00156 { m_serverCertVerifyCB = cbfunc; }
00157
00158 static void uninit();
00162 static void generateEphRSAKey(SSL_CTX* ctx);
00163
00164 static String getOpenSSLErrorDescription();
00165
00166 private:
00167
00168 friend class SSLCtxBase;
00169 static SSL_CTX* m_ctxClient;
00170 static SSL_CTX* m_ctxServer;
00171 static certVerifyFuncPtr_t m_clientCertVerifyCB;
00172 static certVerifyFuncPtr_t m_serverCertVerifyCB;
00176 static SSL_CTX* initCtx(const String& keyfile);
00180 static void loadDHParams(SSL_CTX* ctx, const String& file);
00181 static void uninitServer();
00182 static void uninitClient();
00183
00184
00185 SSLCtxMgr();
00186 SSLCtxMgr(const SSLCtxMgr&);
00187 SSLCtxMgr& operator=(const SSLCtxMgr&);
00188
00192 static bool checkCert(SSL* ssl, const String& hostName, certVerifyFuncPtr_t cbFunc);
00193 };
00194
00196 struct BLOCXX_COMMON_API SSLOpts
00197 {
00198 SSLOpts();
00199 String keyfile;
00200 String trustStore;
00201 enum VerifyMode_t
00202 {
00203 MODE_DISABLED,
00204 MODE_REQUIRED,
00205 MODE_OPTIONAL,
00206 MODE_AUTOUPDATE
00207 };
00208 VerifyMode_t verifyMode;
00209 };
00210
00211
00213 class BLOCXX_COMMON_API SSLCtxBase
00214 {
00215 public:
00216 SSL_CTX* getSSLCtx() const;
00217
00218 protected:
00219 SSLCtxBase(const SSLOpts& opts);
00220 virtual ~SSLCtxBase();
00221 SSL_CTX* m_ctx;
00222 };
00223
00225 class BLOCXX_COMMON_API SSLServerCtx : public SSLCtxBase, public IntrusiveCountableBase
00226 {
00227 public:
00228 SSLServerCtx(const SSLOpts& opts);
00229 static const int SSL_DATA_INDEX = 0;
00230 };
00231
00233 class BLOCXX_COMMON_API SSLClientCtx : public SSLCtxBase, public IntrusiveCountableBase
00234 {
00235 public:
00236 SSLClientCtx(const SSLOpts& opts = SSLOpts());
00237 };
00238
00239 typedef IntrusiveReference<SSLServerCtx> SSLServerCtxRef;
00240 typedef IntrusiveReference<SSLClientCtx> SSLClientCtxRef;
00241
00243 class BLOCXX_COMMON_API SSLTrustStore: public IntrusiveCountableBase
00244 {
00245 public:
00246 SSLTrustStore(const String& storeLocation);
00247 void addCertificate(X509* cert, const String& user, const String& uid);
00248 bool getUser(const String& certhash, String& user, String& uid);
00249
00250 static String getCertMD5Fingerprint(X509* cert);
00251 private:
00252 String m_store;
00253 String m_mapfile;
00254 struct UserInfo
00255 {
00256 String user;
00257 String uid;
00258 };
00259
00260 #ifdef BLOCXX_WIN32
00261 #pragma warning (push)
00262 #pragma warning (disable: 4251)
00263 #endif
00264
00265 Map<String, UserInfo> m_map;
00266
00267 #ifdef BLOCXX_WIN32
00268 #pragma warning (pop)
00269 #endif
00270
00271 void readMap();
00272 void writeMap();
00273
00274 };
00275
00276 typedef IntrusiveReference<SSLTrustStore> SSLTrustStoreRef;
00278
00279 struct BLOCXX_COMMON_API OWSSLContext
00280 {
00281 enum CertVerifyState_t
00282 {
00283 VERIFY_NONE,
00284 VERIFY_PASS,
00285 VERIFY_FAIL
00286 };
00287 OWSSLContext();
00288 ~OWSSLContext();
00289 CertVerifyState_t peerCertPassedVerify;
00290 };
00291
00293
00294
00295 #else // ifdef BLOCXX_HAVE_OPENSSL
00296
00297 namespace BLOCXX_NAMESPACE
00298 {
00299
00300 class BLOCXX_COMMON_API SSLServerCtx : public IntrusiveCountableBase
00301 {
00302 };
00303
00304 class BLOCXX_COMMON_API SSLClientCtx : public IntrusiveCountableBase
00305 {
00306 };
00307
00308 #endif // ifdef BLOCXX_HAVE_OPENSSL
00309
00310 typedef IntrusiveReference<SSLServerCtx> SSLServerCtxRef;
00311 typedef IntrusiveReference<SSLClientCtx> SSLClientCtxRef;
00312
00313 }
00314
00315
00316 #endif