PWLib
1.10.10
|
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.23 2005/11/30 12:47:37 csoutheren 00028 * Removed tabs, reformatted some code, and changed tags for Doxygen 00029 * 00030 * Revision 1.22 2005/01/26 05:37:40 csoutheren 00031 * Added ability to remove config file support 00032 * 00033 * Revision 1.21 2004/11/11 07:34:50 csoutheren 00034 * Added #include <ptlib.h> 00035 * 00036 * Revision 1.20 2004/03/23 05:59:17 csoutheren 00037 * Moved the Base64 routines into cypher.cxx, which is a more sensible 00038 * place and reduces the inclusion of unrelated code 00039 * 00040 * Revision 1.19 2004/02/04 02:31:34 csoutheren 00041 * Remove SHA-1 functions when OpenSSL is disabled 00042 * 00043 * Revision 1.18 2003/04/17 03:34:07 craigs 00044 * Fixed problem with delete'ing a void * 00045 * 00046 * Revision 1.17 2003/04/10 07:02:38 craigs 00047 * Fixed link problem in MD5 class 00048 * 00049 * Revision 1.16 2003/04/10 06:16:30 craigs 00050 * Added SHA-1 digest 00051 * 00052 * Revision 1.15 2002/11/06 22:47:23 robertj 00053 * Fixed header comment (copyright etc) 00054 * 00055 * Revision 1.14 2002/09/16 01:08:59 robertj 00056 * Added #define so can select if #pragma interface/implementation is used on 00057 * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan. 00058 * 00059 * Revision 1.13 2001/09/10 00:28:21 robertj 00060 * Fixed extra CR in comments. 00061 * 00062 * Revision 1.12 1999/03/09 08:01:46 robertj 00063 * Changed comments for doc++ support (more to come). 00064 * 00065 * Revision 1.11 1999/02/16 08:07:10 robertj 00066 * MSVC 6.0 compatibility changes. 00067 * 00068 * Revision 1.10 1998/09/23 06:19:24 robertj 00069 * Added open source copyright license. 00070 * 00071 * Revision 1.9 1997/10/10 10:44:01 robertj 00072 * Fixed bug in password encryption, missing string terminator. 00073 * 00074 * Revision 1.8 1996/11/16 10:50:24 robertj 00075 * Fixed bug in registration order form showing incorrect check code when have key. 00076 * 00077 * Revision 1.7 1996/07/15 10:29:38 robertj 00078 * Changed memory block cypher conversion functions to be void *. 00079 * Changed key types to be structures rather than arrays to avoid pinter/reference confusion by compilers. 00080 * 00081 * Revision 1.6 1996/03/17 05:47:00 robertj 00082 * Changed secured config to allow for expiry dates. 00083 * 00084 * Revision 1.5 1996/03/16 04:36:43 robertj 00085 * Redesign of secure config to accommodate expiry dates and option values passed in security key code. 00086 * 00087 * Revision 1.4 1996/02/25 02:52:46 robertj 00088 * Further secure config development. 00089 * 00090 * Revision 1.3 1996/01/28 14:16:11 robertj 00091 * Further implementation of secure config. 00092 * 00093 * Revision 1.2 1996/01/28 02:41:00 robertj 00094 * Removal of MemoryPointer classes as usage didn't work for GNU. 00095 * Added the secure configuration mechanism for protecting applications. 00096 * 00097 * Revision 1.1 1996/01/23 13:04:20 robertj 00098 * Initial revision 00099 * 00100 */ 00101 00102 00103 #ifndef _PCYPHER 00104 #define _PCYPHER 00105 00106 #ifdef P_USE_PRAGMA 00107 #pragma interface 00108 #endif 00109 00110 #include <ptlib.h> 00111 00142 class PBase64 : public PObject 00143 { 00144 PCLASSINFO(PBase64, PObject); 00145 00146 public: 00150 PBase64(); 00151 00152 void StartEncoding( 00153 BOOL useCRLFs = TRUE // Use CR, LF pairs in end of line characters. 00154 ); 00155 // Begin a base 64 encoding operation, initialising the object instance. 00156 00157 void ProcessEncoding( 00158 const PString & str // String to be encoded 00159 ); 00160 void ProcessEncoding( 00161 const char * cstr // C String to be encoded 00162 ); 00163 void ProcessEncoding( 00164 const PBYTEArray & data // Data block to be encoded 00165 ); 00166 void ProcessEncoding( 00167 const void * dataBlock, // Pointer to data to be encoded 00168 PINDEX length // Length of the data block. 00169 ); 00170 // Incorporate the specified data into the base 64 encoding. 00171 00177 PString GetEncodedString(); 00178 00186 PString CompleteEncoding(); 00187 00188 00189 static PString Encode( 00190 const PString & str // String to be encoded to Base64 00191 ); 00192 static PString Encode( 00193 const char * cstr // C String to be encoded to Base64 00194 ); 00195 static PString Encode( 00196 const PBYTEArray & data // Data block to be encoded to Base64 00197 ); 00198 static PString Encode( 00199 const void * dataBlock, // Pointer to data to be encoded to Base64 00200 PINDEX length // Length of the data block. 00201 ); 00202 // Encode the data in memory to Base 64 data returnin the string. 00203 00204 00205 void StartDecoding(); 00206 // Begin a base 64 decoding operation, initialising the object instance. 00207 00213 BOOL ProcessDecoding( 00214 const PString & str // String to be encoded 00215 ); 00216 BOOL ProcessDecoding( 00217 const char * cstr // C String to be encoded 00218 ); 00219 00225 BOOL GetDecodedData( 00226 void * dataBlock, // Pointer to data to be decoded from base64 00227 PINDEX length // Length of the data block. 00228 ); 00229 PBYTEArray GetDecodedData(); 00230 00238 BOOL IsDecodeOK() { return perfectDecode; } 00239 00240 00252 static PString Decode( 00253 const PString & str // Encoded base64 string to be decoded. 00254 ); 00255 static BOOL Decode( 00256 const PString & str, // Encoded base64 string to be decoded. 00257 PBYTEArray & data // Converted binary data from base64. 00258 ); 00259 static BOOL Decode( 00260 const PString & str, // Encoded base64 string to be decoded. 00261 void * dataBlock, // Pointer to data to be decoded from base64 00262 PINDEX length // Length of the data block. 00263 ); 00264 00265 00266 00267 private: 00268 void OutputBase64(const BYTE * data); 00269 00270 PString encodedString; 00271 PINDEX encodeLength; 00272 BYTE saveTriple[3]; 00273 PINDEX saveCount; 00274 PINDEX nextLine; 00275 BOOL useCRLFs; 00276 00277 BOOL perfectDecode; 00278 PINDEX quadPosition; 00279 PBYTEArray decodedData; 00280 PINDEX decodeSize; 00281 }; 00282 00283 class PMessageDigest : public PObject 00284 { 00285 PCLASSINFO(PMessageDigest, PObject) 00286 00287 public: 00289 PMessageDigest(); 00290 00291 class Result { 00292 public: 00293 PINDEX GetSize() const { return value.GetSize(); } 00294 const BYTE * GetPointer() const { return (const BYTE *)value; } 00295 00296 private: 00297 PBYTEArray value; 00298 friend class PMessageDigest5; 00299 friend class PMessageDigestSHA1; 00300 }; 00301 00303 virtual void Start() = 0; 00304 00305 virtual void Process( 00306 const void * dataBlock, 00307 PINDEX length 00308 ); 00309 00311 virtual void Process( 00312 const PString & str 00313 ); 00315 virtual void Process( 00316 const char * cstr 00317 ); 00319 virtual void Process( 00320 const PBYTEArray & data 00321 ); 00322 00330 virtual PString CompleteDigest(); 00331 virtual void CompleteDigest( 00332 Result & result 00333 ); 00334 00335 protected: 00336 virtual void InternalProcess( 00337 const void * dataBlock, 00338 PINDEX length 00339 ) = 0; 00340 00341 virtual void InternalCompleteDigest( 00342 Result & result 00343 ) = 0; 00344 }; 00345 00346 00352 class PMessageDigest5 : public PMessageDigest 00353 { 00354 PCLASSINFO(PMessageDigest5, PMessageDigest) 00355 00356 public: 00358 PMessageDigest5(); 00359 00361 void Start(); 00362 00364 static PString Encode( 00365 const PString & str 00366 ); 00368 static void Encode( 00369 const PString & str, 00370 Result & result 00371 ); 00373 static PString Encode( 00374 const char * cstr 00375 ); 00377 static void Encode( 00378 const char * cstr, 00379 Result & result 00380 ); 00382 static PString Encode( 00383 const PBYTEArray & data 00384 ); 00386 static void Encode( 00387 const PBYTEArray & data, 00388 Result & result 00389 ); 00391 static PString Encode( 00392 const void * dataBlock, 00393 PINDEX length 00394 ); 00400 static void Encode( 00401 const void * dataBlock, 00402 PINDEX length, 00403 Result & result 00404 ); 00405 00406 // backwards compatibility functions 00407 class Code { 00408 private: 00409 PUInt32l value[4]; 00410 friend class PMessageDigest5; 00411 }; 00412 00414 static void Encode( 00415 const PString & str, 00416 Code & result 00417 ); 00419 static void Encode( 00420 const char * cstr, 00421 Code & result 00422 ); 00424 static void Encode( 00425 const PBYTEArray & data, 00426 Code & result 00427 ); 00433 static void Encode( 00434 const void * dataBlock, 00435 PINDEX length, 00436 Code & result 00437 ); 00438 virtual void Complete( 00439 Code & result 00440 ); 00441 virtual PString Complete(); 00442 00443 protected: 00444 virtual void InternalProcess( 00445 const void * dataBlock, 00446 PINDEX length 00447 ); 00448 00449 virtual void InternalCompleteDigest( 00450 Result & result 00451 ); 00452 00453 private: 00454 void Transform(const BYTE * block); 00455 00457 BYTE buffer[64]; 00459 DWORD state[4]; 00461 PUInt64 count; 00462 }; 00463 00464 #if P_SSL 00465 00470 class PMessageDigestSHA1 : public PMessageDigest 00471 { 00472 PCLASSINFO(PMessageDigestSHA1, PMessageDigest) 00473 00474 public: 00476 PMessageDigestSHA1(); 00477 ~PMessageDigestSHA1(); 00478 00480 void Start(); 00481 00483 static PString Encode( 00484 const PString & str 00485 ); 00487 static void Encode( 00488 const PString & str, 00489 Result & result 00490 ); 00492 static PString Encode( 00493 const char * cstr 00494 ); 00496 static void Encode( 00497 const char * cstr, 00498 Result & result 00499 ); 00501 static PString Encode( 00502 const PBYTEArray & data 00503 ); 00505 static void Encode( 00506 const PBYTEArray & data, 00507 Result & result 00508 ); 00510 static PString Encode( 00511 const void * dataBlock, 00512 PINDEX length 00513 ); 00519 static void Encode( 00520 const void * dataBlock, 00521 PINDEX length, 00522 Result & result 00523 ); 00524 00525 protected: 00526 virtual void InternalProcess( 00527 const void * dataBlock, 00528 PINDEX length 00529 ); 00530 00531 void InternalCompleteDigest( 00532 Result & result 00533 ); 00534 00535 private: 00536 void * shaContext; 00537 }; 00538 00539 #endif 00540 00544 class PCypher : public PObject 00545 { 00546 PCLASSINFO(PCypher, PObject) 00547 00548 public: 00550 enum BlockChainMode { 00551 ElectronicCodebook, 00552 ECB = ElectronicCodebook, 00553 CypherBlockChaining, 00554 CBC = CypherBlockChaining, 00555 OutputFeedback, 00556 OFB = OutputFeedback, 00557 CypherFeedback, 00558 CFB = CypherFeedback, 00559 NumBlockChainModes 00560 }; 00561 00562 // New functions for class 00564 PString Encode( 00565 const PString & str 00566 ); 00568 PString Encode( 00569 const PBYTEArray & clear 00570 ); 00572 PString Encode( 00573 const void * data, 00574 PINDEX length 00575 ); 00577 void Encode( 00578 const PBYTEArray & clear, 00579 PBYTEArray & coded 00580 ); 00596 void Encode( 00597 const void * data, // Clear text binary data to be encoded. 00598 PINDEX length, // Number of bytes of data to be encoded. 00599 PBYTEArray & coded // Encoded data. 00600 ); 00601 00603 PString Decode( 00604 const PString & cypher 00605 ); 00607 BOOL Decode( 00608 const PString & cypher, 00609 PString & clear 00610 ); 00612 BOOL Decode( 00613 const PString & cypher, 00614 PBYTEArray & clear 00615 ); 00617 PINDEX Decode( 00618 const PString & cypher, 00619 void * data, 00620 PINDEX length 00621 ); 00623 PINDEX Decode( 00624 const PBYTEArray & coded, 00625 void * data, 00626 PINDEX length 00627 ); 00643 BOOL Decode( 00644 const PBYTEArray & coded, 00645 PBYTEArray & clear 00646 ); 00647 00648 00649 protected: 00653 PCypher( 00654 PINDEX blockSize, 00655 BlockChainMode chainMode 00656 ); 00657 PCypher( 00658 const void * keyData, 00659 PINDEX keyLength, 00660 PINDEX blockSize, 00661 BlockChainMode chainMode 00662 ); 00663 00664 00666 virtual void Initialise( 00667 BOOL encoding 00668 ) = 0; 00669 00671 virtual void EncodeBlock( 00672 const void * in, 00673 void * out 00674 ) = 0; 00675 00676 00678 virtual void DecodeBlock( 00679 const void * in, 00680 void * out 00681 ) = 0; 00682 00683 00685 PBYTEArray key; 00687 PINDEX blockSize; 00689 BlockChainMode chainMode; 00690 }; 00691 00692 00700 class PTEACypher : public PCypher 00701 { 00702 PCLASSINFO(PTEACypher, PCypher) 00703 00704 public: 00705 struct Key { 00706 BYTE value[16]; 00707 }; 00708 00713 PTEACypher( 00714 BlockChainMode chainMode = ElectronicCodebook 00715 ); 00716 PTEACypher( 00717 const Key & keyData, 00718 BlockChainMode chainMode = ElectronicCodebook 00719 ); 00720 00721 00723 void SetKey( 00724 const Key & newKey 00725 ); 00726 00728 void GetKey( 00729 Key & newKey 00730 ) const; 00731 00732 00734 static void GenerateKey( 00735 Key & newKey 00736 ); 00737 00738 00739 protected: 00741 virtual void Initialise( 00742 BOOL encoding 00743 ); 00744 00746 virtual void EncodeBlock( 00747 const void * in, 00748 void * out 00749 ); 00750 00752 virtual void DecodeBlock( 00753 const void * in, 00754 void * out 00755 ); 00756 00757 private: 00758 DWORD k0, k1, k2, k3; 00759 }; 00760 00761 00762 #ifdef P_CONFIG_FILE 00763 00764 class PSecureConfig : public PConfig 00765 { 00766 PCLASSINFO(PSecureConfig, PConfig) 00767 /* This class defines a set of configuration keys which may be secured by an 00768 encrypted hash function. Thus values contained in keys specified by this 00769 class cannot be changed without invalidating the hash function. 00770 */ 00771 00772 public: 00773 PSecureConfig( 00774 const PTEACypher::Key & productKey, // Key to decrypt validation code. 00775 const PStringArray & securedKeys, // List of secured keys. 00776 Source src = Application // Standard source for the configuration. 00777 ); 00778 PSecureConfig( 00779 const PTEACypher::Key & productKey, // Key to decrypt validation code. 00780 const char * const * securedKeyArray, // List of secured keys. 00781 PINDEX count, // Number of secured keys in list. 00782 Source src = Application // Standard source for the configuration. 00783 ); 00784 /* Create a secured configuration. The default section for the 00785 configuration keys is "Secured Options", the default security key is 00786 "Validation" and the defualt prefix string is "Pending:". 00787 00788 The user can descend from this class and change any of the member 00789 variable for the names of keys or the configuration file section. 00790 */ 00791 00792 00793 // New functions for class 00794 const PStringArray & GetSecuredKeys() const { return securedKeys; } 00795 /* Get the list of secured keys in the configuration file section. 00796 00797 @return 00798 Array of strings for the secured keys. 00799 */ 00800 00801 const PString & GetSecurityKey() const { return securityKey; } 00802 /* Get the security keys name in the configuration file section. 00803 00804 @return 00805 String for the security values key. 00806 */ 00807 00808 const PString & GetExpiryDateKey() const { return expiryDateKey; } 00809 /* Get the expiry date keys name in the configuration file section. 00810 00811 @return 00812 String for the expiry date values key. 00813 */ 00814 00815 const PString & GetOptionBitsKey() const { return optionBitsKey; } 00816 /* Get the Option Bits keys name in the configuration file section. 00817 00818 @return 00819 String for the Option Bits values key. 00820 */ 00821 00822 const PString & GetPendingPrefix() const { return pendingPrefix; } 00823 /* Get the pending prefix name in the configuration file section. 00824 00825 @return 00826 String for the pending prefix. 00827 */ 00828 00829 void GetProductKey( 00830 PTEACypher::Key & productKey // Variable to receive the product key. 00831 ) const; 00832 /* Get the pending prefix name in the configuration file section. 00833 00834 @return 00835 String for the pending prefix. 00836 */ 00837 00838 00839 enum ValidationState { 00840 Defaults, 00841 Pending, 00842 IsValid, 00843 Expired, 00844 Invalid 00845 }; 00846 ValidationState GetValidation() const; 00847 /* Check the current values attached to the keys specified in the 00848 constructor against an encoded validation key. 00849 00850 @return 00851 State of the validation keys. 00852 */ 00853 00854 BOOL ValidatePending(); 00855 /* Validate a pending secured option list for the product. All secured 00856 keys with the <CODE>pendingPrefix</CODE> name will be checked against 00857 the value of the field <CODE>securityKey</CODE>. If they match then 00858 they are copied to the secured variables. 00859 00860 @return 00861 TRUE if secure key values are valid. 00862 */ 00863 00864 void ResetPending(); 00865 /* "Unvalidate" a security configuration going back to a pending state, 00866 usually used after an <CODE>Invalid</CODE> response was recieved from 00867 the <A>GetValidation()</A> function. 00868 */ 00869 00870 00871 protected: 00872 PTEACypher::Key productKey; 00873 PStringArray securedKeys; 00874 PString securityKey; 00875 PString expiryDateKey; 00876 PString optionBitsKey; 00877 PString pendingPrefix; 00878 }; 00879 00880 #endif // P_CONFIG_FILE 00881 00882 #endif // _PCYPHER 00883 00884 00885 // End Of File ///////////////////////////////////////////////////////////////