liboscore 0.2.7

Rust wrapper around the libOSCORE implementation of OSCORE (RFC8613), a security layer for CoAP
Documentation
#ifndef OSCORE_NATIVE_MESSAGE_H
#define OSCORE_NATIVE_MESSAGE_H

/** @file */

/** @ingroup oscore_native_api
 *  @addtogroup oscore_native_msg Native message API
 *
 * @brief API which any native CoAP library provides for OSCORE to manipulate
 * its messages
 *
 * Apart from implementing the below functions and making them available
 * through the linker, the backend needs to define the @ref
 * oscore_native_msg_types in its `oscore_native/msg_type.h` header file.
 *
 * If the implementer desires to implement oscore_msg_native functions as
 * static inline functions or even macros, it can set the
 * OSCORE_MSG_NATIVE_STATIC define and provide an equivalent definitions in an
 * `oscore_native/msg_full.h` file instead. That usage pattern is not
 * recommended; instead, link time optimization or similar should be used.
 *
 * @{
 */

#ifndef OSCORE_MSG_NATIVE_STATIC

#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>

/* This needs to define oscore_msg_native_t and oscore_msg_native_err_t */
#include <oscore_native/msg_type.h>

/** Retrieve the CoAP code (request method or response code) from a message */
uint8_t oscore_msg_native_get_code(oscore_msg_native_t msg);
/** Set the CoAP code (request method or response code) of a message */
void oscore_msg_native_set_code(oscore_msg_native_t msg, uint8_t code);

/** @brief Append an option to a CoAP message
 *
 * @param[inout] msg Message to append to
 * @param[in] option_number Option number of the new option
 * @param[in] value Bytes to be added in the  new option
 * @param[in] value_len Number of bytes in the new option
 *
 * Valid reasons for this to return an unsuccessful response include space
 * inside the message, options being written in the wrong order or the native
 * library's inability to add options after the payload has been accessed.
 */
oscore_msgerr_native_t oscore_msg_native_append_option(
        oscore_msg_native_t msg,
        uint16_t option_number,
        const uint8_t *value,
        size_t value_len
        );

/** @brief Update an single occurrence of an option in a CoAP message
 *
 * @param[inout] msg Message to update
 * @param[in] option_number Option number of the new option
 * @param[in] occurrence Index inside the list of options of the same option number to update (starting at zero)
 * @param[in] value Bytes to be added in the  new option
 * @param[in] value_len Number of bytes in the new option
 *
 * This may return unsuccessfully if there was no such option, or if the
 * @p value_len given is not equal to that option's length.
 *
 * If applications on a given platform do not update options (and especially if
 * the native CoAP library does not support such updates), this function can be
 * left unimplemented; libOSCORE will not call it on its own. This is typically
 * the case when integrating with struct-based CoAP libraries as described in
 * @ref structbased_integration.
 */
oscore_msgerr_native_t oscore_msg_native_update_option(
        oscore_msg_native_t msg,
        uint16_t option_number,
        size_t option_occurrence,
        const uint8_t *value,
        size_t value_len
        );

/** @brief Set up an iterator over a CoAP message
 *
 * Set up the previously uninitialized @p iter on which
 * ``oscore_msg_native_optiter_next`` can be called.
 *
 * @param[in] msg Message to iterate over
 * @param[out] iter Caller-allocated (previously unininitialized) iterator
 *     (cursor) to initialize
 *
 * Callers of this function must call @ref oscore_msg_native_optiter_finish
 * when done fetching any errors that occurred) and before attempting to alter
 * the message.
 */
void oscore_msg_native_optiter_init(oscore_msg_native_t msg,
        oscore_msg_native_optiter_t *iter
        );

/** @brief Iterate through options of a CoAP message
 *
 * @param[in] msg Message to iterate over
 * @param[inout] iter Iterator (cursor) that is read and incremented
 * @param[out] option_number Number of the read CoAP option
 * @param[out] value Data inside the read CoAP option
 * @param[out] value_len Number of bytes inside the read CoAP option
 *
 * If there is a next option to be read in the message, set @p value, @p
 * value_len and @p option_number to that option's data and return true.
 *
 * If the iterator has been exhausted or failed, return false; the iterator
 * will then not be called again.
 *
 * Native CoAP implementations that store options in their semantic form
 * internally (eg. options of type uint as uint32_t) may need to have a buffer
 * available inside the iterator into which that value gets serialized for the
 * duration of an iteration step. That overhead is considered acceptable here
 * as serialized storage of options is predominant in embedded libraries in
 * cases where an OSCORE library is useful.
 *
 * As a special exception (see also @ref oscore_specific_native_requirements),
 * the memory area indicated for a found OSCORE option needs to stay valid for
 * as long as the message is not modified.
 */
bool oscore_msg_native_optiter_next(
        oscore_msg_native_t msg,
        oscore_msg_native_optiter_t *iter,
        uint16_t *option_number,
        const uint8_t **value,
        size_t *value_len
        );

/** @brief Clean up an option iterator
 *
 * Close the iterator previously created by @ref oscore_msg_native_optiter_init.
 *
 * @param[in] msg Message that was being iterated over
 * @param[inout] iter Iterator (cursor) that will not be used any more after
 *     this invocation
 *
 * Implementations will typically implement a no-op here if all the iterator
 * contains is pointers into the message. They need to take action here if they
 * use any form of read/write locking that prevents writes to a message while
 * it is being iterated over.
 *
 * If any errors were encountered during the iteration, they are returned from
 * this function. That is to keep the iteration loop simple, and to have a
 * clear place to handle clean-up. Errors can be encountered if the library
 * allows creating a @ref oscore_msg_native_t from messages that have not been
 * parsed completely, which may then have invalid (`0x?f` or `0xf?` for `? =
 * 0xf`) option fields or option lengths exceeding the message.
 */
oscore_msgerr_native_t oscore_msg_native_optiter_finish(
        oscore_msg_native_t msg,
        oscore_msg_native_optiter_t *iter
        );

/** @brief Provide address and size information to writable payload
 *
 * @param[inout] msg Message whose payload is accessed
 * @param[out] payload Address where message payload can be written to
 * @param[out] payload_len Size of writable payload
 *
 * This may modify the message, as a message can keep track of whether its
 * payload has been written or not.
 *
 * This function can fail if the library allows creating a @ref
 * oscore_msg_native_t from messages that have not been parsed completely, and
 * where invalid option encodings are encountered on the search for a payload
 * marker.
 *
 * It could be argued that this can be made infallible and could return
 * arbitrary zero-length memory as the semantics of the payload can't be
 * comprehended exhaustively having gone through the options. Given that this
 * has little cost and large benefits in debugging, this function is allowed an
 * error code.
 */
oscore_msgerr_native_t oscore_msg_native_map_payload(
        oscore_msg_native_t msg,
        uint8_t **payload,
        size_t *payload_len
        );

/** @brief Shorten the payload to a given length
 *
 * @param[inout] msg Message whose payload is accessed
 * @param[in] payload_len Size of writable payload
 *
 * Reduce the payload length of the message to the given size. This must only
 * be called after @ref oscore_msg_native_map_payload invocations, and the
 * given size must be at most the @p payload_len obtained in that call.
 */
oscore_msgerr_native_t oscore_msg_native_trim_payload(
        oscore_msg_native_t msg,
        size_t payload_len
        );

/** Return true if an error type indicates an unsuccessful operation */
bool oscore_msgerr_native_is_error(oscore_msgerr_native_t);

#else

#include <oscore_native/msg_full.h>

#endif

/** @} */

#endif