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 / encrypt / decrypt.ccrypt.c < prev    next >
C/C++ Source or Header  |  1997-10-08  |  6KB  |  207 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. #ifdef USE_BLOCK_CIPHER
  17.     // defines for RC2 block cipher
  18.     #define ENCRYPT_ALGORITHM    CALG_RC2
  19.     #define ENCRYPT_BLOCK_SIZE    8
  20. #else
  21.     // defines for RC4 stream cipher
  22.     #define ENCRYPT_ALGORITHM    CALG_RC4
  23.     #define ENCRYPT_BLOCK_SIZE    1
  24. #endif
  25.  
  26. static BOOL DecryptFile(PCHAR szSource, PCHAR szDestination, PCHAR szPassword);
  27.  
  28. /*****************************************************************************/
  29. void _cdecl main(int argc, char *argv[])
  30. {
  31.     PCHAR szSource    = NULL;
  32.     PCHAR szDestination = NULL;
  33.     PCHAR szPassword    = NULL;
  34.  
  35.     // Validate argument count.
  36.     if(argc != 3 && argc != 4) {
  37.     printf("USAGE: decrypt <source file> <dest file> [ <password> ]\n");
  38.     exit(1);
  39.     }
  40.  
  41.     // Parse arguments.
  42.     szSource       = argv[1];
  43.     szDestination  = argv[2];
  44.     if(argc == 4) {
  45.     szPassword = argv[3];
  46.     }
  47.  
  48.     if(!DecryptFile(szSource, szDestination, szPassword)) {
  49.     printf("Error encrypting file!\n");
  50.     exit(1);
  51.     }
  52.  
  53.     exit(0);
  54. }
  55.  
  56. /*****************************************************************************/
  57. static BOOL DecryptFile(PCHAR szSource, PCHAR szDestination, PCHAR szPassword)
  58. {
  59.     FILE *hSource      = NULL;
  60.     FILE *hDestination = NULL;
  61.     INT eof = 0;
  62.  
  63.     HCRYPTPROV hProv   = 0;
  64.     HCRYPTKEY hKey     = 0;
  65.     HCRYPTHASH hHash   = 0;
  66.  
  67.     PBYTE pbKeyBlob = NULL;
  68.     DWORD dwKeyBlobLen;
  69.  
  70.     PBYTE pbBuffer = NULL;
  71.     DWORD dwBlockLen;
  72.     DWORD dwBufferLen;
  73.     DWORD dwCount;
  74.  
  75.     BOOL status = FALSE;
  76.  
  77.     // Open source file.
  78.     if((hSource = fopen(szSource,"rb")) == NULL) {
  79.     printf("Error opening Ciphertext file!\n");
  80.         goto done;
  81.     }
  82.  
  83.     // Open destination file.
  84.     if((hDestination = fopen(szDestination,"wb")) == NULL) {
  85.     printf("Error opening Plaintext file!\n");
  86.         goto done;
  87.     }
  88.  
  89.     // Get handle to the default provider.
  90.     if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) {
  91.         printf("Error %x during CryptAcquireContext!\n", GetLastError());
  92.         goto done;
  93.     }
  94.  
  95.     if(szPassword == NULL) {
  96.     // Decrypt the file with the saved session key.
  97.  
  98.     // Read key blob length from source file and allocate memory.
  99.     fread(&dwKeyBlobLen, sizeof(DWORD), 1, hSource);
  100.     if(ferror(hSource) || feof(hSource)) {
  101.         printf("Error reading file header!\n");
  102.         goto done;
  103.     }
  104.     if((pbKeyBlob = malloc(dwKeyBlobLen)) == NULL) {
  105.         printf("Out of memory or improperly formatted source file!\n");
  106.         goto done;
  107.     }
  108.  
  109.     // Read key blob from source file.
  110.     fread(pbKeyBlob, 1, dwKeyBlobLen, hSource);
  111.     if(ferror(hSource) || feof(hSource)) {
  112.         printf("Error reading file header!\n");
  113.         goto done;
  114.     }
  115.  
  116.     // Import key blob into CSP.
  117.     if(!CryptImportKey(hProv, pbKeyBlob, dwKeyBlobLen, 0, 0, &hKey)) {
  118.         printf("Error %x during CryptImportKey!\n", GetLastError());
  119.         goto done;
  120.     }
  121.     } else {
  122.     // Decrypt the file with a session key derived from a password.
  123.  
  124.     // Create a hash object.
  125.     if(!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
  126.         printf("Error %x during CryptCreateHash!\n", GetLastError());
  127.         goto done;
  128.     }
  129.  
  130.     // Hash in the password data.
  131.     if(!CryptHashData(hHash, szPassword, strlen(szPassword), 0)) {
  132.         printf("Error %x during CryptHashData!\n", GetLastError());
  133.         goto done;
  134.     }
  135.  
  136.     // Derive a session key from the hash object.
  137.     if(!CryptDeriveKey(hProv, ENCRYPT_ALGORITHM, hHash, 0, &hKey)) {
  138.         printf("Error %x during CryptDeriveKey!\n", GetLastError());
  139.         goto done;
  140.     }
  141.  
  142.     // Destroy the hash object.
  143.     CryptDestroyHash(hHash);
  144.     hHash = 0;
  145.     }
  146.  
  147.     // Determine number of bytes to decrypt at a time. This must be a multiple
  148.     // of ENCRYPT_BLOCK_SIZE.
  149.     dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
  150.     dwBufferLen = dwBlockLen;
  151.  
  152.     // Allocate memory.
  153.     if((pbBuffer = malloc(dwBufferLen)) == NULL) {
  154.     printf("Out of memory!\n");
  155.     goto done;
  156.     }
  157.  
  158.     // Decrypt source file and write to destination file.
  159.     do {
  160.     // Read up to 'dwBlockLen' bytes from source file.
  161.     dwCount = fread(pbBuffer, 1, dwBlockLen, hSource);
  162.     if(ferror(hSource)) {
  163.         printf("Error reading Ciphertext!\n");
  164.             goto done;
  165.         }
  166.     eof = feof(hSource);
  167.  
  168.         // Decrypt data
  169.         if(!CryptDecrypt(hKey, 0, eof, 0, pbBuffer, &dwCount)) {
  170.             printf("Error %x during CryptDecrypt!\n", GetLastError());
  171.             goto done;
  172.         }
  173.  
  174.         // Write data to destination file.
  175.     fwrite(pbBuffer, 1, dwCount, hDestination);
  176.     if(ferror(hDestination)) {
  177.         printf("Error writing Plaintext!\n");
  178.             goto done;
  179.         }
  180.     } while(!feof(hSource));
  181.  
  182.     status = TRUE;
  183.  
  184.     printf("OK\n");
  185.  
  186.     done:
  187.  
  188.     // Close files.
  189.     if(hSource) fclose(hSource);
  190.     if(hDestination) fclose(hDestination);
  191.  
  192.     // Free memory.
  193.     if(pbKeyBlob) free(pbKeyBlob);
  194.     if(pbBuffer) free(pbBuffer);
  195.  
  196.     // Destroy session key.
  197.     if(hKey) CryptDestroyKey(hKey);
  198.  
  199.     // Destroy hash object.
  200.     if(hHash) CryptDestroyHash(hHash);
  201.  
  202.     // Release provider handle.
  203.     if(hProv) CryptReleaseContext(hProv, 0);
  204.  
  205.     return(status);
  206. }
  207.