pub trait AuthenticationInfoExt {
// Required method
fn authentication_info(
self,
nextnonce: Option<&str>,
qop: Option<&str>,
rspauth: Option<&str>,
cnonce: Option<&str>,
nc: Option<&str>,
) -> Self;
}
Expand description
Extension trait for adding Authentication-Info header building capabilities
This trait provides methods for adding Authentication-Info headers to SIP responses. Authentication-Info headers are defined in RFC 3261 and are sent by servers in 2xx responses following successful authentication with either WWW-Authenticate/Authorization or Proxy-Authenticate/Proxy-Authorization.
§Purpose of Authentication-Info
The Authentication-Info header serves several purposes in SIP authentication:
-
Session Continuation: Provides the next nonce to use for subsequent requests, allowing continued authentication without challenging every request
-
Mutual Authentication: Proves the server’s knowledge of shared credentials through the rspauth parameter
-
State Synchronization: Acknowledges the client’s authentication parameters and maintains authentication state
§When to Use Authentication-Info
The Authentication-Info header should be included in successful responses (2xx) following authentication:
- After successful client authentication via Authorization
- As part of an ongoing digest authentication session
- When implementing mutual authentication (server proving its identity to client)
- When the server wants to update authentication parameters
§Relationship with Other Authentication Headers
Authentication-Info works together with other SIP authentication headers:
// Authentication flow diagram:
//
// Client Server
// | |
// |------- REQUEST -------->|
// | |
// |<-- 401 + WWW-Auth. ----| (Challenge)
// | |
// |-- REQ + Authorization ->| (Response)
// | |
// |<-- 200 + Auth-Info ----| (Acknowledgment + Next credentials)
// | |
// |-- REQ + Authorization ->| (Using nextnonce)
// | |
§Security Considerations
The Authentication-Info header enhances security in SIP in several ways:
- Protects against replay attacks through nonce rotation
- Enables mutual authentication so clients can verify server identity
- Maintains authentication state for long-running sessions
§Examples
§Complete Authentication Flow Example
use rvoip_sip_core::prelude::*;
use rvoip_sip_core::builder::{SimpleRequestBuilder, SimpleResponseBuilder};
use rvoip_sip_core::builder::headers::{WwwAuthenticateExt, AuthorizationExt, AuthenticationInfoExt};
// Step 1: Server challenges client with WWW-Authenticate
let challenge_response = SimpleResponseBuilder::new(StatusCode::Unauthorized, None)
.www_authenticate_digest(
"example.com", // realm
"dcd98b7102dd2f0e8b11d0f600bfb0c093", // nonce
None, // opaque
Some("SHA-256"), // algorithm
Some(vec!["auth"]), // qop
None, // stale
None // domain
)
.to("Alice", "sip:alice@example.com", Some("a73kszlfl"))
.from("SIP Server", "sip:registrar@example.com", Some("1232412"))
.call_id("f81d4fae-7dec-11d0-a765-00a0c91e6bf6@alice-pc")
.cseq(1, Method::Register)
.build();
// Step 2: Client calculates response and authenticates
// In practice, this would be calculated per RFC 2617/7616
let response_hash = "31e9ee75f699bd4b23a36577542c7dcc";
let client_nonce = "0a4f113b";
let uri = "sip:example.com";
let authenticated_request = SimpleRequestBuilder::register("sip:example.com").unwrap()
.from("Alice", "sip:alice@example.com", Some("a73kszlfl"))
.to("Alice", "sip:alice@example.com", Some("a73kszlfl"))
.call_id("f81d4fae-7dec-11d0-a765-00a0c91e6bf6@alice-pc")
.cseq(2)
// Note: authorization_digest() parameter order:
// username, realm, nonce, response, uri, algorithm, cnonce, opaque, qop, nc, userhash
.authorization_digest(
"alice", // username
"example.com", // realm
"dcd98b7102dd2f0e8b11d0f600bfb0c093", // nonce
response_hash, // response
Some(uri), // uri (needs to be wrapped in Some)
Some("SHA-256"), // algorithm
Some(client_nonce), // cnonce
None, // opaque
Some("auth"), // qop
Some("00000001"), // nc
None // userhash
)
.build();
// Step 3: Server validates auth and responds with Authentication-Info
// Also calculate server authentication response for mutual auth
let server_rspauth = "6629fae49393a05397450978507c4ef1";
let next_nonce = "fcb7bae57a15b83854575c0643bb9254"; // Provide new nonce for future requests
let success_response = SimpleResponseBuilder::new(StatusCode::Ok, None)
.to("Alice", "sip:alice@example.com", Some("a73kszlfl"))
.from("SIP Server", "sip:registrar@example.com", Some("1232412"))
.call_id("f81d4fae-7dec-11d0-a765-00a0c91e6bf6@alice-pc")
.cseq(2, Method::Register)
.authentication_info(
Some(next_nonce), // nextnonce (for future requests)
Some("auth"), // qop (same as in client request)
Some(server_rspauth), // rspauth (for mutual authentication)
Some(client_nonce), // cnonce (echoed from client)
Some("00000001") // nc (echoed from client)
)
.build();
// Step 4: Client validates server's rspauth and stores nextnonce for future requests
Required Methods§
Sourcefn authentication_info(
self,
nextnonce: Option<&str>,
qop: Option<&str>,
rspauth: Option<&str>,
cnonce: Option<&str>,
nc: Option<&str>,
) -> Self
fn authentication_info( self, nextnonce: Option<&str>, qop: Option<&str>, rspauth: Option<&str>, cnonce: Option<&str>, nc: Option<&str>, ) -> Self
Add an Authentication-Info header to the response
The Authentication-Info header is typically included in 2xx responses following successful authentication. It provides authentication session continuation information and can be used for mutual authentication (allowing clients to verify the server’s identity).
§Parameters
nextnonce
- Optional new nonce value that should be used for the next client request, helping prevent replay attacks and allowing for credential rotationqop
- Optional quality of protection that was applied to the message (usually “auth” or “auth-int”), should match the qop from the client’s requestrspauth
- Optional server response digest value used for mutual authentication, calculated similar to the client’s response but using an empty method fieldcnonce
- Optional client nonce reflected back from the client’s Authorization headernc
- Optional nonce count reflected back from the client’s Authorization header
§Returns
Self for method chaining
§Use cases
There are several common use cases for the Authentication-Info header:
- Basic Acknowledgment: Simply confirm successful authentication
- Nonce Rotation: Provide a new nonce for continued authentication
- Mutual Authentication: Prove server identity with rspauth
- Complete Session: Maintain all authentication parameters
§Examples
§Basic Example with New Nonce
use rvoip_sip_core::prelude::*;
use rvoip_sip_core::builder::{SimpleResponseBuilder, headers::AuthenticationInfoExt};
use rvoip_sip_core::types::{Method, StatusCode};
// Send a new nonce for the next request
let response = SimpleResponseBuilder::new(StatusCode::Ok, None)
.from("Alice", "sip:alice@example.com", Some("1928301774"))
.to("Bob", "sip:bob@example.com", Some("a6c85cf"))
.authentication_info(
Some("dcd98b7102dd2f0e8b11d0f600bfb0c099"), // nextnonce
None, // no qop needed for basic usage
None, // no rspauth needed
None, // no cnonce needed
None // no nc needed
)
.build();
§Full Example with Mutual Authentication
use rvoip_sip_core::prelude::*;
use rvoip_sip_core::builder::{SimpleResponseBuilder, headers::AuthenticationInfoExt};
use rvoip_sip_core::types::{Method, StatusCode};
// Complete response with mutual authentication
let response = SimpleResponseBuilder::new(StatusCode::Ok, None)
.from("Alice", "sip:alice@example.com", Some("1928301774"))
.to("Bob", "sip:bob@example.com", Some("a6c85cf"))
.authentication_info(
Some("dcd98b7102dd2f0e8b11d0f600bfb0c099"), // nextnonce
Some("auth"), // qop
Some("6629fae49393a05397450978507c4ef1"), // rspauth for mutual auth
Some("8dd675a9"), // cnonce (echoed from client)
Some("00000001") // nc (echoed from client)
)
.build();
§Authentication-Info in a Proxy Response
use rvoip_sip_core::prelude::*;
use rvoip_sip_core::builder::{SimpleResponseBuilder, headers::AuthenticationInfoExt};
use rvoip_sip_core::types::{Method, StatusCode};
// A proxy server responding after successful Proxy-Authorization
let proxy_response = SimpleResponseBuilder::new(StatusCode::Ok, None)
.to("Bob", "sip:bob@example.com", Some("a6c85cf"))
.from("Alice", "sip:alice@example.com", Some("1928301774"))
// Via headers would normally be here
.authentication_info(
Some("9de5b7ac8dc25c96b512dc458d393b35"), // nextnonce
Some("auth"), // qop
None, // no rspauth (not using mutual auth)
Some("a71d2bef"), // cnonce (from client)
Some("00000001") // nc (from client)
)
.build();
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.