示例#1
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;
}
示例#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
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;
}
示例#4
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;
}