From HTTP to HTTPS

Here is how you publish a TRestServer instance over HTTP, on port 8888, and with 16 threads for the thread pool:

    Server := TRestHttpServer.Create([RestServer], '8888', 16);

Note the new constructor, easier to use than before, if you just want the default asynchronous server.

And to publish over HTTPS, on the very same port, with a self-signed certificate:

    Server := TRestHttpServer.Create([RestServer], '8888', 16, secTLSSelfSigned);

For a mORMot client, you should also specify that you expect TLS support, and ignore the fact that this self-signed certificate is unknown by the system:

  Client := TRestHttpClientSocket.Create('127.0.0.1', '8888', Model, {https=}true);
  Client.IgnoreTlsCertificateErrors := true;

Then, at least with OpenSSL, you could serve TLS 1.3 content from now on, with a safe cipher negotiation by default (which could be tuned if needed).
Nice and easy!

Give Me the Keys

And if you generated your own public/private keys pair, you could specify it:

    Server := TRestHttpServer.Create([RestServer], '8888', 16, secTLS,
      HTTPSERVER_DEFAULT_OPTIONS, 'mycert.pem', 'mypriv.pem', 'privpassw');

And don't forget to keep your private key... private. :)

Keys Rule

Where do those certificates come from? Do I need to read endless and complex OpenSSL command line samples, and mess with files and passwords?
Our framework make it easy. You can now use the new mORMot 2 high-level cryptography interfaces to generate the keys you want in simple pascal code.

Here is how the framework generates the self-signed server certificate on OpenSSL, or use a pre-computed one for SChannel:

procedure InitNetTlsContextSelfSignedServer(var TLS: TNetTlsContext;
  Algo: TCryptAsymAlgo);
var
  cert: ICryptCert;
  certfile, keyfile: TFileName;
  keypass: RawUtf8;
begin
  certfile := TemporaryFileName;
  if CryptCertAlgoOpenSsl[Algo] = nil then
  begin
    FileFromString(PrivKeyCertPfx, certfile); // use pre-computed key
    keypass := 'pass';
  end
  else
  begin
    keyfile := TemporaryFileName;
    keypass := CardinalToHexLower(Random32);
    cert := CryptCertAlgoOpenSsl[Algo].
              Generate(CU_TLS_SERVER, '127.0.0.1', {authority=}nil, 3650);
    cert.SaveToFile(certfile, cccCertOnly, '', ccfPem);
    cert.SaveToFile(keyfile, cccPrivateKeyOnly, keypass, ccfPem);
    //writeln(BinToSource('PRIVKEY_PFX', '',
    //  cert.Save(cccCertWithPrivateKey, 'pass', ccfBinary)));
  end;
  InitNetTlsContext(TLS, {server=}true, certfile, keyfile, keypass);
end;

As you can see, the ICryptCert interface is very simple to use, and hide all the complexity of X509 and OpenSSL. We provided nil as authority, but you could specify a ICryptCert instance to sign your certificate, if needed.
Under comments in the above source, you can see how to export the keys pair as PKCS#12 certificate, ready to be used for SChannel.

TLS Everywhere

Offering TLS as part of your software solution could be a game-changer for serious business, even over a corporate network, with self-signed certificates. It would help your IT and management people trust your mORMot / pascal solution in an heterogeneous and complex mesh of services. Modern object pascal is still on track for the next decades! :)

Feedback is welcome on our forum, as usual. :)