Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
COAP_OSCORE(3)			 libcoap Manual 		  COAP_OSCORE(3)

NAME
     coap_oscore,  coap_new_oscore_conf,  coap_delete_oscore_conf,  coap_new_os-
     core_recipient,  coap_delete_oscore_recipient,  coap_new_client_session_os-
     core,    coap_new_client_session_oscore_pki,    coap_new_client_session_os-
     core_psk, coap_context_oscore_server - Work with CoAP OSCORE

SYNOPSIS
     #include <coap3/coap.h>

     coap_oscore_conf_t     *coap_new_oscore_conf(coap_str_const_t     conf_mem,
     coap_oscore_save_seq_num_t 	     save_seq_num_func, 	    void
     *save_seq_num_func_param, uint64_t start_seq_num);

     int coap_delete_oscore_conf(coap_oscore_conf_t *oscore_conf);

     int  coap_new_oscore_recipient(coap_context_t  *context,	coap_bin_const_t
     *recipient_id);

     int  coap_delete_oscore_recipient(coap_context_t *context, coap_bin_const_t
     *recipient_id);

     coap_session_t   *coap_new_client_session_oscore(coap_context_t   *context,
     const  coap_address_t *local_if, const coap_address_t *server, coap_proto_t
     proto, coap_oscore_conf_t *oscore_conf);

     coap_session_t *coap_new_client_session_oscore_psk(coap_context_t *context,
     const coap_address_t *local_if, const coap_address_t *server,  coap_proto_t
     proto, coap_dtls_cpsk_t *psk_data, coap_oscore_conf_t *oscore_conf);

     coap_session_t *coap_new_client_session_oscore_pki(coap_context_t *context,
     const  coap_address_t *local_if, const coap_address_t *server, coap_proto_t
     proto, coap_dtls_pki_t *pki_data, coap_oscore_conf_t *oscore_conf);

     int coap_context_oscore_server(coap_context_t *context,  coap_oscore_conf_t
     *oscore_conf);

     For   specific   (D)TLS   library	 support,   link   with  -lcoap-3-notls,
     -lcoap-3-gnutls, -lcoap-3-openssl,  -lcoap-3-mbedtls,  -lcoap-3-wolfssl  or
     -lcoap-3-tinydtls.  Otherwise, link with -lcoap-3 to get the default (D)TLS
     library support.

DESCRIPTION
     This describes libcoap's support for using OSCORE as defined in RFC8613.

     OSCORE provides end-to-end protection between endpoints communicating using
     CoAP. (D)TLS can only protect HOP by HOP traffic which  allows  proxies  to
     manipulate information.

CALLBACK HANDLER
     Callback Type: coap_oscore_save_seq_num_t

     The coap_oscore_save_seq_num_t method handler function prototype is defined
     as:

	 /**
	  * Definition of the function used to save the current Sender Sequence Number
	  *
	  * @param sender_seq_num The Sender Sequence Number to save in non-volatile
	  *			 memory.
	  * @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);

FUNCTIONS
     Function: coap_new_oscore_conf()

     The  coap_new_oscore_conf() function is used to build a new OSCORE configu-
     ration. It parses the provided OSCORE configuration in conf_mem. The format
     of the keywords, encoding	types  and  values  is	documented  in	coap-os-
     core-conf(5).  It	also  sets an optional function save_seq_num_func (which
     gets save_seq_num_func_param passed in) that is called to	store  the  next
     Sender  Sequence  Number (SSN) in non-volatile storage. The latest next SSN
     from non-volatile storage (or 0) is then put in start_seq_num. SSN are used
     so that  anti-replay  mechanisms  do  not	kick  in  following  application
     restarts.	The  rate  of calling save_seq_num_func can be controlled by the
     ssn_freq parameter as defined in coap-oscore-conf(5).

     This OSCORE configuration is then used in the client and server OSCORE ver-
     sion of the setup functions.

     If the server is proxy enabled and the new incoming session is  OSCORE  en-
     coded  with  the Outer CoAP ProxyScheme and Host options set, then the lib-
     coap logic will determine whether the server is the final endpoint  of  the
     session, or whether the proxy will be forwarding the session off to another
     server,  based  on how coap_resource_proxy_uri_init(3) configured the proxy
     logic. If the session is going to forwarded,  then  the  OSCORE  protection
     will not be removed.

     If  coap_context_oscore_server() is not called and the proxy logic (if set)
     indicates the session will get forwarded, then the OSCORE protection is un-
     touched, otherwise the session will get dropped with  an  unknown	critical
     option error response.

     Function: coap_new_oscore_recipient()

     The  coap_new_oscore_recipient()  is  used to add a new recipient_id to the
     OSCORE information associated with context. The new recipient_id should  be
     unique  and this function should only be used for server based applications
     as the client will only ever use the first defined recipient_id. It is  as-
     sumed  that  coap_context_oscore_server() has already been called to update
     context with the appropriate OSCORE information.

     Function: coap_delete_oscore_recipient()

     The coap_delete_oscore_recipient() is used to remove the recipient_id  from
     the  OSCORE  information associated with context. OSCORE Traffic continuing
     to use recipient_id will then fail.

     Function: coap_delete_oscore_conf()

     The coap_delete_oscore_conf() function is used to	free  off  the	coap_os-
     core_conf_t  structure  oscore_conf  as returned by coap_new_oscore_conf().
     Normally this function never needs to be called as oscore_conf is freed off
     by the call the client or server setup functions.

     Function: coap_new_client_session_oscore()

     The   coap_new_client_session_oscore()   is   basically   the    same    as
     coap_new_client_session(3),  but  has  an	additional parameter oscore_conf
     that is created by coap_new_oscore_conf(). This function creates  a  client
     endpoint  for  a specific context and initiates a new client session to the
     specified server using the CoAP protocol proto and OSCORE protected by  the
     oscore_conf  definition  (which  is freed off by this call). If the port is
     set to 0 in server, then the default CoAP port is used.  Normally	local_if
     would  be set to NULL, but by specifying local_if the source of the network
     session can be bound to a specific IP address or  port.  The  session  will
     initially have a reference count of 1.

     Function: coap_new_client_session_oscore_psk()

     The   coap_new_client_session_oscore_psk()   is   basically   the	same  as
     coap_new_client_session_psk2(3),  but  has  an  additional  parameter   os-
     core_conf	that  is created by coap_new_oscore_conf(). This function, for a
     specific context, is used to configure the TLS context using the setup_data
     variables as defined in the coap_dtls_cpsk_t structure in the newly created
     endpoint session - see coap_encryption(3), as well as OSCORE  protected  by
     the  oscore_conf  definition (which is freed off by this call). The connec-
     tion is to the specified server using the CoAP protocol proto. If the  port
     is  set  to  0  in server, then the default CoAP port is used. Normally lo-
     cal_if would be set to NULL, but by specifying local_if the source  of  the
     network  session can be bound to a specific IP address or port. The session
     will initially have a reference count of 1.

     Function: coap_new_client_session_oscore_pki()

     The  coap_new_client_session_oscore_pki()	is   basically	 the   same   as
     coap_new_client_session_pki(3), but has an additional parameter oscore_conf
     that  is  created	by coap_new_oscore_conf(). This function, for a specific
     context, is used to configure the TLS context using  the  setup_data  vari-
     ables as defined in the coap_dtls_pki_t structure in the newly created end-
     point  session - see coap_encryption(3), as well as OSCORE protected by the
     oscore_conf definition (which is freed off by this call). The connection is
     to the specified server using the CoAP protocol proto. If the port  is  set
     to 0 in server, then the default CoAP port is used. Normally local_if would
     be  set  to NULL, but by specifying local_if the source of the network ses-
     sion can be bound to a specific IP address or port. The session  will  ini-
     tially have a reference count of 1.

     Function: coap_context_oscore_server()

     The  coap_context_oscore_server()	function is used to enable the server to
     support OSCORE incoming sessions. It updates context with the  OSCORE  con-
     figure oscore_conf (which is freed off by this call).

RETURN VALUES
     coap_new_client_session_oscore(),	coap_new_client_session_oscore_psk() and
     coap_new_client_session_oscore_pki() return a newly created client  session
     or NULL if there is a malloc or parameter failure.

     coap_new_oscore_conf() returns a coap_oscore_conf_t or NULL on failure.

     coap_context_oscore_server(),    coap_delete_oscore_conf(),    coap_new_os-
     core_recipient() and coap_delete_oscore_recipient() return 0 on failure,  1
     on success.

EXAMPLES
     Client Setup

	 #include <coap3/coap.h>

	 #include <netinet/in.h>
	 #include <stdio.h>

	 static uint8_t oscore_config[] =
	     "master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\n"
	     "master_salt,hex,\"9e7ca92223786340\"\n"
	     "server_id,ascii,\"client\"\n"
	     "recipient_id,ascii,\"server\"\n"
	     "replay_window,integer,30\n"
	     "aead_alg,integer,10\n"
	     "hkdf_alg,integer,-10\n"
	     ;
	 static FILE *oscore_seq_num_fp = NULL;
	 /* Not a particularly safe place to keep next Sender Sequence Number ... */
	 static const char *oscore_seq_save_file = "/tmp/client.seq";

	 static int
	 oscore_save_seq_num(uint64_t sender_seq_num, void *param COAP_UNUSED) {
	   if (oscore_seq_num_fp) {
	     rewind(oscore_seq_num_fp);
	     fprintf(oscore_seq_num_fp, "%lu\n", sender_seq_num);
	     fflush(oscore_seq_num_fp);
	   }
	   return 1;
	 }

	 static coap_session_t *
	 setup_client_session(struct in_addr ip_address) {
	   coap_session_t *session;
	   coap_address_t server;
	   /* See coap_context(3) */
	   coap_context_t *context = coap_new_context(NULL);

	   if (!context)
	     return NULL;

	   /* See coap_block(3) */
	   coap_context_set_block_mode(context,
				       COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY);

	   coap_address_init(&server);
	   server.addr.sa.sa_family = AF_INET;
	   server.addr.sin.sin_addr = ip_address;
	   server.addr.sin.sin_port = htons(5683);

	   if (coap_oscore_is_supported()) {
	     coap_str_const_t config = { sizeof(oscore_config), oscore_config };
	     uint64_t start_seq_num = 0;
	     coap_oscore_conf_t *oscore_conf;

	     if (oscore_seq_save_file) {
	       oscore_seq_num_fp = fopen(oscore_seq_save_file, "r+");
	       if (oscore_seq_num_fp == NULL) {
		 /* Try creating it */
		 oscore_seq_num_fp = fopen(oscore_seq_save_file, "w+");
		 if (oscore_seq_num_fp == NULL) {
		   coap_log_err("OSCORE save restart info file error: %s\n",
				oscore_seq_save_file);
		   return NULL;
		 }
	       }
	       fscanf(oscore_seq_num_fp, "%ju", &start_seq_num);
	     }
	     oscore_conf = coap_new_oscore_conf(config, oscore_save_seq_num,
						NULL, start_seq_num);
	     if (!oscore_conf) {
	       coap_free_context(context);
	       return NULL;
	     }
	     session = coap_new_client_session_oscore(context, NULL, &server,
						      COAP_PROTO_UDP, oscore_conf);
	   } else {
	     session = coap_new_client_session(context, NULL, &server, COAP_PROTO_UDP);
	   }
	   if (!session) {
	     coap_free_context(context);
	     return NULL;
	   }
	   /* The context is in session->context */
	   return session;
	 }

     Server Setup

	 #include <coap3/coap.h>
	 #include <stdio.h>

	 static uint8_t oscore_config[] =
	     "master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\n"
	     "master_salt,hex,\"9e7ca92223786340\"\n"
	     "sender_id,ascii,\"server\"\n"
	     "recipient_id,ascii,\"client\"\n"
	     "replay_window,integer,30\n"
	     "aead_alg,integer,10\n"
	     "hkdf_alg,integer,-10\n"
	     ;
	 static FILE *oscore_seq_num_fp = NULL;
	 /* Not a particularly safe place to keep next Sender Sequence Number ... */
	 static const char *oscore_seq_save_file = "/tmp/server.seq";

	 static int
	 oscore_save_seq_num(uint64_t sender_seq_num, void *param COAP_UNUSED) {
	   if (oscore_seq_num_fp) {
	     rewind(oscore_seq_num_fp);
	     fprintf(oscore_seq_num_fp, "%lu\n", sender_seq_num);
	     fflush(oscore_seq_num_fp);
	   }
	   return 1;
	 }

	 static int
	 setup_context(void) {
	   /* See coap_context(3) */
	   coap_context_t *context = coap_new_context(NULL);

	   if (!context)
	     return 0;

	   /* See coap_block(3) */
	   coap_context_set_block_mode(context,
				       COAP_BLOCK_USE_LIBCOAP | COAP_BLOCK_SINGLE_BODY);

	   if (coap_oscore_is_supported()) {
	     coap_str_const_t config = { sizeof(oscore_config), oscore_config };
	     uint64_t start_seq_num = 0;
	     coap_oscore_conf_t *oscore_conf;

	     if (oscore_seq_save_file) {
	       oscore_seq_num_fp = fopen(oscore_seq_save_file, "r+");
	       if (oscore_seq_num_fp == NULL) {
		 /* Try creating it */
		 oscore_seq_num_fp = fopen(oscore_seq_save_file, "w+");
		 if (oscore_seq_num_fp == NULL) {
		   coap_log_err("OSCORE save restart info file error: %s\n",
				oscore_seq_save_file);
		   return 0;
		 }
	       }
	       fscanf(oscore_seq_num_fp, "%ju", &start_seq_num);
	     }
	     oscore_conf = coap_new_oscore_conf(config, oscore_save_seq_num,
						NULL, start_seq_num);
	     if (!oscore_conf) {
	       coap_free_context(context);
	       return 0;
	     }
	     coap_context_oscore_server(context, oscore_conf);
	   }
	   return 1;
	 }

SEE ALSO
     coap_endpoint_client(3),  coap_endpoint_server(3),  coap-oscore-conf(5) and
     coap_supported(3)

FURTHER INFORMATION
     See

     "RFC7252: The Constrained Application Protocol (CoAP)"

     "RFC8613: Object Security for Constrained RESTful Environments (OSCORE)"

     for further information.

BUGS
     Please raise an issue on GitHub  at  https://github.com/obgm/libcoap/issues
     to report any bugs.

     Please  raise  a  Pull Request at https://github.com/obgm/libcoap/pulls for
     any fixes.

AUTHORS
     The libcoap project <libcoap-developers@lists.sourceforge.net>

coap_oscore 4.3.5		   08/02/2026			  COAP_OSCORE(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=coap_oscore&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help