EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Error : Index out of bounds.

Also by EldoS: CallbackProcess
A component to control process creation and termination in Windows and .NET applications.
#18223
Posted: 11/17/2011 04:14:10
by David MICHEL (Standard support level)
Joined: 09/23/2009
Posts: 48

Hi,

I am using PKCS#11 component to work with USB Security token. There is a x.509 certificate in the token.
I open a session with password to use the certificate.

From time to time, I have an error message which occurs : Index out of bounds.

What could generate this error ?

Thank you.


Sincerely yours,
David MICHEL.
#18224
Posted: 11/17/2011 04:21:12
by Vsevolod Ievgiienko (EldoS Corp.)

Thank you for contacting us.

Its hard to say what could be the reason without additional information.

Try to check if the same error occurs if you work with the token using our demo that is located in \EldoS\SecureBlackbox\Samples\Delphi\PKIBlackbox\PKCS11\CertStorage.
#18225
Posted: 11/17/2011 04:39:50
by Eugene Mayevski (EldoS Corp.)

Also please try to reproduce the problem under debugger and if the error happens, capture the call stack.


Sincerely yours
Eugene Mayevski
#18226
Posted: 11/17/2011 04:48:17
by David MICHEL (Standard support level)
Joined: 09/23/2009
Posts: 48

Thank you for your answer.

I took as a starting point the demonstration which is in \EldoS\SecureBlackbox\Samples\Delphi\PKIBlackbox\PKCS11\CertStorage.

Precisely, this morning I try to reproduce the error without success. It occurs randomly.

I call the functions since SignatureDigital (...);

My code :

Code
var  
  Storage      : TElPKCS11CertStorage;
  Session      : TElPKCS11SessionInfo;
  Cert         : TElX509Certificate;
  CertStorage  : TElMemoryCertStorage;
  Signer       : TElMessageSigner;
  FichierDLL   : TFileName;

...

function TAuthSignature.SignatureDigital(fileASigner, fileDLL: TFileName ; MDPToken: String ; SerialUtil: String = ''): TFileName;
var
  SlotToken : Integer;
  Session   : Integer;
  Signature : TFileName;
begin

  MDP := MDPToken;

  //On va detecter un slot (port usb active)
  SlotToken := DetectionSlot(fileDLL);
  if (SlotToken < 0) then
  begin
    Result := '';
    Exit;
  end;

  //Ici un slot active, on va maintenant ouvrir une session
  Session := OpenSession(SlotToken, MDPToken);  //Ouverture d'une session
  if (Session < 0) then
  begin
    Result := '';
    Exit;
  end;

  //On contrôle la valeur SerialNumber du certificat avec celui sauvegardé dans la table
  //pour contrôler si l'util ne tente pas de signer avec un autre certificat autre que le sien
  if (SerialUtil <> '') then
  begin
    if (SerialUtil <> SerialNumber) then
    begin
      MessageBox(GetForegroundWindow,PChar('Erreur de Certificat !' + #13
                            + 'Impossible de signer le fichier. Le certificat de signature avec lequel vous souhaitez signer' + #13
                            + 'ne correspond pas avec celui enregistré pour l''utilisateur en cours.'),'Erreur !',MB_ICONERROR + MB_OK);
      Result := '';
      Exit;
    end;
  end;

  //Ici, le token est activé, on va pouvoir signer
  Signature := SignaturePersonnelle(fileASigner);
  if (Signature = '') then
  begin
    Result := '';
    //CertStorage.Free;
    Exit;
  end;

  //CertStorage.Free;
  Result := Signature;

end;

//DetectionSlot
function TAuthSignature.DetectionSlot(FichDLL: TFileName): Integer;
begin

  FichierDLL := FichDLL;

  if (Storage <> nil) then
    CloseStorage();

  OpenStorage();

  //Si Resultat = -1
  if (Resultat < 0) then
    CloseStorage();

  Result := Resultat;

end;

//OpenStorage
procedure TAuthSignature.OpenStorage();
var
  SlotInfo       : TElPKCS11SlotInfo;
  Path           : String;
  Present        : Boolean;
  i              : Integer;
  NbTokenPresent : Integer;
begin

  Present := False;
  NbTokenPresent := 0;

  //Si le chemin du fichier DLL est renseigné et que le fichier existe
  if (FichierDLL <> '') then
  begin

    Storage := TElPKCS11CertStorage.Create(Nil);
    try
      Storage.DLLName := FichierDLL;
      Path := ExtractFilePath(Storage.DLLName);

      if (Path <> '') then
        SetCurrentDir(Path);

      try
        Storage.Open;

        //Si on détecte au moins 2 token de connecté, on stoppe et on demande à l'utilisateur de ne laisser qu'un seul token sur un port usb
        for i := 0 to Storage.Module.SlotCount - 1 do
        begin
          SlotInfo := Storage.Module.Slot[i];
          //Si le token est détecté et connecté
          if Storage.Module.Slot[i].TokenPresent then
          begin
            Inc(NbTokenPresent);
          end;
        end;

        if (NbTokenPresent >= 2) then
        begin
          MessageBox(GetForegroundWindow,PChar('Plusieurs clés usb ont été détectées.' + #13 + 'Veuillez ne laisser qu''une clé usb de connecté.'),'Attention !',MB_ICONWARNING + MB_OK);
          Present  := True;
          Resultat := -1;
          Exit;
        end;

        for i := 0 to Storage.Module.SlotCount - 1 do
        begin
          SlotInfo := Storage.Module.Slot[i];

          //Si le token est détecté et connecté
          if Storage.Module.Slot[i].TokenPresent then
          begin
            Present  := True;
            Resultat := i;  //Si Present, on retourne l'index du port
            Break;
          end
          else begin
            Present  := False;
            Resultat := -1;
          end;
        end;

      except
        on E : Exception do
        begin
          FreeAndNil(Storage);
          //MessageBox(GetForegroundWindow,PChar('Erreur de lecture de la clé : ' + FichierDLL + #13#10 + E.Message),'Erreur !',MB_ICONERROR + MB_OK);
          MessageBox(GetForegroundWindow,PChar('Erreur de lecture de la clé. La DLL n''a pas été trouvée.' +#13+ FichierDLL),'Erreur !',MB_ICONERROR + MB_OK);
          Present  := True;  //Pour ne pas afficher le message se trouvant dans le finally
          Resultat := -1;
          Exit;
        end;
      end;

    finally
      if (not Present) then
        MessageBox(GetForegroundWindow,PChar('Aucune clé n''a été détectée.'),'Erreur !',MB_ICONERROR + MB_OK);
    end;

  end
  else begin
    FreeAndNil(Storage);
    MessageBox(GetForegroundWindow,PChar('Erreur de Certificat !' + #13 + 'Veuillez indiquer le chemin du fichier DLL.'),'Erreur !',MB_ICONERROR+MB_OK);
    Resultat := -1;
  end;

end;

//OpenSession
function TAuthSignature.OpenSession(IntSlot: Integer ; MDPToken: String): Integer;
var
  Pin : string;
  RO  : boolean;
begin

  MDP := MDPToken;

  //Fermeture de la session si déjà ouverte
  if (Session <> nil) then
  begin
    Session.Logout;
    Storage.CloseSession(0);
    Session := Nil;
  end;

  //Ouverture d'une nouvelle session
  RO := Storage.Module.Slot[IntSlot].ReadOnly;
  try
    Session := Storage.OpenSession(IntSlot, RO);
  except
    on E : EElCertStorageError do
    begin
      if not RO then
        Session := Storage.OpenSession(IntSlot, True)
      else
        Raise;
    end;
  end;

  Pin := MDPToken;
  if (Session <> Nil) and (Pin <> '') then
  begin
    try
      Session.Login(utUser, Pin);
    except
      Storage.CloseSession(0);
      Session := nil;
      MessageBox(GetForegroundWindow,PChar('Erreur de mot de passe !'),'Erreur !',MB_ICONERROR + MB_OK);
      Resultat := -1;
      Result := Resultat;
      Exit;
    end;
  end;

  //On mémorise le certificat
  LoadCertificat(IntSlot);

  Resultat := 0;  //Ok
  Result := Resultat;

end;

procedure TAuthSignature.LoadCertificat(NumSlot: Integer);
var
  fnDest : TFileName;
begin

  CertStorage := TElMemoryCertStorage.Create(nil);
  try
    Cert := Storage.Certificates[NumSlot];
  finally
    Cert.Free;
  end;

end;

//SignaturePersonnelle
function TAuthSignature.SignaturePersonnelle(fnSourceSigner: TFileName): TFileName;
var
  InBuffer  : ByteArray;
  OutBuffer : ByteArray;
  Stream    : TFileStream;
  FichDest  : TFileName;
  InSize    : Integer;
  OutSize   : Integer;
  Res       : Integer;

  Signature  : TElRSAPublicKeyCrypto;
  fsSource   : TFileStream;
  fsDest     : TFileStream;

begin

  //Fichier de sortie de la Signature
  FichDest := frmEspBanqueMain.repTemp + frmEspBanqueMain.FUtilisateur.Idf + '\' + 'DigitalSign.sig';

  Signature := TElRSAPublicKeyCrypto.Create(SB_CERT_ALGORITHM_SHA256_RSA_ENCRYPTION);
  try
    try

      //Paramètres de la signature
      Signature.KeyMaterial := Cert.KeyMaterial;
      Signature.CryptoType  := rsapktPKCS1;

      Signature.UseAlgorithmPrefix := True;

      //Format fichier source et destination
      Signature.InputEncoding  := pkeBinary;  //Fichier de destination => Format binaire
      Signature.OutputEncoding := pkeBase64;  //Fichier source => Format B64

      fsSource := TFileStream.Create(fnSourceSigner, fmOpenRead);
      try//fsSource
        fsDest := TFileStream.Create(FichDest, fmCreate);
        try//fsDest
          //Signature du document
          Signature.SignDetached(fsSource, fsDest);
        finally
          FreeAndNil(fsDest);
        end;//fsDest
      finally
        FreeAndNil(fsSource);
      end;//fsSource

    except
      Result := '';
      exit;
    end;

    Result := FichDest;

  finally
    FreeAndNil(Signature);
  end;

end;


Thank you.


Sincerely yours,
David MICHEL.
#18227
Posted: 11/17/2011 05:10:27
by Vsevolod Ievgiienko (EldoS Corp.)

From the first point of view the code is correct. Are you sure that SBB is a source of the error? Could you please post a call stack.
#18257
Posted: 11/21/2011 10:04:59
by David MICHEL (Standard support level)
Joined: 09/23/2009
Posts: 48

Hi,

The error is in this function :

Code
procedure TAuthSignature.LoadCertificat(NumSlot: Integer);
var
  fnDest : TFileName;
begin

  CertStorage := TElMemoryCertStorage.Create(nil);
  try
    Cert := Storage.Certificates[NumSlot];
  finally
    Cert.Free;
  end;

end;


Indeed if NumSlot = 2, one has the error : out Index of bounds.

NumSlot is the number of the slot (OpenSession) where the token is connected.
And not the number of the certificate (Storage.Count, Storage.Certificates[i]);

On the other hand with Windows XP NumSlot = 0 whereas in Windows Seven NumSlot = 2 (From where the error).

Thank you.


Sincerely yours,
David MICHEL.
#18262
Posted: 11/22/2011 03:45:56
by Ken Ivanov (EldoS Corp.)

So do I understand right that the issue is resolved now?
#18265
Posted: 11/22/2011 08:01:33
by David MICHEL (Standard support level)
Joined: 09/23/2009
Posts: 48

Yes, the problem is solved.

Thank you.


Sincerely yours,
David MICHEL.
Also by EldoS: CallbackRegistry
A component to monitor and control Windows registry access and create virtual registry keys.

Reply

Statistics

Topic viewed 1357 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!