home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 September / Chip_2002-09_cd1.bin / zkuste / vbasic / Data / Utils / XZipComp.exe / XceedEncryption.Cab / F112969_Decrypt.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-06-06  |  10.9 KB  |  316 lines

  1. /* Xceed Encryption Library - Decrypt Sample Application
  2.  * Copyright (c) 2001 Xceed Software Inc.
  3.  *
  4.  * [Decrypt.cpp]
  5.  *
  6.  * This console application shows how to encrypt a file, using different
  7.  * encryption methods. It specifically demonstrates:
  8.  *  - The SetSecretKeyFromPassPhrase, ReadFile and ProcessFile methods.
  9.  *  - The EncryptionMethod, EncryptionMode properties.
  10.  *
  11.  * This file is part of the Xceed Encryption Library sample 
  12.  * applications. The source code in this file is only intended as 
  13.  * a supplement to Xceed Encryption Library's documentation, 
  14.  * and is provided "as is", without warranty of any kind, either 
  15.  * expressed or implied. 
  16.  */
  17.  
  18. #include "stdafx.h"
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <limits.h>
  22. #include "Decrypt.h"
  23.  
  24. //
  25. // Mapping between command-line and property values
  26. //
  27. // The RSA Decryption method is not supported in this sample as it will rarely be used
  28. // to encrypt/decrypt a file. RSA is not efficient to encrypt large chunks of data.
  29.  
  30. static SEncryptionMethod g_pxEncryptionMethods[] = 
  31. {
  32.   { "=AES",     emRijndael },
  33.   { "=Twofish", emTwofish }
  34. };
  35.  
  36.  
  37. //
  38. // Entry point of the application
  39. //
  40.  
  41. int main(int argc, char* argv[])
  42. {
  43.   CoInitialize( NULL );
  44.  
  45.   try
  46.   {
  47.     // Create an instance of the XceedEncryption coclass, and
  48.     // use the "I" interface which manipulates byte arrays instead of
  49.     // Variants as the "D" interface does.
  50.     IXceedEncryptionPtr piEncrypt;
  51.     piEncrypt.CreateInstance( CLSID_XceedEncryption );
  52.  
  53.     _bstr_t bstrInputFileName;
  54.     _bstr_t bstrOutputFileName;
  55.  
  56.     // Extract the command line parameters and initialize the Encryption 
  57.     // instance according to the user specification. After this call
  58.     // the Encryption instance piEncrypt is ready to decrypt.
  59.     if( !ExtractParameters( argc, argv, 
  60.                             piEncrypt,
  61.                             bstrInputFileName, 
  62.                             bstrOutputFileName ) )
  63.     {
  64.       //There's been an error extracting the command-line parameters or the
  65.       //user requested some help.
  66.       ShowHelp();
  67.       return 1;
  68.     }
  69.  
  70.     if( bstrOutputFileName.length() == 0 )
  71.     {
  72.       // An output file name was not provided by the user.
  73.       // Output the result to the console
  74.  
  75.       BYTE* pcDecrypt     = NULL;
  76.       DWORD dwDecryptSize = 0;
  77.       DWORD dwBytesRead   = 0;
  78.  
  79.       // Decrypt by reading a file and sending the output to a buffer.
  80.       // We specify :
  81.       //  - The source filename, without any offset or size, since we want
  82.       //    to encrypt all the source file.
  83.       //  - The processing we want to perform, in this case efpDecrypt.
  84.       //  - The bEndOfData parameter set to TRUE, since we do all the
  85.       //    processing in a single block.
  86.       //  - The destination buffer, a byte array that will be allocated in the
  87.       //    function by CoTaskMemAlloc.
  88.       //  - The address of two DWORD that will receive the number of bytes
  89.       //    actually read from the source, and written to the destination.
  90.       piEncrypt->ReadFile( bstrInputFileName, 0, 0, 
  91.                            efpDecrypt, TRUE, 
  92.                            &dwBytesRead, &pcDecrypt, &dwDecryptSize );
  93.  
  94.       if( pcDecrypt )
  95.       {
  96.         // No error during decryption. Write the result to the standard output.
  97.         fwrite( pcDecrypt, sizeof( BYTE ), dwDecryptSize, stdout );
  98.         
  99.         // Free the Decrypt buffer allocated by the Xceed Encryption Library.
  100.         CoTaskMemFree( pcDecrypt );
  101.       }
  102.     }
  103.     else
  104.     {
  105.       // An output file name was provided by the user.
  106.       // Output the result to the specified file
  107.  
  108.       DWORD dwBytesRead     = 0;
  109.       DWORD dwBytesWritten  = 0;
  110.  
  111.       // Decrypt by reading a file and sending the output to another file.
  112.       // We specify :
  113.       //  - The source filename, without any offset or size, since we want
  114.       //    to encrypt all the source file.
  115.       //  - The processing we want to perform, in this case efpDecrypt.
  116.       //  - The bEndOfData parameter set to TRUE, since we do all the
  117.       //    processing in a single block.
  118.       //  - The destination filename, with the bAppend parameter set to FALSE
  119.       //    since we want to overwrite any existing file.
  120.       //  - The address of two DWORD that will receive the number of bytes
  121.       //    actually read from the source, and written to the destination.
  122.       piEncrypt->ProcessFile( bstrInputFileName, 0, 0, efpDecrypt, TRUE, 
  123.                           bstrOutputFileName, FALSE, 
  124.                           &dwBytesRead, &dwBytesWritten );
  125.  
  126.       // Write the decryption statistics to the screen. 
  127.       printf( "Successfully decrypted file %s [%d] to file %s [%d]\n", 
  128.               ( const char* )bstrInputFileName, dwBytesRead, 
  129.               ( const char* )bstrOutputFileName, dwBytesWritten );
  130.     }
  131.   }
  132.   catch( const _com_error& err )
  133.   {
  134.     // When using the "#import" directive, the compiler generates wrapper classes
  135.     // around all interface types. These wrapper classes throw exceptions when
  136.     // a method call returns an HRESULT which is a failure code.
  137.     printf( "Error %08x: %s\n", err.Error(), ( const char* )err.Description() );
  138.   }
  139.   catch( ... )
  140.   {
  141.     // Catch any other exceptions
  142.     printf( "An unknown error occured.\n" );
  143.   }
  144.  
  145.   // Close the COM library for the current thread
  146.   CoUninitialize();
  147.  
  148.     return 0;
  149. }
  150.  
  151. //--------------------------------------------------------------------------
  152. // Display usage information
  153. //--------------------------------------------------------------------------
  154. void ShowHelp()
  155. {
  156.   //      "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
  157.   printf( "Usage: Decrypt [options] input_file pass_phrase [output_file]\n\n"
  158.           "  input_file: the file to decrypt\n"
  159.           "  pass_phrase: the passphrase used to produce the secret key (between \"\" if\n"
  160.           "               you use spaces.\n"
  161.           "  output_file: the destination file\n\n"
  162.           "  options: /m=[AES | Twofish]\n"
  163.           "              This is the decryption method. The default is 'AES' (Rijndael)\n"
  164.           "           /h or /? : Show this help\n" );
  165. }
  166.  
  167. //--------------------------------------------------------------------------
  168. // Extract commands from the parameters
  169. //
  170. // In this function, we call the piEncrypt interface and let exceptions
  171. // be caught by the caller.
  172. // This function returns false if an error occured parsing the command
  173. // line parameters or if the user requested help.
  174. //--------------------------------------------------------------------------
  175. bool ExtractParameters( int argc, char* argv[],
  176.                         IXceedEncryptionPtr piEncrypt, 
  177.                         _bstr_t& bstrInputFileName,
  178.                         _bstr_t& bstrOutputFileName )
  179. {
  180.   // These variables used to initialize the Encryption Method property
  181.   // are set, here, to their default values.
  182.   SEncryptionMethod*  pxMethod = g_pxEncryptionMethods;
  183.  
  184.   bool                bFound;
  185.  
  186.   // We parse each command line parameter
  187.   int   i = 0;
  188.   while( ++i < argc )
  189.   {
  190.     if( argv[ i ][ 0 ] == '/' )
  191.     {
  192.       // The parameter starts with a /
  193.       // Meaning it's an option parameter
  194.       switch( argv[ i ][ 1 ] )
  195.       {
  196.         case 'm':
  197.         case 'M':
  198.           // The user wants to set the encryption method
  199.           bFound = false;
  200.  
  201.           // We go through all the encryption methods in the 
  202.           // correspondence table, stopping when we find a 
  203.           // match.
  204.           for( pxMethod = g_pxEncryptionMethods;
  205.                pxMethod->pszCommandLine != NULL;
  206.                pxMethod++ )
  207.           {
  208.             if( lstrcmpi( argv[ i ] + 2, pxMethod->pszCommandLine ) == 0 )
  209.             {
  210.               bFound = true;
  211.               break;
  212.             }
  213.           }
  214.  
  215.           if( !bFound )
  216.           {
  217.             printf( "Invalid decryption method '%s'\n\n", argv[ i ] );
  218.             return false;
  219.           }
  220.  
  221.           break;
  222.  
  223.         default:
  224.           printf( "Unknown command '%s'\n\n", argv[ i ] );
  225.           // Continue
  226.         case 'h':
  227.         case 'H':
  228.         case '?':
  229.           return false;
  230.       }
  231.     }
  232.   }
  233.  
  234.   _bstr_t bstrPassPhrase;
  235.  
  236.   // Check if the user provided an input file name
  237.   if( argc < 3 || argv[ argc - 1 ][ 0 ] == '/' || argv[ argc - 2 ][ 0 ] == '/' )
  238.   {
  239.     printf( "You did not specify a passphrase or an input filename\n\n" );
  240.     return false;
  241.   }
  242.   else if( argc < 4 || argv[ argc - 3 ][ 0 ] == '/' )
  243.   {
  244.     // Only an input file was specified
  245.     bstrInputFileName = argv[ argc - 2 ];
  246.     bstrPassPhrase    = argv[ argc - 1 ];
  247.   }
  248.   else
  249.   {
  250.     // Both input and output file were specified
  251.     bstrInputFileName  = argv[ argc - 3 ];
  252.     bstrPassPhrase     = argv[ argc - 2 ];
  253.     bstrOutputFileName = argv[ argc - 1 ];
  254.   }
  255.  
  256.   // According the encryption method chosen by the user, we set the various 
  257.   // properties of an encryption method and prepare the 
  258.   // Encryption interface (piEncrypt).
  259.  
  260.   // The properties common to all encryption method are:
  261.   // EncryptionMode
  262.   // The methods common to all encryption method are:
  263.   // SetSecretKeyFromPassPhrase
  264.  
  265.   // For each encryption method, we begin by creating a temporary instance 
  266.   // of the appropriate encryption method. The properties of this instance
  267.   // are then set and the instance is assign to the EncryptionMethod property
  268.   // of the XceedEncryption instance. This adds a reference to the 
  269.   // Encryption method instance so that the instance will not be freed
  270.   // when it will fall out of scope.
  271.  
  272.   switch( pxMethod->eMethod )
  273.   {
  274.     case emRijndael :
  275.     {
  276.       IXceedRijndaelEncryptionMethodPtr piRijndaelMethod;
  277.  
  278.       piRijndaelMethod.CreateInstance( CLSID_XceedRijndaelEncryptionMethod );
  279.  
  280.       // Set the Secret key using the pass phrase specified on the command prompt.
  281.       piRijndaelMethod->SetSecretKeyFromPassPhrase( bstrPassPhrase, KEY_SIZE );
  282.  
  283.       // We assume that the file was encrypted in CBC mode, which is more secure
  284.       // than ECB mode.
  285.       piRijndaelMethod->EncryptionMode = emoChainedBlocks;
  286.  
  287.       piEncrypt->EncryptionMethod = IXceedEncryptDataPtr( piRijndaelMethod );
  288.     }
  289.     break;
  290.  
  291.     case emTwofish :
  292.     {
  293.       IXceedTwofishEncryptionMethodPtr piTwofishMethod;
  294.  
  295.       piTwofishMethod.CreateInstance( CLSID_XceedTwofishEncryptionMethod );
  296.  
  297.       // Set the Secret key using the pass phrase specified on the command prompt.
  298.       piTwofishMethod->SetSecretKeyFromPassPhrase( bstrPassPhrase, KEY_SIZE );
  299.  
  300.       // We assume that the file was encrypted in CBC mode, which is more secure
  301.       // than ECB mode.
  302.       piTwofishMethod->EncryptionMode = emoChainedBlocks;
  303.  
  304.       piEncrypt->EncryptionMethod = IXceedEncryptDataPtr( piTwofishMethod );
  305.     }
  306.     break;
  307.   }
  308.  
  309.   return true;
  310. }
  311.  
  312.  
  313. //
  314. // END_OF_FILE
  315. //
  316.