Files
EgtLock/KeyProc.cpp
T
DarioS 7a4efed8cf EgtLock 2.5a1 :
- ricompilazione con cambio versione.
2023-01-03 08:55:35 +01:00

230 lines
8.2 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2014-2023
//----------------------------------------------------------------------------
// File : KeyProc.cpp Data : 01.01.23 Versione : 2.5a1
// Contenuto : Funzioni per la gestione della chiave.
//
//
//
// Modifiche : 10.09.14 DS Creazione modulo.
// 29.02.16 DS Controllo prodotti con & (and bit a bit).
// 12.07.16 DS In recupero opzioni, se chiave ko azzero risultati.
// 26.12.20 DS Gestione versione MMmm (vecchie chiavi convertite).
//
//----------------------------------------------------------------------------
//------------------ Include -------------------------------------------------
#include "stdafx.h"
#include <time.h>
#include "LockId.h"
#include "Obfuscate.h"
#include "/EgtDev/Include/EGnStringUtils.h"
#include "/EgtDev/Include/EgtNumUtils.h"
#include "/EgtDev/Include/EgtBase64.h"
#include "/EgtDev/Include/EgtCrc32.h"
#include "/EgtDev/Include/SELkKeyProc.h"
#include "/EgtDev/Include/SELkLockId.h"
using namespace std ;
//----------------------------------------------------------------------------
static const int MIN_DAYS = 19358 ; // giorni dal 01/01/1970 al 01/01/2023
static const int N_STEP = 7 ;
//----------------------------------------------------------------------------
bool
MakeKey( int nProd, int nVer, int nLev, int nExpDays,
unsigned int nOpt1, unsigned int nOpt2, int nOptExpDays,
const string& sScramKey, string& sKey)
{
// sistemazioni per nuova versione mensile valide fino alla 2806
// ( 16->16, 19->19, 21->21, 22->22, 2201->22, 2202->23 ... 2212->33, 2301->34, 2302->35 ... 2312->45)
int nVerNew ;
if ( nVer >= 1 && nVer <= 22)
nVerNew = nVer ;
else if ( nVer >= 2201) {
int nVerY = ( nVer >= 100 ? nVer / 100 : nVer) ;
int nVerM = ( nVer >= 100 ? Clamp( nVer % 100 - 1, 0, 11) : 0) ;
nVerNew = Clamp( 22 + 12 * ( nVerY - 22) + nVerM, 0, 99) ;
}
else
return false ;
// inizializzo parte pseudorandom
srand( nVerNew + nLev) ;
// preparo la stringa da criptare
string sClearKey ;
sClearKey += ToString( ( rand() % 9), 1) ;
sClearKey += ToString( nProd, 4) ;
sClearKey += ToString( nVerNew, 2) ;
sClearKey += ToString( nLev, 2) ;
sClearKey += ToString( ( rand() % 9), 1) ;
sClearKey += ToString( nExpDays, 6) ;
sClearKey += ToString( ( rand() % 9), 1) ;
sClearKey += " " ;
sClearKey[17] = ( nOpt1 >> 0) & 0xFF ;
sClearKey[18] = ( nOpt1 >> 8) & 0xFF ;
sClearKey[19] = ( nOpt1 >> 16) & 0xFF ;
sClearKey[20] = ( nOpt1 >> 24) & 0xFF ;
sClearKey += " " ;
sClearKey[21] = ( nOpt2 >> 0) & 0xFF ;
sClearKey[22] = ( nOpt2 >> 8) & 0xFF ;
sClearKey[23] = ( nOpt2 >> 16) & 0xFF ;
sClearKey[24] = ( nOpt2 >> 24) & 0xFF ;
sClearKey += ToString( ( rand() % 9), 1) ;
sClearKey += ToString( nOptExpDays, 6) ;
// eseguo la cifratura
string sMidKey = sClearKey ;
if ( ! ScrambleData( sMidKey, sScramKey, N_STEP))
return false ;
// aggiungo Crc32
AddCrc32ToString( sMidKey) ;
// trasformo in Base64
return B64Encode( sMidKey, sKey) ;
}
//----------------------------------------------------------------------------
bool
ReadKey( const string& sKey, const string& sScramKey,
int& nProd, int& nVer, int& nLev, int& nExpDays,
unsigned int& nOpt1, unsigned int& nOpt2, int& nOptExpDays)
{
// decodifico da Base64
string sClearKey ;
if ( ! B64Decode( sKey, sClearKey))
return false ;
// verifico e tolgo CRC32
if ( ! TestCrc32AndRemoveFromString( sClearKey))
return false ;
// eseguo la decifratura
if ( ! UnScrambleData( sClearKey, sScramKey, N_STEP))
return false ;
// verifico la lunghezza della stringa risultante
if ( sClearKey.length() != 32)
return false ;
// leggo le varie parti
if ( ! FromString( sClearKey.substr( 1, 4), nProd))
return false ;
if ( ! FromString( sClearKey.substr( 5, 2), nVer))
return false ;
if ( ! FromString( sClearKey.substr( 7, 2), nLev))
return false ;
if ( ! FromString( sClearKey.substr( 10, 6), nExpDays))
return false ;
nOpt1 = ((unsigned char)sClearKey[17]) | ( ((unsigned char)sClearKey[18]) << 8) |
( ((unsigned char)sClearKey[19]) << 16) | ( ((unsigned char)sClearKey[20]) << 24) ;
nOpt2 = ((unsigned char)sClearKey[21]) | ( ((unsigned char)sClearKey[22]) << 8) |
( ((unsigned char)sClearKey[23]) << 16) | ( ((unsigned char)sClearKey[24]) << 24) ;
if ( ! FromString( sClearKey.substr( 26, 6), nOptExpDays))
return false ;
// sistemazioni per nuova versione mensile valide fino alla 2806
// ( 2201->22, 2202->23 ... 2212->33, 2301->34, 2302->35 ... 2312->45)
if ( nVer > 22) {
int nVerY = 22 + ( nVer - 22) / 12 ;
int nVerM = nVer - ( 22 + 12 * ( nVerY - 22)) ;
nVer = nVerY * 100 + nVerM + 1 ;
}
return true ;
}
//----------------------------------------------------------------------------
static int
VerifyKey( const string& sKey, int nProd, int nVer, int nLev,
int& nKProd, int& nKVer, int& nKLev, int& nKExpDays,
unsigned int& nKOpt1, unsigned int& nKOpt2, int& nKOptExpDays)
{
// creo la chiave di scramble
string sLockId2 ;
if ( ! GetLockId2( sLockId2))
return KEY_ERR_MACHID ;
string sScramKey ;
if ( ! ConvertLockId2ToScramKey( sLockId2, sScramKey))
return KEY_ERR_SCRAMKEY ;
// recupero le informazioni nella chiave
if ( ! ReadKey( sKey, sScramKey,
nKProd, nKVer, nKLev, nKExpDays,
nKOpt1, nKOpt2, nKOptExpDays))
return KEY_ERR_KEYDECODE ;
// aggiusto i dati di versione
if ( nVer < 100)
nVer = nVer * 100 + 7 ;
if ( nKVer < 100)
nKVer = nKVer * 100 + 7 ;
// verifico dati prodotto
if ( ( nProd & nKProd) != nProd)
return KEY_ERR_PROD ;
if ( nVer > nKVer + 100)
return KEY_ERR_VER ;
if ( nLev > nKLev)
return KEY_ERR_LEV ;
// verifico scadenza
int nDays = GetCurrDay() ;
if ( nDays < MIN_DAYS)
return KEY_ERR_WRONG_TIME ;
if ( nDays > nKExpDays)
return KEY_ERR_TIME ;
return KEY_OK ;
}
//----------------------------------------------------------------------------
int
VerifyKey( const string& sKey, int nProd, int nVer, int nLev)
{
int nKProd, nKVer, nKLev, nKExpDays ;
unsigned int nKOpt1, nKOpt2 ;
int nKOptExpDays ;
return VerifyKey( sKey, nProd, nVer, nLev,
nKProd, nKVer, nKLev, nKExpDays,
nKOpt1, nKOpt2, nKOptExpDays) ;
}
//----------------------------------------------------------------------------
int
GetKeyLevel( const string& sKey, int nProd, int nVer, int nLev,
int& nKLev, int& nKExpDays)
{
int nKProd, nKVer ;
unsigned int nKOpt1, nKOpt2 ;
int nKOptExpDays ;
int nErr = VerifyKey( sKey, nProd, nVer, nLev,
nKProd, nKVer, nKLev, nKExpDays,
nKOpt1, nKOpt2, nKOptExpDays) ;
if ( nErr != KEY_OK) {
nKLev = 0 ;
nKExpDays = 0 ;
}
return nErr ;
}
//----------------------------------------------------------------------------
int
GetKeyOptions( const string& sKey, int nProd, int nVer, int nLev,
unsigned int& nKOpt1, unsigned int& nKOpt2, int& nKOptExpDays)
{
int nKProd, nKVer, nKLev, nKExpDays ;
int nErr = VerifyKey( sKey, nProd, nVer, nLev,
nKProd, nKVer, nKLev, nKExpDays,
nKOpt1, nKOpt2, nKOptExpDays) ;
if ( nErr != KEY_OK) {
nKOpt1 = 0 ;
nKOpt2 = 0 ;
nKOptExpDays = 0 ;
}
return nErr ;
}
//----------------------------------------------------------------------------
int
GetCurrDay( void)
{
time_t nClock = time( nullptr) ; // secondi da 00:00:00 1/1/1970 in UTC
long nDelta ; // offset tra UTC e tempo locale (nDelta = T_UTC - T_LOC)
_tzset() ;
if ( _get_timezone( &nDelta) != 0) // con errore nessun offset
nDelta = 0 ;
int nDays = int( ( nClock - nDelta) / ( 24 * 3600)) ; // (24*3600) secondi in un giorno
return nDays ;
}