1
// SPDX-License-Identifier: BSD-2-Clause
2
/*
3
 * crypto/psk/mod.rs - Interfaces and types for PSK support in libcoap-rs.
4
 * This file is part of the libcoap-rs crate, see the README and LICENSE files for
5
 * more information and terms of use.
6
 * Copyright © 2021-2024 The NAMIB Project Developers, all rights reserved.
7
 * See the README as well as the LICENSE file for more information.
8
 */
9
//! Types and traits related to support for (D)TLS with pre-shared keys for CoAP.
10
//!
11
//! PSK configuration differs between client-side and server-side.
12
//!
13
//! # Client Configuration
14
//! Typically, you would follow these steps to configure a DTLS PSK client:
15
//! 1. Create a [`PskKey`](psk::PskKey) that should be used as a default key when connecting to servers.
16
//! 2. Create a [`ClientPskContextBuilder`](psk::ClientPskContextBuilder) using the default key,
17
//!    (optionally) make some additional configuration changes in the builder.
18
//!    Most notably, you might want to call [`ClientPskContextBuilder::key_provider`](psk::ClientPskContextBuilder::key_provider)
19
//!    to set a key provider that may use server-provided identity hints to select a different key
20
//!    than the default key (if your target server sends those hints).
21
//! 3. Call [`ClientPskContextBuilder::build`](psk::ClientPskContextBuilder::build) to create a
22
//!    [`ClientPskContext`](psk::ClientPskContext).
23
//! 4. Provide the created context to [`CoapClientSession::connect_dtls`](crate::session::CoapClientSession::connect_dtls).
24
//!
25
//! ## Example
26
//!
27
//! ```no_run
28
//! use libcoap_rs::CoapContext;
29
//! use libcoap_rs::crypto::psk::{ClientPskContextBuilder, PskKey};
30
//! use libcoap_rs::session::CoapClientSession;
31
//!
32
//! let example_key = PskKey::new(Some("dtls_test_id_client1"), "dtls_test_key__1");
33
//! let psk_context = ClientPskContextBuilder::new(example_key.clone());
34
//!
35
//! let psk_context = psk_context.build();
36
//!
37
//! let mut context = CoapContext::new().unwrap();
38
//! let session = CoapClientSession::connect_dtls(
39
//!                 &mut context,
40
//!                 "example.com:5684".parse().unwrap(),
41
//!                 psk_context
42
//!               ).unwrap();
43
//!
44
//! // The session might not be immediately established, but you can already create and send
45
//! // requests as usual after this point.
46
//! // To check for errors and/or disconnections, you might want to call and check the return value
47
//! // of `session.state()` occasionally.
48
//! // For error handling, you might also want to register an event handler with the CoAP context.
49
//! // Remaining code omitted for brevity, see the crate-level docs for a full example of client
50
//! // operation.
51
//! ```
52
//!
53
//! # Server Configuration
54
//! Typically, you would follow these steps to configure a DTLS PSK server:
55
//! 1. Create a [`PskKey`](psk::PskKey) that should be used as a default key when connecting to clients.
56
//! 2. Create a [`ServerPskContextBuilder`](psk::ServerPskContextBuilder) using the default key, (optionally) make some additional
57
//!    configuration changes in the builder.
58
//!    Most notably, you might want to call [`ServerPskContextBuilder::id_key_provider`](psk::ServerPskContextBuilder::id_key_provider) to choose
59
//!    different pre-shared keys depending on the identity sent by clients, and
60
//!    [`ServerPskContextBuilder::sni_key_provider`](psk::ServerPskContextBuilder::sni_key_provider) to send different identity hints for different
61
//!    requested domains.
62
//! 3. Call [`ServerPskContextBuilder::build`](psk::ServerPskContextBuilder::build) to create a [`ServerPskContext`](psk::ServerPskContext).
63
//! 4. Provide the created context to [`CoapContext::set_psk_context`](crate::CoapContext::set_psk_context).
64
//! 5. Add a DTLS endpoint using [`CoapContext::add_endpoint_dtls`](crate::CoapContext::add_endpoint_dtls).
65
//!
66
//! ## Example
67
//!
68
//! ```no_run
69
//! use std::collections::HashMap;
70
//! use libcoap_rs::CoapContext;
71
//! use libcoap_rs::crypto::psk::{ClientPskContextBuilder, PskKey, ServerPskContextBuilder};
72
//! use libcoap_rs::session::CoapClientSession;
73
//!
74
//!
75
//! let example_key = PskKey::new(Some("dtls_test_id"), "dtls_test_key___");
76
//!
77
//! let mut client_keys = [
78
//!     PskKey::new(Some("dtls_test_id_client1"), "dtls_test_key__1"),
79
//!     PskKey::new(Some("dtls_test_id_client2"), "dtls_test_key__2"),
80
//! ];
81
//!
82
//! let psk_context = ServerPskContextBuilder::new(example_key.clone())
83
//!                     // Some types already implement ServerPskIdentityKeyProvider by default.
84
//!                     // Namely, all types that implement AsRef<[PskKey]> do, such as [PskKey] and
85
//!                     // Vec<PskKey>.
86
//!                     .id_key_provider(client_keys);
87
//!
88
//! let psk_context = psk_context.build();
89
//!
90
//! let mut context = CoapContext::new().unwrap();
91
//! context.set_psk_context(psk_context).expect("error while setting PSK context");
92
//! context.add_endpoint_dtls("[::1]:5684".parse().unwrap()).expect("unable to create DTLS endpoint");
93
//!
94
//! // For error handling, you might want to register an event handler with the CoAP context.
95
//! // Remaining code omitted for brevity, see the crate-level docs for a full example of server
96
//! // operation.
97
//!
98
//! ```
99

            
100
/// Data structures and builders for PSK client-side operation.
101
mod client;
102
/// Data structures for PSKs.
103
mod key;
104
/// Data structures and builders for PSK server-side operation.
105
mod server;
106

            
107
pub use client::*;
108
pub use key::*;
109
pub use server::*;