use super::{CertChain, ManifestRef, UnsignedManifestRef};
use crate::{
manifest::AnyManifestRef,
property::{Dict, Value},
Tag,
};
use alloc::{collections::BTreeMap, vec::Vec};
use der::{
asn1::OctetString,
referenced::{OwnedToRef, RefToOwned},
DecodeValue, EncodeValue, FixedTag, Header, Length, Reader, Writer,
};
#[cfg(feature = "signature")]
use {
super::SigningError,
signature::{SignatureEncoding, Signer},
};
#[derive(Clone, Debug)]
#[cfg_attr(test, derive(Eq, PartialEq))]
pub struct Manifest {
pub(super) tbs: UnsignedManifest,
pub(super) signature: OctetString,
pub(super) cert_chain: CertChain,
}
impl Manifest {
#[cfg(feature = "signature")]
pub fn encode_and_sign<K: Signer<S>, S: SignatureEncoding>(
body: &BTreeMap<Tag, Value>,
key: &K,
cert_chain: impl Into<CertChain>,
) -> Result<Self, SigningError> {
let body = Dict::encode_from(body)?;
Self::sign_encoded(body, key, cert_chain)
}
#[cfg(feature = "signature")]
pub fn sign_encoded<K: Signer<S>, S: SignatureEncoding>(
body: impl Into<Dict>,
key: &K,
cert_chain: impl Into<CertChain>,
) -> Result<Self, SigningError> {
let body = body.into();
let signature = key.try_sign(body.as_bytes())?;
Ok(Manifest {
tbs: UnsignedManifest { version: 0, body },
signature: OctetString::new(signature.to_vec())?,
cert_chain: cert_chain.into(),
})
}
pub fn decode_after_magic<'a, R: Reader<'a>>(decoder: &mut R) -> der::Result<Self> {
Ok(ManifestRef::decode_after_magic(decoder)?.into())
}
pub fn version(&self) -> u32 {
self.tbs.version
}
pub fn body(&self) -> &Dict {
&self.tbs.body
}
pub fn decode_body(&self) -> der::Result<BTreeMap<Tag, Value>> {
self.tbs.decode_body()
}
pub fn encode_body(&mut self, body: &BTreeMap<Tag, Value>) -> der::Result<()> {
self.tbs.encode_body(body)
}
pub fn signature(&self) -> &[u8] {
self.signature.as_bytes()
}
pub fn set_signature(&mut self, signature: Vec<u8>) -> der::Result<()> {
self.signature = OctetString::new(signature)?;
Ok(())
}
pub fn cert_chain(&self) -> &CertChain {
&self.cert_chain
}
pub fn cert_chain_mut(&mut self) -> &mut CertChain {
&mut self.cert_chain
}
pub fn set_cert_chain(&mut self, cert_chain: CertChain) {
self.cert_chain = cert_chain;
}
#[cfg(feature = "signature")]
pub fn resign<K: Signer<S>, S: SignatureEncoding>(
&mut self,
key: &K,
cert_chain: impl Into<CertChain>,
) -> Result<(), SigningError> {
let signature = key.try_sign(self.tbs.body.as_bytes())?;
self.signature = OctetString::new(signature.to_vec())?;
self.cert_chain = cert_chain.into();
Ok(())
}
}
impl FixedTag for Manifest {
const TAG: der::Tag = der::Tag::Sequence;
}
impl<'a> DecodeValue<'a> for Manifest {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
ManifestRef::decode_value(reader, header).map(Manifest::from)
}
}
impl EncodeValue for Manifest {
fn value_len(&self) -> der::Result<Length> {
ManifestRef::from(self).value_len()
}
fn encode_value(&self, encoder: &mut impl Writer) -> der::Result<()> {
ManifestRef::from(self).encode_value(encoder)
}
}
impl From<ManifestRef<'_>> for Manifest {
fn from(value: ManifestRef<'_>) -> Self {
(&value).into()
}
}
impl From<&'_ ManifestRef<'_>> for Manifest {
fn from(value: &'_ ManifestRef<'_>) -> Self {
Self {
tbs: value.tbs.ref_to_owned(),
signature: value.signature.ref_to_owned(),
cert_chain: value.cert_chain.ref_to_owned(),
}
}
}
impl OwnedToRef for Manifest {
type Borrowed<'a> = ManifestRef<'a>;
fn owned_to_ref(&self) -> Self::Borrowed<'_> {
self.into()
}
}
impl AsRef<UnsignedManifest> for Manifest {
fn as_ref(&self) -> &UnsignedManifest {
&self.tbs
}
}
#[derive(Clone, Debug)]
#[cfg_attr(test, derive(Eq, PartialEq))]
pub struct UnsignedManifest {
pub(super) version: u32,
pub(super) body: Dict,
}
impl UnsignedManifest {
pub fn new(body: Dict) -> Self {
Self { version: 0, body }
}
pub fn encode_from(dict: &BTreeMap<Tag, Value>) -> der::Result<Self> {
Ok(Self {
version: 0,
body: Dict::encode_from(dict)?,
})
}
pub fn decode_after_magic<'a, R: Reader<'a>>(decoder: &mut R) -> der::Result<Self> {
Ok(UnsignedManifestRef::decode_after_magic(decoder)?.into())
}
pub fn version(&self) -> u32 {
self.version
}
pub fn body(&self) -> &Dict {
&self.body
}
pub fn decode_body(&self) -> der::Result<BTreeMap<Tag, Value>> {
self.body.decode_owned()
}
pub fn encode_body(&mut self, body: &BTreeMap<Tag, Value>) -> der::Result<()> {
self.body = Dict::encode_from(body)?;
Ok(())
}
#[cfg(feature = "signature")]
pub fn sign<K: Signer<S>, S: SignatureEncoding>(
self,
key: &K,
cert_chain: impl Into<CertChain>,
) -> Result<Manifest, SigningError> {
let signature = key.try_sign(self.body.as_bytes())?;
Ok(Manifest {
tbs: self,
signature: OctetString::new(signature.to_vec())?,
cert_chain: cert_chain.into(),
})
}
}
impl FixedTag for UnsignedManifest {
const TAG: der::Tag = der::Tag::Sequence;
}
impl<'a> DecodeValue<'a> for UnsignedManifest {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
UnsignedManifestRef::decode_value(reader, header).map(From::from)
}
}
impl EncodeValue for UnsignedManifest {
fn value_len(&self) -> der::Result<Length> {
UnsignedManifestRef::from(self).value_len()
}
fn encode_value(&self, encoder: &mut impl Writer) -> der::Result<()> {
UnsignedManifestRef::from(self).encode_value(encoder)
}
}
impl From<Manifest> for UnsignedManifest {
fn from(value: Manifest) -> Self {
value.tbs
}
}
impl From<ManifestRef<'_>> for UnsignedManifest {
fn from(value: ManifestRef<'_>) -> Self {
(&value.tbs).into()
}
}
impl From<&'_ ManifestRef<'_>> for UnsignedManifest {
fn from(value: &'_ ManifestRef<'_>) -> Self {
(&value.tbs).into()
}
}
impl From<UnsignedManifestRef<'_>> for UnsignedManifest {
fn from(value: UnsignedManifestRef<'_>) -> Self {
(&value).into()
}
}
impl From<&'_ UnsignedManifestRef<'_>> for UnsignedManifest {
fn from(value: &'_ UnsignedManifestRef<'_>) -> Self {
Self {
version: value.version,
body: value.body.ref_to_owned(),
}
}
}
impl OwnedToRef for UnsignedManifest {
type Borrowed<'a> = UnsignedManifestRef<'a>;
fn owned_to_ref(&self) -> Self::Borrowed<'_> {
self.into()
}
}
#[derive(Clone, Debug)]
#[cfg_attr(test, derive(Eq, PartialEq))]
pub enum AnyManifest {
Signed(Manifest),
Unsigned(UnsignedManifest),
}
impl AnyManifest {
pub fn decode_after_magic<'a, R: Reader<'a>>(decoder: &mut R) -> der::Result<Self> {
Ok(UnsignedManifestRef::decode_after_magic(decoder)?.into())
}
pub fn version(&self) -> u32 {
match self {
AnyManifest::Signed(m) => m.version(),
AnyManifest::Unsigned(m) => m.version(),
}
}
pub fn decode_body(&self) -> der::Result<BTreeMap<Tag, Value>> {
match self {
AnyManifest::Signed(m) => m.decode_body(),
AnyManifest::Unsigned(m) => m.decode_body(),
}
}
pub fn encode_body(&mut self, body: &BTreeMap<Tag, Value>) -> der::Result<()> {
match self {
AnyManifest::Signed(m) => m.encode_body(body),
AnyManifest::Unsigned(m) => m.encode_body(body),
}
}
}
impl From<Manifest> for AnyManifest {
fn from(value: Manifest) -> Self {
Self::Signed(value)
}
}
impl From<UnsignedManifest> for AnyManifest {
fn from(value: UnsignedManifest) -> Self {
Self::Unsigned(value)
}
}
impl From<UnsignedManifestRef<'_>> for AnyManifest {
fn from(value: UnsignedManifestRef<'_>) -> Self {
(&value).into()
}
}
impl From<&'_ UnsignedManifestRef<'_>> for AnyManifest {
fn from(value: &'_ UnsignedManifestRef<'_>) -> Self {
Self::Unsigned(value.into())
}
}
impl From<ManifestRef<'_>> for AnyManifest {
fn from(value: ManifestRef<'_>) -> Self {
(&value).into()
}
}
impl From<&'_ ManifestRef<'_>> for AnyManifest {
fn from(value: &'_ ManifestRef<'_>) -> Self {
Self::Signed(value.into())
}
}
impl From<AnyManifestRef<'_>> for AnyManifest {
fn from(value: AnyManifestRef<'_>) -> Self {
(&value).into()
}
}
impl From<&'_ AnyManifestRef<'_>> for AnyManifest {
fn from(value: &'_ AnyManifestRef<'_>) -> Self {
match value {
AnyManifestRef::Signed(m) => Self::Signed(m.into()),
AnyManifestRef::Unsigned(m) => Self::Unsigned(m.into()),
}
}
}
impl OwnedToRef for AnyManifest {
type Borrowed<'a> = AnyManifestRef<'a>;
fn owned_to_ref(&self) -> Self::Borrowed<'_> {
self.into()
}
}
impl AsRef<UnsignedManifest> for AnyManifest {
fn as_ref(&self) -> &UnsignedManifest {
match self {
AnyManifest::Signed(m) => &m.tbs,
AnyManifest::Unsigned(m) => m,
}
}
}