|
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