1#![cfg(target_os = "windows")]
2use ncrypt::{Algorithm, ExportType, Key, ProviderName, RsaKeyBlob, StorageProvider};
3use rsa::RsaPublicKey;
4
5mod error;
6
7pub use error::Error;
8
9pub struct Tpm(StorageProvider);
11
12pub struct RsaKey(Key);
14
15pub struct KeyIterator<'a>(ncrypt::KeyIterator<'a>, &'a Tpm);
17
18pub struct KeyInfo<'a> {
19 pub name: String,
20 pub algorithm: String,
21 tpm: &'a Tpm,
22}
23
24impl Tpm {
25 pub fn open() -> Result<Self, Error> {
29 let handle = StorageProvider::open(ProviderName::PlatformCrypto).map_err(|e| match e {
30 ncrypt::Error::DeviceNotReady => Error::NotReady(e),
31 _ => Error::Internal(e),
32 })?;
33
34 Ok(Self(handle))
35 }
36
37 pub fn create_rsa_key(&self, key_name: &str) -> Result<RsaKey, Error> {
38 let key = self
39 .0
40 .create_persisted_key(key_name, Algorithm::Rsa)
41 .map_err(|e| match e {
42 ncrypt::Error::ObjectExists => Error::KeyExists(e),
43 _ => Error::Internal(e),
44 })?
45 .finalize()
46 .map_err(Error::Internal)?;
47
48 Ok(RsaKey(key))
49 }
50
51 pub fn open_rsa_key(&self, key_name: &str) -> Result<RsaKey, Error> {
52 let key = self.0.open_key(key_name).map_err(|e| match e {
53 ncrypt::Error::BadKeyset => Error::KeyNotFound(e),
54 _ => Error::Internal(e),
55 })?;
56
57 Ok(RsaKey(key))
58 }
59
60 pub fn enum_keys(&self) -> KeyIterator {
62 KeyIterator(self.0.enum_keys(), self)
63 }
64}
65
66impl RsaKey {
67 pub fn public_key(&self) -> Result<Box<RsaPublicKey>, Error> {
72 let export = self
73 .0
74 .export(ExportType::RsaPublicKey)
75 .map_err(Error::Internal)?;
76
77 let RsaKeyBlob::PublicKey(key) = export else {
78 return Err(Error::UnexpectedKeyType);
79 };
80
81 Ok(key)
82 }
83
84 pub fn encrypt(&self, data: &[u8]) -> Result<Vec<u8>, Error> {
86 self.0.encrypt(data).map_err(Error::Internal)
87 }
88
89 pub fn decrypt(&self, data: &[u8]) -> Result<Vec<u8>, Error> {
91 self.0.decrypt(data).map_err(|e| match e {
92 ncrypt::Error::Other(inner) if inner as u32 == 0x80280095 => Error::DecryptionFailed,
93 _ => Error::Internal(e),
94 })
95 }
96
97 pub fn delete(self) {
101 self.0.delete()
102 }
103}
104
105impl<'a> Iterator for KeyIterator<'a> {
106 type Item = KeyInfo<'a>;
107
108 fn next(&mut self) -> Option<Self::Item> {
109 if let Some(item) = self.0.next() {
110 return Some(KeyInfo {
111 name: item.name,
112 algorithm: item.algorithm,
113 tpm: self.1,
114 });
115 }
116
117 None
118 }
119}
120
121impl<'a> KeyInfo<'a> {
122 pub fn open(&self) -> Result<RsaKey, Error> {
124 if self.algorithm != "RSA" {
125 return Err(Error::UnexpectedKeyType);
126 }
127
128 self.tpm.open_rsa_key(&self.name)
129 }
130}