Skip to content

Add OSCORE Support #47

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 39 commits into
base: main
Choose a base branch
from
Open

Conversation

ln4c
Copy link

@ln4c ln4c commented Mar 20, 2025

This pull request aims to provide support for OSCORE in libcoap-rs.
It adds a new feature flag "oscore" which has to be activated to enable all functions regarding OSCORE under which we provide the following:

libcoap libcoap-rs
coap_oscore_conf_t OscoreConf::new
coap_new_oscore_recipient CoapContext::new_oscore_recipient
coap_delete_oscore_recipient CoapContext::delete_oscore_recipient
coap_new_client_session_oscore CoapClientSession::connect_oscore
coap_context_oscore_server CoapContext::oscore_server

We introduced two new structs OscoreConf and OscoreRecipient which are currently located within oscore.rs.

We also added new errors to allow for error-handling by the user in errors.rs.

There is also a minimal client and server example available, deriving from the official documentation.

Security was a priority and all unsafe calls have been annotated with an appropriate security notice, as is the standard for this project.

ln4c and others added 30 commits December 19, 2024 22:00
…ons to add oscore conf to context for servers and to add new recipients
…ence_number() using Option and pattern-matching
@pulsastrix pulsastrix self-requested a review March 20, 2025 18:51
@pulsastrix pulsastrix added this to the v0.3.0 milestone Mar 20, 2025
@pulsastrix pulsastrix added enhancement New feature or request libcoap-parity Features that libcoap offers, but libcoap-rs currently does not labels Mar 20, 2025
@pulsastrix pulsastrix linked an issue Mar 20, 2025 that may be closed by this pull request
Copy link

github-actions bot commented Mar 20, 2025

Workflow Status Report

Generated for commit 82a4039 on Mon May 26 15:14:46 UTC 2025.

Test and Analyze
Docs, Coverage Report and PR Updates

In case of failure, clippy warnings and rustfmt changes (if any) will be indicated as CI check warnings in the file comparison view.

Documentation: Download

Coverage Report: Download

Note: Online versions of documentation and coverage reports may not be available indefinitely, especially after the pull request was merged.

Code Coverage Report

Coverage

Coverage target is 80%.

Expand to view coverage statistics
file coverage covered missed_lines
libcoap-sys/src/lib.rs 77.78% 133 / 171 370-381, 489-492, 500, 527-544, 669-672, 756-759
libcoap/src/context.rs 59.52% 175 / 294 131, 196-241, 252-257, 275, 304, 351-355, 388, 403-404, 595-611, 645, 650, 666, 674-836
libcoap/src/crypto/pki_rpk/key.rs 56.32% 49 / 87 179-213, 242-250, 252-255, 261-263
libcoap/src/crypto/pki_rpk/mod.rs 26.44% 87 / 329 36-275, 454-486, 507-605, 613, 616, 650-668, 678-680, 685-687, 692-694, 755, 767-903
libcoap/src/crypto/pki_rpk/pki.rs 76.15% 99 / 130 90-149, 302-315
libcoap/src/crypto/pki_rpk/rpk.rs 68.33% 41 / 60 68-98, 160-171
libcoap/src/crypto/psk/client.rs 43.31% 55 / 127 71-75, 83, 106-192, 234-242, 269-271, 276-278, 306-338
libcoap/src/crypto/psk/key.rs 55.42% 46 / 83 42-49, 163-205
libcoap/src/crypto/psk/mod.rs 0.00% 0 / 24 30-96
libcoap/src/crypto/psk/server.rs 32.43% 48 / 148 69-88, 96, 99, 116-119, 145-147, 152-154, 159-161, 189-234, 255, 271-396
libcoap/src/error.rs 0.00% 0 / 6 160-240
libcoap/src/event.rs 29.73% 11 / 37 36-168
libcoap/src/lib.rs 0.00% 0 / 33 62-165
libcoap/src/mem.rs 72.56% 119 / 164 148-163, 196-198, 210-212, 280, 296-298, 319-324, 353-355, 369, 381-393, 454-456, 473, 481-488, 507, 527, 531
libcoap/src/message/mod.rs 57.37% 183 / 319 105-108, 110-131, 139-145, 147-168, 172, 174, 176, 208, 210, 213-222, 225-243, 245-249, 265-275, 295-302, 398-399, 441, 447, 478, 488-491, 497-499, 506, 511-523, 529, 549-551, 561-563
libcoap/src/message/request.rs 33.79% 99 / 293 51, 68-202, 228-256, 264-365, 371-375, 380-381, 383-386, 389, 395-400, 430-432, 436, 439-441, 444-446, 449, 452, 455, 458, 461, 472-479
libcoap/src/message/response.rs 22.17% 45 / 203 36-160, 165, 168, 171, 174, 177, 195-325, 329-334, 360
libcoap/src/prng.rs 54.79% 40 / 73 66, 78-116, 139-149, 196
libcoap/src/protocol.rs 33.33% 54 / 162 164-166, 171-176, 178-193, 195-196, 203-208, 210-225, 227-228, 285-287, 308, 322-324, 369-374, 383-388, 444-469, 475-488, 520, 522
libcoap/src/resource.rs 67.23% 160 / 238 62, 94-96, 171-176, 183-208, 214-219, 249, 266-288, 300-303, 319-339, 351-354, 387-396, 529-531
libcoap/src/session/client.rs 87.27% 96 / 110 168, 195, 262, 270-272, 278-280, 327-333
libcoap/src/session/mod.rs 41.13% 102 / 248 62-74, 105, 115-230, 240-285, 294-310, 319-330, 359, 363, 395-415, 437, 445, 477, 484, 502-508, 583, 589
libcoap/src/session/server.rs 80.88% 55 / 68 75-77, 81, 152, 162-164, 179, 194-200
libcoap/src/transport.rs 72.73% 16 / 22 29-36, 55
libcoap/src/types.rs 54.69% 268 / 490 71-125, 131-160, 210-243, 253-265, 272-278, 284-286, 295, 371, 411, 450, 562, 571, 583, 610, 636-705, 758, 803-824, 845-868, 879-964
libcoap/tests/common/dtls.rs 93.02% 40 / 43 49, 54-55
libcoap/tests/common/mod.rs 92.00% 69 / 75 85-88, 92, 126
libcoap/tests/dtls_pki_client_server_test.rs 100.00% 65 / 65
libcoap/tests/dtls_psk_client_server_test.rs 100.00% 21 / 21
libcoap/tests/dtls_rpk_client_server_test.rs 100.00% 6 / 6
libcoap/tests/tcp_client_server_test.rs 100.00% 17 / 17
libcoap/tests/udp_client_server_test.rs 100.00% 17 / 17

Total coverage: 53.23%

Copy link
Member

@pulsastrix pulsastrix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, thanks for the contribution!
You can find my initial comments below.

Regarding the examples: Would it be possible to add an abridged version of the examples (without the EDHOC part) to the examples subdirectory or to the module-level rustdoc in oscore.rs?
That way, we can use those as (no_run) tests.

Lastly, it would also be nice if we had a runnable test case that runs both a server and a client and performs a basic request, akin to the test cases already present for UDP and DTLS.

Comment on lines 437 to 456
// SAFETY: Properly initialized CoapContext always has a valid raw_context that is not deleted until
// the CoapContextInner is dropped. OscoreConf raw_conf should be valid, else return an error.
//
// coap_context_oscore_server will also always free the raw_conf, regardless of the result:
// [libcoap docs](https://libcoap.net/doc/reference/4.3.5/group__oscore.html#ga71ddf56bcd6d6650f8235ee252fde47f)
unsafe {
result = coap_context_oscore_server(inner_ref.raw_context, oscore_conf.as_mut_raw_conf()?);
};

// Invalidate the OscoreConf raw_conf as its freed by the call above.
oscore_conf.raw_conf_valid = false;

// Check whether adding the config to the context failed.
if result == 0 {
return Err(OscoreServerCreationError::Unknown);
}

// Add the initial_recipient (if present).
if let Some(initial_recipient) = oscore_conf.initial_recipient.clone() {
let initial_recipient = OscoreRecipient::new(initial_recipient.as_str());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't this be easier to represent by having a function OscoreConf::into_raw_conf(self) -> (*mut coap_oscore_conf_t, Option<OscoreRecipient>) that consumes the config?

That way, you can avoid managing a separate field to check that the pointer is still usable (the pointer being valid would be guaranteed/an invariant for the lifetime of the OscoreConf instance.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still needed to revert to the a separate field because else OscoreConf instances that were never consumed can't be freed of easily as we cannot determine whether the raw_conf might have been freed before.

}

// ...or else save the recipient to keep alive the pointer to its raw struct.
inner_ref.recipients.push(recipient);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Raw pointers are not freed if the struct containing them is dropped, so you might not even have to keep the OscoreRecipient stored at all.

In fact, you might also get away with not having an OscoreRecipient struct at all and just taking a recipient_id: &str as arguments for this method and delete_oscore_recipient() instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request libcoap-parity Features that libcoap offers, but libcoap-rs currently does not
Projects
None yet
Development

Successfully merging this pull request may close these issues.

OSCORE support
3 participants