Merge "Keystore 2.0 permissions.rs: Use generated aidl types."
This commit is contained in:
commit
21e53ab0ff
2 changed files with 192 additions and 134 deletions
|
@ -18,6 +18,7 @@ rust_library {
|
|||
srcs: ["src/lib.rs"],
|
||||
|
||||
rustlibs: [
|
||||
"libandroid_security_keystore2",
|
||||
"libanyhow",
|
||||
"libandroid_hardware_keymint",
|
||||
"libkeystore_aidl_generated",
|
||||
|
@ -39,6 +40,7 @@ rust_test {
|
|||
auto_gen_config: true,
|
||||
rustlibs: [
|
||||
"libandroid_logger",
|
||||
"libandroid_security_keystore2",
|
||||
"libanyhow",
|
||||
"libandroid_hardware_keymint",
|
||||
"libkeystore_aidl_generated",
|
||||
|
|
|
@ -18,7 +18,9 @@
|
|||
//! It also provides KeystorePerm and KeyPerm as convenience wrappers for the SELinux permission
|
||||
//! defined by keystore2 and keystore2_key respectively.
|
||||
|
||||
use keystore_aidl_generated as aidl;
|
||||
use android_security_keystore2::aidl::android::security::keystore2::KeyPermission;
|
||||
|
||||
use android_security_keystore2::aidl::android::security::keystore2::KeyDescriptor::KeyDescriptor;
|
||||
|
||||
use std::cmp::PartialEq;
|
||||
use std::convert::From;
|
||||
|
@ -49,17 +51,25 @@ fn lookup_keystore2_key_context(namespace: i64) -> anyhow::Result<selinux::Conte
|
|||
KEYSTORE2_KEY_LABEL_BACKEND.lookup(&namespace.to_string())
|
||||
}
|
||||
|
||||
/// The below example wraps the enum MyPermission in the tuple struct `MyPerm` and implements
|
||||
/// * `From<i32> for `MyPerm`, where each unknown numeric value is mapped to the given default,
|
||||
/// here `None`
|
||||
/// * `Into<MyPermission> for `MyPerm`
|
||||
/// * `MyPerm::foo()` and `MyPerm::bar()` which construct MyPerm instances representing
|
||||
/// `MyPermission::Foo` and `MyPermission::Bar` respectively.
|
||||
/// * `MyPerm.to_selinux(&self)`, which returns the selinux string representation of the
|
||||
/// ## Background
|
||||
///
|
||||
/// AIDL enums are represented as constants of the form:
|
||||
/// ```
|
||||
/// mod EnumName {
|
||||
/// pub type EnumName = i32;
|
||||
/// pub const Variant1: EnumName = <value1>;
|
||||
/// pub const Variant2: EnumName = <value2>;
|
||||
/// ...
|
||||
/// }
|
||||
///```
|
||||
/// This macro wraps the enum in a new type, e.g., `MyPerm` and maps each variant to an SELinux
|
||||
/// permission while providing the following interface:
|
||||
/// * From<EnumName> and Into<EnumName> are implemented. Where the implementation of From maps
|
||||
/// any variant not specified to the default.
|
||||
/// * Every variant has a constructor with a name corresponding to its lower case SELinux string
|
||||
/// representation.
|
||||
/// * `MyPerm.to_selinux(&self)` returns the SELinux string representation of the
|
||||
/// represented permission.
|
||||
/// * Tests in the given test namespace for each permision that check that the numeric
|
||||
/// representations of MyPermission and MyPerm match. (TODO replace with static assert if
|
||||
/// they become available.)
|
||||
///
|
||||
/// ## Special behavior
|
||||
/// If the keyword `use` appears as an selinux name `use_` is used as identifier for the
|
||||
|
@ -68,85 +78,78 @@ fn lookup_keystore2_key_context(namespace: i64) -> anyhow::Result<selinux::Conte
|
|||
///
|
||||
/// ## Example
|
||||
/// ```
|
||||
/// #[i32]
|
||||
/// enum MyPermission {
|
||||
/// None = 0,
|
||||
/// Foo = 1,
|
||||
/// Bar = 2,
|
||||
/// }
|
||||
///
|
||||
/// implement_permission!(
|
||||
/// /// MyPerm documentation.
|
||||
/// #[derive(Clone, Copy, Debug, PartialEq)]
|
||||
/// MyPermission as MyPerm with default (None = 0, none)
|
||||
/// and test namespace my_perm_tests {
|
||||
/// Foo = 1, selinux name: foo;
|
||||
/// Bar = 2, selinux name: bar;
|
||||
/// MyPerm from EnumName with default (None, none) {}
|
||||
/// Variant1, selinux name: variant1;
|
||||
/// Variant2, selinux name: variant1;
|
||||
/// }
|
||||
/// );
|
||||
/// ```
|
||||
macro_rules! implement_permission {
|
||||
macro_rules! implement_permission_aidl {
|
||||
// This rule provides the public interface of the macro. And starts the preprocessing
|
||||
// recursion (see below).
|
||||
($(#[$m:meta])* $t:ty as $name:ident with default ($($def:tt)*)
|
||||
and test namespace $tn:ident { $($element:tt)* })
|
||||
($(#[$m:meta])* $name:ident from $aidl_name:ident with default ($($def:tt)*)
|
||||
{ $($element:tt)* })
|
||||
=> {
|
||||
implement_permission!(@replace_use $($m)*, $t, $name, $tn, ($($def)*), [] , $($element)*);
|
||||
implement_permission_aidl!(@replace_use $($m)*, $name, $aidl_name, ($($def)*), [],
|
||||
$($element)*);
|
||||
};
|
||||
|
||||
|
||||
// The following three rules recurse through the elements of the form
|
||||
// `<enum variant> = <integer_literal>, selinux name: <selinux_name>;`
|
||||
// `<enum variant>, selinux name: <selinux_name>;`
|
||||
// preprocessing the input.
|
||||
|
||||
// The first rule terminates the recursion and passes the processed arguments to the final
|
||||
// rule that spills out the implementation.
|
||||
(@replace_use $($m:meta)*, $t:ty, $name:ident, $tn:ident, ($($def:tt)*), [$($out:tt)*], ) => {
|
||||
implement_permission!(@end $($m)*, $t, $name, $tn, ($($def)*) { $($out)* } );
|
||||
(@replace_use $($m:meta)*, $name:ident, $aidl_name:ident, ($($def:tt)*), [$($out:tt)*], ) => {
|
||||
implement_permission_aidl!(@end $($m)*, $name, $aidl_name, ($($def)*) { $($out)* } );
|
||||
};
|
||||
|
||||
// The second rule is triggered if the selinux name of an element is literally `use`.
|
||||
// It produces the tuple `<enum variant> = <integer_literal>, use_, use;`
|
||||
// It produces the tuple `<enum variant>, use_, use;`
|
||||
// and appends it to the out list.
|
||||
(@replace_use $($m:meta)*, $t:ty, $name:ident, $tn:ident, ($($def:tt)*), [$($out:tt)*],
|
||||
$e_name:ident = $e_val:expr, selinux name: use; $($element:tt)*)
|
||||
(@replace_use $($m:meta)*, $name:ident, $aidl_name:ident, ($($def:tt)*), [$($out:tt)*],
|
||||
$e_name:ident, selinux name: use; $($element:tt)*)
|
||||
=> {
|
||||
implement_permission!(@replace_use $($m)*, $t, $name, $tn, ($($def)*),
|
||||
[$($out)* $e_name = $e_val, use_, use;], $($element)*);
|
||||
implement_permission_aidl!(@replace_use $($m)*, $name, $aidl_name, ($($def)*),
|
||||
[$($out)* $e_name, use_, use;], $($element)*);
|
||||
};
|
||||
|
||||
// The third rule is the default rule which replaces every input tuple with
|
||||
// `<enum variant> = <integer_literal>, <selinux_name>, <selinux_name>;`
|
||||
// `<enum variant>, <selinux_name>, <selinux_name>;`
|
||||
// and appends the result to the out list.
|
||||
(@replace_use $($m:meta)*, $t:ty, $name:ident, $tn:ident, ($($def:tt)*), [$($out:tt)*],
|
||||
$e_name:ident = $e_val:expr, selinux name: $e_str:ident; $($element:tt)*)
|
||||
(@replace_use $($m:meta)*, $name:ident, $aidl_name:ident, ($($def:tt)*), [$($out:tt)*],
|
||||
$e_name:ident, selinux name: $e_str:ident; $($element:tt)*)
|
||||
=> {
|
||||
implement_permission!(@replace_use $($m)*, $t, $name, $tn, ($($def)*),
|
||||
[$($out)* $e_name = $e_val, $e_str, $e_str;], $($element)*);
|
||||
implement_permission_aidl!(@replace_use $($m)*, $name, $aidl_name, ($($def)*),
|
||||
[$($out)* $e_name, $e_str, $e_str;], $($element)*);
|
||||
};
|
||||
|
||||
(@end $($m:meta)*, $t:ty, $name:ident, $tn:ident,
|
||||
($def_name:ident = $def:expr, $def_selinux_name:ident) {
|
||||
$($element_name:ident = $element_val:expr, $element_identifier:ident,
|
||||
(@end $($m:meta)*, $name:ident, $aidl_name:ident,
|
||||
($def_name:ident, $def_selinux_name:ident) {
|
||||
$($element_name:ident, $element_identifier:ident,
|
||||
$selinux_name:ident;)*
|
||||
})
|
||||
=>
|
||||
{
|
||||
$(#[$m])*
|
||||
pub struct $name($t);
|
||||
pub struct $name(pub $aidl_name::$aidl_name);
|
||||
|
||||
impl From<i32> for $name {
|
||||
fn from (p: i32) -> Self {
|
||||
impl From<$aidl_name::$aidl_name> for $name {
|
||||
fn from (p: $aidl_name::$aidl_name) -> Self {
|
||||
match p {
|
||||
$def => Self(<$t>::$def_name),
|
||||
$($element_val => Self(<$t>::$element_name),)*
|
||||
_ => Self(<$t>::$def_name),
|
||||
$aidl_name::$def_name => Self($aidl_name::$def_name),
|
||||
$($aidl_name::$element_name => Self($aidl_name::$element_name),)*
|
||||
_ => Self($aidl_name::$def_name),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<$t> for $name {
|
||||
fn into(self) -> $t {
|
||||
impl Into<$aidl_name::$aidl_name> for $name {
|
||||
fn into(self) -> $aidl_name::$aidl_name {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
@ -156,39 +159,23 @@ macro_rules! implement_permission {
|
|||
/// `selinux::check_access`.
|
||||
pub fn to_selinux(&self) -> &'static str {
|
||||
match self {
|
||||
Self(<$t>::$def_name) => stringify!($def_selinux_name),
|
||||
$(Self(<$t>::$element_name) => stringify!($selinux_name),)*
|
||||
Self($aidl_name::$def_name) => stringify!($def_selinux_name),
|
||||
$(Self($aidl_name::$element_name) => stringify!($selinux_name),)*
|
||||
_ => stringify!($def_selinux_name),
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates an instance representing a permission with the same name.
|
||||
pub const fn $def_selinux_name() -> Self { Self(<$t>::$def_name) }
|
||||
pub const fn $def_selinux_name() -> Self { Self($aidl_name::$def_name) }
|
||||
$(
|
||||
/// Creates an instance representing a permission with the same name.
|
||||
pub const fn $element_identifier() -> Self { Self(<$t>::$element_name) }
|
||||
)*
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod $tn {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn $def_selinux_name() {
|
||||
assert_eq!($name::$def_selinux_name(), (<$t>::$def_name as i32).into());
|
||||
}
|
||||
$(
|
||||
#[test]
|
||||
fn $element_identifier() {
|
||||
assert_eq!($name::$element_identifier(), (<$t>::$element_name as i32).into());
|
||||
}
|
||||
pub const fn $element_identifier() -> Self { Self($aidl_name::$element_name) }
|
||||
)*
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
implement_permission!(
|
||||
implement_permission_aidl!(
|
||||
/// KeyPerm provides a convenient abstraction from the SELinux class `keystore2_key`.
|
||||
/// At the same time it maps `KeyPermissions` from the Keystore 2.0 AIDL Grant interface to
|
||||
/// the SELinux permissions. With the implement_permission macro, we conveniently
|
||||
|
@ -204,56 +191,113 @@ implement_permission!(
|
|||
/// KeyPerm::get_info().to_selinux());
|
||||
/// ```
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
aidl::KeyPermission as KeyPerm with default (None = 0, none)
|
||||
and test namespace key_perm_tests {
|
||||
Delete = 1, selinux name: delete;
|
||||
GenUniqueId = 2, selinux name: gen_unique_id;
|
||||
GetInfo = 4, selinux name: get_info;
|
||||
Grant = 8, selinux name: grant;
|
||||
List = 0x10, selinux name: list;
|
||||
ManageBlob = 0x20, selinux name: manage_blob;
|
||||
Rebind = 0x40, selinux name: rebind;
|
||||
ReqForcedOp = 0x80, selinux name: req_forced_op;
|
||||
Update = 0x100, selinux name: update;
|
||||
Use = 0x200, selinux name: use;
|
||||
UseDevId = 0x400, selinux name: use_dev_id;
|
||||
KeyPerm from KeyPermission with default (None, none) {
|
||||
Delete, selinux name: delete;
|
||||
GenUniqueId, selinux name: gen_unique_id;
|
||||
GetInfo, selinux name: get_info;
|
||||
Grant, selinux name: grant;
|
||||
List, selinux name: list;
|
||||
ManageBlob, selinux name: manage_blob;
|
||||
Rebind, selinux name: rebind;
|
||||
ReqForcedOp, selinux name: req_forced_op;
|
||||
Update, selinux name: update;
|
||||
Use, selinux name: use;
|
||||
UseDevId, selinux name: use_dev_id;
|
||||
}
|
||||
);
|
||||
|
||||
/// KeystorePermission defines values for the SELinux `keystore2` security class.
|
||||
/// Countrary to `KeyPermission`, this enum is not generated by AIDL and need not be
|
||||
/// wrapped by newtype pattern. But we conveniently use the implement_permission macro
|
||||
/// to provide the same feature that we did for `KeyPermission` to this set of permissions.
|
||||
#[repr(i32)]
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
pub enum KeystorePermission {
|
||||
/// `None` is not a permission that can ever be granted. It is not known to the SEPolicy.
|
||||
None = 0,
|
||||
/// Checked when a new auth token is installed.
|
||||
AddAuth = 1,
|
||||
/// Checked when an app is uninstalled or wiped.
|
||||
ClearNs = 2,
|
||||
/// Checked when the locked state of Keystore 2.0 is queried.
|
||||
GetState = 4,
|
||||
/// Checked when Keystore 2.0 gets locked.
|
||||
Lock = 8,
|
||||
/// Checked when Keystore 2.0 shall be reset.
|
||||
Reset = 0x10,
|
||||
/// Checked when Keystore 2.0 shall be unlocked.
|
||||
Unlock = 0x20,
|
||||
/// This macro implements an enum with values mapped to SELinux permission names.
|
||||
/// The below example wraps the enum MyPermission in the tuple struct `MyPerm` and implements
|
||||
/// * From<i32> and Into<i32> are implemented. Where the implementation of From maps
|
||||
/// any variant not specified to the default.
|
||||
/// * Every variant has a constructor with a name corresponding to its lower case SELinux string
|
||||
/// representation.
|
||||
/// * `MyPerm.to_selinux(&self)` returns the SELinux string representation of the
|
||||
/// represented permission.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```
|
||||
/// implement_permission!(
|
||||
/// /// MyPerm documentation.
|
||||
/// #[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
/// MyPerm with default (None = 0, none) {
|
||||
/// Foo = 1, selinux name: foo;
|
||||
/// Bar = 2, selinux name: bar;
|
||||
/// }
|
||||
/// );
|
||||
/// ```
|
||||
macro_rules! implement_permission {
|
||||
// This rule provides the public interface of the macro. And starts the preprocessing
|
||||
// recursion (see below).
|
||||
($(#[$m:meta])* $name:ident with default
|
||||
($def_name:ident = $def_val:expr, $def_selinux_name:ident)
|
||||
{
|
||||
$($(#[$element_meta:meta])*
|
||||
$element_name:ident = $element_val:expr, selinux name: $selinux_name:ident;)*
|
||||
})
|
||||
=> {
|
||||
$(#[$m])*
|
||||
pub enum $name {
|
||||
/// The default variant of an enum.
|
||||
$def_name = $def_val,
|
||||
$(
|
||||
$(#[$element_meta])*
|
||||
$element_name = $element_val,
|
||||
)*
|
||||
}
|
||||
|
||||
impl From<i32> for $name {
|
||||
fn from (p: i32) -> Self {
|
||||
match p {
|
||||
$def_val => Self::$def_name,
|
||||
$($element_val => Self::$element_name,)*
|
||||
_ => Self::$def_name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<i32> for $name {
|
||||
fn into(self) -> i32 {
|
||||
self as i32
|
||||
}
|
||||
}
|
||||
|
||||
impl $name {
|
||||
/// Returns a string representation of the permission as required by
|
||||
/// `selinux::check_access`.
|
||||
pub fn to_selinux(&self) -> &'static str {
|
||||
match self {
|
||||
Self::$def_name => stringify!($def_selinux_name),
|
||||
$(Self::$element_name => stringify!($selinux_name),)*
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates an instance representing a permission with the same name.
|
||||
pub const fn $def_selinux_name() -> Self { Self::$def_name }
|
||||
$(
|
||||
/// Creates an instance representing a permission with the same name.
|
||||
pub const fn $selinux_name() -> Self { Self::$element_name }
|
||||
)*
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
implement_permission!(
|
||||
/// KeystorePerm provides a convenient abstraction from the SELinux class `keystore2`.
|
||||
/// Using the implement_permission macro we get the same features as `KeyPerm`.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
KeystorePermission as KeystorePerm with default (None = 0, none)
|
||||
and test namespace keystore_perm_tests {
|
||||
KeystorePerm with default (None = 0, none) {
|
||||
/// Checked when a new auth token is installed.
|
||||
AddAuth = 1, selinux name: add_auth;
|
||||
/// Checked when an app is uninstalled or wiped.
|
||||
ClearNs = 2, selinux name: clear_ns;
|
||||
/// Checked when Keystore 2.0 gets locked.
|
||||
GetState = 4, selinux name: get_state;
|
||||
/// Checked when Keystore 2.0 gets locked.
|
||||
Lock = 8, selinux name: lock;
|
||||
/// Checked when Keystore 2.0 shall be reset.
|
||||
Reset = 0x10, selinux name: reset;
|
||||
/// Checked when Keystore 2.0 shall be unlocked.
|
||||
Unlock = 0x20, selinux name: unlock;
|
||||
}
|
||||
);
|
||||
|
@ -281,8 +325,8 @@ implement_permission!(
|
|||
/// assert_eq(Some(KeyPerm::use_()), i.next());
|
||||
/// assert_eq(None, i.next());
|
||||
/// ```
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct KeyPermSet(i32);
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub struct KeyPermSet(pub i32);
|
||||
|
||||
mod perm {
|
||||
use super::*;
|
||||
|
@ -322,9 +366,22 @@ impl From<KeyPerm> for KeyPermSet {
|
|||
}
|
||||
}
|
||||
|
||||
/// allow conversion from the AIDL wire type i32 to a permission set.
|
||||
impl From<i32> for KeyPermSet {
|
||||
fn from(p: i32) -> Self {
|
||||
Self(p)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<KeyPermSet> for i32 {
|
||||
fn from(p: KeyPermSet) -> i32 {
|
||||
p.0
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyPermSet {
|
||||
/// Returns true iff this permission set has all of the permissions that are in `other`.
|
||||
fn includes<T: Into<KeyPermSet>>(&self, other: T) -> bool {
|
||||
pub fn includes<T: Into<KeyPermSet>>(&self, other: T) -> bool {
|
||||
let o: KeyPermSet = other.into();
|
||||
(self.0 & o.0) == o.0
|
||||
}
|
||||
|
@ -379,9 +436,9 @@ pub fn check_keystore_permission(
|
|||
pub fn check_grant_permission(
|
||||
caller_ctx: &selinux::Context,
|
||||
access_vec: KeyPermSet,
|
||||
key: &aidl::KeyDescriptor,
|
||||
key: &KeyDescriptor,
|
||||
) -> anyhow::Result<()> {
|
||||
use aidl::Domain;
|
||||
use android_security_keystore2::aidl::android::security::keystore2::Domain;
|
||||
|
||||
let target_context = match key.domain {
|
||||
Domain::App => getcon().context("check_grant_permission: getcon failed.")?,
|
||||
|
@ -429,10 +486,10 @@ pub fn check_grant_permission(
|
|||
pub fn check_key_permission(
|
||||
caller_ctx: &selinux::Context,
|
||||
perm: KeyPerm,
|
||||
key: &aidl::KeyDescriptor,
|
||||
key: &KeyDescriptor,
|
||||
access_vector: &Option<KeyPermSet>,
|
||||
) -> anyhow::Result<()> {
|
||||
use aidl::Domain;
|
||||
use android_security_keystore2::aidl::android::security::keystore2::Domain;
|
||||
|
||||
let target_context = match key.domain {
|
||||
// apps get the default keystore context
|
||||
|
@ -477,6 +534,10 @@ pub fn check_key_permission(
|
|||
|
||||
tctx
|
||||
}
|
||||
_ => {
|
||||
return Err(KsError::sys())
|
||||
.context(format!("Unknown domain value: \"{}\".", key.domain))
|
||||
}
|
||||
};
|
||||
|
||||
selinux::check_access(caller_ctx, &target_context, "keystore2_key", perm.to_selinux())
|
||||
|
@ -488,7 +549,6 @@ mod tests {
|
|||
use anyhow::anyhow;
|
||||
use anyhow::Result;
|
||||
use keystore2_selinux::*;
|
||||
use keystore_aidl_generated as aidl;
|
||||
|
||||
const ALL_PERMS: KeyPermSet = key_perm_set![
|
||||
KeyPerm::manage_blob(),
|
||||
|
@ -591,9 +651,8 @@ mod tests {
|
|||
fn check_grant_permission_app() -> Result<()> {
|
||||
let system_server_ctx = Context::new("u:r:system_server:s0")?;
|
||||
let shell_ctx = Context::new("u:r:shell:s0")?;
|
||||
use aidl::Domain;
|
||||
let key =
|
||||
aidl::KeyDescriptor { domain: Domain::App, namespace_: 0, alias: None, blob: None };
|
||||
use android_security_keystore2::aidl::android::security::keystore2::Domain;
|
||||
let key = KeyDescriptor { domain: Domain::App, namespace_: 0, alias: None, blob: None };
|
||||
assert!(check_grant_permission(&system_server_ctx, NOT_GRANT_PERMS, &key).is_ok());
|
||||
// attempts to grant the grant permission must always fail even when privileged.
|
||||
|
||||
|
@ -609,9 +668,9 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn check_grant_permission_selinux() -> Result<()> {
|
||||
use aidl::Domain;
|
||||
use android_security_keystore2::aidl::android::security::keystore2::Domain;
|
||||
let (sctx, namespace, is_su) = check_context()?;
|
||||
let key = aidl::KeyDescriptor {
|
||||
let key = KeyDescriptor {
|
||||
domain: Domain::SELinux,
|
||||
namespace_: namespace as i64,
|
||||
alias: None,
|
||||
|
@ -630,9 +689,8 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn check_key_permission_domain_grant() -> Result<()> {
|
||||
use aidl::Domain;
|
||||
let key =
|
||||
aidl::KeyDescriptor { domain: Domain::Grant, namespace_: 0, alias: None, blob: None };
|
||||
use android_security_keystore2::aidl::android::security::keystore2::Domain;
|
||||
let key = KeyDescriptor { domain: Domain::Grant, namespace_: 0, alias: None, blob: None };
|
||||
|
||||
assert_perm_failed!(check_key_permission(
|
||||
&selinux::Context::new("ignored").unwrap(),
|
||||
|
@ -654,10 +712,9 @@ mod tests {
|
|||
let system_server_ctx = Context::new("u:r:system_server:s0")?;
|
||||
let shell_ctx = Context::new("u:r:shell:s0")?;
|
||||
let gmscore_app = Context::new("u:r:gmscore_app:s0")?;
|
||||
use aidl::Domain;
|
||||
use android_security_keystore2::aidl::android::security::keystore2::Domain;
|
||||
|
||||
let key =
|
||||
aidl::KeyDescriptor { domain: Domain::App, namespace_: 0, alias: None, blob: None };
|
||||
let key = KeyDescriptor { domain: Domain::App, namespace_: 0, alias: None, blob: None };
|
||||
|
||||
assert!(check_key_permission(&system_server_ctx, KeyPerm::use_(), &key, &None).is_ok());
|
||||
assert!(check_key_permission(&system_server_ctx, KeyPerm::delete(), &key, &None).is_ok());
|
||||
|
@ -698,9 +755,9 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn check_key_permission_domain_selinux() -> Result<()> {
|
||||
use aidl::Domain;
|
||||
use android_security_keystore2::aidl::android::security::keystore2::Domain;
|
||||
let (sctx, namespace, is_su) = check_context()?;
|
||||
let key = aidl::KeyDescriptor {
|
||||
let key = KeyDescriptor {
|
||||
domain: Domain::SELinux,
|
||||
namespace_: namespace as i64,
|
||||
alias: None,
|
||||
|
@ -737,9 +794,9 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn check_key_permission_domain_blob() -> Result<()> {
|
||||
use aidl::Domain;
|
||||
use android_security_keystore2::aidl::android::security::keystore2::Domain;
|
||||
let (sctx, namespace, is_su) = check_context()?;
|
||||
let key = aidl::KeyDescriptor {
|
||||
let key = KeyDescriptor {
|
||||
domain: Domain::Blob,
|
||||
namespace_: namespace as i64,
|
||||
alias: None,
|
||||
|
@ -756,9 +813,8 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn check_key_permission_domain_key_id() -> Result<()> {
|
||||
use aidl::Domain;
|
||||
let key =
|
||||
aidl::KeyDescriptor { domain: Domain::KeyId, namespace_: 0, alias: None, blob: None };
|
||||
use android_security_keystore2::aidl::android::security::keystore2::Domain;
|
||||
let key = KeyDescriptor { domain: Domain::KeyId, namespace_: 0, alias: None, blob: None };
|
||||
|
||||
assert_eq!(
|
||||
Some(&KsError::sys()),
|
||||
|
|
Loading…
Reference in a new issue