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.23  2005/11/30 12:47:37  csoutheren
00028  * Removed tabs, reformatted some code, and changed tags for Doxygen
00029  *
00030  * Revision 1.22  2005/01/26 05:37:40  csoutheren
00031  * Added ability to remove config file support
00032  *
00033  * Revision 1.21  2004/11/11 07:34:50  csoutheren
00034  * Added #include <ptlib.h>
00035  *
00036  * Revision 1.20  2004/03/23 05:59:17  csoutheren
00037  * Moved the Base64 routines into cypher.cxx, which is a more sensible
00038  * place and reduces the inclusion of unrelated code
00039  *
00040  * Revision 1.19  2004/02/04 02:31:34  csoutheren
00041  * Remove SHA-1 functions when OpenSSL is disabled
00042  *
00043  * Revision 1.18  2003/04/17 03:34:07  craigs
00044  * Fixed problem with delete'ing a void *
00045  *
00046  * Revision 1.17  2003/04/10 07:02:38  craigs
00047  * Fixed link problem in MD5 class
00048  *
00049  * Revision 1.16  2003/04/10 06:16:30  craigs
00050  * Added SHA-1 digest
00051  *
00052  * Revision 1.15  2002/11/06 22:47:23  robertj
00053  * Fixed header comment (copyright etc)
00054  *
00055  * Revision 1.14  2002/09/16 01:08:59  robertj
00056  * Added #define so can select if #pragma interface/implementation is used on
00057  *   platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
00058  *
00059  * Revision 1.13  2001/09/10 00:28:21  robertj
00060  * Fixed extra CR in comments.
00061  *
00062  * Revision 1.12  1999/03/09 08:01:46  robertj
00063  * Changed comments for doc++ support (more to come).
00064  *
00065  * Revision 1.11  1999/02/16 08:07:10  robertj
00066  * MSVC 6.0 compatibility changes.
00067  *
00068  * Revision 1.10  1998/09/23 06:19:24  robertj
00069  * Added open source copyright license.
00070  *
00071  * Revision 1.9  1997/10/10 10:44:01  robertj
00072  * Fixed bug in password encryption, missing string terminator.
00073  *
00074  * Revision 1.8  1996/11/16 10:50:24  robertj
00075  * Fixed bug in registration order form showing incorrect check code when have key.
00076  *
00077  * Revision 1.7  1996/07/15 10:29:38  robertj
00078  * Changed memory block cypher conversion functions to be void *.
00079  * Changed key types to be structures rather than arrays to avoid pinter/reference confusion by compilers.
00080  *
00081  * Revision 1.6  1996/03/17 05:47:00  robertj
00082  * Changed secured config to allow for expiry dates.
00083  *
00084  * Revision 1.5  1996/03/16 04:36:43  robertj
00085  * Redesign of secure config to accommodate expiry dates and option values passed in security key code.
00086  *
00087  * Revision 1.4  1996/02/25 02:52:46  robertj
00088  * Further secure config development.
00089  *
00090  * Revision 1.3  1996/01/28 14:16:11  robertj
00091  * Further implementation of secure config.
00092  *
00093  * Revision 1.2  1996/01/28 02:41:00  robertj
00094  * Removal of MemoryPointer classes as usage didn't work for GNU.
00095  * Added the secure configuration mechanism for protecting applications.
00096  *
00097  * Revision 1.1  1996/01/23 13:04:20  robertj
00098  * Initial revision
00099  *
00100  */
00101 
00102 
00103 #ifndef _PCYPHER
00104 #define _PCYPHER
00105 
00106 #ifdef P_USE_PRAGMA
00107 #pragma interface
00108 #endif
00109 
00110 #include <ptlib.h>
00111 
00142 class PBase64 : public PObject
00143 {
00144   PCLASSINFO(PBase64, PObject);
00145 
00146   public:
00150     PBase64();
00151 
00152     void StartEncoding(
00153       BOOL useCRLFs = TRUE  // Use CR, LF pairs in end of line characters.
00154     );
00155     // Begin a base 64 encoding operation, initialising the object instance.
00156 
00157     void ProcessEncoding(
00158       const PString & str      // String to be encoded
00159     );
00160     void ProcessEncoding(
00161       const char * cstr        // C String to be encoded
00162     );
00163     void ProcessEncoding(
00164       const PBYTEArray & data  // Data block to be encoded
00165     );
00166     void ProcessEncoding(
00167       const void * dataBlock,  // Pointer to data to be encoded
00168       PINDEX length            // Length of the data block.
00169     );
00170     // Incorporate the specified data into the base 64 encoding.
00171 
00177     PString GetEncodedString();
00178 
00186     PString CompleteEncoding();
00187 
00188 
00189     static PString Encode(
00190       const PString & str     // String to be encoded to Base64
00191     );
00192     static PString Encode(
00193       const char * cstr       // C String to be encoded to Base64
00194     );
00195     static PString Encode(
00196       const PBYTEArray & data // Data block to be encoded to Base64
00197     );
00198     static PString Encode(
00199       const void * dataBlock, // Pointer to data to be encoded to Base64
00200       PINDEX length           // Length of the data block.
00201     );
00202     // Encode the data in memory to Base 64 data returnin the string.
00203 
00204 
00205     void StartDecoding();
00206     // Begin a base 64 decoding operation, initialising the object instance.
00207 
00213     BOOL ProcessDecoding(
00214       const PString & str      // String to be encoded
00215     );
00216     BOOL ProcessDecoding(
00217       const char * cstr        // C String to be encoded
00218     );
00219 
00225     BOOL GetDecodedData(
00226       void * dataBlock,    // Pointer to data to be decoded from base64
00227       PINDEX length        // Length of the data block.
00228     );
00229     PBYTEArray GetDecodedData();
00230 
00238     BOOL IsDecodeOK() { return perfectDecode; }
00239 
00240 
00252     static PString Decode(
00253       const PString & str // Encoded base64 string to be decoded.
00254     );
00255     static BOOL Decode(
00256       const PString & str, // Encoded base64 string to be decoded.
00257       PBYTEArray & data    // Converted binary data from base64.
00258     );
00259     static BOOL Decode(
00260       const PString & str, // Encoded base64 string to be decoded.
00261       void * dataBlock,    // Pointer to data to be decoded from base64
00262       PINDEX length        // Length of the data block.
00263     );
00264 
00265 
00266 
00267   private:
00268     void OutputBase64(const BYTE * data);
00269 
00270     PString encodedString;
00271     PINDEX  encodeLength;
00272     BYTE    saveTriple[3];
00273     PINDEX  saveCount;
00274     PINDEX  nextLine;
00275     BOOL    useCRLFs;
00276 
00277     BOOL       perfectDecode;
00278     PINDEX     quadPosition;
00279     PBYTEArray decodedData;
00280     PINDEX     decodeSize;
00281 };
00282 
00283 class PMessageDigest : public PObject
00284 {
00285   PCLASSINFO(PMessageDigest, PObject)
00286 
00287   public:
00289     PMessageDigest();
00290 
00291     class Result {
00292       public:
00293         PINDEX GetSize() const          { return value.GetSize(); }
00294         const BYTE * GetPointer() const { return (const BYTE *)value; }
00295 
00296       private:
00297         PBYTEArray value;
00298         friend class PMessageDigest5;
00299         friend class PMessageDigestSHA1;
00300     };
00301 
00303     virtual void Start() = 0;
00304 
00305     virtual void Process(
00306       const void * dataBlock,  
00307       PINDEX length            
00308     );
00309 
00311     virtual void Process(
00312       const PString & str      
00313     );
00315     virtual void Process(
00316       const char * cstr        
00317     );
00319     virtual void Process(
00320       const PBYTEArray & data  
00321     );
00322 
00330     virtual PString CompleteDigest();
00331     virtual void CompleteDigest(
00332       Result & result   
00333     );
00334 
00335   protected:
00336     virtual void InternalProcess(
00337        const void * dataBlock,  
00338       PINDEX length            
00339     ) = 0;
00340 
00341     virtual void InternalCompleteDigest(
00342       Result & result   
00343     ) = 0;
00344 };
00345 
00346 
00352 class PMessageDigest5 : public PMessageDigest
00353 {
00354   PCLASSINFO(PMessageDigest5, PMessageDigest)
00355 
00356   public:
00358     PMessageDigest5();
00359 
00361     void Start();
00362 
00364     static PString Encode(
00365       const PString & str      
00366     );
00368     static void Encode(
00369       const PString & str,     
00370       Result & result            
00371     );
00373     static PString Encode(
00374       const char * cstr        
00375     );
00377     static void Encode(
00378       const char * cstr,       
00379       Result & result            
00380     );
00382     static PString Encode(
00383       const PBYTEArray & data  
00384     );
00386     static void Encode(
00387       const PBYTEArray & data, 
00388       Result & result            
00389     );
00391     static PString Encode(
00392       const void * dataBlock,  
00393       PINDEX length            
00394     );
00400     static void Encode(
00401       const void * dataBlock,  
00402       PINDEX length,           
00403       Result & result            
00404     );
00405 
00406     // backwards compatibility functions
00407     class Code {
00408       private:
00409         PUInt32l value[4];
00410         friend class PMessageDigest5;
00411     };
00412 
00414     static void Encode(
00415       const PString & str,     
00416       Code & result            
00417     );
00419     static void Encode(
00420       const char * cstr,       
00421       Code & result            
00422     );
00424     static void Encode(
00425       const PBYTEArray & data, 
00426       Code & result            
00427     );
00433     static void Encode(
00434       const void * dataBlock,  
00435       PINDEX length,           
00436       Code & result            
00437     );
00438     virtual void Complete(
00439       Code & result   
00440     );
00441     virtual PString Complete();
00442 
00443   protected:
00444     virtual void InternalProcess(
00445        const void * dataBlock,  
00446       PINDEX length            
00447     );
00448 
00449     virtual void InternalCompleteDigest(
00450       Result & result   
00451     );
00452 
00453   private:
00454     void Transform(const BYTE * block);
00455 
00457     BYTE buffer[64];
00459     DWORD state[4];
00461     PUInt64 count;
00462 };
00463 
00464 #if P_SSL
00465 
00470 class PMessageDigestSHA1 : public PMessageDigest
00471 {
00472   PCLASSINFO(PMessageDigestSHA1, PMessageDigest)
00473 
00474   public:
00476     PMessageDigestSHA1();
00477     ~PMessageDigestSHA1();
00478 
00480     void Start();
00481 
00483     static PString Encode(
00484       const PString & str      
00485     );
00487     static void Encode(
00488       const PString & str,     
00489       Result & result            
00490     );
00492     static PString Encode(
00493       const char * cstr        
00494     );
00496     static void Encode(
00497       const char * cstr,       
00498       Result & result            
00499     );
00501     static PString Encode(
00502       const PBYTEArray & data  
00503     );
00505     static void Encode(
00506       const PBYTEArray & data, 
00507       Result & result            
00508     );
00510     static PString Encode(
00511       const void * dataBlock,  
00512       PINDEX length            
00513     );
00519     static void Encode(
00520       const void * dataBlock,  
00521       PINDEX length,           
00522       Result & result            
00523     );
00524 
00525   protected:
00526     virtual void InternalProcess(
00527        const void * dataBlock,  
00528       PINDEX length            
00529     );
00530 
00531     void InternalCompleteDigest(
00532       Result & result   
00533     );
00534 
00535   private:
00536     void * shaContext;
00537 };
00538 
00539 #endif
00540 
00544 class PCypher : public PObject
00545 {
00546   PCLASSINFO(PCypher, PObject)
00547 
00548   public:
00550     enum BlockChainMode {
00551       ElectronicCodebook,
00552         ECB = ElectronicCodebook,
00553       CypherBlockChaining,
00554         CBC = CypherBlockChaining,
00555       OutputFeedback,
00556         OFB = OutputFeedback,
00557       CypherFeedback,
00558         CFB = CypherFeedback,
00559       NumBlockChainModes
00560     };
00561 
00562   // New functions for class
00564     PString Encode(
00565       const PString & str       
00566     );
00568     PString Encode(
00569       const PBYTEArray & clear  
00570     );
00572     PString Encode(
00573       const void * data,        
00574       PINDEX length             
00575     );
00577     void Encode(
00578       const PBYTEArray & clear, 
00579       PBYTEArray & coded        
00580     );
00596     void Encode(
00597       const void * data,        // Clear text binary data to be encoded.
00598       PINDEX length,            // Number of bytes of data to be encoded.
00599       PBYTEArray & coded        // Encoded data.
00600     );
00601 
00603     PString Decode(
00604       const PString & cypher   
00605     );
00607     BOOL Decode(
00608       const PString & cypher,  
00609       PString & clear          
00610     );
00612     BOOL Decode(
00613       const PString & cypher,  
00614       PBYTEArray & clear       
00615     );
00617     PINDEX Decode(
00618       const PString & cypher,  
00619       void * data,             
00620       PINDEX length            
00621     );
00623     PINDEX Decode(
00624       const PBYTEArray & coded, 
00625       void * data,              
00626       PINDEX length             
00627     );
00643     BOOL Decode(
00644       const PBYTEArray & coded, 
00645       PBYTEArray & clear       
00646     );
00647 
00648 
00649   protected:
00653     PCypher(
00654       PINDEX blockSize,          
00655       BlockChainMode chainMode   
00656     );
00657     PCypher(
00658       const void * keyData,    
00659       PINDEX keyLength,        
00660       PINDEX blockSize,        
00661       BlockChainMode chainMode 
00662     );
00663 
00664 
00666     virtual void Initialise(
00667       BOOL encoding   
00668     ) = 0;
00669 
00671     virtual void EncodeBlock(
00672       const void * in,    
00673       void * out          
00674     ) = 0;
00675 
00676 
00678     virtual void DecodeBlock(
00679       const void * in,  
00680       void * out        
00681     ) = 0;
00682 
00683 
00685     PBYTEArray key;
00687     PINDEX blockSize;
00689     BlockChainMode chainMode;
00690 };
00691 
00692 
00700 class PTEACypher : public PCypher
00701 {
00702   PCLASSINFO(PTEACypher, PCypher)
00703 
00704   public:
00705     struct Key {
00706       BYTE value[16];
00707     };
00708 
00713     PTEACypher(
00714       BlockChainMode chainMode = ElectronicCodebook   
00715     );
00716     PTEACypher(
00717       const Key & keyData,     
00718       BlockChainMode chainMode = ElectronicCodebook   
00719     );
00720 
00721 
00723     void SetKey(
00724       const Key & newKey    
00725     );
00726 
00728     void GetKey(
00729       Key & newKey    
00730     ) const;
00731 
00732 
00734     static void GenerateKey(
00735       Key & newKey    
00736     );
00737 
00738 
00739   protected:
00741     virtual void Initialise(
00742       BOOL encoding   
00743     );
00744 
00746     virtual void EncodeBlock(
00747       const void * in,  
00748       void * out        
00749     );
00750 
00752     virtual void DecodeBlock(
00753       const void * in,  
00754       void * out        
00755     );
00756 
00757   private:
00758     DWORD k0, k1, k2, k3;
00759 };
00760 
00761 
00762 #ifdef P_CONFIG_FILE
00763 
00764 class PSecureConfig : public PConfig
00765 {
00766   PCLASSINFO(PSecureConfig, PConfig)
00767 /* This class defines a set of configuration keys which may be secured by an
00768    encrypted hash function. Thus values contained in keys specified by this
00769    class cannot be changed without invalidating the hash function.
00770  */
00771 
00772   public:
00773     PSecureConfig(
00774       const PTEACypher::Key & productKey,    // Key to decrypt validation code.
00775       const PStringArray    & securedKeys,   // List of secured keys.
00776       Source src = Application        // Standard source for the configuration.
00777     );
00778     PSecureConfig(
00779       const PTEACypher::Key & productKey,   // Key to decrypt validation code.
00780       const char * const * securedKeyArray, // List of secured keys.
00781       PINDEX count,                         // Number of secured keys in list.
00782       Source src = Application        // Standard source for the configuration.
00783     );
00784     /* Create a secured configuration. The default section for the
00785        configuration keys is "Secured Options", the default security key is
00786        "Validation" and the defualt prefix string is "Pending:".
00787 
00788        The user can descend from this class and change any of the member
00789        variable for the names of keys or the configuration file section.
00790      */
00791 
00792 
00793   // New functions for class
00794     const PStringArray & GetSecuredKeys() const { return securedKeys; }
00795     /* Get the list of secured keys in the configuration file section.
00796 
00797        @return
00798        Array of  strings for the secured keys.
00799      */
00800 
00801     const PString & GetSecurityKey() const { return securityKey; }
00802     /* Get the security keys name in the configuration file section.
00803 
00804        @return
00805        String for the security values key.
00806      */
00807 
00808     const PString & GetExpiryDateKey() const { return expiryDateKey; }
00809     /* Get the expiry date keys name in the configuration file section.
00810 
00811        @return
00812        String for the expiry date values key.
00813      */
00814 
00815     const PString & GetOptionBitsKey() const { return optionBitsKey; }
00816     /* Get the Option Bits keys name in the configuration file section.
00817 
00818        @return
00819        String for the Option Bits values key.
00820      */
00821 
00822     const PString & GetPendingPrefix() const { return pendingPrefix; }
00823     /* Get the pending prefix name in the configuration file section.
00824 
00825        @return
00826        String for the pending prefix.
00827      */
00828 
00829     void GetProductKey(
00830       PTEACypher::Key & productKey  // Variable to receive the product key.
00831     ) const;
00832     /* Get the pending prefix name in the configuration file section.
00833 
00834        @return
00835        String for the pending prefix.
00836      */
00837 
00838 
00839     enum ValidationState {
00840       Defaults,
00841       Pending,
00842       IsValid,
00843       Expired,
00844       Invalid
00845     };
00846     ValidationState GetValidation() const;
00847     /* Check the current values attached to the keys specified in the
00848        constructor against an encoded validation key.
00849 
00850        @return
00851        State of the validation keys.
00852      */
00853 
00854     BOOL ValidatePending();
00855     /* Validate a pending secured option list for the product. All secured
00856        keys with the <CODE>pendingPrefix</CODE> name will be checked against
00857        the value of the field <CODE>securityKey</CODE>. If they match then
00858        they are copied to the secured variables.
00859 
00860        @return
00861        TRUE if secure key values are valid.
00862      */
00863 
00864     void ResetPending();
00865     /* "Unvalidate" a security configuration going back to a pending state,
00866        usually used after an <CODE>Invalid</CODE> response was recieved from
00867        the <A>GetValidation()</A> function.
00868      */
00869 
00870 
00871   protected:
00872     PTEACypher::Key productKey;
00873     PStringArray    securedKeys;
00874     PString         securityKey;
00875     PString         expiryDateKey;
00876     PString         optionBitsKey;
00877     PString         pendingPrefix;
00878 };
00879 
00880 #endif // P_CONFIG_FILE
00881 
00882 #endif // _PCYPHER
00883 
00884 
00885 // End Of File ///////////////////////////////////////////////////////////////

Generated on Fri Sep 21 14:40:11 2007 for PWLib by  doxygen 1.5.3