35#include <openssl/ssl.h>
36#include <openssl/err.h>
37#include <openssl/rand.h>
38#include <openssl/conf.h>
39#include <openssl/evp.h>
40#include <openssl/hmac.h>
48GSsl::OpenSSL::LibraryImp::LibraryImp(
G::StringArray & library_config , Library::LogFn log_fn ,
bool verbose ) :
51 m_config(library_config)
53#if OPENSSL_VERSION_NUMBER < 0x10100000L
55 SSL_load_error_strings() ;
57 OpenSSL_add_all_digests() ;
63 GDEF_IGNORE_RETURN RAND_status() ;
66 m_index = SSL_get_ex_new_index( 0 ,
nullptr ,
nullptr ,
nullptr ,
nullptr ) ;
70 throw Error(
"SSL_get_ex_new_index" ) ;
74GSsl::OpenSSL::LibraryImp::~LibraryImp()
79void GSsl::OpenSSL::LibraryImp::cleanup()
81#if OPENSSL_VERSION_NUMBER < 0x10100000L
84 CRYPTO_cleanup_all_ex_data();
88std::string GSsl::OpenSSL::LibraryImp::sid()
90#if OPENSSL_VERSION_NUMBER < 0x10100000L
91 std::string v = SSLeay_version(SSLEAY_VERSION) ;
93 std::string v = OpenSSL_version(OPENSSL_VERSION) ;
98std::string GSsl::OpenSSL::LibraryImp::id()
const
103bool GSsl::OpenSSL::LibraryImp::generateKeyAvailable()
const
108std::string GSsl::OpenSSL::LibraryImp::generateKey(
const std::string & )
const
110 return std::string() ;
118std::string GSsl::OpenSSL::LibraryImp::credit(
const std::string & prefix ,
const std::string & eol ,
const std::string & eot )
120 std::ostringstream ss ;
122 << prefix <<
"This product includes software developed by the OpenSSL Project" << eol
123 << prefix <<
"for use in the OpenSSL Toolkit (http://www.openssl.org/)" << eol
128void GSsl::OpenSSL::LibraryImp::addProfile(
const std::string & profile_name ,
bool is_server_profile ,
129 const std::string & key_file ,
const std::string & cert_file ,
const std::string & ca_file ,
130 const std::string & default_peer_certificate_name ,
const std::string & default_peer_host_name ,
131 const std::string & profile_config )
133 std::shared_ptr<ProfileImp> profile_ptr =
134 std::make_shared<ProfileImp>(*
this,is_server_profile,key_file,cert_file,ca_file,
135 default_peer_certificate_name,default_peer_host_name,profile_config) ;
136 m_profile_map.insert( Map::value_type(profile_name,profile_ptr) ) ;
139bool GSsl::OpenSSL::LibraryImp::hasProfile(
const std::string & profile_name )
const
141 auto p = m_profile_map.find( profile_name ) ;
142 return p != m_profile_map.end() ;
145const GSsl::Profile & GSsl::OpenSSL::LibraryImp::profile(
const std::string & profile_name )
const
147 auto p = m_profile_map.find( profile_name ) ;
148 if( p == m_profile_map.end() )
throw Error(
"no such profile: [" + profile_name +
"]" ) ;
149 return *(*p).second ;
152GSsl::Library::LogFn GSsl::OpenSSL::LibraryImp::log()
const
157bool GSsl::OpenSSL::LibraryImp::verbose()
const
162int GSsl::OpenSSL::LibraryImp::index()
const
167G::StringArray GSsl::OpenSSL::LibraryImp::digesters(
bool need_state )
const
171 result.push_back(
"SHA512" ) ;
172 result.push_back(
"SHA256" ) ;
173 result.push_back(
"SHA1" ) ;
174 result.push_back(
"MD5" ) ;
178GSsl::Digester GSsl::OpenSSL::LibraryImp::digester(
const std::string & hash_type ,
const std::string & state ,
bool need_state )
const
180 return Digester( std::make_unique<GSsl::OpenSSL::DigesterImp>(hash_type,state,need_state) ) ;
183GSsl::OpenSSL::DigesterImp::DigesterImp(
const std::string & hash_type ,
const std::string & state ,
bool need_state ) :
184 m_hash_type(Type::Other) ,
187 bool have_state = !state.empty() ;
188 if( hash_type ==
"MD5" && ( have_state || need_state ) )
190 m_hash_type = Type::Md5 ;
196 m_state_size = m_value_size + 4U ;
198 else if( hash_type ==
"SHA1" && ( have_state || need_state ) )
200 m_hash_type = Type::Sha1 ;
201 SHA1_Init( &m_sha1 ) ;
206 m_state_size = m_value_size + 4U ;
208 else if( hash_type ==
"SHA256" && ( have_state || need_state ) )
210 m_hash_type = Type::Sha256 ;
211 SHA256_Init( &m_sha256 ) ;
216 m_state_size = m_value_size + 4U ;
220 m_hash_type = Type::Other ;
221 m_evp_ctx = EVP_MD_CTX_create() ;
223 const EVP_MD * md = EVP_get_digestbyname( hash_type.c_str() ) ;
225 throw Error(
"unsupported hash function name: [" + hash_type +
"]" ) ;
227 m_block_size =
static_cast<std::size_t
>( EVP_MD_block_size(md) ) ;
228 m_value_size =
static_cast<std::size_t
>( EVP_MD_size(md) ) ;
231 if( m_state_size == 0U && !state.empty() )
232 throw Error(
"hash state resoration not implemented for " + hash_type ) ;
234 EVP_DigestInit_ex( m_evp_ctx , md ,
nullptr ) ;
238GSsl::OpenSSL::DigesterImp::~DigesterImp()
240 if( m_hash_type == Type::Other )
241 EVP_MD_CTX_destroy( m_evp_ctx ) ;
244std::size_t GSsl::OpenSSL::DigesterImp::blocksize()
const
246 return m_block_size ;
249std::size_t GSsl::OpenSSL::DigesterImp::valuesize()
const
251 return m_value_size ;
254std::size_t GSsl::OpenSSL::DigesterImp::statesize()
const
256 return m_state_size ;
259std::string GSsl::OpenSSL::DigesterImp::state()
261 if( m_hash_type == Type::Md5 )
263 else if( m_hash_type == Type::Sha1 )
265 else if( m_hash_type == Type::Sha256 )
268 return std::string() ;
271void GSsl::OpenSSL::DigesterImp::add(
const std::string & data )
273 if( m_hash_type == Type::Md5 )
274 MD5_Update( &m_md5 , data.data() , data.size() ) ;
275 else if( m_hash_type == Type::Sha1 )
276 SHA1_Update( &m_sha1 , data.data() , data.size() ) ;
277 else if( m_hash_type == Type::Sha256 )
278 SHA256_Update( &m_sha256 , data.data() , data.size() ) ;
280 EVP_DigestUpdate( m_evp_ctx , data.data() , data.size() ) ;
283std::string GSsl::OpenSSL::DigesterImp::value()
285 std::vector<unsigned char> output ;
287 if( m_hash_type == Type::Md5 )
289 n = MD5_DIGEST_LENGTH ;
291 MD5_Final( &output[0] , &m_md5 ) ;
293 else if( m_hash_type == Type::Sha1 )
295 n = SHA_DIGEST_LENGTH ;
297 SHA1_Final( &output[0] , &m_sha1 ) ;
299 else if( m_hash_type == Type::Sha256 )
301 n = SHA256_DIGEST_LENGTH ;
303 SHA256_Final( &output[0] , &m_sha256 ) ;
307 unsigned int output_size = 0 ;
308 output.resize( EVP_MAX_MD_SIZE ) ;
309 EVP_DigestFinal_ex( m_evp_ctx , &output[0] , &output_size ) ;
310 n =
static_cast<std::size_t
>(output_size) ;
312 G_ASSERT( n == valuesize() ) ;
313 const char * p =
reinterpret_cast<char*
>(&output[0]) ;
314 return std::string(p,n) ;
319GSsl::OpenSSL::ProfileImp::ProfileImp(
const LibraryImp & library_imp ,
bool is_server_profile ,
320 const std::string & key_file ,
const std::string & cert_file ,
const std::string & ca_path ,
321 const std::string & default_peer_certificate_name ,
const std::string & default_peer_host_name ,
322 const std::string & profile_config ) :
323 m_library_imp(library_imp) ,
324 m_default_peer_certificate_name(default_peer_certificate_name) ,
325 m_default_peer_host_name(default_peer_host_name) ,
326 m_ssl_ctx(nullptr,std::function<void(SSL_CTX*)>(deleter))
330 Config extra_config = m_library_imp.config() ;
331 if( !profile_config.empty() )
334 extra_config = Config( profile_config_list ) ;
335 if( !profile_config_list.empty() )
336 G_WARNING(
"GSsl::OpenSSL::ProfileImp::ctor: tls-config: tls " << (is_server_profile?
"server":
"client")
337 <<
" profile configuration ignored: [" <<
G::Str::join(
",",profile_config_list) <<
"]" ) ;
340 if( m_ssl_ctx ==
nullptr )
342 Config::Fn version_fn = extra_config.fn( is_server_profile ) ;
343 m_ssl_ctx.reset( SSL_CTX_new( version_fn() ) ) ;
344 if( m_ssl_ctx !=
nullptr )
345 apply( extra_config ) ;
348 if( m_ssl_ctx ==
nullptr )
349 throw Error(
"SSL_CTX_new" , ERR_get_error() ) ;
351 if( !key_file.empty() )
355 G_WARNING(
"GSsl::Profile: " << format(
gettext(
"cannot open ssl key file: %1%")) % key_file ) ;
357 check( SSL_CTX_use_PrivateKey_file(m_ssl_ctx.get(),key_file.c_str(),SSL_FILETYPE_PEM) ,
358 "use_PrivateKey_file" , key_file ) ;
361 if( !cert_file.empty() )
365 G_WARNING(
"GSsl::Profile: " << format(
gettext(
"cannot open ssl certificate file: %1%")) % cert_file ) ;
367 check( SSL_CTX_use_certificate_chain_file(m_ssl_ctx.get(),cert_file.c_str()) ,
368 "use_certificate_chain_file" , cert_file ) ;
371 if( ca_path.empty() )
375 SSL_CTX_set_verify( m_ssl_ctx.get() , SSL_VERIFY_PEER , verifyPass ) ;
377 else if( ca_path ==
"<none>" )
380 SSL_CTX_set_verify( m_ssl_ctx.get() , SSL_VERIFY_NONE ,
nullptr ) ;
382 else if( ca_path ==
"<default>" )
385 bool no_verify = extra_config.noverify() ;
386 SSL_CTX_set_verify( m_ssl_ctx.get() , no_verify ? SSL_VERIFY_NONE : (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT) , verifyPeerName ) ;
387 check( SSL_CTX_set_default_verify_paths( m_ssl_ctx.get() ) ,
"set_default_verify_paths" ) ;
393 const char * ca_file_p = ca_path_is_dir ? nullptr : ca_path.c_str() ;
394 const char * ca_dir_p = ca_path_is_dir ? ca_path.c_str() : nullptr ;
395 bool no_verify = extra_config.noverify() ;
396 SSL_CTX_set_verify( m_ssl_ctx.get() , no_verify ? SSL_VERIFY_NONE : (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT) , verifyPeerName ) ;
397 check( SSL_CTX_load_verify_locations( m_ssl_ctx.get() , ca_file_p , ca_dir_p ) ,
"load_verify_locations" , ca_path ) ;
400 SSL_CTX_set_cipher_list( m_ssl_ctx.get() ,
"DEFAULT" ) ;
401 SSL_CTX_set_session_cache_mode( m_ssl_ctx.get() , SSL_SESS_CACHE_OFF ) ;
402 if( is_server_profile )
405 SSL_CTX_set_session_id_context( m_ssl_ctx.get() ,
reinterpret_cast<const unsigned char *
>(x.data()) , x.size() ) ;
409GSsl::OpenSSL::ProfileImp::~ProfileImp()
412void GSsl::OpenSSL::ProfileImp::deleter( SSL_CTX * p )
418std::unique_ptr<GSsl::ProtocolImpBase> GSsl::OpenSSL::ProfileImp::newProtocol(
const std::string & peer_certificate_name ,
419 const std::string & peer_host_name )
const
421 return std::make_unique<OpenSSL::ProtocolImp>( *
this ,
422 peer_certificate_name.empty()?defaultPeerCertificateName():peer_certificate_name ,
423 peer_host_name.empty()?defaultPeerHostName():peer_host_name ) ;
426SSL_CTX * GSsl::OpenSSL::ProfileImp::p()
const
428 return const_cast<SSL_CTX*
>( m_ssl_ctx.get() ) ;
433 return m_library_imp ;
436const std::string & GSsl::OpenSSL::ProfileImp::defaultPeerCertificateName()
const
438 return m_default_peer_certificate_name ;
441const std::string & GSsl::OpenSSL::ProfileImp::defaultPeerHostName()
const
443 return m_default_peer_host_name ;
446void GSsl::OpenSSL::ProfileImp::check(
int rc ,
const std::string & fnname_tail ,
const std::string & file )
450 std::string fnname =
"SSL_CTX_" + fnname_tail ;
451 throw Error( fnname , ERR_get_error() , file ) ;
455void GSsl::OpenSSL::ProfileImp::apply(
const Config & config )
457 #if GCONFIG_HAVE_OPENSSL_MIN_MAX
459 SSL_CTX_set_min_proto_version( m_ssl_ctx.get() , config.min_() ) ;
462 SSL_CTX_set_max_proto_version( m_ssl_ctx.get() , config.max_() ) ;
465 if( config.reset() != 0L )
466 SSL_CTX_clear_options( m_ssl_ctx.get() , config.reset() ) ;
468 if( config.set() != 0L )
469 SSL_CTX_set_options( m_ssl_ctx.get() , config.set() ) ;
472int GSsl::OpenSSL::ProfileImp::verifyPass(
int , X509_STORE_CTX * )
477int GSsl::OpenSSL::ProfileImp::verifyPeerName(
int ok , X509_STORE_CTX * ctx )
481 if( ok && X509_STORE_CTX_get_error_depth(ctx) == 0 )
483 SSL * ssl =
static_cast<SSL*
>( X509_STORE_CTX_get_ex_data( ctx , SSL_get_ex_data_X509_STORE_CTX_idx() ) ) ;
487 OpenSSL::LibraryImp & library =
dynamic_cast<OpenSSL::LibraryImp&
>(
Library::impstance() ) ;
488 OpenSSL::ProtocolImp * protocol =
static_cast<OpenSSL::ProtocolImp*
>( SSL_get_ex_data(ssl,library.index()) ) ;
489 if( protocol ==
nullptr )
492 std::string required_peer_certificate_name = protocol->requiredPeerCertificateName() ;
493 if( !required_peer_certificate_name.empty() )
495 X509 * cert = X509_STORE_CTX_get_current_cert( ctx ) ;
496 std::string subject = name(X509_get_subject_name(cert)) ;
498 bool found = std::find( subject_parts.begin() , subject_parts.end() ,
"CN="+required_peer_certificate_name ) != subject_parts.end() ;
499 library.log()( 2 ,
"certificate-subject=[" + subject +
"] required-peer-name=[" + required_peer_certificate_name +
"] ok=" + (found?
"1":
"0") ) ;
514std::string GSsl::OpenSSL::ProfileImp::name( X509_NAME * x509_name )
516 if( x509_name ==
nullptr )
return std::string() ;
517 std::vector<char> buffer( 2048U ) ;
518 X509_NAME_oneline( x509_name , &buffer[0] , buffer.size() ) ;
519 buffer.back() =
'\0' ;
525GSsl::OpenSSL::ProtocolImp::ProtocolImp(
const ProfileImp & profile ,
const std::string & required_peer_certificate_name ,
526 const std::string & target_peer_host_name ) :
527 m_ssl(nullptr,std::function<void(SSL*)>(deleter)) ,
528 m_log_fn(profile.lib().log()) ,
529 m_verbose(profile.lib().verbose()) ,
531 m_required_peer_certificate_name(required_peer_certificate_name) ,
534 m_ssl.reset( SSL_new(profile.p()) ) ;
535 if( m_ssl ==
nullptr )
536 throw Error(
"SSL_new" , ERR_get_error() ) ;
539 if( !target_peer_host_name.empty() )
540 SSL_set_tlsext_host_name( m_ssl.get() , target_peer_host_name.c_str() ) ;
543 SSL_set_ex_data( m_ssl.get() , profile.lib().index() ,
this ) ;
546GSsl::OpenSSL::ProtocolImp::~ProtocolImp()
549void GSsl::OpenSSL::ProtocolImp::deleter( SSL * p )
555void GSsl::OpenSSL::ProtocolImp::clearErrors()
559 Error::clearErrors() ;
562int GSsl::OpenSSL::ProtocolImp::error(
const char * op ,
int rc )
const
564 int e = SSL_get_error( m_ssl.get() , rc ) ;
569GSsl::Protocol::Result GSsl::OpenSSL::ProtocolImp::convert(
int e )
571 if( e == SSL_ERROR_WANT_READ )
return Protocol::Result::read ;
572 if( e == SSL_ERROR_WANT_WRITE )
return Protocol::Result::write ;
573 return Protocol::Result::error ;
576GSsl::Protocol::Result GSsl::OpenSSL::ProtocolImp::connect(
G::ReadWrite & io )
582GSsl::Protocol::Result GSsl::OpenSSL::ProtocolImp::accept(
G::ReadWrite & io )
588void GSsl::OpenSSL::ProtocolImp::set(
int fd )
592 int rc = SSL_set_fd( m_ssl.get() , fd ) ;
594 throw Error(
"SSL_set_fd" , ERR_get_error() ) ;
598 BIO_set_callback( SSL_get_rbio(m_ssl.get()) , BIO_debug_callback ) ;
599 BIO_set_callback( SSL_get_wbio(m_ssl.get()) , BIO_debug_callback ) ;
606GSsl::Protocol::Result GSsl::OpenSSL::ProtocolImp::connect()
609 int rc = SSL_connect( m_ssl.get() ) ;
613 return Protocol::Result::ok ;
617 return convert(error(
"SSL_connect",rc)) ;
621 return convert(error(
"SSL_connect",rc)) ;
625GSsl::Protocol::Result GSsl::OpenSSL::ProtocolImp::accept()
628 int rc = SSL_accept( m_ssl.get() ) ;
632 return Protocol::Result::ok ;
636 return convert(error(
"SSL_accept",rc)) ;
640 return convert(error(
"SSL_accept",rc)) ;
644void GSsl::OpenSSL::ProtocolImp::saveResult()
646 m_peer_certificate = Certificate(SSL_get_peer_certificate(m_ssl.get()),
true).str() ;
647 m_peer_certificate_chain = CertificateChain(SSL_get_peer_cert_chain(m_ssl.get())).str() ;
648 m_verified = !m_peer_certificate.empty() && SSL_get_verify_result(m_ssl.get()) == X509_V_OK ;
651GSsl::Protocol::Result GSsl::OpenSSL::ProtocolImp::shutdown()
653 int rc = SSL_shutdown( m_ssl.get() ) ;
654 if( rc == 0 || rc == 1 )
655 return Protocol::Result::ok ;
657 return convert( rc ) ;
660GSsl::Protocol::Result GSsl::OpenSSL::ProtocolImp::read(
char * buffer , std::size_t buffer_size_in , ssize_t & read_size )
665 int buffer_size =
static_cast<int>(buffer_size_in) ;
666 int rc = SSL_read( m_ssl.get() , buffer , buffer_size ) ;
669 read_size =
static_cast<ssize_t
>(rc) ;
670 return SSL_pending(m_ssl.get()) ? Protocol::Result::more : Protocol::Result::ok ;
674 return convert(error(
"SSL_read",rc)) ;
678 return convert(error(
"SSL_read",rc)) ;
682GSsl::Protocol::Result GSsl::OpenSSL::ProtocolImp::write(
const char * buffer , std::size_t size_in , ssize_t & size_out )
686 int size =
static_cast<int>(size_in) ;
687 int rc = SSL_write( m_ssl.get() , buffer , size ) ;
690 size_out =
static_cast<ssize_t
>(rc) ;
691 return Protocol::Result::ok ;
695 return convert(error(
"SSL_write",rc)) ;
699 return convert(error(
"SSL_write",rc)) ;
703std::string GSsl::OpenSSL::ProtocolImp::peerCertificate()
const
705 return m_peer_certificate ;
708std::string GSsl::OpenSSL::ProtocolImp::peerCertificateChain()
const
710 return m_peer_certificate_chain ;
713std::string GSsl::OpenSSL::ProtocolImp::cipher()
const
715 const SSL_CIPHER * cipher = SSL_get_current_cipher(
const_cast<SSL*
>(m_ssl.get()) ) ;
716 const char * name = cipher ? SSL_CIPHER_get_name(cipher) : nullptr ;
720std::string GSsl::OpenSSL::ProtocolImp::protocol()
const
722 #if OPENSSL_VERSION_NUMBER < 0x10100000L
723 int v = SSL_version( m_ssl.get() ) ;
725 const SSL_SESSION * session = SSL_get_session(
const_cast<SSL*
>(m_ssl.get()) ) ;
726 if( session ==
nullptr )
return std::string() ;
727 int v = SSL_SESSION_get_protocol_version( session ) ;
730 if( v == TLS1_VERSION )
return "TLSv1.0" ;
732 #ifdef TLS1_1_VERSION
733 if( v == TLS1_1_VERSION )
return "TLSv1.1" ;
735 #ifdef TLS1_2_VERSION
736 if( v == TLS1_2_VERSION )
return "TLSv1.2" ;
738 #ifdef TLS1_3_VERSION
739 if( v == TLS1_3_VERSION )
return "TLSv1.3" ;
741 if( v == 0x304 )
return "TLSv1.3" ;
746bool GSsl::OpenSSL::ProtocolImp::verified()
const
751void GSsl::OpenSSL::ProtocolImp::logErrors(
const std::string & op ,
int rc ,
int e ,
const std::string & strerr )
const
753 if( m_log_fn !=
nullptr )
757 std::ostringstream ss ;
758 ss << op <<
": rc=" << rc <<
": error " << e <<
" => " << strerr ;
759 (*m_log_fn)( 1 , ss.str() ) ;
762 for(
int i = 2 ; i < 10000 ; i++ )
764 unsigned long ee = ERR_get_error() ;
765 if( ee == 0 ) break ;
766 Error eee( op , ee ) ;
767 (*m_log_fn)( 3 , std::string() + eee.what() ) ;
772std::string GSsl::OpenSSL::ProtocolImp::requiredPeerCertificateName()
const
774 return m_required_peer_certificate_name ;
779GSsl::OpenSSL::Error::Error(
const std::string & s ) :
780 std::runtime_error(
"tls error: " + s )
784GSsl::OpenSSL::Error::Error(
const std::string & fnname ,
unsigned long e ) :
785 std::runtime_error(
"tls error: " + fnname +
"(): [" + text(e) +
"]" )
790GSsl::OpenSSL::Error::Error(
const std::string & fnname ,
unsigned long e ,
const std::string & file ) :
791 std::runtime_error(
"tls error: " + fnname +
"(): [" + text(e) +
"]: file=[" + file +
"]" )
796void GSsl::OpenSSL::Error::clearErrors()
798 for(
int i = 0 ; ERR_get_error() && i < 10000 ; i++ )
802std::string GSsl::OpenSSL::Error::text(
unsigned long e )
804 std::vector<char> v( 300 ) ;
805 ERR_error_string_n( e , &v[0] , v.size() ) ;
806 std::string s( &v[0] , v.size() ) ;
807 return std::string( s.c_str() ) ;
812GSsl::OpenSSL::CertificateChain::CertificateChain( STACK_OF(X509) * chain )
814 for(
int i = 0 ; chain !=
nullptr && i < sk_X509_num(chain) ; i++ )
816 void * p = sk_X509_value(chain,i) ;
if( p ==
nullptr ) break ;
817 X509 * x509 =
static_cast<X509*
>(p) ;
818 m_str.append( Certificate(x509,
false).str() ) ;
822std::string GSsl::OpenSSL::CertificateChain::str()
const
829GSsl::OpenSSL::Certificate::Certificate( X509 * x509 ,
bool do_free )
831 if( x509 ==
nullptr ) return ;
832 BIO * bio = BIO_new( BIO_s_mem() ) ;
833 int rc = PEM_write_bio_X509( bio , x509 ) ;
835 BUF_MEM * mem = nullptr ;
836 BIO_get_mem_ptr( bio , &mem ) ;
837 std::size_t n = mem ?
static_cast<std::size_t
>(mem->length) : 0U ;
838 const char * p = mem ? mem->data : nullptr ;
839 std::string data = p&&n ? std::string(p,n) : std::string() ;
841 if( do_free ) X509_free( x509 ) ;
850std::string GSsl::OpenSSL::Certificate::str()
const
861 m_options_reset(0L) ,
862 m_noverify(consume(cfg,
"noverify"))
864 #if GCONFIG_HAVE_OPENSSL_TLS_METHOD
865 m_server_fn = TLS_server_method ;
866 m_client_fn = TLS_client_method ;
868 m_server_fn = SSLv23_server_method ;
869 m_client_fn = SSLv23_client_method ;
872 #if GCONFIG_HAVE_OPENSSL_MIN_MAX
875 if( consume(cfg,
"sslv3") ) m_min = SSL3_VERSION ;
876 if( consume(cfg,
"-sslv3") ) m_max = SSL3_VERSION ;
880 if( consume(cfg,
"tlsv1.0") ) m_min = TLS1_VERSION ;
881 if( consume(cfg,
"-tlsv1.0") ) m_max = TLS1_VERSION ;
884 #ifdef TLS1_1_VERSION
885 if( consume(cfg,
"tlsv1.1") ) m_min = TLS1_1_VERSION ;
886 if( consume(cfg,
"-tlsv1.1") ) m_max = TLS1_1_VERSION ;
889 #ifdef TLS1_2_VERSION
890 if( consume(cfg,
"tlsv1.2") ) m_min = TLS1_2_VERSION ;
891 if( consume(cfg,
"-tlsv1.2") ) m_max = TLS1_2_VERSION ;
894 #ifdef TLS1_3_VERSION
895 if( consume(cfg,
"tlsv1.3") ) m_min = TLS1_3_VERSION ;
896 if( consume(cfg,
"-tlsv1.3") ) m_max = TLS1_3_VERSION ;
902 if( consume(cfg,
"op_all") ) m_options_set |= SSL_OP_ALL ;
905 #ifdef SSL_OP_NO_TICKET
906 if( consume(cfg,
"op_no_ticket") ) m_options_set |= SSL_OP_NO_TICKET ;
909 #ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
910 if( consume(cfg,
"op_no_resumption") ) m_options_set |= SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION ;
913 #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
914 if( consume(cfg,
"op_server_preference") ) m_options_set |= SSL_OP_CIPHER_SERVER_PREFERENCE ;
918bool GSsl::OpenSSL::Config::consume(
G::StringArray & list ,
const std::string & item )
923GSsl::OpenSSL::Config::Fn GSsl::OpenSSL::Config::fn(
bool server )
925 return server ? m_server_fn : m_client_fn ;
928long GSsl::OpenSSL::Config::set()
const
930 return m_options_set ;
933long GSsl::OpenSSL::Config::reset()
const
935 return m_options_reset ;
938int GSsl::OpenSSL::Config::min_()
const
943int GSsl::OpenSSL::Config::max_()
const
948bool GSsl::OpenSSL::Config::noverify()
const
A class for objects that can perform a cryptographic hash.
static bool consume(G::StringArray &list, const std::string &item)
A convenience function that removes the item from the list and returns true iff is was removed.
static LibraryImpBase & impstance()
Returns a reference to the pimple object when enabled().
Holds protocol version information, etc.
An implementation of the GSsl::LibraryImpBase interface for OpenSSL.
A base interface for profile classes that work with concrete classes derived from GSsl::LibraryImpBas...
static std::string str(Result result)
Converts a result enumeration into a printable string.
static bool isDirectory(const Path &path, std::nothrow_t)
Returns true if the path exists() and is a directory.
static bool exists(const Path &file)
Returns true if the file (directory, device etc.) exists.
static std::string encode(const uint_type *)
Returns the hash state as an N-character string of non-printing characters.
static void decode(const std::string &s, uint_type *values_out, size_type &size_out)
Converts an encode()d string back into a hash state of N/4 integers and a data size returned by refer...
A Path object represents a file system path.
std::string basename() const
Returns the rightmost part of the path, ignoring "." parts.
static std::string exe()
Returns the absolute path of the current executable, independent of the argv array passed to main().
An abstract interface for reading and writing from a non-blocking i/o channel.
virtual SOCKET fd() const noexcept=0
Returns the file descriptor.
A class which acquires the process's special privileges on construction and releases them on destruct...
static std::string join(const std::string &sep, const StringArray &strings)
Concatenates an array of strings with separators.
static void splitIntoTokens(const std::string &in, StringArray &out, string_view ws, char esc='\0')
Splits the string into 'ws'-delimited tokens.
static std::string unique(const std::string &s, char c, char r)
Returns a string with repeated 'c' characters replaced by one 'r' character.
static std::string fromInt(int i)
Converts int 'i' to a string.
static std::string printable(const std::string &in, char escape='\\')
Returns a printable representation of the given input string, using chacter code ranges 0x20 to 0x7e ...
static unsigned int replaceAll(std::string &s, const std::string &from, const std::string &to)
Does a global replace on string 's', replacing all occurrences of sub-string 'from' with 'to'.
static bool enabled() noexcept
Returns true if test features are enabled.
An interface to an underlying TLS library.
std::vector< std::string > StringArray
A std::vector of std::strings.
const char * gettext(const char *)
Returns the message translation in the current locale's codeset, eg.