|
Barracuda Application Server C/C++ Reference
Native APIs, integration guides, and platform interfaces
|
The Barracuda App Server (BAS) can protect deployed Lua ZIP applications in two different ways:
Signing is most useful when Lua applications are deployed as external ZIP files instead of being embedded directly in firmware.
If you are new to this topic, start with this rule of thumb:
| Goal | Use signing? | Use encryption? |
|---|---|---|
| Deploy a normal application with no secrets in the ZIP | Yes | Usually no |
| Prevent unauthorized or modified Lua applications from running | Yes | Usually no |
| Protect passwords, private keys, or other secrets stored inside the ZIP | Yes | Yes, for the sensitive files |
| Build the strongest practical deployment | Yes | Yes, but encrypt only the files that need confidentiality |
For most embedded products, signing is the most important feature. If you use ZIP encryption, you should also require ZIP signing. Otherwise, an attacker may be able to replace encrypted entries with spoofed plaintext files.
When BaLua_param.zipPubKey is configured, the Lua ba.mkio ZIP creation paths verify the archive before exposing the resulting I/O object. This does not automatically verify a ZipIo that application C code constructs itself, nor the vmio supplied before the Lua VM is created. Verify those archives explicitly with baCheckZipSignature when verification is required.
Signing gives you two important guarantees:
In practice, signing is what prevents unauthorized Lua applications, modified scripts, or injected files from being mounted and executed.
ZIP encryption protects the content of selected files inside the archive. This is useful for files such as:
You do not need to encrypt every file in the archive. In fact, that is usually a bad idea because it increases runtime decryption work, especially for frequently accessed Lua files and Lua Server Pages. ZIP encryption is applied per file, so it is usually best to encrypt only the files that actually contain secrets.
These two mechanisms are independent and solve different problems:
A signed ZIP file is not automatically encrypted. An encrypted ZIP file is not automatically trusted. In practice, encrypted ZIP files must be signed. Without signing, an attacker may be able to replace encrypted files in the archive with plaintext files containing spoofed data.
If you prefer not to embed a global ZIP password in C code, or if different ZIP files use different passwords, Lua code can set passwords individually by using io:setpasswd().
For most deployments, the easiest way to think about the process is:
io:setpasswd().Important: If you modify the ZIP file after signing it, you must sign it again. A signature always covers the final ZIP file bytes.
BAS verifies signed ZIP files by using a standard public/private key model:
Only someone with the private key can produce a valid signature. BAS only needs the public key to verify the signature when the ZIP file is mounted.
ZIP files permit extra data to be appended to the end of the file. BAS takes advantage of this by storing the digital signature after the ZIP data. The BAS verifier expects its signature immediately after the archive end record. Use a ZIP without an archive comment, then sign it as shown below. The current verifier requires a signed file of at least 512 bytes and searches its final 512 bytes for the end record. See baCheckZipSignature for results.
When the configured Lua ZIP creation path opens the archive, it checks the signature before returning the I/O object.
If you do not already have an ECC key pair, you can create one with OpenSSL:
Files:
private_key.pem: keep this secure; it is used to sign ZIP files.public_key.pem: embed this key in BAS so signed ZIP files can be verified.The following Bash script shows the basic signing process:
Usage:
Important: Run the script only on the final ZIP file. If you sign a ZIP file twice, or edit it after signing, signature verification will fail.
To enforce signed ZIP files, embed the public key in your BAS startup code and assign it to BaLua_param.zipPubKey.
Use the SharkSSLParseKey command-line tool to convert the PEM public key into a C array:
This produces C data similar to:
With zipPubKey configured, the Lua ZIP creation paths verify archives against that borrowed key. Keep its storage alive for the VM lifetime.
ZIP encryption uses a symmetric password. The same password is used to encrypt and decrypt the protected files inside the ZIP archive.
The binary password can be embedded in compiled code. The password conversion tool changes its representation; it does not itself provide white-box protection or make an embedded password impossible to recover. BAS uses the matching password to decrypt entries when accessed.
Use ZIP encryption when your deployed ZIP contains secrets that should not be visible just because someone can copy the ZIP file. This works best for secrets that are static: files that never change after deployment, or that only change when you deliver a new signed application or OTA upgrade. In practice, ZIP encryption should be combined with ZIP signing.
Examples:
ZIP encryption is not intended for data that your application must update continuously at runtime. If you need encrypted read/write storage for files that are created or modified while the system is running, use a runtime encryption layer such as CryptoIO.
Do not treat ZIP encryption as a substitute for ZIP signing. ZIP signing controls what code BAS is willing to trust. ZIP encryption only controls who can read selected file contents. If signing is not enabled, an attacker may be able to replace encrypted files with plaintext files containing spoofed data.
To prepare a ZIP password for BAS, use the binpwd2str command line tool. This tool is designed for BAS deployments and produces three forms of the same password:
binpwd2str (source in the SDK's bin/binpwd2str.c).binpwd2str input-file to produce the corresponding C array and ZIP-tool password. Use externally generated random bytes for production passwords; the tool's no-argument generator uses C rand.io:setpasswd().With zipBinPwd configured, BAS can automatically decrypt encrypted ZIP entries that use the matching password.
zipBinPwd is a borrowed const U8*; zipBinPwdLen is its byte count as U16, so the array must fit that type and remain alive for the VM lifetime. With a default password configured, pwdRequired (BaBool) additionally controls whether plaintext entries are rejected. Leave it FALSE when encrypting only selected files; TRUE requires every accessed entry to be encrypted.
The snippets show only ZIP policy fields. Also initialize the required vmio and other host fields before calling balua_create, and check its return.
If you want both protections, embed both the public key and the ZIP password:
The Barracuda App Server can support secure OTA upgrades both manually, for example through a web interface, and automatically through IoT protocols. A practical way to deliver an upgrade is to package it as a ZIP file and then protect that ZIP with the same signing and encryption mechanisms described in this document.
An OTA ZIP package can contain the new firmware image and any additional files required by the upgrade process, such as standalone applications, configuration files, or other deployment assets. This makes the ZIP file a convenient upgrade container for both firmware and application-level updates.
When ZIP signing is enabled, opening the OTA package with ba.mkio(baseio, path) automatically triggers signature verification. If the ZIP file is unsigned or has been modified, the call fails. This gives the upgrade logic a strong integrity and authenticity check before Lua code reads any data from the package.
If ZIP encryption is also enabled, the OTA package can additionally protect the confidentiality of sensitive upgrade files (secrets) stored inside the ZIP archive. In other words, signing protects the upgrade package from tampering, while encryption keeps selected files inside the package confidential.
Lua code can then be designed to open the verified ZIP package, extract the required files, and deploy the new firmware or accompanying resources. This approach works well when you want one upgrade artifact to carry everything needed for a secure field update.
If a ZIP file does not load as expected, check the following: