title: Digital signature with CryptVerifySignature
body: <p>I want to implement digital signature app using CryptVerifySignature. I've written this code(with help of MSDN example):</p>
  
  <pre><code>#define Check(condition, message) if (!(condition)) { fprintf(stderr, "%s\n", message); goto Exit; };
  void DigSign(const char* inputFileName, const char* signFileName)
  {
  
      HCRYPTPROV hProv;
      BYTE *pbBuffer= NULL;
      DWORD dwBufferLen = 0;
      HCRYPTHASH hHash;
      HCRYPTKEY hKey;
      HCRYPTKEY hPubKey;
      BYTE *pbKeyBlob;        
      BYTE *pbSignature;
      DWORD dwSigLen;
      DWORD dwBlobLen;
  
      FILE* inputFile = NULL;
  
      Check((inputFile = fopen(inputFileName, "r")) != NULL, "File does not exists");
      dwBufferLen = GetFileSize(inputFile);
      Check(pbBuffer = (BYTE*)malloc(dwBufferLen + 1), "cannot allocate memory");
  
      fread(pbBuffer, 1, dwBufferLen, inputFile);
      pbBuffer[dwBufferLen] = '\0';
      fclose(inputFile);
  
  
      //-------------------------------------------------------------------
      // Acquire a cryptographic provider context handle.
  
      Check(CryptAcquireContext(&amp;hProv, NULL, NULL, PROV_RSA_FULL, 0), "Error during CryptAcquireContext.");
  
  
      if(!CryptGetUserKey(hProv, AT_SIGNATURE, &amp;hKey)) 
      {
          if(NTE_NO_KEY == GetLastError())
          {
              Check(CryptGenKey(hProv, AT_SIGNATURE, CRYPT_EXPORTABLE, &amp;hKey), "Could not create a user public key.\n");
          }
          else
          {
              goto Exit;
          }
      }
  
      Check(CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, NULL, &amp;dwBlobLen), "Error computing BLOB length.");
      Check(pbKeyBlob = (BYTE*)malloc(dwBlobLen), "Out of memory. \n");
      Check(CryptExportKey(hKey, NULL, PUBLICKEYBLOB, 0, pbKeyBlob, &amp;dwBlobLen), "Error during CryptExportKey.");
  
      //-------------------------------------------------------------------
      // Create the hash object.
      Check(CryptCreateHash(hProv, CALG_SHA, 0, 0, &amp;hHash), "Error during CryptCreateHash.");
  
      //-------------------------------------------------------------------
      // Compute the cryptographic hash of the buffer.
      Check(CryptHashData(hHash, pbBuffer, dwBufferLen, 0), "Error during CryptHashData.");
  
      //-------------------------------------------------------------------
      // Determine the size of the signature and allocate memory.
  
      dwSigLen= 0;
      Check(CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, NULL, &amp;dwSigLen), "Error during CryptSignHash.");
  
      //-------------------------------------------------------------------
      // Allocate memory for the signature buffer.
      Check(pbSignature = (BYTE *)malloc(dwSigLen), "Out of memory.");
  
      //-------------------------------------------------------------------
      // Sign the hash object.
      Check(CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, pbSignature, &amp;dwSigLen), "Error during CryptSignHash.");
  
      FILE* f = fopen(signFileName, "w");
      fwrite(pbSignature, dwSigLen, 1, f);
      printf("W: %.128s\n", pbSignature);
      fwrite(pbKeyBlob, dwBlobLen, 1, f);
      printf("W: %.148s\n", pbKeyBlob);
      fclose(f);
      //-------------------------------------------------------------------
      // Destroy the hash object.
  
      if(hHash) 
          CryptDestroyHash(hHash);
  
      free(pbSignature);
      free(pbKeyBlob);
  
      if(hProv) 
          CryptReleaseContext(hProv, 0);
  
  Exit:;
  }
  
  
  bool CheckDigSign(const char* inputFileName, const char* signFileName, const char* userName)
  {
      bool result = false;
      HCRYPTPROV hProv;
      BYTE *pbBuffer= (BYTE *)"The data that is to be hashed and signed.";
      DWORD dwBufferLen = strlen((char *)pbBuffer)+1;
      HCRYPTHASH hHash;
      HCRYPTKEY hKey;
      HCRYPTKEY hPubKey;
      BYTE *pbKeyBlob;        
      BYTE *pbSignature;
      DWORD dwSigLen;
      DWORD dwBlobLen;
  
      FILE* inputFile = NULL;
  
      Check((inputFile = fopen(inputFileName, "r")) != NULL, "File does not exists");
      dwBufferLen = GetFileSize(inputFile);
      Check(pbBuffer = (BYTE*)malloc(dwBufferLen + 1), "cannot allocate memory");
  
      fread(pbBuffer, 1, dwBufferLen, inputFile);
      pbBuffer[dwBufferLen] = '\0';
      fclose(inputFile);
  
  
      FILE* signFile = NULL;
      Check((signFile = fopen(signFileName, "r")) != NULL, "File does not exists");
      DWORD dwSignFileLen = GetFileSize(signFile);
      dwSigLen = 128;
      pbSignature = (BYTE*)malloc(dwSigLen);
      dwBlobLen = dwSignFileLen - dwSigLen;
      pbKeyBlob = (BYTE*)malloc(dwBlobLen);
      fread(pbSignature, 1, dwSigLen, signFile);
      fread(pbKeyBlob, 1, dwBlobLen, signFile);
      fclose(signFile);
  
  
  
      printf("R: %.128s\n", pbSignature);
      printf("R: %.148s\n", pbKeyBlob);
  
      Check(CryptAcquireContext(&amp;hProv, NULL, NULL, PROV_RSA_FULL, 0), "Error during CryptAcquireContext.");
  
      Check(CryptImportKey(hProv, pbKeyBlob, dwBlobLen, 0, 0, &amp;hPubKey), "Public key import failed.");
  
      //-------------------------------------------------------------------
      // Create a new hash object.
      Check(CryptCreateHash(hProv, CALG_SHA, 0, 0, &amp;hHash), "Error during CryptCreateHash.");
  
      //-------------------------------------------------------------------
      // Compute the cryptographic hash of the buffer.
      Check(CryptHashData(hHash, pbBuffer, dwBufferLen, 0), "Error during CryptHashData.");
  
      //-------------------------------------------------------------------
      // Validate the digital signature.
  
      result = CryptVerifySignature(hHash, pbSignature, dwSigLen, hPubKey, NULL, 0); 
      printf("%u %x", GetLastError(), GetLastError());
      //-------------------------------------------------------------------
      // Free memory to be used to store signature.
  
      if(pbSignature)
          free(pbSignature);
  
      //-------------------------------------------------------------------
      // Destroy the hash object.
  
      if(hHash) 
          CryptDestroyHash(hHash);
  
      //-------------------------------------------------------------------
      // Release the provider handle.
  
      if(hProv) 
          CryptReleaseContext(hProv, 0);
  
  Exit:
      return result;
  }
  
  
  int _tmain(int argc, _TCHAR* argv[])
  {
  
  
      DigSign("test3.txt", "test.sig");
      printf("TEST: %u\n", CheckDigSign("test3.txt", "test.sig", ""));
  }
  </code></pre>
  
  <p>DigSign function must sign content of file and write signature and public key to another file. CheckSign must return true if sign is right. But I don't understand why my code doesn't work. CheckDigSign in _tmain must return true, but it returns false. Can anybody help me pls?</p>