From dbf988c60736cc5e226c55b19e6a0a68a085bf3b Mon Sep 17 00:00:00 2001 From: George Hazan Date: Fri, 10 Jul 2020 16:20:04 +0300 Subject: fixes #1727 completely (Jabber: SCRAM-SHA-1(-PLUS) + SCRAM-SHA-256(-PLUS) support) --- protocols/JabberG/src/jabber_proto.h | 6 ++++-- protocols/JabberG/src/jabber_secur.cpp | 19 ++++++++--------- protocols/JabberG/src/jabber_secur.h | 3 ++- protocols/JabberG/src/jabber_thread.cpp | 36 ++++++++++++++++++++++++--------- 4 files changed, 43 insertions(+), 21 deletions(-) (limited to 'protocols/JabberG/src') diff --git a/protocols/JabberG/src/jabber_proto.h b/protocols/JabberG/src/jabber_proto.h index 9a0588d6e1..6531e59319 100755 --- a/protocols/JabberG/src/jabber_proto.h +++ b/protocols/JabberG/src/jabber_proto.h @@ -800,8 +800,10 @@ struct CJabberProto : public PROTO, public IJabberInterface bool m_isPlainAvailable : 1; bool m_isPlainOldAvailable : 1; bool m_isMd5Available : 1; - bool m_isScramAvailable : 1; - bool m_isScramPlusAvailable : 1; + bool m_isScramSha1Available : 1; + bool m_isScramSha1PlusAvailable : 1; + bool m_isScramSha256Available : 1; + bool m_isScramSha256PlusAvailable : 1; bool m_isNtlmAvailable : 1; bool m_isSpnegoAvailable : 1; bool m_isKerberosAvailable : 1; diff --git a/protocols/JabberG/src/jabber_secur.cpp b/protocols/JabberG/src/jabber_secur.cpp index d3f640f194..0a20304cc7 100644 --- a/protocols/JabberG/src/jabber_secur.cpp +++ b/protocols/JabberG/src/jabber_secur.cpp @@ -206,16 +206,17 @@ char* TMD5Auth::getChallenge(const char *challenge) ///////////////////////////////////////////////////////////////////////////////////////// // SCRAM-SHA-1 authorization -TScramAuth::TScramAuth(ThreadData *info, void *pData, size_t cbLen) : - TJabberAuth(info) +TScramAuth::TScramAuth(ThreadData *info, bool bSha1, void *pData, size_t cbLen) : + TJabberAuth(info), + hashMethod(bSha1 ? EVP_sha1() : EVP_sha256()) { if (pData) { - szName = "SCRAM-SHA-1-PLUS"; + szName = bSha1 ? "SCRAM-SHA-1-PLUS" : "SCRAM-SHA-256-PLUS"; bindFlag = "p=tls-unique,,"; bindData.append(pData, cbLen); } else { - szName = "SCRAM-SHA-1"; + szName = bSha1 ? "SCRAM-SHA-1" : "SCRAM-SHA-256"; bindFlag = "n,,"; } } @@ -237,7 +238,7 @@ void TScramAuth::Hi(BYTE* res, char* passw, size_t passwLen, char* salt, size_t for (int i = 0; i < ind; i++) { unsigned int len; - HMAC(EVP_sha1(), (BYTE*)passw, (unsigned)passwLen, u, (unsigned)bufLen, u, &len); + HMAC(hashMethod, (BYTE*)passw, (unsigned)passwLen, u, (unsigned)bufLen, u, &len); bufLen = MIR_SHA1_HASH_SIZE; for (unsigned j = 0; j < MIR_SHA1_HASH_SIZE; j++) @@ -292,7 +293,7 @@ char* TScramAuth::getChallenge(const char *challenge) BYTE clientKey[MIR_SHA1_HASH_SIZE]; unsigned int len; - HMAC(EVP_sha1(), saltedPassw, sizeof(saltedPassw), (BYTE*)"Client Key", 10, clientKey, &len); + HMAC(hashMethod, saltedPassw, sizeof(saltedPassw), (BYTE*)"Client Key", 10, clientKey, &len); BYTE storedKey[MIR_SHA1_HASH_SIZE]; @@ -304,7 +305,7 @@ char* TScramAuth::getChallenge(const char *challenge) CMStringA authmsg(FORMAT, "%s,%s,c=%s,r=%s", msg1, chl.get(), cbd.get(), snonce.get()); BYTE clientSig[MIR_SHA1_HASH_SIZE]; - HMAC(EVP_sha1(), storedKey, sizeof(storedKey), (BYTE*)authmsg.c_str(), authmsg.GetLength(), clientSig, &len); + HMAC(hashMethod, storedKey, sizeof(storedKey), (BYTE*)authmsg.c_str(), authmsg.GetLength(), clientSig, &len); BYTE clientProof[MIR_SHA1_HASH_SIZE]; for (unsigned j = 0; j < sizeof(clientKey); j++) @@ -312,10 +313,10 @@ char* TScramAuth::getChallenge(const char *challenge) /* Calculate the server signature */ BYTE serverKey[MIR_SHA1_HASH_SIZE]; - HMAC(EVP_sha1(), saltedPassw, sizeof(saltedPassw), (BYTE*)"Server Key", 10, serverKey, &len); + HMAC(hashMethod, saltedPassw, sizeof(saltedPassw), (BYTE*)"Server Key", 10, serverKey, &len); BYTE srvSig[MIR_SHA1_HASH_SIZE]; - HMAC(EVP_sha1(), serverKey, sizeof(serverKey), (BYTE*)authmsg.c_str(), authmsg.GetLength(), srvSig, &len); + HMAC(hashMethod, serverKey, sizeof(serverKey), (BYTE*)authmsg.c_str(), authmsg.GetLength(), srvSig, &len); serverSignature = mir_base64_encode(srvSig, sizeof(srvSig)); ptrA encproof(mir_base64_encode(clientProof, sizeof(clientProof))); diff --git a/protocols/JabberG/src/jabber_secur.h b/protocols/JabberG/src/jabber_secur.h index dc098213bf..78dccfa70a 100644 --- a/protocols/JabberG/src/jabber_secur.h +++ b/protocols/JabberG/src/jabber_secur.h @@ -86,9 +86,10 @@ class TScramAuth : public TJabberAuth char *bindFlag, *cnonce = 0, *msg1 = 0, *serverSignature = 0; MBinBuffer bindData; + const EVP_MD *hashMethod; public: - TScramAuth(ThreadData*, void *pData = nullptr, size_t cbLen = 0); + TScramAuth(ThreadData*, bool bSha1, 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 77ea881769..586cbce6f9 100755 --- a/protocols/JabberG/src/jabber_thread.cpp +++ b/protocols/JabberG/src/jabber_thread.cpp @@ -627,18 +627,32 @@ void CJabberProto::PerformAuthentication(ThreadData *info) } } - if (auth == nullptr && m_isScramPlusAvailable) { - m_isScramPlusAvailable = false; - + if (auth == nullptr && m_isScramSha256PlusAvailable) { + m_isScramSha256PlusAvailable = false; + + int len = 0; + void *pBuf = Netlib_GetTlsUnique(info->s, len); + if (pBuf) + auth = new TScramAuth(info, EVP_sha256(), pBuf, len); + } + + if (auth == nullptr && m_isScramSha256Available) { + m_isScramSha256Available = false; + auth = new TScramAuth(info, EVP_sha256()); + } + + if (auth == nullptr && m_isScramSha1PlusAvailable) { + m_isScramSha1PlusAvailable = false; + int len = 0; void *pBuf = Netlib_GetTlsUnique(info->s, len); if (pBuf) - auth = new TScramAuth(info, pBuf, len); + auth = new TScramAuth(info, EVP_sha1(), pBuf, len); } - if (auth == nullptr && m_isScramAvailable) { - m_isScramAvailable = false; - auth = new TScramAuth(info); + if (auth == nullptr && m_isScramSha1Available) { + m_isScramSha1Available = false; + auth = new TScramAuth(info, EVP_sha1()); } if (auth == nullptr && m_isMd5Available) { @@ -724,9 +738,13 @@ void CJabberProto::OnProcessFeatures(const TiXmlElement *node, ThreadData *info) else if (!mir_strcmp(szMechanism, "DIGEST-MD5")) m_isMd5Available = true; else if (!mir_strcmp(szMechanism, "SCRAM-SHA-1")) - m_isScramAvailable = true; + m_isScramSha1Available = true; else if (!mir_strcmp(szMechanism, "SCRAM-SHA-1-PLUS")) - m_isScramPlusAvailable = true; + m_isScramSha1PlusAvailable = true; + else if (!mir_strcmp(szMechanism, "SCRAM-SHA-256")) + m_isScramSha256Available = true; + else if (!mir_strcmp(szMechanism, "SCRAM-SHA-256-PLUS")) + m_isScramSha256PlusAvailable = true; else if (!mir_strcmp(szMechanism, "NTLM")) m_isNtlmAvailable = true; else if (!mir_strcmp(szMechanism, "GSS-SPNEGO")) -- cgit v1.2.3