From 2242bcb7125940e5fbeb3708f867e6021279b820 Mon Sep 17 00:00:00 2001 From: Jesper Brynolf Date: Sat, 1 Jun 2024 23:14:05 +0200 Subject: [PATCH] Makes the serde dependency optional. This fixes #525 adding the `serde` feature which when enabled makes it possible to serialize and deserialize the types that previously supported it automatically. Signed-off-by: Jesper Brynolf --- tss-esapi/Cargo.toml | 2 +- tss-esapi/src/abstraction/public.rs | 8 ++-- tss-esapi/src/abstraction/transient/mod.rs | 8 +++- tss-esapi/src/structures/buffers/private.rs | 47 +++++++++--------- tss-esapi/src/structures/tagged/public.rs | 53 ++++++++++++--------- tss-esapi/src/structures/tpm_context.rs | 51 +++++++++++--------- tss-esapi/src/utils/mod.rs | 8 +++- tss-esapi/tests/all-fedora.sh | 4 +- tss-esapi/tests/all-ubuntu.sh | 4 +- tss-esapi/tests/coverage.sh | 2 +- tss-esapi/tests/valgrind.sh | 2 +- 11 files changed, 108 insertions(+), 81 deletions(-) diff --git a/tss-esapi/Cargo.toml b/tss-esapi/Cargo.toml index 3740da0f..f89fee56 100644 --- a/tss-esapi/Cargo.toml +++ b/tss-esapi/Cargo.toml @@ -17,7 +17,7 @@ name = "hmac" [dependencies] bitfield = "0.14" -serde = { version = "1.0.115", features = ["derive"] } +serde = { version = "1.0.115", features = ["derive"], optional = true, default-features = false } malloced = "1.3.1" log = "0.4.11" enumflags2 = "0.7.7" diff --git a/tss-esapi/src/abstraction/public.rs b/tss-esapi/src/abstraction/public.rs index f05de297..319278a4 100644 --- a/tss-esapi/src/abstraction/public.rs +++ b/tss-esapi/src/abstraction/public.rs @@ -12,16 +12,18 @@ use picky_asn1::wrapper::{IntegerAsn1, OctetStringAsn1}; use picky_asn1_x509::{ AlgorithmIdentifier, EcParameters, EcPoint, PublicKey, RsaPublicKey, SubjectPublicKeyInfo, }; -use serde::{Deserialize, Serialize}; /// Can be converted from [`crate::structures::Public`] when not a fully constructed /// [`picky_asn1_x509::SubjectPublicKeyInfo`] is required. /// /// # Details -/// /// Holds either [`picky_asn1_x509::RsaPublicKey`] for [`crate::structures::Public::Rsa`] or /// [`picky_asn1_x509::EcPoint`] for [`crate::structures::Public::Ecc`]. -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] +/// +/// This object can be serialized and deserialized +/// using serde if the `serde` feature is enabled. +#[derive(Debug, PartialEq, Eq, Clone)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub enum DecodedKey { RsaPublicKey(RsaPublicKey), EcPoint(EcPoint), diff --git a/tss-esapi/src/abstraction/transient/mod.rs b/tss-esapi/src/abstraction/transient/mod.rs index e54cfa9f..eea4a234 100644 --- a/tss-esapi/src/abstraction/transient/mod.rs +++ b/tss-esapi/src/abstraction/transient/mod.rs @@ -29,7 +29,6 @@ use crate::{ }; use log::error; -use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::convert::{AsMut, AsRef, TryFrom, TryInto}; use zeroize::Zeroize; @@ -65,17 +64,22 @@ pub enum KeyParams { /// Structure representing a key created or stored in the TPM /// +/// # Details /// The `public` field represents the public part of the key in plain text, /// while `private` is the encrypted version of the private key. /// /// For information on public key formats, see the documentation of [`PublicKey`]. /// The private part of the key should be treated as an opaque binary blob. /// +/// This object can be serialized and deserialized +/// using serde if the `serde` feature is enabled. +/// /// # Warning /// /// If the Owner hierarchy is cleared, any key material generated /// prior to that event will become unusable. -#[derive(Debug, Serialize, Deserialize, Clone, Zeroize)] +#[derive(Debug, Clone, Zeroize)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct KeyMaterial { public: PublicKey, private: Vec, diff --git a/tss-esapi/src/structures/buffers/private.rs b/tss-esapi/src/structures/buffers/private.rs index a122db56..9c6611b7 100644 --- a/tss-esapi/src/structures/buffers/private.rs +++ b/tss-esapi/src/structures/buffers/private.rs @@ -2,34 +2,37 @@ // SPDX-License-Identifier: Apache-2.0 use crate::traits::impl_mu_standard; -use crate::traits::{Marshall, UnMarshall}; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; use tss_esapi_sys::_PRIVATE; buffer_type!(Private, ::std::mem::size_of::<_PRIVATE>(), TPM2B_PRIVATE); impl_mu_standard!(Private, TPM2B_PRIVATE); -impl Serialize for Private { - /// Serialise the [Private] data into it's bytes representation of the TCG - /// TPM2B_PRIVATE structure. - fn serialize(&self, serializer: S) -> std::result::Result - where - S: Serializer, - { - let bytes = self.marshall().map_err(serde::ser::Error::custom)?; - serializer.serialize_bytes(&bytes) - } -} +cfg_if::cfg_if! { + if #[cfg(feature = "serde")] { + use crate::traits::{Marshall, UnMarshall}; + impl serde::Serialize for Private { + /// Serialize the [Private] data into it's bytes representation of the TCG + /// TPM2B_PRIVATE structure. + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + let bytes = self.marshall().map_err(serde::ser::Error::custom)?; + serializer.serialize_bytes(&bytes) + } + } -impl<'de> Deserialize<'de> for Private { - /// Deserialise the [Private] data from it's bytes representation of the TCG - /// TPM2B_PRIVATE structure. - fn deserialize(deserializer: D) -> std::result::Result - where - D: Deserializer<'de>, - { - let bytes = >::deserialize(deserializer)?; - Self::unmarshall(&bytes).map_err(serde::de::Error::custom) + impl<'de> serde::Deserialize<'de> for Private { + /// Deserialize the [Private] data from it's bytes representation of the TCG + /// TPM2B_PRIVATE structure. + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + let bytes = >::deserialize(deserializer)?; + Self::unmarshall(&bytes).map_err(serde::de::Error::custom) + } + } } } diff --git a/tss-esapi/src/structures/tagged/public.rs b/tss-esapi/src/structures/tagged/public.rs index 693d86d6..0c467bf9 100644 --- a/tss-esapi/src/structures/tagged/public.rs +++ b/tss-esapi/src/structures/tagged/public.rs @@ -8,7 +8,7 @@ use crate::{ attributes::ObjectAttributes, interface_types::algorithm::{HashingAlgorithm, PublicAlgorithm}, structures::{Digest, EccPoint, PublicKeyRsa, SymmetricCipherParameters}, - traits::{impl_mu_standard, Marshall, UnMarshall}, + traits::{impl_mu_standard, Marshall}, tss2_esys::{TPM2B_PUBLIC, TPMT_PUBLIC}, Error, Result, ReturnCode, WrapperErrorKind, }; @@ -18,7 +18,6 @@ use keyed_hash::PublicKeyedHashParameters; use rsa::PublicRsaParameters; use log::error; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::convert::{TryFrom, TryInto}; use tss_esapi_sys::{TPMU_PUBLIC_ID, TPMU_PUBLIC_PARMS}; @@ -299,6 +298,9 @@ impl Default for PublicBuilder { /// /// # Details /// This corresponds to TPMT_PUBLIC +/// +/// This object can be serialized and deserialized +/// using serde if the `serde` feature is enabled. #[derive(Debug, Clone, Eq, PartialEq)] pub enum Public { Rsa { @@ -500,30 +502,35 @@ impl TryFrom for Public { impl_mu_standard!(Public, TPMT_PUBLIC); -impl Serialize for Public { - /// Serialize the [Public] data into it's bytes representation of the TCG - /// TPMT_PUBLIC structure. - fn serialize(&self, serializer: S) -> std::result::Result - where - S: Serializer, - { - let bytes = self.marshall().map_err(serde::ser::Error::custom)?; - serializer.serialize_bytes(&bytes) - } -} +cfg_if::cfg_if! { + if #[cfg(feature = "serde")] { + use crate::traits::UnMarshall; + + impl serde::Serialize for Public { + /// Serialize the [Public] data into it's bytes representation of the TCG + /// TPMT_PUBLIC structure. + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + let bytes = self.marshall().map_err(serde::ser::Error::custom)?; + serializer.serialize_bytes(&bytes) + } + } -impl<'de> Deserialize<'de> for Public { - /// Deserialise the [Public] data from it's bytes representation of the TCG - /// TPMT_PUBLIC structure. - fn deserialize(deserializer: D) -> std::result::Result - where - D: Deserializer<'de>, - { - let bytes = >::deserialize(deserializer)?; - Self::unmarshall(&bytes).map_err(serde::de::Error::custom) + impl<'de> serde::Deserialize<'de> for Public { + /// Deserialise the [Public] data from it's bytes representation of the TCG + /// TPMT_PUBLIC structure. + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + let bytes = >::deserialize(deserializer)?; + Self::unmarshall(&bytes).map_err(serde::de::Error::custom) + } + } } } - impl TryFrom for Public { type Error = Error; diff --git a/tss-esapi/src/structures/tpm_context.rs b/tss-esapi/src/structures/tpm_context.rs index 120f1f5b..a8222a62 100644 --- a/tss-esapi/src/structures/tpm_context.rs +++ b/tss-esapi/src/structures/tpm_context.rs @@ -5,14 +5,16 @@ use crate::{ interface_types::{data_handles::Saved, reserved_handles::Hierarchy}, structures::TpmContextData, traits::impl_mu_standard, - traits::{Marshall, UnMarshall}, tss2_esys::TPMS_CONTEXT, Error, Result, }; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::convert::TryFrom; /// Structure holding the content of a TPM context. +/// +/// # Details +/// This object can be serialized and deserialized +/// using serde if the `serde` feature is enabled. #[derive(Debug, Clone)] pub struct SavedTpmContext { sequence: u64, @@ -79,26 +81,31 @@ impl From for TPMS_CONTEXT { impl_mu_standard!(SavedTpmContext, TPMS_CONTEXT); -impl Serialize for SavedTpmContext { - /// Serialize the [SavedTpmContext] data into it's bytes representation of the TCG - /// TPMS_CONTEXT structure. - fn serialize(&self, serializer: S) -> std::result::Result - where - S: Serializer, - { - let bytes = self.marshall().map_err(serde::ser::Error::custom)?; - serializer.serialize_bytes(&bytes) - } -} +cfg_if::cfg_if! { + if #[cfg(feature = "serde")] { + use crate::traits::{Marshall, UnMarshall}; + impl serde::Serialize for SavedTpmContext { + /// Serialize the [SavedTpmContext] data into it's bytes representation of the TCG + /// TPMS_CONTEXT structure. + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + let bytes = self.marshall().map_err(serde::ser::Error::custom)?; + serializer.serialize_bytes(&bytes) + } + } -impl<'de> Deserialize<'de> for SavedTpmContext { - /// Deserialize the [SavedTpmContext] data from it's bytes representation of the TCG - /// TPMS_CONTEXT structure. - fn deserialize(deserializer: D) -> std::result::Result - where - D: Deserializer<'de>, - { - let bytes = >::deserialize(deserializer)?; - Self::unmarshall(&bytes).map_err(serde::de::Error::custom) + impl<'de> serde::Deserialize<'de> for SavedTpmContext { + /// Deserialize the [SavedTpmContext] data from it's bytes representation of the TCG + /// TPMS_CONTEXT structure. + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + let bytes = >::deserialize(deserializer)?; + Self::unmarshall(&bytes).map_err(serde::de::Error::custom) + } + } } } diff --git a/tss-esapi/src/utils/mod.rs b/tss-esapi/src/utils/mod.rs index 17103111..3bce9096 100644 --- a/tss-esapi/src/utils/mod.rs +++ b/tss-esapi/src/utils/mod.rs @@ -20,7 +20,6 @@ use crate::structures::{ PublicRsaParametersBuilder, RsaExponent, RsaScheme, SymmetricDefinitionObject, }; use crate::{Context, Error, Result, WrapperErrorKind}; -use serde::{Deserialize, Serialize}; use std::convert::TryFrom; use zeroize::Zeroize; @@ -201,7 +200,12 @@ pub fn create_unrestricted_signing_ecc_public( } /// Container for public key values -#[derive(Debug, Clone, Serialize, Deserialize, Zeroize, PartialEq, Eq)] +/// +/// # Details +/// This object can be serialized and deserialized +/// using serde if the `serde` feature is enabled. +#[derive(Debug, Clone, Zeroize, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub enum PublicKey { /// RSA public modulus (see 27.5.3.4 in the Architecture spec) /// diff --git a/tss-esapi/tests/all-fedora.sh b/tss-esapi/tests/all-fedora.sh index 534d9744..1eb52118 100755 --- a/tss-esapi/tests/all-fedora.sh +++ b/tss-esapi/tests/all-fedora.sh @@ -43,9 +43,9 @@ tpm2-abrmd \ ################### # Build the crate # ################### -RUST_BACKTRACE=1 cargo build --features "generate-bindings integration-tests" +RUST_BACKTRACE=1 cargo build --features "generate-bindings integration-tests serde" ################# # Run the tests # ################# -TEST_TCTI=tabrmd:bus_type=session RUST_BACKTRACE=1 RUST_LOG=info cargo test --features "generate-bindings integration-tests" -- --test-threads=1 --nocapture +TEST_TCTI=tabrmd:bus_type=session RUST_BACKTRACE=1 RUST_LOG=info cargo test --features "generate-bindings integration-tests serde" -- --test-threads=1 --nocapture diff --git a/tss-esapi/tests/all-ubuntu.sh b/tss-esapi/tests/all-ubuntu.sh index 41dae611..6cb34d1f 100755 --- a/tss-esapi/tests/all-ubuntu.sh +++ b/tss-esapi/tests/all-ubuntu.sh @@ -24,9 +24,9 @@ fi # Generate bindings for non-"standard" versions # ################################################# if [[ "${TPM2_TSS_VERSION}" != "${TPM2_TSS_BINDINGS_VERSION}" ]]; then - FEATURES="generate-bindings integration-tests" + FEATURES="generate-bindings integration-tests serde" else - FEATURES="integration-tests" + FEATURES="integration-tests serde" fi if [[ ! -z ${TPM2_TSS_PATH:+x} ]]; then diff --git a/tss-esapi/tests/coverage.sh b/tss-esapi/tests/coverage.sh index 656e5bd7..513dd921 100755 --- a/tss-esapi/tests/coverage.sh +++ b/tss-esapi/tests/coverage.sh @@ -16,4 +16,4 @@ tpm2_startup -c -T mssim # Install and run tarpaulin # ############################# cargo install cargo-tarpaulin -cargo tarpaulin --features integration-tests --tests --out xml --exclude-files="tests/*,../*" -- --test-threads=1 --nocapture +cargo tarpaulin --features integration-tests serde --tests --out xml --exclude-files="tests/*,../*" -- --test-threads=1 --nocapture diff --git a/tss-esapi/tests/valgrind.sh b/tss-esapi/tests/valgrind.sh index ae6ea6f7..1936ddda 100755 --- a/tss-esapi/tests/valgrind.sh +++ b/tss-esapi/tests/valgrind.sh @@ -24,4 +24,4 @@ cargo install cargo-valgrind ################# # Run the tests # ################# -TEST_TCTI=mssim: RUST_BACKTRACE=1 RUST_LOG=info cargo valgrind test --features integration-tests -- --test-threads=1 --nocapture +TEST_TCTI=mssim: RUST_BACKTRACE=1 RUST_LOG=info cargo valgrind test --features "integration-tests serde" -- --test-threads=1 --nocapture