Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

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.21  2004/11/11 07:34:50  csoutheren
00028  * Added #include <ptlib.h>
00029  *
00030  * Revision 1.20  2004/03/23 05:59:17  csoutheren
00031  * Moved the Base64 routines into cypher.cxx, which is a more sensible
00032  * place and reduces the inclusion of unrelated code
00033  *
00034  * Revision 1.19  2004/02/04 02:31:34  csoutheren
00035  * Remove SHA-1 functions when OpenSSL is disabled
00036  *
00037  * Revision 1.18  2003/04/17 03:34:07  craigs
00038  * Fixed problem with delete'ing a void *
00039  *
00040  * Revision 1.17  2003/04/10 07:02:38  craigs
00041  * Fixed link problem in MD5 class
00042  *
00043  * Revision 1.16  2003/04/10 06:16:30  craigs
00044  * Added SHA-1 digest
00045  *
00046  * Revision 1.15  2002/11/06 22:47:23  robertj
00047  * Fixed header comment (copyright etc)
00048  *
00049  * Revision 1.14  2002/09/16 01:08:59  robertj
00050  * Added #define so can select if #pragma interface/implementation is used on
00051  *   platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
00052  *
00053  * Revision 1.13  2001/09/10 00:28:21  robertj
00054  * Fixed extra CR in comments.
00055  *
00056  * Revision 1.12  1999/03/09 08:01:46  robertj
00057  * Changed comments for doc++ support (more to come).
00058  *
00059  * Revision 1.11  1999/02/16 08:07:10  robertj
00060  * MSVC 6.0 compatibility changes.
00061  *
00062  * Revision 1.10  1998/09/23 06:19:24  robertj
00063  * Added open source copyright license.
00064  *
00065  * Revision 1.9  1997/10/10 10:44:01  robertj
00066  * Fixed bug in password encryption, missing string terminator.
00067  *
00068  * Revision 1.8  1996/11/16 10:50:24  robertj
00069  * Fixed bug in registration order form showing incorrect check code when have key.
00070  *
00071  * Revision 1.7  1996/07/15 10:29:38  robertj
00072  * Changed memory block cypher conversion functions to be void *.
00073  * Changed key types to be structures rather than arrays to avoid pinter/reference confusion by compilers.
00074  *
00075  * Revision 1.6  1996/03/17 05:47:00  robertj
00076  * Changed secured config to allow for expiry dates.
00077  *
00078  * Revision 1.5  1996/03/16 04:36:43  robertj
00079  * Redesign of secure config to accommodate expiry dates and option values passed in security key code.
00080  *
00081  * Revision 1.4  1996/02/25 02:52:46  robertj
00082  * Further secure config development.
00083  *
00084  * Revision 1.3  1996/01/28 14:16:11  robertj
00085  * Further implementation of secure config.
00086  *
00087  * Revision 1.2  1996/01/28 02:41:00  robertj
00088  * Removal of MemoryPointer classes as usage didn't work for GNU.
00089  * Added the secure configuration mechanism for protecting applications.
00090  *
00091  * Revision 1.1  1996/01/23 13:04:20  robertj
00092  * Initial revision
00093  *
00094  */
00095 
00096 
00097 #ifndef _PCYPHER
00098 #define _PCYPHER
00099 
00100 #ifdef P_USE_PRAGMA
00101 #pragma interface
00102 #endif
00103 
00104 #include <ptlib.h>
00105 
00136 class PBase64 : public PObject
00137 {
00138   PCLASSINFO(PBase64, PObject);
00139 
00140   public:
00144     PBase64();
00145 
00146     void StartEncoding(
00147       BOOL useCRLFs = TRUE  // Use CR, LF pairs in end of line characters.
00148     );
00149     // Begin a base 64 encoding operation, initialising the object instance.
00150 
00151     void ProcessEncoding(
00152       const PString & str      // String to be encoded
00153     );
00154     void ProcessEncoding(
00155       const char * cstr        // C String to be encoded
00156     );
00157     void ProcessEncoding(
00158       const PBYTEArray & data  // Data block to be encoded
00159     );
00160     void ProcessEncoding(
00161       const void * dataBlock,  // Pointer to data to be encoded
00162       PINDEX length            // Length of the data block.
00163     );
00164     // Incorporate the specified data into the base 64 encoding.
00165 
00171     PString GetEncodedString();
00172 
00180     PString CompleteEncoding();
00181 
00182 
00183     static PString Encode(
00184       const PString & str     // String to be encoded to Base64
00185     );
00186     static PString Encode(
00187       const char * cstr       // C String to be encoded to Base64
00188     );
00189     static PString Encode(
00190       const PBYTEArray & data // Data block to be encoded to Base64
00191     );
00192     static PString Encode(
00193       const void * dataBlock, // Pointer to data to be encoded to Base64
00194       PINDEX length           // Length of the data block.
00195     );
00196     // Encode the data in memory to Base 64 data returnin the string.
00197 
00198 
00199     void StartDecoding();
00200     // Begin a base 64 decoding operation, initialising the object instance.
00201 
00207     BOOL ProcessDecoding(
00208       const PString & str      // String to be encoded
00209     );
00210     BOOL ProcessDecoding(
00211       const char * cstr        // C String to be encoded
00212     );
00213 
00219     BOOL GetDecodedData(
00220       void * dataBlock,    // Pointer to data to be decoded from base64
00221       PINDEX length        // Length of the data block.
00222     );
00223     PBYTEArray GetDecodedData();
00224 
00232     BOOL IsDecodeOK() { return perfectDecode; }
00233 
00234 
00246     static PString Decode(
00247       const PString & str // Encoded base64 string to be decoded.
00248     );
00249     static BOOL Decode(
00250       const PString & str, // Encoded base64 string to be decoded.
00251       PBYTEArray & data    // Converted binary data from base64.
00252     );
00253     static BOOL Decode(
00254       const PString & str, // Encoded base64 string to be decoded.
00255       void * dataBlock,    // Pointer to data to be decoded from base64
00256       PINDEX length        // Length of the data block.
00257     );
00258 
00259 
00260 
00261   private:
00262     void OutputBase64(const BYTE * data);
00263 
00264     PString encodedString;
00265     PINDEX  encodeLength;
00266     BYTE    saveTriple[3];
00267     PINDEX  saveCount;
00268     PINDEX  nextLine;
00269     BOOL    useCRLFs;
00270 
00271     BOOL       perfectDecode;
00272     PINDEX     quadPosition;
00273     PBYTEArray decodedData;
00274     PINDEX     decodeSize;
00275 };
00276 
00277 class PMessageDigest : public PObject
00278 {
00279   PCLASSINFO(PMessageDigest, PObject)
00280 
00281   public:
00283     PMessageDigest();
00284 
00285     class Result {
00286       public:
00287         PINDEX GetSize() const          { return value.GetSize(); }
00288         const BYTE * GetPointer() const { return (const BYTE *)value; }
00289 
00290       private:
00291         PBYTEArray value;
00292         friend class PMessageDigest5;
00293         friend class PMessageDigestSHA1;
00294     };
00295 
00297     virtual void Start() = 0;
00298 
00299     virtual void Process(
00300       const void * dataBlock,  
00301       PINDEX length            
00302     );
00303 
00305     virtual void Process(
00306       const PString & str      
00307     );
00309     virtual void Process(
00310       const char * cstr        
00311     );
00313     virtual void Process(
00314       const PBYTEArray & data  
00315     );
00316 
00324     virtual PString CompleteDigest();
00325     virtual void CompleteDigest(
00326       Result & result   
00327     );
00328 
00329   protected:
00330     virtual void InternalProcess(
00331        const void * dataBlock,  
00332       PINDEX length            
00333     ) = 0;
00334 
00335     virtual void InternalCompleteDigest(
00336       Result & result   
00337     ) = 0;
00338 };
00339 
00340 
00346 class PMessageDigest5 : public PMessageDigest
00347 {
00348   PCLASSINFO(PMessageDigest5, PMessageDigest)
00349 
00350   public:
00352     PMessageDigest5();
00353 
00355     void Start();
00356 
00358     static PString Encode(
00359       const PString & str      
00360     );
00362     static void Encode(
00363       const PString & str,     
00364       Result & result            
00365     );
00367     static PString Encode(
00368       const char * cstr        
00369     );
00371     static void Encode(
00372       const char * cstr,       
00373       Result & result            
00374     );
00376     static PString Encode(
00377       const PBYTEArray & data  
00378     );
00380     static void Encode(
00381       const PBYTEArray & data, 
00382       Result & result            
00383     );
00385     static PString Encode(
00386       const void * dataBlock,  
00387       PINDEX length            
00388     );
00394     static void Encode(
00395       const void * dataBlock,  
00396       PINDEX length,           
00397       Result & result            
00398     );
00399 
00400     // backwards compatibility functions
00401     class Code {
00402       private:
00403         PUInt32l value[4];
00404         friend class PMessageDigest5;
00405     };
00406 
00408     static void Encode(
00409       const PString & str,     
00410       Code & result            
00411     );
00413     static void Encode(
00414       const char * cstr,       
00415       Code & result            
00416     );
00418     static void Encode(
00419       const PBYTEArray & data, 
00420       Code & result            
00421     );
00427     static void Encode(
00428       const void * dataBlock,  
00429       PINDEX length,           
00430       Code & result            
00431     );
00432     virtual void Complete(
00433       Code & result   
00434     );
00435     virtual PString Complete();
00436 
00437   protected:
00438     virtual void InternalProcess(
00439        const void * dataBlock,  
00440       PINDEX length            
00441     );
00442 
00443     virtual void InternalCompleteDigest(
00444       Result & result   
00445     );
00446 
00447   private:
00448     void Transform(const BYTE * block);
00449 
00451     BYTE buffer[64];
00453     DWORD state[4];
00455     PUInt64 count;
00456 };
00457 
00458 #if P_SSL
00459 
00464 class PMessageDigestSHA1 : public PMessageDigest
00465 {
00466   PCLASSINFO(PMessageDigestSHA1, PMessageDigest)
00467 
00468   public:
00470     PMessageDigestSHA1();
00471     ~PMessageDigestSHA1();
00472 
00474     void Start();
00475 
00477     static PString Encode(
00478       const PString & str      
00479     );
00481     static void Encode(
00482       const PString & str,     
00483       Result & result            
00484     );
00486     static PString Encode(
00487       const char * cstr        
00488     );
00490     static void Encode(
00491       const char * cstr,       
00492       Result & result            
00493     );
00495     static PString Encode(
00496       const PBYTEArray & data  
00497     );
00499     static void Encode(
00500       const PBYTEArray & data, 
00501       Result & result            
00502     );
00504     static PString Encode(
00505       const void * dataBlock,  
00506       PINDEX length            
00507     );
00513     static void Encode(
00514       const void * dataBlock,  
00515       PINDEX length,           
00516       Result & result            
00517     );
00518 
00519   protected:
00520     virtual void InternalProcess(
00521        const void * dataBlock,  
00522       PINDEX length            
00523     );
00524 
00525     void InternalCompleteDigest(
00526       Result & result   
00527     );
00528 
00529   private:
00530     void * shaContext;
00531 };
00532 
00533 #endif
00534 
00538 class PCypher : public PObject
00539 {
00540   PCLASSINFO(PCypher, PObject)
00541 
00542   public:
00544     enum BlockChainMode {
00545       ElectronicCodebook,
00546         ECB = ElectronicCodebook,
00547       CypherBlockChaining,
00548         CBC = CypherBlockChaining,
00549       OutputFeedback,
00550         OFB = OutputFeedback,
00551       CypherFeedback,
00552         CFB = CypherFeedback,
00553       NumBlockChainModes
00554     };
00555 
00556   // New functions for class
00558     PString Encode(
00559       const PString & str       
00560     );
00562     PString Encode(
00563       const PBYTEArray & clear  
00564     );
00566     PString Encode(
00567       const void * data,        
00568       PINDEX length             
00569     );
00571     void Encode(
00572       const PBYTEArray & clear, 
00573       PBYTEArray & coded        
00574     );
00590     void Encode(
00591       const void * data,        // Clear text binary data to be encoded.
00592       PINDEX length,            // Number of bytes of data to be encoded.
00593       PBYTEArray & coded        // Encoded data.
00594     );
00595 
00597     PString Decode(
00598       const PString & cypher   
00599     );
00601     BOOL Decode(
00602       const PString & cypher,  
00603       PString & clear          
00604     );
00606     BOOL Decode(
00607       const PString & cypher,  
00608       PBYTEArray & clear       
00609     );
00611     PINDEX Decode(
00612       const PString & cypher,  
00613       void * data,             
00614       PINDEX length            
00615     );
00617     PINDEX Decode(
00618       const PBYTEArray & coded, 
00619       void * data,              
00620       PINDEX length             
00621     );
00637     BOOL Decode(
00638       const PBYTEArray & coded, 
00639       PBYTEArray & clear       
00640     );
00641 
00642 
00643   protected:
00647     PCypher(
00648       PINDEX blockSize,          
00649       BlockChainMode chainMode   
00650     );
00651     PCypher(
00652       const void * keyData,    
00653       PINDEX keyLength,        
00654       PINDEX blockSize,        
00655       BlockChainMode chainMode 
00656     );
00657 
00658 
00660     virtual void Initialise(
00661       BOOL encoding   
00662     ) = 0;
00663 
00665     virtual void EncodeBlock(
00666       const void * in,    
00667       void * out          
00668     ) = 0;
00669 
00670 
00672     virtual void DecodeBlock(
00673       const void * in,  
00674       void * out        
00675     ) = 0;
00676 
00677 
00679     PBYTEArray key;
00681     PINDEX blockSize;
00683     BlockChainMode chainMode;
00684 };
00685 
00686 
00694 class PTEACypher : public PCypher
00695 {
00696   PCLASSINFO(PTEACypher, PCypher)
00697 
00698   public:
00699     struct Key {
00700       BYTE value[16];
00701     };
00702 
00707     PTEACypher(
00708       BlockChainMode chainMode = ElectronicCodebook   
00709     );
00710     PTEACypher(
00711       const Key & keyData,     
00712       BlockChainMode chainMode = ElectronicCodebook   
00713     );
00714 
00715 
00717     void SetKey(
00718       const Key & newKey    
00719     );
00720 
00722     void GetKey(
00723       Key & newKey    
00724     ) const;
00725 
00726 
00728     static void GenerateKey(
00729       Key & newKey    
00730     );
00731 
00732 
00733   protected:
00735     virtual void Initialise(
00736       BOOL encoding   
00737     );
00738 
00740     virtual void EncodeBlock(
00741       const void * in,  
00742       void * out        
00743     );
00744 
00746     virtual void DecodeBlock(
00747       const void * in,  
00748       void * out        
00749     );
00750 
00751   private:
00752     DWORD k0, k1, k2, k3;
00753 };
00754 
00755 
00756 
00757 class PSecureConfig : public PConfig
00758 {
00759   PCLASSINFO(PSecureConfig, PConfig)
00760 /* This class defines a set of configuration keys which may be secured by an
00761    encrypted hash function. Thus values contained in keys specified by this
00762    class cannot be changed without invalidating the hash function.
00763  */
00764 
00765   public:
00766     PSecureConfig(
00767       const PTEACypher::Key & productKey,    // Key to decrypt validation code.
00768       const PStringArray    & securedKeys,   // List of secured keys.
00769       Source src = Application        // Standard source for the configuration.
00770     );
00771     PSecureConfig(
00772       const PTEACypher::Key & productKey,   // Key to decrypt validation code.
00773       const char * const * securedKeyArray, // List of secured keys.
00774       PINDEX count,                         // Number of secured keys in list.
00775       Source src = Application        // Standard source for the configuration.
00776     );
00777     /* Create a secured configuration. The default section for the
00778        configuration keys is "Secured Options", the default security key is
00779        "Validation" and the defualt prefix string is "Pending:".
00780 
00781        The user can descend from this class and change any of the member
00782        variable for the names of keys or the configuration file section.
00783      */
00784 
00785 
00786   // New functions for class
00787     const PStringArray & GetSecuredKeys() const { return securedKeys; }
00788     /* Get the list of secured keys in the configuration file section.
00789 
00790        @return
00791        Array of  strings for the secured keys.
00792      */
00793 
00794     const PString & GetSecurityKey() const { return securityKey; }
00795     /* Get the security keys name in the configuration file section.
00796 
00797        @return
00798        String for the security values key.
00799      */
00800 
00801     const PString & GetExpiryDateKey() const { return expiryDateKey; }
00802     /* Get the expiry date keys name in the configuration file section.
00803 
00804        @return
00805        String for the expiry date values key.
00806      */
00807 
00808     const PString & GetOptionBitsKey() const { return optionBitsKey; }
00809     /* Get the Option Bits keys name in the configuration file section.
00810 
00811        @return
00812        String for the Option Bits values key.
00813      */
00814 
00815     const PString & GetPendingPrefix() const { return pendingPrefix; }
00816     /* Get the pending prefix name in the configuration file section.
00817 
00818        @return
00819        String for the pending prefix.
00820      */
00821 
00822     void GetProductKey(
00823       PTEACypher::Key & productKey  // Variable to receive the product key.
00824     ) const;
00825     /* Get the pending prefix name in the configuration file section.
00826 
00827        @return
00828        String for the pending prefix.
00829      */
00830 
00831 
00832     enum ValidationState {
00833       Defaults,
00834       Pending,
00835       IsValid,
00836       Expired,
00837       Invalid
00838     };
00839     ValidationState GetValidation() const;
00840     /* Check the current values attached to the keys specified in the
00841        constructor against an encoded validation key.
00842 
00843        @return
00844        State of the validation keys.
00845      */
00846 
00847     BOOL ValidatePending();
00848     /* Validate a pending secured option list for the product. All secured
00849        keys with the <CODE>pendingPrefix</CODE> name will be checked against
00850        the value of the field <CODE>securityKey</CODE>. If they match then
00851        they are copied to the secured variables.
00852 
00853        @return
00854        TRUE if secure key values are valid.
00855      */
00856 
00857     void ResetPending();
00858     /* "Unvalidate" a security configuration going back to a pending state,
00859        usually used after an <CODE>Invalid</CODE> response was recieved from
00860        the <A>GetValidation()</A> function.
00861      */
00862 
00863 
00864   protected:
00865     PTEACypher::Key productKey;
00866     PStringArray    securedKeys;
00867     PString         securityKey;
00868     PString         expiryDateKey;
00869     PString         optionBitsKey;
00870     PString         pendingPrefix;
00871 };
00872 
00873 
00874 #endif // _PCYPHER
00875 
00876 
00877 // End Of File ///////////////////////////////////////////////////////////////

Generated on Mon Feb 21 20:43:08 2005 for PWLib by  doxygen 1.4.1