SnmpKit.SnmpLib.Security.USM (snmpkit v0.6.4)
User Security Model (USM) implementation for SNMPv3 - RFC 3414 compliant.
The User Security Model provides the foundation for SNMPv3 security by implementing:
- User-based authentication with multiple protocols
- Privacy (encryption) for message confidentiality
- Time synchronization to prevent replay attacks
- Engine discovery for secure agent communication
- Security parameter validation and error handling
RFC 3414 Compliance
This implementation fully complies with RFC 3414 "User-based Security Model (USM) for version 3 of the Simple Network Management Protocol (SNMPv3)" including:
- Message authentication using HMAC-MD5 and HMAC-SHA
- Privacy using DES and AES encryption
- Key derivation using password localization
- Time window validation for message freshness
- Engine ID discovery and management
Architecture
The USM coordinates with other security modules:
SnmpKit.SnmpLib.Security.USM
├── Auth protocols (MD5, SHA variants)
├── Priv protocols (DES, AES variants)
├── Key derivation and management
└── Engine and time management
Usage Examples
Engine Discovery
# Discover remote engine for secure communication
{:ok, engine_id} = SnmpKit.SnmpLib.Security.USM.discover_engine("192.168.1.1")
# Time synchronization
{:ok, {boots, time}} = SnmpKit.SnmpLib.Security.USM.synchronize_time("192.168.1.1", engine_id)
Message Processing
# Process outgoing secure message
{:ok, secure_message} = SnmpKit.SnmpLib.Security.USM.process_outgoing_message(
user, message, security_level
)
# Process incoming secure message
{:ok, {plain_message, user}} = SnmpKit.SnmpLib.Security.USM.process_incoming_message(
secure_message, user_database
)
Security Considerations
- Engine boot counters must be persistent across restarts
- Time synchronization is critical for security
- Failed authentication attempts should be logged
- Key material should never be logged or persisted in plain text
Summary
Functions
Discovers the engine ID of a remote SNMP agent.
Generates security error reports for invalid messages.
Calculates current engine time since boot.
Updates engine boot counter, handling rollover at maximum value.
Processes an incoming SNMP message with USM security.
Processes an outgoing SNMP message with USM security.
Synchronizes time with a remote SNMP agent.
Validates time-based security parameters to prevent replay attacks.
Types
@type engine_boots() :: non_neg_integer()
@type engine_id() :: binary()
@type engine_time() :: non_neg_integer()
@type security_level() :: :no_auth_no_priv | :auth_no_priv | :auth_priv
@type security_name() :: binary()
@type security_parameters() :: %{ authoritative_engine_id: engine_id(), authoritative_engine_boots: engine_boots(), authoritative_engine_time: engine_time(), user_name: security_name(), authentication_parameters: binary(), privacy_parameters: binary() }
Functions
Discovers the engine ID of a remote SNMP agent.
Engine discovery is the first step in establishing secure communication with a remote SNMPv3 agent. This function sends a discovery request and retrieves the agent's authoritative engine ID.
Parameters
host
: Target agent IP address or hostnameopts
: Discovery options including port, timeout, and community
Returns
{:ok, engine_id}
: Successfully discovered engine ID{:error, reason}
: Discovery failed
Examples
{:ok, engine_id} = SnmpKit.SnmpLib.Security.USM.discover_engine("192.168.1.1")
{:ok, engine_id} = SnmpKit.SnmpLib.Security.USM.discover_engine("10.0.0.1", port: 1161, timeout: 5000)
Generates security error reports for invalid messages.
USM error reports are sent back to the originator to indicate security violations or configuration issues.
@spec get_engine_time(non_neg_integer()) :: engine_time()
Calculates current engine time since boot.
@spec increment_engine_boots(engine_boots()) :: engine_boots()
Updates engine boot counter, handling rollover at maximum value.
@spec process_incoming_message(binary(), map()) :: {:ok, {binary(), user_entry()}} | {:error, atom()}
Processes an incoming SNMP message with USM security.
This function validates and decrypts an incoming secure message, returning the plain message content and validated user information.
@spec process_outgoing_message(user_entry(), binary(), security_level()) :: {:ok, binary()} | {:error, atom()}
Processes an outgoing SNMP message with USM security.
This function applies authentication and/or privacy protection to an outgoing message based on the user's security level configuration.
@spec synchronize_time(binary(), engine_id(), keyword()) :: {:ok, {engine_boots(), engine_time()}} | {:error, atom()}
Synchronizes time with a remote SNMP agent.
Time synchronization is required for authenticated communication to prevent replay attacks. This function retrieves the agent's current boot counter and engine time.
@spec validate_time_window( engine_boots(), engine_time(), engine_boots(), engine_time() ) :: :ok | {:error, atom()}
Validates time-based security parameters to prevent replay attacks.
Per RFC 3414, messages are considered fresh if:
- Engine boots match (within 1)
- Engine time is within 150 seconds