/**
 * @file
 * This command group regroups the commands needed for public key infrastructure
 * (PKI)-based protocol encryption.
 */
/**
 * @file
 * @defgroup baltech_api Baltech API
 * @{
 */
#ifndef __BRP_BALTECH_API_CMDS_PKI_H__
#define __BRP_BALTECH_API_CMDS_PKI_H__
#include "../typedefs.h"
/**
 * Invalid Key used for encryption/MACing or MAC is invalid.
 */
#define BRP_Pki_ErrCrypto BRP_ERR_STATUS(0x0900, 0x01)
/**
 * It is not possible to tunnel this command.
 */
#define BRP_Pki_ErrTunnel BRP_ERR_STATUS(0x0900, 0x02)
/**
 * The certificate (or key) has invalid format or signature.
 */
#define BRP_Pki_ErrCert BRP_ERR_STATUS(0x0900, 0x03)
/**
 * The sequence counter was too low.
 */
#define BRP_Pki_ErrSeqctr BRP_ERR_STATUS(0x0900, 0x04)
/**
 * This security level has no key for authentication.
 */
#define BRP_Pki_ErrSeclevelUnsupported BRP_ERR_STATUS(0x0900, 0x05)
/**
 * The security session timed out.
 */
#define BRP_Pki_ErrSessionTimeout BRP_ERR_STATUS(0x0900, 0x06)
/**
 * 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
 *  brp_Pki_PfsAuthHostCert() and
 *  brp_Pki_PfsAuthRdrCert() commands.
 * 
 * The next step in negotiating a session key can be performed by running the
 *  brp_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] protocol used to execute the command
 * @param[in] TmpHostPubKey The host's temporary generated public ECC key in ASN.1 DER format.
 * @param[in] TmpHostPubKey_len 
 * @param[out] TmpRdrPubKey The reader's temporary generated public ECC key in ASN.1 DER format.
 * @param[out] TmpRdrPubKey_len 
 * @param[in] mempool 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
 */
brp_errcode brp_Pki_PfsGenKey(brp_protocol protocol, brp_buf TmpHostPubKey, size_t TmpHostPubKey_len, brp_buf* TmpRdrPubKey, size_t* TmpRdrPubKey_len, brp_mempool *mempool);
/**
 * 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] protocol used to execute the command
 * @param[in] EncryptedPayload 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  brp_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  brp_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  brp_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.
 * @param[in] EncryptedPayload_len 
 */
brp_errcode brp_Pki_PfsAuthHostCert(brp_protocol protocol, brp_buf EncryptedPayload, size_t EncryptedPayload_len);
/**
 * After successfully authenticating the host against the reader using the
 *  brp_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
 *  brp_Pki_Tunnel2() command.
 * 
 * **This command needs a long timeout, since the ECC operations may take up to
 * 15 seconds.**
 * 
 * @param[in] protocol used to execute the command
 * @param[out] EncryptedResponse Encrypted reader's certificate. The data is encrypted via AES-128 CBC using the key and IV generated by the  brp_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  brp_Pki_StoreX509Cert() command).    * Several Bytes of padding zeros to ensure that the total length of _EncryptedResponse_ is a multiple of 16.
 * @param[out] EncryptedResponse_len 
 * @param[in] mempool 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
 */
brp_errcode brp_Pki_PfsAuthRdrCert(brp_protocol protocol, brp_buf* EncryptedResponse, size_t* EncryptedResponse_len, brp_mempool *mempool);
/**
 * Runs a command in the Security Level authenticated by the
 *  brp_Pki_PfsGenKey(),
 *  brp_Pki_PfsAuthHostCert(),
 *  brp_Pki_PfsAuthRdrCert() commands sequence. The command is
 * encrypted with the session key calculated by
 *  brp_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] protocol used to execute the command
 * @param[in] SequenceCounter 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  brp_Pki_PfsAuthRdrCert() command.
 * @param[in] CmdHMAC An AES 128 CBC-MAC over _EncryptedCmd_ using the session key calculated by  brp_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.
 * @param[in] EncryptedCmd Encrypted command to execute in the authenticated Security Level. Data is encrypted via AES-128 CBC using the session key generated by  brp_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.
 * @param[in] EncryptedCmd_len 
 * @param[out] RspHMAC An AES 128 CBC-MAC over _EncryptedRsp_ using the session key calculated by  brp_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.
 * @param[out] EncryptedRsp 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  brp_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.
 * @param[out] EncryptedRsp_len 
 * @param[in] mempool 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
 */
brp_errcode brp_Pki_Tunnel2(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);
/**
 * 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
 *  brp_Pki_StoreX509Cert() command afterwards.
 * 
 * @param[in] protocol used to execute the command
 * @param[out] Csr Certificate signing request (CSR) for the reader's public key encoded in ASN.1 DER format.
 * @param[out] Csr_len 
 * @param[in] mempool 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
 */
brp_errcode brp_Pki_GetX509Csr(brp_protocol protocol, brp_buf* Csr, size_t* Csr_len, brp_mempool *mempool);
/**
 * After signing a CSR using the  brp_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/products/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] protocol used to execute the command
 * @param[in] SecLevel Security level (1-3), which you want to provide with a (new) reader certificate.
 * @param[in] Cert X.509 certificate created by signing a CSR returned by  brp_Pki_GetX509Csr(), encoded in ASN.1 DER format.
 * @param[in] Cert_len 
 */
brp_errcode brp_Pki_StoreX509Cert(brp_protocol protocol, unsigned SecLevel, brp_buf Cert, size_t Cert_len);
/**
 * Every security level that should be usable with the PKI must be provided with
 * a root certificate. The certificate chain provided in the
 *  brp_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/products/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] protocol used to execute the command
 * @param[in] SecLevel Security level (1-3), for which the root certificate should be stored.
 * @param[in] Cert X.509 root certificate encoded in ASN.1 DER format.
 * @param[in] Cert_len 
 */
brp_errcode brp_Pki_StoreX509RootCert(brp_protocol protocol, unsigned SecLevel, brp_buf Cert, size_t Cert_len);
#endif
/**
 * @}
 */