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. :)

