From b869163609473f05c4f5d1d72a579b9f6af66ccd Mon Sep 17 00:00:00 2001 From: Don HO Date: Wed, 8 Mar 2017 02:52:58 +0100 Subject: [PATCH] Check SciLexer.dll certificate This fix is about the issue "Vault 7: CIA Hacking Tools Revealed" published on Wikileak: https://wikileaks.org/ciav7p1/cms/page_26968090.html --- PowerEditor/src/MISC/Common/Common.cpp | 122 ++++++++++++++++++ PowerEditor/src/MISC/Common/Common.h | 2 + PowerEditor/src/NppNotification.cpp | 2 +- .../ScitillaComponent/ScintillaEditView.cpp | 19 ++- .../src/ScitillaComponent/ScintillaEditView.h | 1 + .../WinControls/DocumentMap/documentMap.cpp | 31 ++++- .../visual.net/notepadPlus.vs2015.vcxproj | 8 +- 7 files changed, 174 insertions(+), 11 deletions(-) diff --git a/PowerEditor/src/MISC/Common/Common.cpp b/PowerEditor/src/MISC/Common/Common.cpp index a66a2b6d..f2b39b8d 100644 --- a/PowerEditor/src/MISC/Common/Common.cpp +++ b/PowerEditor/src/MISC/Common/Common.cpp @@ -975,3 +975,125 @@ HWND CreateToolTip(int toolID, HWND hDlg, HINSTANCE hInst, const PTSTR pszText) return hwndTip; } + +bool isCertificateValidated(const generic_string & fullFilePath, const generic_string & subjectName2check) +{ + HCERTSTORE hStore = NULL; + HCRYPTMSG hMsg = NULL; + PCCERT_CONTEXT pCertContext = NULL; + BOOL result; + DWORD dwEncoding, dwContentType, dwFormatType; + PCMSG_SIGNER_INFO pSignerInfo = NULL; + DWORD dwSignerInfo; + CERT_INFO CertInfo; + LPTSTR szName = NULL; + + generic_string subjectName; + + try { + // Get message handle and store handle from the signed file. + result = CryptQueryObject(CERT_QUERY_OBJECT_FILE, + fullFilePath.c_str(), + CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, + CERT_QUERY_FORMAT_FLAG_BINARY, + 0, + &dwEncoding, + &dwContentType, + &dwFormatType, + &hStore, + &hMsg, + NULL); + + if (!result) + { + generic_string errorMessage = TEXT("Check certificate of ") + fullFilePath + TEXT(" : "); + errorMessage += GetLastErrorAsString(GetLastError()); + throw errorMessage; + } + + // Get signer information size. + result = CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &dwSignerInfo); + if (!result) + { + generic_string errorMessage = TEXT("CryptMsgGetParam first call: "); + errorMessage += GetLastErrorAsString(GetLastError()); + throw errorMessage; + } + + // Allocate memory for signer information. + pSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSignerInfo); + if (!pSignerInfo) + { + generic_string errorMessage = TEXT("CryptMsgGetParam memory allocation problem: "); + errorMessage += GetLastErrorAsString(GetLastError()); + throw errorMessage; + } + + // Get Signer Information. + result = CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, (PVOID)pSignerInfo, &dwSignerInfo); + if (!result) + { + generic_string errorMessage = TEXT("CryptMsgGetParam: "); + errorMessage += GetLastErrorAsString(GetLastError()); + throw errorMessage; + } + + // Search for the signer certificate in the temporary + // certificate store. + CertInfo.Issuer = pSignerInfo->Issuer; + CertInfo.SerialNumber = pSignerInfo->SerialNumber; + + pCertContext = CertFindCertificateInStore(hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_CERT, (PVOID)&CertInfo, NULL); + if (not pCertContext) + { + generic_string errorMessage = TEXT("Certificate context: "); + errorMessage += GetLastErrorAsString(GetLastError()); + throw errorMessage; + } + + DWORD dwData; + + // Get Subject name size. + dwData = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0); + if (dwData <= 1) + { + throw generic_string(TEXT("Certificate checking error: getting data size problem.")); + } + + // Allocate memory for subject name. + szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR)); + if (!szName) + { + throw generic_string(TEXT("Certificate checking error: memory allocation problem.")); + } + + // Get subject name. + if (CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, szName, dwData) <= 1) + { + throw generic_string(TEXT("Cannot get certificate info.")); + } + + // check Subject name. + subjectName = szName; + if (subjectName != subjectName2check) + { + throw generic_string(TEXT("Certificate checking error: the certificate is not matched.")); + } + } + catch (generic_string s) + { + // display error message + MessageBox(NULL, s.c_str(), TEXT("Certificate checking"), MB_OK); + + // Clean up. + if (pSignerInfo != NULL) LocalFree(pSignerInfo); + if (pCertContext != NULL) CertFreeCertificateContext(pCertContext); + if (hStore != NULL) CertCloseStore(hStore, 0); + if (hMsg != NULL) CryptMsgClose(hMsg); + if (szName != NULL) LocalFree(szName); + + return false; + } + + return true; +} diff --git a/PowerEditor/src/MISC/Common/Common.h b/PowerEditor/src/MISC/Common/Common.h index 16a8d22f..aa74dc4e 100644 --- a/PowerEditor/src/MISC/Common/Common.h +++ b/PowerEditor/src/MISC/Common/Common.h @@ -189,3 +189,5 @@ generic_string intToString(int val); generic_string uintToString(unsigned int val); HWND CreateToolTip(int toolID, HWND hDlg, HINSTANCE hInst, const PTSTR pszText); + +bool isCertificateValidated(const generic_string & fullFilePath, const generic_string & subjectName2check); diff --git a/PowerEditor/src/NppNotification.cpp b/PowerEditor/src/NppNotification.cpp index c1e5e1c7..928fad4a 100644 --- a/PowerEditor/src/NppNotification.cpp +++ b/PowerEditor/src/NppNotification.cpp @@ -160,7 +160,7 @@ BOOL Notepad_plus::notify(SCNotification *notification) { BufferID id = pTabDocView->getBufferByIndex(tbHdr->tabOrigin); Buffer * pBuf = MainFileManager->getBufferByID(id); - _pDocMap->showInMapTemporily(pBuf, notifyView); + _pDocMap->showInMapTemporarily(pBuf, notifyView); _pDocMap->setSyntaxHiliting(); } } diff --git a/PowerEditor/src/ScitillaComponent/ScintillaEditView.cpp b/PowerEditor/src/ScitillaComponent/ScintillaEditView.cpp index 2be4de2c..966f881b 100644 --- a/PowerEditor/src/ScitillaComponent/ScintillaEditView.cpp +++ b/PowerEditor/src/ScitillaComponent/ScintillaEditView.cpp @@ -38,15 +38,15 @@ using namespace std; // initialize the static variable // get full ScinLexer.dll path to avoid hijack -TCHAR * getSciLexerFullPathName(TCHAR * moduleFileName, size_t len){ +TCHAR * getSciLexerFullPathName(TCHAR * moduleFileName, size_t len) +{ ::GetModuleFileName(NULL, moduleFileName, static_cast(len)); ::PathRemoveFileSpec(moduleFileName); ::PathAppend(moduleFileName, TEXT("SciLexer.dll")); return moduleFileName; }; -TCHAR moduleFileName[1024]; -HINSTANCE ScintillaEditView::_hLib = ::LoadLibrary(getSciLexerFullPathName(moduleFileName, 1024)); +HINSTANCE ScintillaEditView::_hLib = loadSciLexerDll(); int ScintillaEditView::_refCount = 0; UserDefineDialog ScintillaEditView::_userDefineDlg; @@ -174,6 +174,16 @@ int getNbDigits(int aNum, int base) return nbChiffre; } +TCHAR moduleFileName[1024]; +HMODULE loadSciLexerDll() +{ + generic_string sciLexerPath = getSciLexerFullPathName(moduleFileName, 1024); + + if (not isCertificateValidated(sciLexerPath, TEXT("Notepad++"))) + return nullptr; + return ::LoadLibrary(sciLexerPath.c_str()); +} + void ScintillaEditView::init(HINSTANCE hInst, HWND hPere) { if (!_hLib) @@ -1675,7 +1685,8 @@ void ScintillaEditView::restoreCurrentPos() execute(SCI_SETANCHOR, pos._startPos); execute(SCI_SETCURRENTPOS, pos._endPos); execute(SCI_CANCEL); //disable - if (!isWrap()) { //only offset if not wrapping, otherwise the offset isnt needed at all + if (not isWrap()) //only offset if not wrapping, otherwise the offset isnt needed at all + { execute(SCI_SETSCROLLWIDTH, pos._scrollWidth); execute(SCI_SETXOFFSET, pos._xOffset); } diff --git a/PowerEditor/src/ScitillaComponent/ScintillaEditView.h b/PowerEditor/src/ScitillaComponent/ScintillaEditView.h index 7bcdae13..291eee52 100644 --- a/PowerEditor/src/ScitillaComponent/ScintillaEditView.h +++ b/PowerEditor/src/ScitillaComponent/ScintillaEditView.h @@ -130,6 +130,7 @@ const int MARK_HIDELINESUNDERLINE = 21; int getNbDigits(int aNum, int base); +HMODULE loadSciLexerDll(); TCHAR * int2str(TCHAR *str, int strLen, int number, int base, int nbChiffre, bool isZeroLeading); diff --git a/PowerEditor/src/WinControls/DocumentMap/documentMap.cpp b/PowerEditor/src/WinControls/DocumentMap/documentMap.cpp index 677d9dc8..e430a5a2 100644 --- a/PowerEditor/src/WinControls/DocumentMap/documentMap.cpp +++ b/PowerEditor/src/WinControls/DocumentMap/documentMap.cpp @@ -75,8 +75,29 @@ void DocumentMap::showInMapTemporarily(Buffer *buf2show, const ScintillaEditView { wrapMap(fromEditView); } + //_pScintillaEditView->restoreCurrentPos(); + scrollMap(fromEditView); - //scrollMap(fromEditView); + /* + Buffer * buf = buf2show; + Position & pos = buf->getPosition(const_cast(fromEditView)); + + _pScintillaEditView->execute(SCI_GOTOPOS, 0); //make sure first line visible by setting caret there, will scroll to top of document + + _pScintillaEditView->execute(SCI_SETSELECTIONMODE, pos._selMode); //enable + _pScintillaEditView->execute(SCI_SETANCHOR, pos._startPos); + _pScintillaEditView->execute(SCI_SETCURRENTPOS, pos._endPos); + _pScintillaEditView->execute(SCI_CANCEL); //disable + if (not _pScintillaEditView->isWrap()) //only offset if not wrapping, otherwise the offset isnt needed at all + { + _pScintillaEditView->execute(SCI_SETSCROLLWIDTH, pos._scrollWidth); + _pScintillaEditView->execute(SCI_SETXOFFSET, pos._xOffset); + } + _pScintillaEditView->execute(SCI_CHOOSECARETX); // choose current x position + + int lineToShow = static_cast(_pScintillaEditView->execute(SCI_VISIBLEFROMDOCLINE, pos._firstVisibleLine)); + _pScintillaEditView->scroll(0, lineToShow); + */ } } @@ -205,7 +226,13 @@ int DocumentMap::getEditorTextZoneWidth(const ScintillaEditView *editView) } return editorRect.right - editorRect.left - marginWidths; } - +/* +struct mapPosition { + int32_t _firstVisibleDocLine; + int32_t _nbLine; + int32_t _lastVisibleDocLine; +}; +*/ void DocumentMap::scrollMap(const ScintillaEditView *editView) { const ScintillaEditView *pEditView = editView ? editView : *_ppEditView; diff --git a/PowerEditor/visual.net/notepadPlus.vs2015.vcxproj b/PowerEditor/visual.net/notepadPlus.vs2015.vcxproj index 438d7466..b597a81f 100644 --- a/PowerEditor/visual.net/notepadPlus.vs2015.vcxproj +++ b/PowerEditor/visual.net/notepadPlus.vs2015.vcxproj @@ -109,7 +109,7 @@ /fixed:no %(AdditionalOptions) - comctl32.lib;shlwapi.lib;shell32.lib;Oleacc.lib;Dbghelp.lib;Version.lib;%(AdditionalDependencies) + comctl32.lib;shlwapi.lib;shell32.lib;Oleacc.lib;Dbghelp.lib;Version.lib;Crypt32.lib;%(AdditionalDependencies) LinkVerboseLib $(OutDir)notepad++.exe 1.0 @@ -146,7 +146,7 @@ /fixed:no %(AdditionalOptions) - comctl32.lib;shlwapi.lib;shell32.lib;Oleacc.lib;Dbghelp.lib;Version.lib;%(AdditionalDependencies) + comctl32.lib;shlwapi.lib;shell32.lib;Oleacc.lib;Dbghelp.lib;Version.lib;Crypt32.lib;%(AdditionalDependencies) LinkVerboseLib $(OutDir)notepad++.exe 1.0 @@ -188,7 +188,7 @@ 18 - comctl32.lib;shlwapi.lib;shell32.lib;Oleacc.lib;Dbghelp.lib;Version.lib;%(AdditionalDependencies) + comctl32.lib;shlwapi.lib;shell32.lib;Oleacc.lib;Dbghelp.lib;Version.lib;Crypt32.lib;%(AdditionalDependencies) LinkVerboseLib $(OutDir)notepad++.exe 1.0 @@ -239,7 +239,7 @@ copy ..\src\contextMenu.xml ..\bin\contextMenu.xml 18 - comctl32.lib;shlwapi.lib;shell32.lib;Oleacc.lib;Dbghelp.lib;Version.lib;%(AdditionalDependencies) + comctl32.lib;shlwapi.lib;shell32.lib;Oleacc.lib;Dbghelp.lib;Version.lib;Crypt32.lib;%(AdditionalDependencies) LinkVerboseLib $(OutDir)notepad++.exe 1.0