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.1")]

//! # 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];