cypher.h

Go to the documentation of this file.
00001 /*
00002  * cypher.h
00003  *
00004  * Encryption support classes.
00005  *
00006  * Portable Windows Library
00007  *
00008  * Copyright (c) 1993-2002 Equivalence Pty. Ltd.
00009  *
00010  * The contents of this file are subject to the Mozilla Public License
00011  * Version 1.0 (the "License"); you may not use this file except in
00012  * compliance with the License. You may obtain a copy of the License at
00013  * http://www.mozilla.org/MPL/
00014  *
00015  * Software distributed under the License is distributed on an "AS IS"
00016  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
00017  * the License for the specific language governing rights and limitations
00018  * under the License.
00019  *
00020  * The Original Code is Portable Windows Library.
00021  *
00022  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
00023  *
00024  * Contributor(s): ______________________________________.
00025  *
00026  * $Log: cypher.h,v $
00027  * Revision 1.24  2007/04/18 23:49:50  csoutheren
00028  * Add usage of precompiled headers
00029  *
00030  * Revision 1.23  2005/11/30 12:47:37  csoutheren
00031  * Removed tabs, reformatted some code, and changed tags for Doxygen
00032  *
00033  * Revision 1.22  2005/01/26 05:37:40  csoutheren
00034  * Added ability to remove config file support
00035  *
00036  * Revision 1.21  2004/11/11 07:34:50  csoutheren
00037  * Added #include <ptlib.h>
00038  *
00039  * Revision 1.20  2004/03/23 05:59:17  csoutheren
00040  * Moved the Base64 routines into cypher.cxx, which is a more sensible
00041  * place and reduces the inclusion of unrelated code
00042  *
00043  * Revision 1.19  2004/02/04 02:31:34  csoutheren
00044  * Remove SHA-1 functions when OpenSSL is disabled
00045  *
00046  * Revision 1.18  2003/04/17 03:34:07  craigs
00047  * Fixed problem with delete'ing a void *
00048  *
00049  * Revision 1.17  2003/04/10 07:02:38  craigs
00050  * Fixed link problem in MD5 class
00051  *
00052  * Revision 1.16  2003/04/10 06:16:30  craigs
00053  * Added SHA-1 digest
00054  *
00055  * Revision 1.15  2002/11/06 22:47:23  robertj
00056  * Fixed header comment (copyright etc)
00057  *
00058  * Revision 1.14  2002/09/16 01:08:59  robertj
00059  * Added #define so can select if #pragma interface/implementation is used on
00060  *   platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
00061  *
00062  * Revision 1.13  2001/09/10 00:28:21  robertj
00063  * Fixed extra CR in comments.
00064  *
00065  * Revision 1.12  1999/03/09 08:01:46  robertj
00066  * Changed comments for doc++ support (more to come).
00067  *
00068  * Revision 1.11  1999/02/16 08:07:10  robertj
00069  * MSVC 6.0 compatibility changes.
00070  *
00071  * Revision 1.10  1998/09/23 06:19:24  robertj
00072  * Added open source copyright license.
00073  *
00074  * Revision 1.9  1997/10/10 10:44:01  robertj
00075  * Fixed bug in password encryption, missing string terminator.
00076  *
00077  * Revision 1.8  1996/11/16 10:50:24  robertj
00078  * Fixed bug in registration order form showing incorrect check code when have key.
00079  *
00080  * Revision 1.7  1996/07/15 10:29:38  robertj
00081  * Changed memory block cypher conversion functions to be void *.
00082  * Changed key types to be structures rather than arrays to avoid pinter/reference confusion by compilers.
00083  *
00084  * Revision 1.6  1996/03/17 05:47:00  robertj
00085  * Changed secured config to allow for expiry dates.
00086  *
00087  * Revision 1.5  1996/03/16 04:36:43  robertj
00088  * Redesign of secure config to accommodate expiry dates and option values passed in security key code.
00089  *
00090  * Revision 1.4  1996/02/25 02:52:46  robertj
00091  * Further secure config development.
00092  *
00093  * Revision 1.3  1996/01/28 14:16:11  robertj
00094  * Further implementation of secure config.
00095  *
00096  * Revision 1.2  1996/01/28 02:41:00  robertj
00097  * Removal of MemoryPointer classes as usage didn't work for GNU.
00098  * Added the secure configuration mechanism for protecting applications.
00099  *
00100  * Revision 1.1  1996/01/23 13:04:20  robertj
00101  * Initial revision
00102  *
00103  */
00104 
00105 
00106 #ifndef _PCYPHER
00107 #define _PCYPHER
00108 
00109 #ifdef P_USE_PRAGMA
00110 #pragma interface
00111 #endif
00112 
00113 #ifndef _PTLIB_H
00114 #include <ptlib.h>
00115 #endif
00116 
00147 class PBase64 : public PObject
00148 {
00149   PCLASSINFO(PBase64, PObject);
00150 
00151   public:
00155     PBase64();
00156 
00157     void StartEncoding(
00158       BOOL useCRLFs = TRUE  // Use CR, LF pairs in end of line characters.
00159     );
00160     // Begin a base 64 encoding operation, initialising the object instance.
00161 
00162     void ProcessEncoding(
00163       const PString & str      // String to be encoded
00164     );
00165     void ProcessEncoding(
00166       const char * cstr        // C String to be encoded
00167     );
00168     void ProcessEncoding(
00169       const PBYTEArray & data  // Data block to be encoded
00170     );
00171     void ProcessEncoding(
00172       const void * dataBlock,  // Pointer to data to be encoded
00173       PINDEX length            // Length of the data block.
00174     );
00175     // Incorporate the specified data into the base 64 encoding.
00176 
00182     PString GetEncodedString();
00183 
00191     PString CompleteEncoding();
00192 
00193 
00194     static PString Encode(
00195       const PString & str     // String to be encoded to Base64
00196     );
00197     static PString Encode(
00198       const char * cstr       // C String to be encoded to Base64
00199     );
00200     static PString Encode(
00201       const PBYTEArray & data // Data block to be encoded to Base64
00202     );
00203     static PString Encode(
00204       const void * dataBlock, // Pointer to data to be encoded to Base64
00205       PINDEX length           // Length of the data block.
00206     );
00207     // Encode the data in memory to Base 64 data returnin the string.
00208 
00209 
00210     void StartDecoding();
00211     // Begin a base 64 decoding operation, initialising the object instance.
00212 
00218     BOOL ProcessDecoding(
00219       const PString & str      // String to be encoded
00220     );
00221     BOOL ProcessDecoding(
00222       const char * cstr        // C String to be encoded
00223     );
00224 
00230     BOOL GetDecodedData(
00231       void * dataBlock,    // Pointer to data to be decoded from base64
00232       PINDEX length        // Length of the data block.
00233     );
00234     PBYTEArray GetDecodedData();
00235 
00243     BOOL IsDecodeOK() { return perfectDecode; }
00244 
00245 
00257     static PString Decode(
00258       const PString & str // Encoded base64 string to be decoded.
00259     );
00260     static BOOL Decode(
00261       const PString & str, // Encoded base64 string to be decoded.
00262       PBYTEArray & data    // Converted binary data from base64.
00263     );
00264     static BOOL Decode(
00265       const PString & str, // Encoded base64 string to be decoded.
00266       void * dataBlock,    // Pointer to data to be decoded from base64
00267       PINDEX length        // Length of the data block.
00268     );
00269 
00270 
00271 
00272   private:
00273     void OutputBase64(const BYTE * data);
00274 
00275     PString encodedString;
00276     PINDEX  encodeLength;
00277     BYTE    saveTriple[3];
00278     PINDEX  saveCount;
00279     PINDEX  nextLine;
00280     BOOL    useCRLFs;
00281 
00282     BOOL       perfectDecode;
00283     PINDEX     quadPosition;
00284     PBYTEArray decodedData;
00285     PINDEX     decodeSize;
00286 };
00287 
00288 class PMessageDigest : public PObject
00289 {
00290   PCLASSINFO(PMessageDigest, PObject)
00291 
00292   public:
00294     PMessageDigest();
00295 
00296     class Result {
00297       public:
00298         PINDEX GetSize() const          { return value.GetSize(); }
00299         const BYTE * GetPointer() const { return (const BYTE *)value; }
00300 
00301       private:
00302         PBYTEArray value;
00303         friend class PMessageDigest5;
00304         friend class PMessageDigestSHA1;
00305     };
00306 
00308     virtual void Start() = 0;
00309 
00310     virtual void Process(
00311       const void * dataBlock,  
00312       PINDEX length            
00313     );
00314 
00316     virtual void Process(
00317       const PString & str      
00318     );
00320     virtual void Process(
00321       const char * cstr        
00322     );
00324     virtual void Process(
00325       const PBYTEArray & data  
00326     );
00327 
00335     virtual PString CompleteDigest();
00336     virtual void CompleteDigest(
00337       Result & result   
00338     );
00339 
00340   protected:
00341     virtual void InternalProcess(
00342        const void * dataBlock,  
00343       PINDEX length            
00344     ) = 0;
00345 
00346     virtual void InternalCompleteDigest(
00347       Result & result   
00348     ) = 0;
00349 };
00350 
00351 
00357 class PMessageDigest5 : public PMessageDigest
00358 {
00359   PCLASSINFO(PMessageDigest5, PMessageDigest)
00360 
00361   public:
00363     PMessageDigest5();
00364 
00366     void Start();
00367 
00369     static PString Encode(
00370       const PString & str      
00371     );
00373     static void Encode(
00374       const PString & str,     
00375       Result & result            
00376     );
00378     static PString Encode(
00379       const char * cstr        
00380     );
00382     static void Encode(
00383       const char * cstr,       
00384       Result & result            
00385     );
00387     static PString Encode(
00388       const PBYTEArray & data  
00389     );
00391     static void Encode(
00392       const PBYTEArray & data, 
00393       Result & result            
00394     );
00396     static PString Encode(
00397       const void * dataBlock,  
00398       PINDEX length            
00399     );
00405     static void Encode(
00406       const void * dataBlock,  
00407       PINDEX length,           
00408       Result & result            
00409     );
00410 
00411     // backwards compatibility functions
00412     class Code {
00413       private:
00414         PUInt32l value[4];
00415         friend class PMessageDigest5;
00416     };
00417 
00419     static void Encode(
00420       const PString & str,     
00421       Code & result            
00422     );
00424     static void Encode(
00425       const char * cstr,       
00426       Code & result            
00427     );
00429     static void Encode(
00430       const PBYTEArray & data, 
00431       Code & result            
00432     );
00438     static void Encode(
00439       const void * dataBlock,  
00440       PINDEX length,           
00441       Code & result            
00442     );
00443     virtual void Complete(
00444       Code & result   
00445     );
00446     virtual PString Complete();
00447 
00448   protected:
00449     virtual void InternalProcess(
00450        const void * dataBlock,  
00451       PINDEX length            
00452     );
00453 
00454     virtual void InternalCompleteDigest(
00455       Result & result   
00456     );
00457 
00458   private:
00459     void Transform(const BYTE * block);
00460 
00462     BYTE buffer[64];
00464     DWORD state[4];
00466     PUInt64 count;
00467 };
00468 
00469 #if P_SSL
00470 
00475 class PMessageDigestSHA1 : public PMessageDigest
00476 {
00477   PCLASSINFO(PMessageDigestSHA1, PMessageDigest)
00478 
00479   public:
00481     PMessageDigestSHA1();
00482     ~PMessageDigestSHA1();
00483 
00485     void Start();
00486 
00488     static PString Encode(
00489       const PString & str      
00490     );
00492     static void Encode(
00493       const PString & str,     
00494       Result & result            
00495     );
00497     static PString Encode(
00498       const char * cstr        
00499     );
00501     static void Encode(
00502       const char * cstr,       
00503       Result & result            
00504     );
00506     static PString Encode(
00507       const PBYTEArray & data  
00508     );
00510     static void Encode(
00511       const PBYTEArray & data, 
00512       Result & result            
00513     );
00515     static PString Encode(
00516       const void * dataBlock,  
00517       PINDEX length            
00518     );
00524     static void Encode(
00525       const void * dataBlock,  
00526       PINDEX length,           
00527       Result & result            
00528     );
00529 
00530   protected:
00531     virtual void InternalProcess(
00532        const void * dataBlock,  
00533       PINDEX length            
00534     );
00535 
00536     void InternalCompleteDigest(
00537       Result & result   
00538     );
00539 
00540   private:
00541     void * shaContext;
00542 };
00543 
00544 #endif
00545 
00549 class PCypher : public PObject
00550 {
00551   PCLASSINFO(PCypher, PObject)
00552 
00553   public:
00555     enum BlockChainMode {
00556       ElectronicCodebook,
00557         ECB = ElectronicCodebook,
00558       CypherBlockChaining,
00559         CBC = CypherBlockChaining,
00560       OutputFeedback,
00561         OFB = OutputFeedback,
00562       CypherFeedback,
00563         CFB = CypherFeedback,
00564       NumBlockChainModes
00565     };
00566 
00567   // New functions for class
00569     PString Encode(
00570       const PString & str       
00571     );
00573     PString Encode(
00574       const PBYTEArray & clear  
00575     );
00577     PString Encode(
00578       const void * data,        
00579       PINDEX length             
00580     );
00582     void Encode(
00583       const PBYTEArray & clear, 
00584       PBYTEArray & coded        
00585     );
00601     void Encode(
00602       const void * data,        // Clear text binary data to be encoded.
00603       PINDEX length,            // Number of bytes of data to be encoded.
00604       PBYTEArray & coded        // Encoded data.
00605     );
00606 
00608     PString Decode(
00609       const PString & cypher   
00610     );
00612     BOOL Decode(
00613       const PString & cypher,  
00614       PString & clear          
00615     );
00617     BOOL Decode(
00618       const PString & cypher,  
00619       PBYTEArray & clear       
00620     );
00622     PINDEX Decode(
00623       const PString & cypher,  
00624       void * data,             
00625       PINDEX length            
00626     );
00628     PINDEX Decode(
00629       const PBYTEArray & coded, 
00630       void * data,              
00631       PINDEX length             
00632     );
00648     BOOL Decode(
00649       const PBYTEArray & coded, 
00650       PBYTEArray & clear       
00651     );
00652 
00653 
00654   protected:
00658     PCypher(
00659       PINDEX blockSize,          
00660       BlockChainMode chainMode   
00661     );
00662     PCypher(
00663       const void * keyData,    
00664       PINDEX keyLength,        
00665       PINDEX blockSize,        
00666       BlockChainMode chainMode 
00667     );
00668 
00669 
00671     virtual void Initialise(
00672       BOOL encoding   
00673     ) = 0;
00674 
00676     virtual void EncodeBlock(
00677       const void * in,    
00678       void * out          
00679     ) = 0;
00680 
00681 
00683     virtual void DecodeBlock(
00684       const void * in,  
00685       void * out        
00686     ) = 0;
00687 
00688 
00690     PBYTEArray key;
00692     PINDEX blockSize;
00694     BlockChainMode chainMode;
00695 };
00696 
00697 
00705 class PTEACypher : public PCypher
00706 {
00707   PCLASSINFO(PTEACypher, PCypher)
00708 
00709   public:
00710     struct Key {
00711       BYTE value[16];
00712     };
00713 
00718     PTEACypher(
00719       BlockChainMode chainMode = ElectronicCodebook   
00720     );
00721     PTEACypher(
00722       const Key & keyData,     
00723       BlockChainMode chainMode = ElectronicCodebook   
00724     );
00725 
00726 
00728     void SetKey(
00729       const Key & newKey    
00730     );
00731 
00733     void GetKey(
00734       Key & newKey    
00735     ) const;
00736 
00737 
00739     static void GenerateKey(
00740       Key & newKey    
00741     );
00742 
00743 
00744   protected:
00746     virtual void Initialise(
00747       BOOL encoding   
00748     );
00749 
00751     virtual void EncodeBlock(
00752       const void * in,  
00753       void * out        
00754     );
00755 
00757     virtual void DecodeBlock(
00758       const void * in,  
00759       void * out        
00760     );
00761 
00762   private:
00763     DWORD k0, k1, k2, k3;
00764 };
00765 
00766 
00767 #ifdef P_CONFIG_FILE
00768 
00769 class PSecureConfig : public PConfig
00770 {
00771   PCLASSINFO(PSecureConfig, PConfig)
00772 /* This class defines a set of configuration keys which may be secured by an
00773    encrypted hash function. Thus values contained in keys specified by this
00774    class cannot be changed without invalidating the hash function.
00775  */
00776 
00777   public:
00778     PSecureConfig(
00779       const PTEACypher::Key & productKey,    // Key to decrypt validation code.
00780       const PStringArray    & securedKeys,   // List of secured keys.
00781       Source src = Application        // Standard source for the configuration.
00782     );
00783     PSecureConfig(
00784       const PTEACypher::Key & productKey,   // Key to decrypt validation code.
00785       const char * const * securedKeyArray, // List of secured keys.
00786       PINDEX count,                         // Number of secured keys in list.
00787       Source src = Application        // Standard source for the configuration.
00788     );
00789     /* Create a secured configuration. The default section for the
00790        configuration keys is "Secured Options", the default security key is
00791        "Validation" and the defualt prefix string is "Pending:".
00792 
00793        The user can descend from this class and change any of the member
00794        variable for the names of keys or the configuration file section.
00795      */
00796 
00797 
00798   // New functions for class
00799     const PStringArray & GetSecuredKeys() const { return securedKeys; }
00800     /* Get the list of secured keys in the configuration file section.
00801 
00802        @return
00803        Array of  strings for the secured keys.
00804      */
00805 
00806     const PString & GetSecurityKey() const { return securityKey; }
00807     /* Get the security keys name in the configuration file section.
00808 
00809        @return
00810        String for the security values key.
00811      */
00812 
00813     const PString & GetExpiryDateKey() const { return expiryDateKey; }
00814     /* Get the expiry date keys name in the configuration file section.
00815 
00816        @return
00817        String for the expiry date values key.
00818      */
00819 
00820     const PString & GetOptionBitsKey() const { return optionBitsKey; }
00821     /* Get the Option Bits keys name in the configuration file section.
00822 
00823        @return
00824        String for the Option Bits values key.
00825      */
00826 
00827     const PString & GetPendingPrefix() const { return pendingPrefix; }
00828     /* Get the pending prefix name in the configuration file section.
00829 
00830        @return
00831        String for the pending prefix.
00832      */
00833 
00834     void GetProductKey(
00835       PTEACypher::Key & productKey  // Variable to receive the product key.
00836     ) const;
00837     /* Get the pending prefix name in the configuration file section.
00838 
00839        @return
00840        String for the pending prefix.
00841      */
00842 
00843 
00844     enum ValidationState {
00845       Defaults,
00846       Pending,
00847       IsValid,
00848       Expired,
00849       Invalid
00850     };
00851     ValidationState GetValidation() const;
00852     /* Check the current values attached to the keys specified in the
00853        constructor against an encoded validation key.
00854 
00855        @return
00856        State of the validation keys.
00857      */
00858 
00859     BOOL ValidatePending();
00860     /* Validate a pending secured option list for the product. All secured
00861        keys with the <CODE>pendingPrefix</CODE> name will be checked against
00862        the value of the field <CODE>securityKey</CODE>. If they match then
00863        they are copied to the secured variables.
00864 
00865        @return
00866        TRUE if secure key values are valid.
00867      */
00868 
00869     void ResetPending();
00870     /* "Unvalidate" a security configuration going back to a pending state,
00871        usually used after an <CODE>Invalid</CODE> response was recieved from
00872        the <A>GetValidation()</A> function.
00873      */
00874 
00875 
00876   protected:
00877     PTEACypher::Key productKey;
00878     PStringArray    securedKeys;
00879     PString         securityKey;
00880     PString         expiryDateKey;
00881     PString         optionBitsKey;
00882     PString         pendingPrefix;
00883 };
00884 
00885 #endif // P_CONFIG_FILE
00886 
00887 #endif // _PCYPHER
00888 
00889 
00890 // End Of File ///////////////////////////////////////////////////////////////

Generated on Fri Mar 7 06:25:02 2008 for PTLib by  doxygen 1.5.1