Request client certificate

Hi,

Is is possible to write a Sparkle server that requires all connections to provide a valid client certificate?  I have registered my SSL port binding so that 'Negotiate Client Certificate' is enabled, but I can't see where to add code to my server to read and validate a client certificate.

Thanks,
Jonathan
Hello Jonathan,
When using http.sys with Sparkle, you receive a THttpServerContext object (Context) when processing the request. You can always case such object to THttpSysContext, and from that get the SysRequest.RawRequest which is of type PHTTP_REQUEST (https://docs.microsoft.com/en-us/windows/desktop/api/http/ns-http-_http_request_v1). 

From that, you can retrieve pSSLInfo.pClientCertInfo which provides the HTTP_SSL_CLIENT_CERT_INFO structure (https://docs.microsoft.com/en-us/windows/desktop/api/http/ns-http-_http_ssl_client_cert_info)

Here is a quick sample:



    procedure(const C: THttpServerContext)
    var
      CertInfo: PHTTP_SSL_CLIENT_CERT_INFO;
      SslInfo: PHTTP_SSL_INFO;
    begin
      SslInfo := THttpSysContext(C).SysRequest.RawRequest.pSslInfo;
      if SslInfo <> nil then CertInfo := SslInfo^.pClientCertInfo;
      // CertInfo contains client certificate info
    end


Well, side note: Actually SysRequest is not public property. We have changed it here in our development code, but you can simply make it public there in your code (unit Sparkle.HttpSys.Context) and recompile Sparkle packages:



  THttpSysContext = class(THttpServerContext)
  { SNIP }
    property QueueId: NativeUInt read FQueueId;
    property SysRequest: THttpSysRequest read FSysRequest;
  end;


Many thanks Wagner, that looks great.  I'll give it a try.