|
27 | 27 | //! Trusted keys |
28 | 28 |
|
29 | 29 | use std::borrow::Cow; |
| 30 | +use std::fmt; |
30 | 31 |
|
31 | | -use itertools::Itertools; |
32 | | - |
33 | | -use super::AsciiHex; |
| 32 | +use super::ByteBuf; |
34 | 33 | use crate::keytype::*; |
35 | 34 |
|
36 | 35 | /// Trusted keys are rooted in the TPM. |
@@ -111,71 +110,55 @@ pub struct TrustedOptions { |
111 | 110 | pub policyhandle: Option<u32>, |
112 | 111 | } |
113 | 112 |
|
114 | | -impl TrustedOptions { |
115 | | - fn payload_string(&self) -> String { |
116 | | - let parts = [ |
| 113 | +impl fmt::Display for TrustedOptions { |
| 114 | + /// Formats the options that are present. Starts with a leading space. |
| 115 | + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 116 | + if let Some(keyhandle) = self.keyhandle { |
117 | 117 | // keyhandle= ascii hex value of sealing key; default 40000000 (SRK) |
118 | | - ( |
119 | | - "keyhandle", |
120 | | - self.keyhandle |
121 | | - .as_ref() |
122 | | - .map(|v| AsciiHex::convert(&v.to_be().to_be_bytes())), |
123 | | - ), |
| 118 | + write!(f, " keyhandle={:x}", keyhandle)?; |
| 119 | + } |
| 120 | + if let Some(keyauth) = self.keyauth.as_ref() { |
124 | 121 | // keyauth= ascii hex auth for sealing key; default 00... |
125 | 122 | // (40 ascii zeros) |
126 | | - ( |
127 | | - "keyauth", |
128 | | - self.keyauth.as_ref().map(|v| AsciiHex::convert(v)), |
129 | | - ), |
| 123 | + write!(f, " keyauth={:x}", ByteBuf(keyauth))?; |
| 124 | + } |
| 125 | + if let Some(blobauth) = self.blobauth.as_ref() { |
130 | 126 | // blobauth= ascii hex auth for sealed data; default 00... |
131 | 127 | // (40 ascii zeros) |
132 | | - ( |
133 | | - "blobauth", |
134 | | - self.blobauth.as_ref().map(|v| AsciiHex::convert(v)), |
135 | | - ), |
| 128 | + write!(f, " blobauth={:x}", ByteBuf(blobauth))?; |
| 129 | + } |
| 130 | + if let Some(pcrinfo) = self.pcrinfo.as_ref() { |
136 | 131 | // pcrinfo= ascii hex of PCR_INFO or PCR_INFO_LONG (no default) |
137 | | - ( |
138 | | - "pcrinfo", |
139 | | - self.pcrinfo.as_ref().map(|v| AsciiHex::convert(&v)), |
140 | | - ), |
| 132 | + write!(f, " pcrinfo={:x}", ByteBuf(pcrinfo))?; |
| 133 | + } |
| 134 | + if let Some(pcrlock) = self.pcrlock { |
141 | 135 | // pcrlock= pcr number to be extended to "lock" blob |
142 | | - ("pcrlock", self.pcrlock.as_ref().map(|v| format!("{}", v))), |
| 136 | + write!(f, " pcrlock={}", pcrlock)?; |
| 137 | + } |
| 138 | + if let Some(migratable) = self.migratable { |
143 | 139 | // migratable= 0|1 indicating permission to reseal to new PCR values, |
144 | 140 | // default 1 (resealing allowed) |
145 | | - ( |
146 | | - "migratable", |
147 | | - self.migratable |
148 | | - .as_ref() |
149 | | - .map(|&v| if v { "1" } else { "0" }.to_string()), |
150 | | - ), |
| 141 | + write!(f, " migratable={}", migratable as u8)?; |
| 142 | + } |
| 143 | + if let Some(hash) = self.hash { |
151 | 144 | // hash= hash algorithm name as a string. For TPM 1.x the only |
152 | 145 | // allowed value is sha1. For TPM 2.x the allowed values |
153 | 146 | // are sha1, sha256, sha384, sha512 and sm3-256. |
154 | | - ("hash", self.hash.as_ref().map(|v| v.name().to_string())), |
| 147 | + write!(f, " hash={}", hash.name())?; |
| 148 | + } |
| 149 | + if let Some(policydigest) = self.policydigest.as_ref() { |
155 | 150 | // policydigest= digest for the authorization policy. must be calculated |
156 | 151 | // with the same hash algorithm as specified by the 'hash=' |
157 | 152 | // option. |
158 | | - ( |
159 | | - "policydigest", |
160 | | - self.policydigest.as_ref().map(|v| AsciiHex::convert(&v)), |
161 | | - ), |
| 153 | + write!(f, " policydigest={:x}", ByteBuf(policydigest))?; |
| 154 | + } |
| 155 | + if let Some(policyhandle) = self.policyhandle { |
162 | 156 | // policyhandle= handle to an authorization policy session that defines the |
163 | 157 | // same policy and with the same hash algorithm as was used to |
164 | 158 | // seal the key. |
165 | | - ( |
166 | | - "policyhandle", |
167 | | - self.policyhandle |
168 | | - .as_ref() |
169 | | - .map(|v| AsciiHex::convert(&v.to_be().to_be_bytes())), |
170 | | - ), |
171 | | - ]; |
172 | | - |
173 | | - let options = parts |
174 | | - .iter() |
175 | | - .filter_map(|(key, value)| value.as_ref().map(|value| format!("{}={}", key, value))) |
176 | | - .format(" "); |
177 | | - |
178 | | - format!("{}", options) |
| 159 | + write!(f, " policyhandle={:x}", policyhandle)?; |
| 160 | + } |
| 161 | + Ok(()) |
179 | 162 | } |
180 | 163 | } |
181 | 164 |
|
@@ -211,22 +194,20 @@ pub enum Payload { |
211 | 194 |
|
212 | 195 | impl KeyPayload for Payload { |
213 | 196 | fn payload(&self) -> Cow<[u8]> { |
214 | | - let (command, blob, options) = match *self { |
| 197 | + match self { |
215 | 198 | Payload::New { |
216 | | - ref keylen, |
217 | | - ref options, |
218 | | - } => ("new", format!("{}", keylen), options), |
| 199 | + keylen, |
| 200 | + options, |
| 201 | + } => format!("new {}{}", keylen, options), |
219 | 202 | Payload::Load { |
220 | | - ref blob, |
221 | | - ref options, |
222 | | - } => ("load", AsciiHex::convert(&blob), options), |
| 203 | + blob, |
| 204 | + options, |
| 205 | + } => format!("load {:x}{}", ByteBuf(blob), options), |
223 | 206 | Payload::Update { |
224 | | - ref options, |
225 | | - } => ("update", String::new(), options), |
226 | | - }; |
227 | | - |
228 | | - format!("{} {} {}", command, blob, options.payload_string()) |
229 | | - .bytes() |
230 | | - .collect() |
| 207 | + options, |
| 208 | + } => format!("update{}", options), |
| 209 | + } |
| 210 | + .into_bytes() |
| 211 | + .into() |
231 | 212 | } |
232 | 213 | } |
0 commit comments