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 #include "BLOCXX_config.h"
00038 #ifdef BLOCXX_HAVE_OPENSSL
00039 #include "blocxx/SSLCtxMgr.hpp"
00040 #include "blocxx/GetPass.hpp"
00041 #include "blocxx/Format.hpp"
00042 #include "blocxx/FileSystem.hpp"
00043 #include "blocxx/ThreadImpl.hpp"
00044 #include "blocxx/Mutex.hpp"
00045 #include "blocxx/MutexLock.hpp"
00046 #include "blocxx/Assertion.hpp"
00047 #include "blocxx/MD5.hpp"
00048 #include "blocxx/Array.hpp"
00049 #include "blocxx/CryptographicRandomNumber.hpp"
00050
00051 #include <openssl/rand.h>
00052 #include <openssl/err.h>
00053 #include <cstring>
00054 #include <csignal>
00055 #include <cerrno>
00056 #ifndef BLOCXX_WIN32
00057 #include <sys/time.h>
00058 #include <sys/resource.h>
00059 #endif
00060 #include <fcntl.h>
00061
00062 #ifdef BLOCXX_HAVE_SYS_TYPES_H
00063 #include <sys/types.h>
00064 #endif
00065
00066 #ifdef BLOCXX_HAVE_SYS_STAT_H
00067 #include <sys/stat.h>
00068 #endif
00069
00070 #ifdef BLOCXX_HAVE_UNISTD_H
00071 #include <unistd.h>
00072 #endif
00073
00074 #ifdef BLOCXX_DEBUG
00075 #include <iostream>
00076 #endif
00077
00078 #include <fstream>
00079
00080
00081 extern "C"
00082 {
00083 struct CRYPTO_dynlock_value
00084 {
00085 BLOCXX_NAMESPACE::Mutex mutex;
00086 };
00087 }
00088
00089 namespace BLOCXX_NAMESPACE
00090 {
00091
00092 namespace
00093 {
00094
00095 BLOCXX_NAMESPACE::Mutex* mutex_buf = 0;
00096
00097 extern "C"
00098 {
00099
00100 static struct CRYPTO_dynlock_value * dyn_create_function(const char *,int)
00101 {
00102 return new CRYPTO_dynlock_value;
00103 }
00104
00105
00106 static void dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l,
00107 const char *, int)
00108 {
00109 if (mode & CRYPTO_LOCK)
00110 {
00111 l->mutex.acquire();
00112 }
00113 else
00114 {
00115 l->mutex.release();
00116 }
00117 }
00118
00119 static void dyn_destroy_function(struct CRYPTO_dynlock_value *l,
00120 const char *, int)
00121 {
00122 delete l;
00123 }
00124
00125 static unsigned long id_function()
00126 {
00127 return static_cast<unsigned long>(BLOCXX_NAMESPACE::ThreadImpl::thread_t_ToUInt64(BLOCXX_NAMESPACE::ThreadImpl::currentThread()));
00128 }
00129
00130 static void locking_function(int mode, int n, const char*, int)
00131 {
00132 if (mode & CRYPTO_LOCK)
00133 {
00134 mutex_buf[n].acquire();
00135 }
00136 else
00137 {
00138 mutex_buf[n].release();
00139 }
00140 }
00141 }
00142
00143 class X509Freer
00144 {
00145 public:
00146 X509Freer(X509* x509)
00147 : m_x509(x509)
00148 {
00149 }
00150 ~X509Freer()
00151 {
00152 if (m_x509 != 0)
00153 {
00154 X509_free(m_x509);
00155 }
00156 }
00157 private:
00158 X509* m_x509;
00159 };
00160
00161 }
00162
00163 SSL_CTX* SSLCtxMgr::m_ctxClient = 0;
00164 SSL_CTX* SSLCtxMgr::m_ctxServer = 0;
00165 certVerifyFuncPtr_t SSLCtxMgr::m_clientCertVerifyCB = 0;
00166 certVerifyFuncPtr_t SSLCtxMgr::m_serverCertVerifyCB = 0;
00167
00169
00170 String
00171 SSLCtxMgr::getOpenSSLErrorDescription()
00172 {
00173 BIO* bio = BIO_new(BIO_s_mem());
00174 if (!bio)
00175 {
00176 return String();
00177 }
00178 ERR_print_errors(bio);
00179 char* p = 0;
00180 long len = BIO_get_mem_data(bio, &p);
00181 String rval(p, len);
00182 int freerv = BIO_free(bio);
00183 BLOCXX_ASSERT(freerv == 1);
00184 return rval;
00185 }
00186
00188 SSL_CTX*
00189 SSLCtxMgr::initCtx(const String& keyfile)
00190 {
00191 ERR_clear_error();
00192 SSL_CTX* ctx = SSL_CTX_new(SSLv23_method());
00193 if (ctx == 0)
00194 {
00195 BLOCXX_THROW(SSLException, Format("SSLCtxMgr::initCtx(): SSL_CTX_new returned 0: %1", getOpenSSLErrorDescription()).c_str());
00196 }
00197 SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_cb);
00198 if (!keyfile.empty())
00199 {
00200 if (SSL_CTX_use_certificate_chain_file(ctx, keyfile.c_str()) != 1)
00201 {
00202 SSL_CTX_free(ctx);
00203 BLOCXX_THROW(SSLException, Format("SSLCtxMgr::initCtx(): Couldn't read certificate file: %1: %2",
00204 keyfile, getOpenSSLErrorDescription()).c_str());
00205 }
00206 if (SSL_CTX_use_PrivateKey_file(ctx, keyfile.c_str(), SSL_FILETYPE_PEM) != 1)
00207 {
00208 SSL_CTX_free(ctx);
00209 BLOCXX_THROW(SSLException, Format("SSLCtxMgr::initCtx(): Couldn't read key file: %1", getOpenSSLErrorDescription()).c_str());
00210 }
00211 }
00212
00213 CryptographicRandomNumber::initRandomness();
00214
00215 return ctx;
00216 }
00218 namespace
00219 {
00220
00221 class SSLGlobalWork
00222 {
00223 public:
00224 SSLGlobalWork()
00225 {
00226 if (!mutex_buf)
00227 {
00228 mutex_buf = new Mutex[CRYPTO_num_locks()];
00229 }
00230 SSL_library_init();
00231 SSL_load_error_strings();
00232
00233 CRYPTO_set_id_callback(id_function);
00234 CRYPTO_set_locking_callback(locking_function);
00235
00236
00237
00238 CRYPTO_set_dynlock_create_callback(dyn_create_function);
00239 CRYPTO_set_dynlock_lock_callback(dyn_lock_function);
00240 CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function);
00241 }
00242
00243 ~SSLGlobalWork()
00244 {
00245 if (SSLCtxMgr::isClient() || SSLCtxMgr::isServer())
00246 {
00247 CryptographicRandomNumber::saveRandomState();
00248 }
00249 SSLCtxMgr::uninit();
00250 delete[] mutex_buf;
00251 mutex_buf = 0;
00252 }
00253 private:
00254 };
00255
00256 SSLGlobalWork g_sslGLobalWork;
00257
00258 }
00259
00261 void
00262 SSLCtxMgr::loadDHParams(SSL_CTX* ctx, const String& file)
00263 {
00264 BLOCXX_ASSERT(ctx != 0);
00265 ERR_clear_error();
00266 BIO* bio = BIO_new_file(file.c_str(), "r");
00267 if (bio == NULL)
00268 {
00269 BLOCXX_THROW(SSLException, Format("SSLCtxMgr::loadDHParams(): Couldn't open DH file %1: %2", file, getOpenSSLErrorDescription()).c_str());
00270 }
00271 DH* ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
00272 BIO_free(bio);
00273 if (ret == 0)
00274 {
00275 BLOCXX_THROW(SSLException, Format("SSLCtxMgr::loadDHParams(): PEM_read_bio_DHparams failed: %1", getOpenSSLErrorDescription()).c_str());
00276 }
00277 if (SSL_CTX_set_tmp_dh(ctx, ret) != 1)
00278 {
00279 BLOCXX_THROW(SSLException, Format("SSLCtxMgr::loadDHParams(): Couldn't set DH parameters because SSL_CTX_set_tmp_dh failed: %1", getOpenSSLErrorDescription()).c_str());
00280 }
00281 }
00283 void
00284 SSLCtxMgr::generateEphRSAKey(SSL_CTX* ctx)
00285 {
00286 BLOCXX_ASSERT(ctx != 0);
00287 ERR_clear_error();
00288 RSA* rsa = RSA_generate_key(512, RSA_F4, NULL, NULL);
00289 if (rsa == 0)
00290 {
00291 BLOCXX_THROW(SSLException, Format("SSLCtxMgr::generateEphRSAKey(): RSA_generate_key failed: %1", getOpenSSLErrorDescription()).c_str());
00292 }
00293 if (SSL_CTX_set_tmp_rsa(ctx, rsa) != 1)
00294 {
00295 RSA_free(rsa);
00296 BLOCXX_THROW(SSLException, Format("SSLCtxMgr::generateEphRSAKey(): SSL_CTX_set_tmp_rsa failed. Couldn't set RSA key: %1", getOpenSSLErrorDescription()).c_str());
00297 }
00298 RSA_free(rsa);
00299 }
00301 void
00302 SSLCtxMgr::initClient(const String& keyfile)
00303 {
00304 if (m_ctxClient)
00305 {
00306 uninitClient();
00307 }
00308 m_ctxClient = initCtx(keyfile);
00309 }
00311 void
00312 SSLCtxMgr::initServer(const String& keyfile)
00313 {
00314 if (m_ctxServer)
00315 {
00316 uninitServer();
00317 }
00318 m_ctxServer = initCtx(keyfile);
00319
00320 generateEphRSAKey(m_ctxServer);
00321 String sessID("SSL_SESSION_");
00322 CryptographicRandomNumber rn(0, 10000);
00323 sessID += String(static_cast<UInt32>(rn.getNextNumber()));
00324 int sessIDLen =
00325 (SSL_MAX_SSL_SESSION_ID_LENGTH < (sessID.length())) ?
00326 SSL_MAX_SSL_SESSION_ID_LENGTH : (sessID.length());
00327 ERR_clear_error();
00328 if (SSL_CTX_set_session_id_context(m_ctxServer, reinterpret_cast<const unsigned char*>(sessID.c_str()), sessIDLen) != 1)
00329 {
00330 BLOCXX_THROW(SSLException, Format("SSLCtxMgr::initServer(): SSL_CTX_set_session_id_context failed: %1", getOpenSSLErrorDescription()).c_str());
00331 }
00332 SSL_CTX_set_verify(m_ctxServer, SSL_VERIFY_PEER , NULL);
00333 }
00335
00336 int
00337 SSLCtxMgr::pem_passwd_cb(char* buf, int size, int ,
00338 void* )
00339 {
00340 String passwd = GetPass::getPass("Enter the password for the SSL certificate: ");
00341
00342 strncpy(buf, passwd.c_str(), size);
00343 buf[size - 1] = '\0';
00344
00345 return passwd.length();
00346 }
00348
00349 bool
00350 SSLCtxMgr::checkClientCert(SSL* ssl, const String& hostName)
00351 {
00352 return checkCert(ssl, hostName, m_clientCertVerifyCB);
00353 }
00355
00356 bool
00357 SSLCtxMgr::checkServerCert(SSL* ssl, const String& hostName)
00358 {
00359 return checkCert(ssl, hostName, m_serverCertVerifyCB);
00360 }
00362
00363 bool
00364 SSLCtxMgr::checkCert(SSL* ssl, const String& hostName,
00365 certVerifyFuncPtr_t certVerifyCB)
00366 {
00367 BLOCXX_ASSERT(ssl != 0);
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 if (certVerifyCB)
00381 {
00382 X509 *peer = SSL_get_peer_certificate(ssl);
00383 X509Freer x509freer(peer);
00384 if (peer == 0)
00385 {
00386 return false;
00387 }
00388 if (certVerifyCB(peer, hostName) == 0)
00389 {
00390 return false;
00391 }
00392 else
00393 {
00394 return true;
00395 }
00396 }
00397 return true;
00398 }
00400
00401 int
00402 SSLCtxMgr::sslRead(SSL* ssl, char* buf, int len)
00403 {
00404 int cc = SSL_ERROR_WANT_READ;
00405 int r, retries = 0;
00406 while (cc == SSL_ERROR_WANT_READ && retries < BLOCXX_SSL_RETRY_LIMIT)
00407 {
00408 r = SSL_read(ssl, buf, len);
00409 cc = SSL_get_error(ssl, r);
00410 retries++;
00411 }
00412
00413 switch (cc)
00414 {
00415 case SSL_ERROR_NONE:
00416 return r;
00417 case SSL_ERROR_ZERO_RETURN:
00418 return -1;
00419 default:
00420 return -1;
00421 }
00422 }
00424
00425 int
00426 SSLCtxMgr::sslWrite(SSL* ssl, const char* buf, int len)
00427 {
00428 int r, cc, retries;
00429 int myLen = len;
00430 int offset = 0;
00431 while (myLen > 0)
00432 {
00433 cc = SSL_ERROR_WANT_WRITE;
00434 retries = 0;
00435 while(cc == SSL_ERROR_WANT_WRITE && retries < BLOCXX_SSL_RETRY_LIMIT)
00436 {
00437 r = SSL_write(ssl, buf + offset, myLen);
00438 cc = SSL_get_error(ssl, r);
00439 retries++;
00440 }
00441
00442 if (cc == SSL_ERROR_NONE)
00443 {
00444 myLen -= r;
00445 offset += r;
00446 }
00447 else
00448 {
00449 return -1;
00450 }
00451 }
00452 return len;
00453 }
00455 void
00456 SSLCtxMgr::uninit()
00457 {
00458 uninitClient();
00459 uninitServer();
00460
00461
00462 EVP_cleanup();
00463
00464 ERR_free_strings();
00465 }
00467 void
00468 SSLCtxMgr::uninitClient()
00469 {
00470 if (m_ctxClient)
00471 {
00472 SSL_CTX_free(m_ctxClient);
00473 m_ctxClient = NULL;
00474 }
00475 }
00477 void
00478 SSLCtxMgr::uninitServer()
00479 {
00480 if (m_ctxServer)
00481 {
00482 SSL_CTX_free(m_ctxServer);
00483 m_ctxServer = NULL;
00484 }
00485 }
00486
00487 namespace
00488 {
00489
00491 extern "C"
00492 {
00493 static int verify_callback(int ok, X509_STORE_CTX *store)
00494 {
00495 int index = SSL_get_ex_data_X509_STORE_CTX_idx();
00496 if (index < 0)
00497 {
00498 return 0;
00499 }
00500 SSL* ssl = static_cast<SSL*>(X509_STORE_CTX_get_ex_data(store, index));
00501 if (ssl == 0)
00502 {
00503 return 0;
00504 }
00505 OWSSLContext* owctx = static_cast<OWSSLContext*>(SSL_get_ex_data(ssl, SSLServerCtx::SSL_DATA_INDEX));
00506 BLOCXX_ASSERT(owctx);
00507 if (owctx == 0)
00508 {
00509 return 0;
00510 }
00511
00522 if (!ok)
00523 {
00524 owctx->peerCertPassedVerify = OWSSLContext::VERIFY_FAIL;
00525 }
00526 else
00527 {
00528
00529
00530 if (owctx->peerCertPassedVerify != OWSSLContext::VERIFY_FAIL)
00531 {
00532 owctx->peerCertPassedVerify = OWSSLContext::VERIFY_PASS;
00533 }
00534 }
00535
00536 #ifdef BLOCXX_DEBUG
00537 if (!ok)
00538 {
00539 char data[256];
00540 X509 *cert = X509_STORE_CTX_get_current_cert(store);
00541 int depth = X509_STORE_CTX_get_error_depth(store);
00542 int err = X509_STORE_CTX_get_error(store);
00543
00544 fprintf(stderr, "-Error with certificate at depth: %i\n", depth);
00545 X509_NAME_oneline(X509_get_issuer_name(cert), data, 256);
00546 fprintf(stderr, " issuer = %s\n", data);
00547 X509_NAME_oneline(X509_get_subject_name(cert), data, 256);
00548 fprintf(stderr, " subject = %s\n", data);
00549 fprintf(stderr, " err %i:%s\n", err, X509_verify_cert_error_string(err));
00550 }
00551 #endif
00552
00553 return 1;
00554 }
00555 }
00556
00557 }
00558
00560 SSLCtxBase::SSLCtxBase(const SSLOpts& opts)
00561 : m_ctx(0)
00562 {
00563 m_ctx = SSLCtxMgr::initCtx(opts.keyfile);
00564
00565 SSLCtxMgr::generateEphRSAKey(m_ctx);
00566 String sessID("SSL_SESSION_");
00567 CryptographicRandomNumber rn(0, 10000);
00568 sessID += String(static_cast<UInt32>(rn.getNextNumber()));
00569 int sessIDLen =
00570 (SSL_MAX_SSL_SESSION_ID_LENGTH < (sessID.length())) ?
00571 SSL_MAX_SSL_SESSION_ID_LENGTH : (sessID.length());
00572 ERR_clear_error();
00573 if (SSL_CTX_set_session_id_context(m_ctx, reinterpret_cast<const unsigned char*>(sessID.c_str()), sessIDLen) != 1)
00574 {
00575 SSL_CTX_free(m_ctx);
00576 BLOCXX_THROW(SSLException, Format("SSLCtxMgr::initServer(): SSL_CTX_set_session_id_context failed: %1", SSLCtxMgr::getOpenSSLErrorDescription()).c_str());
00577 }
00578
00579 if (opts.verifyMode != SSLOpts::MODE_DISABLED && !opts.trustStore.empty())
00580 {
00581 if (!FileSystem::exists(opts.trustStore))
00582 {
00583 SSL_CTX_free(m_ctx);
00584 BLOCXX_THROW(SSLException, Format("Error loading truststore %1",
00585 opts.trustStore).c_str());
00586 }
00587 if (SSL_CTX_load_verify_locations(m_ctx,0,opts.trustStore.c_str()) != 1)
00588 {
00589 SSL_CTX_free(m_ctx);
00590 BLOCXX_THROW(SSLException, Format("Error loading truststore %1: %2", opts.trustStore, SSLCtxMgr::getOpenSSLErrorDescription()).c_str());
00591 }
00592 }
00593
00594
00595
00596
00597
00598
00599 switch (opts.verifyMode)
00600 {
00601 case SSLOpts::MODE_DISABLED:
00602 SSL_CTX_set_verify(m_ctx, SSL_VERIFY_NONE, 0);
00603 break;
00604 case SSLOpts::MODE_REQUIRED:
00605 SSL_CTX_set_verify(m_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
00606 break;
00607 case SSLOpts::MODE_OPTIONAL:
00608 case SSLOpts::MODE_AUTOUPDATE:
00609 SSL_CTX_set_verify(m_ctx, SSL_VERIFY_PEER, verify_callback);
00610 break;
00611 default:
00612 BLOCXX_ASSERTMSG(false, "Bad option, shouldn't happen");
00613 break;
00614 }
00615
00616 SSL_CTX_set_verify_depth(m_ctx, 4);
00617
00618 }
00619
00621 SSLCtxBase::~SSLCtxBase()
00622 {
00623 if (m_ctx)
00624 {
00625 SSL_CTX_free(m_ctx);
00626 }
00627 ERR_clear_error();
00628 ERR_remove_state(0);
00629 }
00630
00632 SSL_CTX*
00633 SSLCtxBase::getSSLCtx() const
00634 {
00635 return m_ctx;
00636 }
00637
00638 SSLOpts::SSLOpts()
00639 : verifyMode(MODE_DISABLED)
00640 {
00641 }
00642
00643
00644
00645
00646
00648 SSLServerCtx::SSLServerCtx(const SSLOpts& opts)
00649 : SSLCtxBase(opts)
00650 {
00651 }
00653 SSLClientCtx::SSLClientCtx(const SSLOpts& opts)
00654 : SSLCtxBase(opts)
00655 {
00656 }
00657
00658 static Mutex m_mapGuard;
00659
00661 SSLTrustStore::SSLTrustStore(const String& storeLocation)
00662 : m_store(storeLocation)
00663 {
00664 m_mapfile = m_store + "/map";
00665 if (FileSystem::exists(m_mapfile))
00666 {
00667 MutexLock mlock(m_mapGuard);
00668 readMap();
00669 }
00670 }
00671
00673 bool
00674 SSLTrustStore::getUser(const String& certhash, String& user, String& uid)
00675 {
00676 MutexLock mlock(m_mapGuard);
00677 Map<String, UserInfo>::const_iterator iter = m_map.find(certhash);
00678 if (iter == m_map.end())
00679 {
00680 return false;
00681 }
00682 user = iter->second.user;
00683 uid = iter->second.uid;
00684 return true;
00685 }
00686
00688 void
00689 SSLTrustStore::addCertificate(X509* cert, const String& user, const String& uid)
00690 {
00691 static const int numtries = 1000;
00692 BLOCXX_ASSERT(cert);
00693 OStringStream ss;
00694 unsigned long hash = X509_subject_name_hash(cert);
00695 ss << std::hex << hash;
00696 String filename = m_store + "/" + ss.toString() + ".";
00697 int i = 0;
00698 for (i = 0; i < numtries; ++i)
00699 {
00700 String temp = filename + String(i);
00701 if (FileSystem::exists(temp))
00702 {
00703 continue;
00704 }
00705 filename = temp;
00706 break;
00707 }
00708 if (i == numtries)
00709 {
00710 BLOCXX_THROW(SSLException, "Unable to find a valid filename to store cert");
00711 }
00712 FILE* fp = fopen(filename.c_str(), "w");
00713 if (!fp)
00714 {
00715 BLOCXX_THROW_ERRNO_MSG(SSLException, Format("Unable to open new cert file for writing: %1", filename).c_str());
00716 }
00717
00718 ERR_clear_error();
00719
00720
00721 if (PEM_write_X509(fp, cert) != 1)
00722 {
00723 fclose(fp);
00724 BLOCXX_THROW(SSLException, Format("SSL error while writing certificate to %1: %2", filename, SSLCtxMgr::getOpenSSLErrorDescription()).c_str());
00725 }
00726 fclose(fp);
00727
00728 String digest = getCertMD5Fingerprint(cert);
00729 MutexLock mlock(m_mapGuard);
00730 UserInfo info;
00731 info.user = user;
00732 info.uid = uid;
00733 m_map[digest] = info;
00734 writeMap();
00735 }
00736
00738 String
00739 SSLTrustStore::getCertMD5Fingerprint(X509* cert)
00740 {
00741 unsigned char digest[16];
00742 unsigned int len = 16;
00743 X509_digest(cert, EVP_md5(), digest, &len);
00744 return MD5::convertBinToHex(digest);
00745 }
00746
00748 void
00749 SSLTrustStore::writeMap()
00750 {
00751 std::ofstream f(m_mapfile.c_str(), std::ios::out);
00752 if (!f)
00753 {
00754 BLOCXX_THROW_ERRNO_MSG(SSLException, Format("SSL error opening map file: %1", m_mapfile).c_str());
00755 }
00756 for (Map<String, UserInfo>::const_iterator iter = m_map.begin();
00757 iter != m_map.end(); ++iter)
00758 {
00759 f << iter->first << " " << iter->second.user
00760 << " " << iter->second.uid << "\n";
00761 }
00762 f.close();
00763 }
00764
00766 void
00767 SSLTrustStore::readMap()
00768 {
00769 std::ifstream f(m_mapfile.c_str(), std::ios::in);
00770 if (!f)
00771 {
00772 BLOCXX_THROW_ERRNO_MSG(SSLException, Format("SSL error opening map file: %1", m_mapfile).c_str());
00773 }
00774 int lineno = 0;
00775 while (f)
00776 {
00777 String line = String::getLine(f);
00778 if (!f)
00779 {
00780 break;
00781 }
00782 ++lineno;
00783 StringArray toks = line.tokenize();
00784 if (toks.size() != 3 && toks.size() != 2)
00785 {
00786 BLOCXX_THROW(SSLException, Format("Error processing user map %1 at line %2", m_mapfile, lineno).c_str());
00787 }
00788 UserInfo info;
00789 info.user = toks[1];
00790 if (toks.size() == 3)
00791 {
00792 info.uid = toks[2];
00793 }
00794 m_map.insert(std::make_pair(toks[0], info));
00795 }
00796 #ifdef BLOCXX_DEBUG
00797 std::cerr << "cert<>user map initizialized with " << m_map.size() << " users" << std::endl;
00798 #endif
00799 f.close();
00800 }
00801
00803
00804 OWSSLContext::OWSSLContext()
00805 : peerCertPassedVerify(VERIFY_NONE)
00806 {
00807 }
00809 OWSSLContext::~OWSSLContext()
00810 {
00811 }
00812
00813
00814 }
00815
00816 #endif // #ifdef BLOCXX_HAVE_OPENSSL
00817