bool CryptManager::Verify( RageFileBasic &file, RString sSignature, RString sPublicKey ) { RSAKeyWrapper key; RString sError; if( !key.Load(sPublicKey, sError) ) { LOG->Warn( "Error loading RSA key: %s", sError.c_str() ); return false; } int iHash = register_hash( &sha1_desc ); ASSERT( iHash >= 0 ); unsigned char buf_hash[20]; HashFile( file, buf_hash, iHash ); int iMatch; int iRet = rsa_verify_hash_ex( (const unsigned char *) sSignature.data(), sSignature.size(), buf_hash, sizeof(buf_hash), LTC_PKCS_1_EMSA, iHash, 0, &iMatch, &key.m_Key ); if( iRet != CRYPT_OK ) { LOG->Warn( "Verify(%s) failed: %s", file.GetDisplayPath().c_str(), error_to_string(iRet) ); return false; } if( !iMatch ) { LOG->Warn( "Verify(%s) failed: signature mismatch", file.GetDisplayPath().c_str() ); return false; } return true; }
static bool HashFile( RageFileBasic &f, unsigned char buf_hash[20], int iHash ) { hash_state hash; int iRet = hash_descriptor[iHash].init( &hash ); ASSERT_M( iRet == CRYPT_OK, error_to_string(iRet) ); RString s; while( !f.AtEOF() ) { s.erase(); if( f.Read(s, 1024*4) == -1 ) { LOG->Warn( "Error reading %s: %s", f.GetDisplayPath().c_str(), f.GetError().c_str() ); hash_descriptor[iHash].done( &hash, buf_hash ); return false; } iRet = hash_descriptor[iHash].process( &hash, (const unsigned char *) s.data(), s.size() ); ASSERT_M( iRet == CRYPT_OK, error_to_string(iRet) ); } iRet = hash_descriptor[iHash].done( &hash, buf_hash ); ASSERT_M( iRet == CRYPT_OK, error_to_string(iRet) ); return true; }