home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winbase / security / crypto / sign / verifile.c < prev    next >
C/C++ Source or Header  |  1997-10-08  |  6KB  |  215 lines

  1. /******************************************************************************\
  2. *       This is a part of the Microsoft Source Code Samples. 
  3. *       Copyright 1996-1997 Microsoft Corporation.
  4. *       All rights reserved. 
  5. *       This source code is only intended as a supplement to 
  6. *       Microsoft Development Tools and/or WinHelp documentation.
  7. *       See these sources for detailed information regarding the 
  8. *       Microsoft samples programs.
  9. \******************************************************************************/
  10.  
  11. #include <windows.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <wincrypt.h>
  15.  
  16. static BOOL VerifyFile(PCHAR szSourceFile, PCHAR szSignatureFile, PCHAR szDescription);
  17.  
  18. /*****************************************************************************/
  19. void _cdecl main(int argc, char *argv[])
  20. {
  21.     PCHAR szSourceFile      = NULL;
  22.     PCHAR szSignatureFile = NULL;
  23.     PCHAR szDescription  = NULL;
  24.  
  25.     // Validate argument count.
  26.     if(argc != 4) {
  27.     printf("USAGE: signfile <source file> <signature file> <description>\n");
  28.     exit(1);
  29.     }
  30.  
  31.     // Parse arguments.
  32.     szSourceFile    = argv[1];
  33.     szSignatureFile = argv[2];
  34.     szDescription   = argv[3];
  35.  
  36.     if(!VerifyFile(szSourceFile, szSignatureFile, szDescription)) {
  37.     printf("Error verifying file!\n");
  38.     exit(1);
  39.     }
  40.  
  41.     exit(0);
  42. }
  43.  
  44. /*****************************************************************************/
  45. static BOOL VerifyFile(PCHAR szSourceFile, PCHAR szSignatureFile, PCHAR szDescription)
  46. {
  47.     FILE *hSourceFile     = NULL;
  48.     FILE *hSignatureFile = NULL;
  49.     INT eof = 0;
  50.  
  51.     HCRYPTPROV hProv = 0;
  52.     HCRYPTHASH hHash = 0;
  53.     HCRYPTKEY hSigPublicKey = 0;
  54.  
  55.     PBYTE pbSignature = NULL;
  56.     DWORD dwSignatureLen;
  57.  
  58.     PBYTE pbBuffer = NULL;
  59.     DWORD dwBufferLen;
  60.     DWORD dwCount;
  61.  
  62.     // Get handle to the default provider.
  63.     if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) {
  64.         printf("Error %x during CryptAcquireContext!\n", GetLastError());
  65.     goto error;
  66.     }
  67.  
  68.     //
  69.     // Hash source file.
  70.     //
  71.  
  72.     // Determine number of bytes to hash at once.
  73.     dwBufferLen = 1000;
  74.  
  75.     // Allocate memory for 'pbBuffer'.
  76.     if((pbBuffer = malloc(dwBufferLen)) == NULL) {
  77.     printf("Out of memory 1!\n");
  78.     goto error;
  79.     }
  80.  
  81.     // Open source file.
  82.     if((hSourceFile = fopen(szSourceFile,"rb")) == NULL) {
  83.     printf("Error opening source file!\n");
  84.     goto error;
  85.     }
  86.  
  87.     // Create a hash object.
  88.     if(!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
  89.     printf("Error %x during CryptCreateHash!\n", GetLastError());
  90.     goto error;
  91.     }
  92.  
  93.     // Hash source file.
  94.     do {
  95.     // Read up to 'dwBufferLen' bytes from source file.
  96.     dwCount = fread(pbBuffer, 1, dwBufferLen, hSourceFile);
  97.     if(ferror(hSourceFile)) {
  98.         printf("Error reading Plaintext!\n");
  99.         goto error;
  100.         }
  101.     eof = feof(hSourceFile);
  102.  
  103.     // Add data to hash object.
  104.     if(!CryptHashData(hHash, pbBuffer, dwCount, 0)) {
  105.         printf("Error %x during CryptHashData!\n", GetLastError());
  106.         goto error;
  107.     }
  108.     } while(!feof(hSourceFile));
  109.  
  110.     // Close source file.
  111.     fclose(hSourceFile);
  112.     hSourceFile = 0;
  113.  
  114.     // Free 'pbBuffer' memory.
  115.     free(pbBuffer);
  116.     pbBuffer = NULL;
  117.  
  118.  
  119.     //
  120.     // Read in signature file.
  121.     //
  122.  
  123.     // Determine size of signature.
  124.     dwSignatureLen = 0;
  125.     if(!CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, NULL, &dwSignatureLen)) {
  126.     printf("Error %x during CryptSignHash!\n", GetLastError());
  127.     goto error;
  128.     }
  129.  
  130.     // Allocate memory for 'pbSignature'.
  131.     if((pbSignature = malloc(dwSignatureLen)) == NULL) {
  132.     printf("Out of memory 2!\n");
  133.     goto error;
  134.     }
  135.  
  136.     // Open signature file.
  137.     if((hSignatureFile = fopen(szSignatureFile,"rb")) == NULL) {
  138.     printf("Error opening signature file!\n");
  139.     goto error;
  140.     }
  141.  
  142.     // Read signature data.
  143.     dwCount = fread(pbSignature, 1, dwSignatureLen, hSignatureFile);
  144.     if(ferror(hSignatureFile)) {
  145.     printf("Error reading signature!\n");
  146.     goto error;
  147.     }
  148.  
  149.     // Close signature file.
  150.     fclose(hSignatureFile);
  151.     hSignatureFile = 0;
  152.  
  153.  
  154.     //
  155.     // Verify signature.
  156.     //
  157.  
  158.     // Get handle to signature key.
  159.     if(!CryptGetUserKey(hProv, AT_SIGNATURE, &hSigPublicKey)) {
  160.     printf("Error %x during CryptGetUserKey!\n", GetLastError());
  161.     goto error;
  162.     }
  163.  
  164.     // Verify signature.
  165.     if(!CryptVerifySignature(hHash, pbSignature, dwSignatureLen, hSigPublicKey, szDescription, 0)) {
  166.     if(GetLastError() == NTE_BAD_SIGNATURE) {
  167.         printf("Signature did not match!\n");
  168.     } else {
  169.         printf("Error %x during CryptVerifySignature!\n", GetLastError());
  170.     }
  171.     goto error;
  172.     }
  173.  
  174.     // Release signature key.
  175.     CryptDestroyKey(hSigPublicKey);
  176.     hSigPublicKey = 0;
  177.  
  178.     // Free 'pbSignature' memory.
  179.     free(pbSignature);
  180.     pbSignature = NULL;
  181.  
  182.     // Destroy hash object.
  183.     CryptDestroyHash(hHash);
  184.     hHash = 0;
  185.  
  186.     // Release provider handle.
  187.     CryptReleaseContext(hProv, 0);
  188.     hProv = 0;
  189.  
  190.     printf("OK\n");
  191.  
  192.     return TRUE;
  193.  
  194.     error:
  195.  
  196.     //
  197.     // Do cleanup
  198.     //
  199.  
  200.     // Close files.
  201.     if(hSourceFile) fclose(hSourceFile);
  202.     if(hSignatureFile) fclose(hSignatureFile);
  203.  
  204.     // Free memory.
  205.     if(pbSignature) free(pbSignature);
  206.     if(pbBuffer) free(pbBuffer);
  207.  
  208.     // Release crypto handles.
  209.     if(hHash) CryptDestroyHash(hHash);
  210.     if(hSigPublicKey) CryptDestroyKey(hSigPublicKey);
  211.     if(hProv) CryptReleaseContext(hProv, 0);
  212.  
  213.     return FALSE;
  214. }
  215.