/*
*  Naamari - an AES/SHA-based manual file crypto-synchronizer for cloud transfers
*  Copyright (c) 2015-2017 Sunkware
*  Key FP = 6B6D C8E9 3438 6E9C 3D97  56E5 2CE9 A476 99EF 28F6
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*  See the GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*  ----------------------------------------------------------------
*  WWW:       sunkware.org
*  E-mail:    sunkware@gmail.com
*  ----------------------------------------------------------------
*/

#include "contextglob.h"


namespace cryptrav
{

void           ContextGlob::clearKeys(void)
{
 memset(keyR, 0, KEY_SIZE);
 memset(keyC, 0, KEY_SIZE);
 memset(keyS, 0, KEY_SIZE);
 memset(keyH, 0, KEY_SIZE);
 memset(keyB, 0, KEY_SIZE);
}

void           ContextGlob::Reset(void)
{
 clearKeys();
 areKeysReady = false;

 pathHallway = "";
 isHallwayReady = false;

 pathNominis = "";
 isNominisReady = false;

 pathHarbour = "";
 isHarbourReady = false;

 passTermChr = 0;
}

ContextGlob::ContextGlob()
{
 Reset();
}


quint8*        ContextGlob::getKeyR(void)
{
 return keyR;
}

quint8*        ContextGlob::getKeyC(void)
{
 return keyC;
}

quint8*        ContextGlob::getKeyS(void)
{
 return keyS;
}

quint8*        ContextGlob::getKeyH(void)
{
 return keyH;
}

quint8*        ContextGlob::getKeyB(void)
{
 return keyB;
}


qint32         ContextGlob::loadKeys(QString pathFile, quint8* passHash)
{
 areKeysReady = false;
 clearKeys();


 if (passHash == NULL)
  return (-1);

 Hasher hasher;


 if ( !QFile::exists(pathFile) )
  return (-2);

 QFile keysFile(pathFile);

 if ( !keysFile.open(QIODevice::ReadOnly) )
  return (-3);

 if ( keysFile.size() != KEYSFILE_SIZE )
  {
   keysFile.close();
   return (-4);
  }


// Randomen key...
 keysFile.read((char *)keyR, KEY_SIZE);
 hasher.init();
 hasher.update(keyR, KEY_SIZE);
 hasher.update(passHash, HASH_SIZE);
 hasher.final(keyR); // relies on KEY_SIZE == HASH_SIZE

// Cryptomen key...
 keysFile.read((char *)keyC, KEY_SIZE);
 hasher.init();
 hasher.update(keyC, KEY_SIZE);
 hasher.update(passHash, HASH_SIZE);
 hasher.final(keyC);

// Salt key...
 keysFile.read((char *)keyS, KEY_SIZE);
 hasher.init();
 hasher.update(keyS, KEY_SIZE);
 hasher.update(passHash, HASH_SIZE);
 hasher.final(keyS);

// Integrity hash key...
 keysFile.read((char *)keyH, KEY_SIZE);
 hasher.init();
 hasher.update(keyH, KEY_SIZE);
 hasher.update(passHash, HASH_SIZE);
 hasher.final(keyH);

// Per-block-key key...
 keysFile.read((char *)keyB, KEY_SIZE);
 hasher.init();
 hasher.update(keyB, KEY_SIZE);
 hasher.update(passHash, HASH_SIZE);
 hasher.final(keyB);


 keysFile.close();


 areKeysReady = true;

 return 0;
}


QString        ContextGlob::getHallwayPath(void)
{
 return pathHallway;
}

bool           ContextGlob::setHallwayPath(QString path)
{
 isHallwayReady = false;
 pathHallway.clear();

 if ( path.endsWith("/") )
  path.chop(1);

 isHallwayReady = QDir(path).exists();

 if (isHallwayReady)
  pathHallway = path;

 return isHallwayReady;
}


QString        ContextGlob::getNominisPath(void)
{
 return pathNominis;
}

bool           ContextGlob::setNominisPath(QString path)
{
 isNominisReady = false;
 pathNominis.clear();

 if ( path.endsWith("/") )
  path.chop(1);

 isNominisReady = QDir(path).exists();

 if (isNominisReady)
  pathNominis = path;

 return isNominisReady;
}


QString        ContextGlob::getHarbourPath(void)
{
 return pathHarbour;
}

bool           ContextGlob::setHarbourPath(QString path)
{
 isHarbourReady = false;
 pathHarbour.clear();

 if ( path.endsWith("/") )
  path.chop(1);

 isHarbourReady = QDir(path).exists();

 if (isHarbourReady)
  pathHarbour = path;

 return isHarbourReady;
}


quint8       ContextGlob::getPassTermChr(void)
{
 return passTermChr;
}

void         ContextGlob::setPassTermChr(quint8 chr)
{
 passTermChr = chr;
}


bool           ContextGlob::areKeysSet(void)
{
 return        areKeysReady;
}

bool           ContextGlob::isReady(void)
{
 return ( areKeysReady && isHallwayReady && isNominisReady && isHarbourReady );
}


ContextGlob::~ContextGlob() // mostly for security reasons...
{
 Reset();
}


} // namespace "cryptrav"
