diff options
author | George Hazan <ghazan@miranda.im> | 2020-07-01 14:45:01 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2020-07-01 14:45:01 +0300 |
commit | f10699e580b3eead1cb9c250822abbbc626eb3e3 (patch) | |
tree | 732540d8c618787c4244fc9fb6d8d8ca8fdb7e80 | |
parent | 4ac1dc06f30c240089da5cdeba6cbf46cd598a1e (diff) |
TLS 1.3 support:
Netlib_GetTlsUnique - new function to retrieve TLS binding data for an opened socket
-rw-r--r-- | include/m_netlib.h | 8 | ||||
-rw-r--r-- | include/m_ssl.h | 14 | ||||
-rw-r--r-- | libs/win32/mir_app.lib | bin | 208066 -> 208302 bytes | |||
-rw-r--r-- | libs/win64/mir_app.lib | bin | 203708 -> 203928 bytes | |||
-rw-r--r-- | protocols/JabberG/src/jabber_secur.cpp | 26 | ||||
-rw-r--r-- | protocols/JabberG/src/jabber_secur.h | 6 | ||||
-rwxr-xr-x | protocols/JabberG/src/jabber_thread.cpp | 8 | ||||
-rw-r--r-- | src/core/stdssl/src/netlibssl.cpp | 23 | ||||
-rw-r--r-- | src/mir_app/src/mir_app.def | 1 | ||||
-rw-r--r-- | src/mir_app/src/mir_app64.def | 1 | ||||
-rw-r--r-- | src/mir_app/src/netlib_sock.cpp | 17 |
11 files changed, 83 insertions, 21 deletions
diff --git a/include/m_netlib.h b/include/m_netlib.h index 9a77973461..a52100ff3f 100644 --- a/include/m_netlib.h +++ b/include/m_netlib.h @@ -389,7 +389,7 @@ EXTERN_C MIR_APP_DLL(char*) Netlib_AddressToString(sockaddr_in *addr); EXTERN_C MIR_APP_DLL(bool) Netlib_StringToAddress(const char *str, sockaddr_in *addr);
/////////////////////////////////////////////////////////////////////////////////////////
-// Get connection Information
+// Gets connection Information
// IPv4 will be supplied in formats address:port or address
// IPv6 will be supplied in formats [address]:port or [address]
// Returns 0 if successful
@@ -404,6 +404,12 @@ struct NETLIBCONNINFO EXTERN_C MIR_APP_DLL(int) Netlib_GetConnectionInfo(HNETLIBCONN hConnection, NETLIBCONNINFO *connInfo);
/////////////////////////////////////////////////////////////////////////////////////////
+// Gets TLS channel binging data for a socket
+// Returns true if successful
+
+EXTERN_C MIR_APP_DLL(void*) Netlib_GetTlsUnique(HNETLIBCONN nlc, int &cbLen);
+
+/////////////////////////////////////////////////////////////////////////////////////////
// Gets connection Information
//
// Returns (INT_PTR)(NETLIBIPLIST*) numeric IP address address array
diff --git a/include/m_ssl.h b/include/m_ssl.h index d08bc8874d..b55f37eb85 100644 --- a/include/m_ssl.h +++ b/include/m_ssl.h @@ -31,12 +31,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. DECLARE_HANDLE(HSSL);
#endif
-typedef HSSL (__cdecl *pfnConnect)(SOCKET s, const char* host, int verify);
-typedef BOOL (__cdecl *pfnPending)(HSSL ssl);
-typedef int (__cdecl *pfnRead)(HSSL ssl, char *buf, int num, int peek);
-typedef int (__cdecl *pfnWrite)(HSSL ssl, const char *buf, int num);
-typedef void (__cdecl *pfnShutdown)(HSSL ssl);
-typedef void (__cdecl *pfnSfree)(HSSL ssl);
+typedef HSSL (__cdecl *pfnConnect)(SOCKET s, const char* host, int verify);
+typedef BOOL (__cdecl *pfnPending)(HSSL ssl);
+typedef int (__cdecl *pfnRead)(HSSL ssl, char *buf, int num, int peek);
+typedef int (__cdecl *pfnWrite)(HSSL ssl, const char *buf, int num);
+typedef void (__cdecl *pfnShutdown)(HSSL ssl);
+typedef void (__cdecl *pfnSfree)(HSSL ssl);
+typedef void *(__cdecl *pfnUnique)(HSSL ssl, int *cbLen);
struct SSL_API
{
@@ -48,6 +49,7 @@ struct SSL_API pfnWrite write;
pfnShutdown shutdown;
pfnSfree sfree;
+ pfnUnique unique;
};
/*
diff --git a/libs/win32/mir_app.lib b/libs/win32/mir_app.lib Binary files differindex 53816488ba..a96077ac5d 100644 --- a/libs/win32/mir_app.lib +++ b/libs/win32/mir_app.lib diff --git a/libs/win64/mir_app.lib b/libs/win64/mir_app.lib Binary files differindex 7b732bbcfe..3cc71cb27b 100644 --- a/libs/win64/mir_app.lib +++ b/libs/win64/mir_app.lib diff --git a/protocols/JabberG/src/jabber_secur.cpp b/protocols/JabberG/src/jabber_secur.cpp index 67bc2b1ae7..d3f640f194 100644 --- a/protocols/JabberG/src/jabber_secur.cpp +++ b/protocols/JabberG/src/jabber_secur.cpp @@ -206,11 +206,18 @@ char* TMD5Auth::getChallenge(const char *challenge) /////////////////////////////////////////////////////////////////////////////////////////
// SCRAM-SHA-1 authorization
-TScramAuth::TScramAuth(ThreadData *info, bool bPlus) :
- TJabberAuth(info),
- bindingData(bPlus ? "p=tls-unique,," : "n,,")
+TScramAuth::TScramAuth(ThreadData *info, void *pData, size_t cbLen) :
+ TJabberAuth(info)
{
- szName = (bPlus) ? "SCRAM-SHA-1-PLUS" : "SCRAM-SHA-1";
+ if (pData) {
+ szName = "SCRAM-SHA-1-PLUS";
+ bindFlag = "p=tls-unique,,";
+ bindData.append(pData, cbLen);
+ }
+ else {
+ szName = "SCRAM-SHA-1";
+ bindFlag = "n,,";
+ }
}
TScramAuth::~TScramAuth()
@@ -247,7 +254,7 @@ char* TScramAuth::getInitialRequest() CMStringA buf(FORMAT, "n=%s,r=%s", info->conn.username, cnonce);
msg1 = mir_strdup(buf);
- buf.Insert(0, bindingData);
+ buf.Insert(0, bindFlag);
return mir_base64_encode(buf, buf.GetLength());
}
@@ -257,8 +264,13 @@ char* TScramAuth::getChallenge(const char *challenge) ptrA snonce, salt;
int ind = -1;
- ptrA chl((char*)mir_base64_decode(challenge, &chlLen));
- ptrA cbd(mir_base64_encode(bindingData, mir_strlen(bindingData)));
+ ptrA chl((char *)mir_base64_decode(challenge, &chlLen)), cbd;
+ if (bindData.isEmpty())
+ cbd = mir_base64_encode(bindFlag, mir_strlen(bindFlag));
+ else {
+ bindData.appendBefore((void*)bindFlag, mir_strlen(bindFlag));
+ cbd = mir_base64_encode(bindData.data(), bindData.length());
+ }
for (char *p = strtok(NEWSTR_ALLOCA(chl), ","); p != nullptr; p = strtok(nullptr, ",")) {
if (*p == 'r' && p[1] == '=') { // snonce
diff --git a/protocols/JabberG/src/jabber_secur.h b/protocols/JabberG/src/jabber_secur.h index fa3d7531da..dc098213bf 100644 --- a/protocols/JabberG/src/jabber_secur.h +++ b/protocols/JabberG/src/jabber_secur.h @@ -84,11 +84,11 @@ class TScramAuth : public TJabberAuth {
typedef TJabberAuth CSuper;
- const char *bindingData;
- char *cnonce = 0, *msg1 = 0, *serverSignature = 0;
+ char *bindFlag, *cnonce = 0, *msg1 = 0, *serverSignature = 0;
+ MBinBuffer bindData;
public:
- TScramAuth(ThreadData*, bool);
+ TScramAuth(ThreadData*, void *pData = nullptr, size_t cbLen = 0);
~TScramAuth();
char* getInitialRequest() override;
diff --git a/protocols/JabberG/src/jabber_thread.cpp b/protocols/JabberG/src/jabber_thread.cpp index 69d039957d..77ea881769 100755 --- a/protocols/JabberG/src/jabber_thread.cpp +++ b/protocols/JabberG/src/jabber_thread.cpp @@ -629,12 +629,16 @@ void CJabberProto::PerformAuthentication(ThreadData *info) if (auth == nullptr && m_isScramPlusAvailable) {
m_isScramPlusAvailable = false;
- auth = new TScramAuth(info, true);
+
+ int len = 0;
+ void *pBuf = Netlib_GetTlsUnique(info->s, len);
+ if (pBuf)
+ auth = new TScramAuth(info, pBuf, len);
}
if (auth == nullptr && m_isScramAvailable) {
m_isScramAvailable = false;
- auth = new TScramAuth(info, false);
+ auth = new TScramAuth(info);
}
if (auth == nullptr && m_isMd5Available) {
diff --git a/src/core/stdssl/src/netlibssl.cpp b/src/core/stdssl/src/netlibssl.cpp index b8f3975a55..8e7b834646 100644 --- a/src/core/stdssl/src/netlibssl.cpp +++ b/src/core/stdssl/src/netlibssl.cpp @@ -751,6 +751,28 @@ int NetlibSslWrite(SslHandle *ssl, const char *buf, int num) return scRet == SEC_E_OK ? num : SOCKET_ERROR;
}
+static void* NetlibSslUnique(SslHandle *ssl, int *cbLen)
+{
+ *cbLen = 0;
+
+ SEC_CHANNEL_BINDINGS bindings;
+ SECURITY_STATUS scRet = g_pSSPI->QueryContextAttributesW(&ssl->hContext, SECPKG_ATTR_UNIQUE_BINDINGS, &bindings);
+ if (scRet != SEC_E_OK)
+ return nullptr;
+
+ LPBYTE pBuf = LPBYTE(bindings.dwInitiatorOffset);
+ bindings = *(SEC_CHANNEL_BINDINGS *)bindings.dwInitiatorOffset;
+ pBuf += bindings.dwApplicationDataOffset;
+ if (memcmp(pBuf, "tls-unique:", 11))
+ return nullptr;
+
+ pBuf += 11; bindings.cbApplicationDataLength -= 11;
+ *cbLen = bindings.cbApplicationDataLength;
+ void *res = mir_alloc(bindings.cbApplicationDataLength);
+ memcpy(res, pBuf, bindings.cbApplicationDataLength);
+ return res;
+}
+
static INT_PTR GetSslApi(WPARAM, LPARAM lParam)
{
SSL_API *si = (SSL_API*)lParam;
@@ -766,6 +788,7 @@ static INT_PTR GetSslApi(WPARAM, LPARAM lParam) si->write = NetlibSslWrite;
si->shutdown = NetlibSslShutdown;
si->sfree = NetlibSslFree;
+ si->unique = NetlibSslUnique;
return TRUE;
}
diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def index 608dd1e07b..0bf07ba1cc 100644 --- a/src/mir_app/src/mir_app.def +++ b/src/mir_app/src/mir_app.def @@ -740,3 +740,4 @@ Chat_CreateMenu @824 NONAME ?OnEventEdited@PROTO_INTERFACE@@UAEXII@Z @828 NONAME
?GetChecker@MDatabaseCommon@@UAGPAUMIDatabaseChecker@@XZ @829 NONAME
?GetMenuItem@PROTO_INTERFACE@@QAEPAUTMO_IntMenuItem@@W4ProtoMenuItemType@@@Z @830 NONAME
+_Netlib_GetTlsUnique@8 @831 NONAME
diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def index 2e123cd123..945587d58a 100644 --- a/src/mir_app/src/mir_app64.def +++ b/src/mir_app/src/mir_app64.def @@ -740,3 +740,4 @@ Chat_CreateMenu @824 NONAME ?OnEventEdited@PROTO_INTERFACE@@UEAAXII@Z @828 NONAME
?GetChecker@MDatabaseCommon@@UEAAPEAUMIDatabaseChecker@@XZ @829 NONAME
?GetMenuItem@PROTO_INTERFACE@@QEAAPEAUTMO_IntMenuItem@@W4ProtoMenuItemType@@@Z @830 NONAME
+Netlib_GetTlsUnique @831 NONAME
diff --git a/src/mir_app/src/netlib_sock.cpp b/src/mir_app/src/netlib_sock.cpp index 2c4bfdc82a..a5f03114d0 100644 --- a/src/mir_app/src/netlib_sock.cpp +++ b/src/mir_app/src/netlib_sock.cpp @@ -210,9 +210,8 @@ MIR_APP_DLL(char*) Netlib_AddressToString(sockaddr_in *addr) ///////////////////////////////////////////////////////////////////////////////////////// -MIR_APP_DLL(int) Netlib_GetConnectionInfo(HNETLIBCONN hConnection, NETLIBCONNINFO *connInfo) +MIR_APP_DLL(int) Netlib_GetConnectionInfo(HNETLIBCONN nlc, NETLIBCONNINFO *connInfo) { - NetlibConnection *nlc = (NetlibConnection*)hConnection; if (!nlc || !connInfo) return 1; @@ -228,6 +227,20 @@ MIR_APP_DLL(int) Netlib_GetConnectionInfo(HNETLIBCONN hConnection, NETLIBCONNINF ///////////////////////////////////////////////////////////////////////////////////////// +MIR_APP_DLL(void*) Netlib_GetTlsUnique(HNETLIBCONN nlc, int &cbLen) +{ + if (nlc == nullptr || nlc->hSsl == nullptr || sslApi.unique == nullptr) + return nullptr; + + void *pBuf = sslApi.unique(nlc->hSsl, &cbLen); + if (pBuf == nullptr || !cbLen) + return nullptr; + + return pBuf; +} + +///////////////////////////////////////////////////////////////////////////////////////// + inline bool IsAddrGlobal(const IN6_ADDR *a) { unsigned char High = a->s6_bytes[0] & 0xf0; |