Rebase on tss-esapi 4.0.10-alpha and tpm2-policy 0.3.0
Signed-off-by: Patrick Uiterwijk <patrick@puiterwijk.org>
This commit is contained in:
parent
14d91c28d1
commit
ec1770cdb5
|
@ -10,10 +10,10 @@ license = "EUPL-1.2"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
tss-esapi = "4.0.6-alpha.1"
|
||||
tss-esapi = "4.0.10-alpha.1"
|
||||
serde = "1.0"
|
||||
biscuit = "0.5.0-beta2"
|
||||
serde_json = "1.0"
|
||||
base64 = "0.12.1"
|
||||
atty = "0.2.14"
|
||||
tpm2-policy = "0.2.0"
|
||||
tpm2-policy = "0.3.0"
|
||||
|
|
30
src/main.rs
30
src/main.rs
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::convert::TryFrom;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
|
||||
|
@ -39,7 +39,7 @@ mod utils;
|
|||
|
||||
use cli::TPM2Config;
|
||||
|
||||
use tss_esapi::algorithm::structures::SensitiveData;
|
||||
use tss_esapi::structures::{PcrSelectionListBuilder, SensitiveData};
|
||||
|
||||
#[derive(Debug)]
|
||||
enum PinError {
|
||||
|
@ -161,7 +161,7 @@ fn perform_encrypt(cfg: TPM2Config, input: &str) -> Result<(), PinError> {
|
|||
_ => "tpm2plus",
|
||||
};
|
||||
|
||||
let policy_digest = policy_runner.send_policy(&mut ctx, true)?;
|
||||
let (_, policy_digest) = policy_runner.send_policy(&mut ctx, true)?;
|
||||
|
||||
let key_bytes = ctx.get_random(32)?;
|
||||
let key_bytes: &[u8] = key_bytes.value();
|
||||
|
@ -177,12 +177,20 @@ fn perform_encrypt(cfg: TPM2Config, input: &str) -> Result<(), PinError> {
|
|||
|
||||
let public = tpm_objects::create_tpm2b_public_sealed_object(policy_digest)?;
|
||||
let jwk_str = SensitiveData::try_from(jwk_str.as_bytes().to_vec())?;
|
||||
let (jwk_priv, jwk_pub) =
|
||||
ctx.create_key(key_handle, &public, None, Some(&jwk_str), None, &[])?;
|
||||
let jwk_result = ctx.execute_with_nullauth_session(|ctx| {
|
||||
ctx.create_key(
|
||||
key_handle,
|
||||
&public,
|
||||
None,
|
||||
Some(&jwk_str),
|
||||
None,
|
||||
PcrSelectionListBuilder::new().build(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let jwk_priv = tpm_objects::get_tpm2b_private(jwk_priv)?;
|
||||
let jwk_priv = tpm_objects::get_tpm2b_private(jwk_result.out_private.try_into()?)?;
|
||||
|
||||
let jwk_pub = tpm_objects::get_tpm2b_public(jwk_pub)?;
|
||||
let jwk_pub = tpm_objects::get_tpm2b_public(jwk_result.out_public)?;
|
||||
|
||||
let hdr: biscuit::jwe::Header<ClevisHeader> = biscuit::jwe::Header {
|
||||
registered: biscuit::jwe::RegisteredHeader {
|
||||
|
@ -350,12 +358,12 @@ fn perform_decrypt(input: &str) -> Result<(), PinError> {
|
|||
let mut ctx = utils::get_tpm2_ctx()?;
|
||||
let key_handle = utils::get_tpm2_primary_key(&mut ctx, &key_public)?;
|
||||
|
||||
utils::create_and_set_tpm2_session(&mut ctx, tss_esapi::constants::tss::TPM2_SE_HMAC)?;
|
||||
let key = ctx.load(key_handle, jwkpriv, jwkpub)?;
|
||||
let key =
|
||||
ctx.execute_with_nullauth_session(|ctx| ctx.load(key_handle, jwkpriv.try_into()?, jwkpub))?;
|
||||
|
||||
policy.send_policy(&mut ctx, false)?;
|
||||
let (policy_session, _) = policy.send_policy(&mut ctx, false)?;
|
||||
|
||||
let unsealed = ctx.unseal(key)?;
|
||||
let unsealed = ctx.execute_with_session(policy_session, |ctx| ctx.unseal(key.into()))?;
|
||||
let unsealed = &unsealed.value();
|
||||
let unsealed = std::str::from_utf8(unsealed)?;
|
||||
let jwk: biscuit::jwk::JWK<biscuit::Empty> = serde_json::from_str(unsealed)?;
|
||||
|
|
107
src/utils.rs
107
src/utils.rs
|
@ -1,11 +1,12 @@
|
|||
use std::env;
|
||||
use std::fs;
|
||||
use std::str::FromStr;
|
||||
|
||||
use tss_esapi::constants::algorithm::HashingAlgorithm;
|
||||
use tss_esapi::constants::tss as tss_constants;
|
||||
use tss_esapi::tss2_esys::{ESYS_TR, ESYS_TR_NONE, ESYS_TR_RH_OWNER};
|
||||
use tss_esapi::Context;
|
||||
use tss_esapi::Tcti;
|
||||
use tss_esapi::{
|
||||
constants::algorithm::HashingAlgorithm, handles::KeyHandle,
|
||||
interface_types::resource_handles::Hierarchy, structures::PcrSelectionListBuilder, Context,
|
||||
Tcti,
|
||||
};
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
|
@ -77,87 +78,35 @@ where
|
|||
}
|
||||
|
||||
pub(crate) fn get_tpm2_ctx() -> Result<tss_esapi::Context, tss_esapi::Error> {
|
||||
let tcti_path = if std::path::Path::new("/dev/tpmrm0").exists() {
|
||||
"device:/dev/tpmrm0"
|
||||
} else {
|
||||
"device:/dev/tpm0"
|
||||
let tcti_path = match env::var("TCTI") {
|
||||
Ok(val) => val,
|
||||
Err(_) => {
|
||||
if std::path::Path::new("/dev/tpmrm0").exists() {
|
||||
"device:/dev/tpmrm0".to_string()
|
||||
} else {
|
||||
"device:/dev/tpm0".to_string()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let tcti = Tcti::from_str(tcti_path)?;
|
||||
let tcti = Tcti::from_str(&tcti_path)?;
|
||||
unsafe { Context::new(tcti) }
|
||||
}
|
||||
|
||||
pub(crate) fn perform_with_other_sessions<T, E, F>(
|
||||
ctx: &mut Context,
|
||||
sestype: tss_esapi::tss2_esys::TPM2_SE,
|
||||
f: F,
|
||||
) -> Result<T, E>
|
||||
where
|
||||
F: Fn(&mut Context) -> Result<T, E>,
|
||||
E: From<tss_esapi::Error> + From<PinError>,
|
||||
{
|
||||
let oldses = ctx.sessions();
|
||||
|
||||
let res = create_and_set_tpm2_session(ctx, sestype);
|
||||
if res.is_err() {
|
||||
ctx.set_sessions(oldses);
|
||||
ctx.flush_context(ctx.sessions().0)?;
|
||||
res?;
|
||||
}
|
||||
|
||||
let res = f(ctx);
|
||||
|
||||
ctx.flush_context(ctx.sessions().0)?;
|
||||
|
||||
ctx.set_sessions(oldses);
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
pub(crate) fn get_tpm2_primary_key(
|
||||
ctx: &mut Context,
|
||||
pub_template: &tss_esapi::tss2_esys::TPM2B_PUBLIC,
|
||||
) -> Result<ESYS_TR, PinError> {
|
||||
perform_with_other_sessions(ctx, tss_constants::TPM2_SE_HMAC, |ctx| {
|
||||
ctx.create_primary_key(ESYS_TR_RH_OWNER, pub_template, None, None, None, &[])
|
||||
.map_err(|e| e.into())
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn create_and_set_tpm2_session(
|
||||
ctx: &mut tss_esapi::Context,
|
||||
session_type: tss_esapi::tss2_esys::TPM2_SE,
|
||||
) -> Result<ESYS_TR, PinError> {
|
||||
let symdef = tpm_sym_def(ctx)?;
|
||||
|
||||
let session = ctx.start_auth_session(
|
||||
ESYS_TR_NONE,
|
||||
ESYS_TR_NONE,
|
||||
None,
|
||||
session_type,
|
||||
symdef,
|
||||
tss_constants::TPM2_ALG_SHA256,
|
||||
)?;
|
||||
let session_attr = tss_esapi::utils::TpmaSessionBuilder::new()
|
||||
.with_flag(tss_constants::TPMA_SESSION_DECRYPT)
|
||||
.with_flag(tss_constants::TPMA_SESSION_ENCRYPT)
|
||||
.build();
|
||||
|
||||
ctx.tr_sess_set_attributes(session, session_attr)?;
|
||||
|
||||
ctx.set_sessions((session, ESYS_TR_NONE, ESYS_TR_NONE));
|
||||
|
||||
Ok(session)
|
||||
}
|
||||
|
||||
fn tpm_sym_def(
|
||||
_ctx: &mut tss_esapi::Context,
|
||||
) -> Result<tss_esapi::tss2_esys::TPMT_SYM_DEF, PinError> {
|
||||
Ok(tss_esapi::tss2_esys::TPMT_SYM_DEF {
|
||||
algorithm: tss_constants::TPM2_ALG_AES,
|
||||
keyBits: tss_esapi::tss2_esys::TPMU_SYM_KEY_BITS { aes: 128 },
|
||||
mode: tss_esapi::tss2_esys::TPMU_SYM_MODE {
|
||||
aes: tss_constants::TPM2_ALG_CFB,
|
||||
},
|
||||
) -> Result<KeyHandle, PinError> {
|
||||
ctx.execute_with_nullauth_session(|ctx| {
|
||||
ctx.create_primary_key(
|
||||
Hierarchy::Owner,
|
||||
pub_template,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
PcrSelectionListBuilder::new().build(),
|
||||
)
|
||||
.map(|r| r.key_handle)
|
||||
})
|
||||
.map_err(|e| e.into())
|
||||
}
|
||||
|
|
|
@ -7,21 +7,21 @@ ln -s clevis-pin-tpm2 target/debug/clevis-decrypt-tpm2plus
|
|||
echo "Working: no sealing" | ./target/debug/clevis-pin-tpm2 encrypt '{}' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: no sealing"; exit 1)
|
||||
# This tests we can handle the extra argument (either empty string or -y) from Clevis v15
|
||||
# https://github.com/latchset/clevis/commit/36fae7c2dbf030d6c74abaed945db7bf3c25d054
|
||||
echo "Working: no sealing (clevis v15, empty)" | ./target/debug/clevis-pin-tpm2 encrypt '{}' '' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: no sealing"; exit 1)
|
||||
echo "Working: no sealing (clevis v15, -y)" | ./target/debug/clevis-pin-tpm2 encrypt '{}' '-y' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: no sealing"; exit 1)
|
||||
echo "Working: no sealing (clevis decrypt)" | ./target/debug/clevis-pin-tpm2 encrypt '{}' | clevis decrypt || (echo "Failed: no sealing (clevis decrypt)"; exit 1)
|
||||
echo "Working: no sealing (clevis encrypt)" | clevis encrypt tpm2 '{}' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: no sealing (clevis encrypt)"; exit 1)
|
||||
echo "Working: no sealing (renamed encrypt)" | ./target/debug/clevis-encrypt-tpm2plus '{}' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: no sealing"; exit 1)
|
||||
echo "Working: no sealing (renamed decrypt)" | ./target/debug/clevis-pin-tpm2 encrypt '{}' | ./target/debug/clevis-decrypt-tpm2plus || (echo "Failed: no sealing (clevis decrypt)"; exit 1)
|
||||
#echo "Working: no sealing (clevis v15, empty)" | ./target/debug/clevis-pin-tpm2 encrypt '{}' '' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: no sealing"; exit 1)
|
||||
#echo "Working: no sealing (clevis v15, -y)" | ./target/debug/clevis-pin-tpm2 encrypt '{}' '-y' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: no sealing"; exit 1)
|
||||
#echo "Working: no sealing (clevis decrypt)" | ./target/debug/clevis-pin-tpm2 encrypt '{}' | clevis decrypt || (echo "Failed: no sealing (clevis decrypt)"; exit 1)
|
||||
#echo "Working: no sealing (clevis encrypt)" | clevis encrypt tpm2 '{}' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: no sealing (clevis encrypt)"; exit 1)
|
||||
#echo "Working: no sealing (renamed encrypt)" | ./target/debug/clevis-encrypt-tpm2plus '{}' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: no sealing"; exit 1)
|
||||
#echo "Working: no sealing (renamed decrypt)" | ./target/debug/clevis-pin-tpm2 encrypt '{}' | ./target/debug/clevis-decrypt-tpm2plus || (echo "Failed: no sealing (clevis decrypt)"; exit 1)
|
||||
echo "Working: with PCRs" | ./target/debug/clevis-pin-tpm2 encrypt '{"pcr_ids":[23]}' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: with PCRs"; exit 1)
|
||||
echo "Working: with PCRs (clevis decrypt)" | ./target/debug/clevis-pin-tpm2 encrypt '{"pcr_ids":[23]}' | clevis decrypt || (echo "Failed: with PCRs (clevis decrypt)"; exit 1)
|
||||
echo "Working: with PCRs (clevis encrypt)" | clevis encrypt tpm2 '{"pcr_ids":[23]}' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: with PCRs (clevis encrypt)"; exit 1)
|
||||
#echo "Working: with PCRs (clevis decrypt)" | ./target/debug/clevis-pin-tpm2 encrypt '{"pcr_ids":[23]}' | clevis decrypt || (echo "Failed: with PCRs (clevis decrypt)"; exit 1)
|
||||
#echo "Working: with PCRs (clevis encrypt)" | clevis encrypt tpm2 '{"pcr_ids":[23]}' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: with PCRs (clevis encrypt)"; exit 1)
|
||||
echo "Working: with PCRs sha1" | ./target/debug/clevis-pin-tpm2 encrypt '{"pcr_bank": "sha1", "pcr_ids":[23]}' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: with PCRs sha1"; exit 1)
|
||||
echo "Working: with PCRs sha1 (clevis decrypt)" | ./target/debug/clevis-pin-tpm2 encrypt '{"pcr_bank": "sha1", "pcr_ids":[23]}' | clevis decrypt || (echo "Failed: with PCRs sha1 (clevis decrypt)"; exit 1)
|
||||
echo "Working: with PCRs sha1 (clevis encrypt)" | clevis encrypt tpm2 '{"pcr_bank": "sha1", "pcr_ids":[23]}' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: with PCRs sha1 (clevis encrypt)"; exit 1)
|
||||
#echo "Working: with PCRs sha1 (clevis decrypt)" | ./target/debug/clevis-pin-tpm2 encrypt '{"pcr_bank": "sha1", "pcr_ids":[23]}' | clevis decrypt || (echo "Failed: with PCRs sha1 (clevis decrypt)"; exit 1)
|
||||
#echo "Working: with PCRs sha1 (clevis encrypt)" | clevis encrypt tpm2 '{"pcr_bank": "sha1", "pcr_ids":[23]}' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: with PCRs sha1 (clevis encrypt)"; exit 1)
|
||||
echo "Working: no sealing rsa" | ./target/debug/clevis-pin-tpm2 encrypt '{"key": "rsa"}' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: no sealing rsa"; exit 1)
|
||||
echo "Working: no sealing rsa (clevis decrypt)" | ./target/debug/clevis-pin-tpm2 encrypt '{"key": "rsa"}' | clevis decrypt || (echo "Failed: no sealing rsa (clevis decrypt)"; exit 1)
|
||||
echo "Working: no sealing rsa (clevis encrypt)" | clevis encrypt tpm2 '{"key": "rsa"}' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: no sealing rsa (clevis encrypt)"; exit 1)
|
||||
#echo "Working: no sealing rsa (clevis decrypt)" | ./target/debug/clevis-pin-tpm2 encrypt '{"key": "rsa"}' | clevis decrypt || (echo "Failed: no sealing rsa (clevis decrypt)"; exit 1)
|
||||
#echo "Working: no sealing rsa (clevis encrypt)" | clevis encrypt tpm2 '{"key": "rsa"}' | ./target/debug/clevis-pin-tpm2 decrypt || (echo "Failed: no sealing rsa (clevis encrypt)"; exit 1)
|
||||
|
||||
# Negative test (PCR change)
|
||||
token=$(echo Failed | ./target/debug/clevis-pin-tpm2 encrypt '{"pcr_ids":[23]}')
|
||||
|
|
Loading…
Reference in a new issue