-
Notifications
You must be signed in to change notification settings - Fork 55
How to configure TLS in Brook 5 Framework on a Microsoft Windows Server
On your Production Server
This document describes the steps to get TLS working in the Brook 5 Framework, using certificate files from DigiCert for public facing servers, and OpenSSL certificate files for development work using localhost.
This configuration was generously assisted by the author of the Brook 5 Framework, Silvio Clécio
Tags
I will use this invented tag [!! your !!] to indicate the place where you are supposed to substitute your own value. The opening and closing tags are NOT part of the command string.
Line breaks
Long URLs and DOS commands shown in this document text may be wrapped to more than one line. Be sure to copy the WHOLE URL or command line, AND remove any word wrap characters, before trying to execute them.
Platform
Microsoft Windows Server 2016 Lazarus 2.0.10, FPC 3.2.0 Brook 5 Framework 5.4.7.0 DigiCert .pem files OpenSSL 1.1.1.10
Assumptions
You are familiar with using the Windows command line, (sometimes called a “DOS” window by us old people) with Administrator privileges.
You have a domain name ready to be used in a Certificate Signing Request (CSR)
You will figure out how to purchase certs from DigiCert.
You have a basic understanding of how to program in Free Pascal and have built several 64bit Windows applications before.
And now you have created a 64bit Windows application in Lazarus and you have placed a TBrookHTTPServer component (let's name it brk_svr) on the app's main window. You have reviewed all the Brook examples in the examples folder.
IMPORTANT: You are at the point where the Brook server is functioning properly, without TLS. You just need to get TLS working.
Let's get started...
First, you must obtain the TLS enabled libsagui-3.dll file from URL
In this case, the file you want is
libsagui_tls-3.3.1-windows_amd64.zip
Notice the “_tls” in the name. This is very important. Don't download the similarly named file without the “_tls” in the name. It won't work for our purposes.
Unzip and place the libsagui-3.dll in the same folder as your application.
Next...
Generate a CSR using OpenSSL This must be done on the physical server that will be used to run your Lazarus Brook 5 application.
Get OpenSSL from here:
The file I used was named:
Win64OpenSSL_Light-1_1_1j.exe
It will install to the folder:
C:\Program Files\OpenSSL-Win64\bin
Using File Explorer, navigate to that folder and run the following command:
openssl req -new -newkey rsa:2048 -nodes -out [!! the name you want to use for your csr file !!].csr -keyout [!! the name you want to use for your key file !!].key -subj "/C=CA/ST=[!! your province name !!]/L=[!! your city name !!]/O=[!! your organization name !!]/CN=[!! your domain name, also known as common name !!]"
The above command will produce two files that you will need. Don't use a password on your private key. Let's assume you named your csr file “my”, so you will end up with a file named my.csr and let's assume you named your key file “mykey”, so you end up with mykey.key.
The .key file is supposed to be kept secret and never transmitted via unsecure methods. The .csr file is for use on the DigiCert website.
Log onto the DigiCert website and purchase the type of cert that you want. (Wild card, or single, expiry options). Then when you get to the download, chose the OTHER format, so that you end up with INDIVIDUAL .pem files. The DigiCert window will show three smaller windows:
Certificate, Intermediate and Root
From among the three windows, you will only need the middle one, the “Intermediate” certificate. Copy/paste that to a text editor and save it as “intermed.pem”.
Next, choose the option “Individual .crt files with a .pem extension (zipped)”
Download and unzip the file. You will end up with files named similar to as follows:
DigiCertCA2.pem, your domain name_ca.pem, TrustedRoot.pem
IMPORTANT: You will have to concatinate all files together as follows:
Open the file your domain name_ca.pem in a text editor. Open the file TrustedRoot.pem in another instance of a text editor. Open the file intermed.pem in another instance of a text editor. Open the file DigiCertCA2.pem in another instance of a text editor.
Now open a blank document in your text editor, and copy in, one by one, each one directly under the previous one, the contents of each .pem file named above, in the order named above. So you will end up with one file, with contents of all the above named .pem files, in one file. Each certificate directly below the other. Save that file as “certs.pem”
certs.pem
Copy the certs.pem file to the same folder as your application's .exe file. Copy the mykey.key file to the same folder as your application's executable and for naming consistency within your application's folder, rename it to key.pem.
So you now have, in the same folder as your Lazarus application, with a Brook server.. the following files:
key.pem certs.pem
Next, generate a Diffie-Hellman params file. To generate a DH file use the following OpenSSL command:
dhparam -out dhparams.pem 4096
You will end up with the following file:
dhparams.pem
Copy or move this file to the same folder as your application.
The task of obtaining all the .pem files you need is now completed. These .pem files only handle what I call lthe “recognition and approval” of your domain. They do not handle the mechanics of TLS. Now you need the DLL files that will handle the mechanics of TLS.
Go to the website:
Normally, you would download the latest version for 64bit Windows, but at the time of writing, the latest version, being 3.7.0, was broken, and not available.
If a 3.7x or higher, is available at the time you read this, you can try to use it. In my case I had to use an earlier working version:
Download the .zip file, unzip and place ALL the DLLs into the same folder as your Lazarus Brook 5 application.
We now have all the correct versions, of the correct files in place to get TLS working.
Loading your .pem files...
In the comments of the source code for Brook 5 Framework, TbrookHTTPServerSecurity.pas file, for the properties, FPrivateKey, FCertificate, FTrust, and FDHParams, the phrase “contents of” is used. This means the property is expecting the contents of the file, not the file name. So I made a small procedure that allows me to enter a file name as the property value, but will load the contents of the file at run time.
Here is that procedure:
function LoadStringFromFile(const fyl_nm: String; const lst: TStringList): String; begin lst.Clear; lst.LoadFromFile(fyl_nm); Result := StringReplace(lst.Text, #13#10, '', [rfReplaceAll]); lst.Clear; end;
(Update: FreePascal has it's own LoadStringFromFile() function which can be used for the same purpose. I discovered it AFTER I wrote my own.)
Usage:
(My Brook 5 Server component is named “brk_svr”)
procedure TfrmMain.LoadSecurityParams; // Run this once at start up (OnCreate of your form) var lst: TStringList; begin // Loads file contents for properties that contain file names // Be aware that you can only run this once, because after the property contains file contents, it no longer contains a file name, so this won't work lst := nil; try
lst := TStringList.Create;
brk_svr.Security.Certificate := LoadStringFromFile(brk_svr.Security.Certificate, lst); // cert.pem
brk_svr.Security.PrivateKey := LoadStringFromFile(brk_svr.Security.PrivateKey, lst); // key.pem
brk_svr.Security.DHParams := LoadStringFromFile(brk_svr.Security.DHParams, lst); // dhparams.pem
brk_svr.Security.Trust := LoadStringFromFile(brk_svr.Security.Trust, lst); // root.pem
finally
lst.Free;
end;
end;`
We are now ready to run...
Start your application and enable Security.
brk_svr.Security.Active := True;
Your server should start without any error messages about missing DLLs or wrong versions.
Use your browser to visit the URLs that point to your applications. The page should render, and the little “lock” icon should show as “Locked”.
I was able to get this working, thanks to the generous help received by Silvio and several members of the Lazarus Forum.
On your Development Server
Open the file: C:\Windows\System32\drivers\etc\hosts
Add the lines:
127.0.0.1 fake1.local 127.0.0.1 fake2.local
Save the file.
Run the following commands:
openssl req -x509 -nodes -new -sha256 -days 1024 -newkey rsa:2048 -keyout RootCA.key -out RootCA.pem -subj "/C=US/CN=Example-Root-CA" openssl x509 -outform pem -in RootCA.pem -out RootCA.crt
Create a file named domains.ext that contains the following text, and place it in the same folder as your OpenSSL .exe:
authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment subjectAltName = @alt_names [alt_names] DNS.1 = localhost DNS.2 = fake1.local DNS.3 = fake2.local
Then run the following commands:
openssl req -new -nodes -newkey rsa:2048 -keyout localhost.key -out localhost.csr -subj "/C=US/ST=YourState/L=YourCity/O=Example-Certificates/CN=localhost.local" openssl x509 -req -sha256 -days 1024 -in localhost.csr -CA RootCA.pem -CAkey RootCA.key -CAcreateserial -extfile domains.ext -out localhost.crt
Using File Explorer, navigate to the file you just created called localhost.crt, right click on it, and add it to "Trusted Root Certificate Authorities".
Now your Lazarus app can point to [Your local host]([https://localhost:!!your port number!!]) and the connection will be secure.