/**
 * @file
 * This command group regroups the commands needed for public key infrastructure (PKI)-based protocol encryption.
 */
/**
 * @file
 * @defgroup baltech_sdk Wrapper functions
 * @{
 */
#ifndef __BRP_BALTECH_SDK_CMDS_PKI_H__
#define __BRP_BALTECH_SDK_CMDS_PKI_H__
#include "../typedefs.h"
#ifdef BALTECH_SDK_INTERNAL
/**
 * Invalid Key used for encryption/MACing or MAC is invalid.
 */
#define BRP_Pki_ErrCrypto BRP_ERR_STATUS(0x0900, 0x01)
#endif  // BALTECH_SDK_INTERNAL
#ifdef BALTECH_SDK_INTERNAL
/**
 * It is not possible to tunnel this command.
 */
#define BRP_Pki_ErrTunnel BRP_ERR_STATUS(0x0900, 0x02)
#endif  // BALTECH_SDK_INTERNAL
#ifdef BALTECH_SDK_INTERNAL
/**
 * The certificate (or key) has invalid format or signature.
 */
#define BRP_Pki_ErrCert BRP_ERR_STATUS(0x0900, 0x03)
#endif  // BALTECH_SDK_INTERNAL
#ifdef BALTECH_SDK_INTERNAL
/**
 * The sequence counter was too low.
 */
#define BRP_Pki_ErrSeqctr BRP_ERR_STATUS(0x0900, 0x04)
#endif  // BALTECH_SDK_INTERNAL
#ifdef BALTECH_SDK_INTERNAL
/**
 * This security level has no key for authentication.
 */
#define BRP_Pki_ErrSeclevelUnsupported BRP_ERR_STATUS(0x0900, 0x05)
#endif  // BALTECH_SDK_INTERNAL
#ifdef BALTECH_SDK_INTERNAL
/**
 * The security session timed out.
 */
#define BRP_Pki_ErrSessionTimeout BRP_ERR_STATUS(0x0900, 0x06)
#endif  // BALTECH_SDK_INTERNAL
#ifdef BALTECH_SDK_INTERNAL
typedef struct {
	brp_protocol protocol;
	brp_buf TmpHostPubKey;
	size_t TmpHostPubKey_len;
	brp_buf* TmpRdrPubKey;
	size_t* TmpRdrPubKey_len;
	brp_mempool *mempool;
} brp_Pki_PfsGenKey_t;
/**
 * This command prepares a perfect forward secrecy (PFS) session by exchanging the public part of temporary elliptic curve cryptography (ECC) keys generated by host and reader. These are needed by the Pki.PfsAuthHostCert and Pki.PfsAuthRdrCert commands. 
 * 
 * The next step in negotiating a session key can be performed by running the Pki.PfsAuthHostCert command. 
 * 
 * If a session key was negotiated before running this command, it will be invalidated. For this reason, it is not possible to exchange encrypted commands until finalizing the session setup sequence. 
 * 
 * The temporary keys generated by the host (_TmpHostPubKey_ parameter) and by the reader (_TmpRdrPubKey_ response variable) follow the Abstract Syntax Notation One (ASN.1) Distinguished Encoding Rules (DER) format. An example of the format for such keys is as follows: 
 * 
 * 30 59 30 13 06 07 2A 86 48 CE 3D 02 01 06 08 2A 86 48 CE 3D 03 01 07 03 42 00 04 0C C2 D2 24 16 47 4B DC A1 39 52 08 73 B7 6E A1 32 40 34 7B 8D 70 2F E1 FC CC 93 81 ED EF 65 8E 0C 49 A8 63 0F 23 65 07 5F C1 19 3A 3B 90 4F CA 35 E7 18 52 F7 95 AA CF FB FE 96 66 3D 44 0A BA 
 * 
 * Please not that the initial part of the key (30 59 30 13 06 07 2A 86 48 CE 3D 02 01 06 08 2A 86 48 CE 3D 03 01 07) is the ASN.1 DER-specific header and must always be identical. 
 * 
 * **This command needs a long timeout, since the ECC operations may take up to 15 seconds.**
 * 
 * @param[in] params Struct with the following fields:
 *   - **protocol** used to execute the command
 *   - **TmpHostPubKey** (in) The host's temporary generated public ECC key in ASN.1 DER format.
 *   - **TmpHostPubKey_len** (in) Length of **TmpHostPubKey** (in bytes).
 *   - **TmpRdrPubKey** (out) The reader's temporary generated public ECC key in ASN.1 DER format.
 *   - **TmpRdrPubKey_len** (out) Length of **TmpRdrPubKey** (in bytes).
 *   - **mempool** (in) is used to store response data. Maybe NULL to use an internal mempool, in this case the data is only available until another command uses the internal mempool
 */
#ifdef BRP_SUPPORT_LEGACY_METHODS
brp_errcode brp_Pki_PfsGenKey(brp_protocol protocol, brp_buf _input_TmpHostPubKey, size_t _input_TmpHostPubKey_len, brp_buf* TmpRdrPubKey, size_t* TmpRdrPubKey_len, brp_mempool *mempool);
#else
brp_errcode brp_Pki_PfsGenKey(brp_Pki_PfsGenKey_t params);
#endif
typedef struct {
	brp_protocol protocol;
	brp_buf EncryptedPayload;
	size_t EncryptedPayload_len;
} brp_Pki_PfsAuthHostCert_t;
/**
 * This command authenticates the host's certificate chain to the reader. If the certificate chain is longer than one certificate, this command has to be called multiple times with the _IsEndCert_ flag of the _EncryptedPayload_ parameter set to 0, until the last certificate has been reached in which case it must be set to 1. 
 * 
 * The certificates must comply with the following limitations: 
 * 
 *   * Certificates have to be X.509 v3 certificates. 
 *   * As signing algorithms, only ECC P-256 and SHA256 are allowed. 
 *   * The only allowed extensions are _basicConstraints_ (indicating the certificate is a CA certificate) and the (optional) Baltech proprietary certificate _acMask_ using the ASN.1 object identifier (OID) _1.3.6.1.4.1.44885.1_. 
 * 
 * The 32-bit _acMask_ extension makes it possible to further restrict the allowed operations by the reader in the Security Level corresponding to the certificate since it will be combined with the reader's internal 32-bit _Access Condition Mask_ , using a logical _AND_ operator. 
 * 
 * 
 * 
 * 
 * If this command is called multiple times (since the certificate chain contains multiple entries), it is required that the _SecLevel_ and _SessionTimeout_ field always have the same value. 
 * 
 * If the format of _HostCert_ is invalid or if the signature verification fails, the ERR_CERT status code is returned. 
 * 
 * **This command needs a long timeout, since the ECC operations may take up to 15 seconds.**
 * 
 * @param[in] params Struct with the following fields:
 *   - **protocol** used to execute the command
 *   - **EncryptedPayload** (in) This parameter specifies the host certificate. The data is encrypted via AES-128 with Cipher Block Chaining (CBC) using the key and initial vector (IV) generated by the Pki.PfsGenKey command.   The certificate is accompanied by some additional data fields. Before encryption, this parameter is split up into the following fields:     * _SecLevel_ (1 Byte): The Security Level (1-3) which has to be authenticated.    * _SessionTimeout_ (4 Bytes): Specifies how long the generated session key shall be valid after running this command. If this value is between 1 and 0xffff159f (higher values must not be used!) it specifies the validity time in milliseconds. Internally the reader will add one additional minute, to ensure that the host has enough time to setup a new session. If this value is set to 0, no timeout will be set and the session key will be valid until the reader is restarted or until the Pki.PfsGenKey command is called again.    * _IsEndCert_ (1 Byte): Has to be set to 1 if the current certificate is the last certificate in the host's certificate chain. Has to be set to 0 if more certificates are following (i.e. if Pki.PfsAuthHostCert must be called again for another certificate).    * _HostCertLen_ (2 Bytes): Length of the host certificate in Bytes.    * _HostCert_ (n Bytes): An X.509 host certificate encoded in ASN.1 DER format.    * Several Bytes of padding zeros to ensure that the total length of _EncryptedPayload_ is a multiple of 16.
 *   - **EncryptedPayload_len** (in) Length of **EncryptedPayload** (in bytes).
 */
#ifdef BRP_SUPPORT_LEGACY_METHODS
brp_errcode brp_Pki_PfsAuthHostCert(brp_protocol protocol, brp_buf _input_EncryptedPayload, size_t _input_EncryptedPayload_len);
#else
brp_errcode brp_Pki_PfsAuthHostCert(brp_Pki_PfsAuthHostCert_t params);
#endif
typedef struct {
	brp_protocol protocol;
	brp_buf* EncryptedResponse;
	size_t* EncryptedResponse_len;
	brp_mempool *mempool;
} brp_Pki_PfsAuthRdrCert_t;
/**
 * After successfully authenticating the host against the reader using the Pki.PfsAuthHostCert command, the reader must return its own certificate to the host in order the host to verify it. 
 * 
 * This command will finalize the PFS session setup and calculate the new AES-128 session key. This session key has to be used for all following calls of the Pki.Tunnel2 command. 
 * 
 * **This command needs a long timeout, since the ECC operations may take up to 15 seconds.**
 * 
 * @param[in] params Struct with the following fields:
 *   - **protocol** used to execute the command
 *   - **EncryptedResponse** (out) Encrypted reader's certificate. The data is encrypted via AES-128 CBC using the key and IV generated by the Pki.PfsGenKey command.   After decryption, _EncryptedResp_ can be split up into the following fields:     * _ReaderCertLen_ (2 Bytes): Length of the reader's certificate in Bytes.    * _RdrCert_ (n Bytes): The X.509 end certificate of the reader encoded in ASN.1 DER format (set by the Pki.StoreX509Cert command).    * Several Bytes of padding zeros to ensure that the total length of _EncryptedResponse_ is a multiple of 16.
 *   - **EncryptedResponse_len** (out) Length of **EncryptedResponse** (in bytes).
 *   - **mempool** (in) is used to store response data. Maybe NULL to use an internal mempool, in this case the data is only available until another command uses the internal mempool
 */
#ifdef BRP_SUPPORT_LEGACY_METHODS
brp_errcode brp_Pki_PfsAuthRdrCert(brp_protocol protocol, brp_buf* EncryptedResponse, size_t* EncryptedResponse_len, brp_mempool *mempool);
#else
brp_errcode brp_Pki_PfsAuthRdrCert(brp_Pki_PfsAuthRdrCert_t params);
#endif
typedef struct {
	brp_protocol protocol;
	unsigned SequenceCounter;
	brp_buf CmdHMAC;
	brp_buf EncryptedCmd;
	size_t EncryptedCmd_len;
	brp_buf* RspHMAC;
	brp_buf* EncryptedRsp;
	size_t* EncryptedRsp_len;
	brp_mempool *mempool;
} brp_Pki_Tunnel2_t;
/**
 * Runs a command in the Security Level authenticated by the Pki.PfsGenKey, Pki.PfsAuthHostCert, Pki.PfsAuthRdrCert commands sequence. The command is encrypted with the session key calculated by Pki.PfsAuthRdrCert. 
 * 
 * After the reader decrypts the received tunnelled command, it checks whether this command is blocked by the _Access Condition Mask_ assigned to the Security Level or by one of the Access Condition Masks of the certificates in the host certificate chain. If this command is blocked by one of these Access Condition Masks, it is not allowed to be executed in the given Security Level and the ErrAccessDenied status code is returned.
 * 
 * @param[in] params Struct with the following fields:
 *   - **protocol** used to execute the command
 *   - **SequenceCounter** (in) A continuous counter that has to be incremented every time Pki.Tunnel2 is executed (no matter if successful), and that is reset to 0 after a successful execution of the Pki.PfsAuthRdrCert command.
 *   - **CmdHMAC** (in) An AES 128 CBC-MAC over _EncryptedCmd_ using the session key calculated by Pki.PfsAuthRdrCert and an IV constructed from _SequenceCounter_. To get the IV, the sequence counter has to be padded by leading 0x00 and the first Byte of the IV has to be set to 0x20.
 *   - **EncryptedCmd** (in) Encrypted command to execute in the authenticated Security Level. Data is encrypted via AES-128 CBC using the session key generated by Pki.PfsAuthRdrCert and an IV constructed from _SequenceCounter_. To get the IV for encryption, the sequence counter has to be padded by leading 0x00 and the first Byte of the IV has to be set to 0x10.   Before encryption, _EncryptedCmd_ is split up into the following fields:     * _DevCode_ (1 Byte): Device code of the command which must be executed in the authenticated Security Level.    * _CmdCode_ (1 Byte): Command code of the command which must be executed in the authenticated Security Level.    * _PayloadLen_ (2 Bytes): Length of _Payload_ in Bytes.    * _Payload_ (n Bytes): contains the parameters buffer for the command which must be executed in the authenticated Security Level.
 *   - **EncryptedCmd_len** (in) Length of **EncryptedCmd** (in bytes).
 *   - **RspHMAC** (out) An AES 128 CBC-MAC over _EncryptedRsp_ using the session key calculated by Pki.PfsAuthRdrCert and an IV constructed from _SequenceCounter_. To get the IV, the sequence counter has to be padded by leading 0x00 and the first Byte of the IV has to be set to 0x80.
 *   - **EncryptedRsp** (out) Encrypted response of the command which was executed in the authenticated Security Level. Data is encrypted via AES-128 CBC using the session key generated by Pki.PfsAuthRdrCert and an IV constructed from _SequenceCounter_. To get the IV for encryption, the sequence counter has to be padded by leading 0x00 and the first Byte of the IV has to be set to 0x40.   Before encryption, _EncryptedRsp_ is split up into the following fields:     * _StatusCode_ (1 Byte): Has to be 0x00 on successful execution of the encrypted command. Else, an error occurred.    * _RespLen_ (2 Bytes): Length of _Resp_ in Bytes.    * _Resp_ (n Bytes): Contains the response buffer of the command which was executed in the authenticated Security Level.
 *   - **EncryptedRsp_len** (out) Length of **EncryptedRsp** (in bytes).
 *   - **mempool** (in) is used to store response data. Maybe NULL to use an internal mempool, in this case the data is only available until another command uses the internal mempool
 */
#ifdef BRP_SUPPORT_LEGACY_METHODS
brp_errcode brp_Pki_Tunnel2(brp_protocol protocol, unsigned _input_SequenceCounter, brp_buf _input_CmdHMAC, brp_buf _input_EncryptedCmd, size_t _input_EncryptedCmd_len, brp_buf* RspHMAC, brp_buf* EncryptedRsp, size_t* EncryptedRsp_len, brp_mempool *mempool);
#else
brp_errcode brp_Pki_Tunnel2(brp_Pki_Tunnel2_t params);
#endif
typedef struct {
	brp_protocol protocol;
	brp_buf* Csr;
	size_t* Csr_len;
	brp_mempool *mempool;
} brp_Pki_GetX509Csr_t;
/**
 * Every reader is shipped with a unique ECC P-256 key, generated at the time of manufacturing. This command returns a certificate signing request (CSR) over the public part of the reader's key, which can be signed by a certificate authority. To store the signed certificate on the reader, run the Pki.StoreX509Cert command afterwards.
 * 
 * @param[in] params Struct with the following fields:
 *   - **protocol** used to execute the command
 *   - **Csr** (out) Certificate signing request (CSR) for the reader's public key encoded in ASN.1 DER format.
 *   - **Csr_len** (out) Length of **Csr** (in bytes).
 *   - **mempool** (in) is used to store response data. Maybe NULL to use an internal mempool, in this case the data is only available until another command uses the internal mempool
 */
#ifdef BRP_SUPPORT_LEGACY_METHODS
brp_errcode brp_Pki_GetX509Csr(brp_protocol protocol, brp_buf* Csr, size_t* Csr_len, brp_mempool *mempool);
#else
brp_errcode brp_Pki_GetX509Csr(brp_Pki_GetX509Csr_t params);
#endif
typedef struct {
	brp_protocol protocol;
	unsigned SecLevel;
	brp_buf Cert;
	size_t Cert_len;
} brp_Pki_StoreX509Cert_t;
/**
 * After signing a CSR using the Pki.GetX509Csr command, run this command to store the resulting in the reader's certificate store. The certificate store provides up to 3 slots (for security level 1-3). This means up to 3 different certificate authorities can store their certificates in a reader. 
 * 
 * The certificates must comply with the following limitations: 
 * 
 *   * Only ECC P-256 and SHA256 are allowed as signing algorithms. 
 *   * The length of the tag containing the issuer distinguished name must not exceed 128 Bytes. 
 *   * No extensions are allowed. 
 * 
 * 
 * 
 * A sample certificate matching all these limitations is the following: 
 * 
 * 30 82 01 6C 30 82 01 11 A0 03 02 01 02 02 01 01 30 0A 06 08 2A 86 48 CE 3D 04 03 02 30 3C 31 23 30 21 06 03 55 04 03 0C 1A 49 6E 74 65 72 6D 65 64 69 61 74 65 20 43 41 20 66 6F 72 20 52 65 61 64 65 72 31 15 30 13 06 03 55 04 0A 0C 0C 43 75 73 74 6F 6D 65 72 20 4F 6E 65 30 1E 17 0D 30 30 30 31 30 31 30 30 30 30 30 30 5A 17 0D 33 38 30 31 31 39 30 32 31 34 30 37 5A 30 42 31 14 30 12 06 03 55 04 03 0C 0B 53 23 20 31 31 31 31 31 31 31 31 31 13 30 11 06 03 55 04 0A 0C 0A 42 61 6C 74 65 63 68 20 41 47 31 15 30 13 06 03 55 04 07 0C 0C 48 61 6C 6C 62 65 72 67 6D 6F 6F 73 30 59 30 13 06 07 2A 86 48 CE 3D 02 01 06 08 2A 86 48 CE 3D 03 01 07 03 42 00 04 C3 4D 0E D2 EA 8F 94 88 93 E0 16 75 06 78 67 BB 96 14 5A A9 24 F8 95 02 4F 47 87 C7 1C B3 1F D5 83 CD 8C A3 FB B2 57 51 38 BF 81 AA 9C 26 DC CA 71 A6 FE 83 1B 2C 88 60 86 69 D3 53 93 08 39 D7 30 0A 06 08 2A 86 48 CE 3D 04 03 02 03 49 00 30 46 02 21 00 90 6F 97 EF C0 95 1C 9C FC 60 4C 1F F7 12 00 F4 C8 2C EA FE 4E 9D C9 F0 BE 29 75 C6 E6 42 3C 1B 02 21 00 BB 22 42 56 13 5A B5 BF D1 19 B7 40 EA 44 30 2B 14 3B 86 4E 0C 48 24 96 8F FB 49 69 24 71 CA DF 
 * 
 * This sample certificate can be decoded using the following online tool: <https://redkestrel.co.uk/tools/decoder/>
 * 
 * Furthermore, the access conditions mask of the security level running the Pki.StoreX509Cert command has to allow setting the corresponding key (SEC_SETKEY1, SEC_SETKEY2 or SEC_SETKEY3 bit of the access condition mask must be set). 
 * 
 * **This command needs a long timeout, since the ECC operations may take up to 15 seconds.**
 * 
 * @param[in] params Struct with the following fields:
 *   - **protocol** used to execute the command
 *   - **SecLevel** (in) Security level (1-3), which you want to provide with a (new) reader certificate.
 *   - **Cert** (in) X.509 certificate created by signing a CSR returned by Pki.GetX509Csr, encoded in ASN.1 DER format.
 *   - **Cert_len** (in) Length of **Cert** (in bytes).
 */
#ifdef BRP_SUPPORT_LEGACY_METHODS
brp_errcode brp_Pki_StoreX509Cert(brp_protocol protocol, unsigned _input_SecLevel, brp_buf _input_Cert, size_t _input_Cert_len);
#else
brp_errcode brp_Pki_StoreX509Cert(brp_Pki_StoreX509Cert_t params);
#endif
typedef struct {
	brp_protocol protocol;
	unsigned SecLevel;
	brp_buf Cert;
	size_t Cert_len;
} brp_Pki_StoreX509RootCert_t;
/**
 * Every security level that should be usable with the PKI must be provided with a root certificate. The certificate chain provided in the Pki.PfsAuthHostCert command will be verified against this root certificate. 
 * 
 * The root certificates must comply with the following limitations: 
 * 
 *   * Certificates have to be X.509 v3 certificates. 
 *   * Only ECC P-256 and SHA256 are allowed as signing algorithms. 
 *   * The length of the tags containing the Issuer Unique Identifier and the Subject Unique Identifier must not exceed 128 Bytes. 
 *   * The only allowed extension is _basicConstraints_ (indicating the certificate is a CA certificate) 
 *   * The validity period always has to be from "Jan 1 00:00:00 2000 GMT" to "Jan 19 02:14:07 2038 GMT". 
 * 
 * 
 * 
 * A sample certificate matching all these limitations is the following: 
 * 
 * 30 82 01 9D 30 82 01 43 A0 03 02 01 02 02 01 01 30 0A 06 08 2A 86 48 CE 3D 04 03 02 30 41 31 19 30 17 06 03 55 04 03 0C 10 52 6F 6F 74 20 43 65 72 74 69 66 69 63 61 74 65 31 11 30 0F 06 03 55 04 0A 0C 08 45 71 75 69 74 72 61 63 31 11 30 0F 06 03 55 04 07 0C 08 57 61 74 65 72 6C 6F 6F 30 1E 17 0D 30 30 30 31 30 31 30 30 30 30 30 30 5A 17 0D 33 38 30 31 31 39 30 32 31 34 30 37 5A 30 41 31 19 30 17 06 03 55 04 03 0C 10 52 6F 6F 74 20 43 65 72 74 69 66 69 63 61 74 65 31 11 30 0F 06 03 55 04 0A 0C 08 45 71 75 69 74 72 61 63 31 11 30 0F 06 03 55 04 07 0C 08 57 61 74 65 72 6C 6F 6F 30 59 30 13 06 07 2A 86 48 CE 3D 02 01 06 08 2A 86 48 CE 3D 03 01 07 03 42 00 04 B0 13 B7 1F A6 61 47 8E 8D 2F FC C0 36 17 C0 51 5D 2A 39 C5 67 15 1A E3 85 2A 3B 9C 2E 93 FA 41 0A B5 F3 66 62 6A F8 04 D7 0E D1 DB 7A 2D 36 26 0A A5 77 D2 9C D4 65 24 70 DF 9A 74 40 C2 A7 B1 A3 2C 30 2A 30 0F 06 03 55 1D 13 01 01 FF 04 05 30 03 01 01 FF 30 17 06 09 2B 06 01 04 01 82 DE 55 01 01 01 FF 04 07 03 05 00 08 00 10 80 30 0A 06 08 2A 86 48 CE 3D 04 03 02 03 48 00 30 45 02 21 00 BB 42 BB 32 8C D5 68 39 E9 40 28 10 5F 63 E1 52 9A 63 06 BF B2 69 03 0A F8 9D A5 56 95 CF 0F B2 02 20 35 D6 FF 5C 9A 42 D9 85 5E F3 16 DA 7A 53 19 F7 74 81 A4 54 B3 D4 C9 74 26 78 D2 1D 11 52 2D 2A 
 * 
 * This sample certificate can be decoded using the following online tool: <https://redkestrel.co.uk/tools/decoder/>
 * 
 * Furthermore, the access conditions mask of the security llevel running the Pki.StoreX509RootCert command has to allow setting the corresponding key (SEC_SETKEY1, SEC_SETKEY2 or SEC_SETKEY3 bit of the access condition mask must be set). 
 * 
 * **This command needs a long timeout, since the ECC operations may take up to 15 seconds.**
 * 
 * @param[in] params Struct with the following fields:
 *   - **protocol** used to execute the command
 *   - **SecLevel** (in) Security level (1-3), for which the root certificate should be stored.
 *   - **Cert** (in) X.509 root certificate encoded in ASN.1 DER format.
 *   - **Cert_len** (in) Length of **Cert** (in bytes).
 */
#ifdef BRP_SUPPORT_LEGACY_METHODS
brp_errcode brp_Pki_StoreX509RootCert(brp_protocol protocol, unsigned _input_SecLevel, brp_buf _input_Cert, size_t _input_Cert_len);
#else
brp_errcode brp_Pki_StoreX509RootCert(brp_Pki_StoreX509RootCert_t params);
#endif
#endif  // BALTECH_SDK_INTERNAL
#endif
/**
 * @}
 */