0abaaacff6
- correzione calcolo giorni di assistenza per versioni da 3.1 in poi.
306 lines
11 KiB
C++
306 lines
11 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2014-2026
|
|
//----------------------------------------------------------------------------
|
|
// File : KeyProc.cpp Data : 02.01.26 Versione : 3.1a1
|
|
// 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).
|
|
// 24.01.24 DS Aggiunta GetKeyLevelEx con anche giorni scadenza assistenza.
|
|
// 02.01.26 DS Aggiunta gestione versioni da 2801 a 36812.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
//------------------ 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 = 20454 ; // giorni dal 01/01/1970 al 01/01/2026
|
|
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 2712
|
|
// ( 16->16, 19->19, 21->21, 22->22, 2201->22, 2202->23 ... 2212->33, 2301->34, 2302->35 ... 2312->45, 2701->82 ... 2712->93)
|
|
// nuove sistemazioni valide dalla 2801 alla 36812 (sempre NNN01 ... NNN12, dove NNN è la versione e il resto è il mese)
|
|
int nVerNew = 0 ;
|
|
int nVerTot = 0 ;
|
|
int nVerA1 = -1 ;
|
|
int nVerA2 = -1 ;
|
|
if ( nVer >= 1 && nVer <= 22) {
|
|
nVerNew = nVer ;
|
|
nVerTot = nVerNew ;
|
|
}
|
|
else if ( nVer >= 2201 && nVer <= 2712) {
|
|
int nVerY = nVer / 100 ;
|
|
int nVerM = Clamp( nVer % 100 - 1, 0, 11) ;
|
|
nVerNew = Clamp( 22 + 12 * ( nVerY - 22) + nVerM, 0, 99) ;
|
|
nVerTot = nVerNew ;
|
|
}
|
|
else if ( nVer >= 2801 && nVer <= 36812) {
|
|
int nVerY = nVer / 100 ;
|
|
int nVerM = Clamp( nVer % 100 - 1, 0, 11) ;
|
|
nVerNew = Clamp( 94 + nVerY % 6, 94, 99) ;
|
|
nVerTot = Clamp( 12 * ( nVerY - 28) + nVerM, 0, 4095) ;
|
|
nVerA1 = nVerTot / 64 ;
|
|
nVerA2 = nVerTot % 64 ;
|
|
}
|
|
else
|
|
return false ;
|
|
// inizializzo parte pseudorandom
|
|
srand( nVerTot + 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) ;
|
|
if ( nVerA1 >= 0) sClearKey[16] = nVerA1 + 63 ;
|
|
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) ;
|
|
if ( nVerA2 >= 0) sClearKey[25] = nVerA2 + 63 ;
|
|
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 2712
|
|
// ( 16->16, 19->19, 21->21, 22->22, 2201->22, 2202->23 ... 2212->33, 2301->34, 2302->35 ... 2312->45, 2701->82 ... 2712->93)
|
|
// nuove sistemazioni valide dalla 2801 alla 36812 (sempre NNN01 ... NNN12, dove NNN è la versione e il resto è il mese)
|
|
if ( nVer > 93) {
|
|
int nVerA1 = sClearKey[16] - 63 ;
|
|
int nVerA2 = sClearKey[25] - 63 ;
|
|
int nVerTot = nVerA1 * 64 + nVerA2 ;
|
|
int nVerY = 28 + nVerTot / 12 ;
|
|
int nVerM = nVerTot - ( 12 * ( nVerY - 28)) ;
|
|
nVer = nVerY * 100 + nVerM + 1 ;
|
|
}
|
|
else 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)) {
|
|
if ( NotFoundNetHwKey())
|
|
return KEY_ERR_NETKEY_NOTFOUND ;
|
|
else
|
|
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 (da 2712 si salta a 3101)
|
|
if ( nVer < 100)
|
|
nVer = nVer * 100 + 7 ;
|
|
if ( nKVer < 100)
|
|
nKVer = nKVer * 100 + 7 ;
|
|
else if ( nKVer >= 2701 && nKVer <= 2712)
|
|
nKVer += 300 ;
|
|
// 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
|
|
GetKeyLevelEx( const string& sKey, int nProd, int nVer, int nLev,
|
|
int& nKLev, int& nKExpDays, int& nKAssExpDays)
|
|
{
|
|
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 ;
|
|
nKAssExpDays = 0 ;
|
|
}
|
|
else {
|
|
// sistemazioni per vecchie gestioni chiavi
|
|
// 16xx -> 17xx, 18xx -> 18xx, 19xx -> 19xx, 21xx -> 20xx, 22xx -> 21xx, ... , 27xx -> 26xx, 31xx -> 27xx, ...
|
|
int nKAssEnd = nKVer + ( nKVer < 1800 ? 100 : ( nKVer < 2000 ? 0 : ( nKVer < 3100 ? -100 : -400))) ;
|
|
// si considera il primo giorno del mese successivo (mesi sono 0-based, con dicembre si va a gennaio anno dopo)
|
|
int nKAssEndM = Clamp( nKAssEnd % 100, 1, 12) ;
|
|
int nKAssEndY = nKAssEnd / 100 + 100 ;
|
|
if ( nKAssEndM == 12) {
|
|
nKAssEndM = 0 ;
|
|
nKAssEndY += 1 ;
|
|
}
|
|
struct tm tmAssEnd = { 0, 0, 0, 1, nKAssEndM, nKAssEndY, 0, 0, 0} ;
|
|
time_t nClock = mktime( &tmAssEnd) ;
|
|
nKAssExpDays = int( nClock / ( 24 * 3600)) ; // (24*3600) secondi in un giorno
|
|
nKAssExpDays = min( nKAssExpDays, nKExpDays) ;
|
|
}
|
|
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 ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
GetMinDay( void)
|
|
{
|
|
return MIN_DAYS ;
|
|
}
|