linux_keyutils/ffi/
types.rs

1//! Definitions ported from the C keyutils library
2//!
3use crate::utils::CStr;
4use crate::KeyError;
5
6/// Primary kernel identifier for a key or keyring.
7#[derive(Debug, Copy, Clone, PartialEq, Eq)]
8#[repr(transparent)]
9pub struct KeySerialId(pub i32);
10
11/// Pre-defined key types the kernel understands. See `man 7 keyrings`.
12#[derive(Debug, Copy, Clone, PartialEq, Eq)]
13pub enum KeyType {
14    /// Keyrings  are  special  key  types that may contain links to sequences of other
15    /// keys of any type.
16    KeyRing,
17    /// This is a general purpose key type whose payload may be read and updated by
18    /// user-space  applications. The  key is kept entirely within kernel memory.
19    /// The payload for keys of this type is a blob of arbitrary data of up to 32,767 bytes.
20    User,
21    /// This key type is essentially the same as "user", but it does not permit the key
22    /// to read. This is suitable for storing payloads that you do not want to be
23    /// readable from user space.
24    Logon,
25    /// This key type is similar to "user", but may hold a payload of up to 1 MiB.
26    /// If the key payload is large  enough, then it may be stored encrypted in
27    /// tmpfs (which can be swapped out) rather than kernel memory.
28    BigKey,
29}
30
31/// Special identifiers for default keyrings. See `man 7 keyrings`.
32#[allow(dead_code)]
33pub enum KeyRingIdentifier {
34    /// Key ID for thread-specific keyring
35    Thread = -1,
36    /// Key ID for process-specific keyring
37    Process = -2,
38    /// Key ID for session-specific keyring
39    Session = -3,
40    /// Key ID for UID-specific keyring
41    User = -4,
42    /// Key ID for UID-session keyring
43    UserSession = -5,
44    /// Key ID for GID-specific keyring
45    Group = -6,
46    /// Key ID for assumed request_key auth key
47    ReqKeyAuthKey = -7,
48}
49
50#[allow(dead_code)]
51pub enum DefaultKeyring {
52    NoChange = -1,
53    Default = 0,
54    Thread = 1,
55    Process = 2,
56    Session = 3,
57    User = 4,
58    UserSession = 5,
59    Group = 6,
60}
61
62#[allow(dead_code)]
63#[repr(u32)]
64pub enum KeyCtlOperation {
65    /// Ask for a keyring's ID
66    GetKeyRingId = 0,
67    /// Join or start named session keyring
68    JoinSessionKeyRing = 1,
69    /// Update a key
70    Update = 2,
71    /// Revoke a key
72    Revoke = 3,
73    /// Set ownership of a key
74    Chown = 4,
75    /// Set permissions of a key
76    SetPerm = 5,
77    /// Describe a key
78    Describe = 6,
79    /// Clear contents of a keyring
80    Clear = 7,
81    /// Link a key into a keyring
82    Link = 8,
83    /// Unlink a key from a keyring
84    Unlink = 9,
85    /// Search for a key in a keyring
86    Search = 10,
87    /// Read a key or keyring's contents
88    Read = 11,
89    /// Instantiate a partially constructed key
90    Instantiate = 12,
91    /// Negate a partially constructed key
92    Negate = 13,
93    /// Set default request-key keyring
94    SetRequestKeyKeyring = 14,
95    /// Set timeout on a key
96    SetTimeout = 15,
97    /// Assume authority to instantiate key
98    AssumeAuthority = 16,
99    /// Get key security label
100    GetSecurityLabel = 17,
101    /// Set my session keyring on my parent process
102    SessionToParent = 18,
103    /// Reject a partially constructed key
104    Reject = 19,
105    /// Instantiate a partially constructed key
106    InstantiageIov = 20,
107    /// Invalidate a key
108    Invalidate = 21,
109    /// Get a user's persistent keyring
110    GetPersistent = 22,
111    /// Compute Diffie-Hellman values
112    DiffieHellmanCompute = 23,
113    /// Query public key parameters
114    PubkeyQuery = 24,
115    /// Encrypt a blob using a public key
116    PubkeyEncrypt = 25,
117    /// Decrypt a blob using a public key
118    PubkeyDecrypt = 26,
119    /// Create a public key signature
120    PubkeySign = 27,
121    /// Verify a public key signature
122    PubkeyVerify = 28,
123    /// Restrict keys allowed to link to a keyring
124    RestrictKeyring = 29,
125    /// Move keys between keyrings
126    Move = 30,
127    /// Find capabilities of keyrings subsystem
128    Capabilities = 31,
129    /// Watch a key or ring of keys for changes
130    WatchKey = 32,
131}
132
133impl KeySerialId {
134    /// Construct from a raw i32
135    pub fn new(raw: i32) -> Self {
136        Self(raw)
137    }
138
139    /// Allow conversion into the raw i32 for FFI
140    pub fn as_raw_id(&self) -> i32 {
141        self.0
142    }
143}
144
145/// Perform the conversion here so that invalid KeyType strings cannot be used.
146/// Using Rust's type system to ensure only valid strings are provided to the syscall.
147impl From<KeyType> for &'static CStr {
148    fn from(t: KeyType) -> &'static CStr {
149        unsafe {
150            match t {
151                KeyType::KeyRing => CStr::from_bytes_with_nul_unchecked(b"keyring\0"),
152                KeyType::User => CStr::from_bytes_with_nul_unchecked(b"user\0"),
153                KeyType::Logon => CStr::from_bytes_with_nul_unchecked(b"logon\0"),
154                KeyType::BigKey => CStr::from_bytes_with_nul_unchecked(b"big_key\0"),
155            }
156        }
157    }
158}
159
160/// Perform the conversion here so that invalid KeyType strings cannot be used.
161/// Using Rust's type system to ensure only valid strings are provided to the syscall.
162impl TryFrom<&str> for KeyType {
163    type Error = KeyError;
164    fn try_from(s: &str) -> Result<Self, Self::Error> {
165        let val = match s {
166            "keyring" => KeyType::KeyRing,
167            "user" => KeyType::User,
168            "logon" => KeyType::Logon,
169            "big_key" => KeyType::BigKey,
170            _ => return Err(KeyError::InvalidIdentifier),
171        };
172        Ok(val)
173    }
174}
175
176/// Allow easy conversion from i32 to KeySerialId
177impl From<KeySerialId> for i32 {
178    fn from(id: KeySerialId) -> i32 {
179        id.0
180    }
181}
182
183/// Direct conversion
184impl From<i32> for KeySerialId {
185    fn from(n: i32) -> Self {
186        Self(n)
187    }
188}
189
190/// Allow easy conversion from u64 to KeySerialId
191impl TryFrom<i64> for KeySerialId {
192    type Error = KeyError;
193
194    fn try_from(n: i64) -> Result<Self, Self::Error> {
195        Ok(Self(n.try_into().or(Err(KeyError::InvalidIdentifier))?))
196    }
197}