matrix_sdk_crypto/types/cross_signing/
self_signing.rs1use std::collections::btree_map::Iter;
2
3use ruma::{OwnedDeviceKeyId, UserId, encryption::KeyUsage};
4use serde::{Deserialize, Serialize};
5use vodozemac::Ed25519PublicKey;
6
7use super::{CrossSigningKey, SigningKey};
8use crate::{
9 DeviceData, SignatureError,
10 olm::VerifyJson,
11 types::{DeviceKeys, SigningKeys},
12};
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
18#[serde(try_from = "CrossSigningKey")]
19pub struct SelfSigningPubkey(pub(super) CrossSigningKey);
20
21impl SelfSigningPubkey {
22 pub fn user_id(&self) -> &UserId {
24 &self.0.user_id
25 }
26
27 pub fn keys(&self) -> &SigningKeys<OwnedDeviceKeyId> {
29 &self.0.keys
30 }
31
32 pub fn usage(&self) -> &[KeyUsage] {
34 &self.0.usage
35 }
36
37 pub fn get_first_key(&self) -> Option<Ed25519PublicKey> {
42 self.0.get_first_key_and_id().map(|(_, k)| k)
43 }
44
45 pub fn verify_device_keys(&self, device_keys: &DeviceKeys) -> Result<(), SignatureError> {
48 if let Some((key_id, key)) = self.0.get_first_key_and_id() {
49 key.verify_json(&self.0.user_id, key_id, device_keys)
50 } else {
51 Err(SignatureError::UnsupportedAlgorithm)
52 }
53 }
54
55 pub(crate) fn verify_device(&self, device: &DeviceData) -> Result<(), SignatureError> {
64 self.verify_device_keys(device.as_device_keys())
65 }
66}
67
68impl<'a> IntoIterator for &'a SelfSigningPubkey {
69 type Item = (&'a OwnedDeviceKeyId, &'a SigningKey);
70 type IntoIter = Iter<'a, OwnedDeviceKeyId, SigningKey>;
71
72 fn into_iter(self) -> Self::IntoIter {
73 self.keys().iter()
74 }
75}
76
77impl TryFrom<CrossSigningKey> for SelfSigningPubkey {
78 type Error = serde_json::Error;
79
80 fn try_from(key: CrossSigningKey) -> Result<Self, Self::Error> {
81 if key.usage.contains(&KeyUsage::SelfSigning) && key.usage.len() == 1 {
82 Ok(Self(key))
83 } else {
84 Err(serde::de::Error::custom(format!(
85 "Expected cross signing key usage {} was not found",
86 KeyUsage::SelfSigning
87 )))
88 }
89 }
90}
91
92impl AsRef<CrossSigningKey> for SelfSigningPubkey {
93 fn as_ref(&self) -> &CrossSigningKey {
94 &self.0
95 }
96}
97
98impl AsMut<CrossSigningKey> for SelfSigningPubkey {
99 fn as_mut(&mut self) -> &mut CrossSigningKey {
100 &mut self.0
101 }
102}