1 /***************************************************************************
2        ssl_connection.cpp  -  ssl connection with certificate support
3                              -------------------
4     begin                : Sun May 29 2005
5     copyright            : (C) 2005 Dmitry Nizovtsev <funt@alarit.com>
6                                     Olexander Shtepa <isk@alarit.com>
7 
8     $Id: ssl_connection.cpp 940 2006-12-30 18:22:05Z ewald-arnold $
9 
10  ***************************************************************************/
11 
12 /**************************************************************************
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU Lesser General Public License as
16  * published by the Free Software Foundation; either version 2 of the License,
17  * or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27  *
28  ***************************************************************************/
29 
30 
31 #define ULXR_NEED_EXPORTS
32 #include <ulxmlrpcpp/ulxmlrpcpp.h>  // always first header
33 
34 #ifdef ULXR_INCLUDE_SSL_STUFF
35 
36 #include <ulxmlrpcpp/contrib/ssl_connection.h>
37 
38 #include <openssl/err.h>
39 
40 //STL
41 #include <deque>
42 #include <iostream>
43 #include <cstring>
44 
45 #include <errno.h>
46 
47 
48 namespace funtik {
49 
50 
SSLConnectionException()51 ULXR_API_IMPL0 SSLConnectionException::SSLConnectionException():
52 	ulxr::ConnectionException(ulxr::SystemError,ULXR_PCHAR("SSL error"),500)
53 {
54 	this->_what+="SSLError:";
55     this->_what+=get_error_queue();
56 }
57 
SSLConnectionException(ulxr::CppString strPhrase,int stat)58 ULXR_API_IMPL0 SSLConnectionException::SSLConnectionException(ulxr::CppString strPhrase, int stat):
59 	ulxr::ConnectionException(ulxr::SystemError,ULXR_PCHAR("SSL error"),stat)
60 {
61 	this->_what+=ulxr::getLatin1(strPhrase);
62 }
63 
SSLConnectionException(SSL * ssl,int ret_code)64 ULXR_API_IMPL0 SSLConnectionException::SSLConnectionException(SSL *ssl, int ret_code):
65 	ulxr::ConnectionException(ulxr::SystemError,ULXR_PCHAR("SSL error"),500)
66 {
67 	this->_what+="SSLError:";
68 	int err=SSL_get_error(ssl,ret_code);
69     switch (err)
70 	{
71 		case SSL_ERROR_NONE:
72         this->_what+=" SSL_ERROR_NONE";
73                 break;
74         case SSL_ERROR_ZERO_RETURN:
75                 this->_what+=" SSL_ERROR_ZERO_RETURN";
76                 break;
77         case SSL_ERROR_WANT_READ:
78                 this->_what+=" SSL_ERROR_WANT_READ";
79                 break;
80         case SSL_ERROR_WANT_WRITE:
81                 this->_what+=" SSL_ERROR_WANT_WRITE";
82                 break;
83         case SSL_ERROR_WANT_CONNECT:
84                 this->_what+=" SSL_ERROR_WANT_CONNECT";
85                 break;
86 
87 #ifdef ULXR_HAVE_SSL_ERROR_WANT_ACCEPT
88         case SSL_ERROR_WANT_ACCEPT:
89                 this->_what+=" SSL_ERROR_WANT_ACCEPT";
90                 break;
91 #endif
92 
93         case SSL_ERROR_WANT_X509_LOOKUP:
94                 this->_what+=" SSL_ERROR_WANT_X509_LOOKUP";
95                 break;
96         case SSL_ERROR_SYSCALL:
97                 {
98                         std::string error_queue=get_error_queue();
99                         if ( !error_queue.empty())
100                                 this->_what+=error_queue;
101                         else
102                         {
103                                 this->_what+=" ";
104                                 if (ret_code==0)
105                                         this->_what+="an EOF was observed";
106                                 else if (ret_code==-1)
107                                   this->_what+=ulxr::getLatin1(ulxr::getLastErrorString(errno));
108                                 else
109                                         this->_what+="unknown error";
110                         }
111                 }
112                 break;
113         case SSL_ERROR_SSL:
114                 this->_what+=get_error_queue();
115                 break;
116         default:
117                 this->_what+=" unknown error code";
118         }
119 
120 }
121 
ULXR_API_IMPL(std::string)122 ULXR_API_IMPL(std::string) SSLConnectionException::get_error_queue()
123 {
124 	typedef std::deque<unsigned long> __list_type;
125 
126     __list_type errors;
127     unsigned long error_code;
128     char buf[120];
129     std::string __ret;
130 
131     while ((error_code=ERR_get_error())!=0)
132                 errors.push_front(error_code);
133 	for (__list_type::const_iterator error=errors.begin();error!=errors.end();++error)
134 	{
135 		__ret+="\n";
136 		ERR_error_string_n(*error,buf,sizeof(buf));
137 		__ret+=buf;
138 	}
139 	return __ret;
140 }
141 
ULXR_API_IMPL(ulxr::CppString)142 ULXR_API_IMPL(ulxr::CppString) SSLConnectionException::why() const
143 {
144 #ifdef ULXR_UNICODE
145   return ulxr::getUnicode(_what.c_str());
146 #else
147   return _what.c_str();
148 #endif
149 }
150 
ULXR_API_IMPL(const char *)151 ULXR_API_IMPL(const char *) SSLConnectionException::what() const throw()
152 {
153 	return _what.c_str();
154 }
155 
156 static int s_server_session_id_context      = 1;
157 static int s_server_auth_session_id_context = 2;
158 
159 bool SSLConnection::ssl_initialized = false;
160 
161 
162 
password_cb(char * buf,int num,int,void * userdata)163 static int password_cb(char *buf,int num, int /*rwflag*/, void *userdata)
164 {
165 	ULXR_TRACE(ULXR_PCHAR("password_cb"));
166 	SSLConnection *conn = (SSLConnection *)userdata;
167 	std::string pass = conn->getPassword();
168 
169 	if((unsigned int)num < pass.length()+1)
170 	    return 0;
171 
172 	strncpy(buf, pass.c_str(),num);
173 	return(strlen(buf));
174 }
175 
176 
177 
178 
179 
180 
SSLConnection(bool I_am_server,const ulxr::CppString & domain,unsigned port)181 ULXR_API_IMPL0 SSLConnection::SSLConnection(bool I_am_server, const ulxr::CppString &domain, unsigned port)
182  : ulxr::TcpIpConnection(I_am_server, domain, port)
183 {
184 	ULXR_TRACE(ULXR_PCHAR("SSLConnection"));
185 	init();
186 }
187 
188 
SSLConnection(bool I_am_server,long adr,unsigned port)189 ULXR_API_IMPL0 SSLConnection::SSLConnection(bool I_am_server, long adr, unsigned port)
190  : ulxr::TcpIpConnection(I_am_server, adr, port)
191 {
192 	ULXR_TRACE(ULXR_PCHAR("SSLConnection"));
193 	init();
194 }
195 
196 
ULXR_API_IMPL(void)197 ULXR_API_IMPL(void)
198   SSLConnection::setCryptographyData (const std::string &in_password,
199                                       const std::string &in_certfile,
200                                       const std::string &in_keyfile)
201 {
202 
203 	m_strPassword = in_password;
204 
205 	if(in_certfile.size()>0)
206 	{
207 		if (SSL_CTX_use_certificate_file(ssl_ctx, in_certfile.c_str(), SSL_FILETYPE_PEM) <= 0)
208     		throw SSLConnectionException(ulxr_i18n(ULXR_PCHAR("SSLConnection::setCryptographyData: problem setting up certificate from file: ")+ULXR_GET_STRING(in_certfile)), 500);
209    		m_strCertFileName = in_certfile;
210 	}
211 
212 	if(in_keyfile.size()>0)
213 	{
214 		if (SSL_CTX_use_PrivateKey_file(ssl_ctx, in_keyfile.c_str(), SSL_FILETYPE_PEM) <= 0)
215 			throw SSLConnectionException(ulxr_i18n(ULXR_PCHAR("SSLConnection::setCryptographyData: problem setting up key from file: ")+ULXR_GET_STRING(in_keyfile)), 500);
216 		m_strKeyFileName = in_keyfile;
217 	}
218 }
219 
220 
221 
222 
ULXR_API_IMPL(void)223 ULXR_API_IMPL(void) SSLConnection::initializeCTX()
224 {
225 	ULXR_TRACE(ULXR_PCHAR("initializeCTX"));
226 
227 //free context
228 	if (ssl_ctx != 0)
229     	    SSL_CTX_free(ssl_ctx);
230 
231 #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10000000L
232 	const SSL_METHOD *meth = SSLv23_method();
233 #else
234 	SSL_METHOD *meth = SSLv23_method();
235 #endif
236 
237 	ssl_ctx = SSL_CTX_new (meth);
238 
239 //!!!
240 	if (!ssl_ctx)
241 		throw SSLConnectionException(ulxr_i18n(ULXR_PCHAR("Cann`t initialize CTX context")), 500);
242 
243 
244 	SSL_CTX_set_default_passwd_cb(ssl_ctx, password_cb);
245 	SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, this);
246 
247 
248 	ssl = 0;
249 
250 	if (isServerMode())
251 	{
252 		if (0 >= SSL_CTX_set_session_id_context(ssl_ctx,
253 		(const unsigned char *)&s_server_session_id_context,
254 		sizeof s_server_session_id_context))
255 		{
256 			throw SSLConnectionException(ulxr_i18n(ULXR_PCHAR("Context session error")), 500);
257 
258     	}
259     }
260 }
261 
262 
ULXR_API_IMPL(void)263 ULXR_API_IMPL(void) SSLConnection::init()
264 {
265 	ULXR_TRACE(ULXR_PCHAR("init"));
266 	session = 0;
267 	m_iAuthType=0;
268 	ssl_ctx=0;
269 	if (!ssl_initialized)
270 	{
271 		SSL_library_init();
272 		SSLeay_add_ssl_algorithms();
273 		SSL_load_error_strings();
274 		ssl_initialized = true;
275 	}
276 	initializeCTX();
277 }
278 
279 
~SSLConnection()280 ULXR_API_IMPL0 SSLConnection::~SSLConnection()
281 {
282 	ULXR_TRACE(ULXR_PCHAR("~SSLConnection"));
283 	close();
284 
285 	if (ssl_ctx != 0)
286 		SSL_CTX_free(ssl_ctx);
287 	ssl_ctx = 0;
288 
289 	ULXR_TRACE(ULXR_PCHAR("~SSLConnection 2"));
290 
291 
292 	if (0 != session)
293 		SSL_SESSION_free(session);
294 	session = 0;
295 }
296 
297 
ULXR_API_IMPL(void)298 ULXR_API_IMPL(void) SSLConnection::close()
299 {
300 	ULXR_TRACE(ULXR_PCHAR("close"));
301 
302 	if (!isServerMode()) // clients keeps session
303 	{
304 		if (0 != session)
305 		{
306 			SSL_SESSION_free(session);
307 			session=0;
308 		}
309 		if(0 != ssl)
310 		    session = SSL_get1_session(ssl);
311 	}
312 
313 	ULXR_TRACE(ULXR_PCHAR("close 2"));
314 
315 	ulxr::TcpIpConnection::close();
316 
317 	if (ssl != 0)
318         	SSL_free(ssl);
319 	ssl = 0;
320 }
321 
322 
ULXR_API_IMPL(ssize_t)323 ULXR_API_IMPL(ssize_t) SSLConnection::low_level_write(char const *buff, long len)
324 {
325 	ULXR_TRACE(ULXR_PCHAR("low_level_write"));
326 
327   if (isConnecting())
328     return TcpIpConnection::low_level_write(buff, len);
329 
330 	ssize_t ret;
331 	while (true)
332 	{
333 		ULXR_TRACE(ULXR_PCHAR("low_level_write 2"));
334 		ret = SSL_write(ssl, buff, len);
335 		ULXR_TRACE(ULXR_PCHAR("low_level_write 3 ") << ret);
336 		if (ret >= 0)
337 			break;
338 		else
339 			throw SSLConnectionException(ssl, ret);
340 
341 	}
342 	return ret;
343 }
344 
345 
ULXR_API_IMPL(bool)346 ULXR_API_IMPL(bool) SSLConnection::hasPendingInput() const
347 {
348   if (isConnecting())
349     return TcpIpConnection::hasPendingInput();
350 
351 	int avail = SSL_pending(ssl);
352 	ULXR_TRACE(ULXR_PCHAR("hasPendingInput ") << avail);
353 	return avail != 0;
354 }
355 
356 
ULXR_API_IMPL(ssize_t)357 ULXR_API_IMPL(ssize_t) SSLConnection::low_level_read(char *buff, long len)
358 {
359 	ULXR_TRACE(ULXR_PCHAR("low_level_read"));
360 
361   if (isConnecting())
362     return TcpIpConnection::low_level_read(buff, len);
363 
364 	ssize_t ret;
365 	while (true)
366 	{
367 		ULXR_TRACE(ULXR_PCHAR("low_level_read 2"));
368 		ret = SSL_read(ssl, buff, len);
369 		ULXR_TRACE(ULXR_PCHAR("low_level_read 3 ") << ret);
370 		if (ret >= 0)
371 			break;
372       	else
373 	       throw SSLConnectionException(ssl, ret);
374 	}
375   return ret;
376 }
377 
378 
detach()379 ulxr::Connection *ULXR_API_IMPL0 SSLConnection::detach()
380 {
381 	ULXR_TRACE(ULXR_PCHAR("detach"));
382 	SSLConnection *clone = new SSLConnection(*this);
383 //reset ssl_ctx,ssl,session old pointers will be stored in clone object
384 	ssl_ctx=0;
385 	ssl=0;
386 	session=0;
387 
388 //init new CTX
389 	cut();
390 
391 	clone->setServerData(getServerData()); // from TcpIpConnection
392 	if (getServerData() != 0)
393 		getServerData()->incRef();
394 
395 	return clone;
396 }
397 
398 
ULXR_API_IMPL(void)399 ULXR_API_IMPL(void) SSLConnection::createSSL()
400 {
401 	ULXR_TRACE(ULXR_PCHAR("createSSL"));
402 	if(ssl != 0)
403 	    SSL_free(ssl);
404 	ssl = SSL_new (ssl_ctx);
405 	if (ssl == 0)
406 		throw SSLConnectionException(ulxr_i18n(ULXR_PCHAR("problem creating SSL conext object")), 500);
407 
408 	int err = SSL_set_fd (ssl, getHandle());
409 	if (err == 0)
410 		throw SSLConnectionException(ulxr_i18n(ULXR_PCHAR("problem set file descriptor for SSL")), 500);
411 
412 	if (isServerMode())
413 	{
414 		if (0 >= SSL_set_session_id_context(ssl,
415 		(const unsigned char *)&s_server_auth_session_id_context,
416 		sizeof(s_server_auth_session_id_context)))
417 		{
418 			throw SSLConnectionException(ulxr_i18n(ULXR_PCHAR("Context session error")), 500);
419 
420 		}
421 	}
422 }
423 
424 
ULXR_API_IMPL(void)425 ULXR_API_IMPL(void) SSLConnection::open()
426 {
427 	ULXR_TRACE(ULXR_PCHAR("open"));
428 
429 	ulxr::TcpIpConnection::open();
430 
431   doConnect();  // CONNECT in non-SSL mode!
432 
433 	int err;
434 	createSSL();
435 
436 	if (0 != session)
437 	{
438 		ULXR_TRACE(ULXR_PCHAR("SSL_set_session"));
439 		SSL_set_session(ssl, session);
440 	}
441 
442 	err = SSL_connect (ssl);
443 	X509 *peer_cert=0;
444 	try{
445 		if (err <= 0)
446 			throw SSLConnectionException(ssl, err);
447 
448 		peer_cert=SSL_get_peer_certificate(ssl);
449 		if(!checkAccess(peer_cert))
450 			throw SSLConnectionException(ULXR_PCHAR("Fault fingerprint of certificate. Access denied."),500);
451 
452 		if(peer_cert!=0)
453 			X509_free(peer_cert);
454 	}
455 	catch(SSLConnectionException& ex)
456 	{
457 //sweep all
458 		if(peer_cert!=0)
459 			X509_free(peer_cert);
460 	    close();
461 	    throw;
462 	}
463 }
464 
465 
ULXR_API_IMPL(void)466 ULXR_API_IMPL(void) SSLConnection::accept()
467 {
468 	ULXR_TRACE(ULXR_PCHAR("accept"));
469 //Set SSL context before every connect. Authentification options could be changed.
470 	ulxr::TcpIpConnection::accept();
471 	createSSL();
472 
473 	int err = SSL_accept (ssl);
474 	X509 *peer_cert=0;
475 	try{
476 	    if (err <= 0)
477 			throw SSLConnectionException(ssl, err);
478 //check access
479 		peer_cert=SSL_get_peer_certificate(ssl);
480    	    if(!checkAccess(peer_cert))
481 			throw SSLConnectionException(ULXR_PCHAR("Fault fingerprint of certificate. Access denied."),500);
482 
483 		if(peer_cert!=0)
484 			X509_free(peer_cert);
485 	}
486 	catch(SSLConnectionException& ex)
487 	{
488 //sweep all
489 		if(peer_cert!=0)
490 			X509_free(peer_cert);
491 	    close();
492 	    throw;
493 	}
494   /* Get the cipher - opt */
495 	ULXR_TRACE(ULXR_PCHAR("SSL connection using ") << ULXR_GET_STRING(SSL_get_cipher (ssl)));
496 }
497 
498 
ULXR_API_IMPL(ulxr::CppString)499 ULXR_API_IMPL(ulxr::CppString) SSLConnection::getInterfaceName()
500 {
501   ULXR_TRACE(ULXR_PCHAR("getInterfaceName"));
502   return ULXR_PCHAR("ssl");
503 }
504 
505 
506 
ULXR_API_IMPL(void)507 ULXR_API_IMPL(void) SSLConnection::cut()
508 {
509 	ULXR_TRACE(ULXR_PCHAR("cut"));
510 	ulxr::TcpIpConnection::cut();
511 	initializeCTX();
512 }
513 
514 
ULXR_API_IMPL(std::string)515 ULXR_API_IMPL(std::string) SSLConnection::getPassword() const
516 {
517 	return m_strPassword;
518 }
519 
520 
ULXR_API_IMPL(SSL *)521 ULXR_API_IMPL(SSL *) SSLConnection::getSslObject() const
522 {
523 	return ssl;
524 }
525 
526 
ULXR_API_IMPL(SSL_CTX *)527 ULXR_API_IMPL(SSL_CTX *) SSLConnection::getSslContextObject() const
528 {
529 	return ssl_ctx;
530 }
531 
532 
ULXR_API_IMPL(SSL_SESSION *)533 ULXR_API_IMPL(SSL_SESSION *) SSLConnection::getSslSessionObject() const
534 {
535 	return session;
536 }
537 
ULXR_API_IMPL(void)538 ULXR_API_IMPL(void ) SSLConnection::setPassword(const std::string &strPassword)
539 {
540 	m_strPassword=strPassword;
541 }
542 
ULXR_API_IMPL(void)543 ULXR_API_IMPL(void) SSLConnection::setCertFile(const std::string &strCertFileName)
544 {
545 
546 //
547 	if (SSL_CTX_use_certificate_file(ssl_ctx, strCertFileName.c_str(), SSL_FILETYPE_PEM) <= 0)
548     	throw SSLConnectionException(ulxr_i18n(ULXR_PCHAR("SSLConnection::setCertFile: problem setting up certificate from file: ")+ULXR_GET_STRING(strCertFileName)), 500);
549     m_strCertFileName=strCertFileName;
550 }
551 
ULXR_API_IMPL(void)552 ULXR_API_IMPL(void) SSLConnection::setKeyFile(const std::string &strKeyFileName)
553 {
554 	if (SSL_CTX_use_PrivateKey_file(ssl_ctx, strKeyFileName.c_str(), SSL_FILETYPE_PEM) <= 0)
555 		throw SSLConnectionException(ulxr_i18n(ULXR_PCHAR("SSLConnection::setKeyFile: problem setting up key from file: ")+ULXR_GET_STRING(strKeyFileName)), 500);
556 	m_strKeyFileName=strKeyFileName;
557 }
558 
ULXR_API_IMPL(std::string)559 ULXR_API_IMPL(std::string) SSLConnection::getKeyFileName() const
560 {
561 	return 	m_strKeyFileName;
562 }
563 
ULXR_API_IMPL(std::string)564 ULXR_API_IMPL(std::string) SSLConnection::getCertFileName() const
565 {
566 	return m_strCertFileName;
567 }
568 
569 
570 
ULXR_API_IMPL(void)571 ULXR_API_IMPL(void ) SSLConnection::disableAuth(int iType)
572 {
573 	if ( 0 == iType )
574 	{
575 		m_iAuthType=0;
576 	}
577 	else
578 	{
579 		m_iAuthType^=iType;
580 	}
581 
582 	activateAuth();
583 }
584 
ULXR_API_IMPL(void)585 ULXR_API_IMPL(void) SSLConnection::enableAuth(int iType)
586 {
587 	m_iAuthType|=iType;
588 
589 	activateAuth();
590 }
591 
ULXR_API_IMPL(void)592 ULXR_API_IMPL(void) SSLConnection::setCAFile(const std::string &strCAFileName)
593 {
594 	m_strCAFileName=strCAFileName;
595 
596 	if (!SSL_CTX_load_verify_locations(ssl_ctx, m_strCAFileName.c_str(),NULL))
597         throw SSLConnectionException(ulxr_i18n(ULXR_PCHAR("TLS engine: cannot load list of CA data from: ")+ULXR_GET_STRING(m_strCAFileName)), 500);
598 
599 
600 	  	/* SSL_load_client_CA_file is a misnomer, it just creates a list of CNs. */
601 
602    	STACK_OF(X509_NAME)* cert_names=SSL_load_client_CA_file(m_strCAFileName.c_str());
603    	if(cert_names == 0)
604    		throw SSLConnectionException(ulxr_i18n(ULXR_PCHAR("TLS engine: cannot load list of CA data from: ")+ULXR_GET_STRING(m_strCAFileName)), 500);
605 
606 	SSL_CTX_set_client_CA_list(ssl_ctx, cert_names);
607 
608         /* SSL_CTX_set_client_CA_list does not have a return value;
609          * it does not really need one, but make sure
610          * (we really test if SSL_load_client_CA_file worked) */
611 
612 	if (SSL_CTX_get_client_CA_list(ssl_ctx) == 0)
613 	    		throw SSLConnectionException(ulxr_i18n(ULXR_PCHAR("Could not set client CA list from: ")+ULXR_GET_STRING(m_strCAFileName)), 500);
614 
615 
616 }
617 
618 
ULXR_API_IMPL(void)619 ULXR_API_IMPL(void ) SSLConnection::addFingerprintData(const std::string  &strFingerprint)
620 {
621 	m_mapFingerpintData[strFingerprint]=1;
622 }
623 
ULXR_API_IMPL(void)624 ULXR_API_IMPL(void) SSLConnection::addRevocationData(const std::string &strRevocation)
625 {
626 	m_mapRevocationData[strRevocation]=1;
627 }
628 
ULXR_API_IMPL(void)629 ULXR_API_IMPL(void) SSLConnection::resetFingerprintData()
630 {
631 	m_mapFingerpintData.clear();
632 }
633 
ULXR_API_IMPL(void)634 ULXR_API_IMPL(void) SSLConnection::resetRevocationData()
635 {
636 	m_mapRevocationData.clear();
637 }
638 
639 //use algoritm for calculate fingerprint like postfix
ULXR_API_IMPL(std::string)640 ULXR_API_IMPL(std::string) SSLConnection::calculateFingerprint(X509 * poCertificate) const
641 {
642 	unsigned int n;
643 	unsigned char md[EVP_MAX_MD_SIZE];
644 	char fingerprint[EVP_MAX_MD_SIZE * 3];
645 	static const char hexcodes[] = "0123456789ABCDEF";
646 
647 	if (X509_digest(poCertificate, EVP_md5(), md, &n))
648 	{
649 		for (int j = 0; j < (int) n; j++)
650 		{
651 			fingerprint[j * 3] =
652                 hexcodes[(md[j] & 0xf0) >> 4];
653 			fingerprint[(j * 3) + 1] =
654                         hexcodes[(md[j] & 0x0f)];
655 			if (j + 1 != (int) n)
656             	    fingerprint[(j * 3) + 2] = ':';
657 			else
658                     fingerprint[(j * 3) + 2] = '\0';
659  		}
660 	}
661     return std::string(fingerprint);
662 }
663 
664 
ULXR_API_IMPL(bool)665 ULXR_API_IMPL(bool) SSLConnection::checkFingerprint(std::string strFingerprint) const
666 {
667 
668 	if(m_mapFingerpintData.find(strFingerprint) == m_mapFingerpintData.end())
669         return false;
670 
671 	return true;
672 }
673 
674 
ULXR_API_IMPL(bool)675 ULXR_API_IMPL(bool) SSLConnection::checkRevocationFingerprint(std::string strFingerprint) const
676 {
677 	if(m_mapRevocationData.find(strFingerprint) == m_mapRevocationData.end())
678         return false;
679 
680 	return true;
681 }
682 
ULXR_API_IMPL(bool)683 ULXR_API_IMPL(bool) SSLConnection::checkAccess(X509 * poCertificate)
684 {
685 	bool bReturn=true;
686 	std::string strCertFingerprint="";
687 
688 
689 //FINGERPRINT_AUTH
690 	if((0 !=(m_iAuthType&SSLConnection::FINGERPRINT_AUTH)) && bReturn)
691 	{
692 		if(poCertificate == NULL)
693 			bReturn=false;
694 		else
695 		{
696 			strCertFingerprint=strCertFingerprint.size()?strCertFingerprint:calculateFingerprint(poCertificate);
697 			if(checkFingerprint(strCertFingerprint))
698 				bReturn=true;
699 			else bReturn=false;
700 		}
701 	}
702 
703 //CHECK_REVOCATIONCERT
704 	if((0 !=(m_iAuthType&SSLConnection::CHECK_REVOCATIONCERT)) && bReturn)
705 	{
706 		if(poCertificate == NULL)
707 			bReturn=false;
708 		else
709 		{
710 			strCertFingerprint=strCertFingerprint.size()?strCertFingerprint:calculateFingerprint(poCertificate);
711 			if(!checkRevocationFingerprint(strCertFingerprint))
712 				bReturn=true;
713 			else bReturn=false;
714 		}
715 	}
716 	return bReturn;
717 }
718 
ULXR_API_IMPL(void)719 ULXR_API_IMPL(void) SSLConnection::activateAuth()
720 {
721 //	if(0 !=(m_iAuthType&SSLConnection::CA_AUTH) && ssl_ctx)
722 	if(0 !=m_iAuthType && ssl_ctx)
723 	{
724 		/* Set options*/
725 		SSL_CTX_set_verify(ssl_ctx,SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,NULL);
726 	}
727 	else
728 	{
729 		/* Set options*/
730 		SSL_CTX_set_verify(ssl_ctx,SSL_VERIFY_NONE,NULL);
731 	}
732 //if we don`t use
733 }
734 
735 
736 } // namespace funtik
737 
738 
739 #endif // ULXR_INCLUDE_SSL_STUFF
740 
741 
742 
743 
744