parsec_interface/requests/
mod.rs

1// Copyright 2019 Contributors to the Parsec project.
2// SPDX-License-Identifier: Apache-2.0
3//! # Request and response definitions
4//!
5//! A `Request` is what is sent to the service to execute one operation. A `Response` is what the
6//! service returns.
7use num_derive::FromPrimitive;
8
9mod response_status;
10
11pub mod utils;
12pub mod common;
13pub mod request;
14pub mod response;
15#[cfg(feature = "fuzz")]
16use arbitrary::Arbitrary;
17pub use request::Request;
18pub use response::Response;
19pub use response_status::{ResponseStatus, Result};
20use std::convert::TryFrom;
21use std::fmt;
22
23/// Listing of provider types and their associated codes.
24///
25/// Passed in headers as `provider`.
26#[cfg_attr(feature = "fuzz", derive(Arbitrary))]
27#[derive(FromPrimitive, PartialEq, Eq, Hash, Copy, Clone, Debug)]
28#[repr(u8)]
29pub enum ProviderId {
30    /// Provider to use for core Parsec operations.
31    Core = 0,
32    /// Provider using Mbed Crypto software library.
33    MbedCrypto = 1,
34    /// Provider using a PKCS 11 compatible library.
35    Pkcs11 = 2,
36    /// Provider using a TSS 2.0 Enhanced System API library.
37    Tpm = 3,
38    /// Provider using the crypto Trusted Service running in TrustZone
39    TrustedService = 4,
40    /// Provider using the MicrochipTech cryptodevice ATECCx08 via CryptoAuthentication Library
41    CryptoAuthLib = 5,
42}
43
44impl fmt::Display for ProviderId {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46        match self {
47            ProviderId::Core => write!(f, "Core provider"),
48            ProviderId::MbedCrypto => write!(f, "Mbed Crypto provider"),
49            ProviderId::Pkcs11 => write!(f, "PKCS #11 provider"),
50            ProviderId::Tpm => write!(f, "TPM provider"),
51            ProviderId::TrustedService => write!(f, "Trusted Service provider"),
52            ProviderId::CryptoAuthLib => write!(f, "CryptoAuthentication Library provider"),
53        }
54    }
55}
56
57impl TryFrom<u8> for ProviderId {
58    type Error = ResponseStatus;
59
60    fn try_from(provider_id: u8) -> ::std::result::Result<Self, Self::Error> {
61        match num::FromPrimitive::from_u8(provider_id) {
62            Some(provider_id) => Ok(provider_id),
63            None => Err(ResponseStatus::ProviderDoesNotExist),
64        }
65    }
66}
67
68/// Listing of body encoding types and their associated codes.
69///
70/// Passed in headers as `content_type` and `accept_type`.
71#[cfg_attr(feature = "fuzz", derive(Arbitrary))]
72#[derive(FromPrimitive, Copy, Clone, Debug, PartialEq, Eq)]
73#[repr(u8)]
74pub enum BodyType {
75    /// Protobuf format for operations.
76    Protobuf = 0,
77}
78
79/// Listing of available operations and their associated opcode.
80///
81/// Passed in headers as `opcode`. Check the
82/// [Operations](https://parallaxsecond.github.io/parsec-book/parsec_client/operations/index.html)
83/// page of the book for more information.
84#[cfg_attr(feature = "fuzz", derive(Arbitrary))]
85#[derive(FromPrimitive, Copy, Clone, PartialEq, Debug, Hash, Eq)]
86#[repr(u32)]
87pub enum Opcode {
88    /// Ping operation
89    Ping = 0x0001,
90    /// PsaGenerateKey operation
91    PsaGenerateKey = 0x0002,
92    /// PsaDestroyKey operation
93    PsaDestroyKey = 0x0003,
94    /// PsaSignHash operation
95    PsaSignHash = 0x0004,
96    /// PsaVerifyHash operation
97    PsaVerifyHash = 0x0005,
98    /// PsaImportKey operation
99    PsaImportKey = 0x0006,
100    /// PsaExportPublicKey operation
101    PsaExportPublicKey = 0x0007,
102    /// ListProviders operation
103    ListProviders = 0x0008,
104    /// ListOpcodes operation
105    ListOpcodes = 0x0009,
106    /// PsaAsymmetricEncrypt operation
107    PsaAsymmetricEncrypt = 0x000A,
108    /// PsaAsymmetricDecrypt operation
109    PsaAsymmetricDecrypt = 0x000B,
110    /// PsaExportKey operation
111    PsaExportKey = 0x000C,
112    /// PsaGenerateRandom operation
113    PsaGenerateRandom = 0x000D,
114    /// ListAuthenticators operation
115    ListAuthenticators = 0x000E,
116    /// PsaHashCompute operation
117    PsaHashCompute = 0x000F,
118    /// PsaHashCompare operation
119    PsaHashCompare = 0x0010,
120    /// PsaAeadEncrypt
121    PsaAeadEncrypt = 0x0011,
122    /// PsaAeadDecrypt
123    PsaAeadDecrypt = 0x0012,
124    /// PsaRawKeyAgreement operation
125    PsaRawKeyAgreement = 0x0013,
126    /// PsaCipherEncrypt
127    PsaCipherEncrypt = 0x0014,
128    /// PsaCipherDecrypt
129    PsaCipherDecrypt = 0x0015,
130    /// PsaSignMessage operation
131    PsaSignMessage = 0x0018,
132    /// PsaVerifyMessage operation
133    PsaVerifyMessage = 0x0019,
134    /// ListKeys operation
135    ListKeys = 0x001A,
136    /// ListClients operation (admin operation)
137    ListClients = 0x001B,
138    /// DeleteClient operation (admin operation)
139    DeleteClient = 0x001C,
140    /// AttestKey operation
141    AttestKey = 0x001E,
142    /// PrepareKeyAttestation operation
143    PrepareKeyAttestation = 0x001F,
144    /// CanDoCrypto operation
145    CanDoCrypto = 0x0020,
146}
147
148impl Opcode {
149    /// Check if an opcode is one of a Core operation
150    pub fn is_core(&self) -> bool {
151        // match to ensure exhaustivity when a new opcode is added
152        match self {
153            Opcode::Ping
154            | Opcode::ListProviders
155            | Opcode::ListOpcodes
156            | Opcode::ListAuthenticators
157            | Opcode::ListKeys
158            | Opcode::ListClients
159            | Opcode::DeleteClient => true,
160            Opcode::PsaGenerateKey
161            | Opcode::PsaDestroyKey
162            | Opcode::PsaSignHash
163            | Opcode::PsaVerifyHash
164            | Opcode::PsaSignMessage
165            | Opcode::PsaVerifyMessage
166            | Opcode::PsaImportKey
167            | Opcode::PsaExportPublicKey
168            | Opcode::PsaAsymmetricEncrypt
169            | Opcode::PsaAsymmetricDecrypt
170            | Opcode::PsaExportKey
171            | Opcode::PsaGenerateRandom
172            | Opcode::PsaHashCompute
173            | Opcode::PsaHashCompare
174            | Opcode::PsaAeadEncrypt
175            | Opcode::PsaAeadDecrypt
176            | Opcode::PsaCipherEncrypt
177            | Opcode::PsaCipherDecrypt
178            | Opcode::PsaRawKeyAgreement
179            | Opcode::CanDoCrypto
180            | Opcode::AttestKey
181            | Opcode::PrepareKeyAttestation => false,
182        }
183    }
184
185    /// Check if an opcode is an admin operation
186    pub fn is_admin(&self) -> bool {
187        // match to ensure exhaustivity when a new opcode is added
188        match self {
189            Opcode::ListClients | Opcode::DeleteClient => true,
190            Opcode::Ping
191            | Opcode::ListProviders
192            | Opcode::ListOpcodes
193            | Opcode::ListAuthenticators
194            | Opcode::ListKeys
195            | Opcode::PsaGenerateKey
196            | Opcode::PsaDestroyKey
197            | Opcode::PsaSignHash
198            | Opcode::PsaVerifyHash
199            | Opcode::PsaSignMessage
200            | Opcode::PsaVerifyMessage
201            | Opcode::PsaImportKey
202            | Opcode::PsaExportPublicKey
203            | Opcode::PsaAsymmetricEncrypt
204            | Opcode::PsaAsymmetricDecrypt
205            | Opcode::PsaExportKey
206            | Opcode::PsaGenerateRandom
207            | Opcode::PsaHashCompute
208            | Opcode::PsaHashCompare
209            | Opcode::PsaAeadEncrypt
210            | Opcode::PsaAeadDecrypt
211            | Opcode::PsaCipherEncrypt
212            | Opcode::PsaCipherDecrypt
213            | Opcode::PsaRawKeyAgreement
214            | Opcode::CanDoCrypto
215            | Opcode::AttestKey
216            | Opcode::PrepareKeyAttestation => false,
217        }
218    }
219
220    /// Check if an opcode is one of a PSA Crypto operation
221    pub fn is_crypto(&self) -> bool {
222        !self.is_core()
223    }
224}
225
226/// Listing of available authentication methods.
227///
228/// Passed in headers as `auth_type`.
229#[cfg_attr(feature = "fuzz", derive(Arbitrary))]
230#[derive(FromPrimitive, PartialEq, Eq, Hash, Copy, Clone, Debug)]
231#[repr(u8)]
232pub enum AuthType {
233    /// No authentication
234    NoAuth = 0,
235    /// Direct authentication
236    Direct = 1,
237    /// JSON Web Tokens (JWT) authentication (not currently supported)
238    Jwt = 2,
239    /// Unix peer credentials authentication
240    UnixPeerCredentials = 3,
241    /// Authentication verifying a JWT SPIFFE Verifiable Identity Document
242    JwtSvid = 4,
243}
244
245impl fmt::Display for AuthType {
246    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
247        match self {
248            AuthType::NoAuth => write!(f, "No authentication"),
249            AuthType::Direct => write!(f, "Direct authentication"),
250            AuthType::Jwt => write!(f, "JSON Web Tokens authentication"),
251            AuthType::UnixPeerCredentials => write!(f, "Unix Peer Credentials authentication"),
252            AuthType::JwtSvid => {
253                write!(f, "JWT SPIFFE Verifiable Identity Document authentication")
254            }
255        }
256    }
257}
258
259#[test]
260fn check_opcode_nature() {
261    assert!(Opcode::ListKeys.is_core());
262    assert!(!Opcode::ListKeys.is_crypto());
263    assert!(Opcode::PsaGenerateKey.is_crypto());
264    assert!(Opcode::ListClients.is_admin());
265    assert!(!Opcode::PsaGenerateKey.is_admin());
266}