Skip to content

Commit

Permalink
Add suppoprt for keylime tpm data io
Browse files Browse the repository at this point in the history
  • Loading branch information
leonjia0112 committed Nov 29, 2018
1 parent 6da1c06 commit 08c42e5
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 35 deletions.
2 changes: 1 addition & 1 deletion src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ pub static IMA_ML_STUB: &'static str =
pub static IMA_ML: &'static str =
"/sys/kernel/security/ima/ascii_runtime_measurements";
pub static KEY: &'static str = "secret";
pub static WORK_DIR: &'static str = "/tmp";

/*
* Temporaray location for configuration parameters
*/

// cloud node
pub static WORK_DIR: &'static str = "/tmp";
pub static SECURE_SIZE: &'static str = "1m";
pub static MOUNT_SECURE: bool = true;

Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#[macro_use]
extern crate log;

#[macro_use]
// #[macro_use]
extern crate serde_derive;

#[macro_use]
Expand Down
190 changes: 158 additions & 32 deletions src/tpm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ use super::*;
use flate2::write::ZlibEncoder;
use flate2::Compression;
use openssl::sha;
use serde_json::Value;
use std::env;
use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
use std::io::BufWriter;
use std::io::Read;
use std::process::Command;
use std::process::Output;
Expand All @@ -26,50 +28,114 @@ pub const EXIT_SUCCESS: i32 = 0;

static EMPTYMASK: &'static str = "1";

/*
* tpm data struct for tpmdata.json file IO
*/
#[derive(Serialize, Deserialize, Debug)]
struct TpmData {
aik_pw: String,
ek: String,
owner_pw: String,
aik_handle: String,
aikmod: String,
aikpriv: String,
aik: String,
}

/***************************************************************
ftpm_initialize.py
Following are function from tpm_initialize.py program
*****************************************************************/

/*
input: content key in tpmdata
return: deserlized json object
getting the tpm data struct and convert it to a json value object to access to a particular field inside the tpm data file
*/
fn get_tpm_metadata(content_key: String) -> Option<String> {
let t_data = read_tpm_data().unwrap();
let t_data_json_value = serde_json::to_value(t_data).unwrap();
Some(t_data_json_value[content_key].to_string())
* Input: content key in tpmdata
* Return: Result wrap value string or error code -1
*
* Getting the tpm data struct and convert it to a json value object to
* retrive a particular value by the given key inside the tpm data.
*/
fn get_tpm_metadata_content(key: &str) -> Result<Option<String>, i32> {
let tpm_data = match read_tpm_data() {
Ok(data) => data,
Err(e) => {
error!("Fail to read tpmdata.json, error: [{}].", e);
return Err(-1);
}
};
let remove: &[_] = &['"', ' ', '/'];
match tpm_data.get(key) {
Some(content) => Ok(Some(
content
.as_str()
.unwrap()
.to_string()
.trim_matches(remove)
.to_string(),
)),
None => {
debug!("Content field [{}] doesn't exist.", key);
Ok(None)
}
}
}

/*
* input: N/A
* return: tpmdata in json object
* Input: tpm data key
* tpm data value
* Return: Result wrap success or error code -1
*
* Set the corresponding tpm data key with new value and save the new content
* to tpmdata.json. This version remove global tpmdata variable. Read the file
* before write the content to the file.
*/
fn set_tpm_metadata_content(key: &str, value: &str) -> Result<(), i32> {
let mut tpm_data = match read_tpm_data() {
Ok(data) => data,
Err(e) => {
error!("Fail to read tpmdata.json, error: [{}].", e);
return Err(-1);
}
};

match tpm_data.get_mut(key) {
Some(ptr) => {
*ptr = json!(value);
}
None => {
error!("content field [{}] doesn't exist.", key);
return Err(-1);
}
};

match write_tpm_data(tpm_data) {
Ok(_) => Ok(()),
Err(e) => {
error!("Fail to write data to tpmdata.json, erro[{}].", e);
Err(-1)
}
}
}

/*
* Return: Result wrap TPM data or Error
*
* Read in tpmdata.json file and convert it to a pre-defined struct. Now its
* using the sample tpmdata.json in the crate root directory for testing. The
* format the same as the original python version.
* format the same as the original python version. Result is returned to
* caller for error handling.
*/
fn read_tpm_data() -> Result<TpmData, Box<Error>> {
fn read_tpm_data() -> Result<Value, Box<Error>> {
let file = File::open("tpmdata.json")?;
let data: TpmData = serde_json::from_reader(file)?;
let data: Value = serde_json::from_reader(file)?;
Ok(data)
}

/*
* Input: tpmdata in Value type
* Return: Result wrap success or io Error
*
* Write the tpmdata to tpmdata.json file with result indicating execution
* result. Different implementation than the original python version, which
* changes the global variable tpmdata to local scope variable. Because it
* could read the data before write instead of using a static type to store
* it globally.
*/
fn write_tpm_data(data: Value) -> Result<(), std::io::Error> {
// using flush to ensure all the intermediately buffered contents
// reach their destination
let mut buffer = BufWriter::new(File::create("tpmdata.json")?);
let data_string = serde_json::to_string_pretty(&data)?;
buffer.write(data_string.as_bytes())?;
buffer.flush()?;
Ok(())
}

/*
* input: None
* output: boolean
Expand Down Expand Up @@ -136,8 +202,8 @@ pub fn create_quote(
mut pcrmask: String,
) -> Option<String> {
let quote_path = NamedTempFile::new().unwrap();
let key_handle = get_tpm_metadata("aik_handle".to_string());
let aik_password = get_tpm_metadata("aik_pw".to_string());
let key_handle = get_tpm_metadata_content("aik_handle").unwrap();
let aik_password = get_tpm_metadata_content("aik_pw").unwrap();

if pcrmask == "".to_string() {
pcrmask = EMPTYMASK.to_string();
Expand Down Expand Up @@ -206,9 +272,9 @@ pub fn create_deep_quote(
mut vpcrmask: String,
) -> Option<String> {
let quote_path = NamedTempFile::new().unwrap();
let key_handle = get_tpm_metadata("aik_handle".to_string());
let aik_password = get_tpm_metadata("aik_pw".to_string());
let owner_password = get_tpm_metadata("owner_pw".to_string());
let key_handle = get_tpm_metadata_content("aik_handle").unwrap();
let aik_password = get_tpm_metadata_content("aik_pw").unwrap();
let owner_password = get_tpm_metadata_content("owner_pw").unwrap();

if pcrmask == "".to_string() {
pcrmask = EMPTYMASK.to_string();
Expand Down Expand Up @@ -525,6 +591,53 @@ mod tests {
}
}

#[test]
fn test_get_tpm_metadata_1() {
match set_tpmdata_test() {
Ok(_) => {
// using test tpmdata.json content must present, system won't panic
let remove: &[_] = &['"', ' ', '/'];
let password = get_tpm_metadata_content("aik_handle").unwrap();
assert_eq!(
password.unwrap().trim_matches(remove),
String::from("FB1F19E0")
);
}
Err(code) => assert!(false),
}
}

#[test]
fn test_get_tpm_metadata_2() {
match set_tpmdata_test() {
Ok(_) => match get_tpm_metadata_content("foo") {
Ok(content) => assert_eq!(content, None),
Err(e) => assert!(false),
},
Err(code) => assert!(false),
}
}

#[test]
fn test_write_tpm_metadata() {
match set_tpmdata_test() {
Ok(_) => match set_tpm_metadata_content("owner_pw", "hello") {
Ok(_) => {
// using test tpmdata.json content must present, system won't panic
let remove: &[_] = &['"', ' ', '/'];
let password =
get_tpm_metadata_content("owner_pw").unwrap();
assert_eq!(
password.unwrap().trim_matches(remove),
String::from("hello")
)
}
Err(_) => assert!(false),
},
Err(_) => assert!(false),
}
}

/*
* Input: command name
* Output: checkout command result
Expand All @@ -543,4 +656,17 @@ mod tests {
}
false
}

/*
* copy tpmdata_test.json file to tpmdata.json for testing
*/
fn set_tpmdata_test() -> Result<(), Box<Error>> {
let file = File::open("tpmdata_test.json")?;
let data: Value = serde_json::from_reader(file)?;
let mut buffer = BufWriter::new(File::create("tpmdata.json")?);
let data_string = serde_json::to_string_pretty(&data)?;
buffer.write(data_string.as_bytes())?;
buffer.flush()?;
Ok(())
}
}
10 changes: 9 additions & 1 deletion tpmdata.json
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
{"aik_pw": "QXgMbqSxSuB05MVHO0Ox", "ek": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzLJC3n/KpLjUn3DIRkhw\nUO9igtnCugQ92sAM/hJt7wj8uRDtz5O0mv7aHLmrlKA2XVmPgnInD3WOEVyfYpM3\nRXOftLSDdouB/C5iwqCJRiH+gr012SMDdqJsnWb4ofdPNBgJXRTs6+ztXH8GNO0c\nfqoMJBIBizE3P8kRPcqVGMJSXgkS1p9Otp0w431ckXZwdkoNxuM2GF6ktVfOEdCZ\nr8Idm+qbQaK+Ur57VCB02U49ekGdd1qA76BjmSVyHYPEkce7Jf2ipWK3d/yP0exs\neLKL9rO+Aab2X4/2v2NQPwEj0bz6oEAhvgpaoV0eakN2WiXxTVUG30OvCsRFxvUu\nvwIDAQAB\n-----END PUBLIC KEY-----\n", "owner_pw": "keylime", "aik_handle": "FB1F19E0", "aikmod": "wWnAON9h+AYu4Ee+D5LYhqKYiQpbFqboE4ohGYjy/eIAOJ//TKysXmdraiq9XYqRWXC/+K5kFn+irRc9k1snhX2HIsIxdqJOZvzzbWXlZ4VyPsc18DQvNiabelBSWxX3rcpB01liooclPB+WsDkso0Ay/jwgiJvuEbfACzf4z+noQep4x4ysnPd/lcPnN6+TD7TMaaNrMUxp5o8/cmveIor6BuFf9bgXH58UrA0V2Bejh83eoyQQ1V/TkDBbnov9/FGaMTURGonapIh9jy9KSkmsjFp6LQ/YySIArk6gqRS0fSCp//vX/hTBknpcu6u0CqgEzkBhbGnNa7tMOyo9pQ==", "aikpriv": "AQEAAAASAAAAAAEAAAABAAEAAgAAAAwAAAgAAAAAAgAAAAAAAAAAAAABAMFpwDjfYfgGLuBHvg+S2IaimIkKWxam6BOKIRmI8v3iADif/0ysrF5na2oqvV2KkVlwv/iuZBZ/oq0XPZNbJ4V9hyLCMXaiTmb8821l5WeFcj7HNfA0LzYmm3pQUlsV963KQdNZYqKHJTwflrA5LKNAMv48IIib7hG3wAs3+M/p6EHqeMeMrJz3f5XD5zevkw+0zGmjazFMaeaPP3Jr3iKK+gbhX/W4Fx+fFKwNFdgXo4fN3qMkENVf05AwW56L/fxRmjE1ERqJ2qSIfY8vSkpJrIxaei0P2MkiAK5OoKkUtH0gqf/71/4UwZJ6XLurtAqoBM5AYWxpzWu7TDsqPaUAAAEAI/83lAiEz8a8RmgennBJNUELDu+zTARQxjcaWR95cEIMqYP/2V4IEbpp78o9l3BBYyZWnWEUPvzV8z2XpQJ60zp07mjTKTFwH84nl+NAh0wu/CwCfTaLxS0kty2drLHcr/YRC+3g7vvztpmRz3NfgUYvUsozgakfC3IZYXPY0vPFH8uYWFwSnwG7xPgoamcHct0x48N4ejAWx8492QYNyex07A/wdOTETCO7oMTRXlrK4MijgGJ+odZ7owBWrLXHKTl6A6mqmGCbaLR49xgVNTyjdRyEFitpkRMfm59lwab0Ljin2p6YyzN1i0oONpPL8PHtLz9liubQymK73i1KWg==", "aik": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwWnAON9h+AYu4Ee+D5LY\nhqKYiQpbFqboE4ohGYjy/eIAOJ//TKysXmdraiq9XYqRWXC/+K5kFn+irRc9k1sn\nhX2HIsIxdqJOZvzzbWXlZ4VyPsc18DQvNiabelBSWxX3rcpB01liooclPB+WsDks\no0Ay/jwgiJvuEbfACzf4z+noQep4x4ysnPd/lcPnN6+TD7TMaaNrMUxp5o8/cmve\nIor6BuFf9bgXH58UrA0V2Bejh83eoyQQ1V/TkDBbnov9/FGaMTURGonapIh9jy9K\nSkmsjFp6LQ/YySIArk6gqRS0fSCp//vX/hTBknpcu6u0CqgEzkBhbGnNa7tMOyo9\npQIDAQAB\n-----END PUBLIC KEY-----\n"}
{
"aik": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwWnAON9h+AYu4Ee+D5LY\nhqKYiQpbFqboE4ohGYjy/eIAOJ//TKysXmdraiq9XYqRWXC/+K5kFn+irRc9k1sn\nhX2HIsIxdqJOZvzzbWXlZ4VyPsc18DQvNiabelBSWxX3rcpB01liooclPB+WsDks\no0Ay/jwgiJvuEbfACzf4z+noQep4x4ysnPd/lcPnN6+TD7TMaaNrMUxp5o8/cmve\nIor6BuFf9bgXH58UrA0V2Bejh83eoyQQ1V/TkDBbnov9/FGaMTURGonapIh9jy9K\nSkmsjFp6LQ/YySIArk6gqRS0fSCp//vX/hTBknpcu6u0CqgEzkBhbGnNa7tMOyo9\npQIDAQAB\n-----END PUBLIC KEY-----\n",
"aik_handle": "FB1F19E0",
"aik_pw": "QXgMbqSxSuB05MVHO0Ox",
"aikmod": "wWnAON9h+AYu4Ee+D5LYhqKYiQpbFqboE4ohGYjy/eIAOJ//TKysXmdraiq9XYqRWXC/+K5kFn+irRc9k1snhX2HIsIxdqJOZvzzbWXlZ4VyPsc18DQvNiabelBSWxX3rcpB01liooclPB+WsDkso0Ay/jwgiJvuEbfACzf4z+noQep4x4ysnPd/lcPnN6+TD7TMaaNrMUxp5o8/cmveIor6BuFf9bgXH58UrA0V2Bejh83eoyQQ1V/TkDBbnov9/FGaMTURGonapIh9jy9KSkmsjFp6LQ/YySIArk6gqRS0fSCp//vX/hTBknpcu6u0CqgEzkBhbGnNa7tMOyo9pQ==",
"aikpriv": "AQEAAAASAAAAAAEAAAABAAEAAgAAAAwAAAgAAAAAAgAAAAAAAAAAAAABAMFpwDjfYfgGLuBHvg+S2IaimIkKWxam6BOKIRmI8v3iADif/0ysrF5na2oqvV2KkVlwv/iuZBZ/oq0XPZNbJ4V9hyLCMXaiTmb8821l5WeFcj7HNfA0LzYmm3pQUlsV963KQdNZYqKHJTwflrA5LKNAMv48IIib7hG3wAs3+M/p6EHqeMeMrJz3f5XD5zevkw+0zGmjazFMaeaPP3Jr3iKK+gbhX/W4Fx+fFKwNFdgXo4fN3qMkENVf05AwW56L/fxRmjE1ERqJ2qSIfY8vSkpJrIxaei0P2MkiAK5OoKkUtH0gqf/71/4UwZJ6XLurtAqoBM5AYWxpzWu7TDsqPaUAAAEAI/83lAiEz8a8RmgennBJNUELDu+zTARQxjcaWR95cEIMqYP/2V4IEbpp78o9l3BBYyZWnWEUPvzV8z2XpQJ60zp07mjTKTFwH84nl+NAh0wu/CwCfTaLxS0kty2drLHcr/YRC+3g7vvztpmRz3NfgUYvUsozgakfC3IZYXPY0vPFH8uYWFwSnwG7xPgoamcHct0x48N4ejAWx8492QYNyex07A/wdOTETCO7oMTRXlrK4MijgGJ+odZ7owBWrLXHKTl6A6mqmGCbaLR49xgVNTyjdRyEFitpkRMfm59lwab0Ljin2p6YyzN1i0oONpPL8PHtLz9liubQymK73i1KWg==",
"ek": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzLJC3n/KpLjUn3DIRkhw\nUO9igtnCugQ92sAM/hJt7wj8uRDtz5O0mv7aHLmrlKA2XVmPgnInD3WOEVyfYpM3\nRXOftLSDdouB/C5iwqCJRiH+gr012SMDdqJsnWb4ofdPNBgJXRTs6+ztXH8GNO0c\nfqoMJBIBizE3P8kRPcqVGMJSXgkS1p9Otp0w431ckXZwdkoNxuM2GF6ktVfOEdCZ\nr8Idm+qbQaK+Ur57VCB02U49ekGdd1qA76BjmSVyHYPEkce7Jf2ipWK3d/yP0exs\neLKL9rO+Aab2X4/2v2NQPwEj0bz6oEAhvgpaoV0eakN2WiXxTVUG30OvCsRFxvUu\nvwIDAQAB\n-----END PUBLIC KEY-----\n",
"owner_pw": "keylime"
}
9 changes: 9 additions & 0 deletions tpmdata_test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"aik": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwWnAON9h+AYu4Ee+D5LY\nhqKYiQpbFqboE4ohGYjy/eIAOJ//TKysXmdraiq9XYqRWXC/+K5kFn+irRc9k1sn\nhX2HIsIxdqJOZvzzbWXlZ4VyPsc18DQvNiabelBSWxX3rcpB01liooclPB+WsDks\no0Ay/jwgiJvuEbfACzf4z+noQep4x4ysnPd/lcPnN6+TD7TMaaNrMUxp5o8/cmve\nIor6BuFf9bgXH58UrA0V2Bejh83eoyQQ1V/TkDBbnov9/FGaMTURGonapIh9jy9K\nSkmsjFp6LQ/YySIArk6gqRS0fSCp//vX/hTBknpcu6u0CqgEzkBhbGnNa7tMOyo9\npQIDAQAB\n-----END PUBLIC KEY-----\n",
"aik_handle": "FB1F19E0",
"aik_pw": "QXgMbqSxSuB05MVHO0Ox",
"aikmod": "wWnAON9h+AYu4Ee+D5LYhqKYiQpbFqboE4ohGYjy/eIAOJ//TKysXmdraiq9XYqRWXC/+K5kFn+irRc9k1snhX2HIsIxdqJOZvzzbWXlZ4VyPsc18DQvNiabelBSWxX3rcpB01liooclPB+WsDkso0Ay/jwgiJvuEbfACzf4z+noQep4x4ysnPd/lcPnN6+TD7TMaaNrMUxp5o8/cmveIor6BuFf9bgXH58UrA0V2Bejh83eoyQQ1V/TkDBbnov9/FGaMTURGonapIh9jy9KSkmsjFp6LQ/YySIArk6gqRS0fSCp//vX/hTBknpcu6u0CqgEzkBhbGnNa7tMOyo9pQ==",
"aikpriv": "AQEAAAASAAAAAAEAAAABAAEAAgAAAAwAAAgAAAAAAgAAAAAAAAAAAAABAMFpwDjfYfgGLuBHvg+S2IaimIkKWxam6BOKIRmI8v3iADif/0ysrF5na2oqvV2KkVlwv/iuZBZ/oq0XPZNbJ4V9hyLCMXaiTmb8821l5WeFcj7HNfA0LzYmm3pQUlsV963KQdNZYqKHJTwflrA5LKNAMv48IIib7hG3wAs3+M/p6EHqeMeMrJz3f5XD5zevkw+0zGmjazFMaeaPP3Jr3iKK+gbhX/W4Fx+fFKwNFdgXo4fN3qMkENVf05AwW56L/fxRmjE1ERqJ2qSIfY8vSkpJrIxaei0P2MkiAK5OoKkUtH0gqf/71/4UwZJ6XLurtAqoBM5AYWxpzWu7TDsqPaUAAAEAI/83lAiEz8a8RmgennBJNUELDu+zTARQxjcaWR95cEIMqYP/2V4IEbpp78o9l3BBYyZWnWEUPvzV8z2XpQJ60zp07mjTKTFwH84nl+NAh0wu/CwCfTaLxS0kty2drLHcr/YRC+3g7vvztpmRz3NfgUYvUsozgakfC3IZYXPY0vPFH8uYWFwSnwG7xPgoamcHct0x48N4ejAWx8492QYNyex07A/wdOTETCO7oMTRXlrK4MijgGJ+odZ7owBWrLXHKTl6A6mqmGCbaLR49xgVNTyjdRyEFitpkRMfm59lwab0Ljin2p6YyzN1i0oONpPL8PHtLz9liubQymK73i1KWg==",
"ek": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzLJC3n/KpLjUn3DIRkhw\nUO9igtnCugQ92sAM/hJt7wj8uRDtz5O0mv7aHLmrlKA2XVmPgnInD3WOEVyfYpM3\nRXOftLSDdouB/C5iwqCJRiH+gr012SMDdqJsnWb4ofdPNBgJXRTs6+ztXH8GNO0c\nfqoMJBIBizE3P8kRPcqVGMJSXgkS1p9Otp0w431ckXZwdkoNxuM2GF6ktVfOEdCZ\nr8Idm+qbQaK+Ur57VCB02U49ekGdd1qA76BjmSVyHYPEkce7Jf2ipWK3d/yP0exs\neLKL9rO+Aab2X4/2v2NQPwEj0bz6oEAhvgpaoV0eakN2WiXxTVUG30OvCsRFxvUu\nvwIDAQAB\n-----END PUBLIC KEY-----\n",
"owner_pw": "keylime"
}

0 comments on commit 08c42e5

Please sign in to comment.