mirror of
https://github.com/obgm/libcoap.git
synced 2026-11-12 11:40:39 +03:00
100 lines
3.3 KiB
C
100 lines
3.3 KiB
C
#include "coap3/coap_internal.h"
|
|
|
|
int
|
|
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
|
coap_context_t *ctx;
|
|
coap_session_t *session = NULL;
|
|
coap_pdu_t *pdu = NULL, *decrypted = NULL;
|
|
coap_address_t addr;
|
|
size_t opt_len, encrypted_len;
|
|
uint16_t partial_iv_len, kid_context_len, kid_len;
|
|
uint8_t oscore_option[256];
|
|
static const char oscore_conf_str[] =
|
|
"master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\n"
|
|
"master_salt,hex,\"9e7ca92223786340\"\n"
|
|
"sender_id,hex,\"\"\n"
|
|
"rfc8613_b_1_2,bool,false\n"
|
|
"recipient_id,hex,\"01\"\n";
|
|
|
|
if (size < 2)
|
|
return 0;
|
|
|
|
/* Initialize libcoap with OSCORE support */
|
|
coap_startup();
|
|
coap_set_log_level(COAP_LOG_ERR);
|
|
coap_str_const_t conf = { sizeof(oscore_conf_str) - 1, (const uint8_t *)oscore_conf_str };
|
|
coap_oscore_conf_t *oscore_conf = coap_new_oscore_conf(conf, NULL, NULL, 0);
|
|
|
|
/* Stop transmission of any error packets */
|
|
coap_debug_set_packet_loss("50%");
|
|
coap_debug_set_packet_fail("100%");
|
|
|
|
/* Set up OSCORE context */
|
|
ctx = coap_new_context(NULL);
|
|
if (ctx && oscore_conf) {
|
|
if (coap_context_oscore_server(ctx, oscore_conf)) {
|
|
/* Create a new client session */
|
|
coap_address_init(&addr);
|
|
addr.size = sizeof(struct sockaddr_in);
|
|
addr.addr.sin.sin_family = AF_INET;
|
|
addr.addr.sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
|
addr.addr.sin.sin_port = htons(5683);
|
|
|
|
session = coap_new_client_session(ctx, NULL, &addr, COAP_PROTO_UDP);
|
|
|
|
/* Build PDU with OSCORE option and encrypted data from fuzzer data */
|
|
if (session) {
|
|
/* Calculate OSCORE option length based on RFC 8613 Section 6.1 */
|
|
partial_iv_len = data[0] & 0x7;
|
|
if (1UL + partial_iv_len >= size)
|
|
goto cleanup;
|
|
|
|
kid_context_len = data[0] & 0x10 ? 1 + data[1 + partial_iv_len] : 0;
|
|
|
|
/* Build option with KID forced to one byte to match recipient_id in oscore_conf_str */
|
|
kid_len = 1;
|
|
/* Include byte 0 in the length */
|
|
opt_len = 1 + partial_iv_len + kid_context_len + kid_len;
|
|
/* Max allowed option size is 256 */
|
|
if (opt_len >= sizeof(oscore_option) || opt_len > size)
|
|
goto cleanup;
|
|
memcpy(oscore_option, data, opt_len - 1);
|
|
oscore_option[opt_len - 1] = 0x01;
|
|
|
|
pdu = coap_pdu_init(COAP_MESSAGE_NON, COAP_REQUEST_CODE_GET,
|
|
coap_new_message_id(session), 256);
|
|
|
|
if (pdu) {
|
|
/* Add OSCORE option with KID fixed to 0x01 */
|
|
if (coap_add_option(pdu, COAP_OPTION_OSCORE, opt_len, oscore_option)) {
|
|
/* Add remaining data as encrypted payload (from after original option) */
|
|
encrypted_len = size - opt_len;
|
|
if (encrypted_len > 0) {
|
|
coap_add_data(pdu, encrypted_len, &data[opt_len]);
|
|
}
|
|
|
|
/* Test OSCORE decryption */
|
|
decrypted = coap_oscore_decrypt_pdu(session, pdu);
|
|
if (decrypted) {
|
|
coap_show_pdu(COAP_LOG_ERR, decrypted);
|
|
coap_delete_pdu(decrypted);
|
|
}
|
|
}
|
|
coap_delete_pdu(pdu);
|
|
}
|
|
cleanup:
|
|
coap_session_release(session);
|
|
}
|
|
}
|
|
} else if (oscore_conf) {
|
|
/* ctx creation failed, need to free oscore_conf */
|
|
coap_delete_oscore_conf(oscore_conf);
|
|
}
|
|
|
|
if (ctx)
|
|
coap_free_context(ctx);
|
|
|
|
coap_cleanup();
|
|
return 0;
|
|
}
|