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.