pub fn verify_certificate(
    certificate: &[u8],
    canister_id: &CanisterId,
    root_pk: &ThresholdSigPublicKey,
    certified_data: &[u8],
) -> Result<Time, CertificateValidationError> {
    #[derive(Deserialize)]
    struct CanisterView {
        certified_data: Blob,
    }

    #[derive(Deserialize)]
    struct ReplicaState {
        time: Leb128EncodedU64,
        canister: BTreeMap<CanisterId, CanisterView>,
    }

    let certificate: Certificate = serde_cbor::from_slice(certificate).map_err(|err| {
        CertificateValidationError::DeserError(format!(
            "failed to decode certificate from canister {}: {}",
            canister_id, err
        ))
    })?;

    if certificate.delegation.is_some() {
        return Err(CertificateValidationError::SubnetDelegationNotAllowed);
    }

    let digest = CryptoHashOfPartialState::from(CryptoHash(certificate.tree.digest().to_vec()));
    let content = CertificationContent::new(digest.clone());
    let sig = CombinedThresholdSigOf::new(CombinedThresholdSig(certificate.signature.to_vec()));
    verify_combined(&content, &sig, root_pk).map_err(|err| {
        CertificateValidationError::InvalidSignature(format!(
            "root_hash={:?}, sig={:?}, pk={:?}, error={:?}",
            digest, certificate.signature, root_pk, err
        ))
    })?;

    let replica_labeled_tree =
        LabeledTree::<Vec<u8>>::try_from(certificate.tree).map_err(|err| {
            CertificateValidationError::MalformedHashTree(format!(
                "failed to convert hash tree to labeled tree: {:?}",
                err
            ))
        })?;

    let replica_state = ReplicaState::deserialize(LabeledTreeDeserializer::new(
        &replica_labeled_tree,
    ))
    .map_err(|err| {
        CertificateValidationError::DeserError(format!(
            "failed to unpack replica state from a labeled tree: {}",
            err
        ))
    })?;

    let time = Time::from_nanos_since_unix_epoch(replica_state.time.0);

    let certificate_certified_data = replica_state
        .canister
        .get(canister_id)
        .map(|canister| canister.certified_data.clone())
        .ok_or_else(|| {
            CertificateValidationError::MalformedHashTree(format!(
                "cannot find certified_data for canister {} in the tree",
                canister_id
            ))
        })?;

    if certified_data != certificate_certified_data.0.as_slice() {
        return Err(CertificateValidationError::CertifiedDataMismatch {
            certified: certificate_certified_data.0,
            computed: certified_data.to_vec(),
        });
    }

    Ok(time)
}
/// Checks if the specified certificate verifies the certified data of
/// specified canister.
///
/// If the check is successful, this function returns the timestamp on the
/// certificate.
Checks if the specified certificate verifies the certified data of
specified canister.

If the check is successful, this function returns the timestamp on the
certificate.
Checks if the specified certificate verifies the certified data of specified canister . If the check is successful this function returns the timestamp on the certificate .
pub fn verify_certificate(
    certificate: &[u8],
    canister_id: &CanisterId,
    root_pk: &ThresholdSigPublicKey,
    certified_data: &[u8],
) -> Result<Time, CertificateValidationError> {
    #[derive(Deserialize)]
    struct CanisterView {
        certified_data: Blob,
    }
    #[derive(Deserialize)]
    struct ReplicaState {
        time: Leb128EncodedU64,
        canister: BTreeMap<CanisterId, CanisterView>,
    }
    let certificate: Certificate = serde_cbor::from_slice(certificate).map_err(|err| {
        CertificateValidationError::DeserError(format!(
            "failed to decode certificate from canister {}: {}",
            canister_id, err
        ))
    })?;
    if certificate.delegation.is_some() {
        return Err(CertificateValidationError::SubnetDelegationNotAllowed);
    }
    let digest = CryptoHashOfPartialState::from(CryptoHash(certificate.tree.digest().to_vec()));
    let content = CertificationContent::new(digest.clone());
    let sig = CombinedThresholdSigOf::new(CombinedThresholdSig(certificate.signature.to_vec()));
    verify_combined(&content, &sig, root_pk).map_err(|err| {
        CertificateValidationError::InvalidSignature(format!(
            "root_hash={:?}, sig={:?}, pk={:?}, error={:?}",
            digest, certificate.signature, root_pk, err
        ))
    })?;
    let replica_labeled_tree =
        LabeledTree::<Vec<u8>>::try_from(certificate.tree).map_err(|err| {
            CertificateValidationError::MalformedHashTree(format!(
                "failed to convert hash tree to labeled tree: {:?}",
                err
            ))
        })?;
    let replica_state = ReplicaState::deserialize(LabeledTreeDeserializer::new(
        &replica_labeled_tree,
    ))
    .map_err(|err| {
        CertificateValidationError::DeserError(format!(
            "failed to unpack replica state from a labeled tree: {}",
            err
        ))
    })?;
    let time = Time::from_nanos_since_unix_epoch(replica_state.time.0);
    let certificate_certified_data = replica_state
        .canister
        .get(canister_id)
        .map(|canister| canister.certified_data.clone())
        .ok_or_else(|| {
            CertificateValidationError::MalformedHashTree(format!(
                "cannot find certified_data for canister {} in the tree",
                canister_id
            ))
        })?;
    if certified_data != certificate_certified_data.0.as_slice() {
        return Err(CertificateValidationError::CertifiedDataMismatch {
            certified: certificate_certified_data.0,
            computed: certified_data.to_vec(),
        });
    }
    Ok(time)
}
pub fn verify_certificate ( certificate : & [ u8 ] , canister_id : & CanisterId , root_pk : & ThresholdSigPublicKey , certified_data : & [ u8 ] , ) -> Result < Time , CertificateValidationError > { # [ derive ( Deserialize ) ] struct CanisterView { certified_data : Blob , } # [ derive ( Deserialize ) ] struct ReplicaState { time : Leb128EncodedU64 , canister : BTreeMap < CanisterId , CanisterView > , } let certificate : Certificate = serde_cbor :: from_slice ( certificate ) . map_err ( | err | { CertificateValidationError :: DeserError ( format ! ( " " canister_id err ) ) } ) ? ; if certificate . delegation . is_some ( ) { return Err ( CertificateValidationError :: SubnetDelegationNotAllowed ) ; } let digest = CryptoHashOfPartialState :: from ( CryptoHash ( certificate . tree . digest ( ) . to_vec ( ) ) ) ; let content = CertificationContent :: new ( digest . clone ( ) ) ; let sig = CombinedThresholdSigOf :: new ( CombinedThresholdSig ( certificate . signature . to_vec ( ) ) ) ; verify_combined ( & content , & sig , root_pk ) . map_err ( | err | { CertificateValidationError :: InvalidSignature ( format ! ( " " digest certificate signature root_pk err ) ) } ) ? ; let replica_labeled_tree = LabeledTree :: < Vec < u8 > > :: try_from ( certificate . tree ) . map_err ( | err | { CertificateValidationError :: MalformedHashTree ( format ! ( " " err ) ) } ) ? ; let replica_state = ReplicaState :: deserialize ( LabeledTreeDeserializer :: new ( & replica_labeled_tree , ) ) . map_err ( | err | { CertificateValidationError :: DeserError ( format ! ( " " err ) ) } ) ? ; let time = Time :: from_nanos_since_unix_epoch ( replica_state . time . 0 ) ; let certificate_certified_data = replica_state . canister . get ( canister_id ) . map ( | canister | canister . certified_data . clone ( ) ) . ok_or_else ( | | { CertificateValidationError :: MalformedHashTree ( format ! ( " " canister_id ) ) } ) ? ; if certified_data != certificate_certified_data . 0 . as_slice ( ) { return Err ( CertificateValidationError :: CertifiedDataMismatch { certified : certificate_certified_data . 0 , computed : certified_data . to_vec ( ) , } ) ; } Ok ( time ) }
Checks if the specified certificate verifies the certified data of
specified canister.
Checks if the specified certificate verifies the certified data of specified canister .
certificate
&[u8]
canister_id
&CanisterId
root_pk
&ThresholdSigPublicKey
certified_data
&[u8]
certificate
&[u8]
canister_id
&CanisterId
root_pk
&ThresholdSigPublicKey
certified_data
&[u8]