PTLib
Version 2.10.4
|
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 ///////////////////////////////////////////////////////////////