📄 cypher.cxx
字号:
/* * cypher.cxx * * Encryption support classes. * * Portable Windows Library * * Copyright (c) 1993-2002 Equivalence Pty. Ltd. * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Contributor(s): ______________________________________. * * $Log: cypher.cxx,v $ * Revision 1.47 2005/01/26 05:37:57 csoutheren * Added ability to remove config file support * * Revision 1.46 2004/07/06 10:12:52 csoutheren * Added static integer o factory template to assist in ensuring factories are instantiated * * Revision 1.45 2004/06/29 12:22:22 rjongbloed * Fixed incorrect usage of result (now object rather than scalar), thanks Michal Zygmuntowicz * * Revision 1.44 2004/04/09 06:52:17 rjongbloed * Removed #pargma linker command for /delayload of DLL as documentations sais that * you cannot do this. * * Revision 1.43 2004/04/03 23:53:09 csoutheren * Added various changes to improce compatibility with the Sun Forte compiler * Thanks to Brian Cameron * Added detection of readdir_r version * * Revision 1.42 2004/03/23 05:59:17 csoutheren * Moved the Base64 routines into cypher.cxx, which is a more sensible * place and reduces the inclusion of unrelated code * * Revision 1.41 2004/03/14 10:03:47 rjongbloed * Fixed "security patch" that cleared entire object (including the vtable!) isntead of * clearing the "sensitive" information it was supposed to clear. * * Revision 1.40 2004/03/02 12:08:27 rjongbloed * Added missing pragmas to automatically include libraries for OpenSSL * * Revision 1.39 2004/02/23 23:52:19 csoutheren * Added pragmas to avoid every Windows application needing to include libs explicitly * * Revision 1.38 2003/04/27 23:52:57 craigs * Fixed problem with SHA1 not calling Start * * Revision 1.37 2003/04/17 12:12:59 robertj * Added windows library inclusion for optional openssl. * * Revision 1.36 2003/04/17 07:34:46 robertj * Fixed correct test for P_SSL * * Revision 1.35 2003/04/17 01:21:55 craigs * Fixed problem with delete'ing a void * * * Revision 1.33 2003/04/10 07:14:27 craigs * Fixed link problem in MD5 class * * Revision 1.32 2003/04/10 06:16:09 craigs * Added SHA-1 digest * * Revision 1.31 2002/11/06 22:47:24 robertj * Fixed header comment (copyright etc) * * Revision 1.30 2002/06/05 12:29:15 craigs * Changes for gcc 3.1 * * Revision 1.29 2001/03/01 03:55:59 robertj * Fixed MSVC warnings. * * Revision 1.28 2001/02/28 21:10:47 craigs * Fixed problem in Decode function * Added randomizer to fill data in Decode * * Revision 1.27 2000/02/17 12:05:02 robertj * Added better random number generator after finding major flaws in MSVCRT version. * * Revision 1.26 1998/11/30 04:50:45 robertj * New directory structure * * Revision 1.25 1998/09/23 06:21:56 robertj * Added open source copyright license. * * Revision 1.24 1998/07/24 06:58:13 robertj * Improved robustness of encrypted data decoding, error on illegal tail block size. * * Revision 1.23 1998/02/16 00:14:36 robertj * Fixed ability to register in one stage instead of always having to use 2. * * Revision 1.22 1998/01/26 02:49:14 robertj * GNU support. * * Revision 1.21 1997/10/30 10:19:19 robertj * Fixed bug with having empty string in encrypted text. * * Revision 1.20 1997/10/10 10:43:41 robertj * Fixed bug in password encryption, missing string terminator. * * Revision 1.19 1997/08/04 10:39:53 robertj * Fixed bug for decoding empty string. * * Revision 1.18 1997/07/26 11:35:38 robertj * Fixed bug where illegal data errors were not propagated. * * Revision 1.17 1996/11/16 10:50:26 robertj * ?? * * Revision 1.16 1996/08/17 09:56:02 robertj * Fixed big endian processor platform conformance. * * Revision 1.15 1996/07/15 10:33:42 robertj * Changed memory block base64 conversion functions to be void *. * Changed memory block cypher conversion functions to be void *. * Changed endian classes to be memory mapped. * * Revision 1.14 1996/06/18 12:35:49 robertj * Fixed bug in registration when language is not English. * * Revision 1.13 1996/06/10 10:01:23 robertj * Fixed bug in getting cypher key, not copying all the bytes. * * Revision 1.12 1996/05/26 03:46:31 robertj * Compatibility to GNU 2.7.x * * Revision 1.11 1996/04/09 03:32:45 robertj * Fixed bug in registration so now works in time zones other than Eastern Australia. * * Revision 1.11 1996/04/08 05:18:38 robertj * Fixed bug in registering programs in a different time zone. * * Revision 1.10 1996/03/17 05:47:19 robertj * Changed secured config to allow for expiry dates. * * Revision 1.9 1996/03/16 04:37:20 robertj * Redesign of secure config to accommodate expiry dates and option values passed in security key code. * * Revision 1.8 1996/03/11 10:28:53 robertj * Fixed bug in C++ optimising compiler. * * Revision 1.7 1996/03/02 03:20:52 robertj * Fixed secured config parameters so leading/trailing blanks not significant. * * Revision 1.6 1996/02/25 11:22:42 robertj * Added assertion if try and SetValidation when not pending. * * Revision 1.5 1996/02/25 02:53:05 robertj * Further secure config development. * * Revision 1.4 1996/02/15 14:43:28 robertj * Allowed no secured config data at all to be "valid". All vars will then be guarenteed to default. * * Revision 1.3 1996/01/28 14:14:12 robertj * Further implementation of secure config. * * Revision 1.2 1996/01/28 02:49:00 robertj * Removal of MemoryPointer classes as usage didn't work for GNU. * Added the secure configuration mechanism for protecting applications. * * Revision 1.1 1996/01/23 13:05:58 robertj * Initial revision * */#ifdef __GNUC__#pragma implementation "cypher.h"#endif#define P_DISABLE_FACTORY_INSTANCES#include <ptlib.h>#include <ptclib/cypher.h>#include <ptclib/mime.h>#include <ptclib/random.h>///////////////////////////////////////////////////////////////////////////////// PBase64PBase64::PBase64(){ StartEncoding(); StartDecoding();}void PBase64::StartEncoding(BOOL useCRLF){ encodedString = ""; encodeLength = nextLine = saveCount = 0; useCRLFs = useCRLF;}void PBase64::ProcessEncoding(const PString & str){ ProcessEncoding((const char *)str);}void PBase64::ProcessEncoding(const char * cstr){ ProcessEncoding((const BYTE *)cstr, strlen(cstr));}void PBase64::ProcessEncoding(const PBYTEArray & data){ ProcessEncoding(data, data.GetSize());}static const char Binary2Base64[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";void PBase64::OutputBase64(const BYTE * data){ char * out = encodedString.GetPointer(((encodeLength+7)&~255) + 256); out[encodeLength++] = Binary2Base64[data[0] >> 2]; out[encodeLength++] = Binary2Base64[((data[0]&3)<<4) | (data[1]>>4)]; out[encodeLength++] = Binary2Base64[((data[1]&15)<<2) | (data[2]>>6)]; out[encodeLength++] = Binary2Base64[data[2]&0x3f]; if (++nextLine > 18) { // 76 columns if (useCRLFs) out[encodeLength++] = '\r'; out[encodeLength++] = '\n'; nextLine = 0; }}void PBase64::ProcessEncoding(const void * dataPtr, PINDEX length){ if (length == 0) return; const BYTE * data = (const BYTE *)dataPtr; while (saveCount < 3) { saveTriple[saveCount++] = *data++; if (--length == 0) return; } OutputBase64(saveTriple); PINDEX i; for (i = 0; i+2 < length; i += 3) OutputBase64(data+i); saveCount = length - i; switch (saveCount) { case 2 : saveTriple[0] = data[i++]; saveTriple[1] = data[i]; break; case 1 : saveTriple[0] = data[i]; }}PString PBase64::GetEncodedString(){ PString retval = encodedString; encodedString = ""; encodeLength = 0; return retval;}PString PBase64::CompleteEncoding(){ char * out = encodedString.GetPointer(encodeLength + 5)+encodeLength; switch (saveCount) { case 1 : *out++ = Binary2Base64[saveTriple[0] >> 2]; *out++ = Binary2Base64[(saveTriple[0]&3)<<4]; *out++ = '='; *out = '='; break; case 2 : *out++ = Binary2Base64[saveTriple[0] >> 2]; *out++ = Binary2Base64[((saveTriple[0]&3)<<4) | (saveTriple[1]>>4)]; *out++ = Binary2Base64[((saveTriple[1]&15)<<2)]; *out = '='; } return encodedString;}PString PBase64::Encode(const PString & str){ return Encode((const char *)str);}PString PBase64::Encode(const char * cstr){ return Encode((const BYTE *)cstr, strlen(cstr));}PString PBase64::Encode(const PBYTEArray & data){ return Encode(data, data.GetSize());}PString PBase64::Encode(const void * data, PINDEX length){ PBase64 encoder; encoder.ProcessEncoding(data, length); return encoder.CompleteEncoding();}void PBase64::StartDecoding(){ perfectDecode = TRUE; quadPosition = 0; decodedData.SetSize(0); decodeSize = 0;}BOOL PBase64::ProcessDecoding(const PString & str){ return ProcessDecoding((const char *)str);}BOOL PBase64::ProcessDecoding(const char * cstr){ static const BYTE Base642Binary[256] = { 96, 99, 99, 99, 99, 99, 99, 99, 99, 99, 98, 99, 99, 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 62, 99, 99, 99, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 99, 99, 99, 97, 99, 99, 99, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 99, 99, 99, 99, 99, 99, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 }; for (;;) { BYTE value = Base642Binary[(BYTE)*cstr++]; switch (value) { case 96 : // end of string return FALSE; case 97 : // '=' sign if (quadPosition == 3 || (quadPosition == 2 && *cstr == '=')) { quadPosition = 0; // Reset this to zero, as have a perfect decode return TRUE; // Stop decoding now as must be at end of data } perfectDecode = FALSE; // Ignore '=' sign but flag decode as suspect break; case 98 : // CRLFs break; // Ignore totally case 99 : // Illegal characters perfectDecode = FALSE; // Ignore rubbish but flag decode as suspect break; default : // legal value from 0 to 63 BYTE * out = decodedData.GetPointer(((decodeSize+1)&~255) + 256); switch (quadPosition) { case 0 : out[decodeSize] = (BYTE)(value << 2); break; case 1 : out[decodeSize++] |= (BYTE)(value >> 4); out[decodeSize] = (BYTE)((value&15) << 4); break; case 2 : out[decodeSize++] |= (BYTE)(value >> 2); out[decodeSize] = (BYTE)((value&3) << 6); break; case 3 : out[decodeSize++] |= (BYTE)value; break; } quadPosition = (quadPosition+1)&3; } }}PBYTEArray PBase64::GetDecodedData(){ perfectDecode = quadPosition == 0; decodedData.SetSize(decodeSize); PBYTEArray retval = decodedData; retval.MakeUnique(); decodedData.SetSize(0); decodeSize = 0; return retval;}BOOL PBase64::GetDecodedData(void * dataBlock, PINDEX length){ perfectDecode = quadPosition == 0; BOOL bigEnough = length >= decodeSize; memcpy(dataBlock, decodedData, bigEnough ? decodeSize : length); decodedData.SetSize(0); decodeSize = 0; return bigEnough;}PString PBase64::Decode(const PString & str){ PBYTEArray data; Decode(str, data); return PString((const char *)(const BYTE *)data, data.GetSize());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -