BlowFish::~BlowFish()
{
  // trashMemory((unsigned char*)tempbf_P, 18*4);
  // trashMemory((unsigned char*)tempbf_S, 256*4);
  trashMemory(bf_P, sizeof(bf_P));
  trashMemory(bf_S, sizeof(bf_S));
}
示例#2
0
size_t PWSfileV1V2::ReadCBC(unsigned char &type, StringX &data)
{
  unsigned char *buffer = NULL;
  size_t buffer_len = 0;
  size_t retval;

  ASSERT(m_fish != NULL && m_IV != NULL);
  retval = _readcbc(m_fd, buffer, buffer_len, type,
                    m_fish, m_IV, m_terminal);

  if (buffer_len > 0) {
    wchar_t *wc = new wchar_t[buffer_len+1];

    size_t wcLen = pws_os::mbstowcs(wc, buffer_len + 1,
                                    reinterpret_cast<const char *>(buffer),
                                    buffer_len, false);
    ASSERT(wcLen != 0);
    if (wcLen < buffer_len + 1)
      wc[wcLen] = TCHAR('\0');
    else
      wc[buffer_len] = TCHAR('\0');
    data = wc;
    trashMemory(wc, wcLen);
    delete[] wc;
    trashMemory(buffer, buffer_len);
    delete[] buffer;
  } else {
    data = _T("");
    // no need to delete[] buffer, since _readcbc will not allocate if
    // buffer_len is zero
  }
  return retval;
}
示例#3
0
BYTE* CSMemFile::Realloc(BYTE* lpOldMem, SIZE_T nBytes)
{
  if (nBytes == 0) {
    trashMemory(lpOldMem, m_size);
    Free(lpOldMem);
    m_size = 0;
    return NULL;
  }

  size_t old_size = _msize((void *)lpOldMem);
  ASSERT(m_size == old_size);
  BYTE* lpNewMem = (BYTE *)malloc(nBytes);

  if (lpNewMem == NULL) {
    trashMemory(lpOldMem, old_size);
    free(lpOldMem);
    m_size = 0;
    return NULL;
  }

  memcpy_s((void *)lpNewMem, nBytes, (void *)lpOldMem, old_size);
  trashMemory(lpOldMem, old_size);
  free(lpOldMem);

  m_size = nBytes;
  return lpNewMem;
}
示例#4
0
CUTF8Conv::~CUTF8Conv()
{
  if (m_utf8 != NULL) {
    trashMemory(m_utf8, m_utf8MaxLen * sizeof(m_utf8[0]));
    delete[] m_utf8;
  }
  if (m_wc != NULL) {
    trashMemory(m_wc, m_wcMaxLen);
    delete[] m_wc;
  }
  if (m_tmp != NULL) {
    trashMemory(m_tmp, m_tmpMaxLen * sizeof(m_tmp[0]));
    delete[] m_tmp;
  }
}
void CYubiMixin::yubiRequestHMACSha1(const CSecString &challenge)
{
  if (m_pending) {
    // no-op if a request's already in the air
  } else {
    CSingleLock singeLock(&m_mutex);
    singeLock.Lock();
    // open key
    // if zero or >1 key, we'll fail
    if (m_yk.openKey() != YKLIB_OK) {
      return;
    }

    // Prepare the HMAC-SHA1 challenge here

    BYTE chalBuf[SHA1_MAX_BLOCK_SIZE];
    BYTE chalLength = BYTE(challenge.GetLength()*sizeof(TCHAR));
    memset(chalBuf, 0, SHA1_MAX_BLOCK_SIZE);
    if (chalLength > SHA1_MAX_BLOCK_SIZE)
      chalLength = SHA1_MAX_BLOCK_SIZE;

    memcpy(chalBuf, challenge, chalLength);

    // Initiate HMAC-SHA1 operation now

    if (m_yk.writeChallengeBegin(YKLIB_SECOND_SLOT, YKLIB_CHAL_HMAC,
                                 chalBuf, chalLength) == YKLIB_OK) {
      m_pending = true;
      yubiShowChallengeSent(); // request's in the air, setup GUI to wait for reply
    } else {
      TRACE(_T("m_yk.writeChallengeBegin() failed"));
    }
    trashMemory(chalBuf, chalLength);
  }
}
示例#6
0
void CItemField::Get(StringX &value, Fish *bf) const
{
  // Sanity check: length is 0 iff data ptr is NULL
  ASSERT((m_Length == 0 && m_Data == NULL) ||
         (m_Length > 0 && m_Data != NULL));

  if (m_Length == 0) {
    value = _T("");
  } else { // we have data to decrypt
    size_t BlockLength = GetBlockSize(m_Length);
    unsigned char *tempmem = new unsigned char[BlockLength];
    TCHAR *pt = reinterpret_cast<TCHAR *>(tempmem);
    size_t x;

    // decrypt block by block
    for (x = 0; x < BlockLength; x += 8)
      bf->Decrypt(m_Data + x, tempmem + x);

    // copy to value TCHAR by TCHAR
    for (x = 0; x < m_Length/sizeof(TCHAR); x++)
      value += pt[x];

    trashMemory(tempmem, BlockLength);
    delete [] tempmem;
  }
}
示例#7
0
PWSfileHeader &PWSfileHeader::operator=(const PWSfileHeader &h)
{
  if (this != &h) {
    m_nCurrentMajorVersion = h.m_nCurrentMajorVersion;
    m_nCurrentMinorVersion = h.m_nCurrentMinorVersion;
    m_file_uuid = h.m_file_uuid;
    m_displaystatus = h.m_displaystatus;
    m_prefString = h.m_prefString;
    m_whenlastsaved = h.m_whenlastsaved;
    m_lastsavedby = h.m_lastsavedby;
    m_lastsavedon = h.m_lastsavedon;
    m_whatlastsaved = h.m_whatlastsaved;
    m_whenpwdlastchanged = h.m_whenpwdlastchanged;
    m_DB_Name = h.m_DB_Name;
    m_DB_Description = h.m_DB_Description;
    m_RUEList = h.m_RUEList;
    if (h.m_yubi_sk != nullptr) {
      if (m_yubi_sk)
        trashMemory(m_yubi_sk, YUBI_SK_LEN);
      delete[] m_yubi_sk;
      m_yubi_sk = new unsigned char[YUBI_SK_LEN];
      memcpy(m_yubi_sk, h.m_yubi_sk, YUBI_SK_LEN);
    } else {
      m_yubi_sk = nullptr;
    }
  }
  return *this;
}
示例#8
0
/**
Burn some stack memory
@param len amount of stack to burn in bytes
*/
void burnStack(unsigned long len)
{
    unsigned char buf[32];
    trashMemory(buf, sizeof(buf));
    if (len > static_cast<unsigned long>(sizeof(buf)))
        burnStack(len - sizeof(buf));
}
示例#9
0
PWSfile::HeaderRecord &PWSfile::HeaderRecord::operator=(const PWSfile::HeaderRecord &h)
{
  if (this != &h) {
    m_nCurrentMajorVersion = h.m_nCurrentMajorVersion;
    m_nCurrentMinorVersion = h.m_nCurrentMinorVersion;
    m_file_uuid = h.m_file_uuid;
    m_displaystatus = h.m_displaystatus;
    m_prefString = h.m_prefString;
    m_whenlastsaved = h.m_whenlastsaved;
    m_lastsavedby = h.m_lastsavedby;
    m_lastsavedon = h.m_lastsavedon;
    m_whatlastsaved = h.m_whatlastsaved;
    m_dbname = h.m_dbname;
    m_dbdesc = h.m_dbdesc;
    m_RUEList = h.m_RUEList;
    if (h.m_yubi_sk != NULL) {
      if (m_yubi_sk)
        trashMemory(m_yubi_sk, YUBI_SK_LEN);
      delete[] m_yubi_sk;
      m_yubi_sk = new unsigned char[YUBI_SK_LEN];
      memcpy(m_yubi_sk, h.m_yubi_sk, YUBI_SK_LEN);
    } else {
      m_yubi_sk = NULL;
    }
  }
  return *this;
}
示例#10
0
size_t PWSfile::ReadCBC(unsigned char &type, unsigned char* &data,
                        size_t &length)
{
  unsigned char *buffer = NULL;
  size_t buffer_len = 0;
  size_t retval;

  ASSERT(m_fish != NULL && m_IV != NULL);
  retval = _readcbc(m_fd, buffer, buffer_len, type,
    m_fish, m_IV, m_terminal, m_fileLength);

  if (buffer_len > 0) {
    if (buffer_len < length || data == NULL)
      length = buffer_len; // set to length read
    // if buffer_len > length, data is truncated to length
    // probably an error.
    if (data != NULL) {
      memcpy(data, buffer, length);
      trashMemory(buffer, buffer_len);
      delete[] buffer;
    } else { // NULL data means pass buffer directly to caller
      data = buffer; // caller must trash & delete[]!
    }
  } else {
    // no need to delete[] buffer, since _readcbc will not allocate if
    // buffer_len is zero
  }
  return retval;
}
UnknownFieldEntry::~UnknownFieldEntry()
{
  if (st_length > 0 && uc_pUField != NULL) {
    trashMemory(reinterpret_cast<void *>(uc_pUField), st_length);
    delete[] uc_pUField;
    st_length = 0;
    uc_pUField = NULL;
  }
}
CPasskeyEntry::~CPasskeyEntry()
{
  ::DestroyIcon(m_hIcon);

  if (m_yubi_sk != NULL) {
    trashMemory(m_yubi_sk, PWSfile::HeaderRecord::YUBI_SK_LEN);
    delete[] m_yubi_sk;
  }
}
示例#13
0
/*
  Terminate the hash to get the digest
  @param digest The destination of the hash (32 bytes)
*/
void SHA256::Final(unsigned char digest[HASHLEN])
{
  int i;

  ASSERT(digest != NULL);

  ASSERT(curlen < sizeof(buf));

  /* increase the length of the message */
  length += curlen * 8;

  /* append the '1' bit */
  buf[curlen++] = static_cast<unsigned char>(0x80);

  /* if the length is currently above 56 bytes we append zeros
  * then compress.  Then we can fall back to padding zeros and length
  * encoding like normal.
  */
  if (curlen > 56) {
    while (curlen < 64) {
      buf[curlen++] = 0;
    }
    sha256_compress(state, buf);
    curlen = 0;
  }

  /* pad upto 56 bytes of zeroes */
  while (curlen < 56) {
    buf[curlen++] = 0;
  }

  /* store length */
  STORE64H(length, buf+56);
  sha256_compress(state, buf);

  /* copy output */
  for (i = 0; i < 8; i++) {
    STORE32H(state[i], digest+(4*i));
  }
#ifdef LTC_CLEAN_STACK
  trashMemory(state, sizeof(state));
  trashMemory(buf, sizeof(buf));
#endif
}
示例#14
0
void CSMemFile::Free(BYTE* lpMem)
{
  size_t mem_size = _msize((void *)lpMem);
  ASSERT(m_size == mem_size);
  m_size = 0;
  if (lpMem == NULL)
    return;

  if (mem_size != 0)
    trashMemory(lpMem, mem_size);

  free(lpMem);
}
UnknownFieldEntry &UnknownFieldEntry::operator=(const UnknownFieldEntry &that)
{
  if (this != &that) {
    uc_Type = that.uc_Type;
    st_length = that.st_length;
    if (uc_pUField != NULL) {
      ASSERT(st_length != 0);
      trashMemory(uc_pUField, st_length);
    }
    uc_pUField = new unsigned char[st_length];
    memcpy(uc_pUField, that.uc_pUField, st_length);
  }
  return *this;
}
示例#16
0
size_t PWSfileV1V2::WriteCBC(unsigned char type, const StringX &data)
{
  wchar_t *wcPtr = const_cast<wchar_t *>(data.c_str());
  size_t wcLen = data.length() + 1;
  size_t mbLen = 3 * wcLen;
  unsigned char *acp = new unsigned char[mbLen];
  size_t acpLen = pws_os::wcstombs(reinterpret_cast<char *>(acp), mbLen,
                                   wcPtr, wcLen, false);
  ASSERT(acpLen != 0);
  acpLen--; // remove unneeded null termination
  size_t retval = PWSfile::WriteCBC(type, acp, acpLen);
  trashMemory(acp, mbLen);
  delete[] acp;
  return retval;
}
void CViewReport::Finish()
{
  if (m_bMemoryAllocOK) {
    HLOCAL h = m_editreport.GetHandle();
    LPCWSTR lpszText = (LPCWSTR)::LocalLock(h);

    if (m_dwDatasize > 0) {
      trashMemory((void *)lpszText, m_dwDatasize);
      m_dwDatasize = 0;
    }

    ::LocalUnlock(h);
  }

  CPWResizeDialog::OnCancel();
}
BlowFish *BlowFish::MakeBlowFish(const unsigned char *pass, int passlen,
                                 const unsigned char *salt, int saltlen)
{
  unsigned char passkey[SHA1::HASHLEN];
  pws_os::mlock(passkey, sizeof(passkey));

  SHA1 context;
  context.Update(pass, passlen);
  context.Update(salt, saltlen);
  context.Final(passkey);

  BlowFish *retval = new BlowFish(passkey, sizeof(passkey));
  trashMemory(passkey, sizeof(passkey));
  pws_os::munlock(passkey, sizeof(passkey));
  return retval;
}
void CYubiMixin::yubiCheckCompleted()
{
  // We now wait for a response with the HMAC-SHA1 digest
  BYTE respBuf[SHA1_DIGEST_SIZE];
  memset(respBuf, 0, sizeof(respBuf));
  unsigned short timer;
  CSingleLock singeLock(&m_mutex);
  singeLock.Lock();
  YKLIB_RC rc = m_yk.waitForCompletion(YKLIB_NO_WAIT,
                                       respBuf, sizeof(respBuf), &timer);
  if (rc != YKLIB_PROCESSING && rc != YKLIB_TIMER_WAIT) {
    m_pending = false;
    m_yk.closeKey();
  }
  yubiProcessCompleted(rc, timer, respBuf);
  trashMemory(respBuf, sizeof(respBuf));
}
示例#20
0
bool CUTF8Conv::ToUTF8(const StringX &data,
                       const unsigned char *&utf8, size_t &utf8Len)
{
    // If we're not in Unicode, call MultiByteToWideChar to get from
    // current codepage to Unicode, and then WideCharToMultiByte to
    // get to UTF-8 encoding.
    
    if (data.empty()) {
        utf8Len = 0;
        return true;
    }
    
    wchar_t *wcPtr = const_cast<wchar_t *>(data.c_str());
    size_t wcLen = data.length()+1;
    // first get needed utf8 buffer size
    size_t mbLen = pws_os::wcstombs(NULL, 0, wcPtr, wcLen);
    
    if (mbLen == 0) { // uh-oh
        ASSERT(0);
        m_utf8Len = 0;
        return false;
    }
    // Allocate buffer (if previous allocation was smaller)
    if (mbLen > m_utf8MaxLen) {
        if (m_utf8 != NULL)
            trashMemory(m_utf8, m_utf8MaxLen);
        delete[] m_utf8;
        m_utf8 = new unsigned char[mbLen];
        m_utf8MaxLen = mbLen;
    }
    // Finally get result
    m_utf8Len = pws_os::wcstombs(reinterpret_cast<char *>(m_utf8), mbLen, wcPtr, wcLen);
    ASSERT(m_utf8Len != 0);
    m_utf8Len--; // remove unneeded null termination
    utf8 = m_utf8;
    utf8Len = m_utf8Len;
    return true;
}
示例#21
0
int PWSfileV1V2::Open(const StringX &passkey)
{
  int status = SUCCESS;

  ASSERT(m_curversion == V17 || m_curversion == V20);

  m_passkey = passkey;
  FOpen();
  if (m_fd == NULL)
    return CANT_OPEN_FILE;

  LPCTSTR passstr = m_passkey.c_str();
  size_t passLen = passkey.length();
  unsigned char *pstr;

#ifdef UNICODE
  size_t pstr_len = 3 * passLen;
  pstr = new unsigned char[pstr_len];
  size_t len = pws_os::wcstombs(reinterpret_cast<char *>(pstr), 3 * passLen, passstr, passLen, false);
  ASSERT(len != 0);
  // hack around OS-dependent semantics - too widespread to fix systematically :-(
  pstr[len < pstr_len ? len : pstr_len - 1] = '\0';
  passLen = strlen(reinterpret_cast<const char *>(pstr));
#else
  pstr = reinterpret_cast<unsigned char *>(passstr);
#endif

  if (m_rw == Write) {
    // Following used to verify passkey against file's passkey
    unsigned char randstuff[StuffSize];
    unsigned char randhash[20];   // HashSize

    PWSrand::GetInstance()->GetRandomData( randstuff, 8 );
    randstuff[8] = randstuff[9] = TCHAR('\0');
    GenRandhash(m_passkey, randstuff, randhash);

    SAFE_FWRITE(randstuff, 1, 8, m_fd);
    SAFE_FWRITE(randhash, 1, 20, m_fd);

    PWSrand::GetInstance()->GetRandomData(m_salt, SaltLength);

    SAFE_FWRITE(m_salt, 1, SaltLength, m_fd);

    PWSrand::GetInstance()->GetRandomData( m_ipthing, 8);
    SAFE_FWRITE(m_ipthing, 1, 8, m_fd);

    m_fish = BlowFish::MakeBlowFish(pstr, reinterpret_cast<int &>(passLen),
                                    m_salt, SaltLength);
    if (m_curversion == V20) {
      status = WriteV2Header();
    }
  } else { // open for read
    status = CheckPasskey(m_filename, m_passkey, m_fd);
    if (status != SUCCESS) {
#ifdef UNICODE
      trashMemory(pstr, pstr_len);
      delete[] pstr;
#endif
      Close();
      return status;
    }
    fread(m_salt, 1, SaltLength, m_fd);
    fread(m_ipthing, 1, 8, m_fd);

    m_fish = BlowFish::MakeBlowFish(pstr, reinterpret_cast<int &>(passLen),
                                    m_salt, SaltLength);
    if (m_curversion == V20)
      status = ReadV2Header();
  } // read mode
 exit:
  if (status != SUCCESS)
    Close();
#ifdef UNICODE
  trashMemory(pstr, pstr_len);
  delete[] pstr;
#endif
  return status;
}
示例#22
0
void CDDStatic::OnMouseMove(UINT nFlags, CPoint point)
{
  if (!m_bMouseInClient) {
    m_bMouseInClient = true;

    m_pci = app.GetMainDlg()->GetLastSelected();
    TRACKMOUSEEVENT tme = {sizeof(TRACKMOUSEEVENT), TME_LEAVE, CStatic::GetSafeHwnd(), 0};
    TrackMouseEvent(&tme);
  }

  if (m_TimerID == 0)
    goto StandardProcessing;

  // Check if we really moved enough
  int iX = m_StartPoint.x - point.x;
  int iY = m_StartPoint.y - point.y;
  if ((iX * iX + iY * iY) > MINIMUM_MOVE_SQUARE) {
    m_pci = app.GetMainDlg()->GetLastSelected();
    if (m_pci == NULL) {
      m_groupname = app.GetMainDlg()->GetGroupName();
    } else {
      m_groupname = L"";
    }

    // Get client rectangle
    RECT rClient;
    GetClientRect(&rClient);

    // Copy data to Clipboard if Control pressed
    if (nFlags & MK_CONTROL)
      SendToClipboard();

    // Start dragging
    m_bDropped = false;
    //pws_os::Trace(L"CDDStatic::OnMouseMove: call m_pDataSource->StartDragging\n");
    DROPEFFECT de = m_pDataSource->StartDragging(&rClient);

    if (de == DROPEFFECT_NONE) {
      // Do cleanup - otherwise this is the responsibility of the recipient!
      if (m_hgDataTXT != NULL) {
        LPVOID lpData = GlobalLock(m_hgDataTXT);
        SIZE_T memsize = GlobalSize(m_hgDataTXT);
        if (lpData != NULL) {
          trashMemory(lpData, memsize);
          GlobalUnlock(m_hgDataTXT);
        }
        GlobalFree(m_hgDataTXT);
        m_hgDataTXT = NULL;
      }
      if (m_hgDataUTXT != NULL) {
        LPVOID lpData = GlobalLock(m_hgDataUTXT);
        SIZE_T memsize = GlobalSize(m_hgDataUTXT);
        if (lpData != NULL) {
          trashMemory(lpData, memsize);
          GlobalUnlock(m_hgDataUTXT);
        }
        GlobalFree(m_hgDataUTXT);
        m_hgDataUTXT = NULL;
      }
      pws_os::Trace(L"m_pDataSource->StartDragging() failed\n");
    } else {
      pws_os::Trace(L"CDDStatic::OnMouseMove() show cursor\n");
      while (ShowCursor(TRUE) < 0)
        ;
    }

    LPARAM lparam = (LPARAM(point.y) << 16) | LPARAM(point.x);
    ::SendMessage(GetActiveWindow()->GetSafeHwnd(), WM_LBUTTONUP, 0, lparam);
  }

StandardProcessing:
  CStatic::OnMouseMove(nFlags, point);
}
示例#23
0
// In following, char * is managed by caller.
bool CUTF8Conv::FromUTF8(const unsigned char *utf8, size_t utf8Len,
                         StringX &data)
{
  // Call MultiByteToWideChar to get from UTF-8 to Unicode.
  // If we're not in Unicode, call WideCharToMultiByte to
  // get to current codepage.
  //
  // Due to a bug in pre-3.08 versions, data may be in ACP
  // instead of UTF-8. We try to detect and workaround this.

  if (utf8Len == 0 || (utf8Len == 1 && utf8[0] == '\0')) {
    data = _T("");
    return true;
  }

  ASSERT(utf8 != NULL);

  // first get needed wide char buffer size
  size_t wcLen = pws_os::mbstowcs(NULL, 0,
                                  reinterpret_cast<const char *>(utf8),
                                  size_t(-1), !m_cp_acp);
  if (wcLen == 0) { // uh-oh
    // it seems that this always returns non-zero, even if encoding
    // broken. Therefore, we'll give a conservative value here,
    // and try to recover later
    pws_os::Trace0(_T("FromUTF8: Couldn't get buffer size - guessing!"));
    wcLen = sizeof(StringX::value_type) * (utf8Len + 1);
  }
  // Allocate buffer (if previous allocation was smaller)
  if (wcLen > m_wcMaxLen) {
    if (m_wc != NULL)
      trashMemory(m_wc, m_wcMaxLen);
    delete[] m_wc;
    m_wc = new wchar_t[wcLen];
    m_wcMaxLen = wcLen;
  }
  // next translate to buffer
  wcLen = pws_os::mbstowcs(m_wc, wcLen,
                           reinterpret_cast<const char *>(utf8),
                           size_t(-1), !m_cp_acp);
#ifdef _WIN32
  if (wcLen == 0) {
    DWORD errCode = GetLastError();
    switch (errCode) {
    case ERROR_INSUFFICIENT_BUFFER:
      pws_os::Trace0(_T("INSUFFICIENT BUFFER")); break;
    case ERROR_INVALID_FLAGS:
      pws_os::Trace0(_T("INVALID FLAGS")); break;
    case ERROR_INVALID_PARAMETER:
      pws_os::Trace0(_T("INVALID PARAMETER")); break;
    case ERROR_NO_UNICODE_TRANSLATION:
      // try to recover
      pws_os::Trace0(_T("NO UNICODE TRANSLATION"));
      wcLen = MultiByteToWideChar(CP_ACP,        // code page
                                  0,             // character-type options
                                  LPSTR(utf8),   // string to map
                                  -1,            // -1 means null-terminated
                                  m_wc,          // output buffer
                                  reinterpret_cast<int &>(wcLen));  // output buffer size
      if (wcLen > 0) {
        pws_os::Trace0(_T("FromUTF8: recovery succeeded!"));
      }
      break;
    default:
      ASSERT(0);
    }
  }
  ASSERT(wcLen != 0);
#endif /* _WIN32 */
#ifdef UNICODE
  if (wcLen != 0) {
    m_wc[wcLen - 1] = TCHAR('\0');
    data = m_wc;
    return true;
  } else
    return false;
#else /* Go from Unicode to Locale encoding */
  // first get needed utf8 buffer size
  size_t mbLen = pws_os::wcstombs(NULL, 0, m_wc, size_t(-1), false);
  if (mbLen == 0) { // uh-oh
    ASSERT(0);
    data = _T("");
    return false;
  }
  // Allocate buffer (if previous allocation was smaller)
  if (mbLen > m_tmpMaxLen) {
    if (m_tmp != NULL)
      trashMemory(m_tmp, m_tmpMaxLen);
    delete[] m_tmp;
    m_tmp = new unsigned char[mbLen];
    m_tmpMaxLen = mbLen;
  }
  // Finally get result
  size_t tmpLen = pws_os::wcstombs((char *)m_tmp, mbLen, m_wc, size_t(-1), false);
  ASSERT(tmpLen == mbLen);
  m_tmp[mbLen - 1] = '\0'; // char, no need to _T()...
  data = (char *)m_tmp;
  ASSERT(!data.empty());
  return true;
#endif /* !UNICODE */
}
示例#24
0
PWSfileHeader::~PWSfileHeader()
{
  if (m_yubi_sk)
    trashMemory(m_yubi_sk, YUBI_SK_LEN);
  delete[] m_yubi_sk;
}
示例#25
0
BOOL CDDStatic::OnRenderGlobalData(LPFORMATETC lpFormatEtc, HGLOBAL* phGlobal)
{
  pws_os::Trace(L"CDDStatic::OnRenderGlobalData: %s; ci == %p\n",
          lpFormatEtc->cfFormat == CF_UNICODETEXT ? L"CF_UNICODETEXT" : L"CF_TEXT",
          m_pci);

  if (lpFormatEtc->cfFormat != CF_UNICODETEXT &&
      lpFormatEtc->cfFormat != CF_TEXT)
    return FALSE;

  if (m_hgDataTXT != NULL) {
    pws_os::Trace(L"CDDStatic::OnRenderGlobalData - Unlock/Free m_hgDataTXT\n");
    GlobalUnlock(m_hgDataTXT);
    GlobalFree(m_hgDataTXT);
    m_hgDataTXT = NULL;
  }

  if (m_hgDataUTXT != NULL) {
    pws_os::Trace(L"CDDStatic::OnRenderGlobalData - Unlock/Free m_hgDataUTXT\n");
    GlobalUnlock(m_hgDataUTXT);
    GlobalFree(m_hgDataUTXT);
    m_hgDataUTXT = NULL;
  }

  StringX cs_dragdata;
  if (m_pci == NULL) {
    if (m_groupname.empty()) {
      pws_os::Trace(L"CDDStatic::OnRenderGlobalData - mpci == NULL\n");
      return FALSE;
    } else {
      cs_dragdata = m_groupname;
    }
  } else { // m_pci != NULL
    const CItemData *pci(m_pci);

    // Handle shortcut or alias
    if ((m_nID == IDC_STATIC_DRAGPASSWORD && pci->IsAlias()) ||
        (pci->IsShortcut() && (m_nID != IDC_STATIC_DRAGGROUP &&
                               m_nID != IDC_STATIC_DRAGTITLE &&
                               m_nID != IDC_STATIC_DRAGUSER))) {
      pci = app.GetMainDlg()->GetBaseEntry(pci);
    }
    cs_dragdata = GetData(pci);
    if (cs_dragdata.empty() && m_nID != IDC_STATIC_DRAGAUTO)
      return FALSE;
  }

  const size_t ilen = cs_dragdata.length();
  if (ilen == 0 && m_nID != IDC_STATIC_DRAGAUTO) {
    // Nothing to do - why were we even called???
    return FALSE;
  }

  DWORD dwBufLen;
  LPSTR lpszA(NULL);
  LPWSTR lpszW(NULL);

  if (lpFormatEtc->cfFormat == CF_UNICODETEXT) {
    // So is requested data!
    dwBufLen = (DWORD)((ilen + 1) * sizeof(wchar_t));
    lpszW = new WCHAR[ilen + 1];
    //pws_os::Trace(L"lpszW allocated %p, size %d\n", lpszW, dwBufLen);
    if (ilen == 0) {
      lpszW[ilen] = L'\0';
    } else {
      (void) wcsncpy_s(lpszW, ilen + 1, cs_dragdata.c_str(), ilen);
    }
  } else {
    // They want it in ASCII - use lpszW temporarily
    if (ilen == 0) {
      dwBufLen = 1;
      lpszA = new char[dwBufLen];
      lpszA = '\0';
    } else {
      lpszW = const_cast<LPWSTR>(cs_dragdata.c_str());
      dwBufLen = WideCharToMultiByte(CP_ACP, 0, lpszW, -1, NULL, 0, NULL, NULL);
      ASSERT(dwBufLen != 0);
      lpszA = new char[dwBufLen];
      pws_os::Trace(L"lpszA allocated %p, size %d\n", lpszA, dwBufLen);
      WideCharToMultiByte(CP_ACP, 0, lpszW, -1, lpszA, dwBufLen, NULL, NULL);
      lpszW = NULL;
    }
  }

  LPVOID lpData(NULL);
  LPVOID lpDataBuffer;
  HGLOBAL *phgData;
  if (lpFormatEtc->cfFormat == CF_UNICODETEXT) {
    lpDataBuffer = (LPVOID)lpszW;
    phgData = &m_hgDataUTXT;
  } else {
    lpDataBuffer = (LPVOID)lpszA;
    phgData = &m_hgDataTXT;
  }

  BOOL retval(FALSE);
  if (*phGlobal == NULL) {
    //pws_os::Trace(L"CDDStatic::OnRenderGlobalData - Alloc global memory\n");
    *phgData = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBufLen);
    ASSERT(*phgData != NULL);
    if (*phgData == NULL)
      goto bad_return;

    lpData = GlobalLock(*phgData);
    ASSERT(lpData != NULL);
    if (lpData == NULL)
      goto bad_return;

    // Copy data
    memcpy(lpData, lpDataBuffer, dwBufLen);
    *phGlobal = *phgData;
    retval = TRUE;
  } else {
    pws_os::Trace(L"CDDStatic::OnRenderGlobalData - *phGlobal NOT NULL!\n");
    SIZE_T inSize = GlobalSize(*phGlobal);
    SIZE_T ourSize = GlobalSize(*phgData);
    if (inSize < ourSize) {
      // Pre-allocated space too small.  Not allowed to increase it - FAIL
      pws_os::Trace(L"CDDStatic::OnRenderGlobalData - NOT enough room - FAIL\n");
    } else {
      // Enough room - copy our data into supplied area
      pws_os::Trace(L"CDDStatic::OnRenderGlobalData - enough room - copy our data\n");
      LPVOID pInGlobalLock = GlobalLock(*phGlobal);
      ASSERT(pInGlobalLock != NULL);
      if (pInGlobalLock == NULL)
        goto bad_return;

      memcpy(pInGlobalLock, lpDataBuffer, ourSize);
      GlobalUnlock(*phGlobal);
      retval = TRUE;
    }
  }

bad_return:
  // Finished with buffer - trash it
  trashMemory(lpDataBuffer, dwBufLen);
  // Free the strings (only one is actually in use)
  //pws_os::Trace(L"lpszA freed %p\n", lpszA);
  delete[] lpszA;
  //pws_os::Trace(L"lpszW freed %p\n", lpszW);
  delete[] lpszW;
  // Since lpDataBuffer pointed to one of the above - just zero the pointer
  lpDataBuffer = NULL;

  // If retval == TRUE, recipient is responsible for freeing the global memory
  // if D&D succeeds (see after StartDragging in OnMouseMove)
  if (retval == FALSE) {
    pws_os::Trace(L"CDDStatic::OnRenderGlobalData - returning FALSE!\n");
    if (lpData != NULL) {
      GlobalFree(*phgData);
      *phgData = NULL;
    }
  } else {
    pws_os::Trace(L"CDDStatic::OnRenderGlobalData - D&D Data:");
    if (lpFormatEtc->cfFormat == CF_UNICODETEXT) {
      pws_os::Trace(L"\"%ls\"\n", (LPWSTR)lpData);  // data is Unicode
    } else {
      pws_os::Trace(L"\"%hs\"\n", (LPSTR)lpData);  // data is NOT Unicode
    }
  }
  // Unlock our buffer
  if (lpData != NULL)
    GlobalUnlock(*phgData);

  return retval;
}
示例#26
0
bool PWSfile::Encrypt(const stringT &fn, const StringX &passwd, stringT &errmess)
{
  ulong64 len = 0;
  size_t slen = 0;
  unsigned char* buf = nullptr;
  Fish *fish = nullptr;
  bool status = true;
  const stringT out_fn = fn + CIPHERTEXT_SUFFIX;
  unsigned char *pwd = nullptr;
  size_t passlen = 0;
  FILE *out = nullptr;

  FILE *in = pws_os::FOpen(fn, _T("rb"));
  if (in == nullptr) {
    status = false; goto exit;
  }

  len = pws_os::fileLength(in);

  if (len > std::numeric_limits<uint32>::max()) {
    fclose(in);
    errno = EFBIG;
    status = false;
    goto exit;
  }

  slen = static_cast<size_t>(len);
  buf = new unsigned char[slen];

  fread(buf, 1, slen, in);
  if (ferror(in)) { // this is how to detect fread errors
    status = false;
    int save_error = errno;
    fclose(in);
    errno = save_error;
    goto exit;
  }
  if (fclose(in) != 0) {
    status = false;
    goto exit;
  }

  out = pws_os::FOpen(out_fn, _T("wb"));
  if (out == nullptr) {
    status = false; goto exit;
  }
  unsigned char randstuff[StuffSize];
  unsigned char randhash[SHA1::HASHLEN];   // HashSize
  PWSrand::GetInstance()->GetRandomData( randstuff, 8 );
  // miserable bug - have to fix this way to avoid breaking existing files
  randstuff[8] = randstuff[9] = TCHAR('\0');
  GenRandhash(passwd, randstuff, randhash);
  SAFE_FWRITE(randstuff, 1,  8, out);
  SAFE_FWRITE(randhash,  1, sizeof(randhash), out);

  unsigned char thesalt[SaltLength];
  PWSrand::GetInstance()->GetRandomData( thesalt, SaltLength );
  SAFE_FWRITE(thesalt, 1, SaltLength, out);

  unsigned char ipthing[8];
  PWSrand::GetInstance()->GetRandomData( ipthing, 8 );
  SAFE_FWRITE(ipthing, 1, 8, out);

  ConvertPasskey(passwd, pwd, passlen);
  fish = BlowFish::MakeBlowFish(pwd, reinterpret_cast<unsigned int &>(passlen), thesalt, SaltLength);
  trashMemory(pwd, passlen);
  delete[] pwd; // gross - ConvertPasskey allocates.
  try {
    _writecbc(out, buf, slen, 0, fish, ipthing);
  } catch (...) { // _writecbc throws an exception if it fails to write
    fclose(out);
    errno = EIO;
    status = false;
    goto exit;
  }
  status = (fclose(out) == 0);
 exit:
  if (!status)
    errmess = ErrorMessages();
  delete fish;
  delete[] buf;
  return status;
}
示例#27
0
bool PWSfile::Decrypt(const stringT &fn, const StringX &passwd, stringT &errmess)
{
  size_t len;
  unsigned char* buf = NULL;
  bool status = true;
  unsigned char salt[SaltLength];
  unsigned char ipthing[8];
  unsigned char randstuff[StuffSize];
  unsigned char randhash[SHA1::HASHLEN];
  unsigned char temphash[SHA1::HASHLEN];

  FILE *in = pws_os::FOpen(fn, _T("rb"));
  if (in == NULL) {
    status = false;
    goto exit;
  }

#ifdef KEEP_FILE_MODE_BWD_COMPAT
  uint32 i32;
  fread(&i32, 1, sizeof(uint32), in); // XXX portability issue
  len = i32;
#else
  fread(randstuff, 1, 8, in);
  randstuff[8] = randstuff[9] = TCHAR('\0'); // ugly bug workaround
  fread(randhash, 1, sizeof(randhash), in);

  GenRandhash(passwd, randstuff, temphash);
  if (memcmp(reinterpret_cast<char *>(randhash), reinterpret_cast<char *>(temphash), SHA1::HASHLEN) != 0) {
    fclose(in);
    LoadAString(errmess, IDSC_BADPASSWORD);
    return false;
  }
#endif // KEEP_FILE_MODE_BWD_COMPAT

  { // decryption in a block, since we use goto
    fread(salt,    1, SaltLength, in);
    fread(ipthing, 1, 8,          in);

    unsigned char dummyType;
    unsigned char *pwd = NULL;
    size_t passlen = 0;
    long file_len = pws_os::fileLength(in);
    ConvertString(passwd, pwd, passlen);
    Fish *fish = BlowFish::MakeBlowFish(pwd, reinterpret_cast<int &>(passlen), salt, SaltLength);
    trashMemory(pwd, passlen);
#ifdef UNICODE
    delete[] pwd; // gross - ConvertString allocates only if UNICODE.
#endif
    if (_readcbc(in, buf, len,dummyType, fish, ipthing, 0, file_len) == 0) {
      delete fish;
      delete[] buf; // if not yet allocated, delete[] NULL, which is OK
      return false;
    }
    delete fish;
    fclose(in);
  } // decrypt

  { // write decrypted data
    size_t suffix_len = CIPHERTEXT_SUFFIX.length();
    size_t filepath_len = fn.length();

    stringT out_fn = fn;
    out_fn = out_fn.substr(0,filepath_len - suffix_len);

    FILE *out = pws_os::FOpen(out_fn, _T("wb"));
    if (out != NULL) {
      size_t fret = fwrite(buf, 1, len, out);
      if (fret != len) {
        int save_errno = errno;
        fclose(out);
        errno = save_errno;
        goto exit;
      }
      if (fclose(out) != 0) {
        status = false;
        goto exit;
      }
    } else { // open failed
      status = false;
      goto exit;
    }
  } // write decrypted
 exit:
  if (!status)
    errmess = ErrorMessages();
  delete[] buf; // allocated by _readcbc
  return status;
}
示例#28
0
bool PWSfile::Encrypt(const stringT &fn, const StringX &passwd, stringT &errmess)
{
  unsigned int len = 0;
  unsigned char* buf = NULL;
  Fish *fish = NULL;
  bool status = true;
  stringT out_fn;
  unsigned char *pwd = NULL;
  size_t passlen = 0;
  FILE *out = NULL;

  FILE *in = pws_os::FOpen(fn, _T("rb"));;
  if (in != NULL) {
    len = pws_os::fileLength(in);
    buf = new unsigned char[len];

    fread(buf, 1, len, in);
    if (ferror(in)) { // this is how to detect fread errors
      status = false;
      int save_error = errno;
      fclose(in);
      errno = save_error;
      goto exit;
    }
    if (fclose(in) != 0) {
      status = false;
      goto exit;
    }
  } else {
    status = false; goto exit;
  }

  out_fn = fn;
  out_fn += CIPHERTEXT_SUFFIX;

  out = pws_os::FOpen(out_fn, _T("wb"));
  if (out == NULL) {
    status = false; goto exit;
  }
#ifdef KEEP_FILE_MODE_BWD_COMPAT
  uint32 i32 = len;
  SAFE_FWRITE(&i32, 1, sizeof(uint32), out);
#else
  unsigned char randstuff[StuffSize];
  unsigned char randhash[SHA1::HASHLEN];   // HashSize
  PWSrand::GetInstance()->GetRandomData( randstuff, 8 );
  // miserable bug - have to fix this way to avoid breaking existing files
  randstuff[8] = randstuff[9] = TCHAR('\0');
  GenRandhash(passwd, randstuff, randhash);
  SAFE_FWRITE(randstuff, 1,  8, out);
  SAFE_FWRITE(randhash,  1, sizeof(randhash), out);
#endif // KEEP_FILE_MODE_BWD_COMPAT

  unsigned char thesalt[SaltLength];
  PWSrand::GetInstance()->GetRandomData( thesalt, SaltLength );
  SAFE_FWRITE(thesalt, 1, SaltLength, out);

  unsigned char ipthing[8];
  PWSrand::GetInstance()->GetRandomData( ipthing, 8 );
  SAFE_FWRITE(ipthing, 1, 8, out);

  ConvertString(passwd, pwd, passlen);
  fish = BlowFish::MakeBlowFish(pwd, reinterpret_cast<int &>(passlen), thesalt, SaltLength);
  trashMemory(pwd, passlen);
#ifdef UNICODE
  delete[] pwd; // gross - ConvertString allocates only if UNICODE.
#endif
  try {
    _writecbc(out, buf, len, 0, fish, ipthing);
  } catch (...) { // _writecbc throws an exception if it fails to write
    fclose(out);
    errno = EIO;
    status = false;
    goto exit;
  }
  status = (fclose(out) == 0);
 exit:
  if (!status)
    errmess = ErrorMessages();
  delete fish;
  delete[] buf;
  return status;
}
示例#29
0
bool PWSfile::Decrypt(const stringT &fn, const StringX &passwd, stringT &errmess)
{
  ulong64 file_len;
  size_t len;
  unsigned char* buf = nullptr;
  bool status = true;
  unsigned char salt[SaltLength];
  unsigned char ipthing[8];
  unsigned char randstuff[StuffSize];
  unsigned char randhash[SHA1::HASHLEN];
  unsigned char temphash[SHA1::HASHLEN];

  FILE *in = pws_os::FOpen(fn, _T("rb"));
  if (in == nullptr) {
    status = false;
    goto exit;
  }

  file_len = pws_os::fileLength(in);

  if (file_len < (8 + sizeof(randhash) + 8 + SaltLength)) {
    fclose(in);
    LoadAString(errmess, IDSC_FILE_TOO_SHORT);
    return false;
  }

  fread(randstuff, 1, 8, in);
  randstuff[8] = randstuff[9] = TCHAR('\0'); // ugly bug workaround
  fread(randhash, 1, sizeof(randhash), in);

  GenRandhash(passwd, randstuff, temphash);
  if (memcmp(reinterpret_cast<char *>(randhash), reinterpret_cast<char *>(temphash), SHA1::HASHLEN) != 0) {
    fclose(in);
    LoadAString(errmess, IDSC_BADPASSWORD);
    return false;
  }

  { // decryption in a block, since we use goto
    fread(salt,    1, SaltLength, in);
    fread(ipthing, 1, 8,          in);

    unsigned char dummyType;
    unsigned char *pwd = nullptr;
    size_t passlen = 0;
    ConvertPasskey(passwd, pwd, passlen);
    Fish *fish = BlowFish::MakeBlowFish(pwd, reinterpret_cast<unsigned int &>(passlen), salt, SaltLength);
    trashMemory(pwd, passlen);
    delete[] pwd; // gross - ConvertPasskey allocates.
    if (_readcbc(in, buf, len,dummyType, fish, ipthing, 0, file_len) == 0) {
      delete fish;
      delete[] buf; // if not yet allocated, delete[] nullptr, which is OK
      return false;
    }
    delete fish;
    fclose(in);
  } // decrypt

  { // write decrypted data
    size_t suffix_len = CIPHERTEXT_SUFFIX.length();
    size_t filepath_len = fn.length();

    stringT out_fn = fn;
    out_fn = out_fn.substr(0,filepath_len - suffix_len);

    FILE *out = pws_os::FOpen(out_fn, _T("wb"));
    if (out != nullptr) {
      size_t fret = fwrite(buf, 1, len, out);
      if (fret != len) {
        int save_errno = errno;
        fclose(out);
        errno = save_errno;
        goto exit;
      }
      if (fclose(out) != 0) {
        status = false;
        goto exit;
      }
    } else { // open failed
      status = false;
      goto exit;
    }
  } // write decrypted
 exit:
  if (!status)
    errmess = ErrorMessages();
  delete[] buf; // allocated by _readcbc
  return status;
}
示例#30
0
PWSfile::HeaderRecord::~HeaderRecord()
{
  if (m_yubi_sk)
    trashMemory(m_yubi_sk, YUBI_SK_LEN);
  delete[] m_yubi_sk;
}