From fce359b240cc3869f609256701a202c788ba4634 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 6 Oct 2016 12:51:47 +1100 Subject: [PATCH] build system: Add support for embedded arbitrary binary or text files in .rodata Simplifies examples of embedding a certificate file or a root cert. This is a much cruder mechanism than the full flash filesystem we want eventually, but still sometimes useful. --- docs/build_system.rst | 22 +++++++ examples/04_https_request/main/cert.c | 44 -------------- examples/04_https_request/main/component.mk | 9 ++- .../main/https_request_main.c | 18 +++++- .../main/server_root_cert.pem | 27 +++++++++ make/component_common.mk | 57 ++++++++++++++++--- 6 files changed, 117 insertions(+), 60 deletions(-) delete mode 100644 examples/04_https_request/main/cert.c create mode 100644 examples/04_https_request/main/server_root_cert.pem diff --git a/docs/build_system.rst b/docs/build_system.rst index 34db487e0..85ebfe46d 100644 --- a/docs/build_system.rst +++ b/docs/build_system.rst @@ -280,6 +280,28 @@ component and resides under the component path. Because logo.h is a generated file, it needs to be cleaned when make clean is called which why it is added to the COMPONENT_EXTRA_CLEAN variable. +Embedding Binary Data +===================== + +Sometimes you have a file with some binary or text data that you'd like to make available to your component - but you don't want to reformat the file as C source. + +You can set a variable COMPONENT_EMBED_FILES in component.mk, giving the names of the files to embed in this way:: + + COMPONENT_EMBED_FILES := server_root_cert.der + +Or if the file is a string, you can use the variable COMPONENT_EMBED_TXTFILES. This will embed the contents of the text file as a null-terminated string:: + + COMPONENT_EMBED_TXTFILES := server_root_cert.pem + +The file's contents will be added to the .rodata section in flash, and are available via symbol names as follows:: + + extern const uint8_t server_root_cert_pem_start[] asm("_binary_server_root_cert_pem_start"); + extern const uint8_t server_root_cert_pem_end[] asm("_binary_server_root_cert_pem_end"); + +The names are generated from the full name of the file, as given in COMPONENT_EMBED_FILES. Characters /, ., etc. are replaced with underscores. The _binary prefix in the symbol name is added by objcopy and is the same for both text and binary files. + +For an example of using this technique, see examples/04_https_request - the certificate file contents are loaded from the text .pem file at compile time. + Cosmetic Improvements ===================== diff --git a/examples/04_https_request/main/cert.c b/examples/04_https_request/main/cert.c deleted file mode 100644 index 7acc438ef..000000000 --- a/examples/04_https_request/main/cert.c +++ /dev/null @@ -1,44 +0,0 @@ -/* This is the CA certificate for the CA trust chain of - www.howsmyssl.com in PEM format, as dumped via: - - openssl s_client -showcerts -connect www.howsmyssl.com:443 -#include -#include - -/* - 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3 - i:/O=Digital Signature Trust Co./CN=DST Root CA X3 - */ -const char *server_root_cert = "-----BEGIN CERTIFICATE-----\r\n" -"MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/\r\n" -"MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\r\n" -"DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow\r\n" -"SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT\r\n" -"GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC\r\n" -"AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF\r\n" -"q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8\r\n" -"SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0\r\n" -"Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA\r\n" -"a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj\r\n" -"/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T\r\n" -"AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG\r\n" -"CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv\r\n" -"bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k\r\n" -"c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw\r\n" -"VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC\r\n" -"ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz\r\n" -"MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu\r\n" -"Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF\r\n" -"AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo\r\n" -"uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/\r\n" -"wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu\r\n" -"X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG\r\n" -"PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6\r\n" -"KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==\r\n" -"-----END CERTIFICATE-----\r\n"; - - diff --git a/examples/04_https_request/main/component.mk b/examples/04_https_request/main/component.mk index 24356f23e..7fbfcc55d 100644 --- a/examples/04_https_request/main/component.mk +++ b/examples/04_https_request/main/component.mk @@ -1,10 +1,9 @@ # # Main Makefile. This is basically the same as a component makefile. # -# This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, -# this will take the sources in the src/ directory, compile them and link them into -# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, -# please read the ESP-IDF documents if you need to do this. -# + +# embed files from the "certs" directory as binary data symbols +# in the app +COMPONENT_EMBED_TXTFILES := server_root_cert.pem include $(IDF_PATH)/make/component_common.mk diff --git a/examples/04_https_request/main/https_request_main.c b/examples/04_https_request/main/https_request_main.c index 0c8b2463f..7f302409d 100644 --- a/examples/04_https_request/main/https_request_main.c +++ b/examples/04_https_request/main/https_request_main.c @@ -74,8 +74,18 @@ static const char *REQUEST = "GET " WEB_URL " HTTP/1.1\n" "User-Agent: esp-idf/1.0 esp32\n" "\n"; -/* Root cert for howsmyssl.com, found in cert.c */ -extern const char *server_root_cert; +/* Root cert for howsmyssl.com, taken from server_root_cert.pem + + The PEM file was extracted from the output of this command: + openssl s_client -showcerts -connect www.howsmyssl.com:443 > $$(notdir $$<) ) + $$(Q) $$(OBJCOPY) $(OBJCOPY_EMBED_ARGS) $$(notdir $$<) $$@ + $$(Q) rm $$(notdir $$<) +endef + +# generate targets to embed binary & text files +$(foreach binfile,$(COMPONENT_EMBED_FILES), $(eval $(call GenerateEmbedTarget,$(binfile),bin))) + +$(foreach txtfile,$(COMPONENT_EMBED_TXTFILES), $(eval $(call GenerateEmbedTarget,$(txtfile),txt))) + +# generate targets to create binary embed directories +$(foreach bindir,$(sort $(dir $(COMPONENT_EMBED_FILES))), $(eval $(call GenerateBuildDirTarget,$(bindir))))