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  * $Revision: 20385 $
00027  * $Author: rjongbloed $
00028  * $Date: 2008-06-04 10:40:38 +0000 (Wed, 04 Jun 2008) $
00029  */
00030 
00031 
00032 #ifndef _PCYPHER
00033 #define _PCYPHER
00034 
00035 #ifdef P_USE_PRAGMA
00036 #pragma interface
00037 #endif
00038 
00039 #ifndef _PTLIB_H
00040 #include <ptlib.h>
00041 #endif
00042 
00073 class PBase64 : public PObject
00074 {
00075   PCLASSINFO(PBase64, PObject);
00076 
00077   public:
00081     PBase64();
00082 
00083     void StartEncoding(
00084       PBoolean useCRLFs = PTrue  // Use CR, LF pairs in end of line characters.
00085     );
00086     // Begin a base 64 encoding operation, initialising the object instance.
00087 
00088     void ProcessEncoding(
00089       const PString & str      // String to be encoded
00090     );
00091     void ProcessEncoding(
00092       const char * cstr        // C String to be encoded
00093     );
00094     void ProcessEncoding(
00095       const PBYTEArray & data  // Data block to be encoded
00096     );
00097     void ProcessEncoding(
00098       const void * dataBlock,  // Pointer to data to be encoded
00099       PINDEX length            // Length of the data block.
00100     );
00101     // Incorporate the specified data into the base 64 encoding.
00102 
00108     PString GetEncodedString();
00109 
00117     PString CompleteEncoding();
00118 
00119 
00120     static PString Encode(
00121       const PString & str     // String to be encoded to Base64
00122     );
00123     static PString Encode(
00124       const char * cstr       // C String to be encoded to Base64
00125     );
00126     static PString Encode(
00127       const PBYTEArray & data // Data block to be encoded to Base64
00128     );
00129     static PString Encode(
00130       const void * dataBlock, // Pointer to data to be encoded to Base64
00131       PINDEX length           // Length of the data block.
00132     );
00133     // Encode the data in memory to Base 64 data returnin the string.
00134 
00135 
00136     void StartDecoding();
00137     // Begin a base 64 decoding operation, initialising the object instance.
00138 
00144     PBoolean ProcessDecoding(
00145       const PString & str      // String to be encoded
00146     );
00147     PBoolean ProcessDecoding(
00148       const char * cstr        // C String to be encoded
00149     );
00150 
00156     PBoolean GetDecodedData(
00157       void * dataBlock,    // Pointer to data to be decoded from base64
00158       PINDEX length        // Length of the data block.
00159     );
00160     PBYTEArray GetDecodedData();
00161 
00169     PBoolean IsDecodeOK() { return perfectDecode; }
00170 
00171 
00183     static PString Decode(
00184       const PString & str // Encoded base64 string to be decoded.
00185     );
00186     static PBoolean Decode(
00187       const PString & str, // Encoded base64 string to be decoded.
00188       PBYTEArray & data    // Converted binary data from base64.
00189     );
00190     static PBoolean Decode(
00191       const PString & str, // Encoded base64 string to be decoded.
00192       void * dataBlock,    // Pointer to data to be decoded from base64
00193       PINDEX length        // Length of the data block.
00194     );
00195 
00196 
00197 
00198   private:
00199     void OutputBase64(const BYTE * data);
00200 
00201     PString encodedString;
00202     PINDEX  encodeLength;
00203     BYTE    saveTriple[3];
00204     PINDEX  saveCount;
00205     PINDEX  nextLine;
00206     PBoolean    useCRLFs;
00207 
00208     PBoolean       perfectDecode;
00209     PINDEX     quadPosition;
00210     PBYTEArray decodedData;
00211     PINDEX     decodeSize;
00212 };
00213 
00214 class PMessageDigest : public PObject
00215 {
00216   PCLASSINFO(PMessageDigest, PObject)
00217 
00218   public:
00220     PMessageDigest();
00221 
00222     class Result {
00223       public:
00224         PINDEX GetSize() const          { return value.GetSize(); }
00225         const BYTE * GetPointer() const { return (const BYTE *)value; }
00226 
00227       private:
00228         PBYTEArray value;
00229         friend class PMessageDigest5;
00230         friend class PMessageDigestSHA1;
00231     };
00232 
00234     virtual void Start() = 0;
00235 
00236     virtual void Process(
00237       const void * dataBlock,  
00238       PINDEX length            
00239     );
00240 
00242     virtual void Process(
00243       const PString & str      
00244     );
00246     virtual void Process(
00247       const char * cstr        
00248     );
00250     virtual void Process(
00251       const PBYTEArray & data  
00252     );
00253 
00261     virtual PString CompleteDigest();
00262     virtual void CompleteDigest(
00263       Result & result   
00264     );
00265 
00266   protected:
00267     virtual void InternalProcess(
00268        const void * dataBlock,  
00269       PINDEX length            
00270     ) = 0;
00271 
00272     virtual void InternalCompleteDigest(
00273       Result & result   
00274     ) = 0;
00275 };
00276 
00277 
00283 class PMessageDigest5 : public PMessageDigest
00284 {
00285   PCLASSINFO(PMessageDigest5, PMessageDigest)
00286 
00287   public:
00289     PMessageDigest5();
00290 
00292     void Start();
00293 
00295     static PString Encode(
00296       const PString & str      
00297     );
00299     static void Encode(
00300       const PString & str,     
00301       Result & result            
00302     );
00304     static PString Encode(
00305       const char * cstr        
00306     );
00308     static void Encode(
00309       const char * cstr,       
00310       Result & result            
00311     );
00313     static PString Encode(
00314       const PBYTEArray & data  
00315     );
00317     static void Encode(
00318       const PBYTEArray & data, 
00319       Result & result            
00320     );
00322     static PString Encode(
00323       const void * dataBlock,  
00324       PINDEX length            
00325     );
00331     static void Encode(
00332       const void * dataBlock,  
00333       PINDEX length,           
00334       Result & result            
00335     );
00336 
00337     // backwards compatibility functions
00338     class Code {
00339       private:
00340         PUInt32l value[4];
00341         friend class PMessageDigest5;
00342     };
00343 
00345     static void Encode(
00346       const PString & str,     
00347       Code & result            
00348     );
00350     static void Encode(
00351       const char * cstr,       
00352       Code & result            
00353     );
00355     static void Encode(
00356       const PBYTEArray & data, 
00357       Code & result            
00358     );
00364     static void Encode(
00365       const void * dataBlock,  
00366       PINDEX length,           
00367       Code & result            
00368     );
00369     virtual void Complete(
00370       Code & result   
00371     );
00372     virtual PString Complete();
00373 
00374   protected:
00375     virtual void InternalProcess(
00376        const void * dataBlock,  
00377       PINDEX length            
00378     );
00379 
00380     virtual void InternalCompleteDigest(
00381       Result & result   
00382     );
00383 
00384   private:
00385     void Transform(const BYTE * block);
00386 
00388     BYTE buffer[64];
00390     DWORD state[4];
00392     PUInt64 count;
00393 };
00394 
00395 #if P_SSL
00396 
00401 class PMessageDigestSHA1 : public PMessageDigest
00402 {
00403   PCLASSINFO(PMessageDigestSHA1, PMessageDigest)
00404 
00405   public:
00407     PMessageDigestSHA1();
00408     ~PMessageDigestSHA1();
00409 
00411     void Start();
00412 
00414     static PString Encode(
00415       const PString & str      
00416     );
00418     static void Encode(
00419       const PString & str,     
00420       Result & result            
00421     );
00423     static PString Encode(
00424       const char * cstr        
00425     );
00427     static void Encode(
00428       const char * cstr,       
00429       Result & result            
00430     );
00432     static PString Encode(
00433       const PBYTEArray & data  
00434     );
00436     static void Encode(
00437       const PBYTEArray & data, 
00438       Result & result            
00439     );
00441     static PString Encode(
00442       const void * dataBlock,  
00443       PINDEX length            
00444     );
00450     static void Encode(
00451       const void * dataBlock,  
00452       PINDEX length,           
00453       Result & result            
00454     );
00455 
00456   protected:
00457     virtual void InternalProcess(
00458        const void * dataBlock,  
00459       PINDEX length            
00460     );
00461 
00462     void InternalCompleteDigest(
00463       Result & result   
00464     );
00465 
00466   private:
00467     void * shaContext;
00468 };
00469 
00470 #endif
00471 
00475 class PCypher : public PObject
00476 {
00477   PCLASSINFO(PCypher, PObject)
00478 
00479   public:
00481     enum BlockChainMode {
00482       ElectronicCodebook,
00483         ECB = ElectronicCodebook,
00484       CypherBlockChaining,
00485         CBC = CypherBlockChaining,
00486       OutputFeedback,
00487         OFB = OutputFeedback,
00488       CypherFeedback,
00489         CFB = CypherFeedback,
00490       NumBlockChainModes
00491     };
00492 
00493   // New functions for class
00495     PString Encode(
00496       const PString & str       
00497     );
00499     PString Encode(
00500       const PBYTEArray & clear  
00501     );
00503     PString Encode(
00504       const void * data,        
00505       PINDEX length             
00506     );
00508     void Encode(
00509       const PBYTEArray & clear, 
00510       PBYTEArray & coded        
00511     );
00527     void Encode(
00528       const void * data,        // Clear text binary data to be encoded.
00529       PINDEX length,            // Number of bytes of data to be encoded.
00530       PBYTEArray & coded        // Encoded data.
00531     );
00532 
00534     PString Decode(
00535       const PString & cypher   
00536     );
00538     PBoolean Decode(
00539       const PString & cypher,  
00540       PString & clear          
00541     );
00543     PBoolean Decode(
00544       const PString & cypher,  
00545       PBYTEArray & clear       
00546     );
00548     PINDEX Decode(
00549       const PString & cypher,  
00550       void * data,             
00551       PINDEX length            
00552     );
00554     PINDEX Decode(
00555       const PBYTEArray & coded, 
00556       void * data,              
00557       PINDEX length             
00558     );
00574     PBoolean Decode(
00575       const PBYTEArray & coded, 
00576       PBYTEArray & clear       
00577     );
00578 
00579 
00580   protected:
00584     PCypher(
00585       PINDEX blockSize,          
00586       BlockChainMode chainMode   
00587     );
00588     PCypher(
00589       const void * keyData,    
00590       PINDEX keyLength,        
00591       PINDEX blockSize,        
00592       BlockChainMode chainMode 
00593     );
00594 
00595 
00597     virtual void Initialise(
00598       PBoolean encoding   
00599     ) = 0;
00600 
00602     virtual void EncodeBlock(
00603       const void * in,    
00604       void * out          
00605     ) = 0;
00606 
00607 
00609     virtual void DecodeBlock(
00610       const void * in,  
00611       void * out        
00612     ) = 0;
00613 
00614 
00616     PBYTEArray key;
00618     PINDEX blockSize;
00620     BlockChainMode chainMode;
00621 };
00622 
00623 
00631 class PTEACypher : public PCypher
00632 {
00633   PCLASSINFO(PTEACypher, PCypher)
00634 
00635   public:
00636     struct Key {
00637       BYTE value[16];
00638     };
00639 
00644     PTEACypher(
00645       BlockChainMode chainMode = ElectronicCodebook   
00646     );
00647     PTEACypher(
00648       const Key & keyData,     
00649       BlockChainMode chainMode = ElectronicCodebook   
00650     );
00651 
00652 
00654     void SetKey(
00655       const Key & newKey    
00656     );
00657 
00659     void GetKey(
00660       Key & newKey    
00661     ) const;
00662 
00663 
00665     static void GenerateKey(
00666       Key & newKey    
00667     );
00668 
00669 
00670   protected:
00672     virtual void Initialise(
00673       PBoolean encoding   
00674     );
00675 
00677     virtual void EncodeBlock(
00678       const void * in,  
00679       void * out        
00680     );
00681 
00683     virtual void DecodeBlock(
00684       const void * in,  
00685       void * out        
00686     );
00687 
00688   private:
00689     DWORD k0, k1, k2, k3;
00690 };
00691 
00692 
00693 #ifdef P_CONFIG_FILE
00694 
00695 class PSecureConfig : public PConfig
00696 {
00697   PCLASSINFO(PSecureConfig, PConfig)
00698 /* This class defines a set of configuration keys which may be secured by an
00699    encrypted hash function. Thus values contained in keys specified by this
00700    class cannot be changed without invalidating the hash function.
00701  */
00702 
00703   public:
00704     PSecureConfig(
00705       const PTEACypher::Key & productKey,    // Key to decrypt validation code.
00706       const PStringArray    & securedKeys,   // List of secured keys.
00707       Source src = Application        // Standard source for the configuration.
00708     );
00709     PSecureConfig(
00710       const PTEACypher::Key & productKey,   // Key to decrypt validation code.
00711       const char * const * securedKeyArray, // List of secured keys.
00712       PINDEX count,                         // Number of secured keys in list.
00713       Source src = Application        // Standard source for the configuration.
00714     );
00715     /* Create a secured configuration. The default section for the
00716        configuration keys is "Secured Options", the default security key is
00717        "Validation" and the defualt prefix string is "Pending:".
00718 
00719        The user can descend from this class and change any of the member
00720        variable for the names of keys or the configuration file section.
00721      */
00722 
00723 
00724   // New functions for class
00725     const PStringArray & GetSecuredKeys() const { return securedKeys; }
00726     /* Get the list of secured keys in the configuration file section.
00727 
00728        @return
00729        Array of  strings for the secured keys.
00730      */
00731 
00732     const PString & GetSecurityKey() const { return securityKey; }
00733     /* Get the security keys name in the configuration file section.
00734 
00735        @return
00736        String for the security values key.
00737      */
00738 
00739     const PString & GetExpiryDateKey() const { return expiryDateKey; }
00740     /* Get the expiry date keys name in the configuration file section.
00741 
00742        @return
00743        String for the expiry date values key.
00744      */
00745 
00746     const PString & GetOptionBitsKey() const { return optionBitsKey; }
00747     /* Get the Option Bits keys name in the configuration file section.
00748 
00749        @return
00750        String for the Option Bits values key.
00751      */
00752 
00753     const PString & GetPendingPrefix() const { return pendingPrefix; }
00754     /* Get the pending prefix name in the configuration file section.
00755 
00756        @return
00757        String for the pending prefix.
00758      */
00759 
00760     void GetProductKey(
00761       PTEACypher::Key & productKey  // Variable to receive the product key.
00762     ) const;
00763     /* Get the pending prefix name in the configuration file section.
00764 
00765        @return
00766        String for the pending prefix.
00767      */
00768 
00769 
00770     enum ValidationState {
00771       Defaults,
00772       Pending,
00773       IsValid,
00774       Expired,
00775       Invalid
00776     };
00777     ValidationState GetValidation() const;
00778     /* Check the current values attached to the keys specified in the
00779        constructor against an encoded validation key.
00780 
00781        @return
00782        State of the validation keys.
00783      */
00784 
00785     PBoolean ValidatePending();
00786     /* Validate a pending secured option list for the product. All secured
00787        keys with the <CODE>pendingPrefix</CODE> name will be checked against
00788        the value of the field <CODE>securityKey</CODE>. If they match then
00789        they are copied to the secured variables.
00790 
00791        @return
00792        PTrue if secure key values are valid.
00793      */
00794 
00795     void ResetPending();
00796     /* "Unvalidate" a security configuration going back to a pending state,
00797        usually used after an <CODE>Invalid</CODE> response was recieved from
00798        the <A>GetValidation()</A> function.
00799      */
00800 
00801 
00802   protected:
00803     PTEACypher::Key productKey;
00804     PStringArray    securedKeys;
00805     PString         securityKey;
00806     PString         expiryDateKey;
00807     PString         optionBitsKey;
00808     PString         pendingPrefix;
00809 };
00810 
00811 #endif // P_CONFIG_FILE
00812 
00813 #endif // _PCYPHER
00814 
00815 
00816 // End Of File ///////////////////////////////////////////////////////////////

Generated on Mon Sep 15 01:21:34 2008 for PTLib by  doxygen 1.5.1