none
Why does the return value of ICLRRuntime::StrongNameSignatureVerificationEx() not equal StrongNameSignatureVerificationEx() in StrongName.h? RRS feed

  • Question

  • I do assembly strong name signing in my application. I've moved my mixed mode assembly to .NET 4 so this mean moving from StrongName.h to using the new metahost.h ICLRMetaHost and all it's associated interfaces to get to ICLRRuntime.

    For some reason the new ICLRRuntime::StrongNameSignatureVerificationEx() returns false whereas the old .NET 2.0 StrongNameSignatureVerificationEx() returns true on my signed assembly.

    Here is the MSDN article for the old StrongName.h function http://msdn.microsoft.com/en-us/library/ms232579.aspx

    Here is the new MSDN article for the MetaHost.h function http://msdn.microsoft.com/en-us/library/ff844043.aspx

    They take the same inputs and return the same output but in practice the new one fails. Is there a bug here?

    Here's my long winded NET 4.0 implementation

    BYTE tokenstore[128];
    BYTE* token = tokenstore;
    ULONG len = 0;
    
    
    StrongNameTokenFromAssembly(MyFileHelper::getApplicationExecutablePath().c_str(), &token, &len);
     BOOLEAN verified = false;
     BOOLEAN sigVerified = StrongNameSignatureVerificationEx(MyFileHelper::getApplicationExecutablePath().c_str(), true, &verified);
     if (!sigVerified || MyDataStruct(token, len).<pre lang="x-cpp"> BYTE tokenstore[128];
     BYTE* token = tokenstore;
     ULONG len = 0;
     
     ICLRMetaHost *pMetaHost = NULL;
     HRESULT hr = CLRCreateInstance(CLSID_CLRMetaHost,
         IID_ICLRMetaHost, (LPVOID*)&pMetaHost); 
     if(hr== S_OK)
     {
      WCHAR version[100];
      DWORD size;
    
      hr == pMetaHost->GetVersionFromFile(MyFileHelper::getApplicationExecutablePath().c_str(), (LPWSTR) &version, &size);
      if(hr ==S_OK)
      {
       LPWSTR assemblyVer = version;
       ICLRRuntimeInfo *pRuntimInfo = NULL;
    
       hr = pMetaHost->GetRuntime(assemblyVer, IID_ICLRRuntimeInfo, (LPVOID*)&pRuntimInfo);
       if (hr == S_OK)
       {
       ICLRStrongName *pStrongName = NULL;
       hr = pRuntimInfo->GetInterface(CLSID_CLRStrongName, IID_ICLRStrongName, (LPVOID*)&pStrongName);
    
       if(hr == S_OK)
       {
        pStrongName->StrongNameTokenFromAssembly(MyFileHelper::getApplicationExecutablePath().c_str(), &token, &len);
        BOOLEAN verified = false;
        BOOLEAN sigVerified = pStrongName->StrongNameSignatureVerificationEx(MyFileHelper::getApplicationExecutablePath().c_str(), true, &verified);
        //sigVerified always returns false here!
        if (!sigVerified || MyDataStruct(token, len).HexConvert() != "<MY KEY>")
        {
         //Nasty exit or something
        }
        pStrongName->StrongNameFreeBuffer(token);
       }
       }
      }
     }
    

    Here's my old .NET 2.0 based one.

    StrongNameTokenFromAssembly(MyHelper::getApplicationExecutablePath().c_str(), &token, &len);
      BOOLEAN verified = false;
      BOOLEAN sigVerified = StrongNameSignatureVerificationEx(MyHelper::getApplicationExecutablePath().c_str(), true, &verified);
      if (!sigVerified || MyDataStruct(token, len).HexConvert() != "<MY KEY>")
      {
       // handle failed sign
      }

     

     

    Thursday, October 21, 2010 5:36 PM

Answers

  • it appears the documentation for the ICLRRuntime implementation needs clarification.

    The return value is a HRESULT, not a BOOL to indicate whether the verification worked. So a succesful verfication is "0" or S_OK, but the old one returned 1 for TRUE.

    • Marked as answer by jippers Thursday, October 21, 2010 7:53 PM
    Thursday, October 21, 2010 7:51 PM