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

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