cesanta / mongoose

Embedded Web Server

Home Page:https://mongoose.ws

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Mongoose documentation SSL/TLS tutorial is inaccurate for mg_tls_opts.

jimellert opened this issue · comments

  • My goal is: To understand how to initialize TLS on the server side.
  • My actions were: Follow the example in the SSL/TLS tutorial.
  • My expectation was: Correct operation.
  • The result I saw: OpenSSL complaint about "not enough data" for certs.

The mg_tls_opts .cert and .key fields are supposed to be assigned the actual cert and key strings, not a path to the cert and key files.
The "How to load credentials" section correctly shows using mg_file_read to load the cert and key files and assign the cert and key strings to mg_tls_opts.
But the "TLS for servers", TLS for clients", and "Two-way TLS" sections show using mg_unpacked to assign a path to the .ca, .cert, & .key variables. These sections should be updated to use mg_file_read unstead of mg_unpacked.

Thank you for your opinions. I beg to differ.
The very same section you mention, in the following paragraphs, shows other two forms in which you can load your credentials.

They can also be loaded from a file in an embedded filesystem, using mg_unpacked() as shown above:

struct mg_tls_opts opts = {.ca = mg_unpacked("/certs/ca.pem")};

This accesses the file directly from the code, where it has been embedded.

"above" in the first sentence, makes reference to what you've seen in the server and client sections.

Finally, certificates and keys can be defined as C strings in source code:

That can be seen in the http-restful-server example, linked in the server section, the device-dashboard example, and probably others too.

These three ways are also tested every day on every push:

mongoose/test/unit_test.c

Lines 1286 to 1289 in dd64582

char *data = mg_file_read(&mg_fs_posix, "test/data/ca.pem", &size);
struct mg_tls_opts opts;
memset(&opts, 0, sizeof(opts));
mg_mgr_init(&mgr);

mongoose/test/unit_test.c

Lines 786 to 787 in dd64582

memset(&opts, 0, sizeof(opts)); // read CA from packed_fs
opts.ca = mg_unpacked("test/data/ca.pem");

mongoose/test/unit_test.c

Lines 790 to 794 in dd64582

opts.ca = mg_str(s_tls_ca);
// opts.cert = mg_str(s_tls_cert);
// opts.key = mg_str(s_tls_key);
}
mg_tls_init(c, &opts);

Which way you choose, is up to you.

Mongoose is embedded oriented, and while we serve the OS world, we aim to support devices with no built-in filesystem.
The client and server sections do not say "do this to load your credentials", those sections are explaining that you have to initalize TLS at that point, and how real world examples taken from actual examples in our repo, linked in the final lines of that section, do it:
TCP server:

struct mg_tls_opts opts = {.ca = mg_unpacked("/certs/ss_ca.pem"),
.cert = mg_unpacked("/certs/ss_server.pem"),
.key = mg_unpacked("/certs/ss_server.pem")};
mg_tls_init(c, &opts);

HTTP client:
if (mg_url_is_ssl(s_url)) {
struct mg_tls_opts opts = {.ca = mg_unpacked("/certs/ca.pem"),
.name = mg_url_host(s_url)};
mg_tls_init(c, &opts);

Both show you how to build the embedded file system, and the TCP server example does not carry the packed filesystem itself so it will generate it on the fly for you. It also shows both client and server.

[tcp]$ make CFLAGS_EXTRA="-DMG_TLS=MG_TLS_OPENSSL -lssl -lcrypto"
cc ../../test/pack.c -o ./pack
./pack                     certs/ss_server.pem certs/ss_ca.pem certs/ss_client.pem > packed_fs.c
cc main.c mongoose.c packed_fs.c        -W -Wall -Wextra -g -I.   -DMG_ENABLE_PACKED_FS=1 -DMG_TLS=MG_TLS_OPENSSL -lssl -lcrypto -o example                     
./example
21064ce 2 main.c:56:sfn                 SERVER is listening
2106532 2 main.c:19:cfn                 CLIENT has been initialized
2106532 2 main.c:83:timer_fn            CLIENT connecting
2106532 2 main.c:21:cfn                 CLIENT connected
2106532 2 main.c:58:sfn                 SERVER accepted a connection
21078c3 2 main.c:43:cfn                 CLIENT sent data
21078c3 2 main.c:67:sfn                 SERVER got data: Hi, there
21078c3 2 main.c:31:cfn                 CLIENT got data: Hi, there
2108ac3 2 main.c:34:cfn                 CLIENT disconnected
2108ac3 2 main.c:71:sfn                 SERVER disconnected

I'm sorry. I did not specify MG_ENABLE_PACKED_FS when compiling. I think that's what caused mg_unpacked(path) to not work for me. My bad.