bool OpenSSLBase::handshake() { doTLSOperation( TLSHandshake ); if( !m_secure ) return true; int res = SSL_get_verify_result( m_ssl ); if( res != X509_V_OK ) m_certInfo.status = CertInvalid; else m_certInfo.status = CertOk; X509* peer = SSL_get_peer_certificate( m_ssl ); if( peer ) { char peer_CN[256]; X509_NAME_get_text_by_NID( X509_get_issuer_name( peer ), NID_commonName, peer_CN, sizeof( peer_CN ) ); m_certInfo.issuer = peer_CN; X509_NAME_get_text_by_NID( X509_get_subject_name( peer ), NID_commonName, peer_CN, sizeof( peer_CN ) ); m_certInfo.server = peer_CN; m_certInfo.date_from = openSSLTime2UnixTime( (char*) (peer->cert_info->validity->notBefore->data) ); m_certInfo.date_to = openSSLTime2UnixTime( (char*) (peer->cert_info->validity->notAfter->data) ); std::string p( peer_CN ); std::transform( p.begin(), p.end(), p.begin(), tolower ); if( p != m_server ) m_certInfo.status |= CertWrongPeer; if( ASN1_UTCTIME_cmp_time_t( X509_get_notBefore( peer ), time( 0 ) ) != -1 ) m_certInfo.status |= CertNotActive; if( ASN1_UTCTIME_cmp_time_t( X509_get_notAfter( peer ), time( 0 ) ) != 1 ) m_certInfo.status |= CertExpired; } else { m_certInfo.status = CertInvalid; } const char* tmp; tmp = SSL_get_cipher_name( m_ssl ); if( tmp ) m_certInfo.cipher = tmp; tmp = SSL_get_cipher_version( m_ssl ); if( tmp ) m_certInfo.protocol = tmp; tmp = SSL_COMP_get_name( SSL_get_current_compression( m_ssl ) ); if( tmp ) m_certInfo.compression = tmp; m_valid = true; m_handler->handleHandshakeResult( this, true, m_certInfo ); return true; }
int OpenSSL::decrypt( const std::string& data ) { m_recvBuffer += data; if( !m_secure ) { handshake(); return 0; } doTLSOperation( TLSRead ); return true; }
bool OpenSSL::encrypt( const std::string& data ) { m_sendBuffer += data; if( !m_secure ) { handshake(); return 0; } doTLSOperation( TLSWrite ); return true; }
bool OpenSSLBase::handshake() { doTLSOperation( TLSHandshake ); if( !m_secure ) return true; long res = SSL_get_verify_result( m_ssl ); if( res != X509_V_OK ) m_certInfo.status = CertInvalid; else m_certInfo.status = CertOk; X509* peer = SSL_get_peer_certificate( m_ssl ); if( peer ) { char peer_CN[256]; X509_NAME_get_text_by_NID( X509_get_issuer_name( peer ), NID_commonName, peer_CN, sizeof( peer_CN ) ); m_certInfo.issuer = peer_CN; X509_NAME_get_text_by_NID( X509_get_subject_name( peer ), NID_commonName, peer_CN, sizeof( peer_CN ) ); m_certInfo.server = peer_CN; m_certInfo.date_from = ASN1Time2UnixTime( X509_get_notBefore( peer ) ); m_certInfo.date_to = ASN1Time2UnixTime( X509_get_notAfter( peer ) ); std::string p( peer_CN ); std::transform( p.begin(), p.end(), p.begin(), tolower ); #if defined OPENSSL_VERSION_NUMBER && ( OPENSSL_VERSION_NUMBER >= 0x10002000 ) res = X509_check_host( peer, p.c_str(), p.length(), X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS, 0 ); if( res <= 0 ) // 0: verification failed; -1: internal error; -2 input is malformed m_certInfo.status |= CertWrongPeer; #else if( p != m_server ) m_certInfo.status |= CertWrongPeer; #endif // OPENSSL_VERSION_NUMBER >= 0x10002000 if( ASN1_UTCTIME_cmp_time_t( X509_get_notBefore( peer ), time( 0 ) ) != -1 ) m_certInfo.status |= CertNotActive; if( ASN1_UTCTIME_cmp_time_t( X509_get_notAfter( peer ), time( 0 ) ) != 1 ) m_certInfo.status |= CertExpired; X509_free( peer ); } else { m_certInfo.status = CertInvalid; } const char* tmp; tmp = SSL_get_cipher_name( m_ssl ); if( tmp ) m_certInfo.cipher = tmp; SSL_SESSION* sess = SSL_get_session( m_ssl ); if( sess ) { switch( SSL_SESSION_get_protocol_version( sess ) ) { case TLS1_VERSION: m_certInfo.protocol = "TLSv1"; break; case TLS1_1_VERSION: m_certInfo.protocol = "TLSv1.1"; break; case TLS1_2_VERSION: m_certInfo.protocol = "TLSv1.2"; break; #ifdef TLS1_3_VERSION case TLS1_3_VERSION: m_certInfo.protocol = "TLSv1.3"; break; #endif // TLS1_3_VERSION default: m_certInfo.protocol = "Unknown TLS version"; break; } } tmp = SSL_COMP_get_name( SSL_get_current_compression( m_ssl ) ); if( tmp ) m_certInfo.compression = tmp; m_valid = true; m_handler->handleHandshakeResult( this, true, m_certInfo ); return true; }