Skip to content

Commit d4e75db

Browse files
authored
Merge pull request #380 from baloo/baloo/swtpm/add-support-for-unix-sockets
tcti: adds support for unix sockets
2 parents 072bd20 + 62f022d commit d4e75db

File tree

1 file changed

+137
-66
lines changed

1 file changed

+137
-66
lines changed

tss-esapi/src/tcti_ldr.rs

Lines changed: 137 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,11 @@ pub enum TctiNameConf {
134134
/// Connect to a TPM (simulator) available as a network device via the MSSIM protocol
135135
///
136136
/// For more information about configuration, see [this page](https://www.mankier.com/3/Tss2_Tcti_Mssim_Init)
137-
Mssim(NetworkTPMConfig),
137+
Mssim(TpmSimulatorConfig),
138138
/// Connect to a TPM (simulator) available as a network device via the SWTPM protocol
139139
///
140140
/// For more information about configuration, see [this page](https://www.mankier.com/3/Tss2_Tcti_Mssim_Init)
141-
Swtpm(NetworkTPMConfig),
141+
Swtpm(TpmSimulatorConfig),
142142
/// Connect to a TPM through an Access Broker/Resource Manager daemon
143143
///
144144
/// For more information about configuration, see [this page](https://www.mankier.com/3/Tss2_Tcti_Tabrmd_Init)
@@ -177,21 +177,25 @@ impl TryFrom<TctiNameConf> for CString {
177177
};
178178

179179
let tcti_conf = match tcti {
180-
TctiNameConf::Mssim(config) => {
181-
if let ServerAddress::Hostname(name) = &config.host {
180+
TctiNameConf::Mssim(TpmSimulatorConfig::Tcp { host, port }) => {
181+
if let ServerAddress::Hostname(name) = &host {
182182
if !hostname_validator::is_valid(name) {
183183
return Err(Error::WrapperError(WrapperErrorKind::InvalidParam));
184184
}
185185
}
186-
format!("host={},port={}", config.host, config.port)
186+
format!("host={},port={}", host, port)
187187
}
188-
TctiNameConf::Swtpm(config) => {
189-
if let ServerAddress::Hostname(name) = &config.host {
188+
TctiNameConf::Swtpm(TpmSimulatorConfig::Tcp { host, port }) => {
189+
if let ServerAddress::Hostname(name) = &host {
190190
if !hostname_validator::is_valid(name) {
191191
return Err(Error::WrapperError(WrapperErrorKind::InvalidParam));
192192
}
193193
}
194-
format!("host={},port={}", config.host, config.port)
194+
format!("host={},port={}", host, port)
195+
}
196+
TctiNameConf::Mssim(TpmSimulatorConfig::Unix { path })
197+
| TctiNameConf::Swtpm(TpmSimulatorConfig::Unix { path }) => {
198+
format!("path={}", path)
195199
}
196200
TctiNameConf::Device(DeviceConfig { path }) => path
197201
.to_str()
@@ -224,14 +228,14 @@ impl FromStr for TctiNameConf {
224228

225229
let mssim_pattern = Regex::new(r"^mssim(:(.*))?$").unwrap(); //should not fail
226230
if let Some(captures) = mssim_pattern.captures(config_str) {
227-
return Ok(TctiNameConf::Mssim(NetworkTPMConfig::from_str(
231+
return Ok(TctiNameConf::Mssim(TpmSimulatorConfig::from_str(
228232
captures.get(2).map_or("", |m| m.as_str()),
229233
)?));
230234
}
231235

232236
let swtpm_pattern = Regex::new(r"^swtpm(:(.*))?$").unwrap(); //should not fail
233237
if let Some(captures) = swtpm_pattern.captures(config_str) {
234-
return Ok(TctiNameConf::Swtpm(NetworkTPMConfig::from_str(
238+
return Ok(TctiNameConf::Swtpm(TpmSimulatorConfig::from_str(
235239
captures.get(2).map_or("", |m| m.as_str()),
236240
)?));
237241
}
@@ -252,7 +256,7 @@ fn validate_from_str_tcti() {
252256
let tcti = TctiNameConf::from_str("mssim:port=1234,host=168.0.0.1").unwrap();
253257
assert_eq!(
254258
tcti,
255-
TctiNameConf::Mssim(NetworkTPMConfig {
259+
TctiNameConf::Mssim(TpmSimulatorConfig::Tcp {
256260
port: 1234,
257261
host: ServerAddress::Ip(IpAddr::V4(std::net::Ipv4Addr::new(168, 0, 0, 1)))
258262
})
@@ -261,16 +265,24 @@ fn validate_from_str_tcti() {
261265
let tcti = TctiNameConf::from_str("mssim").unwrap();
262266
assert_eq!(
263267
tcti,
264-
TctiNameConf::Mssim(NetworkTPMConfig {
265-
port: DEFAULT_SERVER_PORT,
268+
TctiNameConf::Mssim(TpmSimulatorConfig::Tcp {
269+
port: TpmSimulatorConfig::DEFAULT_PORT_CONFIG,
266270
host: Default::default()
267271
})
268272
);
269273

274+
let tcti = TctiNameConf::from_str("mssim:path=/foo/bar").unwrap();
275+
assert_eq!(
276+
tcti,
277+
TctiNameConf::Mssim(TpmSimulatorConfig::Unix {
278+
path: "/foo/bar".to_string(),
279+
})
280+
);
281+
270282
let tcti = TctiNameConf::from_str("swtpm:port=1234,host=168.0.0.1").unwrap();
271283
assert_eq!(
272284
tcti,
273-
TctiNameConf::Swtpm(NetworkTPMConfig {
285+
TctiNameConf::Swtpm(TpmSimulatorConfig::Tcp {
274286
port: 1234,
275287
host: ServerAddress::Ip(IpAddr::V4(std::net::Ipv4Addr::new(168, 0, 0, 1)))
276288
})
@@ -279,12 +291,20 @@ fn validate_from_str_tcti() {
279291
let tcti = TctiNameConf::from_str("swtpm").unwrap();
280292
assert_eq!(
281293
tcti,
282-
TctiNameConf::Swtpm(NetworkTPMConfig {
283-
port: DEFAULT_SERVER_PORT,
294+
TctiNameConf::Swtpm(TpmSimulatorConfig::Tcp {
295+
port: TpmSimulatorConfig::DEFAULT_PORT_CONFIG,
284296
host: Default::default()
285297
})
286298
);
287299

300+
let tcti = TctiNameConf::from_str("swtpm:path=/foo/bar").unwrap();
301+
assert_eq!(
302+
tcti,
303+
TctiNameConf::Swtpm(TpmSimulatorConfig::Unix {
304+
path: "/foo/bar".to_string(),
305+
})
306+
);
307+
288308
let tcti = TctiNameConf::from_str("device:/try/this/path").unwrap();
289309
assert_eq!(
290310
tcti,
@@ -352,39 +372,67 @@ fn validate_from_str_device_config() {
352372
assert_eq!(config.path, PathBuf::from("/dev/tpm0"));
353373
}
354374

355-
/// Configuration for an Mssim TCTI context
375+
/// Configuration for an Mssim or Swtpm TCTI context
356376
///
357377
/// The default configuration will point to `localhost:2321`
378+
///
379+
/// Examples:
380+
/// - Use of a TCP connection: `swtpm:host=localhost,port=2321`
381+
/// - Use of a unix socket: `swtpm:path=/path/to/sock`
382+
/// Available on tpm2-tss >= 3.2.
358383
#[derive(Clone, Debug, PartialEq, Eq)]
359-
pub struct NetworkTPMConfig {
360-
/// Address of the server to connect to
384+
pub enum TpmSimulatorConfig {
385+
/// Connects to tpm over TCP
386+
Tcp {
387+
/// Address of the server to connect to
388+
///
389+
/// Defaults to `localhost`
390+
host: ServerAddress,
391+
/// Port used by the server at the address given in `host`
392+
///
393+
/// Defaults to `2321`
394+
port: u16,
395+
},
396+
/// Connects to tpm over Unix socket
361397
///
362-
/// Defaults to `localhost`
363-
host: ServerAddress,
364-
/// Port used by the server at the address given in `host`
365-
///
366-
/// Defaults to `2321`
367-
port: u16,
398+
/// If used with a library without unix socket support (< 3.2.0),
399+
/// a [`Error::TssError`] error will be returned.
400+
/// `base_error()` of which will be a `BaseError::BadValue`.
401+
Unix { path: String },
368402
}
369403

370-
const DEFAULT_SERVER_PORT: u16 = 2321;
404+
impl TpmSimulatorConfig {
405+
const DEFAULT_PORT_CONFIG: u16 = 2321;
406+
}
371407

372-
impl Default for NetworkTPMConfig {
408+
impl Default for TpmSimulatorConfig {
373409
fn default() -> Self {
374-
NetworkTPMConfig {
410+
TpmSimulatorConfig::Tcp {
375411
host: Default::default(),
376-
port: DEFAULT_SERVER_PORT,
412+
port: TpmSimulatorConfig::DEFAULT_PORT_CONFIG,
377413
}
378414
}
379415
}
380416

381-
impl FromStr for NetworkTPMConfig {
417+
impl FromStr for TpmSimulatorConfig {
382418
type Err = Error;
383419

384420
fn from_str(config_str: &str) -> Result<Self> {
385421
if config_str.is_empty() {
386422
return Ok(Default::default());
387423
}
424+
425+
let path_pattern = Regex::new(r"(,|^)path=(.*?)(,|$)").unwrap(); // should not fail
426+
if let Some(path) = path_pattern
427+
.captures(config_str)
428+
.and_then(|c| c.get(2))
429+
.map(|m| m.as_str())
430+
{
431+
return Ok(TpmSimulatorConfig::Unix {
432+
path: path.to_string(),
433+
});
434+
}
435+
388436
let host_pattern = Regex::new(r"(,|^)host=(.*?)(,|$)").unwrap(); // should not fail
389437
let host = host_pattern
390438
.captures(config_str)
@@ -393,63 +441,86 @@ impl FromStr for NetworkTPMConfig {
393441
})?;
394442

395443
let port_pattern = Regex::new(r"(,|^)port=(.*?)(,|$)").unwrap(); // should not fail
396-
let port =
397-
port_pattern
398-
.captures(config_str)
399-
.map_or(Ok(DEFAULT_SERVER_PORT), |captures| {
400-
u16::from_str(captures.get(2).map_or("", |m| m.as_str()))
401-
.or(Err(Error::WrapperError(WrapperErrorKind::InvalidParam)))
402-
})?;
403-
Ok(NetworkTPMConfig { host, port })
444+
let port = port_pattern.captures(config_str).map_or(
445+
Ok(TpmSimulatorConfig::DEFAULT_PORT_CONFIG),
446+
|captures| {
447+
u16::from_str(captures.get(2).map_or("", |m| m.as_str()))
448+
.or(Err(Error::WrapperError(WrapperErrorKind::InvalidParam)))
449+
},
450+
)?;
451+
452+
Ok(TpmSimulatorConfig::Tcp { host, port })
404453
}
405454
}
406455

407456
#[test]
408457
fn validate_from_str_networktpm_config() {
409-
let config = NetworkTPMConfig::from_str("").unwrap();
458+
let config = TpmSimulatorConfig::from_str("").unwrap();
410459
assert_eq!(config, Default::default());
411460

412-
let config = NetworkTPMConfig::from_str("fjshd89943r=joishdf894u9r,sio0983=9u98jj").unwrap();
461+
let config = TpmSimulatorConfig::from_str("fjshd89943r=joishdf894u9r,sio0983=9u98jj").unwrap();
413462
assert_eq!(config, Default::default());
414463

415-
let config = NetworkTPMConfig::from_str("host=127.0.0.1,random=value").unwrap();
464+
let config = TpmSimulatorConfig::from_str("host=127.0.0.1,random=value").unwrap();
416465
assert_eq!(
417-
config.host,
418-
ServerAddress::Ip(IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1)))
466+
config,
467+
TpmSimulatorConfig::Tcp {
468+
host: ServerAddress::Ip(IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1))),
469+
port: TpmSimulatorConfig::DEFAULT_PORT_CONFIG
470+
}
419471
);
420-
assert_eq!(config.port, DEFAULT_SERVER_PORT);
421472

422-
let config = NetworkTPMConfig::from_str("port=1234,random=value").unwrap();
423-
assert_eq!(config.host, Default::default());
424-
assert_eq!(config.port, 1234);
473+
let config = TpmSimulatorConfig::from_str("port=1234,random=value").unwrap();
474+
assert_eq!(
475+
config,
476+
TpmSimulatorConfig::Tcp {
477+
host: Default::default(),
478+
port: 1234
479+
}
480+
);
425481

426-
let config = NetworkTPMConfig::from_str("host=localhost,port=1234").unwrap();
482+
let config = TpmSimulatorConfig::from_str("host=localhost,port=1234").unwrap();
427483
assert_eq!(
428-
config.host,
429-
ServerAddress::Hostname(String::from("localhost"))
484+
config,
485+
TpmSimulatorConfig::Tcp {
486+
host: ServerAddress::Hostname(String::from("localhost")),
487+
port: 1234
488+
}
430489
);
431-
assert_eq!(config.port, 1234);
432490

433-
let config = NetworkTPMConfig::from_str("port=1234,host=localhost").unwrap();
434-
assert_eq!(config.host, "localhost".parse::<ServerAddress>().unwrap());
435-
assert_eq!(config.port, 1234);
491+
let config = TpmSimulatorConfig::from_str("port=1234,host=localhost").unwrap();
492+
assert_eq!(
493+
config,
494+
TpmSimulatorConfig::Tcp {
495+
host: ServerAddress::Hostname(String::from("localhost")),
496+
port: 1234
497+
}
498+
);
436499

437-
let config = NetworkTPMConfig::from_str("port=1234,host=localhost,random=value").unwrap();
438-
assert_eq!(config.host, "localhost".parse::<ServerAddress>().unwrap());
439-
assert_eq!(config.port, 1234);
500+
let config = TpmSimulatorConfig::from_str("port=1234,host=localhost,random=value").unwrap();
501+
assert_eq!(
502+
config,
503+
TpmSimulatorConfig::Tcp {
504+
host: "localhost".parse::<ServerAddress>().unwrap(),
505+
port: 1234
506+
}
507+
);
440508

441-
let config = NetworkTPMConfig::from_str("host=1234.1234.1234.1234.12445.111").unwrap();
509+
let config = TpmSimulatorConfig::from_str("host=1234.1234.1234.1234.12445.111").unwrap();
442510
assert_eq!(
443-
config.host,
444-
ServerAddress::Hostname(String::from("1234.1234.1234.1234.12445.111"))
511+
config,
512+
TpmSimulatorConfig::Tcp {
513+
host: ServerAddress::Hostname(String::from("1234.1234.1234.1234.12445.111")),
514+
port: TpmSimulatorConfig::DEFAULT_PORT_CONFIG
515+
}
445516
);
446517

447-
let _ = NetworkTPMConfig::from_str("port=abdef").unwrap_err();
448-
let _ = NetworkTPMConfig::from_str("host=-timey-wimey").unwrap_err();
449-
let _ = NetworkTPMConfig::from_str("host=abc@def").unwrap_err();
450-
let _ = NetworkTPMConfig::from_str("host=").unwrap_err();
451-
let _ = NetworkTPMConfig::from_str("port=").unwrap_err();
452-
let _ = NetworkTPMConfig::from_str("port=,host=,yas").unwrap_err();
518+
let _ = TpmSimulatorConfig::from_str("port=abdef").unwrap_err();
519+
let _ = TpmSimulatorConfig::from_str("host=-timey-wimey").unwrap_err();
520+
let _ = TpmSimulatorConfig::from_str("host=abc@def").unwrap_err();
521+
let _ = TpmSimulatorConfig::from_str("host=").unwrap_err();
522+
let _ = TpmSimulatorConfig::from_str("port=").unwrap_err();
523+
let _ = TpmSimulatorConfig::from_str("port=,host=,yas").unwrap_err();
453524
}
454525

455526
/// Address of a TPM server

0 commit comments

Comments
 (0)