From 086617572376a04a929bce0a14aa23c799bce277 Mon Sep 17 00:00:00 2001 From: Dmitrii Pichulin Date: Wed, 13 Mar 2024 00:16:29 +0300 Subject: [PATCH] update gostssl --- src/gostssl.cpp | 91 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 69 insertions(+), 22 deletions(-) diff --git a/src/gostssl.cpp b/src/gostssl.cpp index 05385e3..1712040 100644 --- a/src/gostssl.cpp +++ b/src/gostssl.cpp @@ -55,9 +55,16 @@ DLLEXPORT char gostssl_certificate_info( const char * cert, size_t size, const c #include #else #define LEGACY_FORMAT_MESSAGE_IMPL +#define UNIX +#ifndef SIZEOF_VOID_P +#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) +#define SIZEOF_VOID_P 8 +#else +#define SIZEOF_VOID_P 4 +#endif +#endif /*SIZEOF_VOID_P*/ #include "CSP_WinDef.h" #include "CSP_WinCrypt.h" -#define UNIX #endif // WIN32 #include "WinCryptEx.h" @@ -87,6 +94,11 @@ static const SSL_CIPHER * tls_FF85 = NULL; static int g_tlsmode = 2; +#define TLS_FLAG_V1_0 ( 1 << 0 ) +#define TLS_FLAG_V1_1 ( 1 << 1 ) +#define TLS_FLAG_V1_2 ( 1 << 2 ) +#define TLS_FLAG_V1_3 ( 1 << 3 ) + int gostssl_init() { if( g_tlsmode == -1 ) @@ -110,15 +122,20 @@ int gostssl_init() NULL == ( tls_FF85 = boring_SSL_get_cipher_by_value( 0xFF85 ) ) ) return init_status; + char tls10 = msspi_is_version_supported( TLS1_VERSION ); + char tls11 = msspi_is_version_supported( TLS1_1_VERSION ); + char tls12 = msspi_is_version_supported( TLS1_2_VERSION ); + char tls13 = msspi_is_version_supported( TLS1_3_VERSION ); + char cipher_0x0081 = msspi_is_cipher_supported( 0x0081 ); - char cipher_0xC100 = msspi_is_cipher_supported( 0xC100 ); - char cipher_0xC101 = msspi_is_cipher_supported( 0xC101 ); - char cipher_0xC102 = msspi_is_cipher_supported( 0xC102 ); - char cipher_0xC103 = msspi_is_cipher_supported( 0xC103 ); - char cipher_0xC104 = msspi_is_cipher_supported( 0xC104 ); - char cipher_0xC105 = msspi_is_cipher_supported( 0xC105 ); - char cipher_0xC106 = msspi_is_cipher_supported( 0xC106 ); char cipher_0xFF85 = msspi_is_cipher_supported( 0xFF85 ); + char cipher_0xC100 = tls12 ? msspi_is_cipher_supported( 0xC100 ) : 0; + char cipher_0xC101 = tls12 ? msspi_is_cipher_supported( 0xC101 ) : 0; + char cipher_0xC102 = tls12 ? msspi_is_cipher_supported( 0xC102 ) : 0; + char cipher_0xC103 = tls13 ? msspi_is_cipher_supported( 0xC103 ) : 0; + char cipher_0xC104 = tls13 ? msspi_is_cipher_supported( 0xC104 ) : 0; + char cipher_0xC105 = tls13 ? msspi_is_cipher_supported( 0xC105 ) : 0; + char cipher_0xC106 = tls13 ? msspi_is_cipher_supported( 0xC106 ) : 0; bool cipher_tls10 = cipher_0x0081 || cipher_0xFF85; bool cipher_tls11 = cipher_tls10; @@ -126,22 +143,17 @@ int gostssl_init() bool cipher_tls13 = cipher_0xC103 || cipher_0xC104 || cipher_0xC105 || cipher_0xC106; bool cipher_any = cipher_tls10 || cipher_tls11 || cipher_tls12 || cipher_tls13; - char tls10 = msspi_is_version_supported( TLS1_VERSION ); - char tls11 = msspi_is_version_supported( TLS1_1_VERSION ); - char tls12 = msspi_is_version_supported( TLS1_2_VERSION ); - char tls13 = msspi_is_version_supported( TLS1_3_VERSION ); - if( tls10 && cipher_tls10 ) - init_status |= ( 1 << 0 ); + init_status |= TLS_FLAG_V1_0; if( tls11 && cipher_tls11 ) - init_status |= ( 1 << 1 ); + init_status |= TLS_FLAG_V1_1; if( tls12 && cipher_tls12 ) - init_status |= ( 1 << 2 ); + init_status |= TLS_FLAG_V1_2; if( tls13 && cipher_tls13 ) - init_status |= ( 1 << 3 ); + init_status |= TLS_FLAG_V1_3; if( init_status == 0 && cipher_any ) - init_status = 1; + init_status = TLS_FLAG_V1_0; return init_status; } @@ -367,6 +379,28 @@ static GostSSL_Worker * workers_api( const SSL * s, WORKER_DB_ACTION action, con w->host_string += cachestring ? cachestring : "*"; w->host_status = host_status_get( w->host_string ); + int tls_flags = gostssl_init(); + if( tls_flags && tls_flags != TLS_FLAG_V1_0 ) + { + int min = TLS1_3_VERSION; + if( tls_flags & TLS_FLAG_V1_0 ) + min = TLS1_VERSION; + else if( tls_flags & TLS_FLAG_V1_1 ) + min = TLS1_1_VERSION; + else if( tls_flags & TLS_FLAG_V1_2 ) + min = TLS1_2_VERSION; + + int max = TLS1_VERSION; + if( tls_flags & TLS_FLAG_V1_3 ) + min = TLS1_3_VERSION; + else if( tls_flags & TLS_FLAG_V1_2 ) + min = TLS1_2_VERSION; + else if( tls_flags & TLS_FLAG_V1_1 ) + min = TLS1_1_VERSION; + + msspi_set_version( w->h, min, max ); + } + msspi_set_cert_cb( w->h, (msspi_cert_cb)gostssl_cert_cb ); msspi_set_cipherlist( w->h, ciphers ); w->tlsmode = atoi( tlsmode ); @@ -774,18 +808,21 @@ static std::vector & g_certbufs = *( new std::vector() static std::vector & g_certnames = *( new std::vector() ); static std::vector & g_certnamebufs = *( new std::vector() ); -static BOOL CertHasOid( PCCERT_CONTEXT pcert, const char * oid ) +static BOOL CertHasUsage( PCCERT_CONTEXT pcert, const char * oid ) { DWORD ekuLength = 0; - BOOL result = CertGetEnhancedKeyUsage( pcert, 0, NULL, &ekuLength ); - if( result && ekuLength > 0 ) + if( CertGetEnhancedKeyUsage( pcert, 0, NULL, &ekuLength ) && ekuLength > 0 ) { std::vector ekuListBuffer(ekuLength); PCERT_ENHKEY_USAGE ekuList = (PCERT_ENHKEY_USAGE) &ekuListBuffer[0]; if( CertGetEnhancedKeyUsage( pcert, 0, ekuList, &ekuLength ) ) + { + if( ekuList->cUsageIdentifier == 0 ) + return GetLastError() == CRYPT_E_NOT_FOUND ? TRUE : FALSE; for( DWORD i = 0; i < ekuList->cUsageIdentifier; i++ ) if( 0 == strcmp( ekuList->rgpszUsageIdentifier[i], oid ) ) return TRUE; + } } return FALSE; } @@ -795,10 +832,20 @@ void gostssl_clientcertshook( char *** certs, int ** lens, wchar_t *** names, in *is_gost = 1; *count = 0; + if( g_tlsmode == -1 ) + { + *is_gost = 0; + return; + } + HCERTSTORE hStore = CertOpenStore( CERT_STORE_PROV_SYSTEM_A, 0, 0, CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_CURRENT_USER, "MY" ); if( !hStore ) + { + if( g_tlsmode != 1 ) + *is_gost = 0; return; + } int i = 0; g_certs.clear(); @@ -815,7 +862,7 @@ void gostssl_clientcertshook( char *** certs, int ** lens, wchar_t *** names, in // basic TLS client cert filtering if( CertVerifyTimeValidity( NULL, pcert->pCertInfo ) == 0 && CertGetCertificateContextProperty( pcert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &dw ) - && CertHasOid( pcert, szOID_PKIX_KP_CLIENT_AUTH ) ) + && CertHasUsage( pcert, szOID_PKIX_KP_CLIENT_AUTH ) ) { g_certbufs.push_back( std::string( (char *)pcert->pbCertEncoded, pcert->cbCertEncoded ) ); g_certlens.push_back( (int)g_certbufs[i].size() );