Class desfire::tag

Inheritance Relationships

Base Type

  • public std::enable_shared_from_this< tag >

Class Documentation

class tag : public std::enable_shared_from_this<tag>

Main class representing a Desfire tag.

Note

This class is stateful, and despite being very lightweight (does not store anything about the card), still has to store the protocol and cipher status, authentication status, active app and so on. It does not store the keys, that are only used for authentication and to derive a session key (which might be stored into the crypto implementation).

Move-only semantics.

tag(tag const&) = delete
tag(tag&&) = default
tag &operator=(tag const&) = delete
tag &operator=(tag&&) = default

Assert communication mode

All these methods take a validated parameter. This means that the communication mode has been validated, i.e. tested and decided by libSpookyAction. For the overloads that instead take the comm mode from the user, we assume that there could be a user error and the comm mode is incorrect. In the first case, we have a hard error message on a different message tag. In the second, we just issue a regular warning.

Public Functions

tag(std::shared_ptr<pn532::controller> ctrl, std::uint8_t logical_index)

Construct a new tag object through a pn532::desfire_pcd PCD subclass. This will use the platform default cipher provider.

Parameters:
  • ctrl – PN532 controller.

  • logical_index – Logical index of the target.

explicit tag(std::shared_ptr<desfire::pcd> pcd)

Construct a new tag object with a custom PCD. This will use the platform default cipher provider.

Note

If you want to handle a custom PCD, you should extend desfire::pcd and implement desfire::pcd::communicate.

Parameters:

pcd – A desfire::pcd class that handles the tag communication.

tag(std::shared_ptr<desfire::pcd> pcd, std::unique_ptr<cipher_provider> provider)

Construct a new tag object with a custom PCD and cipher provider.

Parameters:
result<bin_data> raw_command_response(bin_stream &tx_data, bool rx_fetch_additional_frames)

Exchanges a raw command with the tag.

Note

This method is not private because we do not have access to a Desfire/Mifare specification, therefore we cannot guarantee that the list of commands implemented here is at all complete. Users who have access to the manual may therefore directly send packets encoding further commands without having to explicitly extend or modify this class.

Parameters:
  • tx_data – Already preprocessed data, containing command code and payload.

  • rx_fetch_additional_frames – If true and the response is marked as being incomplete (“additional frames”), it will automatically continue fetching data until when the response is complete. Otherwise, it will return the response with the additional frame marker as-is.

Returns:

bin_data, or the following errors:

result<bits::status, bin_data> command_status_response(bits::command_code cmd, bin_data const &payload, comm_cfg const &cfg, bool rx_fetch_additional_frames = true, protocol *override_protocol = nullptr)

Assembles and preprocesses a commands, sends it over and postprocesses the answer. This method automatically divides data into appropriate chunks and sends them to the PICC, pre-processing the data to send according to cfg by means of protocol::prepare_tx (which is called on every chunk). It will then collect the response data, and if cfg allows, it will also automatically concatenate all response chunks, should the PICC request to send additional frames. The response data is the post-processed by means of protocol::confirm_rx, as set by cfg. The status byte is passed through and returned.

Note

Only returns an error in case of malformed packet sequence, communication error, malformed data in the sense of not passing protocol::confirm_rx. All other status codes are passed through as the first result arguments. To automatically convert the status into an error, see command_response or command_parse_response. This is a lower level command.

Parameters:
  • cmd – Command code of the command to issue.

  • payload – Payload of the command (might be empty).

  • cfg – Communication configuration.

  • rx_fetch_additional_frames – If true and the response is marked as being incomplete (“additional frames”), it will automatically continue fetching data until when the response is complete. Otherwise the returned status byte will be “additional frames”.

  • override_protocol – Specify a valid pointer to a protocol to use a different protocol other than the currently set up one for preparing the transmission and decoding the response. This is useful in a very specific scenario: when authenticating to a different key.

Returns:

The status and the response payload, or one the following errors:

result<bin_data> command_response(bits::command_code cmd, bin_data const &payload, comm_cfg const &cfg, bool rx_fetch_additional_frames = true, protocol *override_protocol = nullptr)

Like command_status_response, but will also convert the status byte into a error. Will automatically fetch all additional frames if requested to do so by cfg, and at the end will parse the status byte to decide whether the command was successful (status::ok or status::no_changes).

Parameters:
  • cmd – Command code of the command to issue.

  • payload – Payload of the command (might be empty).

  • cfg – Communication configuration.

  • rx_fetch_additional_frames – If true and the response is marked as being incomplete (“additional frames”), it will automatically continue fetching data until when the response is complete. Otherwise the returned status byte will be “additional frames”.

  • override_protocol – Specify a valid pointer to a protocol to use a different protocol other than the currently set up one for preparing the transmission and decoding the response. This is useful in a very specific scenario: when authenticating to a different key.

Returns:

The response payload, or any of error.

template<is_parsable_reponse_t Data>
result<Data> command_parse_response(bits::command_code cmd, bin_data const &payload, comm_cfg const &cfg)

Like command_response, but will also parse the returned bin_data into a specific type Data. This command will always fetch additional frames until the end.

See also

command_response

Template Parameters:

Data – Type into which to convert the obtained response data. Must be extractable from mlab::bin_stream.

Parameters:
  • cmd – Command code of the command to issue.

  • payload – Payload of the command (might be empty).

  • cfg – Communication configuration.

Returns:

The response payload, or any of error.

inline app_id const &active_app() const

The currently active app id (by default, root_app).

inline cipher_type active_cipher_type() const

The cipher_type of the currently active key (by default, cipher_type::none).

See also

authenticate

inline std::uint8_t active_key_no() const

The number of the currently authenticated key (0..13, included), or 0xff if no authentication has taken place.

See also

authenticate

result authenticate(any_key const &k)

Authenticates to the active application active_app with key k. As a consequence, active_cipher_type and active_key_no will be updated.

Parameters:

k – Key to use to authenticate.

Returns:

Either mlab::result_success or any of error (usually error::authentication_error or error::permission_denied).

template<cipher_type Type>
result authenticate(key<Type> const &k)

Authenticates to the active application active_app with key k. As a consequence, active_cipher_type and active_key_no will be updated. Strongly-typed version of authenticate(any_key const &).

Template Parameters:

Type – Type of the key and cipher.

Parameters:

k – Key to use to authenticate.

Returns:

Either mlab::result_success or any of error (usually error::authentication_error or error::permission_denied).

result select_application(app_id const &aid = root_app)

Selects the application to use for successive operations. After selecting a new application, the PICC is logged out and you need to authenticate again.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0x5A\n[1 byte]|AID\n[3 byte LSB first]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Parameters:

aid – The id of the app to be selected.

Returns:

Either mlab::result_success or any of error. If the app is not present, error::app_not_found is returned.

result create_application(app_id const &aid, app_settings settings)

Add a new application to the card. Must be on the root_app for this to succeed (select_application), and a previous authenticate must have taken place, unless the root_app’s key_rights::create_delete_without_master_key is set to true. In that case, no authentication is necessary.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0xCA\n[1 byte]|AID\n[3 byte LSB first]|key settings\n[1 byte]|# of Keys\n[1 byte]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Parameters:
  • aid – The id of the new app to be created.

  • settings – Configuration of tha app (mainly: number of keys and witch cipher to use)

Returns:

Either mlab::result_success or any of error, in particular error::permission_denied if the operation is now allowed, or error::duplicate_error if the app exists already.

result change_app_settings(key_rights new_rights)

Change the setting of active_app. This requires a previous authenticate command with the app master key (i.e. key number zero); moreover the app’s key_rights::config_changeable must be set to true.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0x54\n[1 byte]|key settings\n[8 byte enchipered]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Parameters:

new_rights – the new app settings

Returns:

Either mlab::result_success or any of error, in particular error::permission_denied.

result<app_settings> get_app_settings()

Get the configuration of active_app. The app need to be selected first (with select_application) for this to succeed. Moreover, you need to authenticate with the master key, unless the app’s key_rights::dir_access_without_auth is set to true.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0x45\n[1 byte]}"]; received1 [label="{0x00\n[1 byte]|key settings\n[1 byte]|# of Keys\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Returns:

The app_settings, any of error, in particular error::permission_denied.

result<std::uint8_t> get_key_version(std::uint8_t key_no)

Get the version of the key (in the active_app).

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0x64\n[1 byte]|Key #\n[1 byte]}"]; received1 [label="{0x00\n[1 byte]|key version\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Parameters:

key_no – Number of the key, an integer in the range 0..13 (included). If an out-of-range number is specified, this method returns error::parameter_error.

Returns:

Integer representing the key version, any of error, in particular error::parameter_error.

result<std::vector<app_id>> get_application_ids()

Get a list of all application in the card. Must be on the root_app (select_application) for this to succeed. Moreover, a previous authenticate command might be required, unless the root_app’s key_rights::dir_access_without_auth is set to true.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0x6A\n[1 byte]}"]; received1 [label="{0x00\n[1 byte]|AID\n[3xN byte 0-7 AIDs]}"]; received2 [label="{0xAF\n[1 byte]|AID\n[3xN byte 0-19 AIDs]}"]; received3 [label="{0x00\n[1 byte]|AID\n[3xN byte 0-7 AIDs]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent2 [label="{0xAF\n[1 byte]}"]; sent1 -> {received1 received2 error}[sametail="b"]; received2 -> sent2 -> received3; }

Returns:

Vector of app_id, any of error, in particular error::permission_denied.

result delete_application(app_id const &aid)

Delete the application, and all data stored in it. Must authenticated on the root_app or in aid, with the master key (key number zero) for this to succeed. Alternatively, if the root_app’s key_rights::create_delete_without_master_key is set to true, the deletion can be performed without authentication on the root_app.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0xDA\n[1 byte]|AID\n[3 byte LSB first]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Parameters:

aid – The app ID of the application to be deleted

Returns:

Either mlab::result_success or any of error, in particular error::permission_denied.

result<manufacturing_info> get_info()

Read tag information. Serial number, production year and so on. We conjecture this can be called on any app and without authentication.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; graph [ranksep=2] subgraph cluster_ss{ sent1 [label="{0x60\n[1 byte]}"]; sent2 [label="{0xAF\n[1 byte]}"]; sent3 [label="{0xAF\n[1 byte]}"]; } subgraph cluster_rr{ received1 [label="{0xAF\n[1 byte]|Vendor ID\n[1 byte]|Type\n[1 byte]|Sub-type\n[1 byte]|Mayor version\n[1 byte]|Minor version\n[1 byte]|Tag size\n[1 byte]|protocol\n[1 byte]}"]; received2 [label="{0xAF\n[1 byte]|Vendor ID\n[1 byte]|Type\n[1 byte]|Sub-type\n[1 byte]|Mayor version\n[1 byte]|Minor version\n[1 byte]|Tag size\n[1 byte]|protocol\n[1 byte]}"]; received3 [label="{0x00\n[1 byte]|UID\n[7 byte]|Batch #\n[5 byte]|Production week\n[1 byte]|Production year\n[1 byte]}"]; } sent1 -> received1 [samehead="s1" ]; sent2 -> received1 [samehead="s1" sametail="r1" dir=back ]; sent2 -> received2[sametail="r1" samehead="s2"]; sent3 -> received2[samehead="s2" sametail="r2" dir=back]; sent3 -> received3[sametail="r2"]; }

Returns:

A manufacturing_info instance containing tag information, or any of error.

result format_picc()

Delete all the applications and files. This requires a previous authenticate of root_app with the master (root) key. Afterwards, the PICC will be on root_app with no authentication.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0xFC\n[1 byte]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Note

This does not change the root key and the root_app’s settings!

Returns:

Either mlab::result_success or any of error.

result change_key(any_key const &new_key)

Changes the current key. You must have a valid authenticate with the key of the same number as new_key. Moreover, the active_app’s key_rights::allowed_to_change_keys must be either same_key, or exactly active_key_no. After this command, the app is unchanged but a new authenticate command must be performed.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0x54\n[1 byte]|Key #\n[1 byte]|key body\n[24 byte echipered]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Returns:

Either mlab::result_success, or any of error, in particular error::permission_denied.

template<cipher_type Type>
result change_key(key<Type> const &new_key)

Changes the current key. Strongly-typed version of change_key(any_key const &). You must have a valid authenticate with the key of the same number as new_key. Moreover, the active_app’s key_rights::allowed_to_change_keys must be either same_key, or exactly active_key_no. After this command, the app is unchanged but a new authenticate command must be performed.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0x54\n[1 byte]|Key #\n[1 byte]|key body\n[24 byte echipered]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Returns:

Either mlab::result_success, or any of error, in particular error::permission_denied.

result change_key(any_key const &previous_key, any_key const &new_key)

Changes a key other than the active_key_no. You must have a valid authenticate with the key specified by active_app’s key_rights::allowed_to_change_keys in order for this to succeed. Moreover, you still need to pass the key to be changed together with the new key. In case of success, the app and the authentication status are unchanged.

Note

You are not supposed to use this to change active_key_no; if you do, this method will automatically attempt an authenticate command with previous_key, and then call change_key(any_key const &) with new_key instead. A new authentication will thus be required.

Parameters:
Returns:

Either mlab::result_success, or any of error, in particular error::permission_denied.

template<cipher_type Type>
result change_key(key<Type> const &previous_key, key<Type> const &new_key)

Changes a key other than the active_key_no. Strongly-typed version of change_key(any_key const &, any_key const &). You must have a valid authenticate with the key specified by active_app’s key_rights::allowed_to_change_keys in order for this to succeed. Moreover, you still need to pass the key to be changed together with the new key. In case of success, the app and the authentication status are unchanged.

Note

You are not supposed to use this to change active_key_no; if you do, this method will automatically attempt an authenticate command with previous_key, and then call change_key(any_key const &) with new_key instead. A new authentication will thus be required.

Parameters:
Returns:

Either mlab::result_success, or any of error, in particular error::permission_denied.

result<std::vector<file_id>> get_file_ids()

Get a list of files in active_app. You must have a preceding authenticate command on the app, or active_app’s key_rights::dir_access_without_auth must be set to true.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0x6F\n[1 byte]}"]; received1 [label="{0x00\n[1 byte]|FID\n[1xN byte (0-16 FIDs)]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Returns:

Vector of file_id, or any of error, in particular error::permission_denied.

result<any_file_settings> get_file_settings(file_id fid)

Read the file settings. You must have a preceding authenticate command on the app, or active_app’s key_rights::dir_access_without_auth must be set to true.

Parameters:

fid – The file id, in the range 0..15 (included).

Returns:

A any_file_settings containing the file settings, or any of error. In particular, if the file does not exist, error::file_not_found, or if the operation is not allowed, error::permission_denied.

template<file_type Type>
result<file_settings<Type>> get_specific_file_settings(file_id fid)

Read the settings of a specific file_type. You must have a preceding authenticate command on the app, or active_app’s key_rights::dir_access_without_auth must be set to true. Moreover, if the file exists, it must have exactly Type file_type.

Template Parameters:

Type – Expected file_type. In case of mismatch, error::malformed is returned.

Parameters:

fid – The file id, in the range 0..15 (included).

Returns:

A file_settings containing the file settings, or any of error. In particular, if the file does not exist, error::file_not_found, or if the operation is not allowed, error::permission_denied. If the file exists but has the wrong file_type, error::malformed.

result change_file_settings(file_id fid, common_file_settings const &settings, trust_card_t)

Modify the file settings. This requires a previous authenticate command on active_app, and the key must match the key number specified in any_file_settings::common_settings file_access_rights::change. If instead file_access_rights::change is set to free_access, no authentication is required, just select_application.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0x5F\n[1 byte]|FID\n[1 byte]|Comm. settings\n[1 byte]|Access rights\n[2 byte LDB first]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; sent1e [label="{0x5F\n[1 byte]|FID\n[1 byte]|new settings\n[8 byte enchipered]}"]; received1e [label="{0x00\n[1 byte]}"]; errore [style=dashed label="{Error code\n[1 byte]}"]; sent1e -> {received1e errore}[ sametail="b"]; }

Warning

Consider using the overload of this method which requires explicitly a comm_mode operation mode parameter. This method will auto-detect the security settings used: if a card is cloned and a file is created with the same id but different security, this method will accept the different security transmission mode. It may thus leak data.

Parameters:
  • fid – The file id, in the range 0..15 (included).

  • settings – The new file settings.

Returns:

Either mlab::result_success or any of error, in particular error::permission_denied or error::file_not_found.

result change_file_settings(file_id fid, common_file_settings const &settings, comm_mode operation_mode)

Modify the file settings. This requires a previous authenticate command on active_app, and the key must match the key number specified in any_file_settings::common_settings file_access_rights::change. If instead file_access_rights::change is set to free_access, no authentication is required, just select_application.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0x5F\n[1 byte]|FID\n[1 byte]|Comm. settings\n[1 byte]|Access rights\n[2 byte LDB first]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; sent1e [label="{0x5F\n[1 byte]|FID\n[1 byte]|new settings\n[8 byte enchipered]}"]; received1e [label="{0x00\n[1 byte]}"]; errore [style=dashed label="{Error code\n[1 byte]}"]; sent1e -> {received1e errore}[ sametail="b"]; }

Parameters:
  • fid – The file id, in the range 0..15 (included).

  • settings – The new file settings.

  • operation_mode – The communication mode to use for this operation. This is derived from the base file security and the value of file_access_rights::change member: a free access implies no security is specified, otherwise it falls back to the file’s own security mode.

Returns:

Either mlab::result_success or any of error, in particular error::permission_denied or error::file_not_found. If operation_mode is incorrect, error::crypto_error is returned.

result create_file(file_id fid, file_settings<file_type::standard> const &settings)

Create a new standard data file in active_app. This requires a valid authenticate command with the master key (key number zero), unless key_rights::create_delete_without_master_key is set to true.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0xCD\n[1 byte]|FID\n[1 byte]|Comm. settings\n[1 byte]|Access rights\n[2 byte LSB first]|File size\n[3 byte LSB first]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Parameters:
  • fid – The file id, in the range 0..15 (included).

  • settings – The new file settings.

Returns:

Either mlab::result_success or any of error, in particular error::permission_denied or error::duplicate_error if the file exists already.

result create_file(file_id fid, any_file_settings const &settings)

Create a new file in active_app. This requires a valid authenticate command with the master key (key number zero), unless key_rights::create_delete_without_master_key is set to true.

Parameters:
  • fid – The file id, in the range 0..15 (included). For any file other than file_type::standard, this can be at most 7.

  • settings – The new file settings.

Returns:

Either mlab::result_success or any of error, in particular error::permission_denied or error::duplicate_error if the file exists already.

result create_file(file_id fid, file_settings<file_type::backup> const &settings)

Create a new backup data file in active_app. This requires a valid authenticate command with the master key (key number zero), unless key_rights::create_delete_without_master_key is set to true.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0xCB\n[1 byte]|FID\n[1 byte]|Comm. settings\n[1 byte]|Access rights\n[2 byte LSB first]|File size\n[3 byte LSB first]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Parameters:
  • fid – The file id, in the range 0..7 (included).

  • settings – The new file settings.

Returns:

Either mlab::result_success or any of error, in particular error::permission_denied or error::duplicate_error if the file exists already.

result create_file(file_id fid, file_settings<file_type::value> const &settings)

Create a new value file in active_app. This requires a valid authenticate command with the master key (key number zero), unless key_rights::create_delete_without_master_key is set to true.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0xCC\n[1 byte]|FID\n[1 byte]|Comm. settings\n[1 byte]|Access rights\n[2 byte LSB first]|Lower Limit\n[4 byte LSB first]|Upper Limit\n[4 byte LSB first]|Value\n[4 byte LSB first]|Lim. credit\n[1 byte]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Parameters:
Returns:

Either mlab::result_success or any of error, in particular error::permission_denied or error::duplicate_error if the file exists already.

result create_file(file_id fid, file_settings<file_type::linear_record> const &settings)

Create a new linear record file in active_app. This requires a valid authenticate command with the master key (key number zero), unless key_rights::create_delete_without_master_key is set to true.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0xC1\n[1 byte]|FID\n[1 byte]|Comm. settings\n[1 byte]|Access rights\n[2 byte LSB first]|Record Size\n[3 byte LSB first]|Max # of records\n[3 byte LSB first]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Parameters:
Returns:

Either mlab::result_success or any of error, in particular error::permission_denied or error::duplicate_error if the file exists already.

result create_file(file_id fid, file_settings<file_type::cyclic_record> const &settings)

Create a new cyclic record file in active_app. This requires a valid authenticate command with the master key (key number zero), unless key_rights::create_delete_without_master_key is set to true.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0xC0\n[1 byte]|FID\n[1 byte]|Comm. settings\n[1 byte]|Access rights\n[2 byte LSB first]|Record Size\n[3 byte LSB first]|Max # of records\n[3 byte LSB first]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Parameters:
Returns:

Either mlab::result_success or any of error, in particular error::permission_denied or error::duplicate_error if the file exists already.

result delete_file(file_id fid)

Deletes a file from active_app. This requires a valid authenticate command with the master key (key number zero), unless key_rights::create_delete_without_master_key is set to true.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0xDF\n[1 byte]|FID\n[1 byte]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Parameters:

fid – The file id, in the range 0..15 (included).

Returns:

Either mlab::result_success or any of error, in particular error::permission_denied or error::file_not_found if the file does not exist.

result clear_record_file(file_id fid)

Clear the records from a linear or cyclic record file. This requires a valid authenticate command with a key that satisfies file_access_rights::read_write (possibly none if set to free_access).

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0xEB\n[1 byte]|FID\n[1 byte]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Parameters:

fid – The file id of the record file, in the range 0..7 (included).

Returns:

Either mlab::result_success or any of error, in particular error::permission_denied or error::file_not_found if the file does not exist.

result commit_transaction()

Commits all data to a value, record or backup file. The changes to any file type other than file_type::standard require a call to this method to be saved.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0xC7\n[1 byte]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Returns:

Either mlab::result_success or any of error, in particular error::permission_denied.

result abort_transaction()

Aborts any change to a value, record or backup file. Any change that has not been committed will be discarded.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0xA7\n[1 byte]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

See also

commit_transaction.

Returns:

Either mlab::result_success or any of error.

result<bin_data> read_data(file_id fid, trust_card_t, std::uint32_t offset = 0, std::uint32_t length = all_data)

Read data from a standard or backup file. This method requires a previous authenticate command with a key that is compatible with the file_access_rights::read (or file_access_rights::read_write) in order to complete successfully. If the file is a file_type::backup, this will read the content of the file after the last commit_transaction call, i.e. uncommitted changes are not reflected here.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0xBD\n[1 byte]|FID\n[1 byte]|Offset\n[3 byte LSB first]|Lenght\n[3 byte LSB first]}"]; received1 [label="{0xAF\n[1 byte]|DATA\n[1-59 bytes]}"]; received2 [label="{0x00\n[1 byte]|DATA\n[1-59 bytes]}"]; received3 [label="{0x00\n[1 byte]|DATA\n[1-59 bytes]}"]; sent2 [label="{0xAF\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 received2 error}[ sametail="b"]; received1 -> sent2 -> received3; }

Warning

Consider using the overload of this method which requires explicitly a comm_mode operation mode parameter. This method will auto-detect the security settings used: if a card is cloned and a file is created with the same id but different security, this method will accept the different security transmission mode. It may thus leak data.

Parameters:
  • fid – The file id, in the range 0..15 (included). For file_type::backup, this can be at most 7.

  • offset – Limited to 24 bits, i.e. must be below 0xFFFFFF. Must also be less than the file size.

  • length – Limited to 24 bits, i.e. must be below 0xFFFFFF. Specify all_data (zero) to read until the end.

Returns:

The data (or part thereof) in the file, or any of error. In particular, error::permission_denied, or error::file_not_found if the file does not exist. If offset or length are not valid, error::parameter_error and error::length_error are also possible.

result<bin_data> read_data(file_id fid, comm_mode operation_mode, std::uint32_t offset = 0, std::uint32_t length = all_data)

Read data from a standard or backup file. This method requires a previous authenticate command with a key that is compatible with the file_access_rights::read (or file_access_rights::read_write) in order to complete successfully. If the file is a file_type::backup, this will read the content of the file after the last commit_transaction call, i.e. uncommitted changes are not reflected here.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0xBD\n[1 byte]|FID\n[1 byte]|Offset\n[3 byte LSB first]|Lenght\n[3 byte LSB first]}"]; received1 [label="{0xAF\n[1 byte]|DATA\n[1-59 bytes]}"]; received2 [label="{0x00\n[1 byte]|DATA\n[1-59 bytes]}"]; received3 [label="{0x00\n[1 byte]|DATA\n[1-59 bytes]}"]; sent2 [label="{0xAF\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 received2 error}[ sametail="b"]; received1 -> sent2 -> received3; }

Parameters:
  • fid – The file id, in the range 0..15 (included). For file_type::backup, this can be at most 7.

  • operation_mode – The communication mode to use for this operation. This is derived from the base file security and the value of file_access_rights::read and file_access_rights::read_write members: a free access implies no security is specified, otherwise it falls back to the file’s own security mode.

  • offset – Limited to 24 bits, i.e. must be below 0xFFFFFF. Must also be less than the file size.

  • length – Limited to 24 bits, i.e. must be below 0xFFFFFF. Specify all_data (zero) to read until the end.

Returns:

The data (or part thereof) in the file, or any of error. In particular, error::permission_denied, or error::file_not_found if the file does not exist. If operation_mode is incorrect, error::crypto_error is returned. If offset or length are not valid, error::parameter_error and error::length_error are also possible.

result write_data(file_id fid, bin_data const &data, trust_card_t, std::uint32_t offset = 0)

Writes data to a standard or backup file. This method requires a previous authenticate command with a key that is compatible with the file_access_rights::write (or file_access_rights::read_write) in order to complete successfully. If the file is a file_type::backup, a subsequent call to commit_transaction is required.

Warning

Consider using the overload of this method which requires explicitly a comm_mode operation mode parameter. This method will auto-detect the security settings used: if a card is cloned and a file is created with the same id but different security, this method will accept the different security transmission mode. It may thus leak data.

Parameters:
  • fid – The file id, in the range 0..15 (included). For file_type::backup, this can be at most 7.

  • data – Limited to 24 bits, i.e. must be shorter than 0xFFFFFF.

  • offset – Limited to 24 bits, i.e. must be below 0xFFFFFF.

Returns:

Either mlab::result_success or any of error. In particular, error::permission_denied, or error::file_not_found if the file does not exist. If offset is not valid or data's length is invalid, error::parameter_error and error::length_error are also possible.

result write_data(file_id fid, bin_data const &data, comm_mode operation_mode, std::uint32_t offset = 0)

Writes data to a standard or backup file. This method requires a previous authenticate command with a key that is compatible with the file_access_rights::write (or file_access_rights::read_write) in order to complete successfully. If the file is a file_type::backup, a subsequent call to commit_transaction is required.

Parameters:
  • fid – The file id, in the range 0..15 (included). For file_type::backup, this can be at most 7.

  • data – Limited to 24 bits, i.e. must be shorten than 0xFFFFFF.

  • operation_mode – The communication mode to use for this operation. This is derived from the base file security and the value of file_access_rights::write and file_access_rights::read_write members: a free access implies no security is specified, otherwise it falls back to the file’s own security mode.

  • offset – Limited to 24 bits, i.e. must be below 0xFFFFFF.

Returns:

Either mlab::result_success or any of error. In particular, error::permission_denied, or error::file_not_found if the file does not exist. If operation_mode is incorrect, error::crypto_error is returned. If offset is not valid or data's length is invalid, error::parameter_error and error::length_error are also possible.

result<std::int32_t> get_value(file_id fid, trust_card_t)

Gets the content of a value file. This method requires a previous authenticate command with a key that is compatible with the file_access_rights::read, or file_access_rights::write, or file_access_rights::read_write in order to complete successfully. Any change that has not been committed via commit_transaction is not reflected in the returned value.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0x6C\n[1 byte]|FID\n[1 byte]}"]; received1 [label="{0x00\n[1 byte]|Value\n[4 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Warning

Consider using the overload of this method which requires explicitly a comm_mode operation mode parameter. This method will auto-detect the security settings used: if a card is cloned and a file is created with the same id but different security, this method will accept the different security transmission mode. It may thus leak data.

Parameters:

fid – The file id, in the range 0..7 (included).

Returns:

The value of the file or any of error. In particular, error::permission_denied, or error::file_not_found if the file does not exist.

result<std::int32_t> get_value(file_id fid, comm_mode operation_mode)

Gets the content of a value file. This method requires a previous authenticate command with a key that is compatible with the file_access_rights::read, or file_access_rights::write, or file_access_rights::read_write in order to complete successfully. Any change that has not been committed via commit_transaction is not reflected in the returned value.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0x6C\n[1 byte]|FID\n[1 byte]}"]; received1 [label="{0x00\n[1 byte]|Value\n[4 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Parameters:
  • fid – The file id, in the range 0..7 (included).

  • operation_mode – The communication mode to use for this operation. This is derived from the base file security and the value of file_access_rights::read and file_access_rights::read_write members: a free access implies no security is specified, otherwise it falls back to the file’s own security mode.

Returns:

The value of the file or any of error. In particular, error::permission_denied, or error::file_not_found if the file does not exist. If operation_mode is incorrect, error::crypto_error is returned.

result credit(file_id fid, std::int32_t amount, trust_card_t)

Increments a value file. This method requires a previous authenticate command with a key that is compatible with the file_access_rights::read_write in order to complete successfully. A call to commit_transaction is necessary to permanently update the value.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0x0C\n[1 byte]|FID\n[1 byte]| Credit anmount\n[4 byte]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Warning

Consider using the overload of this method which requires explicitly a comm_mode operation mode parameter. This method will auto-detect the security settings used: if a card is cloned and a file is created with the same id but different security, this method will accept the different security transmission mode. It may thus leak data.

Parameters:
  • fid – The file id, in the range 0..7 (included).

  • amount – Must be non-negative.

Returns:

Either mlab::result_success or any of error. In particular, error::permission_denied, or error::file_not_found if the file does not exist. If amount is invalid, error::parameter_error is also possible.

result credit(file_id fid, std::int32_t amount, comm_mode operation_mode)

Increments a value file. This method requires a previous authenticate command with a key that is compatible with the file_access_rights::read_write in order to complete successfully. A call to commit_transaction is necessary to permanently update the value.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0x0C\n[1 byte]|FID\n[1 byte]| Credit amount\n[4 byte]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Parameters:
  • fid – The file id, in the range 0..7 (included).

  • amount – Must be non-negative.

  • operation_mode – The communication mode to use for this operation. This is derived from the base file security and the value of file_access_rights::write and file_access_rights::read_write members: a free access implies no security is specified, otherwise it falls back to the file’s own security mode.

Returns:

Either mlab::result_success or any of error. In particular, error::permission_denied, or error::file_not_found if the file does not exist. If operation_mode is incorrect, error::crypto_error is returned. If amount is invalid, error::parameter_error is also possible.

result limited_credit(file_id fid, std::int32_t amount, trust_card_t)

Increments the value file, to the maximum amount of the past debit transactions. This method requires a previous authenticate command with a key that is compatible with the file_access_rights::write (or file_access_rights::read_write) in order to complete successfully. Moreover, the setting value_file_settings::limited_credit_enabled must be set to true. A call to commit_transaction is necessary to permanently update the value.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0xDC\n[1 byte]|FID\n[1 byte]| Credit anmount\n[4 byte]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Note

This can be used without full write/read permission. It can be use to refound a transaction in a safe way.

Warning

Consider using the overload of this method which requires explicitly a comm_mode operation mode parameter. This method will auto-detect the security settings used: if a card is cloned and a file is created with the same id but different security, this method will accept the different security transmission mode. It may thus leak data.

Parameters:
  • fid – The file id, in the range 0..7 (included).

  • amount – Must be non-negative.

Returns:

Either mlab::result_success or any of error. In particular, error::permission_denied, or error::file_not_found if the file does not exist. If amount is invalid, error::parameter_error is also possible.

result limited_credit(file_id fid, std::int32_t amount, comm_mode operation_mode)

Increments the value file, to the maximum amount of the past debit transactions. This method requires a previous authenticate command with a key that is compatible with the file_access_rights::write (or file_access_rights::read_write) in order to complete successfully. Moreover, the setting value_file_settings::limited_credit_enabled must be set to true. A call to commit_transaction is necessary to permanently update the value.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0xDC\n[1 byte]|FID\n[1 byte]| Credit anmount\n[4 byte]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Note

This can be used without full write/read permission. It can be use to refound a transaction in a safe way.

Parameters:
  • fid – The file id, in the range 0..7 (included).

  • amount – Must be non-negative.

  • operation_mode – The communication mode to use for this operation. This is derived from the base file security and the value of file_access_rights::write and file_access_rights::read_write members: a free access implies no security is specified, otherwise it falls back to the file’s own security mode.

Returns:

Either mlab::result_success or any of error. In particular, error::permission_denied, or error::file_not_found if the file does not exist. If operation_mode is incorrect, error::crypto_error is returned. If amount is invalid, error::parameter_error is also possible.

result debit(file_id fid, std::int32_t amount, trust_card_t)

Decrements a value file. This method requires a previous authenticate command with a key that is compatible with the file_access_rights::read, or file_access_rights::write, or file_access_rights::read_write in order to complete successfully. A call to commit_transaction is necessary to permanently update the value.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0xDC\n[1 byte]|FID\n[1 byte]| Debit anmount\n[4 byte]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Warning

Consider using the overload of this method which requires explicitly a comm_mode operation mode parameter. This method will auto-detect the security settings used: if a card is cloned and a file is created with the same id but different security, this method will accept the different security transmission mode. It may thus leak data.

Parameters:
  • fid – The file id, in the range 0..7 (included).

  • amount – Must be non-negative.

Returns:

Either mlab::result_success or any of error. In particular, error::permission_denied, or error::file_not_found if the file does not exist. If amount is invalid, error::parameter_error is also possible.

result debit(file_id fid, std::int32_t amount, comm_mode operation_mode)

Decrements a value file. This method requires a previous authenticate command with a key that is compatible with the file_access_rights::read, or file_access_rights::write, or file_access_rights::read_write in order to complete successfully. A call to commit_transaction is necessary to permanently update the value.

digraph AlignmentMap { node [shape=record fontname="Lato, proxima-nova, 'Helvetica Neue', Arial, sans-serif"]; rankdir=LR; sent1 [label="{0xDC\n[1 byte]|FID\n[1 byte]| Debit anmount\n[4 byte]}"]; received1 [label="{0x00\n[1 byte]}"]; error [style=dashed label="{Error code\n[1 byte]}"]; sent1 -> {received1 error}[ sametail="b"]; }

Parameters:
  • fid – The file id, in the range 0..7 (included).

  • amount – Must be non-negative.

  • operation_mode – The communication mode to use for this operation. This is derived from the base file security and the value of file_access_rights::write and file_access_rights::read_write members: a free access implies no security is specified, otherwise it falls back to the file’s own security mode.

Returns:

Either mlab::result_success or any of error. In particular, error::permission_denied, or error::file_not_found if the file does not exist. If operation_mode is incorrect, error::crypto_error is returned. If amount is invalid, error::parameter_error is also possible.

result write_record(file_id fid, bin_data const &data, trust_card_t, std::uint32_t offset = 0)

Appends a record to a linear or cyclic file. This method requires a previous authenticate command with a key that is compatible with the file_access_rights::write (or file_access_rights::read_write) in order to complete successfully. A call to commit_transaction is necessary to permanently update the value.

Warning

Consider using the overload of this method which requires explicitly a comm_mode operation mode parameter. This method will auto-detect the security settings used: if a card is cloned and a file is created with the same id but different security, this method will accept the different security transmission mode. It may thus leak data.

Parameters:
  • fid – The file id, in the range 0..7 (included).

  • data – Limited to 24 bits, must match in length record_file_settings::record_size.

  • offset – Limited to 24 bits, i.e. must be below 0xFFFFFF. Must also be less than the record size. This is the offset within the record at which to write.

Returns:

Either mlab::result_success or any of error. In particular, error::permission_denied, or error::file_not_found if the file does not exist. If offset is invalid or data's length incorrect, error::parameter_error and error::length_error are also possible.

result write_record(file_id fid, bin_data const &data, comm_mode operation_mode, std::uint32_t offset = 0)

Appends a record to a linear or cyclic file. This method requires a previous authenticate command with a key that is compatible with the file_access_rights::write (or file_access_rights::read_write) in order to complete successfully. A call to commit_transaction is necessary to permanently update the value.

Parameters:
  • fid – The file id, in the range 0..7 (included).

  • data – Limited to 24 bits, must match in length record_file_settings::record_size.

  • operation_mode – The communication mode to use for this operation. This is derived from the base file security and the value of file_access_rights::write and file_access_rights::read_write members: a free access implies no security is specified, otherwise it falls back to the file’s own security mode.

  • offset – Limited to 24 bits, i.e. must be below 0xFFFFFF. Must also be less than the record size. This is the offset within the record at which to write.

Returns:

Either mlab::result_success or any of error. In particular, error::permission_denied, or error::file_not_found if the file does not exist. If operation_mode is incorrect, error::crypto_error is returned. If offset is invalid or data's length incorrect, error::parameter_error and error::length_error are also possible.

template<class T>
result write_record(file_id fid, T &&record, trust_card_t)

Appends a record of a given type T to a cyclic or linear record file. This method requires a previous authenticate command with a key that is compatible with the file_access_rights::write (or file_access_rights::read_write) in order to complete successfully. A call to commit_transaction is necessary to permanently update the value.

Warning

Consider using the overload of this method which requires explicitly a comm_mode operation mode parameter. This method will auto-detect the security settings used: if a card is cloned and a file is created with the same id but different security, this method will accept the different security transmission mode. It may thus leak data.

Template Parameters:

T – A record type which can be injected into mlab::bin_data.

Parameters:
  • fid – The file id, in the range 0..7 (included).

  • record – Record to write. Must be injectable to mlab::bin_data with as many bytes as record_file_settings::record_size.

Returns:

Either mlab::result_success or any of error. In particular, error::permission_denied, or error::file_not_found if the file does not exist. If the encoded length of record is incorrect, error::parameter_error and error::length_error are also possible.

template<class T>
result write_record(file_id fid, T &&record, comm_mode operation_mode)

Appends a record of a given type T to a cyclic or linear record file. This method requires a previous authenticate command with a key that is compatible with the file_access_rights::write (or file_access_rights::read_write) in order to complete successfully. A call to commit_transaction is necessary to permanently update the value.

Template Parameters:

T – A record type which can be injected into mlab::bin_data.

Parameters:
  • fid – The file id, in the range 0..7 (included).

  • record – Record to write. Must be injectable to mlab::bin_data with as many bytes as record_file_settings::record_size.

  • operation_mode – The communication mode to use for this operation. This is derived from the base file security and the value of file_access_rights::write and file_access_rights::read_write members: a free access implies no security is specified, otherwise it falls back to the file’s own security mode.

Returns:

Either mlab::result_success or any of error. In particular, error::permission_denied, or error::file_not_found if the file does not exist. If operation_mode is incorrect, error::crypto_error is returned. If the encoded length of record is incorrect, error::parameter_error and error::length_error are also possible.

template<class T>
result<std::vector<T>> read_parse_records(file_id fid, trust_card_t, std::uint32_t record_index = 0, std::uint32_t record_count = all_records)

Read records from a linear or cyclic file, oldest to most recent, and converts the records to T. This method requires a previous authenticate command with a key that is compatible with the file_access_rights::read (or file_access_rights::read_write) in order to complete successfully. The changes made by write_record that have not been committed via commit_transaction are not visible through this method.

Warning

Consider using the overload of this method which requires explicitly a comm_mode operation mode parameter. This method will auto-detect the security settings used: if a card is cloned and a file is created with the same id but different security, this method will accept the different security transmission mode. It may thus leak data.

Template Parameters:

T – A type that can be extracted from a mlab::bin_stream. They must be fixed-size when encoded into binary form, because each record has a fixed size, and they will be extracted one by one, in a flat-array form, from the binary data returned by the PICC.

Parameters:
  • fid – The file id, in the range 0..7 (included).

  • record_index – Limited to 24 bits, i.e. must be below 0xFFFFFF. Must be less than the number of existing records.

  • record_count – Limited to 24 bits, i.e. must be below 0xFFFFFF. Must be less or equal than the number of existing records. Specify zero to read all records.

Returns:

The binary data of the selected records or any of error. In particular, error::permission_denied, or error::file_not_found if the file does not exist. If record_index is invalid or record_count incorrect, error::parameter_error and error::length_error are also possible.

template<class T>
result<std::vector<T>> read_parse_records(file_id fid, comm_mode operation_mode, std::uint32_t record_index = 0, std::uint32_t record_count = all_records)

Read records from a linear or cyclic file, oldest to most recent, and converts the records to T. This method requires a previous authenticate command with a key that is compatible with the file_access_rights::read (or file_access_rights::read_write) in order to complete successfully. The changes made by write_record that have not been committed via commit_transaction are not visible through this method.

Template Parameters:

T – A type that can be extracted from a mlab::bin_stream. They must be fixed-size when encoded into binary form, because each record has a fixed size, and they will be extracted one by one, in a flat-array form, from the binary data returned by the PICC.

Parameters:
  • fid – The file id, in the range 0..7 (included).

  • record_index – Limited to 24 bits, i.e. must be below 0xFFFFFF. Must be less than the number of existing records.

  • record_count – Limited to 24 bits, i.e. must be below 0xFFFFFF. Must be less or equal than the number of existing records. Specify zero to read all records.

  • operation_mode – The communication mode to use for this operation. This is derived from the base file security and the value of file_access_rights::read and file_access_rights::read_write members: a free access implies no security is specified, otherwise it falls back to the file’s own security mode.

Returns:

The binary data of the selected records or any of error. In particular, error::permission_denied, or error::file_not_found if the file does not exist. If operation_mode is incorrect, error::crypto_error is returned. If record_index is invalid or record_count incorrect, error::parameter_error and error::length_error are also possible.

result<bin_data> read_records(file_id fid, trust_card_t, std::uint32_t record_index = 0, std::uint32_t record_count = all_records)

Read records from a linear or cyclic file, oldest to most recent. This method requires a previous authenticate command with a key that is compatible with the file_access_rights::read (or file_access_rights::read_write) in order to complete successfully. The changes made by write_record that have not been committed via commit_transaction are not visible through this method.

Warning

Consider using the overload of this method which requires explicitly a comm_mode operation mode parameter. This method will auto-detect the security settings used: if a card is cloned and a file is created with the same id but different security, this method will accept the different security transmission mode. It may thus leak data.

Parameters:
  • fid – The file id, in the range 0..7 (included).

  • record_index – Limited to 24 bits, i.e. must be below 0xFFFFFF. Must be less than the number of existing records.

  • record_count – Limited to 24 bits, i.e. must be below 0xFFFFFF. Must be less or equal than the number of existing records. Specify zero to read all records.

Returns:

The binary data of the selected records or any of error. In particular, error::permission_denied, or error::file_not_found if the file does not exist. If record_index is invalid or record_count incorrect, error::parameter_error and error::length_error are also possible.

result<bin_data> read_records(file_id fid, std::uint32_t record_index, std::uint32_t record_count, comm_mode operation_mode)

Read records from a linear or cyclic file, oldest to most recent. This method requires a previous authenticate command with a key that is compatible with the file_access_rights::read (or file_access_rights::read_write) in order to complete successfully. The changes made by write_record that have not been committed via commit_transaction are not visible through this method.

Parameters:
  • fid – The file id, in the range 0..7 (included).

  • record_index – Limited to 24 bits, i.e. must be below 0xFFFFFF. Must be less than the number of existing records.

  • record_count – Limited to 24 bits, i.e. must be below 0xFFFFFF. Must be less or equal than the number of existing records. Specify zero to read all records.

  • operation_mode – The communication mode to use for this operation. This is derived from the base file security and the value of file_access_rights::read and file_access_rights::read_write members: a free access implies no security is specified, otherwise it falls back to the file’s own security mode.

Returns:

The binary data of the selected records or any of error. In particular, error::permission_denied, or error::file_not_found if the file does not exist. If operation_mode is incorrect, error::crypto_error is returned. If record_index is invalid or record_count incorrect, error::parameter_error and error::length_error are also possible.

result<pn532::nfcid_2t> get_card_uid()

Get the card UID. This does not require authentication (and is not transmitted in a secure way); however, in case UID randomization is enabled via set_configuration, this method will return the random UID generated when the PICC was activated, unless an authentication with a valid key had been performed.

Warning

We sacrificed some cards to the random UID features, and for the cards we tested, this method actually still returned the random UID even though it was authenticated, despite other publicly available libraries claiming otherwise (MF2DL(H)x0 §11.5.3).

Returns:

The card UID or any of error.

result<std::uint32_t> get_free_mem()

Read the amount of free flash memory. We conjecture no authentication is required for this.

Returns:

The amount of free memory in bytes, or one of error.

result set_configuration(bool allow_format = true, bool enable_random_id = false)

Configure whether the card can be formatted, or whether will show the real UID.

Warning

Enabling random id is an irreversible operation! And get_card_uid does not seem to work.

Parameters:
  • allow_format – Allow clearing all the apps and files in the card.

  • enable_random_id – Enable if UID should be randomized (the real UID supposedly should be read with get_card_uid).

Returns:

Either mlab::result_success or any of error.

result<comm_mode> determine_operation_mode(file_access requested_access, file_id fid)

Determines which security level to apply for a certain file operation. This method will query the file settings via get_file_settings and test file_rights and security against the specified requested_access.

Parameters:
  • requested_access – Type of access requested.

  • fid – The file id, in the range 0..15 (included). For any file other than file_type::standard, this can be at most 7.

Returns:

The security mode to apply to an operation that requires the specified requested_access mode, or any of the errors that might be returned by get_file_settings.

Public Static Functions

static comm_mode determine_operation_mode(file_access requested_access, file_access_rights const &file_rights, file_security security)

Determines which security level to apply for a certain file operation. This method will test file_rights and security against the specified requested_access.

Parameters:
  • requested_access – Type of access requested.

  • file_rights – Access rights to the given file.

  • security – Security with which the file was created.

Returns:

The security mode to apply to an operation that requires the specified requested_access mode.

static comm_mode determine_operation_mode(file_access requested_access, common_file_settings const &settings)

Determines which security level to apply for a certain file operation. This method will test common_file_settings::rights and common_file_settings::security against the specified requested_access.

Parameters:
  • requested_access – Type of access requested.

  • settings – File settings.

Returns:

The security mode to apply to an operation that requires the specified requested_access mode.

static comm_mode determine_operation_mode(file_access requested_access, any_file_settings const &settings)

Determines which security level to apply for a certain file operation. This method will test common_file_settings::rights and common_file_settings::security against the specified requested_access from the any_file_settings::common_settings property.

Parameters:
  • requested_access – Type of access requested.

  • settings – File settings.

Returns:

The security mode to apply to an operation that requires the specified requested_access mode.

Friends

friend struct ut::desfire_exchanges::session