SnmpKit.SnmpLib.Security (snmpkit v0.6.4)

SNMPv3 Security Framework - Phase 5.1A Implementation

Provides comprehensive SNMPv3 User Security Model (USM) implementation including authentication and privacy protocols for secure SNMP communications.

Features

  • User Security Model (USM) with complete RFC 3414 compliance
  • Authentication Protocols: MD5, SHA-1, SHA-256, SHA-384, SHA-512
  • Privacy Protocols: DES, AES-128, AES-192, AES-256
  • Key Derivation: Password-based and localized key generation
  • Security Parameters: Boot counter, time synchronization, message validation
  • Error Handling: Comprehensive security error classification and recovery

Architecture

The security framework is built on a modular architecture:

Usage Examples

Basic SNMPv3 Authentication

# Create authenticated user
{:ok, user} = SnmpKit.SnmpLib.Security.create_user("admin",
  auth_protocol: :sha256,
  auth_password: "secure_password",
  engine_id: "engine123"
)

# Authenticate message
{:ok, auth_params} = SnmpKit.SnmpLib.Security.authenticate_message(user, message)

Privacy (Encryption) Support

# Create user with privacy
{:ok, user} = SnmpKit.SnmpLib.Security.create_user("secure_admin",
  auth_protocol: :sha256,
  auth_password: "auth_password",
  priv_protocol: :aes256,
  priv_password: "priv_password"
)

# Encrypt message
{:ok, encrypted} = SnmpKit.SnmpLib.Security.encrypt_message(user, message)

Engine ID Management

# Generate engine ID
engine_id = SnmpKit.SnmpLib.Security.generate_engine_id("192.168.1.1")

# Discover remote engine
{:ok, remote_engine} = SnmpKit.SnmpLib.Security.discover_engine("10.0.0.1")

Security Considerations

  • All key material is stored securely in memory
  • Authentication and privacy keys are derived using RFC-compliant algorithms
  • Time-based authentication prevents replay attacks
  • Boot counter management ensures message freshness
  • Comprehensive input validation prevents security bypasses

Summary

Functions

Authenticates an SNMP message using the user's authentication protocol.

Builds security parameters for inclusion in SNMPv3 messages.

Creates a new SNMPv3 security user with specified authentication and privacy settings.

Decrypts message data using the user's privacy protocol.

Discovers the engine ID of a remote SNMP agent.

Encrypts message data using the user's privacy protocol.

Generates a unique engine ID for an SNMP entity.

Determines the security level for a message based on user configuration.

Returns comprehensive information about security capabilities and status.

Updates engine time and boot counter for time synchronization.

Updates security user credentials and regenerates keys.

Validates security parameters from received messages.

Validates user credentials against stored authentication data.

Verifies message authentication using provided authentication parameters.

Types

auth_protocol()

@type auth_protocol() :: :none | :md5 | :sha1 | :sha256 | :sha384 | :sha512

engine_id()

@type engine_id() :: binary()

priv_protocol()

@type priv_protocol() :: :none | :des | :aes128 | :aes192 | :aes256

security_level()

@type security_level() :: :no_auth_no_priv | :auth_no_priv | :auth_priv

security_name()

@type security_name() :: binary()

security_params()

@type security_params() :: %{
  authoritative_engine_id: engine_id(),
  authoritative_engine_boots: non_neg_integer(),
  authoritative_engine_time: non_neg_integer(),
  user_name: security_name(),
  authentication_parameters: binary(),
  privacy_parameters: binary()
}

security_user()

@type security_user() :: %{
  security_name: security_name(),
  auth_protocol: auth_protocol(),
  priv_protocol: priv_protocol(),
  auth_key: binary(),
  priv_key: binary(),
  engine_id: engine_id(),
  engine_boots: non_neg_integer(),
  engine_time: non_neg_integer()
}

user_config()

@type user_config() :: [
  auth_protocol: auth_protocol(),
  auth_password: binary(),
  priv_protocol: priv_protocol(),
  priv_password: binary(),
  engine_id: engine_id()
]

Functions

authenticate_message(user, message)

@spec authenticate_message(security_user(), binary()) ::
  {:ok, binary()} | {:error, atom()}

Authenticates an SNMP message using the user's authentication protocol.

Returns authentication parameters that should be included in the message.

build_security_params(user, auth_params \\ <<>>, priv_params \\ <<>>)

@spec build_security_params(security_user(), binary(), binary()) :: security_params()

Builds security parameters for inclusion in SNMPv3 messages.

create_user(security_name, config)

@spec create_user(security_name(), user_config()) ::
  {:ok, security_user()} | {:error, atom()}

Creates a new SNMPv3 security user with specified authentication and privacy settings.

Parameters

  • security_name: Unique identifier for the user
  • config: User configuration including protocols and passwords

Returns

  • {:ok, user}: Successfully created security user
  • {:error, reason}: Creation failed

Examples

# Authentication only user
{:ok, user} = SnmpKit.SnmpLib.Security.create_user("monitor_user",
  auth_protocol: :sha256,
  auth_password: "monitoring_secret",
  engine_id: "local_engine"
)

# Full authentication and privacy user
{:ok, admin} = SnmpKit.SnmpLib.Security.create_user("admin_user",
  auth_protocol: :sha512,
  auth_password: "admin_auth_pass",
  priv_protocol: :aes256,
  priv_password: "admin_priv_pass",
  engine_id: "management_engine"
)

decrypt_message(user, ciphertext, priv_params)

@spec decrypt_message(security_user(), binary(), binary()) ::
  {:ok, binary()} | {:error, atom()}

Decrypts message data using the user's privacy protocol.

discover_engine(host, opts \\ [])

@spec discover_engine(
  binary(),
  keyword()
) :: {:ok, engine_id()} | {:error, atom()}

Discovers the engine ID of a remote SNMP agent.

This is typically done during the first communication with a remote agent to establish security context.

encrypt_message(user, plaintext)

@spec encrypt_message(security_user(), binary()) ::
  {:ok, {binary(), binary()}} | {:error, atom()}

Encrypts message data using the user's privacy protocol.

generate_engine_id(identifier)

@spec generate_engine_id(binary()) :: engine_id()

Generates a unique engine ID for an SNMP entity.

Engine IDs are used to uniquely identify SNMP engines and are required for SNMPv3 security operations.

get_security_level(user)

@spec get_security_level(security_user()) :: security_level()

Determines the security level for a message based on user configuration.

Security Levels

  • :no_auth_no_priv - No authentication, no privacy
  • :auth_no_priv - Authentication only
  • :auth_priv - Authentication and privacy

info()

@spec info() :: map()

Returns comprehensive information about security capabilities and status.

update_engine_time(user, engine_boots, engine_time)

@spec update_engine_time(security_user(), non_neg_integer(), non_neg_integer()) ::
  security_user()

Updates engine time and boot counter for time synchronization.

update_user(user, new_config)

@spec update_user(security_user(), user_config()) ::
  {:ok, security_user()} | {:error, atom()}

Updates security user credentials and regenerates keys.

validate_security_params(user, params)

@spec validate_security_params(security_user(), security_params()) ::
  :ok | {:error, atom()}

Validates security parameters from received messages.

validate_user(user, auth_password, priv_password \\ "")

@spec validate_user(security_user(), binary(), binary()) :: :ok | {:error, atom()}

Validates user credentials against stored authentication data.

verify_authentication(user, message, auth_params)

@spec verify_authentication(security_user(), binary(), binary()) ::
  :ok | {:error, atom()}

Verifies message authentication using provided authentication parameters.