Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2024-03

client certificate mandatory and verification

3 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Jos Wegman

Hi,

Out of the info on the wiki I created a simple Webserver with a server-certificate.
To get this code working you need to create the necessary certificate. For this I used xca from https://hohnstaedt.de but you can use OpenSSL to do the same.

[code=pascal]
program webserver;
{$mode objfpc}{$H+}

uses
  {$ifdef UNIX}
  cthreads, cmem,
  {$endif}
  fphttpapp,
  httpdefs,
  httproute,
  opensslsockets;

var
   fUseSSL: boolean;
const
   fCertificatePassword: string = 'hello';
   fCertificateHostName: string = 'localhost';
   fCertificateFileName: string = 'Server.crt';
   fCertificatePrivateKey: string = 'Server.key';
   procedure route1(aReq: TRequest; aResp: TResponse);
   begin
     aResp.Content := '<html><body><h1>Route 1 The
Default</h1></body></html>';
   end;
   procedure route2(aReq: TRequest; aResp: TResponse);
   begin
     aResp.Content := '<html><body><h1>Route 2</h1></body></html>';
   end;
begin
   HTTPRouter.RegisterRoute('/', @route1);
   HTTPRouter.RegisterRoute('/2', @route2);
   Application.Port := 1999;
   fUseSSL :=true;
   Application.UseSSL := fUseSSL;
   if fUseSSL then
   begin
     Application.CertificateData.KeyPassword := fCertificatePassword;
     Application.CertificateData.HostName := fCertificateHostName;
     Application.CertificateData.Certificate.FileName :=
fCertificateFileName;
     Application.CertificateData.PrivateKey.FileName :=
fCertificatePrivateKey;
   end;
   Application.Threaded := True;
   Application.Initialize;
   Application.Run;
end.
[/code]

My questions are:
*- How can I modify this example to enforce the use of a client certificate?
- How can I verify a client certificate in the server?*

In the TLS handshake a client certificate is optional but the server can ensure that it is mandatory.

Any help, pointers, sample code is appreciated.

Sincerely,

Jos

Reply by email

Flávio Etrusco
to Jos Wegman

Hello,

This doesn't seem to have an easy solution right now. Many of the functions needed to set up openssl for this doesn't even seem to have imports in the FPC package.
You'd then have to import the functions and implement a custom TSSLSocketHandler, and then hook it using either
(fphttpapp.)Application.HTTPHandler.HTTPServer.OnGetSocketHandler or TSSLSocketHandler.SetDefaultHandlerClass();

Some pointers:
https://stackoverflow.com/questions/4261369/openssl-verify-peer-client-certificate-in-c https://stackoverflow.com/questions/21050366/testing-ssl-tls-client-authentication-with-openssl https://stackoverflow.com/questions/16291809/programmatically-verify-certificate-chain-using-openssl-api https://stackoverflow.com/questions/3412032/how-do-you-verify-a-public-key-was-issued-by-your-private-ca

Best regards,
Flávio

Em sáb., 23 de mar. de 2024 às 08:47, Jos Wegman via fpc-pascal <

Show quoted text 82 lines
escreveu: Hi, Out of the info on the wiki I created a simple Webserver with a server-certificate. To get this code working you need to create the necessary certificate. For this I used xca from https://hohnstaedt.de but you can use OpenSSL to do the same. [code=pascal] program webserver; {$mode objfpc}{$H+} uses {$ifdef UNIX} cthreads, cmem, {$endif} fphttpapp, httpdefs, httproute, opensslsockets; var fUseSSL: boolean; const fCertificatePassword: string = 'hello'; fCertificateHostName: string = 'localhost'; fCertificateFileName: string = 'Server.crt'; fCertificatePrivateKey: string = 'Server.key'; procedure route1(aReq: TRequest; aResp: TResponse); begin aResp.Content := '<html><body><h1>Route 1 The Default</h1></body></html>'; end; procedure route2(aReq: TRequest; aResp: TResponse); begin aResp.Content := '<html><body><h1>Route 2</h1></body></html>'; end; begin HTTPRouter.RegisterRoute('/', @route1); HTTPRouter.RegisterRoute('/2', @route2); Application.Port := 1999; fUseSSL :=true; Application.UseSSL := fUseSSL; if fUseSSL then begin Application.CertificateData.KeyPassword := fCertificatePassword; Application.CertificateData.HostName := fCertificateHostName; Application.CertificateData.Certificate.FileName := fCertificateFileName; Application.CertificateData.PrivateKey.FileName := fCertificatePrivateKey; end; Application.Threaded := True; Application.Initialize; Application.Run; end. [/code] My questions are: *- How can I modify this example to enforce the use of a client certificate? - How can I verify a client certificate in the server?* In the TLS handshake a client certificate is optional but the server can ensure that it is mandatory. Any help, pointers, sample code is appreciated. Sincerely, Jos _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email

Tony Whyman
to Flávio Etrusco

If you want to use OpenSSL then you might be interesting in trying out my proposed update to the Indy components. This is to support the latest versions of OpenSSL and can be downloaded from:

https://github.com/MWASoftware/Indy.proposedUpdate

There is a test case in Test/OpenSSL/openssl-server which is based on the use of the Indy http server and OpenSSL which includes a test case where a client certificate must be validated by the server. This appears to work on both Linux and Windows and hopefully other platforms.

Flávio Etrusco wrote 107 lines
Hello, This doesn't seem to have an easy solution right now. Many of the functions needed to set up openssl for this doesn't even seem to have imports in the FPC package. You'd then have to import the functions and implement a custom TSSLSocketHandler, and then hook it using either (fphttpapp.)Application.HTTPHandler.HTTPServer.OnGetSocketHandler or TSSLSocketHandler.SetDefaultHandlerClass(); Some pointers: https://stackoverflow.com/questions/4261369/openssl-verify-peer-client-certificate-in-c https://stackoverflow.com/questions/21050366/testing-ssl-tls-client-authentication-with-openssl https://stackoverflow.com/questions/16291809/programmatically-verify-certificate-chain-using-openssl-api https://stackoverflow.com/questions/3412032/how-do-you-verify-a-public-key-was-issued-by-your-private-ca Best regards, Flávio Em sáb., 23 de mar. de 2024 às 08:47, Jos Wegman via fpc-pascal escreveu: Hi, Out of the info on the wiki I created a simple Webserver with a server-certificate. To get this code working you need to create the necessary certificate. For this I used xca from https://hohnstaedt.de but you can use OpenSSL to do the same. [code=pascal] program webserver; {$mode objfpc}{$H+} uses   {$ifdef UNIX}   cthreads, cmem,   {$endif}   fphttpapp,   httpdefs,   httproute,   opensslsockets; var   fUseSSL: boolean; const   fCertificatePassword: string = 'hello';   fCertificateHostName: string = 'localhost';   fCertificateFileName: string = 'Server.crt';   fCertificatePrivateKey: string = 'Server.key';   procedure route1(aReq: TRequest; aResp: TResponse);   begin     aResp.Content := '<html><body><h1>Route 1 The Default</h1></body></html>';   end;   procedure route2(aReq: TRequest; aResp: TResponse);   begin     aResp.Content := '<html><body><h1>Route 2</h1></body></html>';   end; begin   HTTPRouter.RegisterRoute('/', @route1);   HTTPRouter.RegisterRoute('/2', @route2);   Application.Port := 1999;   fUseSSL :=true;   Application.UseSSL := fUseSSL;   if fUseSSL then   begin     Application.CertificateData.KeyPassword := fCertificatePassword;     Application.CertificateData.HostName := fCertificateHostName;     Application.CertificateData.Certificate.FileName := fCertificateFileName;     Application.CertificateData.PrivateKey.FileName := fCertificatePrivateKey;   end;   Application.Threaded := True;   Application.Initialize;   Application.Run; end. [/code] My questions are: *- How can I modify this example to enforce the use of a client certificate? - How can I verify a client certificate in the server?* In the TLS handshake a client certificate is optional but the server can ensure that it is mandatory. Any help, pointers, sample code is appreciated. Sincerely, Jos _______________________________________________ fpc-pascal maillist  - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email