From baf275e4e9f18ee1079d9fe159eeb2118180025e Mon Sep 17 00:00:00 2001 From: Tim Trippel Date: Mon, 14 Oct 2024 16:22:00 -0700 Subject: [PATCH 1/3] [ate_client] rename `target` parameter in client options This renames the `target` parameter in the ATE client options struct to be more specific: `pa_socket`. Signed-off-by: Tim Trippel --- src/ate/ate_api.h | 2 +- src/ate/ate_client.cc | 8 ++++---- src/ate/ate_client.h | 2 +- src/ate/ate_dll.cc | 2 +- src/ate/ate_main.cc | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ate/ate_api.h b/src/ate/ate_api.h index b3fc239..6206a62 100644 --- a/src/ate/ate_api.h +++ b/src/ate/ate_api.h @@ -91,7 +91,7 @@ typedef struct { typedef struct { // Endpoint address in IP or DNS format including port number. For example: // "localhost:5000". - const char* target; + const char* pa_socket; // File containing the Client certificate in PEM format. Required when // `enable_mtls` set to true. diff --git a/src/ate/ate_client.cc b/src/ate/ate_client.cc index 5506edf..3bad273 100644 --- a/src/ate/ate_client.cc +++ b/src/ate/ate_client.cc @@ -56,7 +56,8 @@ std::unique_ptr AteClient::Create(AteClient::Options options) { LOG(INFO) << "debug info: In AteClient::Create" << " AteClient.options: " << options; - // establish a grpc channel between the client and the targeted server: + // establish a grpc channel between the client (test program) and the targeted + // provisioning appliance server: // 1. set the grpc channel properties (insecured by default, authenticated and // encrypted if specified in options.enable_mtls parameter) auto credentials = grpc::InsecureChannelCredentials(); @@ -64,9 +65,8 @@ std::unique_ptr AteClient::Create(AteClient::Options options) { credentials = BuildCredentials(options); } // 2. create the grpc channel between the client and the targeted server - // (specified in options.target parameter) auto ate = absl::make_unique(ProvisioningApplianceService::NewStub( - grpc::CreateChannel(options.target, credentials))); + grpc::CreateChannel(options.pa_socket, credentials))); return ate; } @@ -148,7 +148,7 @@ Status AteClient::SendDeviceRegistrationPayload(RegistrationRequest& request, // overloads operator<< for AteClient::Options objects printouts std::ostream& operator<<(std::ostream& os, const AteClient::Options& options) { // write obj to stream - os << std::endl << "options.target = " << options.target << std::endl; + os << std::endl << "options.pa_socket = " << options.pa_socket << std::endl; os << "options.enable_mtls = " << options.enable_mtls << std::endl; os << "options.pem_cert_chain = " << options.pem_cert_chain << std::endl; os << "options.pem_private_key = " << options.pem_private_key << std::endl; diff --git a/src/ate/ate_client.h b/src/ate/ate_client.h index e6dbec0..f972c47 100644 --- a/src/ate/ate_client.h +++ b/src/ate/ate_client.h @@ -22,7 +22,7 @@ class AteClient { struct Options { // Endpoint address in IP or DNS format including port number. For example: // "localhost:5000". - std::string target; + std::string pa_socket; // Set to true to enable mTLS connection. When set to false, the connection // is established with insecure credentials. diff --git a/src/ate/ate_dll.cc b/src/ate/ate_dll.cc index 31c8630..3659d06 100644 --- a/src/ate/ate_dll.cc +++ b/src/ate/ate_dll.cc @@ -262,7 +262,7 @@ DLLEXPORT void CreateClient( // convert from ate_client_ptr to AteClient::Options o.enable_mtls = options->enable_mtls; - o.target = options->target; + o.pa_socket = options->pa_socket; if (o.enable_mtls) { // Load the PEM data from the pointed files absl::Status s = diff --git a/src/ate/ate_main.cc b/src/ate/ate_main.cc index b8e5108..d5d6caf 100644 --- a/src/ate/ate_main.cc +++ b/src/ate/ate_main.cc @@ -20,7 +20,7 @@ #include "src/pa/proto/pa.grpc.pb.h" #include "src/version/version.h" -ABSL_FLAG(std::string, target, "", +ABSL_FLAG(std::string, pa_socket, "", "host:port of the target provisioning appliance server."); ABSL_FLAG(bool, enable_mtls, false, "Enable mTLS secure channel."); ABSL_FLAG(std::string, client_key, "", @@ -64,7 +64,7 @@ int main(int argc, char **argv) { AteClient::Options options; options.enable_mtls = absl::GetFlag(FLAGS_enable_mtls); - options.target = absl::GetFlag(FLAGS_target); + options.pa_socket = absl::GetFlag(FLAGS_pa_socket); if (options.enable_mtls) { std::unordered_map *, std::string *> pem_options = { {&FLAGS_client_key, &options.pem_private_key}, From 88e13557879e3f0056b7b42da21794a45b1af9ac Mon Sep 17 00:00:00 2001 From: Tim Trippel Date: Mon, 14 Oct 2024 16:49:35 -0700 Subject: [PATCH 2/3] [ate,cp] add reference CP test program boilerplate This adds reference CP test program boilerplate code. This partially addresses #6. Signed-off-by: Tim Trippel --- src/ate/test_programs/BUILD.bazel | 19 +++++ src/ate/test_programs/cp.cc | 117 ++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 src/ate/test_programs/BUILD.bazel create mode 100644 src/ate/test_programs/cp.cc diff --git a/src/ate/test_programs/BUILD.bazel b/src/ate/test_programs/BUILD.bazel new file mode 100644 index 0000000..edc8b2b --- /dev/null +++ b/src/ate/test_programs/BUILD.bazel @@ -0,0 +1,19 @@ +# Copyright lowRISC contributors (OpenTitan project). +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +package(default_visibility = ["//visibility:public"]) + +cc_binary( + name = "cp", + srcs = ["cp.cc"], + deps = [ + "//src/ate:ate_client", + "//src/version", + "@com_google_absl//absl/flags:flag", + "@com_google_absl//absl/flags:parse", + "@com_google_absl//absl/log", + "@com_google_absl//absl/status", + "@com_google_absl//absl/status:statusor", + ], +) diff --git a/src/ate/test_programs/cp.cc b/src/ate/test_programs/cp.cc new file mode 100644 index 0000000..68774e9 --- /dev/null +++ b/src/ate/test_programs/cp.cc @@ -0,0 +1,117 @@ +// Copyright lowRISC contributors (OpenTitan project). +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 + +#include + +#include +#include +#include +#include +#include + +#include "absl/flags/flag.h" +#include "absl/flags/parse.h" +#include "absl/flags/usage_config.h" +#include "absl/log/log.h" +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "src/ate/ate_client.h" +#include "src/pa/proto/pa.grpc.pb.h" +#include "src/version/version.h" + +/** + * PA configuration flags. + */ +ABSL_FLAG(std::string, pa_socket, "", "host:port of the PA server."); +ABSL_FLAG(std::string, sku, "", "SKU string to initialize the PA session."); +ABSL_FLAG(std::string, sku_auth_pw, "", + "SKU authorization password string to initialize the PA session."); + +/** + * mTLS configuration flags. + */ +ABSL_FLAG(bool, enable_mtls, false, "Enable mTLS secure channel."); +ABSL_FLAG(std::string, client_key, "", + "File path to the PEM encoding of the client's private key."); +ABSL_FLAG(std::string, client_cert, "", + "File path to the PEM encoding of the client's certificate chain."); +ABSL_FLAG(std::string, ca_root_certs, "", + "File path to the PEM encoding of the server root certificates."); + +namespace { +using provisioning::VersionFormatted; +using provisioning::ate::AteClient; + +// Returns `filename` content in a std::string format +absl::StatusOr ReadFile(const std::string &filename) { + auto output_stream = std::ostringstream(); + std::ifstream file_stream(filename); + if (!file_stream.is_open()) { + return absl::InvalidArgumentError( + absl::StrCat("Unable to open file: \"", filename, "\"")); + } + output_stream << file_stream.rdbuf(); + return output_stream.str(); +} + +} // namespace + +int main(int argc, char **argv) { + // Parse cmd line args. + absl::FlagsUsageConfig config; + config.version_string = &VersionFormatted; + absl::SetFlagsUsageConfig(config); + absl::ParseCommandLine(argc, argv); + LOG(INFO) << VersionFormatted(); + + // Extract and validate ATE client options. + AteClient::Options options; + options.pa_socket = absl::GetFlag(FLAGS_pa_socket); + options.enable_mtls = absl::GetFlag(FLAGS_enable_mtls); + if (options.enable_mtls) { + std::unordered_map *, std::string *> pem_options = { + {&FLAGS_client_key, &options.pem_private_key}, + {&FLAGS_client_cert, &options.pem_cert_chain}, + {&FLAGS_ca_root_certs, &options.pem_root_certs}, + }; + + for (auto opt : pem_options) { + std::string filename = absl::GetFlag(*opt.first); + if (filename.empty()) { + LOG(ERROR) << "--" << absl::GetFlagReflectionHandle(*opt.first).Name() + << " not set. This is a required argument when " + << " --enable_mtls is set to true." << std::endl; + return -1; + } + auto result = ReadFile(filename); + if (!result.ok()) { + LOG(ERROR) << "--" << absl::GetFlagReflectionHandle(*opt.first).Name() + << " " << result.status() << std::endl; + return -1; + } + *opt.second = result.value(); + } + } + + // Instantiate a client. + auto ate = AteClient::Create(options); + + // Init/Close session. + grpc::Status status = ate->InitSession(absl::GetFlag(FLAGS_sku), + absl::GetFlag(FLAGS_sku_auth_pw)); + if (!status.ok()) { + LOG(ERROR) << "InitSession failed with " << status.error_code() << ": " + << status.error_message() << std::endl; + } + + // TODO(#6): add CP test code here. + + status = ate->CloseSession(); + if (!status.ok()) { + LOG(ERROR) << "CloseSession failed with " << status.error_code() << ": " + << status.error_message() << std::endl; + } + + return 0; +} From 10a46b0efa46a47103b459877b17f609da882448 Mon Sep 17 00:00:00 2001 From: Tim Trippel Date: Mon, 14 Oct 2024 17:04:55 -0700 Subject: [PATCH 3/3] [tests] run reference CP flow in CI This adds the reference CP flow to the integration test script to ensure it is run in CI. Signed-off-by: Tim Trippel --- run_integration_tests.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/run_integration_tests.sh b/run_integration_tests.sh index d650fa5..18f03ff 100755 --- a/run_integration_tests.sh +++ b/run_integration_tests.sh @@ -45,3 +45,13 @@ for sku in "${SKUS[@]}"; do --parallel_clients=10 \ --total_calls_per_client=10 done + +# Run the reference CP flow. +CP_SKUS=("sival") +for sku in "${CP_SKUS[@]}"; do + echo "Running reference CP flow with sku: ${sku} ..." + bazelisk run //src/ate/test_programs:cp -- \ + --pa_socket="localhost:5001" \ + --sku="${sku}" \ + --sku_auth_pw="test_password" +done