libcoap_rs/crypto/psk/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright © The libcoap-rs Contributors, all rights reserved.
 * This file is part of the libcoap-rs project, see the README file for
 * general information on this project and the NOTICE.md and LICENSE files
 * for information regarding copyright ownership and terms of use.
 *
 * crypto/psk/mod.rs - Interfaces and types for PSK support in libcoap-rs.
 */

//! Types and traits related to support for (D)TLS with pre-shared keys for CoAP.
//!
//! PSK configuration differs between client-side and server-side.
//!
//! # Client Configuration
//! Typically, you would follow these steps to configure a DTLS PSK client:
//! 1. Create a [`PskKey`](psk::PskKey) that should be used as a default key when connecting to servers.
//! 2. Create a [`ClientPskContextBuilder`](psk::ClientPskContextBuilder) using the default key,
//!    (optionally) make some additional configuration changes in the builder.
//!    Most notably, you might want to call [`ClientPskContextBuilder::key_provider`](psk::ClientPskContextBuilder::key_provider)
//!    to set a key provider that may use server-provided identity hints to select a different key
//!    than the default key (if your target server sends those hints).
//! 3. Call [`ClientPskContextBuilder::build`](psk::ClientPskContextBuilder::build) to create a
//!    [`ClientPskContext`](psk::ClientPskContext).
//! 4. Provide the created context to [`CoapClientSession::connect_dtls`](crate::session::CoapClientSession::connect_dtls).
//!
//! ## Example
//!
//! ```no_run
//! use libcoap_rs::CoapContext;
//! use libcoap_rs::crypto::psk::{ClientPskContextBuilder, PskKey};
//! use libcoap_rs::session::CoapClientSession;
//!
//! let example_key = PskKey::new(Some("dtls_test_id_client1"), "dtls_test_key__1");
//! let psk_context = ClientPskContextBuilder::new(example_key.clone());
//!
//! let psk_context = psk_context.build();
//!
//! let mut context = CoapContext::new().unwrap();
//! let session = CoapClientSession::connect_dtls(
//!                 &mut context,
//!                 "example.com:5684".parse().unwrap(),
//!                 psk_context
//!               ).unwrap();
//!
//! // The session might not be immediately established, but you can already create and send
//! // requests as usual after this point.
//! // To check for errors and/or disconnections, you might want to call and check the return value
//! // of `session.state()` occasionally.
//! // For error handling, you might also want to register an event handler with the CoAP context.
//! // Remaining code omitted for brevity, see the crate-level docs for a full example of client
//! // operation.
//! ```
//!
//! # Server Configuration
//! Typically, you would follow these steps to configure a DTLS PSK server:
//! 1. Create a [`PskKey`](psk::PskKey) that should be used as a default key when connecting to clients.
//! 2. Create a [`ServerPskContextBuilder`](psk::ServerPskContextBuilder) using the default key, (optionally) make some additional
//!    configuration changes in the builder.
//!    Most notably, you might want to call [`ServerPskContextBuilder::id_key_provider`](psk::ServerPskContextBuilder::id_key_provider) to choose
//!    different pre-shared keys depending on the identity sent by clients, and
//!    [`ServerPskContextBuilder::sni_key_provider`](psk::ServerPskContextBuilder::sni_key_provider) to send different identity hints for different
//!    requested domains.
//! 3. Call [`ServerPskContextBuilder::build`](psk::ServerPskContextBuilder::build) to create a [`ServerPskContext`](psk::ServerPskContext).
//! 4. Provide the created context to [`CoapContext::set_psk_context`](crate::CoapContext::set_psk_context).
//! 5. Add a DTLS endpoint using [`CoapContext::add_endpoint_dtls`](crate::CoapContext::add_endpoint_dtls).
//!
//! ## Example
//!
//! ```no_run
//! use std::collections::HashMap;
//! use libcoap_rs::CoapContext;
//! use libcoap_rs::crypto::psk::{ClientPskContextBuilder, PskKey, ServerPskContextBuilder};
//! use libcoap_rs::session::CoapClientSession;
//!
//!
//! let example_key = PskKey::new(Some("dtls_test_id"), "dtls_test_key___");
//!
//! let mut client_keys = [
//!     PskKey::new(Some("dtls_test_id_client1"), "dtls_test_key__1"),
//!     PskKey::new(Some("dtls_test_id_client2"), "dtls_test_key__2"),
//! ];
//!
//! let psk_context = ServerPskContextBuilder::new(example_key.clone())
//!                     // Some types already implement ServerPskIdentityKeyProvider by default.
//!                     // Namely, all types that implement AsRef<[PskKey]> do, such as [PskKey] and
//!                     // Vec<PskKey>.
//!                     .id_key_provider(client_keys);
//!
//! let psk_context = psk_context.build();
//!
//! let mut context = CoapContext::new().unwrap();
//! context.set_psk_context(psk_context).expect("error while setting PSK context");
//! context.add_endpoint_dtls("[::1]:5684".parse().unwrap()).expect("unable to create DTLS endpoint");
//!
//! // For error handling, you might want to register an event handler with the CoAP context.
//! // Remaining code omitted for brevity, see the crate-level docs for a full example of server
//! // operation.
//!
//! ```

/// Data structures and builders for PSK client-side operation.
mod client;
/// Data structures for PSKs.
mod key;
/// Data structures and builders for PSK server-side operation.
mod server;

pub use client::*;
pub use key::*;
pub use server::*;