kipuka_coap/lib.rs
1//! EST over CoAP (RFC 9483) transport for constrained devices.
2//!
3//! This crate implements the CoAP transport binding for Enrollment over Secure
4//! Transport, enabling EST operations on constrained IoT devices that cannot
5//! use HTTP/TLS.
6//!
7//! # Protocol Mapping
8//!
9//! RFC 9483 maps EST operations to CoAP as follows:
10//! - HTTPS transport is replaced by CoAP over DTLS ("coaps")
11//! - EST URI paths use abbreviated names (e.g., `/sen` for `/simpleenroll`)
12//! - HTTP Content-Type headers map to CoAP Content-Format option IDs
13//! - Large payloads (PQC certificates can exceed 7KB) use RFC 7959 block-wise transfer
14//!
15//! # Modules
16//!
17//! - [`server`]: CoAP message parsing, encoding, and EST-coaps URI routing
18//! - [`dtls`]: DTLS session management abstraction for CoAP security
19//! - [`block`]: RFC 7959 block-wise transfer for large EST payloads
20//! - [`content_format`]: CoAP content-format IDs for EST media types (RFC 9483 §5.4)
21
22pub mod block;
23pub mod content_format;
24pub mod dtls;
25pub mod server;
26
27use thiserror::Error;
28
29/// Errors arising from CoAP/EST-coaps protocol handling.
30#[derive(Debug, Error, Clone)]
31pub enum CoapError {
32 /// Malformed CoAP message (header, token, or option encoding).
33 #[error("Invalid CoAP message: {0}")]
34 InvalidMessage(String),
35
36 /// Unrecognized or unsupported CoAP method code.
37 #[error("Unsupported CoAP method: {0}")]
38 UnsupportedMethod(String),
39
40 /// Unrecognized CoAP Content-Format option value.
41 ///
42 /// RFC 9483 §5.4 defines the content-format IDs that EST-coaps supports.
43 #[error("Unsupported Content-Format: {0}")]
44 UnsupportedContentFormat(u16),
45
46 /// Block-wise transfer failure per RFC 7959.
47 #[error("Block transfer error: {0}")]
48 BlockTransferError(String),
49
50 /// DTLS session establishment or resumption failure.
51 ///
52 /// RFC 9483 §5 requires DTLS to secure all EST-coaps exchanges.
53 #[error("DTLS error: {0}")]
54 DtlsError(String),
55
56 /// Payload exceeds the configured maximum size.
57 ///
58 /// Even with block-wise transfer, reassembled payloads are bounded to
59 /// prevent resource exhaustion on constrained devices.
60 #[error("Payload too large: {size} bytes exceeds maximum {max} bytes")]
61 PayloadTooLarge {
62 /// Actual payload size in bytes.
63 size: usize,
64 /// Configured maximum payload size in bytes.
65 max: usize,
66 },
67
68 /// No CoAP resource matches the requested URI path.
69 #[error("Resource not found: {0}")]
70 ResourceNotFound(String),
71
72 /// Internal server error (catch-all).
73 #[error("Internal error: {0}")]
74 Internal(String),
75}
76
77/// Result type for CoAP operations.
78pub type CoapResult<T> = Result<T, CoapError>;