zerodds_security/lib.rs
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 ZeroDDS Contributors
3
4//! Crate `zerodds-security`. Safety classification: **SAFE** (the
5//! security plugins run against production trust boundaries; the SPI
6//! layer itself is trust-neutral).
7//!
8//! DDS-Security 1.1 (formal/2018-04-01) plugin SPI: defines the
9//! abstract plugin traits + data types + generic-message topics;
10//! production implementations live in sister crates.
11//!
12//! ## Layer position
13//!
14//! Layer 4 — Core Services (SPI crate). Pure Rust + `alloc`, **no**
15//! ZeroDDS crate deps.
16//!
17//! ## Public API (as of 1.0.0-rc.1)
18//!
19//! | Spec | Trait / module | Concrete impl |
20//! |-----------------------|-----------------------------------------------------|---------------|
21//! | §8.3 Authentication | [`AuthenticationPlugin`] in [`authentication`] | `zerodds-security-pki` (X.509 + RSA-PSS + ECDSA + OCSP/CRL) |
22//! | §8.4 Access Control | [`AccessControlPlugin`] in [`access_control`] | `zerodds-security-permissions` (Governance + Permissions XML) |
23//! | §8.5 Cryptographic | [`CryptographicPlugin`] in [`crypto`] | `zerodds-security-crypto` (AES-GCM 128/256 + HMAC-SHA256 + receiver-specific MACs) |
24//! | §8.6 Logging | [`LoggingPlugin`] in [`logging`] | `zerodds-security-logging` |
25//! | §8.7 Data Tagging | [`DataTaggingPlugin`] in [`data_tagging`] | `zerodds-security-runtime` (built-in DataTagging) |
26//!
27//! Plus cross-cutting:
28//! - [`token`] — `IdentityToken`, `PermissionsToken`, `CryptoToken`, `DataHolder`, `BinaryProperty`.
29//! - [`generic_message`] — `ParticipantGenericMessage`, `MessageIdentity` + topic constants for DCPSParticipantStatelessMessage / DCPSParticipantVolatileMessageSecure.
30//! - [`properties`] — `Property` / `PropertyList` for plugin configuration.
31//! - [`security_topic_qos`] — built-in security-topic QoS profiles.
32//! - [`error`] — `SecurityError`.
33//! - [`mock`] (feature `std`) — test mock plugins, never in production.
34//!
35//! ## Architecture
36//!
37//! The SPI is trait-based + `Box<dyn Plugin>`-erasable, so that
38//! different backends (rustls vs. ring vs. mbedtls) are interchangeable
39//! without crate wiring. Each plugin trait is self-contained
40//! — no cross-references — so that extensions in one plugin do not
41//! break others.
42//!
43//! ## API stability pledge
44//!
45//! This interface is **API-frozen** as of `1.0.0-rc.1`. Breaking
46//! changes require a v2.0 major bump. Semver patch + minor may
47//! only add new methods with a default body or non-breaking enum
48//! variants.
49
50#![cfg_attr(not(feature = "std"), no_std)]
51#![forbid(unsafe_code)]
52#![warn(missing_docs)]
53
54// zerodds-lint: allow no_dyn_in_safe
55// The plugin SPI needs `Box<dyn Plugin>` for interchangeable backends
56// (rustls/ring/mbedtls). This is architectural and not a memory-safety
57// weakness.
58
59#[cfg(feature = "alloc")]
60extern crate alloc;
61
62pub mod access_control;
63pub mod authentication;
64pub mod crypto;
65pub mod data_tagging;
66pub mod error;
67pub mod generic_message;
68pub mod logging;
69pub mod properties;
70pub mod security_topic_qos;
71pub mod token;
72
73#[cfg(feature = "std")]
74pub mod mock;
75
76pub use access_control::AccessControlPlugin;
77pub use authentication::AuthenticationPlugin;
78pub use crypto::CryptographicPlugin;
79pub use data_tagging::DataTaggingPlugin;
80pub use error::SecurityError;
81pub use generic_message::{
82 MessageIdentity, ParticipantGenericMessage, TOPIC_STATELESS_MESSAGE,
83 TOPIC_VOLATILE_MESSAGE_SECURE, TYPE_NAME_GENERIC_MESSAGE,
84};
85pub use logging::{LogLevel, LoggingPlugin};
86pub use properties::{Property, PropertyList};
87pub use token::{
88 BinaryProperty, CryptoToken, DataHolder, IdentityStatusToken, IdentityToken, PermissionsToken,
89 WireProperty,
90};
91
92#[cfg(test)]
93#[allow(clippy::expect_used)]
94mod tests {
95 #[test]
96 fn plugin_trait_objects_are_object_safe() {
97 // Smoke test: every plugin trait is object-safe (`dyn Plugin`
98 // constructible). Fails at compile time if someone accidentally
99 // adds `Self: Sized` or generic methods.
100 fn _assert_object_safe<T: ?Sized>() {}
101 _assert_object_safe::<dyn super::AuthenticationPlugin>();
102 _assert_object_safe::<dyn super::AccessControlPlugin>();
103 _assert_object_safe::<dyn super::CryptographicPlugin>();
104 _assert_object_safe::<dyn super::LoggingPlugin>();
105 _assert_object_safe::<dyn super::DataTaggingPlugin>();
106 }
107}