Class: NETSNMP::SecurityParameters
- Inherits:
-
Object
- Object
- NETSNMP::SecurityParameters
- Includes:
- Loggable
- Defined in:
- lib/netsnmp/security_parameters.rb
Overview
This module encapsulates the public API for encrypting/decrypting and signing/verifying.
It doesn’t interact with other layers from the library, rather it is used and passed all the arguments (consisting mostly of primitive types). It also provides validation of the security options passed with a client is initialized in v3 mode.
Constant Summary collapse
- IPAD =
"\x36" * 64
- OPAD =
"\x5c" * 64
- TIMELINESS_THRESHOLD =
Timeliness is part of SNMP V3 Security The topic is described very nice here www.snmpsharpnet.com/?page_id=28 www.ietf.org/rfc/rfc2574.txt 1.4.1 Timeliness The probe is outdated after 150 seconds which results in a PDU Error, therefore it should expire before that and be renewed The 150 Seconds is specified in www.ietf.org/rfc/rfc2574.txt 2.2.3
150
Constants included from Loggable
Loggable::DEBUG, Loggable::DEBUG_LEVEL
Instance Attribute Summary collapse
-
#auth_protocol ⇒ Object
readonly
Returns the value of attribute auth_protocol.
-
#engine_id ⇒ Object
Returns the value of attribute engine_id.
-
#security_level ⇒ Object
readonly
Returns the value of attribute security_level.
-
#username ⇒ Object
readonly
Returns the value of attribute username.
Instance Method Summary collapse
- #decode(der, salt:, engine_time:, engine_boots:, security_level: @security_level) ⇒ Object
-
#encode(pdu, salt:, engine_time:, engine_boots:) ⇒ Array
A pair, where the first argument in the asn structure with the encoded pdu, and the second is the calculated salt (if it has been encrypted).
-
#initialize(username:, engine_id: "", security_level: nil, auth_protocol: nil, auth_password: nil, priv_protocol: nil, priv_password: nil) ⇒ SecurityParameters
constructor
A new instance of SecurityParameters.
- #must_revalidate? ⇒ Boolean
-
#sign(message) ⇒ String
The digest signature of the message payload.
- #verify(stream, salt, security_level: @security_level) ⇒ Object
Constructor Details
#initialize(username:, engine_id: "", security_level: nil, auth_protocol: nil, auth_password: nil, priv_protocol: nil, priv_password: nil) ⇒ SecurityParameters
if security level is set to :no_auth_no_priv, all other parameters are optional; if :auth_no_priv, :auth_protocol will be coerced to :md5 (if not explicitly set), and :auth_password is mandatory; if :auth_priv, the sentence before applies, and :priv_protocol will be coerced to :des (if not explicitly set), and :priv_password becomes mandatory.
Returns a new instance of SecurityParameters.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/netsnmp/security_parameters.rb', line 41 def initialize( username:, engine_id: "", security_level: nil, auth_protocol: nil, auth_password: nil, priv_protocol: nil, priv_password: nil ) @security_level = security_level @username = username @engine_id = engine_id @auth_protocol = auth_protocol.to_sym unless auth_protocol.nil? @priv_protocol = priv_protocol.to_sym unless priv_protocol.nil? @auth_password = auth_password @priv_password = priv_password check_parameters @auth_pass_key = passkey(@auth_password) unless @auth_password.nil? @priv_pass_key = passkey(@priv_password) unless @priv_password.nil? end |
Instance Attribute Details
#auth_protocol ⇒ Object (readonly)
Returns the value of attribute auth_protocol.
25 26 27 |
# File 'lib/netsnmp/security_parameters.rb', line 25 def auth_protocol @auth_protocol end |
#engine_id ⇒ Object
Returns the value of attribute engine_id.
26 27 28 |
# File 'lib/netsnmp/security_parameters.rb', line 26 def engine_id @engine_id end |
#security_level ⇒ Object (readonly)
Returns the value of attribute security_level.
25 26 27 |
# File 'lib/netsnmp/security_parameters.rb', line 25 def security_level @security_level end |
#username ⇒ Object (readonly)
Returns the value of attribute username.
25 26 27 |
# File 'lib/netsnmp/security_parameters.rb', line 25 def username @username end |
Instance Method Details
#decode(der, salt:, engine_time:, engine_boots:, security_level: @security_level) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/netsnmp/security_parameters.rb', line 91 def decode(der, salt:, engine_time:, engine_boots:, security_level: @security_level) asn = OpenSSL::ASN1.decode(der) return asn if security_level < 3 return asn unless encryption encrypted_pdu = asn.value pdu_der = encryption.decrypt(encrypted_pdu, salt: salt, engine_time: engine_time, engine_boots: engine_boots) log(level: 2) { "message has been decrypted" } OpenSSL::ASN1.decode(pdu_der) end |
#encode(pdu, salt:, engine_time:, engine_boots:) ⇒ Array
Returns a pair, where the first argument in the asn structure with the encoded pdu, and the second is the calculated salt (if it has been encrypted).
74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/netsnmp/security_parameters.rb', line 74 def encode(pdu, salt:, engine_time:, engine_boots:) if encryption encrypted_pdu, salt = encryption.encrypt(pdu.to_der, engine_boots: engine_boots, engine_time: engine_time) [ OpenSSL::ASN1::OctetString.new(encrypted_pdu).with_label(:encrypted_pdu), OpenSSL::ASN1::OctetString.new(salt).with_label(:salt) ] else [pdu.to_asn, salt] end end |
#must_revalidate? ⇒ Boolean
144 145 146 147 148 |
# File 'lib/netsnmp/security_parameters.rb', line 144 def must_revalidate? return @engine_id.empty? unless return true if @engine_id.empty? || @timeliness.nil? (Process.clock_gettime(Process::CLOCK_MONOTONIC, :second) - @timeliness) >= TIMELINESS_THRESHOLD end |
#sign(message) ⇒ String
this method is used in the process of authenticating a message
Returns the digest signature of the message payload.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/netsnmp/security_parameters.rb', line 107 def sign() # don't sign unless you have to return unless @auth_protocol key = auth_key.dup # SHA256 => https://datatracker.ietf.org/doc/html/rfc7860#section-4.2.2 # The 24 first octets of HMAC are taken as the computed MAC value return OpenSSL::HMAC.digest("SHA256", key, )[0, 24] if @auth_protocol == :sha256 # MD5 => https://datatracker.ietf.org/doc/html/rfc3414#section-6.3.2 # SHA1 => https://datatracker.ietf.org/doc/html/rfc3414#section-7.3.2 key << "\x00" * (@auth_protocol == :md5 ? 48 : 44) k1 = key.xor(IPAD) k2 = key.xor(OPAD) digest.reset digest << (k1 + ) d1 = digest.digest digest.reset digest << (k2 + d1) # The 12 first octets of the digest are taken as the computed MAC value digest.digest[0, 12] end |
#verify(stream, salt, security_level: @security_level) ⇒ Object
137 138 139 140 141 142 |
# File 'lib/netsnmp/security_parameters.rb', line 137 def verify(stream, salt, security_level: @security_level) return if security_level < 1 verisalt = sign(stream) raise Error, "invalid message authentication salt" unless verisalt == salt log(level: 2) { "message has been verified" } end |