SnmpKit.SnmpLib.PDU.V3Encoder (snmpkit v2.0.1)
SNMPv3 message encoding and decoding with User Security Model (USM) support.
This module implements the SNMPv3 message format as specified in RFC 3412 and RFC 3414, providing authentication and privacy protection for SNMP communications.
SNMPv3 Message Structure
SNMPv3 messages have a complex hierarchical structure:
SNMPv3Message ::= SEQUENCE {
msgVersion INTEGER (0..2147483647),
msgGlobalData HeaderData,
msgSecurityParameters OCTET STRING,
msgData ScopedPduData
}
HeaderData ::= SEQUENCE {
msgID INTEGER (0..2147483647),
msgMaxSize INTEGER (484..2147483647),
msgFlags OCTET STRING (SIZE(1)),
msgSecurityModel INTEGER (1..2147483647)
}
ScopedPduData ::= CHOICE {
plaintext ScopedPDU,
encryptedPDU OCTET STRING
}
ScopedPDU ::= SEQUENCE {
contextEngineID OCTET STRING,
contextName OCTET STRING,
data ANY
}Security Processing
The module integrates with the security subsystem to provide:
- Message authentication using HMAC algorithms
- Message encryption using AES/DES algorithms
- Time synchronization and engine discovery
- Replay attack protection
Usage Examples
Encoding a SNMPv3 Message
# Create security user
user = %{
security_name: "testuser",
auth_protocol: :sha256,
priv_protocol: :aes128,
auth_key: derived_auth_key,
priv_key: derived_priv_key,
engine_id: "local_engine"
}
# Create SNMPv3 message
message = %{
version: 3,
msg_id: 12345,
msg_max_size: 65507,
msg_flags: %{auth: true, priv: true, reportable: true},
msg_security_model: 3,
msg_security_parameters: "", # Will be generated
msg_data: %{
context_engine_id: "target_engine",
context_name: "",
pdu: pdu
}
}
# Encode with security
{:ok, encoded} = SnmpKit.SnmpLib.PDU.V3Encoder.encode_message(message, user)Decoding a SNMPv3 Message
{:ok, decoded} = SnmpKit.SnmpLib.PDU.V3Encoder.decode_message(binary_data, user)Security Notes
- Authentication is required for privacy (encryption)
- Engine discovery must be performed before authenticated communication
- Time synchronization is required to prevent replay attacks
- Message IDs should be unique to prevent duplicate processing
Wire-format details
msgAuthenticationParametersis the HMAC computed over the entire serialized message with the parameter field itself zeroed (RFC 3414 6.3.1 / 7.3.1). On decode the MAC is recomputed over the bytes actually received, never over a re-encoding, so any peer's BER choices are accepted.- Encrypted messages carry the ciphertext in an OCTET STRING
msgData; the MAC covers that OCTET STRING, exactly as transmitted. - AES/DES IVs are derived from
msgAuthoritativeEngineBoots/Timeand the 8-octet salt inmsgPrivacyParameters(RFC 3414 8.1.1.1, RFC 3826 3.1.2.1). - Decoded messages expose the received USM parameters under
:security_parameters(seeSnmpKit.SnmpLib.Security.security_params/0) and the raw octets under:msg_security_parameters.
Summary
Functions
Creates a discovery message for engine ID discovery.
Decodes a SNMPv3 message with security processing.
Decodes only the header and security parameters of a SNMPv3 message.
Decodes a raw msgSecurityParameters OCTET STRING as USM parameters.
Encodes a SNMPv3 message with security processing.
Types
@type scoped_pdu() :: SnmpKit.SnmpLib.PDU.Constants.scoped_pdu()
@type security_params() :: SnmpKit.SnmpLib.Security.security_params()
@type security_user() :: SnmpKit.SnmpLib.Security.security_user()
@type v3_message() :: SnmpKit.SnmpLib.PDU.Constants.v3_message()
Functions
@spec create_discovery_message(non_neg_integer()) :: v3_message()
Creates a discovery message for engine ID discovery.
@spec decode_message(binary(), security_user() | nil) :: {:ok, v3_message()} | {:error, atom()}
Decodes a SNMPv3 message with security processing.
Parameters
data- Binary SNMPv3 message datauser- Security user configuration (optional for discovery messages)
Returns
{:ok, message}on success. Besides the header fields and:msg_data(the decoded ScopedPDU) the map carries:msg_security_parameters(raw octets) and:security_parameters(decoded USM parameters, ornilwhen they are not USM-shaped).{:error, reason}on failure. An encrypted message decoded without a user yields{:error, :user_required_for_privacy}; usedecode_message_header/1to read the security parameters first and look the user up.
Decodes only the header and security parameters of a SNMPv3 message.
No authentication or decryption is performed. This is what an authoritative
engine uses to find msgUserName before it can select the user whose keys
verify the message.
Returns the same map as decode_message/2 minus :msg_data.
@spec decode_security_parameters(binary()) :: {:ok, security_params()} | {:error, atom()}
Decodes a raw msgSecurityParameters OCTET STRING as USM parameters.
Returns a map in the SnmpKit.SnmpLib.Security.security_params/0 shape.
@spec encode_message(v3_message(), security_user() | nil) :: {:ok, binary()} | {:error, atom()}
Encodes a SNMPv3 message with security processing.
Parameters
message- SNMPv3 message structureuser- Security user configuration (optional for discovery messages)
Returns
{:ok, binary()}on success{:error, reason}on failure
Examples
{:ok, encoded} = encode_message(snmpv3_message, security_user)
{:ok, discovery_msg} = encode_message(discovery_message, nil)