unit CardEx;

interface
  uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, kbFileCrypt ;
var
  card_connected: boolean = false;
  infinity: boolean;


function connect: boolean;
function GetUserId : string ;
function GetFullId : string ;
function CardCrypt (buf:string) : string ;
function CardDeCrypt (buf:string) : string ;
function CardPass (buf:string) : string ;
function GetUser : string ;
function GetPass : string ;
function CardDestroy : boolean;
function CardBlock : boolean;

implementation
  uses
     uemUser, uemBase, uemTypes, xutil, xCrypt;

const module_required_access_level = 3;
const kb_cr = #$0D#$0A;


function CardCrypt (buf:string) : string ;
const p1_des3key42                       = $38; //content extractor
const p2_des3key42_k11_encrypt_cbc       = $11;
var buffer_8_byte: string;
begin
  if not connect then exit; //just to check is card initialized and ready to work

  {$I VM_Start.inc}
//  {$I crypt_start.inc}
//  AntiDebug();     //execryptor
//  ProtectImport(); //execryptor

  if (not e.access_module_is_active(3)) then
  begin
    ShowMessage('card not activated for this operation');
      Application.Terminate;
    exit;
  end;


  //блоками кратными 8 байт !!!

   buffer_8_byte := buf;

   buffer_8_byte:= e.card_apdu(e.current_cla, e.current_ins, p1_des3key42, p2_des3key42_k11_encrypt_cbc, length(buffer_8_byte), buffer_8_byte);
   Result:= buffer_8_byte;
//    {$I crypt_end.inc}
  {$I VM_End.inc}
end;
function CardPass (buf:string) : string ;
const p1_des3key42                       = $38; //content extractor
const p2_des3key42_k01_encrypt_cbc       = $01;
var buffer_8_byte: string;
begin
//  if not connect then exit; //just to check is card initialized and ready to work

  {$I VM_Start.inc}
//  {$I crypt_start.inc}
//  AntiDebug();     //execryptor
//  ProtectImport(); //execryptor

{  if (not e.access_module_is_active(kb_module_access_level_content_extractor)) then
  begin
    ShowMessage('card not activated for this operation');
      Application.Terminate;
    exit;
  end;
 }

  //блоками кратными 8 байт !!!

   buffer_8_byte := buf;
   buffer_8_byte := e.card_apdu(e.current_cla, e.current_ins, p1_des3key42, p2_des3key42_k01_encrypt_cbc, length(buffer_8_byte), buffer_8_byte);

   Result:= buffer_8_byte;
//    {$I crypt_end.inc}
  {$I VM_End.inc}
end;

function CardDeCrypt (buf:string) : string ;
const p1_des3key42                       = $38; //content extractor
const p2_des3key42_k11_decrypt_cbc       = $11;
var buffer_8_byte: string;
begin
  if not connect then exit; //just to check is card initialized and ready to work

  {$I VM_Start.inc}
//  {$I crypt_start.inc}
//  AntiDebug();     //execryptor
//  ProtectImport(); //execryptor

  if (not e.access_module_is_active(3)) then
  begin
    ShowMessage('card not activated for this operation');
      Application.Terminate;
    exit;
  end;


  //блоками кратными 8 байт !!!

   buffer_8_byte := buf;
   buffer_8_byte := e.card_apdu(e.current_cla, e.current_ins, p1_des3key42, p2_des3key42_k11_decrypt_cbc, length(buffer_8_byte), buffer_8_byte);

   Result:= buffer_8_byte;
//    {$I crypt_end.inc}
  {$I VM_End.inc}
end;

function GetFullId : string ;
begin
  {$I VM_Start.inc}
//    {$I crypt_start.inc}
    Result:='00000000';
    if not connect then begin Application.Terminate; exit; end;
    Result:=e.id_box_no_complete ;
//    {$I crypt_end.inc}
  {$I VM_End.inc}
end;

function GetUser : string ;
begin
  {$I VM_Start.inc}
//    {$I crypt_start.inc}
    Result:='';
    if not connect then begin Application.Terminate; exit; end;
    Result:=e.idUserName ;
//    {$I crypt_end.inc}
  {$I VM_End.inc}
end;

function GetPass : string ;
begin
  {$I VM_Start.inc}
//    {$I crypt_start.inc}
    Result:='';
    if not connect then begin Application.Terminate; exit; end;
    Result:=e.idUserPass;
//    {$I crypt_end.inc}
  {$I VM_End.inc}
end;

function GetUserId : string ;

begin
  {$I VM_Start.inc}
//    {$I crypt_start.inc}
    Result:='Dongle not found';
    if not connect then begin Application.Terminate; exit; end;
    Result:= 'S/N '+inttohex(e.IdBoxNo,4)+':'+inttohex(e.IdBoxVer,4);
//    {$I crypt_end.inc}
  {$I VM_End.inc}
end;


function connect: boolean;
var
    buf: string;
begin

  {$I VM_Start.inc}
//    {$I crypt_start.inc}
//    AntiDebug();     //execryptor
//    ProtectImport(); //execryptor
    result := true;
    if card_connected then exit;
    result := false;

    e := TEGMUser.create;
   dd := ddc.create(e, nil);
    e.ExclusiveConnectionMode := kb_is_egate_exclusive;
    box_found := false;
    //assign required card access module_no & bitmask
    e.access_module_no := kb_module_access_level_bb5_easy; //либо = kb_module_access_level_content_extractor;

    //load applet parameters from database
    e.initialize(e.access_module_no);

    e.RequiredCardAID := #$E7#$11#$0F#$31#$AB#$01;
    if e.SysInit then
    begin
      if e.connect('', e.RequiredCardAID) then //card found
      begin
        e.apdu_SelectAID(e.RequiredCardAID);
        box_found := true;
        infinity:=true;
      end
      else
      begin
       e.RequiredCardAID := #$E7#$11#$0F#$34#$AB#$01;
      if e.connect('', e.RequiredCardAID) then //card found
      begin
        e.apdu_SelectAID(e.RequiredCardAID);
        box_found := true;
        infinity:=false;
      end
      else     MessageDlg('Dongle is not connected',mtError,[mbOK],0);
     end;
    end;
    if not box_found then
    begin
      buf := uem_ALERT_BOX_NOT_FOUND;
      MessageDlg(uem_ALERT_BOX_NOT_FOUND+' !'+KB_CR+'Connect Dongle and restart software.', mtInformation, [mbOk], 0);
      Application.Terminate;
      exit;
    end;

//    if not box_found then begin Application.Terminate; exit; end;

// check current/required card firmware version
   if e.IdBoxVer < e.id_applet_version_required_min then
    begin
      buf := 'Dongle firmware['+IntToHex(e.IdBoxVer,4)+'] is out of date !'+kb_cr+kb_cr+
             'Download latest upgrade-client (DongleManager) from support area'+kb_cr+
             'and upgrade dongle firmware.';
//      Log.Lines.Add(buf);
      MessageDlg(buf, mtInformation, [mbOk], 0);
      Application.Terminate;
      exit;
    end;

    e.access_module_no := module_required_access_level;
    if (e.idAccessBitmask and $8) <> $8 then
    begin
      buf := 'Dongle['+e.id_box_no_complete+'] is not activated for current software module.'+kb_cr+
             'current dongle activation level: '+IntToHex(e.idAccessBitmask,4)+kb_cr+
             'required dongle activation level: '+IntToHex(e.required_access_bitmask,4)+kb_cr+
             'Contact to your reseller to get information about additional activation.';
//      Log.Lines.Add(buf);
      MessageDlg(Buf, mtInformation, [mbOk], 0);
      Application.Terminate;
      exit;
    end;

    Application.ProcessMessages;
    result := true;
    card_connected := true;
//    {$I crypt_end.inc}
  {$I VM_End.inc}
end;

function CardDestroy : boolean;
begin
    e.card_apdu($88, $10, $03, $00, $01, #$FF);
    Result:=true;
end;

function CardBlock: boolean;
begin
    e.card_apdu($88, $27, $03, $00, $01, #$FF);
    Result:=true;
end;

end.
