#1 2023-02-28 09:12:21

Gigo
Member
From: Split, Croatia
Registered: 2012-01-27
Posts: 14

Two-way TLS

I'd like to be able to drop https connections that does not have trusted client certificate.
Current implementation will accept blank certificates from client.

My proposition would be (at least on OpenSSL) :

- using USE_OPENSSL;FORCE_OPENSSL conditional defines

- in mormot.net.sock add two boolean fields to TNetTlsContext

    TNetTlsContext = record
      ...
        // input: Should server request Two-Way TLS connection                      // added
        TwoWayTls : Boolean;                                                        // added
        // input: Should server verify peer just first time                         // added
        VerifyClientOnce : Boolean;                                                 // added
      ...
    end;

- in mormot.lib.openssl11 modify TOpenSslNetTls.SetupCtx

    procedure TOpenSslNetTls.SetupCtx(var Context: TNetTlsContext; Bind: boolean);
    var
      v, PeerVerifyMode: integer;
    begin
      _PeerVerify := self; // safe and simple context for the callbacks
      if Context.IgnoreCertificateErrors then
        SSL_CTX_set_verify(fCtx, SSL_VERIFY_NONE, nil)
      else
      begin
        if Assigned(Context.OnEachPeerVerify) then
          begin                                                                     // added
            PeerVerifyMode := SSL_VERIFY_PEER;                                      // added
            if Context.TwoWayTls then                                               // added
              PeerVerifyMode := PeerVerifyMode or SSL_VERIFY_FAIL_IF_NO_PEER_CERT;  // added
            if Context.VerifyClientOnce then                                        // added
              PeerVerifyMode := PeerVerifyMode or SSL_VERIFY_CLIENT_ONCE;           // added
            SSL_CTX_set_verify(fCtx, PeerVerifyMode, AfterConnectionPeerVerify)     // added
          end                                                                       // added
          // SSL_CTX_set_verify(fCtx, SSL_VERIFY_PEER, AfterConnectionPeerVerify)   // removed
        else
          SSL_CTX_set_verify(fCtx, SSL_VERIFY_PEER, nil);
        if FileExists(TFileName(Context.CACertificatesFile)) then
          SSL_CTX_load_verify_locations(
            fCtx, pointer(Context.CACertificatesFile), nil)
        else
          SSL_CTX_set_default_verify_paths(fCtx);
      end;
      ...
    end;

Then we can create server like this

    InitNetTlsContext(tls, {server=}true,
      'keys\SrvCert.pem',
      'keys\SrvPrivKey.pem',
      'password',
      'keys\CACerts.pem');
    with tls do
      begin
        //OnPeerValidate := MyPeerValidate;               // I guess this works only on client
        //OnAfterPeerValidate := MyAfterPeerValidate;     // I guess this works only on client
        OnEachPeerVerify := MyEachPeerVerify;
        IgnoreCertificateErrors := False;
        AllowDeprecatedTls := False;
        WithPeerInfo := True;
        TwoWayTls := True;
        VerifyClientOnce := True;
      end;

    HttpServer := TRestHttpServer.Create(AHttpPort, [MyRestServer],
      '+', useBidirAsync, 32, secTLS, '', '', [rsoCompressSynLZ,rsoCompressGzip], @tls);
    HttpServer.WebSocketsEnable(MyRestServer,AWebSocketKey)

On each client connection we have option to accept/drop connection using return value of MyEachPeerVerify()

If this does not break anything, maybe AB could merge this to source.
Currently, I have no idea how to achieve this via SSPI/SChannel.

Offline

#2 2023-02-28 09:39:22

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,206
Website

Re: Two-way TLS

Good idea.

Please try https://github.com/synopse/mORMot2/commit/1167ceed

I just renamed the properties, and added some comments/documentation.
On SChannel, I am not sure it is worth it, because SChannel by itself may be unsecure on old Windows - OpenSSL is preferred for any serious server work. wink

Offline

#3 2023-02-28 10:05:55

Gigo
Member
From: Split, Croatia
Registered: 2012-01-27
Posts: 14

Re: Two-way TLS

That was quick ! It works. Thanks !

Offline

Board footer

Powered by FluxBB