1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#![doc(html_root_url = "https://docs.rs/snmp_usm/0.2.0")]

//! # Implementation of the User-based Security Model (USM) for SNMPv3
//!
//! SNMP USM provides SNMP message level security according to RFC 3414 and RFC 3826. It implements
//! primitives that can be used by a security subsystem.
//!
//! Implemented features of USM:
//!
//! * HMAC-MD5-96 Authentication Protocol
//! * HMAC-SHA-96 Authentication Protocol
//! * Timeliness verification
//! * DES encryption
//! * AES encryption
//!
//! ## Authentication and Privacy
//!
//! When privacy is used with authentication, the privacy key must use the same message-digest
//! algorithm as the authentication key. As an example, if the [AuthKey](struct.AuthKey.html) is
//! constructed with a [LocalizedKey](struct.LocalizedKey.html) specialized with the MD5
//! message-digest algorithm, then the [PrivKey](struct.PrivKey.html) must be constructed with a
//! `LocalizedKey` specialized with the MD5 message-digest algorithm.
//!
//! ## Authentication and time synchronization
//!
//! If authenticated communication is required, then the discovery process should also establish
//! time synchronization with the authoritative SNMP engine. This may be accomplished by sending an
//! authenticated Request message with the value of msgAuthoritativeEngineID set to the previously
//! learned snmpEngineID and with the values of msgAuthoritativeEngineBoots and
//! msgAuthoritativeEngineTime set to zero.
//!
//! ## Examples
//!
//! A fictional message processing subsystem is used to clarify the examples.
//!
//! ```no_run
//! use snmp_usm::{
//!     Aes128PrivKey, AuthKey, LocalizedMd5Key, PrivKey, SecurityParams, WithLocalizedKey
//! };
//!
//! # fn main() -> snmp_usm::SecurityResult<()> {
//! # let passwd = [];
//! # let engine_id = [];
//! # let scoped_pdu = vec![];
//! # let incoming_security_params = [];
//! // The password and engine ID are supplied by the security subsystem.
//! let localized_key = LocalizedMd5Key::new(&passwd, &engine_id);
//!
//! let priv_key = Aes128PrivKey::with_localized_key(localized_key.clone());
//! # let mut security_params = SecurityParams::decode(&incoming_security_params)?;
//! // The security parameters are constructed from the local authoritative engine data.
//! let (encrypted_scoped_pdu, salt) = priv_key.encrypt(scoped_pdu, &security_params, 0);
//!
//! // The message processing service would set the encrypted scoped PDU for the outgoing message.
//! // out_msg.set_encrypted_scoped_pdu(encrypted_scoped_pdu);
//!
//! security_params
//!     .set_username(b"username")
//!     .set_priv_params(&salt)
//!     .set_auth_params_placeholder();
//! let encoded_security_params = security_params.encode();
//!
//! // The message processing service would set the security parameters of the outgoing message and
//! // encode it.
//! // out_msg.set_security_params(&encoded_security_params);
//! // let out_msg = out_msg.encode();
//!
//! let auth_key = AuthKey::new(localized_key);
//!
//! // Authenticate the outgoing message.
//! # let mut out_msg = [];
//! auth_key.auth_out_msg(&mut out_msg)?;
//!
//! // Authenticate an incoming message.
//! # let mut in_msg = [];
//! # let local_engine_id = b"";
//! # let local_engine_boots = 0;
//! # let local_engine_time = 0;
//! auth_key.auth_in_msg(&mut in_msg, local_engine_id, local_engine_boots, local_engine_time)?;
//! # Ok(())
//! # }
//! ```

mod auth_key;
mod error;
mod localized_key;
mod pos_finder;
mod priv_key;
mod security_params;

pub use auth_key::{AuthKey, Digest};
pub use error::SecurityError;
pub use localized_key::{LocalizedKey, WithLocalizedKey};
pub use md5::Md5;
pub use priv_key::{Aes128PrivKey, DesPrivKey, PrivKey};
pub use security_params::SecurityParams;
pub use sha1::Sha1;

/// Type alias for a localized key specialized with the MD5 message-digest algorithm.
pub type LocalizedMd5Key<'a> = LocalizedKey<'a, Md5>;
/// Type alias for a localized key specialized with the SHA-1 message-digest algorithm.
pub type LocalizedSha1Key<'a> = LocalizedKey<'a, Sha1>;

/// Type alias for an authentication key specialized with the MD5 message-digest algorithm.
pub type Md5AuthKey<'a> = AuthKey<'a, Md5>;
/// Type alias for an authentication key specialized with SHA-1 message-digest algorithm.
pub type Sha1AuthKey<'a> = AuthKey<'a, Sha1>;

/// Type alias for the result of a security operation.
pub type SecurityResult<T> = Result<T, SecurityError>;

const AUTH_PARAMS_LEN: usize = 12;
const AUTH_PARAMS_PLACEHOLDER: [u8; AUTH_PARAMS_LEN] = [0x0; AUTH_PARAMS_LEN];