Skip to main content

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