✅ File Structure Created:
services/spdm/cert-store/src/lib.rs - Main implementationservices/spdm/cert-store/BUILD.bazel - Bazel build configurationservices/spdm/cert-store/Cargo.toml - Cargo package manifestservices/spdm/cert-store/README.md - DocumentationCargo.toml workspace membersconst CERT_CHAIN_PLACEHOLDER_SIZE: usize = 32;
SHA384_HASH_SIZE = 48 (from spdm-lib)ECC_P384_SIGNATURE_SIZE = 96 (from spdm-lib)ECDSA_P384_PRIVATE_KEY_SIZE = 48 (from crypto-api)pub struct Ast1060CertStore { crypto: CryptoClient, }
SLOT_0_CERT_CHAIN: [u8; 32] = [0xAA; 32]SLOT_0_ROOT_HASH: [u8; 48] = [0xBB; 48]SLOT_0_PRIVATE_KEY: [u8; 48] = [0xCC; 48]SpdmCertStoreslot_count() -> u8
2is_provisioned(slot_id: u8) -> bool
slot_id == 0cert_chain_len(&mut self, asym_algo, slot_id) -> Result<usize>
CERT_CHAIN_PLACEHOLDER_SIZE (32)get_cert_chain(&mut self, slot_id, asym_algo, offset, cert_portion) -> Result<usize>
root_cert_hash(&mut self, slot_id, asym_algo, cert_hash) -> Result<()>
sign_hash(&self, slot_id, hash, signature) -> Result<()>
crypto.ecdsa_p384_sign(&SLOT_0_PRIVATE_KEY, hash)ClientError → CertStoreError::PlatformErrorkey_pair_id(&self, slot_id) -> Option<u8>
Nonecert_info(&self, slot_id) -> Option<CertificateInfo>
Nonekey_usage_mask(&self, slot_id) -> Option<KeyUsageMask>
None| Condition | Error Returned |
|---|---|
slot_id >= 2 | CertStoreError::InvalidSlotId(slot_id) |
slot_id == 1 | CertStoreError::CertReadError |
asym_algo != EccP384 | CertStoreError::UnsupportedHashAlgo |
offset >= cert_len | CertStoreError::InvalidOffset |
| IPC failure | CertStoreError::PlatformError |
✅ test_slot_count() - Verifies 2 slots ✅ test_is_provisioned() - Slot 0 provisioned, others not ✅ test_invalid_slot() - Rejects invalid slot IDs ✅ test_unprovisioned_slot() - Rejects slot 1 ✅ test_cert_chain_len() - Returns correct length ✅ test_get_cert_chain_full() - Full chain retrieval ✅ test_get_cert_chain_with_offset() - Offset reading ✅ test_get_cert_chain_zero_fill() - Zero-fill behavior ✅ test_get_cert_chain_invalid_offset() - Offset validation ✅ test_root_hash_copy() - Hash retrieval ✅ test_optional_methods_return_none() - Optional methods
rust_library( name = "spdm_cert_store_lib", srcs = glob(["src/**/*.rs"]), crate_name = "openprot_spdm_cert_store", edition = "2024", visibility = ["//visibility:public"], deps = [ "//services/crypto/api:crypto_api", "//services/crypto/client:crypto_client", "@rust_crates//:spdm-lib", ], )
[dependencies] spdm-lib = { git = "https://github.com/9elements/spdm-lib.git", branch = "buildup" } crypto-client = { path = "../../crypto/client" } crypto-api = { path = "../../crypto/api" }
The library cannot be built standalone using Bazel due to platform constraints:
crypto-client depends on pw_kernel/userspace--platforms=//target/ast1060-evb:ast1060-evbThis is expected and correct - the library is meant to be used by userspace SPDM applications on the target platform.
To use in an SPDM server application:
use openprot_spdm_cert_store::Ast1060CertStore; use spdm_lib::cert_store::SpdmCertStore; // In your SPDM server init code: let cert_store = Ast1060CertStore::new(handle::CRYPTO); // Pass to SPDM responder let responder = SpdmResponder::new(cert_store, ...);
To verify the implementation:
bazel build --platforms=//target/ast1060-evb:ast1060-evb \ //target/ast1060-evb/spdm:system_image
Before production use, replace placeholder data:
include_bytes!()✅ All planned methods implemented ✅ Error handling complete ✅ Unit tests included ✅ Documentation complete ✅ Build configuration correct ✅ Following spdm-lib patterns ✅ IPC integration with crypto service ✅ Placeholder data for development