Skip to main content

openpgp_card/
lib.rs

1// SPDX-FileCopyrightText: Heiko Schaefer <heiko@schaefer.name>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! Client library for
5//! [OpenPGP card](https://en.wikipedia.org/wiki/OpenPGP_card)
6//! devices (such as Gnuk, Nitrokey, YubiKey, or Java smartcards running an
7//! OpenPGP card application).
8//!
9//! This library aims to offer
10//! - low-level access to all features in the OpenPGP [card specification](https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-3.4.1.pdf)
11//!   via the [crate::ocard] package,
12//! - without relying on a particular [OpenPGP implementation](https://www.openpgp.org/software/developer/).
13//!
14//! The library exposes two modes of access to cards:
15//! - low-level, unmediated, access to card functionality (see [crate::ocard]), and
16//! - a more opinionated, typed wrapper API that performs some amount of caching [Card].
17//!
18//! Note that this library can't directly access cards by itself.
19//! Instead, users need to supply a backend that implements the
20//! [`card_backend::CardBackend`] and [`card_backend::CardTransaction`] traits.
21//! For example [card-backend-pcsc](https://crates.io/crates/card-backend-pcsc)
22//! offers a backend implementation that uses [PC/SC](https://en.wikipedia.org/wiki/PC/SC) to
23//! communicate with Smart Cards.
24//!
25//! See the [architecture diagram](https://codeberg.org/openpgp-card/openpgp-card#architecture)
26//! for an overview of the ecosystem around this crate.
27
28extern crate core;
29
30mod errors;
31pub mod ocard;
32pub mod state;
33
34use card_backend::{CardBackend, SmartcardError};
35use secrecy::SecretString;
36
37pub use crate::errors::Error;
38use crate::{
39    ocard::{
40        KeyType,
41        algorithm::{AlgoSimple, AlgorithmAttributes, AlgorithmInformation},
42        crypto::{CardUploadableKey, PublicKeyMaterial},
43        data::{
44            ApplicationIdentifier,
45            CardholderRelatedData,
46            ExtendedCapabilities,
47            ExtendedLengthInfo,
48            Fingerprint,
49            HistoricalBytes,
50            KdfDo,
51            KeyGenerationTime,
52            KeyInformation,
53            KeySet,
54            Lang,
55            PWStatusBytes,
56            Sex,
57            TouchPolicy,
58            UserInteractionFlag,
59        },
60        kdf::map_pin,
61    },
62    state::{Admin, Open, Sign, State, Transaction, User},
63};
64
65/// For caching DOs in a Transaction
66enum Cached<T> {
67    Uncached,
68    None,
69    Value(T),
70}
71
72/// A PIN in an OpenPGP card application.
73///
74/// - Pw1 is the "User PIN"
75/// - Rc is the "Resetting Code"
76/// - Pw3 is the "Admin PIN"
77pub(crate) enum PinType {
78    Pw1,
79    Rc,
80    Pw3,
81}
82
83/// Optional PIN, used as a parameter to `Card<Transaction>::into_*_card`.
84///
85/// Effectively acts like a `Option<SecretString>`, but with a number of `From`
86/// implementations for convenience.
87pub struct OptionalPin(Option<SecretString>);
88
89impl From<Option<SecretString>> for OptionalPin {
90    fn from(value: Option<SecretString>) -> Self {
91        OptionalPin(value)
92    }
93}
94
95impl From<SecretString> for OptionalPin {
96    fn from(value: SecretString) -> Self {
97        OptionalPin(Some(value))
98    }
99}
100
101/// Representation of an OpenPGP card.
102///
103/// A card transitions between [`State`]s by starting a transaction (that groups together a number
104/// of operations into an atomic sequence) and via PIN presentation.
105///
106/// Depending on the [`State`] of the card and the access privileges that are associated with that
107/// state, different operations can be performed. In many cases, client software will want to
108/// transition between states while performing one workflow for the user.
109pub struct Card<S>
110where
111    S: State,
112{
113    state: S,
114}
115
116impl Card<Open> {
117    /// Takes an iterator over [`CardBackend`]s, tries to SELECT the OpenPGP card
118    /// application on each of them, and checks if its application id matches
119    /// `ident`.
120    /// Returns a [`Card<Open>`] for the first match, if any.
121    pub fn open_by_ident(
122        cards: impl Iterator<Item = Result<Box<dyn CardBackend + Send + Sync>, SmartcardError>>,
123        ident: &str,
124    ) -> Result<Self, Error> {
125        for b in cards.filter_map(|c| c.ok()) {
126            let mut card = Self::new(b)?;
127
128            let aid = {
129                let mut tx = card.transaction()?;
130                tx.state.ard().application_id()?
131            };
132
133            if aid.ident() == ident.to_ascii_uppercase() {
134                return Ok(card);
135            }
136        }
137
138        Err(Error::InternalError(format!(
139            "Couldn't find card {}",
140            ident
141        )))
142    }
143
144    /// Returns a [`Card<Open>`] based on `backend` (after SELECTing the
145    /// OpenPGP card application).
146    pub fn new<B>(backend: B) -> Result<Self, Error>
147    where
148        B: Into<Box<dyn CardBackend + Send + Sync>>,
149    {
150        let pgp = crate::ocard::OpenPGP::new(backend)?;
151
152        Ok(Card::<Open> {
153            state: Open { pgp },
154        })
155    }
156
157    /// Starts a transaction on the underlying backend (if the backend
158    /// implementation supports transactions, otherwise the backend
159    /// will operate without transaction guarantees).
160    ///
161    /// The resulting [`Card<Transaction>`] object allows performing
162    /// operations on the card.
163    pub fn transaction(&mut self) -> Result<Card<Transaction<'_>>, Error> {
164        let opt = self.state.pgp.transaction()?;
165
166        Card::<Transaction>::new(opt)
167    }
168
169    /// Retrieve the underlying [`CardBackend`].
170    ///
171    /// This is useful to take the card object into a different context
172    /// (e.g. to perform operations on the card with the `yubikey-management`
173    /// crate, without closing the connection to the card).
174    pub fn into_backend(self) -> Box<dyn CardBackend + Send + Sync> {
175        self.state.pgp.into_card()
176    }
177}
178
179impl<'a> Card<Transaction<'a>> {
180    /// Internal constructor
181    fn new(mut opt: crate::ocard::Transaction<'a>) -> Result<Self, Error> {
182        let ard = opt.application_related_data()?;
183
184        Ok(Self {
185            state: Transaction::new(opt, ard),
186        })
187    }
188
189    // FIXME: remove later?
190    pub fn card(&mut self) -> &mut crate::ocard::Transaction<'a> {
191        &mut self.state.opt
192    }
193
194    /// Drop cached "application related data" and "kdf do" in this [Card] instance.
195    ///
196    /// This is necessary e.g. after importing or generating keys on a card, to
197    /// drop the now obsolete cached [`crate::ocard::data::ApplicationRelatedData`] and [`KdfDo`].
198    pub fn invalidate_cache(&mut self) -> Result<(), Error> {
199        self.state.invalidate_cache();
200        Ok(())
201    }
202
203    /// True if the reader for this card supports PIN verification with a pin pad.
204    pub fn feature_pinpad_verify(&mut self) -> bool {
205        self.state.opt.feature_pinpad_verify()
206    }
207
208    /// True if the reader for this card supports PIN modification with a pin pad.
209    pub fn feature_pinpad_modify(&mut self) -> bool {
210        self.state.opt.feature_pinpad_modify()
211    }
212
213    /// Verify the User PIN (for operations such as decryption)
214    pub fn verify_user_pin(&mut self, pin: SecretString) -> Result<(), Error> {
215        let pin = map_pin(pin, PinType::Pw1, self.state.kdf_do())?;
216
217        self.state.opt.verify_pw1_user(pin)?;
218        self.state.pw1 = true;
219
220        self.state.invalidate_cache_ard();
221        Ok(())
222    }
223
224    /// Verify the User PIN with a physical PIN pad (if available,
225    /// see [`Self::feature_pinpad_verify`]).
226    pub fn verify_user_pinpad(&mut self, pinpad_prompt: &dyn Fn()) -> Result<(), Error> {
227        pinpad_prompt();
228
229        self.state.opt.verify_pw1_user_pinpad()?;
230        self.state.pw1 = true;
231
232        self.state.invalidate_cache_ard();
233        Ok(())
234    }
235
236    /// Verify the User PIN for signing operations.
237    ///
238    /// (Note that depending on the configuration of the card, this may enable
239    /// performing just one signing operation, or an unlimited amount of
240    /// signing operations).
241    pub fn verify_user_signing_pin(&mut self, pin: SecretString) -> Result<(), Error> {
242        let pin = map_pin(pin, PinType::Pw1, self.state.kdf_do())?;
243
244        self.state.opt.verify_pw1_sign(pin)?;
245
246        // FIXME: depending on card mode, pw1_sign is only usable once
247        self.state.pw1_sign = true;
248
249        self.state.invalidate_cache_ard();
250        Ok(())
251    }
252
253    /// Verify the User PIN for signing operations with a physical PIN pad
254    /// (if available, see [`Self::feature_pinpad_verify`]).
255    pub fn verify_user_signing_pinpad(&mut self, pinpad_prompt: &dyn Fn()) -> Result<(), Error> {
256        pinpad_prompt();
257
258        self.state.opt.verify_pw1_sign_pinpad()?;
259
260        // FIXME: depending on card mode, pw1_sign is only usable once
261        self.state.pw1_sign = true;
262
263        self.state.invalidate_cache_ard();
264        Ok(())
265    }
266
267    /// Verify the Admin PIN.
268    pub fn verify_admin_pin(&mut self, pin: SecretString) -> Result<(), Error> {
269        let pin = map_pin(pin, PinType::Pw3, self.state.kdf_do())?;
270
271        self.state.opt.verify_pw3(pin)?;
272        self.state.pw3 = true;
273
274        self.state.invalidate_cache_ard();
275        Ok(())
276    }
277
278    /// Verify the Admin PIN with a physical PIN pad
279    /// (if available, see [`Self::feature_pinpad_verify`]).
280    pub fn verify_admin_pinpad(&mut self, pinpad_prompt: &dyn Fn()) -> Result<(), Error> {
281        pinpad_prompt();
282
283        self.state.opt.verify_pw3_pinpad()?;
284        self.state.pw3 = true;
285
286        self.state.invalidate_cache_ard();
287        Ok(())
288    }
289
290    /// Ask the card if the user password has been successfully verified.
291    ///
292    /// NOTE: on some cards this functionality seems broken and may decrease
293    /// the pin's error count!
294    pub fn check_user_verified(&mut self) -> Result<(), Error> {
295        self.state.opt.check_pw1_user()
296    }
297
298    /// Ask the card if the admin password has been successfully verified.
299    ///
300    /// NOTE: on some cards this functionality seems broken and may decrease
301    /// the pin's error count!
302    pub fn check_admin_verified(&mut self) -> Result<(), Error> {
303        self.state.opt.check_pw3()
304    }
305
306    /// Change the User PIN, based on the old User PIN.
307    pub fn change_user_pin(&mut self, old: SecretString, new: SecretString) -> Result<(), Error> {
308        let old = map_pin(old, PinType::Pw1, self.state.kdf_do())?;
309        let new = map_pin(new, PinType::Pw1, self.state.kdf_do())?;
310
311        self.state.opt.change_pw1(old, new)?;
312
313        self.state.invalidate_cache_ard();
314        Ok(())
315    }
316
317    /// Change the User PIN, based on the old User PIN, with a physical PIN
318    /// pad (if available, see [`Self::feature_pinpad_modify`]).
319    pub fn change_user_pin_pinpad(&mut self, pinpad_prompt: &dyn Fn()) -> Result<(), Error> {
320        pinpad_prompt();
321        self.state.opt.change_pw1_pinpad()?;
322
323        self.state.invalidate_cache_ard();
324        Ok(())
325    }
326
327    /// Change the User PIN, based on the resetting code `rst`.
328    pub fn reset_user_pin(&mut self, rst: SecretString, new: SecretString) -> Result<(), Error> {
329        let rst = map_pin(rst, PinType::Rc, self.state.kdf_do())?;
330        let new = map_pin(new, PinType::Pw1, self.state.kdf_do())?;
331
332        self.state.opt.reset_retry_counter_pw1(new, Some(rst))?;
333
334        self.state.invalidate_cache_ard();
335        Ok(())
336    }
337
338    /// Change the Admin PIN, based on the old Admin PIN.
339    pub fn change_admin_pin(&mut self, old: SecretString, new: SecretString) -> Result<(), Error> {
340        let old = map_pin(old, PinType::Pw3, self.state.kdf_do())?;
341        let new = map_pin(new, PinType::Pw3, self.state.kdf_do())?;
342
343        self.state.opt.change_pw3(old, new)?;
344
345        self.state.invalidate_cache_ard();
346        Ok(())
347    }
348
349    /// Change the Admin PIN, based on the old Admin PIN, with a physical PIN
350    /// pad (if available, see [`Self::feature_pinpad_modify`]).
351    pub fn change_admin_pin_pinpad(&mut self, pinpad_prompt: &dyn Fn()) -> Result<(), Error> {
352        pinpad_prompt();
353        self.state.opt.change_pw3_pinpad()?;
354
355        self.state.invalidate_cache_ard();
356        Ok(())
357    }
358
359    /// Get a view of the card in the [`Card<User>`] state, and authenticate
360    /// for that state with `pin`, if available.
361    ///
362    /// If `pin` is not None, `verify_user` is called with that pin.
363    pub fn as_user_card<'b, P>(&'b mut self, pin: P) -> Result<Card<User<'a, 'b>>, Error>
364    where
365        P: Into<OptionalPin>,
366    {
367        let pin: OptionalPin = pin.into();
368
369        if let Some(pin) = pin.0 {
370            self.verify_user_pin(pin)?;
371        }
372
373        Ok(Card::<User> {
374            state: User { tx: self },
375        })
376    }
377
378    /// Get a view of the card in the [`Card<Sign>`] state, and authenticate
379    /// for that state with `pin`, if available.
380    ///
381    /// If `pin` is not None, `verify_user_for_signing` is called with that pin.
382    pub fn as_signing_card<'b, P>(&'b mut self, pin: P) -> Result<Card<Sign<'a, 'b>>, Error>
383    where
384        P: Into<OptionalPin>,
385    {
386        let pin: OptionalPin = pin.into();
387
388        if let Some(pin) = pin.0 {
389            self.verify_user_signing_pin(pin)?;
390        }
391
392        Ok(Card::<Sign> {
393            state: Sign { tx: self },
394        })
395    }
396
397    /// Get a view of the card in the [`Card<Admin>`] state, and authenticate
398    /// for that state with `pin`, if available.
399    ///
400    /// If `pin` is not None, `verify_admin` is called with that pin.
401    pub fn as_admin_card<'b, P>(&'b mut self, pin: P) -> Result<Card<Admin<'a, 'b>>, Error>
402    where
403        P: Into<OptionalPin>,
404    {
405        let pin: OptionalPin = pin.into();
406
407        if let Some(pin) = pin.0 {
408            self.verify_admin_pin(pin)?;
409        }
410
411        Ok(Card::<Admin> {
412            state: Admin { tx: self },
413        })
414    }
415
416    // --- application data ---
417
418    /// The Application Identifier is unique for each card.
419    /// It includes a manufacturer code and serial number.
420    ///
421    /// (This is an immutable field on the card. The value is cached in the
422    /// underlying Card object. It can be retrieved without incurring a call
423    /// to the card)
424    pub fn application_identifier(&self) -> Result<ApplicationIdentifier, Error> {
425        // Use immutable data cache from underlying Card object
426        self.state.opt.application_identifier()
427    }
428
429    /// The "Extended Capabilities" data object describes features of a card
430    /// to the caller.
431    /// This includes the availability and length of various data fields.
432    ///
433    /// (This is an immutable field on the card. The value is cached in the
434    /// underlying Card object. It can be retrieved without incurring a call
435    /// to the card)
436    pub fn extended_capabilities(&self) -> Result<ExtendedCapabilities, Error> {
437        // Use immutable data cache from underlying Card object
438        self.state.opt.extended_capabilities()
439    }
440
441    /// The "Historical Bytes" data object describes features of a card
442    /// to the caller.
443    /// The information in this field is probably not relevant for most
444    /// users of this library, however, some of it is used for the internal
445    /// operation of the `openpgp-card` library.
446    ///
447    /// (This is an immutable field on the card. The value is cached in the
448    /// underlying Card object. It can be retrieved without incurring a call
449    /// to the card)
450    pub fn historical_bytes(&self) -> Result<HistoricalBytes, Error> {
451        // Use immutable data cache from underlying Card object
452        match self.state.opt.historical_bytes()? {
453            Some(hb) => Ok(hb),
454            None => Err(Error::NotFound(
455                "Card doesn't have historical bytes DO".to_string(),
456            )),
457        }
458    }
459
460    /// The "Extended Length Information" data object was introduced in
461    /// version 3.0 of the OpenPGP card standard.
462    ///
463    /// The information in this field should not be relevant for
464    /// users of this library.
465    /// However, it is used for the internal operation of the `openpgp-card`
466    /// library.
467    ///
468    /// (This is an immutable field on the card. The value is cached in the
469    /// underlying Card object. It can be retrieved without incurring a call
470    /// to the card)
471    pub fn extended_length_information(&self) -> Result<Option<ExtendedLengthInfo>, Error> {
472        // Use immutable data cache from underlying Card object
473        self.state.opt.extended_length_info()
474    }
475
476    // fn general_feature_management() -> Option<bool> {
477    //     unimplemented!()
478    // }
479
480    // fn discretionary_data_objects() {
481    //     unimplemented!()
482    // }
483
484    /// PW Status Bytes
485    pub fn pw_status_bytes(&mut self) -> Result<PWStatusBytes, Error> {
486        self.state.ard().pw_status_bytes()
487    }
488
489    /// Get algorithm attributes for a key slot.
490    pub fn algorithm_attributes(
491        &mut self,
492        key_type: KeyType,
493    ) -> Result<AlgorithmAttributes, Error> {
494        self.state.ard().algorithm_attributes(key_type)
495    }
496
497    /// Get the Fingerprints for the three basic [`KeyType`]s.
498    ///
499    /// (The fingerprints for the three basic key slots are stored in a
500    /// shared field on the card, thus they can be retrieved in one go)
501    pub fn fingerprints(&mut self) -> Result<KeySet<Fingerprint>, Error> {
502        self.state.ard().fingerprints()
503    }
504
505    /// Get the Fingerprint for one [`KeyType`].
506    ///
507    /// This function allows retrieval for all slots, including
508    /// [`KeyType::Attestation`], if available.
509    pub fn fingerprint(&mut self, key_type: KeyType) -> Result<Option<Fingerprint>, Error> {
510        let fp = match key_type {
511            KeyType::Signing => self.fingerprints()?.signature().cloned(),
512            KeyType::Decryption => self.fingerprints()?.decryption().cloned(),
513            KeyType::Authentication => self.fingerprints()?.authentication().cloned(),
514            KeyType::Attestation => self.state.ard().attestation_key_fingerprint()?,
515        };
516
517        Ok(fp)
518    }
519
520    /// Get the Key Creation Times for the three basic [`KeyType`]s.
521    ///
522    /// (The creation time for the three basic key slots are stored in a
523    /// shared field on the card, thus they can be retrieved in one go)
524    pub fn key_generation_times(&mut self) -> Result<KeySet<KeyGenerationTime>, Error> {
525        self.state.ard().key_generation_times()
526    }
527
528    /// Get the Key Creation Time for one [`KeyType`].
529    ///
530    /// This function allows retrieval for all slots, including
531    /// [`KeyType::Attestation`], if available.
532    pub fn key_generation_time(
533        &mut self,
534        key_type: KeyType,
535    ) -> Result<Option<KeyGenerationTime>, Error> {
536        let ts = match key_type {
537            KeyType::Signing => self.key_generation_times()?.signature().cloned(),
538            KeyType::Decryption => self.key_generation_times()?.decryption().cloned(),
539            KeyType::Authentication => self.key_generation_times()?.authentication().cloned(),
540            KeyType::Attestation => self.state.ard().attestation_key_generation_time()?,
541        };
542
543        Ok(ts)
544    }
545
546    pub fn key_information(&mut self) -> Result<Option<KeyInformation>, Error> {
547        self.state.ard().key_information()
548    }
549
550    /// Get the [`UserInteractionFlag`] for a key slot.
551    /// This includes the [`TouchPolicy`], if the card supports touch
552    /// confirmation.
553    pub fn user_interaction_flag(
554        &mut self,
555        key_type: KeyType,
556    ) -> Result<Option<UserInteractionFlag>, Error> {
557        match key_type {
558            KeyType::Signing => self.state.ard().uif_pso_cds(),
559            KeyType::Decryption => self.state.ard().uif_pso_dec(),
560            KeyType::Authentication => self.state.ard().uif_pso_aut(),
561            KeyType::Attestation => self.state.ard().uif_attestation(),
562        }
563    }
564
565    /// List of CA-Fingerprints of “Ultimately Trusted Keys”.
566    /// May be used to verify Public Keys from servers.
567    pub fn ca_fingerprints(&mut self) -> Result<[Option<Fingerprint>; 3], Error> {
568        self.state.ard().ca_fingerprints()
569    }
570
571    /// Get optional "Private use" data from the card.
572    ///
573    /// The presence and maximum length of these DOs is announced
574    /// in [`ExtendedCapabilities`].
575    ///
576    /// If available, there are 4 data fields for private use:
577    ///
578    /// - `1`: read accessible without PIN verification
579    /// - `2`: read accessible without PIN verification
580    /// - `3`: read accessible with User PIN verification
581    /// - `4`: read accessible with Admin PIN verification
582    pub fn private_use_do(&mut self, num: u8) -> Result<Vec<u8>, Error> {
583        self.state.opt.private_use_do(num)
584    }
585
586    /// Login Data
587    ///
588    /// This DO can be used to store any information used for the Log-In
589    /// process in a client/server authentication (e.g. user name of a
590    /// network).
591    /// The maximum length of this DO is announced in Extended Capabilities.
592    pub fn login_data(&mut self) -> Result<Vec<u8>, Error> {
593        self.state.opt.login_data()
594    }
595
596    // --- URL (5f50) ---
597
598    /// Get "cardholder" URL from the card.
599    ///
600    /// "The URL should contain a link to a set of public keys in OpenPGP format, related to
601    /// the card."
602    pub fn url(&mut self) -> Result<String, Error> {
603        Ok(String::from_utf8_lossy(&self.state.opt.url()?).to_string())
604    }
605
606    /// Cardholder related data (contains the fields: Name, Language preferences and Sex)
607    pub fn cardholder_related_data(&mut self) -> Result<CardholderRelatedData, Error> {
608        self.state.opt.cardholder_related_data()
609    }
610
611    // Unicode codepoints are a superset of iso-8859-1 characters
612    fn latin1_to_string(s: &[u8]) -> String {
613        s.iter().map(|&c| c as char).collect()
614    }
615
616    /// Get cardholder name.
617    ///
618    /// This is an ISO 8859-1 (Latin 1) String of up to 39 characters.
619    ///
620    /// Note that the standard specifies that this field should be encoded
621    /// according to ISO/IEC 7501-1:
622    ///
623    /// "The data element consists of surname (e. g. family name and given
624    /// name(s)) and forename(s) (including name suffix, e. g., Jr. and number).
625    /// Each item is separated by a ´<´ filler character (3C), the family- and
626    /// fore-name(s) are separated by two ´<<´ filler characters."
627    ///
628    /// This library doesn't perform this encoding.
629    pub fn cardholder_name(&mut self) -> Result<String, Error> {
630        let crd = self.state.opt.cardholder_related_data()?;
631
632        match crd.name() {
633            Some(name) => Ok(Self::latin1_to_string(name)),
634            None => Ok("".to_string()),
635        }
636    }
637
638    /// Get the current digital signature count (how many signatures have been issued by the card)
639    pub fn digital_signature_count(&mut self) -> Result<u32, Error> {
640        Ok(self
641            .state
642            .opt
643            .security_support_template()?
644            .signature_count())
645    }
646
647    /// SELECT DATA ("select a DO in the current template").
648    pub fn select_data(&mut self, num: u8, tag: &[u8]) -> Result<(), Error> {
649        self.state.opt.select_data(num, tag)
650    }
651
652    /// Get cardholder certificate.
653    ///
654    /// Call select_data() before calling this fn to select a particular
655    /// certificate (if the card supports multiple certificates).
656    pub fn cardholder_certificate(&mut self) -> Result<Vec<u8>, Error> {
657        self.state.opt.cardholder_certificate()
658    }
659
660    /// "GET NEXT DATA" for the DO cardholder certificate.
661    ///
662    /// Cardholder certificate data for multiple slots can be read from the card by first calling
663    /// cardholder_certificate(), followed by up to two calls to  next_cardholder_certificate().
664    pub fn next_cardholder_certificate(&mut self) -> Result<Vec<u8>, Error> {
665        self.state.opt.next_cardholder_certificate()
666    }
667
668    /// Get KDF DO configuration (from cache).
669    pub fn kdf_do(&mut self) -> Result<KdfDo, Error> {
670        if let Some(kdf) = self.state.kdf_do() {
671            Ok(kdf.clone())
672        } else {
673            Err(Error::NotFound("No KDF DO found".to_string()))
674        }
675    }
676
677    /// Algorithm Information (list of supported Algorithm attributes).
678    pub fn algorithm_information(&mut self) -> Result<Option<AlgorithmInformation>, Error> {
679        // The DO "Algorithm Information" (Tag FA) shall be present if
680        // Algorithm attributes can be changed
681        let ec = self.extended_capabilities()?;
682        if !ec.algo_attrs_changeable() {
683            // Algorithm attributes can not be changed,
684            // list_supported_algo is not supported
685            return Ok(None);
686        }
687
688        self.state.opt.algorithm_information()
689    }
690
691    /// "MANAGE SECURITY ENVIRONMENT".
692    /// Make `key_ref` usable for the operation normally done by the key
693    /// designated by `for_operation`
694    pub fn manage_security_environment(
695        &mut self,
696        for_operation: KeyType,
697        key_ref: KeyType,
698    ) -> Result<(), Error> {
699        self.state
700            .opt
701            .manage_security_environment(for_operation, key_ref)
702    }
703
704    // ----------
705
706    /// Get "Attestation Certificate (Yubico)"
707    pub fn attestation_certificate(&mut self) -> Result<Vec<u8>, Error> {
708        self.state.opt.attestation_certificate()
709    }
710
711    /// Firmware Version, YubiKey specific (?)
712    pub fn firmware_version(&mut self) -> Result<Vec<u8>, Error> {
713        self.state.opt.firmware_version()
714    }
715
716    /// Set "identity", Nitrokey Start specific (possible values: 0, 1, 2).
717    /// <https://docs.nitrokey.com/start/windows/multiple-identities.html>
718    ///
719    /// A Nitrokey Start can present as 3 different virtual OpenPGP cards.
720    /// This command enables one of those virtual cards.
721    ///
722    /// Each virtual card identity behaves like a separate, independent OpenPGP card.
723    pub fn set_identity(&mut self, id: u8) -> Result<(), Error> {
724        // FIXME: what is in the returned data - is it ever useful?
725        let _ = self.state.opt.set_identity(id)?;
726
727        Ok(())
728    }
729
730    // ----------
731
732    /// Get the raw public key material for a key slot on the card
733    pub fn public_key_material(&mut self, key_type: KeyType) -> Result<PublicKeyMaterial, Error> {
734        self.state.opt.public_key(key_type)
735    }
736
737    // ----------
738
739    /// Reset all state on this OpenPGP card
740    pub fn factory_reset(&mut self) -> Result<(), Error> {
741        match self.state.opt.factory_reset() {
742            Ok(()) => {
743                self.state.invalidate_cache();
744                Ok(())
745            }
746            Err(e) => Err(e),
747        }
748    }
749}
750
751impl<'app> Card<User<'app, '_>> {
752    /// Helper fn to easily access underlying openpgp_card object
753    fn card(&mut self) -> &mut crate::ocard::Transaction<'app> {
754        &mut self.state.tx.state.opt
755    }
756
757    // FIXME
758
759    // pub fn decryptor(
760    //     &mut self,
761    //     touch_prompt: &'open (dyn Fn() + Send + Sync),
762    // ) -> Result<CardDecryptor<'_, 'app>, Error> {
763    //     let pk = self
764    //         .state
765    //         .tx
766    //         .public_key(KeyType::Decryption)?
767    //         .expect("Couldn't get decryption pubkey from card");
768    //
769    //     Ok(CardDecryptor::with_pubkey(self.card(), pk, touch_prompt))
770    // }
771    //
772    // pub fn decryptor_from_public(
773    //     &mut self,
774    //     pubkey: PublicKey,
775    //     touch_prompt: &'open (dyn Fn() + Send + Sync),
776    // ) -> CardDecryptor<'_, 'app> {
777    //     CardDecryptor::with_pubkey(self.card(), pubkey, touch_prompt)
778    // }
779    //
780    // pub fn authenticator(
781    //     &mut self,
782    //     touch_prompt: &'open (dyn Fn() + Send + Sync),
783    // ) -> Result<CardSigner<'_, 'app>, Error> {
784    //     let pk = self
785    //         .state
786    //         .tx
787    //         .public_key(KeyType::Authentication)?
788    //         .expect("Couldn't get authentication pubkey from card");
789    //
790    //     Ok(CardSigner::with_pubkey_for_auth(
791    //         self.card(),
792    //         pk,
793    //         touch_prompt,
794    //     ))
795    // }
796    // pub fn authenticator_from_public(
797    //     &mut self,
798    //     pubkey: PublicKey,
799    //     touch_prompt: &'open (dyn Fn() + Send + Sync),
800    // ) -> CardSigner<'_, 'app> {
801    //     CardSigner::with_pubkey_for_auth(self.card(), pubkey, touch_prompt)
802    // }
803
804    /// Set optional "Private use" data on the card.
805    ///
806    /// The presence and maximum length of these DOs is announced
807    /// in [`ExtendedCapabilities`].
808    ///
809    /// If available, there are 4 data fields for private use:
810    ///
811    /// - `1`: write accessible with User PIN verification
812    /// - `2`: write accessible with Admin PIN verification
813    /// - `3`: write accessible with User PIN verification
814    /// - `4`: write accessible with Admin PIN verification
815    pub fn set_private_use_do(&mut self, num: u8, data: Vec<u8>) -> Result<(), Error> {
816        self.card().set_private_use_do(num, data)
817    }
818}
819
820impl<'app, 'open> Card<Sign<'app, 'open>> {
821    /// Helper fn to easily access underlying openpgp_card object
822    fn card(&mut self) -> &mut crate::ocard::Transaction<'app> {
823        &mut self.state.tx.state.opt
824    }
825
826    // FIXME
827
828    // pub fn signer(
829    //     &mut self,
830    //     touch_prompt: &'open (dyn Fn() + Send + Sync),
831    // ) -> Result<CardSigner<'_, 'app>, Error> {
832    //     // FIXME: depending on the setting in "PW1 Status byte", only one
833    //     // signature can be made after verification for signing
834    //
835    //     let pk = self
836    //         .state
837    //         .tx
838    //         .public_key(KeyType::Signing)?
839    //         .expect("Couldn't get signing pubkey from card");
840    //
841    //     Ok(CardSigner::with_pubkey(self.card(), pk, touch_prompt))
842    // }
843    //
844    // pub fn signer_from_public(
845    //     &mut self,
846    //     pubkey: PublicKey,
847    //     touch_prompt: &'open (dyn Fn() + Send + Sync),
848    // ) -> CardSigner<'_, 'app> {
849    //     // FIXME: depending on the setting in "PW1 Status byte", only one
850    //     // signature can be made after verification for signing
851    //
852    //     CardSigner::with_pubkey(self.card(), pubkey, touch_prompt)
853    // }
854
855    /// Generate Attestation (Yubico)
856    pub fn generate_attestation(
857        &mut self,
858        key_type: KeyType,
859        touch_prompt: &'open (dyn Fn() + Send + Sync),
860    ) -> Result<(), Error> {
861        // Touch is required if:
862        // - the card supports the feature
863        // - and the policy is set to a value other than 'Off'
864        if let Some(uif) = self.state.tx.state.ard().uif_attestation()? {
865            if uif.touch_policy().touch_required() {
866                (touch_prompt)();
867            }
868        }
869
870        self.card().generate_attestation(key_type)
871    }
872}
873
874impl<'app> Card<Admin<'app, '_>> {
875    pub fn as_transaction(&'_ mut self) -> &mut Card<Transaction<'app>> {
876        self.state.tx
877    }
878
879    /// Helper fn to easily access underlying openpgp_card object
880    fn card(&mut self) -> &mut crate::ocard::Transaction<'app> {
881        &mut self.state.tx.state.opt
882    }
883}
884
885impl Card<Admin<'_, '_>> {
886    /// Set cardholder name.
887    ///
888    /// This is an ISO 8859-1 (Latin 1) String of max. 39 characters.
889    ///
890    /// Note that the standard specifies that this field should be encoded according
891    /// to ISO/IEC 7501-1:
892    ///
893    /// "The data element consists of surname (e. g. family name and given
894    /// name(s)) and forename(s) (including name suffix, e. g., Jr. and number).
895    /// Each item is separated by a ´<´ filler character (3C), the family- and
896    /// fore-name(s) are separated by two ´<<´ filler characters."
897    ///
898    /// This library doesn't perform this encoding.
899    pub fn set_cardholder_name(&mut self, name: &str) -> Result<(), Error> {
900        // All chars must be in ASCII7
901        if !name.is_ascii() {
902            return Err(Error::InternalError("Invalid char in name".into()));
903        };
904
905        // FIXME: encode spaces and do ordering
906
907        if name.len() >= 40 {
908            return Err(Error::InternalError("name too long".into()));
909        }
910
911        self.card().set_name(name.as_bytes())
912    }
913
914    pub fn set_lang(&mut self, lang: &[Lang]) -> Result<(), Error> {
915        if lang.len() > 8 {
916            return Err(Error::InternalError("lang too long".into()));
917        }
918
919        self.card().set_lang(lang)
920    }
921
922    pub fn set_sex(&mut self, sex: Sex) -> Result<(), Error> {
923        self.card().set_sex(sex)
924    }
925
926    /// Set optional "Private use" data on the card.
927    ///
928    /// The presence and maximum length of these DOs is announced
929    /// in [`ExtendedCapabilities`].
930    ///
931    /// If available, there are 4 data fields for private use:
932    ///
933    /// - `1`: write accessible with User PIN verification
934    /// - `2`: write accessible with Admin PIN verification
935    /// - `3`: write accessible with User PIN verification
936    /// - `4`: write accessible with Admin PIN verification
937    pub fn set_private_use_do(&mut self, num: u8, data: Vec<u8>) -> Result<(), Error> {
938        self.card().set_private_use_do(num, data)
939    }
940
941    pub fn set_login_data(&mut self, login_data: &[u8]) -> Result<(), Error> {
942        self.card().set_login(login_data)
943    }
944
945    /// Set "cardholder" URL on the card.
946    ///
947    /// "The URL should contain a link to a set of public keys in OpenPGP format, related to
948    /// the card."
949    pub fn set_url(&mut self, url: &str) -> Result<(), Error> {
950        if !url.is_ascii() {
951            return Err(Error::InternalError("Invalid char in url".into()));
952        }
953
954        // Check for max len
955        let ec = self.state.tx.extended_capabilities()?;
956
957        if url.len() <= ec.max_len_special_do().unwrap_or(u16::MAX) as usize {
958            // If we don't know the max length for URL ("special DO"),
959            // or if it's within the acceptable length:
960            // send the url update to the card.
961
962            self.card().set_url(url.as_bytes())
963        } else {
964            Err(Error::InternalError("URL too long".into()))
965        }
966    }
967
968    /// Set PW Status Bytes.
969    ///
970    /// According to the spec, length information should not be changed.
971    ///
972    /// If `long` is false, sends 1 byte to the card, otherwise 4.
973    ///
974    /// So, effectively, with `long == false` the setting `pw1_cds_multi`
975    /// can be changed.
976    /// With `long == true`, the settings `pw1_pin_block` and `pw3_pin_block`
977    /// can also be changed.
978    pub fn set_pw_status_bytes(
979        &mut self,
980        pw_status: &PWStatusBytes,
981        long: bool,
982    ) -> Result<(), Error> {
983        self.card().set_pw_status_bytes(pw_status, long)?;
984
985        self.state.tx.state.invalidate_cache_ard();
986        Ok(())
987    }
988
989    /// Configure the "only valid for one PSO:CDS" setting in PW Status Bytes.
990    ///
991    /// If `once` is `true`, the User PIN must be verified before each
992    /// signing operation on the card.
993    /// If `once` is `false`, one User PIN verification is good for an
994    /// unlimited number of signing operations.
995    pub fn set_user_pin_signing_validity(&mut self, once: bool) -> Result<(), Error> {
996        let mut pws = self.as_transaction().pw_status_bytes()?;
997        pws.set_pw1_cds_valid_once(once);
998
999        self.set_pw_status_bytes(&pws, false)
1000    }
1001
1002    /// Set the touch policy for a key slot (if the card supports this
1003    /// feature).
1004    ///
1005    /// Note that the current touch policy setting (if available) can be read
1006    /// via [`Card<Transaction>::user_interaction_flag`].
1007    ///
1008    /// (Caution: Setting the touch policy of the "Attestation" slot on YubiKey 5 devices
1009    /// to a variation of "Fixed" is permanent for the lifetime of the hardware device!
1010    /// It can't be undone with a factory reset!)
1011    pub fn set_touch_policy(&mut self, key: KeyType, policy: TouchPolicy) -> Result<(), Error> {
1012        let uif = match key {
1013            KeyType::Signing => self.state.tx.state.ard().uif_pso_cds()?,
1014            KeyType::Decryption => self.state.tx.state.ard().uif_pso_dec()?,
1015            KeyType::Authentication => self.state.tx.state.ard().uif_pso_aut()?,
1016            KeyType::Attestation => self.state.tx.state.ard().uif_attestation()?,
1017        };
1018
1019        if let Some(mut uif) = uif {
1020            uif.set_touch_policy(policy);
1021
1022            match key {
1023                KeyType::Signing => self.card().set_uif_pso_cds(&uif)?,
1024                KeyType::Decryption => self.card().set_uif_pso_dec(&uif)?,
1025                KeyType::Authentication => self.card().set_uif_pso_aut(&uif)?,
1026                KeyType::Attestation => self.card().set_uif_attestation(&uif)?,
1027            }
1028        } else {
1029            return Err(Error::UnsupportedFeature(
1030                "User Interaction Flag not available".into(),
1031            ));
1032        };
1033
1034        self.state.tx.state.invalidate_cache_ard();
1035        Ok(())
1036    }
1037
1038    /// Set the User PIN on the card (also resets the User PIN error count)
1039    pub fn reset_user_pin(&mut self, new: SecretString) -> Result<(), Error> {
1040        let new = map_pin(new, PinType::Pw1, self.state.tx.state.kdf_do())?;
1041
1042        self.card().reset_retry_counter_pw1(new, None)?;
1043
1044        self.state.tx.state.invalidate_cache_ard();
1045        Ok(())
1046    }
1047
1048    /// Define the "resetting code" on the card
1049    pub fn set_resetting_code(&mut self, pin: SecretString) -> Result<(), Error> {
1050        let pin = map_pin(pin, PinType::Rc, self.state.tx.state.kdf_do())?;
1051
1052        self.card().set_resetting_code(pin)?;
1053
1054        self.state.tx.state.invalidate_cache_ard();
1055        Ok(())
1056    }
1057
1058    /// Set optional AES encryption/decryption key
1059    /// (32 bytes for AES256, or 16 bytes for AES128),
1060    /// if the card supports this feature.
1061    ///
1062    /// The availability of this feature is announced in
1063    /// [`Card<Transaction>::extended_capabilities`].
1064    pub fn set_pso_enc_dec_key(&mut self, key: &[u8]) -> Result<(), Error> {
1065        self.card().set_pso_enc_dec_key(key)
1066    }
1067
1068    /// Import a private key to the card into a specific key slot.
1069    ///
1070    /// (The caller needs to make sure that the content of `key` is suitable for `key_type`)
1071    pub fn import_key(
1072        &mut self,
1073        key: &dyn CardUploadableKey,
1074        key_type: KeyType,
1075    ) -> Result<(), Error> {
1076        self.card().key_import(key, key_type)?;
1077
1078        self.state.tx.state.invalidate_cache_ard();
1079        Ok(())
1080    }
1081
1082    /// Configure the `algorithm_attributes` for key slot `key_type` based on
1083    /// the algorithm `algo`.
1084    /// This can be useful in preparation for [`Self::generate_key`].
1085    ///
1086    /// This is a convenience wrapper for [`Self::set_algorithm_attributes`]
1087    /// that determines the exact appropriate [`AlgorithmAttributes`] by
1088    /// reading information from the card.
1089    pub fn set_algorithm(&mut self, key_type: KeyType, algo: AlgoSimple) -> Result<(), Error> {
1090        let attr = algo.matching_algorithm_attributes(self.card(), key_type)?;
1091        self.set_algorithm_attributes(key_type, &attr)
1092    }
1093
1094    /// Configure the key slot `key_type` to `algorithm_attributes`.
1095    /// This can be useful in preparation for [`Self::generate_key`].
1096    ///
1097    /// Note that legal values for [`AlgorithmAttributes`] are card-specific.
1098    /// Different OpenPGP card implementations may support different
1099    /// algorithms, sometimes with differing requirements for the encoding
1100    /// (e.g. field sizes)
1101    ///
1102    /// See [`Self::set_algorithm`] for a convenience function that sets
1103    /// the algorithm attributes based on an [`AlgoSimple`].
1104    pub fn set_algorithm_attributes(
1105        &mut self,
1106        key_type: KeyType,
1107        algorithm_attributes: &AlgorithmAttributes,
1108    ) -> Result<(), Error> {
1109        self.card()
1110            .set_algorithm_attributes(key_type, algorithm_attributes)?;
1111
1112        self.state.tx.state.invalidate_cache_ard();
1113        Ok(())
1114    }
1115
1116    /// Generate a new cryptographic key in slot `key_type`, with the currently
1117    /// configured cryptographic algorithm
1118    /// (see [`Self::set_algorithm`] for changing the algorithm setting).
1119    pub fn generate_key(
1120        &mut self,
1121        fp_from_pub: fn(
1122            &PublicKeyMaterial,
1123            KeyGenerationTime,
1124            KeyType,
1125        ) -> Result<Fingerprint, Error>,
1126        key_type: KeyType,
1127    ) -> Result<(PublicKeyMaterial, KeyGenerationTime), Error> {
1128        let res = self.card().generate_key(fp_from_pub, key_type)?;
1129
1130        self.state.tx.state.invalidate_cache_ard();
1131        Ok(res)
1132    }
1133}