1
// SPDX-License-Identifier: BSD-2-Clause
2
/*
3
 * Copyright © The libcoap-rs Contributors, all rights reserved.
4
 * This file is part of the libcoap-rs project, see the README file for
5
 * general information on this project and the NOTICE.md and LICENSE files
6
 * for information regarding copyright ownership and terms of use.
7
 *
8
 * crypto/psk/mod.rs - Interfaces and types for PSK support in libcoap-rs.
9
 */
10

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

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

            
109
pub use client::*;
110
pub use key::*;
111
pub use server::*;