# 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 ///////////////////////////////////////////////////////////////