//! Types and traits related to (D)TLS with raw public keys and/or public key infrastructure support
//! In order to configure PKI and/or RPK support, the following general steps need to be followed:
//! 1. Create a key definition for the desired DTLS variant, see [`PkiKeyDef`](pki_rpk::PkiKeyDef)
//! 2. Create a [`PkiRpkContextBuilder`](pki_rpk::PkiRpkContextBuilder) using the provided key and
//! 4. Provide the created context to [`CoapClientSession::connect_dtls`](crate::session::CoapClientSession::connect_dtls)
//! (for client-side sessions) or [`CoapContext::set_pki_rpk_context`](crate::CoapContext::set_pki_rpk_context)
//! 5. On servers, run [`CoapContext::add_endpoint_dtls`](crate::CoapContext::add_endpoint_dtls) to
//! Note that [`PkiRpkContextBuilder`](pki_rpk::PkiRpkContextBuilder) uses generics with the marker
//! structs [`Pki`](pki_rpk::Pki) and [`Rpk`](pki_rpk::Rpk) to statically indicate the DTLS variant
//! and [`NonCertVerifying`](pki_rpk::NonCertVerifying) and [`CertVerifying`](pki_rpk::CertVerifying)
let client_private_key = Vec::from(include_str!("../../../resources/test-keys/client/client.key.pem"));
let client_public_key = Vec::from(include_str!("../../../resources/test-keys/client/client.pub.pem"));
let session = CoapClientSession::connect_dtls(&mut coap_ctx, "example.com:5684".parse().unwrap(), crypto_ctx);
let server_private_key = Vec::from(include_str!("../../../resources/test-keys/server/server.key.pem"));
let server_public_key = Vec::from(include_str!("../../../resources/test-keys/server/server.pub.pem"));
coap_ctx.add_endpoint_dtls("[::1]:5684".parse().unwrap()).expect("unable to create DTLS endpoint");
// It is exclusively used to determine a list of CA names that a server will provide to a client
// It is exclusively used to determine a list of CA names that a server will provide to a client
let server_key_def = PkiKeyDef::with_pem_files(Some(ca_cert), server_public_cert, server_private_key);
// and return either `Some(Box::new(key))` for the appropriate map entry or `None` if the server
coap_ctx.add_endpoint_dtls("[::1]:5684".parse().unwrap()).expect("unable to create DTLS endpoint");
coap_context_set_pki, coap_context_t, coap_dtls_key_t, coap_dtls_pki_t, coap_new_client_session_pki, coap_proto_t,
/// A [`PkiRpkContext`] that is [`NonCertVerifying`] will set the `verify_peer_cert` field of the
/// Trait for markers that indicate whether a PKI/RPK DTLS context performs certificate validation.
/// For server-side sessions, this setting is ignored, and connection identifiers will always be
self.ctx.raw_cfg.client_sni = self.ctx.client_sni.as_mut().unwrap().as_mut_ptr() as *mut c_char;
/// Equivalent to setting `allow_expired_certs` in the underlying [`coap_dtls_pki_t`] structure.
/// Equivalent to setting `check_cert_revocation` in the underlying [`coap_dtls_pki_t`] structure.
/// Allows or disallows disabling certificate revocation checking if a certificate does not have
/// Equivalent to setting `allow_short_rsa_length` in the underlying [`coap_dtls_pki_t`] structure.
/// Keys returned by the key provider will be stored in the context for at least as long as they
pub fn sni_key_provider(mut self, sni_key_provider: impl PkiRpkSniKeyProvider<KTY> + 'a) -> Self {
/// Is referenced in raw_cfg and must therefore not be mutated for the lifetime of this context.
/// Whether PKI or RPK is configured for this context is indicated by the `KTY` generic, which may
/// Configures the provided raw [`coap_context_t`] to use this encryption context for RPK or PKI
unsafe fn apply_to_context(&self, mut ctx: NonNull<coap_context_t>) -> Result<(), ContextConfigurationError> {
/// Depending on whether the encryption context is configured for RPK or PKI operation, the callback
impl<KTY: KeyType, T: Fn(&CStr) -> Option<Box<dyn KeyDef<KeyType = KTY>>>> PkiRpkSniKeyProvider<KTY> for T {
/// This function expects the arguments to be provided in a way that libcoap would when invoking
/// Additionally, `session` must be a valid argument to [`CoapSession::from_raw`], and `arg` must be
/// a valid argument to [`PkiRpkContext::from_raw`] (where the key type of `PkiRpkContext` matches
/// This function expects the arguments to be provided in a way that libcoap would when invoking
/// Additionally, `arg` must be a valid argument to [`PkiRpkContext::from_raw`] (where the key type
unsafe extern "C" fn dtls_pki_sni_callback<KTY: KeyType>(sni: *const c_char, arg: *mut c_void) -> *mut coap_dtls_key_t {