1use core::fmt;
8
9use heapless::{String, Vec};
10
11use crate::limits::MAX_APPLETS;
12
13use crate::aid::Aid;
14use crate::command::install::PrivLen;
15use crate::limits::{
16 ATR_ATS_MAX, CIN_MAX, GETDATA_RAW_MAX, IIN_MAX, MAX_CIPHERS, MAX_ELFS, MAX_KEYSETS,
17 MAX_KEYS_PER_SET, MAX_MODULES_PER_ELF, MAX_PRIVILEGE_BYTES, MAX_QUIRKS, MAX_SCP_VARIANTS,
18 MAX_SDS, MAX_WARNINGS, OTHER_DETAIL_MAX,
19};
20use crate::transport::TransportProtocol;
21
22pub struct CardInfo {
24 pub isd_aid: Aid,
26 pub atr_or_ats: Vec<u8, ATR_ATS_MAX>,
27 pub transport_protocol: TransportProtocol,
28
29 pub scp_supported: Vec<ScpVariant, MAX_SCP_VARIANTS>, pub scp_default: ScpVariant, pub isd_keysets: Vec<Keyset, MAX_KEYSETS>, pub isd_key_template_format: KeyTemplateFormat,
36
37 pub capabilities: CardCapabilities,
39 pub card_recognition_data_raw: Vec<u8, GETDATA_RAW_MAX>, pub iin: Option<Vec<u8, IIN_MAX>>, pub cin: Option<Vec<u8, CIN_MAX>>, pub card_image_number: Option<Vec<u8, CIN_MAX>>, pub jc_platform_version: Option<(u8, u8, u8)>,
46
47 pub privilege_encoding: PrivLen,
50
51 pub quirks_detected: Vec<String<OTHER_DETAIL_MAX>, MAX_QUIRKS>,
53 pub discovery_warnings: Vec<DiscoveryWarning, MAX_WARNINGS>,
54}
55
56#[derive(Debug)]
60pub struct CardInventory {
61 pub security_domains: Vec<SecurityDomainEntry, MAX_SDS>,
62 pub applets: Vec<ApplicationEntry, MAX_APPLETS>,
63 pub elfs: Vec<ExecutableLoadFileEntry, MAX_ELFS>,
64}
65
66#[derive(Clone, Copy, PartialEq, Eq)]
68pub enum ScpVariant {
69 Scp02 { i_param: u8 }, Scp03 { i_param: u8 }, }
72
73impl fmt::Debug for ScpVariant {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 let (name, i) = match self {
76 ScpVariant::Scp02 { i_param } => ("Scp02", i_param),
77 ScpVariant::Scp03 { i_param } => ("Scp03", i_param),
78 };
79 f.debug_struct(name)
80 .field("i_param", &format_args!("{i:#04x}"))
81 .finish()
82 }
83}
84
85pub struct Keyset {
87 pub kvn: u8,
88 pub keys: Vec<KeyInfo, MAX_KEYS_PER_SET>, }
90
91impl fmt::Debug for Keyset {
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 f.debug_struct("Keyset")
97 .field("kvn", &format_args!("{:#04x}", self.kvn))
98 .field("keys", &self.keys)
99 .finish()
100 }
101}
102
103pub struct KeyInfo {
110 pub kid: u8,
111 pub key_type: KeyType,
112 pub key_length: u8,
113}
114
115impl fmt::Debug for KeyInfo {
116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117 f.debug_struct("KeyInfo")
118 .field("kid", &format_args!("{:#04x}", self.kid))
119 .field("key_type", &self.key_type)
120 .field("key_length", &self.key_length)
121 .finish()
122 }
123}
124
125#[derive(Debug, Clone, Copy, PartialEq, Eq)]
127pub enum KeyType {
128 Des, Aes, RsaPublic, RsaPrivateCrt, RsaPrivateExponent, EccPublic, EccPrivate, EccParametersRef, Other(u8),
137}
138
139#[derive(Debug)]
141pub enum KeyTemplateFormat {
142 Basic, Extended, }
145
146pub struct CardCapabilities {
148 pub max_logical_channels: u8, pub ciphers_supported: Vec<CipherAlg, MAX_CIPHERS>,
150 pub privileges_supported: Vec<u8, MAX_PRIVILEGE_BYTES>,
151 pub memory_total_bytes: Option<u32>,
152 pub memory_free_bytes: Option<u32>,
153 pub cci_raw: Vec<u8, GETDATA_RAW_MAX>, }
155
156#[non_exhaustive]
158#[derive(Debug)]
159pub enum CipherAlg {
160 Aes128,
161 Aes192,
162 Aes256,
163 TripleDes,
164 Rsa1024,
165 Rsa2048,
166 Rsa3072,
167 Rsa4096,
168 EccP256,
169 EccP384,
170 EccP521,
171 Sha1,
172 Sha256,
173 Sha384,
174 Sha512,
175 Other(String<OTHER_DETAIL_MAX>),
176}
177
178pub struct SecurityDomainEntry {
180 pub aid: Aid,
181 pub life_cycle_state: u8, pub privileges: [u8; 3],
183 pub associated_sd_aid: Option<Aid>, }
185
186pub struct ApplicationEntry {
188 pub aid: Aid,
189 pub life_cycle_state: u8,
190 pub privileges: [u8; 3],
191 pub associated_sd_aid: Aid, pub associated_elf_aid: Option<Aid>, }
194
195#[derive(Debug)]
197pub struct ExecutableLoadFileEntry {
198 pub aid: Aid,
199 pub life_cycle_state: u8,
200 pub associated_sd_aid: Aid,
201 pub modules: Vec<Aid, MAX_MODULES_PER_ELF>, }
203
204#[non_exhaustive]
206#[derive(Debug)]
207pub enum DiscoveryWarning {
208 CardRecognitionDataMissing,
209 KeyInformationTemplateMissing,
210 CardCapabilityInfoMissing,
211 UnknownLifecycleByte(u8),
212 GetStatusParseFailed,
213 Other(String<OTHER_DETAIL_MAX>),
214}
215
216impl core::fmt::Debug for CardInfo {
219 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
220 f.debug_struct("CardInfo")
221 .field("isd_aid", &self.isd_aid)
222 .field(
223 "atr_or_ats",
224 &crate::hexfmt::HexBytes(self.atr_or_ats.as_slice()),
225 )
226 .field("transport_protocol", &self.transport_protocol)
227 .field("scp_supported", &self.scp_supported)
228 .field("scp_default", &self.scp_default)
229 .field("isd_keysets", &self.isd_keysets)
230 .field("isd_key_template_format", &self.isd_key_template_format)
231 .field("capabilities", &self.capabilities)
232 .field(
233 "card_recognition_data_raw",
234 &crate::hexfmt::HexBytes(self.card_recognition_data_raw.as_slice()),
235 )
236 .field("iin", &self.iin.as_deref().map(crate::hexfmt::HexBytes))
237 .field("cin", &self.cin.as_deref().map(crate::hexfmt::HexBytes))
238 .field(
239 "card_image_number",
240 &self
241 .card_image_number
242 .as_deref()
243 .map(crate::hexfmt::HexBytes),
244 )
245 .field("jc_platform_version", &self.jc_platform_version)
246 .field("privilege_encoding", &self.privilege_encoding)
247 .field("quirks_detected", &self.quirks_detected)
248 .field("discovery_warnings", &self.discovery_warnings)
249 .finish()
250 }
251}
252
253impl core::fmt::Debug for CardCapabilities {
254 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
255 f.debug_struct("CardCapabilities")
256 .field("max_logical_channels", &self.max_logical_channels)
257 .field("ciphers_supported", &self.ciphers_supported)
258 .field(
259 "privileges_supported",
260 &crate::hexfmt::HexBytes(self.privileges_supported.as_slice()),
261 )
262 .field("memory_total_bytes", &self.memory_total_bytes)
263 .field("memory_free_bytes", &self.memory_free_bytes)
264 .field("cci_raw", &crate::hexfmt::HexBytes(self.cci_raw.as_slice()))
265 .finish()
266 }
267}
268
269impl core::fmt::Debug for SecurityDomainEntry {
270 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
271 f.debug_struct("SecurityDomainEntry")
272 .field("aid", &self.aid)
273 .field("life_cycle_state", &self.life_cycle_state)
274 .field("privileges", &crate::hexfmt::HexBytes(&self.privileges[..]))
275 .field("associated_sd_aid", &self.associated_sd_aid)
276 .finish()
277 }
278}
279
280impl core::fmt::Debug for ApplicationEntry {
281 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
282 f.debug_struct("ApplicationEntry")
283 .field("aid", &self.aid)
284 .field("life_cycle_state", &self.life_cycle_state)
285 .field("privileges", &crate::hexfmt::HexBytes(&self.privileges[..]))
286 .field("associated_sd_aid", &self.associated_sd_aid)
287 .field("associated_elf_aid", &self.associated_elf_aid)
288 .finish()
289 }
290}