fphttpapp web server with certificate
lazarus / 38-Networking and Web Programming
----------------------------------------------------------------------
dseligo · 2023-10-07 20:18
I can't make fphttpapp to work with certificates.
Code: Pascal [Select][+][-]window.onload = function(){var x1 =
document.getElementById("main_content_section"); if (x1) { var x =
document.getElementsByClassName("geshi");for (var i = 0; i program
cert_fphttpapp; {$mode objfpc}{$H+} uses {$ifdef UNIX} cthreads,
cmem, {$endif} fphttpapp, httpdefs, httproute, opensslsockets,
SysUtils //, fphttp //, ssockets ; procedure default_route(aReq:
TRequest; aResp: TResponse);begin aResp.Content :=
'
Test SSLTest
response.
'; WriteLn('Default route, IP: ' +
aReq.RemoteAddress + ', URL: ' + aReq.URL)end; var sPath:
String; begin HTTPRouter.RegisterRoute('/', @default_route, True);
Application.Port := 443; ShowCleanUpErrors := True;
Application.UseSSL := True; If Application.UseSSL then begin
Application.CertificateData.HostName := '127.0.0.1'; sPath :=
ExtractFilePath(ParamStr(0)) + 'cert\';
Application.CertificateData.CertCA.FileName := sPath + 'ca-
chain.cert.pem'; Application.CertificateData.Certificate.FileName
:= sPath + 'server.pem';
Application.CertificateData.PrivateKey.FileName := sPath +
'server.key'; Application.CertificateData.KeyPassword := '1234';
end; Application.Threaded := True; Application.Initialize;
WriteLn('Listening on port ' + Application.Port.ToString + '...');
Application.Run;end.
When I try to connect from Firefox I get
Code: Text [Select][+][-]window.onload = function(){var x1 =
document.getElementById("main_content_section"); if (x1) { var x =
document.getElementsByClassName("geshi");for (var i = 0; i Secure
Connection FailedAn error occurred during a connection to 127.0.0.1.
PR_CONNECT_ABORTED_ERROR
Edge and Chrome gives ERR_CONNECTION_RESET.
When I try to connect from (different) Lazarus app with
TFPHTTPClient.Post method I get error 'Connect to 127.0.0.1:443
failed.'.
It's the same for 32 and 64 bit target.
I adapted demo httpserv from Synapse and it works. Browsers warns
about insecure connection, but that is because I made and signed
certificates myself. Lazarus app with TFPHTTPClient.Post method (which
I mentioned above) works without issues.
So, can someone help to troubleshoot what did I do wrong?
I attached both projects: cert_fphttpapp (this one doesn't work) and
cert_synapse (this one works), and certificates under cert directory.
This is under Lazarus 2.2.6, FPC 3.2.2, Windows 11. I also tried with
FPC 3.3.1 but results are the same as under FPC 3.2.2.
----------------------------------------------------------------------
PierceNg · 2023-10-08 05:21
I changed the port number to 8443, as I'm on Linux and have to be root
to bind to port number < 1024.
Code: Text [Select][+][-]window.onload = function(){var x1 =
document.getElementById("main_content_section"); if (x1) { var x =
document.getElementsByClassName("geshi");for (var i = 0; i %
./cert_fphttpapp Listening on port 8443...Exception at
0000000000434A60: ESSL:Failed to initialize SSL keys.double free or
corruption (out)zsh: abort (core dumped) ./cert_fphttpapp
Using strace:
Code: Text [Select][+][-]window.onload = function(){var x1 =
document.getElementById("main_content_section"); if (x1) { var x =
document.getElementsByClassName("geshi");for (var i = 0; i % strace
./cert_fphttpapp...openat(AT_FDCWD, "/tmp/https/cert\\server.pem",
O_RDONLY) = -1 ENOENT (No such file or directory)openat(AT_FDCWD,
"/tmp/https/cert\\server.pem", O_RDONLY) = -1 ENOENT (No such file or
directory)openat(AT_FDCWD, "/tmp/https/cert\\server.pem", O_RDONLY) =
-1 ENOENT (No such file or directory)close(4)
= 0write(1, "Exception at 0000000000434A20: E"..., 68Exception
at 0000000000434A20: ESSL:Failed to initialize SSL keys....
Could not load server.pem. Fix is to make the code portable:
Code: [Select] sPath := ExtractFilePath(ParamStr(0)) + 'cert' +
DirectorySeparator;
Try again:
Code: Text [Select][+][-]window.onload = function(){var x1 =
document.getElementById("main_content_section"); if (x1) { var x =
document.getElementsByClassName("geshi");for (var i = 0; i % strace
./cert_fphttpapp...openat(AT_FDCWD, "/tmp/https/cert/server.key",
O_RDONLY) = 5fstat(5, {st_mode=S_IFREG|0600, st_size=1766, ...}) =
0read(5, "-----BEGIN RSA PRIVATE KEY-----\n"..., 4096) = 1766close(5)
= 0close(4)
= 0write(1, "Exception at 0000000000434A60: E"..., 68Exception at
0000000000434A60: ESSL:Failed to initialize SSL keys.
This time server cert and key found and read, but still SSL
initialization failed.
On a hunch I removed the password from the private key:
Code: Text [Select][+][-]window.onload = function(){var x1 =
document.getElementById("main_content_section"); if (x1) { var x =
document.getElementsByClassName("geshi");for (var i = 0; i % openssl
rsa -text -in server.key -out s.key -outform pem Enter pass phrase for
server.key:writing RSA key
Changed code:
Code: [Select] Application.CertificateData.PrivateKey.FileName
:= sPath + 's.key';
//Application.CertificateData.KeyPassword := '1234';
Build and run again. In another terminal:
Code: Text [Select][+][-]window.onload = function(){var x1 =
document.getElementById("main_content_section"); if (x1) { var x =
document.getElementsByClassName("geshi");for (var i = 0; i % curl -kv
https://localhost:8443/* Trying 127.0.0.1:8443...* TCP_NODELAY set*
Connected to localhost (127.0.0.1) port 8443 (#0)* ALPN, offering h2*
ALPN, offering http/1.1* successfully set certificate verify
locations:* CAfile: /etc/ssl/certs/ca-certificates.crt CApath:
/etc/ssl/certs* TLSv1.3 (OUT), TLS handshake, Client hello (1):*
TLSv1.3 (IN), TLS handshake, Server hello (2):* TLSv1.3 (IN), TLS
handshake, Encrypted Extensions (8):* TLSv1.3 (IN), TLS handshake,
Certificate (11):* TLSv1.3 (IN), TLS handshake, CERT verify (15):*
TLSv1.3 (IN), TLS handshake, Finished (20):* TLSv1.3 (OUT), TLS change
cipher, Change cipher spec (1):* TLSv1.3 (OUT), TLS handshake,
Finished (20):* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384*
ALPN, server did not agree to a protocol* Server certificate:*
subject: CN=example.com* start date: Oct 7 17:37:51 2023 GMT*
expire date: Dec 6 17:37:51 2042 GMT* issuer: C=HR; ST=example;
O=Example; CN=Example CA; emailAddress=info@example.com* SSL
certificate verify result: self signed certificate in certificate
chain (19), continuing anyway.> GET / HTTP/1.1> Host: localhost:8443>
User-Agent: curl/7.68.0> Accept: */*> * TLSv1.3 (IN), TLS handshake,
Newsession Ticket (4):* TLSv1.3 (IN), TLS handshake, Newsession Ticket
(4):* old SSL session ID is stale, removing* Mark bundle as not
supporting multiuse< HTTP/1.1 200 OK< Status: 200 OK< Content-Length:
86< Content-Type: text/html< Test
SSLTest response.
Conclusion: Buggy handling of password-protected private key by FCL.
----------------------------------------------------------------------
xinyiman · 2023-10-09 06:03
See if this article I wrote some time ago can help you.
It's in Italian, but with Google Translate you should understand the
meaning.
https://blog.lazaruspascal.it/2023/05/18/creare-un-web-server-https/
----------------------------------------------------------------------
dseligo · 2023-10-14 09:59
I created bug report:
https://gitlab.com/freepascal.org/fpc/source/-/issues/40468