diff --git a/.codespellrc b/.codespellrc index e2713029..f84f6770 100644 --- a/.codespellrc +++ b/.codespellrc @@ -1,3 +1,3 @@ [codespell] skip = .git,target,Cargo.lock -ignore-words-list = acsend,crate,keypair,daa +ignore-words-list = acsend,crate,keypair,daa,de,ser diff --git a/tss-esapi/Cargo.toml b/tss-esapi/Cargo.toml index 27390df4..9fe0dd66 100644 --- a/tss-esapi/Cargo.toml +++ b/tss-esapi/Cargo.toml @@ -37,6 +37,7 @@ paste = "1.0.14" [dev-dependencies] env_logger = "0.9.0" sha2 = "0.10.1" +serde_json = "^1.0.108" [build-dependencies] semver = "1.0.7" diff --git a/tss-esapi/src/structures/buffers/private.rs b/tss-esapi/src/structures/buffers/private.rs index 321e898b..a122db56 100644 --- a/tss-esapi/src/structures/buffers/private.rs +++ b/tss-esapi/src/structures/buffers/private.rs @@ -2,8 +2,34 @@ // 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) + } +} + +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) + } +} diff --git a/tss-esapi/src/structures/tagged/public.rs b/tss-esapi/src/structures/tagged/public.rs index 3a6ac8b0..5f416a88 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}, + traits::{impl_mu_standard, Marshall, UnMarshall}, tss2_esys::{TPM2B_PUBLIC, TPMT_PUBLIC}, Error, Result, ReturnCode, WrapperErrorKind, }; @@ -18,6 +18,7 @@ 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}; @@ -493,6 +494,30 @@ impl TryFrom for Public { impl_mu_standard!(Public, TPMT_PUBLIC); +impl Serialize for Public { + /// Serialise 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) + } +} + +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 TryFrom for Public { type Error = Error; diff --git a/tss-esapi/tests/integration_tests/common/mod.rs b/tss-esapi/tests/integration_tests/common/mod.rs index 9bd955e3..bc715281 100644 --- a/tss-esapi/tests/integration_tests/common/mod.rs +++ b/tss-esapi/tests/integration_tests/common/mod.rs @@ -32,11 +32,13 @@ use tss_esapi::{ }; mod marshall; +mod serde; mod tpm2b_types_equality_checks; mod tpma_types_equality_checks; mod tpml_types_equality_checks; mod tpms_types_equality_checks; mod tpmt_types_equality_checks; +pub use self::serde::*; pub use marshall::*; pub use tpm2b_types_equality_checks::*; pub use tpma_types_equality_checks::*; diff --git a/tss-esapi/tests/integration_tests/common/serde.rs b/tss-esapi/tests/integration_tests/common/serde.rs new file mode 100644 index 00000000..a346b9f4 --- /dev/null +++ b/tss-esapi/tests/integration_tests/common/serde.rs @@ -0,0 +1,16 @@ +// Copyright 2023 Contributors to the Parsec project. +// SPDX-License-Identifier: Apache-2.0 +use serde::{de::DeserializeOwned, Serialize}; +use tss_esapi::traits::{Marshall, UnMarshall}; + +pub fn check_serialise_deserialise< + T: Serialize + DeserializeOwned + Marshall + UnMarshall + Eq + std::fmt::Debug, +>( + val: &T, +) { + let json = serde_json::to_vec(val).expect("Failed to serialise value"); + + let unmarshalled: T = serde_json::from_slice(&json).expect("Failed to deserialise"); + + assert_eq!(val, &unmarshalled); +} diff --git a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/private.rs b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/private.rs index 6c2f1700..bc57dcec 100644 --- a/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/private.rs +++ b/tss-esapi/tests/integration_tests/structures_tests/buffers_tests/private.rs @@ -11,6 +11,13 @@ fn marshall_unmarshall() { crate::common::check_marshall_unmarshall(&private); } +#[test] +fn serialise_deserialise() { + crate::common::check_serialise_deserialise(&Private::default()); + let private = Private::try_from([0xff; 100].to_vec()).unwrap(); + crate::common::check_serialise_deserialise(&private); +} + #[test] fn marshall_unmarshall_offset() { crate::common::check_marshall_unmarshall_offset(&Private::default()); diff --git a/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/public.rs b/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/public.rs index db299007..f638cad1 100644 --- a/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/public.rs +++ b/tss-esapi/tests/integration_tests/structures_tests/tagged_tests/public.rs @@ -14,6 +14,13 @@ fn marshall_unmarshall() { .for_each(crate::common::check_marshall_unmarshall); } +#[test] +fn serialise_deserialise() { + crate::common::publics() + .iter() + .for_each(crate::common::check_serialise_deserialise); +} + #[test] fn tpm2b_conversion() { crate::common::publics().iter().for_each(|public| {