delphix509certificatecef4delphi

CEF4Delphi certificate selection window


I'm using CEF4Delphi to browse a site, this site asks for a certificate installed on windows, the documentation says I need to select this certificate in the "SelectClientCertificate" event in a callback function passing the index, my question is how to show this certificate window to select one of them

procedure TFPrin.WebBCSelectClientCertificate(Sender: TObject;
  const browser: ICefBrowser; isProxy: Boolean; const host: ustring;
  port: Integer; certificatesCount: NativeUInt;
  const certificates: TCefX509CertificateArray;
  const callback: ICefSelectClientCertificateCallback; var aResult: Boolean);
begin
  aresult:=true;
  //show certificate window here?
  callback.Select(certificates[Certindex]);
end;

would it be the same window when accessing by firefox or chrome?

enter image description here

I appreciate any help, thanks!


Solution

  • I don't understand where the big deal is: you just display either a Form that you've designed just like any other Form, or you temporarily create one on the fly, just to destroy it again. How you plan to display each certificate (level of detail, fancyness, colors...) is up to you and (of course) works better with a Form already designed.

    This is an example with a Form created on the fly:

    procedure TFPrin.Chromium1SelectClientCertificate
    ( Sender: TObject
    ; const browser: ICefBrowser
    ; isProxy: Boolean
    ; const host: uCEFTypes.ustring
    ; port: Integer
    ; certificatesCount: Cardinal
    ; const certificates: TCefX509CertificateArray
    ; const callback: ICefSelectClientCertificateCallback
    ; var aResult: Boolean
    );
    var
      iCert: Integer;  // Which certificate we're just analyzing
      sLine: String;   // Information about the current certificate
      frm: TForm;      // Displayed (temporary) modal window
      lbx: TListBox;   // All certificates to choose from
      pan: TPanel;     // For the buttons
    
      // Converting a certificate time
      function _TimeToStr( vTime: TCefTime ): String;
      begin
        result:= IntToStr( vTime.year )+ '-'
               + IntToStr( vTime.month )+ '-'
               + IntToStr( vTime.day_of_month );
      end;
    
    begin
      // Create temporary form...
      frm:= TForm.Create( Application );
      with frm do begin
        try
          BorderStyle:= bsSizeable;
    
          // ...along with its temporary controls:
    
          // Bottom panel, which will contain both buttons
          pan:= TPanel.Create( frm );
          with pan do begin
            Parent:= frm;
            Align:= alBottom;
            Height:= 30;
          end;
    
          // Buttons that automatically set the form's modal result
          with TButton.Create( frm ) do begin
            Parent:= pan;
            Caption:= '&Ok';
            ModalResult:= ID_OK;
            Default:= True;  // We can press ENTER anywhere to trigger this button
            Top:= 3;
            Left:= 10;
          end;
          with TButton.Create( frm ) do begin
            Parent:= pan;
            Caption:= '&Cancel';
            ModalResult:= ID_CANCEL;
            Cancel:= True;  // We can press ESC anywhere to trigger this button
            Top:= 3;
            Left:= 100;
          end;
    
          // A list displaying one certificate per line to choose from
          lbx:= TListBox.Create( frm );
          with lbx do begin
            Parent:= frm;
            Align:= alClient;
          end;
    
    
          // Now going thru all certificate details and adding each resulting text line to the listbox
          for iCert:= Low( certificates ) to High( certificates ) do begin
            sLine:= 'Subject: '+   certificates[iCert].GetSubject().GetDisplayName()+  '. '
                  + 'Issuer: '+    certificates[iCert].GetIssuer().GetDisplayName()+   '. '
                  + 'Valid from '+ _TimeToStr( certificates[iCert].GetValidStart() )+  ' to '
                  +                _TimeToStr( certificates[iCert].GetValidExpiry() )+ '.';
            lbx.Items.Add( sLine );
          end;
          if lbx.Count> 0 then lbx.ItemIndex:= 0;  // Pre-select first certificate
    
    
          // Display the form and check if the "Ok" button has been pressed and a line is selected.
          // If yes, actually choose a certificate.
          aResult:= (ShowModal()= ID_OK) and (lbx.ItemIndex<> -1);
          if aResult then callback.Select( certificates[lbx.ItemIndex] );
        finally
          // Free temporary form and all its controls
          frm.Free;
        end;
      end;
    end;
    

    And this is an example for calling one of your existing Forms:

    uses
      frmOther;
    
    procedure TFPrin.Chromium1SelectClientCertificate
    ...
    var
      iCert: Integer;  // Which certificate we're just analyzing
      sLine: String;   // Information about the current certificate
    
      // Converting a certificate time
      function _TimeToStr( vTime: TCefTime ): String;
      begin
        result:= IntToStr( vTime.year )+ '-'
               + IntToStr( vTime.month )+ '-'
               + IntToStr( vTime.day_of_month );
      end;
    
    begin
      // Remove any existing entries in TFOther
      FOther.lbxCert.Clear();
    
      // Now going thru all certificate details and adding each resulting text line to the listbox
      for iCert:= Low( certificates ) to High( certificates ) do begin
        sLine:= 'Subject: '+   certificates[iCert].GetSubject().GetDisplayName()+  '. '
              + 'Issuer: '+    certificates[iCert].GetIssuer().GetDisplayName()+   '. '
              + 'Valid from '+ _TimeToStr( certificates[iCert].GetValidStart() )+  ' to '
              +                _TimeToStr( certificates[iCert].GetValidExpiry() )+ '.';
        FOther.lbxCert.Items.Add( sLine );
      end;
      if FOther.lbxCert.Count> 0 then FOther.lbxCert.ItemIndex:= 0;  // Pre-select first certificate
    
    
      // Display the form and check if the "Ok" button has been pressed and a line is selected.
      // If yes, actually choose a certificate.
      aResult:= (FOther.ShowModal()= ID_OK) and (FOther.lbxCert.ItemIndex<> -1);
      if aResult then callback.Select( certificates[FOther.lbxCert.ItemIndex] );
    end;
    

    Using the types/interfaces can't be more straight - just look at their definitions: