Skip to content

Commit

Permalink
OSCORE: Added user-defined callback for finding oscore context
Browse files Browse the repository at this point in the history
  • Loading branch information
Patryk Jarosz committed Mar 6, 2024
1 parent 9a40fb1 commit 9f2f4ec
Show file tree
Hide file tree
Showing 10 changed files with 155 additions and 4 deletions.
2 changes: 2 additions & 0 deletions include/coap3/coap_net_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ struct coap_context_t {
#endif /* WITH_LWIP */
#if COAP_OSCORE_SUPPORT
struct oscore_ctx_t *p_osc_ctx; /**< primary oscore context */
external_oscore_find_context_handler_t external_oscore_find_context_handler;
/**< Called when oscore_find_context didn't find any context*/
#endif /* COAP_OSCORE_SUPPORT */

#if COAP_CLIENT_SUPPORT
Expand Down
46 changes: 45 additions & 1 deletion include/coap3/coap_oscore.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,17 @@ int coap_context_oscore_server(coap_context_t *context,
*
* @param sender_seq_num The Sender Sequence Number to save in non-volatile
* memory.
* @param recipient_id Recipient ID that could be used to find the corresponding SSN entry.
* @param id_context ID Context that could be used to find the corresponding SSN entry.
* @param param The save_seq_num_func_param provided to
* coap_new_oscore_context().
*
* @return @c 1 if success, else @c 0 if a failure of some sort.
*/
typedef int (*coap_oscore_save_seq_num_t)(uint64_t sender_seq_num, void *param);
typedef int (*coap_oscore_save_seq_num_t)(uint64_t sender_seq_num,
const coap_bin_const_t *recipient_id,
const coap_bin_const_t *id_context,
void *param);

/**
* Parse an OSCORE configuration (held in memory) and populate a OSCORE
Expand Down Expand Up @@ -193,6 +198,45 @@ int coap_new_oscore_recipient(coap_context_t *context,
int coap_delete_oscore_recipient(coap_context_t *context,
coap_bin_const_t *recipient_id);

/**
* Opaque pointer for internal oscore_ctx_t type.
*/
typedef struct oscore_ctx_t * oscore_ctx_handle_t;

/**
* Opaque pointer for internal oscore_recipient_ctx_t type.
*
*/
typedef struct oscore_recipient_ctx_t * oscore_recipient_ctx_handle_t;

/**
* Optional user callback to be used, when oscore_find_context can't find any context.
* Could be used to check external storage (e.g. FLASH).
*
* @param c_context The CoAP Context to search.
* @param rcpkey_id The Recipient kid.
* @param ctxkey_id The ID Context to match (or NULL if no check).
* @param oscore_r2 Partial id_context to match against or NULL.
* @param recipient_ctx The recipient context to update.
*
* return The OSCORE context and @p recipient_ctx updated, or NULL is error.
*/
typedef oscore_ctx_handle_t (*external_oscore_find_context_handler_t)(
const coap_context_t *c_context,
const coap_bin_const_t rcpkey_id,
const coap_bin_const_t *ctxkey_id,
uint8_t *oscore_r2,
oscore_recipient_ctx_handle_t *recipient_ctx);

/**
* Register optional user callback to be used, when oscore_find_context can't find any context.
* Callback could be used to check external storage (e.g. FLASH).
*
* @param context The current coap context to use.
* @param handler User callback.
*/
void coap_register_oscore_context_handler(coap_context_t *context, external_oscore_find_context_handler_t handler);

/** @} */

#endif /* COAP_OSCORE_H */
11 changes: 11 additions & 0 deletions include/coap3/coap_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
* @{
*/

#include <stdbool.h>

/**
* Abstraction of a fixed point number that can be used where necessary instead
* of a float. 1,000 fractional bits equals one integer
Expand Down Expand Up @@ -163,6 +165,15 @@ coap_proto_t coap_session_get_proto(const coap_session_t *session);
*/
coap_session_type_t coap_session_get_type(const coap_session_t *session);

/**
* Check if CoAP session is encrypted.
*
* @param session The CoAP session.
*
* @return True if session is encrypted, false if session is not encrypted.
*/
bool coap_session_is_encrypted(const coap_session_t *session);

/**
* Get the session state
*
Expand Down
17 changes: 17 additions & 0 deletions include/oscore/oscore_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,23 @@ oscore_ctx_t *oscore_find_context(const coap_context_t *c_context,
uint8_t *oscore_r2,
oscore_recipient_ctx_t **recipient_ctx);

/**
* oscore_find_context_in_ram - Locate recipient context (and hence OSCORE context) in RAM only
*
* @param c_context The CoAP Context to search.
* @param rcpkey_id The Recipient kid.
* @param ctxkey_id The ID Context to match (or NULL if no check).
* @param oscore_r2 Partial id_context to match against or NULL.
* @param recipient_ctx The recipient context to update.
*
* return The OSCORE context and @p recipient_ctx updated, or NULL is error.
*/
oscore_ctx_t *oscore_find_context_in_ram(const coap_context_t *c_context,
const coap_bin_const_t rcpkey_id,
const coap_bin_const_t *ctxkey_id,
uint8_t *oscore_r2,
oscore_recipient_ctx_t **recipient_ctx);

void oscore_free_association(oscore_association_t *association);

int oscore_new_association(coap_session_t *session,
Expand Down
17 changes: 16 additions & 1 deletion man/coap_oscore.txt.in
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ coap_delete_oscore_recipient,
coap_new_client_session_oscore,
coap_new_client_session_oscore_pki,
coap_new_client_session_oscore_psk,
coap_context_oscore_server
coap_context_oscore_server,
coap_register_oscore_context_handler
- Work with CoAP OSCORE

SYNOPSIS
Expand Down Expand Up @@ -57,6 +58,9 @@ coap_oscore_conf_t *_oscore_conf_);*
*int coap_context_oscore_server(coap_context_t *_context_,
coap_oscore_conf_t *_oscore_conf_);*

*void coap_register_oscore_context_handler(coap_context_t *context,
external_oscore_find_context_handler_t handler);*

For specific (D)TLS library support, link with
*-lcoap-@LIBCOAP_API_VERSION@-notls*, *-lcoap-@LIBCOAP_API_VERSION@-gnutls*,
*-lcoap-@LIBCOAP_API_VERSION@-openssl*, *-lcoap-@LIBCOAP_API_VERSION@-mbedtls*
Expand Down Expand Up @@ -191,6 +195,17 @@ The *coap_context_oscore_server*() function is used to enable the server to
support OSCORE incoming sessions. It updates _context_ with the OSCORE
configure _oscore_conf_ (which is freed off by this call).

*Function: coap_register_oscore_context_handler()*

The *coap_register_oscore_context_handler*() function is used to register
an optional, external callback, which will be called if no OSCORE context
is found by oscore_find_context. It can be used by the user to provide an
external source of OSCORE contexts, e.g. a non-volatile memory.
Together with user-defined coap_oscore_save_seq_num_t callback provided
while creating the context, this mechanism may be used to periodically
store Sender Sequence Number field - thus providing a way to fully restore
the context after the device reboots.

RETURN VALUES
-------------
*coap_new_client_session_oscore*(), *coap_new_client_session_oscore_psk*()
Expand Down
7 changes: 7 additions & 0 deletions man/coap_session.txt.in
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ coap_session_get_proto,
coap_session_get_state,
coap_session_get_tls,
coap_session_get_type,
coap_session_is_encrypted,
coap_session_get_psk_hint,
coap_session_get_psk_key
- Work with CoAP sessions
Expand Down Expand Up @@ -68,6 +69,8 @@ coap_tls_library_t *tls_lib);*

*coap_session_type_t coap_session_get_type(const coap_session_t *_session_);*

*bool coap_session_is_encrypted(const coap_session_t *session);*

*const coap_bin_const_t *coap_session_get_psk_hint(
const coap_session_t *_session_);*

Expand Down Expand Up @@ -216,6 +219,8 @@ COAP_SESSION_TYPE_HELLO /* Negotiating a (D)TLS session */
The *coap_session_get_type*() function is used to get the session type from the
_session_.

The *coap_session_is_encrypted*() function is used to check if incoming _session_ is encrypted.

The *coap_session_get_psk_hint*() function is used to get the current server
_session_'s pre-shared-key identity hint.

Expand Down Expand Up @@ -253,6 +258,8 @@ error.

*coap_session_get_type*() returns the current session's type or 0 on error.

*coap_session_is_encrypted*() returns true if the session is using OSCORE encryption, or false if plain CoAP packets are used.

*coap_session_get_psk_hint*() returns the current server session's
pre-shared-key identity hint, or NULL if not defined.

Expand Down
4 changes: 3 additions & 1 deletion src/coap_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,9 @@ coap_option_check_critical(coap_session_t *session,
case COAP_OPTION_OSCORE:
/* Valid critical if doing OSCORE */
#if COAP_OSCORE_SUPPORT
if (ctx->p_osc_ctx)
/* Only accept OSCORE option if any OSCORE context is available,
or the user provided an external handler for finding the context. */
if ((ctx->p_osc_ctx) || (ctx->external_oscore_find_context_handler))
break;
#endif /* COAP_OSCORE_SUPPORT */
/* Fall Through */
Expand Down
21 changes: 20 additions & 1 deletion src/coap_oscore.c
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,8 @@ coap_oscore_new_pdu_encrypted(coap_session_t *session,
/* Only update at ssn_freq rate */
osc_ctx->sender_context->next_seq += osc_ctx->ssn_freq;
osc_ctx->save_seq_num_func(osc_ctx->sender_context->next_seq,
rcp_ctx->recipient_id,
osc_ctx->id_context,
osc_ctx->save_seq_num_func_param);
}
}
Expand Down Expand Up @@ -808,7 +810,10 @@ coap_oscore_decrypt_pdu(coap_session_t *session,
if (opt == NULL)
return NULL;

if (session->context->p_osc_ctx == NULL) {
/* OSCORE should be processed only if any OSCORE context is available,
or the user provided an external handler for finding the context. */
if ((session->context->p_osc_ctx == NULL) &&
(session->context->external_oscore_find_context_handler == NULL)) {
coap_log_warn("OSCORE: Not enabled\n");
if (!coap_request)
coap_handle_event(session->context,
Expand Down Expand Up @@ -2106,6 +2111,13 @@ coap_delete_oscore_recipient(coap_context_t *context,
return oscore_delete_recipient(context->p_osc_ctx, recipient_id);
}

void
coap_register_oscore_context_handler(coap_context_t *context, external_oscore_find_context_handler_t handler)
{
assert(context);
context->external_oscore_find_context_handler = handler;
}

/** @} */

#else /* !COAP_OSCORE_SUPPORT */
Expand Down Expand Up @@ -2202,4 +2214,11 @@ coap_delete_oscore_recipient(coap_context_t *context,
return 0;
}

void
coap_register_oscore_context_handler(coap_context_t *context, external_oscore_find_context_handler_t handler)
{
(void)context;
(void)handler;
}

#endif /* !COAP_OSCORE_SUPPORT */
8 changes: 8 additions & 0 deletions src/coap_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -1666,6 +1666,14 @@ coap_session_get_type(const coap_session_t *session) {
return 0;
}

bool
coap_session_is_encrypted(const coap_session_t *session) {
#if COAP_OSCORE_SUPPORT
return (session->oscore_encryption != 0);
#endif
return false;
}

#if COAP_CLIENT_SUPPORT
int
coap_session_set_type_client(coap_session_t *session) {
Expand Down
26 changes: 26 additions & 0 deletions src/oscore/oscore_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,32 @@ oscore_find_context(const coap_context_t *c_context,
const coap_bin_const_t *ctxkey_id,
uint8_t *oscore_r2,
oscore_recipient_ctx_t **recipient_ctx) {
oscore_ctx_t *osc_ctx = oscore_find_context_in_ram(c_context, rcpkey_id, ctxkey_id, oscore_r2, recipient_ctx);
if( NULL != osc_ctx )
{
return osc_ctx;
}

/* no context was found in libcoap RAM - call user function to also check external storage (e.g. FLASH) */
if (c_context->external_oscore_find_context_handler)
{
return c_context->external_oscore_find_context_handler(c_context, rcpkey_id, ctxkey_id, oscore_r2, recipient_ctx);
}
return NULL;
}

/*
* oscore_find_context_in_ram
* Finds OSCORE context in RAM for rcpkey_id and optional ctxkey_id
* rcpkey_id can be 0 length.
* Updates recipient_ctx.
*/
oscore_ctx_t *
oscore_find_context_in_ram(const coap_context_t *c_context,
const coap_bin_const_t rcpkey_id,
const coap_bin_const_t *ctxkey_id,
uint8_t *oscore_r2,
oscore_recipient_ctx_t **recipient_ctx) {
oscore_ctx_t *pt = c_context->p_osc_ctx;

*recipient_ctx = NULL;
Expand Down

0 comments on commit 9f2f4ec

Please sign in to comment.