PTLib  Version 2.10.4
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: 24983 $
00027  * $Author: rjongbloed $
00028  * $Date: 2010-12-22 23:23:23 -0600 (Wed, 22 Dec 2010) $
00029  */
00030 
00031 
00032 #ifndef PTLIB_CYPHER_H
00033 #define PTLIB_CYPHER_H
00034 
00035 #ifdef P_USE_PRAGMA
00036 #pragma interface
00037 #endif
00038 
00039 
00070 class PBase64 : public PObject
00071 {
00072   PCLASSINFO(PBase64, PObject);
00073 
00074   public:
00078     PBase64();
00079 
00080     void StartEncoding(
00081       bool useCRLFs = true  
00082     );
00083     void StartEncoding(
00084       const char * endOfLine  
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 
00116     PString CompleteEncoding();
00117 
00118 
00119     static PString Encode(
00120       const PString & str,          
00121       const char * endOfLine = "\n" 
00122     );
00123     static PString Encode(
00124       const char * cstr,            
00125       const char * endOfLine = "\n" 
00126     );
00127     static PString Encode(
00128       const PBYTEArray & data,      
00129       const char * endOfLine = "\n" 
00130     );
00131     static PString Encode(
00132       const void * dataBlock,       
00133       PINDEX length,                
00134       const char * endOfLine = "\n" 
00135     );
00136     // Encode the data in memory to Base 64 data returnin the string.
00137 
00138 
00139     void StartDecoding();
00140     // Begin a base 64 decoding operation, initialising the object instance.
00141 
00147     PBoolean ProcessDecoding(
00148       const PString & str      // String to be encoded
00149     );
00150     PBoolean ProcessDecoding(
00151       const char * cstr        // C String to be encoded
00152     );
00153 
00159     PBoolean GetDecodedData(
00160       void * dataBlock,    // Pointer to data to be decoded from base64
00161       PINDEX length        // Length of the data block.
00162     );
00163     PBYTEArray GetDecodedData();
00164 
00172     PBoolean IsDecodeOK() { return perfectDecode; }
00173 
00174 
00186     static PString Decode(
00187       const PString & str // Encoded base64 string to be decoded.
00188     );
00189     static PBoolean Decode(
00190       const PString & str, // Encoded base64 string to be decoded.
00191       PBYTEArray & data    // Converted binary data from base64.
00192     );
00193     static PBoolean Decode(
00194       const PString & str, // Encoded base64 string to be decoded.
00195       void * dataBlock,    // Pointer to data to be decoded from base64
00196       PINDEX length        // Length of the data block.
00197     );
00198 
00199 
00200 
00201   private:
00202     void OutputBase64(const BYTE * data);
00203 
00204     PString encodedString;
00205     PINDEX  encodeLength;
00206     BYTE    saveTriple[3];
00207     PINDEX  saveCount;
00208     PINDEX  nextLine;
00209     PString endOfLine;
00210 
00211     PBoolean       perfectDecode;
00212     PINDEX     quadPosition;
00213     PBYTEArray decodedData;
00214     PINDEX     decodeSize;
00215 };
00216 
00217 class PMessageDigest : public PObject
00218 {
00219   PCLASSINFO(PMessageDigest, PObject)
00220 
00221   public:
00223     PMessageDigest();
00224 
00225     class Result {
00226       public:
00227         PINDEX GetSize() const          { return value.GetSize(); }
00228         const BYTE * GetPointer() const { return (const BYTE *)value; }
00229 
00230       private:
00231         PBYTEArray value;
00232         friend class PMessageDigest5;
00233         friend class PMessageDigestSHA1;
00234     };
00235 
00237     virtual void Start() = 0;
00238 
00239     virtual void Process(
00240       const void * dataBlock,  
00241       PINDEX length            
00242     );
00243 
00245     virtual void Process(
00246       const PString & str      
00247     );
00249     virtual void Process(
00250       const char * cstr        
00251     );
00253     virtual void Process(
00254       const PBYTEArray & data  
00255     );
00256 
00264     virtual PString CompleteDigest();
00265     virtual void CompleteDigest(
00266       Result & result   
00267     );
00268 
00269   protected:
00270     virtual void InternalProcess(
00271        const void * dataBlock,  
00272       PINDEX length            
00273     ) = 0;
00274 
00275     virtual void InternalCompleteDigest(
00276       Result & result   
00277     ) = 0;
00278 };
00279 
00280 
00286 class PMessageDigest5 : public PMessageDigest
00287 {
00288   PCLASSINFO(PMessageDigest5, PMessageDigest)
00289 
00290   public:
00292     PMessageDigest5();
00293 
00295     void Start();
00296 
00298     static PString Encode(
00299       const PString & str      
00300     );
00302     static void Encode(
00303       const PString & str,     
00304       Result & result            
00305     );
00307     static PString Encode(
00308       const char * cstr        
00309     );
00311     static void Encode(
00312       const char * cstr,       
00313       Result & result            
00314     );
00316     static PString Encode(
00317       const PBYTEArray & data  
00318     );
00320     static void Encode(
00321       const PBYTEArray & data, 
00322       Result & result            
00323     );
00325     static PString Encode(
00326       const void * dataBlock,  
00327       PINDEX length            
00328     );
00334     static void Encode(
00335       const void * dataBlock,  
00336       PINDEX length,           
00337       Result & result            
00338     );
00339 
00340     // backwards compatibility functions
00341     class Code {
00342       private:
00343         PUInt32l value[4];
00344         friend class PMessageDigest5;
00345     };
00346 
00348     static void Encode(
00349       const PString & str,     
00350       Code & result            
00351     );
00353     static void Encode(
00354       const char * cstr,       
00355       Code & result            
00356     );
00358     static void Encode(
00359       const PBYTEArray & data, 
00360       Code & result            
00361     );
00367     static void Encode(
00368       const void * dataBlock,  
00369       PINDEX length,           
00370       Code & result            
00371     );
00372     virtual void Complete(
00373       Code & result   
00374     );
00375     virtual PString Complete();
00376 
00377   protected:
00378     virtual void InternalProcess(
00379        const void * dataBlock,  
00380       PINDEX length            
00381     );
00382 
00383     virtual void InternalCompleteDigest(
00384       Result & result   
00385     );
00386 
00387   private:
00388     void Transform(const BYTE * block);
00389 
00391     BYTE buffer[64];
00393     DWORD state[4];
00395     PUInt64 count;
00396 };
00397 
00398 #if P_SSL
00399 
00404 class PMessageDigestSHA1 : public PMessageDigest
00405 {
00406   PCLASSINFO(PMessageDigestSHA1, PMessageDigest)
00407 
00408   public:
00410     PMessageDigestSHA1();
00411     ~PMessageDigestSHA1();
00412 
00414     void Start();
00415 
00417     static PString Encode(
00418       const PString & str      
00419     );
00421     static void Encode(
00422       const PString & str,     
00423       Result & result            
00424     );
00426     static PString Encode(
00427       const char * cstr        
00428     );
00430     static void Encode(
00431       const char * cstr,       
00432       Result & result            
00433     );
00435     static PString Encode(
00436       const PBYTEArray & data  
00437     );
00439     static void Encode(
00440       const PBYTEArray & data, 
00441       Result & result            
00442     );
00444     static PString Encode(
00445       const void * dataBlock,  
00446       PINDEX length            
00447     );
00453     static void Encode(
00454       const void * dataBlock,  
00455       PINDEX length,           
00456       Result & result            
00457     );
00458 
00459   protected:
00460     virtual void InternalProcess(
00461        const void * dataBlock,  
00462       PINDEX length            
00463     );
00464 
00465     void InternalCompleteDigest(
00466       Result & result   
00467     );
00468 
00469   private:
00470     void * shaContext;
00471 };
00472 
00473 #endif
00474 
00478 class PCypher : public PObject
00479 {
00480   PCLASSINFO(PCypher, PObject)
00481 
00482   public:
00484     enum BlockChainMode {
00485       ElectronicCodebook,
00486         ECB = ElectronicCodebook,
00487       CypherBlockChaining,
00488         CBC = CypherBlockChaining,
00489       OutputFeedback,
00490         OFB = OutputFeedback,
00491       CypherFeedback,
00492         CFB = CypherFeedback,
00493       NumBlockChainModes
00494     };
00495 
00496   // New functions for class
00498     PString Encode(
00499       const PString & str       
00500     );
00502     PString Encode(
00503       const PBYTEArray & clear  
00504     );
00506     PString Encode(
00507       const void * data,        
00508       PINDEX length             
00509     );
00511     void Encode(
00512       const PBYTEArray & clear, 
00513       PBYTEArray & coded        
00514     );
00530     void Encode(
00531       const void * data,        // Clear text binary data to be encoded.
00532       PINDEX length,            // Number of bytes of data to be encoded.
00533       PBYTEArray & coded        // Encoded data.
00534     );
00535 
00537     PString Decode(
00538       const PString & cypher   
00539     );
00541     PBoolean Decode(
00542       const PString & cypher,  
00543       PString & clear          
00544     );
00546     PBoolean Decode(
00547       const PString & cypher,  
00548       PBYTEArray & clear       
00549     );
00551     PINDEX Decode(
00552       const PString & cypher,  
00553       void * data,             
00554       PINDEX length            
00555     );
00557     PINDEX Decode(
00558       const PBYTEArray & coded, 
00559       void * data,              
00560       PINDEX length             
00561     );
00577     PBoolean Decode(
00578       const PBYTEArray & coded, 
00579       PBYTEArray & clear       
00580     );
00581 
00582 
00583   protected:
00587     PCypher(
00588       PINDEX blockSize,          
00589       BlockChainMode chainMode   
00590     );
00591     PCypher(
00592       const void * keyData,    
00593       PINDEX keyLength,        
00594       PINDEX blockSize,        
00595       BlockChainMode chainMode 
00596     );
00597 
00598 
00600     virtual void Initialise(
00601       PBoolean encoding   
00602     ) = 0;
00603 
00605     virtual void EncodeBlock(
00606       const void * in,    
00607       void * out          
00608     ) = 0;
00609 
00610 
00612     virtual void DecodeBlock(
00613       const void * in,  
00614       void * out        
00615     ) = 0;
00616 
00617 
00619     PBYTEArray key;
00621     PINDEX blockSize;
00623     BlockChainMode chainMode;
00624 };
00625 
00626 
00634 class PTEACypher : public PCypher
00635 {
00636   PCLASSINFO(PTEACypher, PCypher)
00637 
00638   public:
00639     struct Key {
00640       BYTE value[16];
00641     };
00642 
00647     PTEACypher(
00648       BlockChainMode chainMode = ElectronicCodebook   
00649     );
00650     PTEACypher(
00651       const Key & keyData,     
00652       BlockChainMode chainMode = ElectronicCodebook   
00653     );
00654 
00655 
00657     void SetKey(
00658       const Key & newKey    
00659     );
00660 
00662     void GetKey(
00663       Key & newKey    
00664     ) const;
00665 
00666 
00668     static void GenerateKey(
00669       Key & newKey    
00670     );
00671 
00672 
00673   protected:
00675     virtual void Initialise(
00676       PBoolean encoding   
00677     );
00678 
00680     virtual void EncodeBlock(
00681       const void * in,  
00682       void * out        
00683     );
00684 
00686     virtual void DecodeBlock(
00687       const void * in,  
00688       void * out        
00689     );
00690 
00691   private:
00692     DWORD k0, k1, k2, k3;
00693 };
00694 
00695 
00696 #ifdef P_CONFIG_FILE
00697 
00698 class PSecureConfig : public PConfig
00699 {
00700   PCLASSINFO(PSecureConfig, PConfig)
00701 /* This class defines a set of configuration keys which may be secured by an
00702    encrypted hash function. Thus values contained in keys specified by this
00703    class cannot be changed without invalidating the hash function.
00704  */
00705 
00706   public:
00707     PSecureConfig(
00708       const PTEACypher::Key & productKey,    // Key to decrypt validation code.
00709       const PStringArray    & securedKeys,   // List of secured keys.
00710       Source src = Application        // Standard source for the configuration.
00711     );
00712     PSecureConfig(
00713       const PTEACypher::Key & productKey,   // Key to decrypt validation code.
00714       const char * const * securedKeyArray, // List of secured keys.
00715       PINDEX count,                         // Number of secured keys in list.
00716       Source src = Application        // Standard source for the configuration.
00717     );
00718     /* Create a secured configuration. The default section for the
00719        configuration keys is "Secured Options", the default security key is
00720        "Validation" and the defualt prefix string is "Pending:".
00721 
00722        The user can descend from this class and change any of the member
00723        variable for the names of keys or the configuration file section.
00724      */
00725 
00726 
00727   // New functions for class
00728     const PStringArray & GetSecuredKeys() const { return securedKeys; }
00729     /* Get the list of secured keys in the configuration file section.
00730 
00731        @return
00732        Array of  strings for the secured keys.
00733      */
00734 
00735     const PString & GetSecurityKey() const { return securityKey; }
00736     /* Get the security keys name in the configuration file section.
00737 
00738        @return
00739        String for the security values key.
00740      */
00741 
00742     const PString & GetExpiryDateKey() const { return expiryDateKey; }
00743     /* Get the expiry date keys name in the configuration file section.
00744 
00745        @return
00746        String for the expiry date values key.
00747      */
00748 
00749     const PString & GetOptionBitsKey() const { return optionBitsKey; }
00750     /* Get the Option Bits keys name in the configuration file section.
00751 
00752        @return
00753        String for the Option Bits values key.
00754      */
00755 
00756     const PString & GetPendingPrefix() const { return pendingPrefix; }
00757     /* Get the pending prefix name in the configuration file section.
00758 
00759        @return
00760        String for the pending prefix.
00761      */
00762 
00763     void GetProductKey(
00764       PTEACypher::Key & productKey  // Variable to receive the product key.
00765     ) const;
00766     /* Get the pending prefix name in the configuration file section.
00767 
00768        @return
00769        String for the pending prefix.
00770      */
00771 
00772 
00773     enum ValidationState {
00774       Defaults,
00775       Pending,
00776       IsValid,
00777       Expired,
00778       Invalid
00779     };
00780     ValidationState GetValidation() const;
00781     /* Check the current values attached to the keys specified in the
00782        constructor against an encoded validation key.
00783 
00784        @return
00785        State of the validation keys.
00786      */
00787 
00788     PBoolean ValidatePending();
00789     /* Validate a pending secured option list for the product. All secured
00790        keys with the <CODE>pendingPrefix</CODE> name will be checked against
00791        the value of the field <CODE>securityKey</CODE>. If they match then
00792        they are copied to the secured variables.
00793 
00794        @return
00795        true if secure key values are valid.
00796      */
00797 
00798     void ResetPending();
00799     /* "Unvalidate" a security configuration going back to a pending state,
00800        usually used after an <CODE>Invalid</CODE> response was recieved from
00801        the <A>GetValidation()</A> function.
00802      */
00803 
00804 
00805   protected:
00806     PTEACypher::Key productKey;
00807     PStringArray    securedKeys;
00808     PString         securityKey;
00809     PString         expiryDateKey;
00810     PString         optionBitsKey;
00811     PString         pendingPrefix;
00812 };
00813 
00814 #endif // P_CONFIG_FILE
00815 
00816 #endif // PTLIB_CYPHER_H
00817 
00818 
00819 // End Of File ///////////////////////////////////////////////////////////////
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines