1use crate::certificate::{
7 CertificateAuthority, CertificateValidator, EcdsaKeyPair, X509Certificate,
8};
9use crate::derivation::derive_agreement_from_master;
10use crate::error::{KeyError, Result};
11use crate::{log_debug, log_error, log_info};
12use p256::elliptic_curve::sec1::ToEncodedPoint;
13use p256::SecretKey as P256SecretKey;
14use pkcs8::{DecodePrivateKey, EncodePrivateKey};
15use runar_common::compact_ids::compact_id;
16use runar_common::logging::Logger;
17use serde::{Deserialize, Serialize};
18use std::collections::HashMap;
19use std::sync::Arc;
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct SetupToken {
24 pub node_public_key: Vec<u8>,
26 pub node_agreement_public_key: Vec<u8>,
28 pub csr_der: Vec<u8>,
30 pub node_id: String,
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize)]
36pub struct NodeCertificateMessage {
37 pub node_certificate: X509Certificate,
39 pub ca_certificate: X509Certificate,
41 pub metadata: CertificateMetadata,
43}
44
45#[derive(Debug, Clone, Serialize, Deserialize)]
47pub struct CertificateMetadata {
48 pub issued_at: u64,
50 pub validity_days: u32,
52 pub purpose: String,
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize)]
58pub struct NetworkKeyMessage {
59 pub network_id: String,
61 pub network_public_key: Vec<u8>,
63 pub encrypted_network_key: Vec<u8>,
65 pub key_derivation_info: String,
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct EnvelopeEncryptedData {
72 pub encrypted_data: Vec<u8>,
74 pub network_id: Option<String>,
76 pub network_encrypted_key: Vec<u8>,
78 pub profile_encrypted_keys: HashMap<String, Vec<u8>>,
80}
81
82pub struct MobileKeyManager {
84 certificate_authority: CertificateAuthority,
86 certificate_validator: CertificateValidator,
88 user_root_key: Option<EcdsaKeyPair>,
90 user_root_agreement: Option<P256SecretKey>,
92 user_profile_keys: HashMap<String, EcdsaKeyPair>,
94 user_profile_agreements: HashMap<String, P256SecretKey>,
96 label_to_pid: HashMap<String, String>,
98 network_data_keys: HashMap<String, P256SecretKey>,
100 network_public_keys: HashMap<String, Vec<u8>>,
102 issued_certificates: HashMap<String, X509Certificate>,
104 serial_counter: u64,
108 logger: Arc<Logger>,
110}
111
112#[derive(Debug, Clone, Serialize, Deserialize)]
116pub struct MobileKeyManagerState {
117 ca_key_pair: EcdsaKeyPair,
118 ca_certificate: X509Certificate,
119 user_root_key: Option<EcdsaKeyPair>,
120 user_root_agreement: Option<Vec<u8>>,
122 user_profile_keys: HashMap<String, EcdsaKeyPair>,
123 user_profile_agreements: HashMap<String, Vec<u8>>,
124 label_to_pid: HashMap<String, String>,
125 network_data_keys: HashMap<String, Vec<u8>>,
126 network_public_keys: HashMap<String, Vec<u8>>,
127 issued_certificates: HashMap<String, X509Certificate>,
128 serial_counter: u64,
129}
130
131impl MobileKeyManager {
132 pub fn new(logger: Arc<Logger>) -> Result<Self> {
134 let ca_subject = "CN=Runar User CA,O=Runar,C=US";
136 let certificate_authority = CertificateAuthority::new(ca_subject)?;
137 let certificate_validator =
138 CertificateValidator::new(vec![certificate_authority.ca_certificate().clone()]);
139
140 Ok(Self {
141 certificate_authority,
142 certificate_validator,
143 user_root_key: None,
144 user_root_agreement: None,
145 user_profile_keys: HashMap::new(),
146 user_profile_agreements: HashMap::new(),
147 label_to_pid: HashMap::new(),
148 network_data_keys: HashMap::new(),
149 network_public_keys: HashMap::new(),
150 issued_certificates: HashMap::new(),
151 serial_counter: 1, logger,
153 })
154 }
155
156 fn dns_safe_node_id(&self, node_id: &str) -> String {
158 node_id
159 .chars()
160 .map(|c| match c {
161 '-' => 'x', '_' => 'y', c if c.is_alphanumeric() => c, _ => 'z', })
166 .collect()
167 }
168
169 pub fn install_network_public_key(&mut self, network_public_key: &[u8]) -> Result<()> {
170 let network_id = compact_id(network_public_key);
171 self.network_public_keys
172 .insert(network_id.clone(), network_public_key.to_vec());
173
174 log_info!(
175 self.logger,
176 "Network public key installed with ID: {network_id}"
177 );
178 Ok(())
179 }
180
181 pub fn initialize_user_root_key(&mut self) -> Result<Vec<u8>> {
183 if self.user_root_key.is_some() {
184 return Err(KeyError::KeyAlreadyInitialized(
185 "User root key already initialized".to_string(),
186 ));
187 }
188
189 let root_key = EcdsaKeyPair::new()?;
190
191 let agreement_secret = derive_agreement_from_master(
193 &root_key.signing_key().to_bytes(),
194 b"runar-v1:user-root:agreement",
195 )?;
196 self.user_root_key = Some(root_key);
197 self.user_root_agreement = Some(agreement_secret);
198 log_info!(
199 self.logger,
200 "User root key initialized (private key secured on mobile)"
201 );
202
203 let agr_pub = self
205 .user_root_agreement
206 .as_ref()
207 .unwrap()
208 .public_key()
209 .to_encoded_point(false)
210 .as_bytes()
211 .to_vec();
212
213 Ok(agr_pub)
214 }
215
216 pub fn get_user_root_public_key(&self) -> Result<Vec<u8>> {
218 let root_agreement = self.user_root_agreement.as_ref().ok_or_else(|| {
219 KeyError::KeyNotFound("User root agreement key not initialized".to_string())
220 })?;
221 Ok(root_agreement
222 .public_key()
223 .to_encoded_point(false)
224 .as_bytes()
225 .to_vec())
226 }
227
228 pub fn derive_user_profile_key(&mut self, label: &str) -> Result<Vec<u8>> {
234 if let Some(pid) = self.label_to_pid.get(label) {
236 if let Some(agr) = self.user_profile_agreements.get(pid) {
237 let pubkey = agr.public_key();
238 return Ok(pubkey.to_encoded_point(false).as_bytes().to_vec());
239 }
240 }
241
242 use hkdf::Hkdf;
243 use sha2::Sha256;
244
245 let root_key = self
247 .user_root_key
248 .as_ref()
249 .ok_or_else(|| KeyError::KeyNotFound("User root key not initialized".to_string()))?;
250
251 let root_scalar_bytes = root_key.signing_key().to_bytes();
253
254 let hk = Hkdf::<Sha256>::new(
256 Some(b"RunarKeyDerivationSalt/v1"),
257 root_scalar_bytes.as_slice(),
258 );
259 let mut counter: u32 = 0;
260 let profile_agreement = loop {
261 let info = if counter == 0 {
262 format!("runar-v1:profile:agreement:{label}")
263 } else {
264 format!("runar-v1:profile:agreement:{label}:{counter}")
265 };
266 let mut candidate_bytes = [0u8; 32];
267 hk.expand(info.as_bytes(), &mut candidate_bytes)
268 .map_err(|e| KeyError::KeyDerivationError(format!("HKDF expansion failed: {e}")))?;
269 match P256SecretKey::from_slice(&candidate_bytes) {
270 Ok(sk) => break sk,
271 Err(_) => {
272 counter = counter.saturating_add(1);
273 continue;
274 }
275 }
276 };
277 let public_key = profile_agreement
278 .public_key()
279 .to_encoded_point(false)
280 .as_bytes()
281 .to_vec();
282 let pid = compact_id(&public_key);
283 self.user_profile_agreements
285 .insert(pid.clone(), profile_agreement);
286 self.label_to_pid.insert(label.to_string(), pid.clone());
287
288 log_info!(self.logger, "User profile key derived using HKDF for label '{label}' (attempts: {counter}, id: {pid})");
289
290 Ok(public_key)
291 }
292
293 pub fn get_network_public_key(&self, network_id: &str) -> Result<Vec<u8>> {
294 if let Some(network_key) = self.network_data_keys.get(network_id) {
296 Ok(network_key
297 .public_key()
298 .to_encoded_point(false)
299 .as_bytes()
300 .to_vec())
301 } else if let Some(network_public_key) = self.network_public_keys.get(network_id) {
302 Ok(network_public_key.clone())
303 } else {
304 Err(KeyError::KeyNotFound(format!(
305 "Network public key not found for network: {network_id}"
306 )))
307 }
308 }
309
310 pub fn generate_network_data_key(&mut self) -> Result<String> {
312 let network_key = P256SecretKey::random(&mut rand::thread_rng());
313 let public_key = network_key
314 .public_key()
315 .to_encoded_point(false)
316 .as_bytes()
317 .to_vec();
318 let network_id = compact_id(&public_key);
319
320 self.network_data_keys
321 .insert(network_id.clone(), network_key);
322 log_info!(
323 self.logger,
324 "Network data key generated with ID: {network_id}"
325 );
326
327 Ok(network_id)
328 }
329
330 pub fn create_envelope_key(&self) -> Result<Vec<u8>> {
333 use hkdf::Hkdf;
335 use rand::RngCore;
336 use sha2::Sha256;
337 let root_key = self
338 .user_root_key
339 .as_ref()
340 .ok_or_else(|| KeyError::KeyNotFound("User root key not initialized".to_string()))?;
341 let ikm = root_key.signing_key().to_bytes();
342 let mut nonce = [0u8; 16];
343 rand::thread_rng().fill_bytes(&mut nonce);
344 let hk = Hkdf::<Sha256>::new(Some(b"RunarKeyDerivationSalt/v1"), ikm.as_slice());
345 let mut envelope_key = [0u8; 32];
346 let mut info = b"runar-v1:user-root:storage:envelope:".to_vec();
347 info.extend_from_slice(&nonce);
348 hk.expand(&info, &mut envelope_key)
349 .map_err(|e| KeyError::KeyDerivationError(format!("HKDF expansion failed: {e}")))?;
350 Ok(envelope_key.to_vec())
351 }
352
353 pub fn encrypt_with_envelope(
359 &self,
360 data: &[u8],
361 network_id: Option<&str>,
362 profile_public_keys: Vec<Vec<u8>>,
363 ) -> Result<EnvelopeEncryptedData> {
364 let envelope_key = self.create_envelope_key()?;
366
367 let encrypted_data = self.encrypt_with_symmetric_key(data, &envelope_key)?;
369
370 let mut network_encrypted_key = Vec::new();
372 if let Some(network_id) = network_id {
373 let network_public_key_bytes = self.get_network_public_key(network_id)?;
375
376 network_encrypted_key =
377 self.encrypt_key_with_ecdsa(&envelope_key, &network_public_key_bytes)?;
378 }
379
380 let mut profile_encrypted_keys = HashMap::new();
382 for profile_public_key in profile_public_keys {
383 let encrypted_key = self.encrypt_key_with_ecdsa(&envelope_key, &profile_public_key)?;
384 let profile_id = compact_id(&profile_public_key);
385 profile_encrypted_keys.insert(profile_id, encrypted_key);
386 }
387
388 Ok(EnvelopeEncryptedData {
389 encrypted_data,
390 network_id: network_id.map(|s| s.to_string()),
391 network_encrypted_key,
392 profile_encrypted_keys,
393 })
394 }
395
396 pub fn decrypt_with_profile(
398 &self,
399 envelope_data: &EnvelopeEncryptedData,
400 profile_id: &str,
401 ) -> Result<Vec<u8>> {
402 let profile_agreement = self
403 .user_profile_agreements
404 .get(profile_id)
405 .ok_or_else(|| KeyError::KeyNotFound(format!("Profile key not found: {profile_id}")))?;
406
407 let encrypted_envelope_key = envelope_data
408 .profile_encrypted_keys
409 .get(profile_id)
410 .ok_or_else(|| {
411 KeyError::KeyNotFound(format!("Envelope key not found for profile: {profile_id}"))
412 })?;
413
414 let envelope_key =
415 self.decrypt_key_with_agreement(encrypted_envelope_key, profile_agreement)?;
416 self.decrypt_with_symmetric_key(&envelope_data.encrypted_data, &envelope_key)
417 }
418
419 pub fn decrypt_with_network(&self, envelope_data: &EnvelopeEncryptedData) -> Result<Vec<u8>> {
421 let network_id = envelope_data
422 .network_id
423 .as_ref()
424 .ok_or_else(|| KeyError::DecryptionError("Envelope missing network_id".to_string()))?;
425
426 let network_key = self.network_data_keys.get(network_id).ok_or_else(|| {
427 KeyError::KeyNotFound(format!(
428 "Network key pair not found for network: {network_id}"
429 ))
430 })?;
431
432 let encrypted_envelope_key = &envelope_data.network_encrypted_key;
433
434 if encrypted_envelope_key.is_empty() {
435 return Err(KeyError::DecryptionError(
436 "Envelope missing network_encrypted_key".to_string(),
437 ));
438 }
439
440 let envelope_key = self.decrypt_key_with_agreement(encrypted_envelope_key, network_key)?;
441 self.decrypt_with_symmetric_key(&envelope_data.encrypted_data, &envelope_key)
442 }
443
444 fn encrypt_with_symmetric_key(&self, data: &[u8], key: &[u8]) -> Result<Vec<u8>> {
446 use aes_gcm::{aead::Aead, Aes256Gcm, KeyInit, Nonce};
447 use rand::{thread_rng, RngCore};
448
449 if key.len() != 32 {
450 return Err(KeyError::SymmetricCipherError(
451 "Key must be 32 bytes for AES-256".to_string(),
452 ));
453 }
454
455 let cipher = Aes256Gcm::new_from_slice(key)
456 .map_err(|e| KeyError::SymmetricCipherError(format!("Failed to create cipher: {e}")))?;
457 let mut nonce = [0u8; 12];
458 thread_rng().fill_bytes(&mut nonce);
459
460 let ciphertext = cipher
461 .encrypt(Nonce::from_slice(&nonce), data)
462 .map_err(|e| KeyError::EncryptionError(format!("AES-GCM encryption failed: {e}")))?;
463
464 let mut result = nonce.to_vec();
466 result.extend_from_slice(&ciphertext);
467 Ok(result)
468 }
469
470 fn decrypt_with_symmetric_key(&self, encrypted_data: &[u8], key: &[u8]) -> Result<Vec<u8>> {
471 use aes_gcm::{aead::Aead, Aes256Gcm, KeyInit, Nonce};
472
473 if key.len() != 32 {
474 return Err(KeyError::SymmetricCipherError(
475 "Key must be 32 bytes for AES-256".to_string(),
476 ));
477 }
478
479 if encrypted_data.len() < 12 {
480 return Err(KeyError::DecryptionError(
481 "Encrypted data too short (missing nonce)".to_string(),
482 ));
483 }
484
485 let cipher = Aes256Gcm::new_from_slice(key)
486 .map_err(|e| KeyError::SymmetricCipherError(format!("Failed to create cipher: {e}")))?;
487 let nonce = &encrypted_data[..12];
488 let ciphertext = &encrypted_data[12..];
489
490 cipher
491 .decrypt(Nonce::from_slice(nonce), ciphertext)
492 .map_err(|e| KeyError::DecryptionError(format!("AES-GCM decryption failed: {e}")))
493 }
494
495 fn encrypt_key_with_ecdsa(
497 &self,
498 data: &[u8],
499 recipient_public_key_bytes: &[u8],
500 ) -> Result<Vec<u8>> {
501 use hkdf::Hkdf;
502 use p256::ecdh::EphemeralSecret;
503 use p256::elliptic_curve::sec1::ToEncodedPoint;
504 use p256::PublicKey;
505 use rand::thread_rng;
506 use sha2::Sha256;
507
508 let ephemeral_secret = EphemeralSecret::random(&mut thread_rng());
510 let ephemeral_public = ephemeral_secret.public_key();
511
512 let recipient_public_key =
514 PublicKey::from_sec1_bytes(recipient_public_key_bytes).map_err(|e| {
515 KeyError::InvalidKeyFormat(format!("Failed to parse recipient public key: {e}"))
516 })?;
517
518 let shared_secret = ephemeral_secret.diffie_hellman(&recipient_public_key);
520 let shared_secret_bytes = shared_secret.raw_secret_bytes();
521
522 let hk = Hkdf::<Sha256>::new(None, shared_secret_bytes.as_slice());
524 let mut encryption_key = [0u8; 32];
525 hk.expand(b"runar-v1:ecies:envelope-key", &mut encryption_key)
526 .map_err(|e| KeyError::KeyDerivationError(format!("HKDF expansion failed: {e}")))?;
527
528 let encrypted_data = self.encrypt_with_symmetric_key(data, &encryption_key)?;
530
531 let ephemeral_public_bytes = ephemeral_public.to_encoded_point(false);
533 let mut result = ephemeral_public_bytes.as_bytes().to_vec();
534 result.extend_from_slice(&encrypted_data);
535 Ok(result)
536 }
537
538 fn decrypt_key_with_agreement(
540 &self,
541 encrypted_data: &[u8],
542 agreement_secret: &p256::SecretKey,
543 ) -> Result<Vec<u8>> {
544 use hkdf::Hkdf;
545 use p256::ecdh::diffie_hellman;
546 use p256::PublicKey;
547 use sha2::Sha256;
548
549 if encrypted_data.len() < 65 {
551 return Err(KeyError::DecryptionError(
552 "Encrypted data too short for ECIES".to_string(),
553 ));
554 }
555
556 let ephemeral_public_bytes = &encrypted_data[..65];
557 let encrypted_payload = &encrypted_data[65..];
558
559 let ephemeral_public = PublicKey::from_sec1_bytes(ephemeral_public_bytes).map_err(|e| {
561 KeyError::DecryptionError(format!("Failed to parse ephemeral public key: {e}"))
562 })?;
563
564 let shared_secret = diffie_hellman(
566 agreement_secret.to_nonzero_scalar(),
567 ephemeral_public.as_affine(),
568 );
569 let shared_secret_bytes = shared_secret.raw_secret_bytes();
570
571 let hk = Hkdf::<Sha256>::new(None, shared_secret_bytes);
573 let mut encryption_key = [0u8; 32];
574 hk.expand(b"runar-v1:ecies:envelope-key", &mut encryption_key)
575 .map_err(|e| KeyError::KeyDerivationError(format!("HKDF expansion failed: {e}")))?;
576
577 self.decrypt_with_symmetric_key(encrypted_payload, &encryption_key)
579 }
580
581 pub fn initialize_user_identity(&mut self) -> Result<Vec<u8>> {
583 self.initialize_user_root_key()
585 }
586
587 pub fn get_ca_certificate(&self) -> &X509Certificate {
589 self.certificate_authority.ca_certificate()
590 }
591
592 pub fn get_ca_public_key(&self) -> Vec<u8> {
594 self.certificate_authority
595 .ca_public_key()
596 .to_encoded_point(true)
597 .as_bytes()
598 .to_vec()
599 }
600
601 pub fn process_setup_token(
603 &mut self,
604 setup_token: &SetupToken,
605 ) -> Result<NodeCertificateMessage> {
606 let node_id = &setup_token.node_id;
607 log_info!(self.logger, "Processing setup token for node: {node_id}");
608
609 if setup_token.csr_der.is_empty() {
611 log_error!(self.logger, "Empty CSR in setup token");
612 return Err(KeyError::InvalidOperation(
613 "Empty CSR in setup token".to_string(),
614 ));
615 }
616
617 {
619 use openssl::nid::Nid;
620 use openssl::x509::X509Req;
621
622 let csr = X509Req::from_der(&setup_token.csr_der).map_err(|e| {
623 KeyError::CertificateError(format!(
624 "Failed to parse CSR DER for subject validation: {e}"
625 ))
626 })?;
627
628 let mut cn_matches = false;
629 let dns_safe_node_id = self.dns_safe_node_id(node_id);
630 for entry in csr.subject_name().entries_by_nid(Nid::COMMONNAME) {
631 if let Ok(data) = entry.data().as_utf8() {
632 if data.to_string() == dns_safe_node_id {
633 cn_matches = true;
634 break;
635 }
636 }
637 }
638
639 if !cn_matches {
640 return Err(KeyError::InvalidOperation(format!(
641 "CSR CN does not match node ID '{node_id}' (DNS-safe: '{dns_safe_node_id}')",
642 )));
643 }
644 }
645
646 let validity_days = 365; let node_certificate = self
649 .certificate_authority
650 .sign_certificate_request_with_serial(
651 &setup_token.csr_der,
652 validity_days,
653 Some(self.serial_counter),
654 )?;
655
656 self.serial_counter = self.serial_counter.wrapping_add(1);
658
659 self.issued_certificates
661 .insert(setup_token.node_id.clone(), node_certificate.clone());
662
663 let metadata = CertificateMetadata {
665 issued_at: std::time::SystemTime::now()
666 .duration_since(std::time::UNIX_EPOCH)
667 .map_err(|e| KeyError::InvalidOperation(format!("System time error: {e}")))?
668 .as_secs(),
669 validity_days,
670 purpose: "Node TLS Certificate".to_string(),
671 };
672
673 Ok(NodeCertificateMessage {
675 node_certificate,
676 ca_certificate: self.certificate_authority.ca_certificate().clone(),
677 metadata,
678 })
679 }
680
681 pub fn get_statistics(&self) -> MobileKeyManagerStatistics {
686 MobileKeyManagerStatistics {
687 issued_certificates_count: self.issued_certificates.len(),
688 user_profile_keys_count: self.user_profile_keys.len(),
689 network_keys_count: self.network_data_keys.len(),
690 ca_certificate_subject: self
691 .certificate_authority
692 .ca_certificate()
693 .subject()
694 .to_string(),
695 }
696 }
697
698 pub fn create_network_key_message(
700 &self,
701 network_id: &str,
702 node_agreement_public_key: &[u8],
703 ) -> Result<NetworkKeyMessage> {
704 let network_key = self.network_data_keys.get(network_id).ok_or_else(|| {
705 KeyError::KeyNotFound(format!(
706 "Network key pair not found for network: {network_id}"
707 ))
708 })?;
709
710 let network_scalar = network_key.to_bytes().to_vec();
712 let encrypted_network_key =
713 self.encrypt_key_with_ecdsa(&network_scalar, node_agreement_public_key)?;
714
715 let node_id = compact_id(node_agreement_public_key);
716 log_info!(
717 self.logger,
718 "Network key encrypted for node {node_id} with ECIES"
719 );
720
721 Ok(NetworkKeyMessage {
722 network_id: network_id.to_string(),
723 network_public_key: network_key
724 .public_key()
725 .to_encoded_point(false)
726 .as_bytes()
727 .to_vec(),
728 encrypted_network_key,
729 key_derivation_info: format!("Network key for node {node_id} (ECIES encrypted)"),
730 })
731 }
732
733 pub fn validate_certificate(&self, certificate: &X509Certificate) -> Result<()> {
735 self.certificate_validator.validate_certificate(certificate)
736 }
737
738 pub fn get_issued_certificate(&self, node_id: &str) -> Option<&X509Certificate> {
740 self.issued_certificates.get(node_id)
741 }
742
743 pub fn list_issued_certificates(&self) -> Vec<(String, &X509Certificate)> {
745 self.issued_certificates
746 .iter()
747 .map(|(node_id, cert)| (node_id.clone(), cert))
748 .collect()
749 }
750
751 pub fn encrypt_for_profile(&self, data: &[u8], profile_id: &str) -> Result<Vec<u8>> {
753 let profile_key_pair = self.user_profile_keys.get(profile_id).ok_or_else(|| {
754 KeyError::KeyNotFound(format!(
755 "Profile public key not found for profile: {profile_id}"
756 ))
757 })?;
758 let envelope_data = MobileKeyManager::encrypt_with_envelope(
760 self,
761 data,
762 None,
763 vec![profile_key_pair.public_key_bytes()],
764 )?;
765 Ok(envelope_data.encrypted_data)
767 }
768
769 pub fn encrypt_for_network(&self, data: &[u8], network_id: &str) -> Result<Vec<u8>> {
771 let envelope_data =
773 MobileKeyManager::encrypt_with_envelope(self, data, Some(network_id), vec![])?;
774 Ok(envelope_data.encrypted_data)
776 }
777
778 pub fn generate_user_profile_key(&mut self, profile_id: &str) -> Result<Vec<u8>> {
780 self.derive_user_profile_key(profile_id)
781 }
782
783 pub fn encrypt_message_for_node(
785 &self,
786 message: &[u8],
787 node_agreement_public_key: &[u8],
788 ) -> Result<Vec<u8>> {
789 let message_len = message.len();
790 log_debug!(
791 self.logger,
792 "Encrypting message for node ({message_len} bytes)"
793 );
794 self.encrypt_key_with_ecdsa(message, node_agreement_public_key)
795 }
796
797 pub fn decrypt_message_from_node(&self, encrypted_message: &[u8]) -> Result<Vec<u8>> {
799 let encrypted_message_len = encrypted_message.len();
800 log_debug!(
801 self.logger,
802 "Decrypting message from node ({encrypted_message_len} bytes)"
803 );
804 let root_agreement = self.user_root_agreement.as_ref().ok_or_else(|| {
805 KeyError::KeyNotFound("User root agreement key not initialized".to_string())
806 })?;
807 self.decrypt_key_with_agreement(encrypted_message, root_agreement)
808 }
809
810 pub fn export_state(&self) -> MobileKeyManagerState {
816 MobileKeyManagerState {
817 ca_key_pair: self.certificate_authority.ca_key_pair().clone(),
818 ca_certificate: self.certificate_authority.ca_certificate().clone(),
819 user_root_key: self.user_root_key.clone(),
820 user_root_agreement: self
821 .user_root_agreement
822 .as_ref()
823 .map(|k| k.to_pkcs8_der().unwrap().as_bytes().to_vec()),
824 user_profile_keys: self.user_profile_keys.clone(),
825 user_profile_agreements: self
826 .user_profile_agreements
827 .iter()
828 .map(|(id, sk)| (id.clone(), sk.to_pkcs8_der().unwrap().as_bytes().to_vec()))
829 .collect(),
830 label_to_pid: self.label_to_pid.clone(),
831 network_data_keys: self
832 .network_data_keys
833 .iter()
834 .map(|(id, sk)| (id.clone(), sk.to_pkcs8_der().unwrap().as_bytes().to_vec()))
835 .collect(),
836 network_public_keys: self.network_public_keys.clone(),
837 issued_certificates: self.issued_certificates.clone(),
838 serial_counter: self.serial_counter,
839 }
840 }
841
842 pub fn from_state(state: MobileKeyManagerState, logger: Arc<Logger>) -> Result<Self> {
844 let certificate_authority = CertificateAuthority::from_existing(
845 state.ca_key_pair.clone(),
846 state.ca_certificate.clone(),
847 );
848
849 let certificate_validator = CertificateValidator::new(vec![state.ca_certificate.clone()]);
850
851 log_info!(logger, "Mobile Key Manager state imported");
852
853 Ok(Self {
854 certificate_authority,
855 certificate_validator,
856 user_root_key: state.user_root_key,
857 user_root_agreement: state
858 .user_root_agreement
859 .and_then(|der| P256SecretKey::from_pkcs8_der(&der).ok()),
860 user_profile_keys: state.user_profile_keys,
861 user_profile_agreements: state
862 .user_profile_agreements
863 .into_iter()
864 .filter_map(|(id, der)| P256SecretKey::from_pkcs8_der(&der).ok().map(|k| (id, k)))
865 .collect(),
866 label_to_pid: state.label_to_pid,
867 network_data_keys: state
868 .network_data_keys
869 .into_iter()
870 .filter_map(|(id, der)| P256SecretKey::from_pkcs8_der(&der).ok().map(|k| (id, k)))
871 .collect(),
872 network_public_keys: state.network_public_keys,
873 issued_certificates: state.issued_certificates,
874 serial_counter: state.serial_counter,
875 logger,
876 })
877 }
878}
879
880impl crate::EnvelopeCrypto for MobileKeyManager {
881 fn encrypt_with_envelope(
882 &self,
883 data: &[u8],
884 network_id: Option<&str>,
885 profile_public_keys: Vec<Vec<u8>>,
886 ) -> crate::Result<crate::mobile::EnvelopeEncryptedData> {
887 MobileKeyManager::encrypt_with_envelope(self, data, network_id, profile_public_keys)
888 }
889
890 fn decrypt_envelope_data(
891 &self,
892 env: &crate::mobile::EnvelopeEncryptedData,
893 ) -> crate::Result<Vec<u8>> {
894 for pid in env.profile_encrypted_keys.keys() {
896 if let Ok(pt) = self.decrypt_with_profile(env, pid) {
897 return Ok(pt);
898 }
899 }
900 self.decrypt_with_network(env)
901 }
902}
903
904#[derive(Debug, Clone)]
906pub struct MobileKeyManagerStatistics {
907 pub issued_certificates_count: usize,
908 pub user_profile_keys_count: usize,
909 pub network_keys_count: usize,
910 pub ca_certificate_subject: String,
911}
912
913