Plant the ability to verify code signing signatures when trying to load kifaces

Off by default and intended for use in released builds only
This commit is contained in:
Marek Roszko 2022-03-12 19:12:34 -05:00
parent 17539a564e
commit 5e9b982ddf
7 changed files with 80 additions and 0 deletions

View File

@ -156,6 +156,12 @@ option( KICAD_STEP_EXPORT_LIB
"Build and use kicad2step as a library, meant for debugging"
OFF )
cmake_dependent_option( KICAD_WIN32_VERIFY_CODESIGN
"When enabled, verifies the code signing signature of certain DLLs loaded during runtime."
OFF "WIN32"
OFF )
endif()
# Global setting: exports are explicit
set( CMAKE_CXX_VISIBILITY_PRESET "hidden" )
set( CMAKE_VISIBILITY_INLINES_HIDDEN ON )
@ -177,6 +183,10 @@ if( KICAD_GAL_PROFILE )
add_definitions( -DKICAD_GAL_PROFILE )
endif()
if( KICAD_WIN32_VERIFY_CODESIGN )
add_definitions( -DKICAD_WIN32_VERIFY_CODESIGN )
endif()
# Ensure DEBUG is defined for all platforms in Debug builds
# change to add_compile_definitions() after minimum required CMake version is 3.12
set_property( DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS $<$<CONFIG:Debug>:DEBUG> )

View File

@ -34,6 +34,7 @@
#include <core/arraydim.h>
#include <id.h>
#include <kiplatform/app.h>
#include <kiplatform/environment.h>
#include <settings/settings_manager.h>
#include <logging.h>
@ -230,6 +231,15 @@ KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
}
}
#ifdef KICAD_WIN32_VERIFY_CODESIGN
bool codeSignOk = KIPLATFORM::ENV::VerifyFileSignature( dname );
if( !codeSignOk )
{
msg.Printf( _( "Failed to verify kiface library '%s' signature." ), dname );
THROW_IO_ERROR( msg );
}
#endif
wxDynamicLibrary dso;
void* addr = nullptr;

View File

@ -30,6 +30,7 @@ elseif( WIN32 )
set( PLATFORM_LIBS
"Shlwapi"
"winhttp"
"wintrust"
)
elseif( UNIX )
set( PLATFORM_SRCS

View File

@ -107,3 +107,9 @@ bool KIPLATFORM::ENV::GetSystemProxyConfig( const wxString& aURL, PROXY_CONFIG&
{
return false;
}
bool KIPLATFORM::ENV::VerifyFileSignature( const wxString& aPath )
{
return true;
}

View File

@ -88,5 +88,13 @@ namespace KIPLATFORM
* @return True if successful fetched proxy info
*/
bool GetSystemProxyConfig( const wxString& aURL, PROXY_CONFIG& aCfg );
/**
* Validates the code signing signature of a given file
* This is most likely only ever going to be applicable to Windows
*
* @return True if file signature passes
*/
bool VerifyFileSignature( const wxString& aPath );
}
}

View File

@ -31,6 +31,10 @@
#include <shlwapi.h>
#include <winhttp.h>
#include <Softpub.h>
#include <wincrypt.h>
#include <wintrust.h>
void KIPLATFORM::ENV::Init()
{
@ -258,3 +262,38 @@ bool KIPLATFORM::ENV::GetSystemProxyConfig( const wxString& aURL, PROXY_CONFIG&
return success;
}
bool KIPLATFORM::ENV::VerifyFileSignature( const wxString& aPath )
{
WINTRUST_FILE_INFO fileData;
memset( &fileData, 0, sizeof( fileData ) );
fileData.cbStruct = sizeof( WINTRUST_FILE_INFO );
fileData.pcwszFilePath = aPath.wc_str();
// verifies entire certificate chain
GUID policy = WINTRUST_ACTION_GENERIC_VERIFY_V2;
WINTRUST_DATA trustData;
memset( &trustData, 0, sizeof( trustData ) );
trustData.cbStruct = sizeof( trustData );
trustData.dwUIChoice = WTD_UI_NONE;
// revocation checking incurs latency penalities due to need for online queries
trustData.fdwRevocationChecks = WTD_REVOKE_NONE;
trustData.dwUnionChoice = WTD_CHOICE_FILE;
trustData.dwStateAction = WTD_STATEACTION_VERIFY;
trustData.pFile = &fileData;
bool verified = false;
LONG status = WinVerifyTrust( NULL, &policy, &trustData );
verified = ( status == ERROR_SUCCESS );
// Cleanup/release (yes its weird looking)
trustData.dwStateAction = WTD_STATEACTION_CLOSE;
WinVerifyTrust( NULL, &policy, &trustData );
return verified;
}

View File

@ -99,4 +99,10 @@ wxString KIPLATFORM::ENV::GetUserCachePath()
bool KIPLATFORM::ENV::GetSystemProxyConfig( const wxString& aURL, PROXY_CONFIG& aCfg )
{
return false;
}
bool KIPLATFORM::ENV::VerifyFileSignature( const wxString& aPath )
{
return true;
}