tss-keyfile 0.1.3

TPM2 TSS Keyfile Types and PEM/DER codec
Documentation
use rasn::types::ObjectIdentifier;
use tss_keyfile::{
    Error, OID_TPMKEY_IMPORTABLE, OID_TPMKEY_LOADABLE, OID_TPMKEY_SEALED, TPMKey, TPMKeyType,
};

#[test]
fn test_tpm_key_type_constructors() {
    let loadable = TPMKeyType::new_loadable();
    let importable = TPMKeyType::new_importable();
    let sealed = TPMKeyType::new_sealed();

    assert_eq!(
        loadable.as_ref(),
        &ObjectIdentifier::from(OID_TPMKEY_LOADABLE)
    );
    assert_eq!(
        importable.as_ref(),
        &ObjectIdentifier::from(OID_TPMKEY_IMPORTABLE)
    );
    assert_eq!(sealed.as_ref(), &ObjectIdentifier::from(OID_TPMKEY_SEALED));
}

#[test]
fn test_tpm_key_type_validation() {
    let loadable = TPMKeyType::new_loadable();
    let importable = TPMKeyType::new_importable();
    let sealed = TPMKeyType::new_sealed();

    assert!(loadable.validate());
    assert!(importable.validate());
    assert!(sealed.validate());
}

#[test]
fn test_tpm_key_constructors() {
    let pubkey = vec![0x01, 0x02, 0x03];
    let privkey = vec![0x04, 0x05, 0x06];
    let parent = 0x40000001;

    let loadable = TPMKey::new_loadable(parent, &pubkey, &privkey);
    assert!(loadable.is_loadable());
    assert!(!loadable.is_importable());
    assert!(!loadable.is_sealed());
    assert_eq!(loadable.parent, parent);
    assert_eq!(loadable.pubkey.as_ref(), &pubkey);
    assert_eq!(loadable.privkey.as_ref(), &privkey);

    let importable = TPMKey::new_importable(parent, &pubkey, &privkey);
    assert!(importable.is_importable());
    assert!(!importable.is_loadable());
    assert!(!importable.is_sealed());

    let sealed = TPMKey::new_sealed(parent, &pubkey, &privkey);
    assert!(sealed.is_sealed());
    assert!(!sealed.is_loadable());
    assert!(!sealed.is_importable());
}

#[test]
fn test_tpm_key_validation() {
    let pubkey = vec![0x01, 0x02, 0x03];
    let privkey = vec![0x04, 0x05, 0x06];

    // Valid permanent handle
    let key = TPMKey::new_loadable(0x40000001, &pubkey, &privkey);
    assert!(key.validate().is_ok());

    // Valid persistent handle
    let key = TPMKey::new_loadable(0x81000001, &pubkey, &privkey);
    assert!(key.validate().is_ok());

    // Valid but discouraged volatile handle
    let key = TPMKey::new_loadable(0x80000001, &pubkey, &privkey);
    assert!(key.validate().is_ok());

    // Invalid unknown handle
    let key = TPMKey::new_loadable(0x12345678, &pubkey, &privkey);
    assert!(matches!(key.validate(), Err(Error::InvalidParentHandle(_))));
}

#[test]
fn test_secret_validation() {
    let pubkey = vec![0x01, 0x02, 0x03];
    let privkey = vec![0x04, 0x05, 0x06];
    let parent = 0x40000001;

    // Loadable key should not have secret
    let mut key = TPMKey::new_loadable(parent, &pubkey, &privkey);
    key.secret = Some(vec![0x07, 0x08].into());
    assert!(matches!(key.validate(), Err(Error::UnexpectedSecret)));

    // Importable key should have secret
    let key = TPMKey::new_importable(parent, &pubkey, &privkey);
    assert!(matches!(key.validate(), Err(Error::MissingSecret)));

    // Importable key with secret should be valid
    let mut key = TPMKey::new_importable(parent, &pubkey, &privkey);
    key.secret = Some(vec![0x07, 0x08].into());
    assert!(key.validate().is_ok());
}

#[test]
fn test_requires_auth() {
    let pubkey = vec![0x01, 0x02, 0x03];
    let privkey = vec![0x04, 0x05, 0x06];
    let parent = 0x40000001;

    let mut key = TPMKey::new_loadable(parent, &pubkey, &privkey);

    // Default should require auth
    assert!(key.requires_auth());

    // Explicitly set to not require auth
    key.empty_auth = Some(true);
    assert!(!key.requires_auth());

    // Explicitly set to require auth
    key.empty_auth = Some(false);
    assert!(key.requires_auth());
}