Add nat20cli command line tool for nat20device.#104
Conversation
LCOV of commit
|
54d8a0f to
0612f25
Compare
This reverts commit b159fbb.
…nux_example_nat20cli
There was a problem hiding this comment.
Pull request overview
Adds a new nat20cli Linux userspace command-line tool that drives the nat20 DICE service through /dev/nat200, together with a parallel nat20test integration test suite and CI plumbing to run both in QEMU. The CLI exposes promote/cdi-cert/eca-cert/eca-ee-cert/eca-ee-sign operations and ships with a helper test script that uses OpenSSL to validate the produced chain; the integration test exhaustively verifies all key-type/format permutations across promote levels using libnat20 + OpenSSL primitives in test_helpers.c/h.
Changes:
- New
nat20clitool (option parsing, request construction, response handling, hex helpers) plus shell test script and OpenSSL DICE OID config. - New
nat20testintegration test binary with COSE/X.509/signature verification helpers and a full multi-level promote chain test. - Buildroot packages (
nat20cli,nat20test), defconfig wiring, envsetup additions, and a CI workflow extension that builds the rootfs and runs both suites under QEMU.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| examples/linux/nat20cli/src/main.c | New CLI program implementing all request types and hex parsing. |
| examples/linux/nat20cli/nat20cli_test.sh | E2E test invoking the CLI and OpenSSL chain/signature verification. |
| examples/linux/nat20cli/nat20cli_qemu_init.sh | PID 1 init wrapper to run the CLI test in QEMU. |
| examples/linux/nat20cli/openssl_dice.cnf | Registers DICE OID names for openssl x509 -text. |
| examples/linux/nat20cli/CMakeLists.txt | CMake build for the CLI binary and scripts. |
| examples/linux/nat20test/test/nat20_integration_test.c | Parameterised integration test driving the DICE service. |
| examples/linux/nat20test/test/test_helpers.{c,h} | OpenSSL/COSE/X.509 verification utilities used by the test. |
| examples/linux/nat20test/nat20test.sh / nat20_qemu_init.sh | Test runner and QEMU init wrappers. |
| examples/linux/nat20test/CMakeLists.txt | CMake build for the integration test. |
| examples/linux/br_external/package/nat20cli/{Config.in,nat20cli.mk} | Buildroot package definition for the CLI. |
| examples/linux/br_external/package/nat20test/{Config.in,nat20test.mk} | Buildroot package definition for the integration test. |
| examples/linux/br_external/Config.in / configs/qemu_br_defconfig | Hooks new packages into the build. |
| examples/linux/br_external/utils/envsetup.sh | Adds SRCDIR overrides and a run_cli_test helper. |
| .github/workflows/linux-kmod-build.yml | Builds CLI/test packages and runs both QEMU test suites in CI. |
| .github/license-check/license-config.json | Adds openssl_dice.cnf to exempted-formats list. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| int parse_output_format(char const *str) { | ||
| if (strcmp(str, "x509") == 0) return n20_certificate_format_x509_e; | ||
| #ifdef N20_WITH_COSE |
| size_t pos = 0; | ||
| if ((len & 1) != 0) { | ||
| // Odd length, assume leading zero | ||
| *out_pos++ = nibble2bits(hex[0]); |
| " --certificate-format -f <x509|cose>\n" | ||
| " The format of the certificate to be issued.\n" | ||
| "\n" | ||
| "Options (cdi-cert):" |
| if (strcmp(str, "sign") == 0) { | ||
| N20_OPEN_DICE_KEY_USAGE_SET_DIGITAL_SIGNATURE(key_usage); | ||
| } else if (strcmp(str, "cert-sign") == 0) { | ||
| N20_OPEN_DICE_KEY_USAGE_SET_KEY_CERT_SIGN(key_usage); | ||
| } |
| " The output file to write the resulting certificate or " | ||
| "signature to.\n" | ||
| "\n" | ||
| "Options (*-cert commands):\n" |
…nux_example_nat20cli
timhirsh
left a comment
There was a problem hiding this comment.
Approving GH Actions changes 👍
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…nux_example_nat20cli
| } | ||
|
|
||
| slice->buffer = (uint8_t *)hex_str; | ||
| int bytes_written = hex_string_to_bytes_in_place((char *)slice->buffer); |
There was a problem hiding this comment.
This was found by Claude and it probably works OK, but this in-place mutation occurs on otparg from the parse_command_options() function. It seems to work with our compiler, so I'm unclear how important this is.
| return cli_error_libnat20; | ||
| } | ||
|
|
||
| printf("Compressed input: "); |
There was a problem hiding this comment.
Not a problem, but you have a lot of informational print statements throughout the code and I just wanted to verify that you meant to keep all of these in.
| exit(EXIT_FAILURE); | ||
| } | ||
|
|
||
| uint8_t response_buffer[1024]; |
There was a problem hiding this comment.
I want to verify that 1024 bytes is sufficient. Is this only going to run on our sample implementation, or might it run in different scenarios? In PR 105 from yesterday, your response buffers were a mixture of 1024 and 2048 sizes (depending on the scenario), but most of the certificate responses were 2048.
| static cli_error_t handle_cdi_cert_response(n20_slice_t response_slice, | ||
| char const *output_file, | ||
| n20_open_dice_input_t const *next_context) { | ||
| cli_error_t err = handle_cert_response(response_slice, output_file, "CDI cert", true); |
There was a problem hiding this comment.
should probably add a verbose option to control these debug prints.
| if (n20_err != n20_error_ok_e) { | ||
| fprintf(stderr, "Failed to write request. libnat20 error: %d (0x%x)\n", n20_err, n20_err); | ||
| print_usage(argv[0]); | ||
| exit(EXIT_FAILURE); |
There was a problem hiding this comment.
do you need cleanup_parsed_options here? and all the other error paths below? Should we add a goto to handle the error paths?
| # along with this program; if not, see | ||
| # <https://www.gnu.org/licenses/>. | ||
|
|
||
| set -e |
There was a problem hiding this comment.
| set -e | |
| set -euo pipefail |
|
|
||
| echo -n "Test message for ECA EE cert" > message.txt | ||
|
|
||
| nat20cli cdi-cert --key-type p256 --parent-key-type p256 --output cdi_0.der --certificate-format x509 --code-desc 795375622d322e332e343a33386334353963666164666132623839353333363939353465313266373534386433613161633937336338383830303563336236646232333436636263386631 --code 228d8f76c811276e991012cf5f46090377fc72c95a6ef9e1ccd4eebec8997be5b57f0fb2c7f4804af212711e7b49533f8bc00ddee9480f76155b3da1101604b9 --conf-desc 45787472616f7264696e617279206e6f726d616c20636f6e66696775726174696f6e --conf 671e957aff5565a55961dcaef7634f1a665d8f286e7bd99593532741417f22981b57bdc39241c9685f7377e3622067c261c3ce974e6db5f18d121adad2d76185 --auth-desc 41206365727469666963617465 --auth 50808e4ab921ecf31ca5f662b6d8b85b98ec4d3f64175c8b5d70c1f0e2fef048f87b3178907e1f2d652bd8588fa84f4c374347cc34b97dae13a5b981790b38cb --mode normal --hidden 2f299d2cc916e5219a6bcbc14c7135fa25e9a71018c2bafe8c0658d4041de6c87aa444aedcc68e7d7674b81b5838be1b74bf19d4d6fb05fb0db9ee7e297afc09 |
There was a problem hiding this comment.
for readability, put each option and value on its own line.
| openssl x509 -inform pem -in eca_ee.pem -pubkey -noout > eca_ee_pubkey.pem | ||
| openssl dgst -sha256 -verify eca_ee_pubkey.pem -signature sig.der message.txt | ||
|
|
||
| echo "OpenSSL signature verification passed." No newline at end of file |
This commandline tool provides a primitive interface to communicate with
a nat20 device.