⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xtunnelscvsaes.cpp

📁 xtunnel nat/fw traversal source code
💻 CPP
字号:
/*	File:		XTunnelsCVsAES.cpp	Contains:   AES routines -- switched to MKS_AES implementation 03.11.07	Copyright:  (c) 2003 by Xten Networks, Inc., all rights reserved.*/#include <iostream>#include <istream.h>#include <strstream>#include <algorithm>#include <string.h>#include "md5.h"#include "uuid.h"#include "XTunnelsCVsAES.h"#include "MKS_AES.h"#include "XTunnelsCVsSHA1.h"using std::string;using std::iostream;using std::istrstream;using std::ostrstream;using std::cout;using std::endl;using std::min;using std::max;using std::streamsize;typedef unsigned char uint8;typedef unsigned int uint32;class CVsInternalAES{public:   PROCESS m_tCurrentEngineSetup;   int m_iCurrentEngineBits;   USERKEY m_tCurrentUserKey;   CVsInternalAES() :   m_tCurrentEngineSetup(nocrypt),   m_iCurrentEngineBits(0)   {   bzero(&m_tCurrentUserKey, sizeof(m_tCurrentUserKey));   }/* AES key scheduling routine */   int aes_set_key(uint8 *key, int nbits )   {   memcpy(&m_tCurrentUserKey, key, 32);   if (nbits != m_iCurrentEngineBits)      {      aessetup(nbits);      m_iCurrentEngineBits = nbits;      m_tCurrentEngineSetup = nocrypt;      bzero(&ukey, sizeof(ukey));      }         return 0; // we could sanity check nbits to avoid exit() in aessetup   }/* AES 128-bit block encryption routine */   void aes_encrypt(char data[16])   {   if ((encrypt != m_tCurrentEngineSetup)         || !memcmp(&ukey, &m_tCurrentUserKey, 32))      {      memcpy(&ukey, &m_tCurrentUserKey, 32);      aeskeyschedule(encrypt);      }      memcpy(&aesin, data, 16);   aesprocess();   memcpy(data, &aesout, 16);   }/* AES 128-bit block decryption routine */   void aes_decrypt(char data[16])   {   if ((decrypt != m_tCurrentEngineSetup)         || !memcmp(&ukey, &m_tCurrentUserKey, 32))      {      memcpy(&ukey, &m_tCurrentUserKey, 32);      aeskeyschedule(decrypt);      }      memcpy(&aesin, data, 16);   aesprocess();   memcpy(data, &aesout, 16);   }}; // class CVsInternalAESstruct STAESPrivateData{public:   STAESPrivateData(      const char * szKey,      bool bEncrypt,      unsigned long dwAESKeyLength   );   ~STAESPrivateData();public:   CVsInternalAES m_cAES;   unsigned long m_dwLength;   unsigned long m_dwBlockWidth;   char m_pBuffer[24];   unsigned long m_dwFilledSize;   bool m_bNextIoFails;};STAESPrivateData::STAESPrivateData(   const char * szKey,   bool bEncrypt,   unsigned long dwAESKeyLength){#if VS_TARGET_OS_MAC#pragma unused (bEncrypt)#endif // VS_TARGET_OS_MAC   m_bNextIoFails = false;   const char * szAscIIKey = szKey;   uuid_t tMD5DigestBytes;   {   struct MD5Context md5c;   MD5Init(&md5c);   MD5Update(&md5c, (const unsigned char *)szAscIIKey, strlen(szAscIIKey)*sizeof(char));   MD5Final((unsigned char*)&tMD5DigestBytes, &md5c);   }   CVsSHA1 cSHA1;   cSHA1.Write((const BYTE *)szAscIIKey, strlen(szAscIIKey)*sizeof(char));   cSHA1.Close();   m_dwFilledSize = 0;   bzero(m_pBuffer, sizeof(m_pBuffer));   m_dwLength = dwAESKeyLength;   m_dwBlockWidth = sizeof(BYTE)*16;   BYTE *pHashKey = new BYTE[cSHA1.GetDigestBytesLength() + sizeof(tMD5DigestBytes) + sizeof(char)];   if (NULL == pHashKey) return;   bzero(pHashKey, cSHA1.GetDigestBytesLength() + sizeof(tMD5DigestBytes) + sizeof(char));   memcpy(pHashKey, cSHA1.GetDigestBytes(), cSHA1.GetDigestBytesLength());   memcpy(pHashKey + cSHA1.GetDigestBytesLength(), &tMD5DigestBytes, sizeof(tMD5DigestBytes));   m_cAES.aes_set_key(&(pHashKey[0]), dwAESKeyLength);}STAESPrivateData::~STAESPrivateData(){}void CVsAES::Init(){   m_pData = NULL;   m_iStream = NULL;   m_oStream = NULL;}void CVsAES::Destroy(){   Close();}void CVsAES::OpenRead(   const char * szKey,   istrstream *ipInputStream,   CVsAES::AESKeyLength eKeyLength){   Close();   if (NULL == ipInputStream)   	return;   m_pData = new STAESPrivateData(      szKey,      false,      (unsigned long)eKeyLength   );   if (NULL == m_pData)   	return;   m_iStream = ipInputStream;   m_bReadMode = true;}void CVsAES::OpenWrite(   const char * szKey,   ostrstream *ipOuputStream,   CVsAES::AESKeyLength eKeyLength){   Close();   if (NULL == ipOuputStream)   	return;   m_pData = new STAESPrivateData(      szKey,      true,      (unsigned long)eKeyLength   );   if (NULL == m_pData)   	return;   m_oStream = ipOuputStream;   m_bReadMode = false;}bool CVsAES::Read(    char  *pBuffer,   unsigned long  dwBytesToRead,   unsigned long *pBytesRead){   bool bReturnResult = false;   unsigned long dwTotalBytesRead = 0;   if (NULL == m_pData)   	return bReturnResult;   if (NULL == m_iStream)   	return bReturnResult;   if (!m_bReadMode)   	return bReturnResult;   if (0 == dwBytesToRead) goto NEXT;   while (0 != dwBytesToRead)   {      // still some stuff in the buffer from the last read      while ((m_pData->m_dwFilledSize > 0) &&             (0 != dwBytesToRead))      {         unsigned long dwReadSize = min<unsigned long>(dwBytesToRead, m_pData->m_dwFilledSize);               // okay lets reads what's left in the buffer         memcpy(pBuffer, m_pData->m_pBuffer, dwReadSize);         pBuffer += dwReadSize;         dwTotalBytesRead += dwReadSize;         m_pData->m_dwFilledSize -= dwReadSize;         if (m_pData->m_dwFilledSize < m_pData->m_dwBlockWidth)         {            // move any unread data in buffer over now...            memcpy(               m_pData->m_pBuffer,               &(m_pData->m_pBuffer[dwReadSize]),               m_pData->m_dwFilledSize            );         }         // decrease amount of buffer left in stream         dwBytesToRead -= dwReadSize;      }   	if (0 == dwBytesToRead) goto NEXT;	if ((0 == dwTotalBytesRead) && (m_pData->m_bNextIoFails))		return bReturnResult;   	if (m_pData->m_bNextIoFails) goto NEXT;      // fill the entire buffer all over again      while (m_pData->m_dwFilledSize < m_pData->m_dwBlockWidth)      {         unsigned long dwActualBytesRead = 0;         bool bResult = false;         streamsize tAvailable = m_iStream->rdbuf()->in_avail();         if (tAvailable > 0)            {            streamsize tToRead = m_pData->m_dwBlockWidth - m_pData->m_dwFilledSize;            tToRead = min<streamsize>(tToRead, tAvailable);            m_iStream->read(               &(m_pData->m_pBuffer[m_pData->m_dwFilledSize]),               tToRead            );            if (m_iStream->good())               {               bResult = true;               dwActualBytesRead = tToRead;               m_pData->m_dwFilledSize += dwActualBytesRead;               }#if DEBUG		      else		         cout << "WARNING: CVsAES::Read(): m_iStream->good() failed!" << endl;#endif // DEBUG            }         // zero out the rest of the buffer         memset(&m_pData->m_pBuffer[m_pData->m_dwFilledSize], 0, m_pData->m_dwBlockWidth - m_pData->m_dwFilledSize);         // the next read should fail as well         if (!bResult)         {            m_pData->m_bNextIoFails = true;            if ((0 == dwTotalBytesRead) &&                (0 == m_pData->m_dwFilledSize))               goto FINALLY;                    // this write fails NOW!            else            {               if (0 == m_pData->m_dwFilledSize)                  goto NEXT;                    // no more data in AES buffer, but some data was read, next read will fail               break;                           // some stuff in AES buffer, decrypt, next read will fail            }         }         if ((0 == dwActualBytesRead) &&             (0 == m_pData->m_dwFilledSize))            goto NEXT;                          // at end of file         if (0 == dwActualBytesRead)            // at end of file, but stuff in AES buffer, decrypt            break;      }      m_pData->m_cAES.aes_decrypt(m_pData->m_pBuffer);   }}   NEXT:   {      if (NULL != pBytesRead)         *pBytesRead = dwTotalBytesRead;      bReturnResult = true;   }   FINALLY:   {   }   return bReturnResult;}bool CVsAES::Write(   const char *pBuffer,   unsigned long dwBufferLength,   unsigned long *pBytesWritten){   bool bReturnResult = false;   if (NULL == m_pData)   	return bReturnResult;   if (NULL == m_oStream)   	return bReturnResult;   if (m_bReadMode)   	return bReturnResult;   if (m_pData->m_bNextIoFails)   	return bReturnResult;   // keep writting while there is more buffer to write   while (dwBufferLength > 0)   {      // fill the AES buffer to max capacity      unsigned long dwFillAmount = min<unsigned long>(dwBufferLength, m_pData->m_dwBlockWidth - m_pData->m_dwFilledSize);      memcpy(&(m_pData->m_pBuffer[m_pData->m_dwFilledSize]), pBuffer, dwFillAmount);      pBuffer += dwFillAmount;      dwBufferLength -= dwFillAmount;      m_pData->m_dwFilledSize += dwFillAmount;      if (m_pData->m_dwFilledSize < m_pData->m_dwBlockWidth)         goto NEXT;        // not enough data to fill the entire buffer with, wait until next fill      // encrypt the data now      m_pData->m_cAES.aes_encrypt(m_pData->m_pBuffer);      // keep trying to output the buffer into the output stream      while (m_pData->m_dwFilledSize > 0)      {         unsigned long dwActualBytesWritten = 0;         dwActualBytesWritten = m_pData->m_dwFilledSize;         bool bResult = NULL != m_oStream->write(m_pData->m_pBuffer, dwActualBytesWritten);         if (pBytesWritten)            *pBytesWritten += dwActualBytesWritten;         if ((!bResult) ||             (0 == dwActualBytesWritten))         {            m_pData->m_bNextIoFails = true;            goto FINALLY;         }         m_pData->m_dwFilledSize -= dwActualBytesWritten;         if (0 != m_pData->m_dwFilledSize)         {            // shift the buffer over            memcpy(m_pData->m_pBuffer, &(m_pData->m_pBuffer[dwActualBytesWritten]), m_pData->m_dwFilledSize);         }      }   }}   NEXT:   {      bReturnResult = true;   }   FINALLY:   {   }   return bReturnResult;}void CVsAES::Close(unsigned long *pBytesWritten){   if (NULL != m_pData)   {      if (!m_bReadMode)      {         if (!m_pData->m_bNextIoFails)         {            // still some data left in AES buffer to write?            if (m_pData->m_dwFilledSize > 0)            {               // zero out any left over bits...               memset(&(m_pData->m_pBuffer[m_pData->m_dwFilledSize]), 0, m_pData->m_dwBlockWidth - m_pData->m_dwFilledSize);               m_pData->m_dwFilledSize += (m_pData->m_dwBlockWidth - m_pData->m_dwFilledSize);               // encrypt the data now               m_pData->m_cAES.aes_encrypt(m_pData->m_pBuffer);               // keep trying to output the buffer into the output stream               while (m_pData->m_dwFilledSize > 0)               {                  unsigned long dwActualBytesWritten = 0;                  dwActualBytesWritten = m_pData->m_dwFilledSize;                  bool bResult = NULL != m_oStream->write(m_pData->m_pBuffer, dwActualBytesWritten);                  if (pBytesWritten)                     *pBytesWritten += dwActualBytesWritten;                  if ((!bResult) ||                      (0 == dwActualBytesWritten))                  {                     break;   // ohh well...                  }                  m_pData->m_dwFilledSize -= dwActualBytesWritten;                  if (0 != m_pData->m_dwFilledSize)                  {                     // shift the buffer over                     memcpy(m_pData->m_pBuffer, &(m_pData->m_pBuffer[dwActualBytesWritten]), m_pData->m_dwFilledSize);                  }               }            }         }      }      delete m_pData;      m_pData = NULL;   }   m_oStream = NULL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -