Lazarus

Programming => Networking and Web Programming => Topic started by: RedOctober on February 22, 2021, 11:56:52 pm

Title: Brook Security (https)
Post by: RedOctober on February 22, 2021, 11:56:52 pm
Platform:  Lazarus 2.0.10    FPC:   3.2.0      OS:  Windows Server 2016

Requirements:

 
 
I know I can get a cert from Let's Encrypt, but I'd rather use the one I have already installed on the server. (I'm still learning how to get a cert from Let's Encrypt)

How can I accomplish this? (If at all possible) (I don't want to regen a cert from DigiCert as I am outside their free regen date limit by one day, and it's expensive  ($1,200 CA))

Thanks in advance. 

Title: Re: Brook Security (https)
Post by: PierceNg on February 23, 2021, 01:23:08 am
I want to use the existing DigiCert cert I just paid for, and installed, on my Windows Server.  (It is not in .pem, .root. cert, .ca format)

Do you know what format the DigiCert cert comes in? How did you generate the private key?

Seems Digicert allows you to redownload your cert in various formats: https://dev.digicert.com/services-api/certificates/download-certificate-format/ (https://dev.digicert.com/services-api/certificates/download-certificate-format/)
Title: Re: Brook Security (https)
Post by: RedOctober on February 24, 2021, 11:39:51 pm
Hi Pierce, (or anyone who can answer this)  (I"m on Brook 5.4.1.0)

I was able to get a duplicate set of files from DigiCert.  Now, I'm having trouble assigning the files to properties.   I tried to do this through process of elimination, but can't get it to work.  Can you, or anyone, tell me which files supplied by DigiCert, go to which properties in the Brook server?  Also, do I have to manually include unit "TBrookHTTPServerSecurity" in the "uses" clause of my app?

In DigiCert, I have
Certificate,
Intermediate Certificate, and
Root. 

In my Brook 5 server, I have properties: 
Certificate,
DHParams,
Private Key (I have a file generated by OpenSSL with a ".key" extension, so I'm guessing that is my "Key",
Private Password (I did not set a password in the CSR, so I'm leaving this blank), and
Trust.

No matter which file I assign to which property, I keep getting an error message:    TLS is not available.

Title: Re: Brook Security (https)
Post by: PierceNg on February 25, 2021, 01:54:45 pm
Also, do I have to manually include unit "TBrookHTTPServerSecurity" in the "uses" clause of my app?

No idea. Check the examples or the source.

DHParams,

Generate it on your computer. May take a while. Don't copy from anywhere.


% openssl dhparam -out dhparams.pem 4096


Trust.

Source code comment for this field says it is for client authentication. Without reading the actual code I assume this is for client _certificate_ authentication. You should be able to leave it unset and ignore it for now.

No matter which file I assign to which property, I keep getting an error message:    TLS is not available.

Does your key file look like this?


-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCfTeC66EZcAttl
blah blah
many lines
-----END PRIVATE KEY-----



If you paste a complete source program that compiles - doesn't need to do anything, just start the HTTPS server - others can better help you.
Title: Re: Brook Security (https)
Post by: RedOctober on February 25, 2021, 06:18:23 pm
>>No idea. Check the examples or the source.

There is no example that deals with HTTPS

>> DHParams

Thanks for that. It's running now.

>>Trust.

Ok, I will leave it blank for now.

Yes, I have these .pem files.  They all look like this

-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCfTeC66EZcAttl
blah blah
many lines
-----END PRIVATE KEY-----

>>If you paste a complete source program that compiles - doesn't need to do anything, just start the HTTPS server - others can better help you.

Ok, I will finish generating the DHParams then get back to this thread.


Title: Re: Brook Security (https)
Post by: RedOctober on February 25, 2021, 07:05:21 pm
I am looking through the source code comments... in the property fields for HTTPS, the author uses an interesting term.  He/She says " Content of".  Hmm...

I was assigning file names to those properties (Example: for the PrivateKey property, in code I'd do...)  .PrivateKey = 'C:\pem_files\privatekey.pem';

But the term "Content of" makes me wonder if I'm supposed to load the privatekey.pem file into a TStringList (.LoadFromFile) then assign the property to the .Text of the TStringList.

Like this:    ....PrivateKey := my_stringlist.Text;

This wd put the "content" of the private key file into the property of the Brook Server's .PrivateKey property.

Does this make sense? Shd it be done this way?
Title: Re: Brook Security (https)
Post by: RedOctober on February 25, 2021, 11:23:53 pm
Still struggling.  I have created a demo project, but it's almost useless, because I can't include any of my .pem files for security reasons.  However, inside the sample project, I do have comments where I'm having trouble understanding.  I built a stand alone server using Delphi and IntraWeb, and it's property naming convention was simpler.  In IntraWeb, it has properties called: Certificate, Root, and Key. There is no "Root" property in Brook.  This is why I'm confused using Brook.

Is the "Certificate" supposed to inlcude only the "Certificate" file from DigiCert, or BOTH the "Certificate" and "Intermediate Certificate" in the same file?
What do I do with the "Root.pem" made by DigiCert.  There is no "Root" property in Brook.Security.
Title: Re: Brook Security (https)
Post by: PierceNg on February 26, 2021, 02:23:01 am
Still struggling.  I have created a demo project, but it's almost useless, because I can't include any of my .pem files for security reasons.  However, inside the sample project, I do have comments where I'm having trouble understanding.  I built a stand alone server using Delphi and IntraWeb, and it's property naming convention was simpler.  In IntraWeb, it has properties called: Certificate, Root, and Key. There is no "Root" property in Brook.  This is why I'm confused using Brook.

Is the "Certificate" supposed to inlcude only the "Certificate" file from DigiCert, or BOTH the "Certificate" and "Intermediate Certificate" in the same file?
What do I do with the "Root.pem" made by DigiCert.  There is no "Root" property in Brook.Security.

Your program is almost there.

Firstly if you are using libsagui binary download then the issue is probably that it does not come with TLS support; see https://github.com/risoflora/libsagui/issues/46 (https://github.com/risoflora/libsagui/issues/46). I am on Ubuntu 20.04 and I built my own libsagui from source that includes TLS.

I tested with my self-generated self-signed certificate with common name "localhost". With suitable changes to your source, running and clicking the button starts a HTTPS server on 8088. I verified that TLS is working using OpenSSL CLI:

% openssl s_client localhost:8088
CONNECTED(00000003)
Can't use SSL_get_servername
depth=0 CN = localhost
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = localhost
verify return:1
---
Certificate chain
 0 s:CN = localhost
   i:CN = localhost
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDCTCCAfGgAwIBAgIUauF1SCdrjBwLAgEBJY9xzmHZ8OkwDQYJKoZIhvcNAQEL
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTIxMDIyNDEwMDYwN1oXDTIxMDMy
NjEwMDYwN1owFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAn03guuhGXALbZVrtlee9McjTFNtcvh6cCfBaI49I4gnk
8KVjHuhpKAGVPKIyDtfbO2QYF1h78c96UilzSQzu3cw6CcV6RLawJnacpfSBDC0B
lo3TiMhCn3nsWVU9PprUIjncrhbCmlj/wCzSvJnCg59+FDFCatUto0wYc6XVCqiL
zv+ht37KaGFDhT8uZs8Sy7lishvIkX7qgH9cPFJ/jAKQnKjDap+wM8K3PrHHytLy
wzPItEkMZW5hp6E7if8xMCbfPDh9dDM9sKXvBUqdsls37Pk0DJeWwzcN2M5uJXPn
Fs58CqHl8NMqj8zb0s8TCCUSxjCW/IyGB1UziZTHeQIDAQABo1MwUTAdBgNVHQ4E
FgQU8b/lkepw6pR6+bwohwXV19Q9UtEwHwYDVR0jBBgwFoAU8b/lkepw6pR6+bwo
hwXV19Q9UtEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAbFCZ
A9Qa69REN40KISmkqmxO4Pupb0x7SMFXQcj/lH1akZai6CpS3uNzxlYLLxZD5iQR
utCOzVlVadcWZSig6YgJ+TtVuIhHiE060dBMf4bOM7rCuKMBo6Cfhc1A46uWv7ER
jgfBA1Nt4zc/bbjtiBAkq9eJVmseJOK8zc8R05wW+J0M6kDb39CcrE76FTOO31Tq
Z4ANOREJw5515eMwx9iwiQnGqQ7e+N0eQQ+Nt0UFERXD67OAtO+Cdco/v6BuWi7K
E/PUXyzQBBIF1aaz5Xn9EGW1CcE3Gvp2J7JHkJJZGQqeKEHZLNEQpNlZmBB8CgB3
VNKK/nlGIQ/ai3KBKQ==
-----END CERTIFICATE-----
subject=CN = localhost

issuer=CN = localhost

---
Acceptable client certificate CA names
CN = localhost
Requested Signature Algorithms: RSA+SHA256:RSA-PSS+SHA256:RSA-PSS+SHA256:ECDSA+SHA256:Ed25519:RSA+SHA384:RSA-PSS+SHA384:RSA-PSS+SHA384:ECDSA+SHA384:Ed448:RSA+SHA512:RSA-PSS+SHA512:RSA-PSS+SHA512:ECDSA+SHA512:RSA+SHA1:ECDSA+SHA1
Shared Requested Signature Algorithms: RSA+SHA256:RSA-PSS+SHA256:RSA-PSS+SHA256:ECDSA+SHA256:Ed25519:RSA+SHA384:RSA-PSS+SHA384:RSA-PSS+SHA384:ECDSA+SHA384:Ed448:RSA+SHA512:RSA-PSS+SHA512:RSA-PSS+SHA512:ECDSA+SHA512
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 1438 bytes and written 393 bytes
Verification error: self signed certificate
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 18 (self signed certificate)
---
Title: Re: Brook Security (https)
Post by: PierceNg on February 26, 2021, 02:31:06 am
I've attached the modified unit1.pas here.

Indeed the properties for certificate and key data are expected to be strings, so I added function loadStringFromFile to load them.

The two writeln statements just before brook_svr.open check whether libsagui has TLS.

Finally brook_svr.open is to run the HTTPS server. Your code didn't actually start the server.
Title: Re: Brook Security (https)
Post by: PierceNg on February 26, 2021, 02:44:57 am
What do I do with the "Root.pem" made by DigiCert.  There is no "Root" property in Brook.Security.

This file should be DigiCert's CA cert. On Windows this CA cert is probably already incorporated into the OS trusted cert store.

For now you should just ignore it. In my modification to your program, I left this field as the empty string.
Title: Re: Brook Security (https)
Post by: RedOctober on February 26, 2021, 03:45:15 am
Hi Pierce... just working through your example now.  Thanks for that.

On Windows, the LineEnding is two characters:  #13#10  and the TStringList.Delimiter is expecting only a Char.  So I modified your function to:

Code: Pascal  [Select][+][-]
  1. function LoadStringFromFile(const fyl_nm: String; const lst: TStringList): String;
  2. begin
  3.   lst.Clear;
  4.   lst.LoadFromFile(fyl_nm);
  5.   Result := StringReplace(lst.Text, #13#10, '', [rfReplaceAll]);
  6.   lst.Clear;
  7. end;
  8.  

so that it compiles.  I'll get back to you with more results in a few hours.
Title: Re: Brook Security (https)
Post by: RedOctober on February 26, 2021, 03:56:34 am
I'm just at the part where testing for TLS is done.  I don't have a file assigned for writeln() so I used the following procedure instead:

Code: Pascal  [Select][+][-]
  1. procedure TfrmMain.sbtnTestClick(Sender: TObject);
  2. begin
  3.   if Assigned(sg_httpsrv_tls_listen) then
  4.     ShowMessage('sg_httpsrv_tls_listen is Assigned');
  5.   if Assigned(sg_httpsrv_tls_listen2) then
  6.     ShowMessage('sg_httpsrv_tls_listen2 is Assigned');
  7. end;
  8.  

Neither of these are Assigned() so I guess that means my libsagui is the one without TLS support.

I'm on Microsoft Windows Server 2016. How do I get (and/or compile) a libsagui with the TLS functions?
I have not gone any further, hoping to get things properly in place before moving to the next step.

Thanks in advance.
Title: Re: Brook Security (https)
Post by: PierceNg on February 26, 2021, 07:01:01 am
Neither of these are Assigned() so I guess that means my libsagui is the one without TLS support.

I'm on Microsoft Windows Server 2016. How do I get (and/or compile) a libsagui with the TLS functions?

Ok this is not that straightforward. I have built libsagui on my Windows 10 with TLS. The program works and openssl s_client gives similar output as when I ran it on Linux. Unfortunately libsagui-3.dll itself dynamically links to libgnutls-30.dll and a whole bunch of other DLLs from the mingw64 runtime. The downloadable version of libsagui-3.dll without TLS has no such dependencies.

I can supply you with the copy of libsagui-3.dll that I built. But you'll still need to get the mingw64 runtime DLLs yourself.

Alternatively you could set up Cygwin. The act of using Cygwin to build libsagui-3.dll with TLS will give you those runtime DLLs.
Title: Re: Brook Security (https)
Post by: PierceNg on February 26, 2021, 07:19:02 am
The GnuTLS CI artefacts are here: https://gitlab.com/gnutls/gnutls/-/jobs (https://gitlab.com/gnutls/gnutls/-/jobs). Clicking on the download button at the right gives you a zip file containing the GnuTLS-related DLLs (and other files). That should get you going. But take note of this warning on https://gnutls.org/download.html (https://gnutls.org/download.html): "As we do not rely on trusted infrastructure for our CI, please consider them as untrusted binaries."
Title: Re: Brook Security (https)
Post by: RedOctober on February 26, 2021, 04:03:26 pm
Hi Pierce,

I think we've come to the end of the road with Brook 5.  I do not want to go through this every time libsagui is updated. 
My project development is at the very beginning and I am dealing with TLS first, to ensure this most important basic feature is functioning correctly.  Back in the day, when I used Delphi and IntraWeb, I dealt with TLS last, and it was enough of a hassle just figuring out the .pem files needed from DigiCert, but I was able to get it done.  I don't want to base my entire project on a component set that is not quite ready for prime time on a Microsoft server, and I don't even have the skill to help out the developers of said component set.

I will move my project over to fpWeb, as I am assuming that it already has TLS 1.3 capability.  Is that a valid assumption?
OR.... see my next post on page 2
Title: Re: Brook Security (https)
Post by: RedOctober on February 26, 2021, 04:31:57 pm
Unless.... at this early point... there is a way to make a Lazarus 2.0.10, FPC 3.2.0, an Apache module.  In that case, Apache wd handle the HTTPS stuff.   I'm just starting to research if this is possible and I have not found any info that says this is possible.

So my current question is:   Is it possible to make a Lazarus, Microsoft app, that uses Brook 5, into an Apache module?  If so, is there a document explaining how to do this?

Thanks in advance.
Title: Re: Brook Security (https)
Post by: RedOctober on February 26, 2021, 06:25:47 pm
Hey... something interesting...maybe nothing...

My little "Test" button, that uses "Assigned()", doesn't seem to recognize that the function variables are assiged.  Pls see the attached file.  Am I not understanding what Assigned() does?  Does my copy of Brook 5 actually HAVE TLS 1.3 support?

The variable is not NULL, which is what I suspected to see in my variable contents viewer in Lazarus.

 
Title: Re: Brook Security (https)
Post by: RedOctober on February 26, 2021, 09:25:29 pm
I can get my app to work in unsecure mode, no problem.  I turn on security, I have all .pem files in place, load them correctly, and I keep getting the error message from the app:   "TLS is not available"
And when I try to connect via browser, I get the error message  "This site can't be reached".
So I guess even though the function variables may be populated, they don't do anything.
Still stuck (using the real, DigiCert .pem files, Brook 5, without the libsabgui that has TLS compiled in, as Pierce was saying)  If there's no way to make an Apache module out of Brook 5, then, for me, Brook 5 cannot be used in my project.
Title: Re: Brook Security (https)
Post by: PierceNg on February 27, 2021, 12:58:43 am
Unless.... at this early point... there is a way to make a Lazarus 2.0.10, FPC 3.2.0, an Apache module.  In that case, Apache wd handle the HTTPS stuff.   I'm just starting to research if this is possible and I have not found any info that says this is possible.

So my current question is:   Is it possible to make a Lazarus, Microsoft app, that uses Brook 5, into an Apache module?  If so, is there a document explaining how to do this?

Thanks in advance.

Brook Framework is unlikely to work as an Apache module. FPC does have with functionality to do so, see the directories httpd20, httpd22, httpd24 in <fpcsrc>/<version>/packages.

But your best bet is to do reverse proxying, letting Apache (or Nginx, or whatever) handle the HTTPS. The reverse proxy then talks to your app over HTTP. This way your can focus on  your app functionality and your can try out any number of Pascal web frameworks.
Title: Re: Brook Security (https)
Post by: PierceNg on February 27, 2021, 01:10:47 am
Hey... something interesting...maybe nothing...

My little "Test" button, that uses "Assigned()", doesn't seem to recognize that the function variables are assiged.  Pls see the attached file.  Am I not understanding what Assigned() does?  Does my copy of Brook 5 actually HAVE TLS 1.3 support?

The variable is not NULL, which is what I suspected to see in my variable contents viewer in Lazarus.

I am not 100% certain, but there are two things here - the Pascal variable and the C function the variable points to. From the libsagui source code, if TLS is not configured, then those functions don't exist. Maybe the inspector is showing the Pascal variable? Anyway, in Brook source code, the error "TLS not available" comes from testing assigned().

One way to find out is to download the GnuTLS dependencies and try it.
Title: Re: Brook Security (https)
Post by: RedOctober on February 27, 2021, 03:23:14 am
I have emailed Silvio via this forum, just asking if there is an existing or upcoming build of Brook 5 Framework that will include HTTPS support on Windows "out of the box".  I included links to this forum post, and the issue link you provided.  I'm hoping the email reaches him and he has time to answer.  Thanks for all your help PierceNG.
TinyPortal © 2005-2018