<commit_before>#include "PWSfileV3.h"
#include "UUIDGen.h"

#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>

static unsigned char TERMINAL_BLOCK[TwoFish::BLOCKSIZE] = {
  'P', 'W', 'S', '3', '-', 'E', 'O', 'F',
  'P', 'W', 'S', '3', '-', 'E', 'O', 'F'};

PWSfileV3::PWSfileV3(const CMyString &filename, RWmode mode, VERSION version)
  : PWSfile(filename,mode)
{
  m_curversion = version;
  m_IV = m_ipthing;
  m_terminal = TERMINAL_BLOCK;
}

PWSfileV3::~PWSfileV3()
{
}

int PWSfileV3::Open(const CMyString &passkey)
{
  int status = SUCCESS;

  ASSERT(m_curversion == V30);

  m_passkey = passkey;

  if (m_rw == Write) {
#ifdef UNICODE
    m_fd = _wfopen((LPCTSTR)m_filename, _T("wb") );
#else
    m_fd = fopen((LPCTSTR)m_filename, _T("wb") );
#endif

    if (m_fd == NULL)
      return CANT_OPEN_FILE;

    status = WriteHeader();
  } else { // open for read
#ifdef UNICODE
    m_fd = _wfopen((LPCTSTR) m_filename, _T("rb"));
#else
    m_fd = fopen((LPCTSTR) m_filename, _T("rb"));
#endif

    if (m_fd == NULL)
      return CANT_OPEN_FILE;
    status = ReadHeader();
    if (status != SUCCESS) {
      Close();
      return status;
    }
  }
  return status;
}

int PWSfileV3::Close()
{
  if (m_fd == NULL)
    return SUCCESS; // idempotent

  unsigned char digest[HMAC_SHA256::HASHLEN];
  m_hmac.Final(digest);

  // Write or verify HMAC, depending on RWmode.
  if (m_rw == Write) {
    fwrite(TERMINAL_BLOCK, sizeof(TERMINAL_BLOCK), 1, m_fd);
    fwrite(digest, sizeof(digest), 1, m_fd);
    return PWSfile::Close();
  } else { // Read
    // We're here *after* TERMINAL_BLOCK has been read
    // and detected (by _readcbc) - just read hmac & verify
    unsigned char d[HMAC_SHA256::HASHLEN];
    fread(d, sizeof(d), 1, m_fd);
    if (memcmp(d, digest, HMAC_SHA256::HASHLEN) == 0)
      return PWSfile::Close();
    else {
      PWSfile::Close();
      return BAD_DIGEST;
    }
  }
}

const char V3TAG[4] = {'P','W','S','3'}; // ASCII chars, not wchar

int PWSfileV3::CheckPassword(const CMyString &filename,
                             const CMyString &passkey,
                             FILE *a_fd, unsigned char *aPtag)
{
  FILE *fd = a_fd;
  if (fd == NULL) {
#ifdef UNICODE
    fd = _wfopen((LPCTSTR) filename, _T("rb"));
#else
    fd = fopen((LPCTSTR) filename, _T("rb"));
#endif
  }
  if (fd == NULL)
    return CANT_OPEN_FILE;

  char tag[sizeof(V3TAG)];
  fread(tag, 1, sizeof(tag), fd);
  if (memcmp(tag, V3TAG, sizeof(tag)) != 0) {
    return NOT_PWS3_FILE;
  }

  unsigned char salt[SaltLengthV3];
  fread(salt, 1, sizeof(salt), fd);

  unsigned char Ptag[SHA256::HASHLEN];
  if (aPtag == NULL)
    aPtag = Ptag;
  LPCSTR passstr = LPCSTR(passkey); 
  StretchKey(salt, sizeof(salt),
             (const unsigned char *)passstr, passkey.GetLength(),
             aPtag);

  unsigned char HPtag[SHA256::HASHLEN];
  SHA256 H;
  H.Update(aPtag, SHA256::HASHLEN);
  H.Final(HPtag);
  unsigned char readHPtag[SHA256::HASHLEN];
  fread(readHPtag, 1, sizeof(readHPtag), fd);
  if (memcmp(readHPtag, HPtag, sizeof(readHPtag)) != 0) {
    return WRONG_PASSWORD;
  }

   if (a_fd == NULL) // if we opened the file, we close it...
     fclose(fd);
   return SUCCESS;
}

int PWSfileV3::WriteCBC(unsigned char type, const CString &data)
{
  LPCSTR d = LPCSTR(data);
  m_hmac.Update((const unsigned char *)d, data.GetLength());

  return PWSfile::WriteCBC(type, data);
}

int PWSfileV3::WriteCBC(unsigned char type, const unsigned char *data,
                        unsigned int length)
{
  m_hmac.Update(data, length);
  return PWSfile::WriteCBC(type, data, length);
}


int PWSfileV3::WriteRecord(const CItemData &item)
{
  ASSERT(m_fd != NULL);
  ASSERT(m_curversion != UNKNOWN_VERSION);
  int status = SUCCESS;
  // XXX TBD

  return status;
}

int
PWSfileV3::ReadCBC(unsigned char &type, CMyString &data)
{
  int status = PWSfile::ReadCBC(type, data);

  if (status == SUCCESS) {
    LPCSTR d = LPCSTR(data);
    m_hmac.Update((const unsigned char *)d, data.GetLength());
  }

  return status;
}

int PWSfileV3::ReadCBC(unsigned char &type, unsigned char *data,
                       unsigned int &length)
{
  int status = PWSfile::ReadCBC(type, data, length);

  if (status == SUCCESS) {
    m_hmac.Update(data, length);
  }

  return status;
}


int PWSfileV3::ReadRecord(CItemData &item)
{
  ASSERT(m_fd != NULL);
  ASSERT(m_curversion == V30);

  CMyString tempdata;  
  int numread = 0;
  unsigned char type;<commit_msg>Write and Read empty v3 file success!<commit_after>#include "PWSfileV3.h"
#include "UUIDGen.h"

#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>

static unsigned char TERMINAL_BLOCK[TwoFish::BLOCKSIZE] = {
  'P', 'W', 'S', '3', '-', 'E', 'O', 'F',
  'P', 'W', 'S', '3', '-', 'E', 'O', 'F'};

PWSfileV3::PWSfileV3(const CMyString &filename, RWmode mode, VERSION version)
  : PWSfile(filename,mode)
{
  m_curversion = version;
  m_IV = m_ipthing;
  m_terminal = TERMINAL_BLOCK;
}

PWSfileV3::~PWSfileV3()
{
}

int PWSfileV3::Open(const CMyString &passkey)
{
  int status = SUCCESS;

  ASSERT(m_curversion == V30);

  m_passkey = passkey;

  if (m_rw == Write) {
#ifdef UNICODE
    m_fd = _wfopen((LPCTSTR)m_filename, _T("wb") );
#else
    m_fd = fopen((LPCTSTR)m_filename, _T("wb") );
#endif

    if (m_fd == NULL)
      return CANT_OPEN_FILE;

    status = WriteHeader();
  } else { // open for read
#ifdef UNICODE
    m_fd = _wfopen((LPCTSTR) m_filename, _T("rb"));
#else
    m_fd = fopen((LPCTSTR) m_filename, _T("rb"));
#endif

    if (m_fd == NULL)
      return CANT_OPEN_FILE;
    status = ReadHeader();
    if (status != SUCCESS) {
      Close();
      return status;
    }
  }
  return status;
}

int PWSfileV3::Close()
{
  if (m_fd == NULL)
    return SUCCESS; // idempotent

  unsigned char digest[HMAC_SHA256::HASHLEN];
  m_hmac.Final(digest);

  // Write or verify HMAC, depending on RWmode.
  if (m_rw == Write) {
    fwrite(TERMINAL_BLOCK, sizeof(TERMINAL_BLOCK), 1, m_fd);
    fwrite(digest, sizeof(digest), 1, m_fd);
    return PWSfile::Close();
  } else { // Read
    // We're here *after* TERMINAL_BLOCK has been read
    // and detected (by _readcbc) - just read hmac & verify
    unsigned char d[HMAC_SHA256::HASHLEN];
    fread(d, sizeof(d), 1, m_fd);
    if (memcmp(d, digest, HMAC_SHA256::HASHLEN) == 0)
      return PWSfile::Close();
    else {
      PWSfile::Close();
      return BAD_DIGEST;
    }
  }
}

const char V3TAG[4] = {'P','W','S','3'}; // ASCII chars, not wchar

int PWSfileV3::CheckPassword(const CMyString &filename,
                             const CMyString &passkey,
                             FILE *a_fd, unsigned char *aPtag)
{
  FILE *fd = a_fd;
  if (fd == NULL) {
#ifdef UNICODE
    fd = _wfopen((LPCTSTR) filename, _T("rb"));
#else
    fd = fopen((LPCTSTR) filename, _T("rb"));
#endif
  }
  if (fd == NULL)
    return CANT_OPEN_FILE;

  char tag[sizeof(V3TAG)];
  fread(tag, 1, sizeof(tag), fd);
  if (memcmp(tag, V3TAG, sizeof(tag)) != 0) {
    return NOT_PWS3_FILE;
  }

  unsigned char salt[SaltLengthV3];
  fread(salt, 1, sizeof(salt), fd);

  unsigned char Ptag[SHA256::HASHLEN];
  if (aPtag == NULL)
    aPtag = Ptag;
  LPCSTR passstr = LPCSTR(passkey); 
  StretchKey(salt, sizeof(salt),
             (const unsigned char *)passstr, passkey.GetLength(),
             aPtag);

  unsigned char HPtag[SHA256::HASHLEN];
  SHA256 H;
  H.Update(aPtag, SHA256::HASHLEN);
  H.Final(HPtag);
  unsigned char readHPtag[SHA256::HASHLEN];
  fread(readHPtag, 1, sizeof(readHPtag), fd);
  if (memcmp(readHPtag, HPtag, sizeof(readHPtag)) != 0) {
    return WRONG_PASSWORD;
  }

   if (a_fd == NULL) // if we opened the file, we close it...
     fclose(fd);
   return SUCCESS;
}

int PWSfileV3::WriteCBC(unsigned char type, const CString &data)
{
  LPCSTR d = LPCSTR(data);
  return WriteCBC(type, (const unsigned char *)d, data.GetLength());
}

int PWSfileV3::WriteCBC(unsigned char type, const unsigned char *data,
                        unsigned int length)
{
  m_hmac.Update(data, length);
  return PWSfile::WriteCBC(type, data, length);
}


int PWSfileV3::WriteRecord(const CItemData &item)
{
  ASSERT(m_fd != NULL);
  ASSERT(m_curversion != UNKNOWN_VERSION);
  int status = SUCCESS;
  // XXX TBD

  return status;
}

int
PWSfileV3::ReadCBC(unsigned char &type, CMyString &data)
{
  int numRead = PWSfile::ReadCBC(type, data);

  if (numRead > 0) {
    LPCSTR d = LPCSTR(data);
    m_hmac.Update((const unsigned char *)d, data.GetLength());
  }

  return numRead;
}

int PWSfileV3::ReadCBC(unsigned char &type, unsigned char *data,
                       unsigned int &length)
{
  int numRead = PWSfile::ReadCBC(type, data, length);

  if (numRead > 0) {
    m_hmac.Update(data, length);
  }

  return numRead;
}


int PWSfileV3::ReadRecord(CItemData &item)
{
  ASSERT(m_fd != NULL);
  ASSERT(m_curversion == V30);

  CMyString tempdata;  
  int numread = 0;
  unsigned char type;
{'fraction_non_alphanumeric': 0.15102589976454758, 'fraction_numerical': 0.014015024105841462, 'mean_word_length': 3.368266405484819, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1866365', 'n_tokens_mistral': 3590, 'n_tokens_neox': 3415, 'n_words': 808}