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