Tuesday, August 10, 2021

p5-Net-SNMP sha2 support

Despite claiming I can't do perl earlier, I decided to give sha2 support
for p5-Net-SNMP another shot and found that I can do enough
perl^Wcopy/paste/tweak to make manubulon-snmp work.

I've already send the patch to David Town, so depending on him still
checking his cpan address it may or may not get upstreamed.

Do we want to have this patch locally pending upstream doing a new
release? If so, someone with actual perl understanding should probably
check this diff.

Since p5-Digest-HMAC doesn't appear to support anything other then
MD5/SHA1 I moved to Digest::SHA for hmac_sha* and kept Digest::HMAC_MD5
for hmac_md5 (which isn't in Digest::MD5). This also removes one
dependency.

martijn@

Index: Makefile
===================================================================
RCS file: /cvs/ports/net/p5-Net-SNMP/Makefile,v
retrieving revision 1.22
diff -u -p -r1.22 Makefile
--- Makefile 31 Jul 2020 09:17:26 -0000 1.22
+++ Makefile 11 Aug 2021 06:49:12 -0000
@@ -6,7 +6,7 @@ MODULES= cpan
PKG_ARCH= *
DISTNAME= Net-SNMP-v6.0.1
PKGNAME= p5-Net-SNMP-6.0.1
-REVISION= 2
+REVISION= 3
CATEGORIES= net devel

# same as perl
@@ -14,8 +14,7 @@ PERMIT_PACKAGE= Yes

RUN_DEPENDS= security/p5-Crypt-DES>=2.03 \
security/p5-Crypt-Rijndael \
- security/p5-Digest-HMAC>=1 \
- security/p5-Digest-SHA1>=1.02
+ security/p5-Digest-HMAC>=1
BUILD_DEPENDS= ${RUN_DEPENDS}

.include <bsd.port.mk>
Index: patches/patch-lib_Net_SNMP_Security_USM_pm
===================================================================
RCS file: patches/patch-lib_Net_SNMP_Security_USM_pm
diff -N patches/patch-lib_Net_SNMP_Security_USM_pm
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-lib_Net_SNMP_Security_USM_pm 11 Aug 2021 06:49:12 -0000
@@ -0,0 +1,201 @@
+$OpenBSD$
+
+Index: lib/Net/SNMP/Security/USM.pm
+--- lib/Net/SNMP/Security/USM.pm.orig
++++ lib/Net/SNMP/Security/USM.pm
+@@ -25,9 +25,11 @@ use Net::SNMP::Message qw(
+
+ use Crypt::DES();
+ use Digest::MD5();
+-use Digest::SHA1();
+-use Digest::HMAC();
++use Digest::SHA();
+
++use Digest::SHA qw( hmac_sha1 hmac_sha224 hmac_sha256 hmac_sha384 hmac_sha512 );
++use Digest::HMAC_MD5 qw ( hmac_md5 );
++
+ ## Version of the Net::SNMP::Security::USM module
+
+ our $VERSION = v4.0.1;
+@@ -40,7 +42,9 @@ our @EXPORT_OK;
+
+ our %EXPORT_TAGS = (
+ authprotos => [
+- qw( AUTH_PROTOCOL_NONE AUTH_PROTOCOL_HMACMD5 AUTH_PROTOCOL_HMACSHA )
++ qw( AUTH_PROTOCOL_NONE AUTH_PROTOCOL_HMACMD5 AUTH_PROTOCOL_HMACSHA
++ AUTH_PROTOCOL_HMACSHA224 AUTH_PROTOCOL_HMACSHA256
++ AUTH_PROTOCOL_HMACSHA384 AUTH_PROTOCOL_HMACSHA512 )
+ ],
+ levels => [
+ qw( SECURITY_LEVEL_NOAUTHNOPRIV SECURITY_LEVEL_AUTHNOPRIV
+@@ -63,9 +67,13 @@ $EXPORT_TAGS{ALL} = [ @EXPORT_OK ];
+
+ ## RCC 3414 - Authentication protocols
+
+-sub AUTH_PROTOCOL_NONE { '1.3.6.1.6.3.10.1.1.1' } # usmNoAuthProtocol
+-sub AUTH_PROTOCOL_HMACMD5 { '1.3.6.1.6.3.10.1.1.2' } # usmHMACMD5AuthProtocol
+-sub AUTH_PROTOCOL_HMACSHA { '1.3.6.1.6.3.10.1.1.3' } # usmHMACSHAAuthProtocol
++sub AUTH_PROTOCOL_NONE { '1.3.6.1.6.3.10.1.1.1' } # usmNoAuthProtocol
++sub AUTH_PROTOCOL_HMACMD5 { '1.3.6.1.6.3.10.1.1.2' } # usmHMACMD5AuthProtocol
++sub AUTH_PROTOCOL_HMACSHA { '1.3.6.1.6.3.10.1.1.3' } # usmHMACSHAAuthProtocol
++sub AUTH_PROTOCOL_HMACSHA224 { '1.3.6.1.6.3.10.1.1.4' } # usmHMAC128SHA224AuthProtocol
++sub AUTH_PROTOCOL_HMACSHA256 { '1.3.6.1.6.3.10.1.1.5' } # usmHMAC192SHA256AuthProtocol
++sub AUTH_PROTOCOL_HMACSHA384 { '1.3.6.1.6.3.10.1.1.6' } # usmHMAC256SHA384AuthProtocol
++sub AUTH_PROTOCOL_HMACSHA512 { '1.3.6.1.6.3.10.1.1.7' } # usmHMAC384SHA512AuthProtocol
+
+ ## RFC 3414 - Privacy protocols
+
+@@ -124,6 +132,7 @@ sub new
+ '_time_epoc' => time(), # snmpEngineBoots epoc
+ '_user_name' => q{}, # securityName
+ '_auth_data' => undef, # Authentication data
++ '_auth_maclen' => undef, # MAC length
+ '_auth_key' => undef, # authKey
+ '_auth_password' => undef, # Authentication password
+ '_auth_protocol' => AUTH_PROTOCOL_HMACMD5, # authProtocol
+@@ -280,10 +289,10 @@ sub generate_request_msg
+ if ($pdu->security_level() > SECURITY_LEVEL_NOAUTHNOPRIV) {
+
+ # Save the location to fill in msgAuthenticationParameters later
+- $auth_location = $msg->length() + 12 + length $pdu_buffer;
++ $auth_location = $msg->length() + $this->{_auth_maclen} + length $pdu_buffer;
+
+ # Set the msgAuthenticationParameters to all zeros
+- $auth_params = pack 'x12';
++ $auth_params = pack "x$this->{_auth_maclen}";
+ }
+
+ if (!defined $msg->prepare(OCTET_STRING, $auth_params)) {
+@@ -418,12 +427,12 @@ sub process_incoming_msg
+ # to compute the HMAC properly.
+
+ if (my $len = length $auth_params) {
+- if ($len != 12) {
++ if ($len != $this->{_auth_maclen}) {
+ return $this->_error(
+ 'The msgAuthenticationParameters length of %d is invalid', $len
+ );
+ }
+- substr ${$msg->reference}, ($msg->index() - 12), 12, pack 'x12';
++ substr ${$msg->reference}, ($msg->index() - $this->{_auth_maclen}), $this->{_auth_maclen}, pack "x$this->{_auth_maclen}";
+ }
+
+ # msgPrivacyParameters::=OCTET STRING
+@@ -747,6 +756,18 @@ sub _auth_password
+ quotemeta AUTH_PROTOCOL_HMACMD5, AUTH_PROTOCOL_HMACMD5,
+ '(?:hmac-)?sha(?:-?1|-96)?', AUTH_PROTOCOL_HMACSHA,
+ quotemeta AUTH_PROTOCOL_HMACSHA, AUTH_PROTOCOL_HMACSHA,
++ '(?:hmac-)?sha(?:-?224)?', AUTH_PROTOCOL_HMACSHA224,
++ 'usmHMAC128SHA224AuthProtocol', AUTH_PROTOCOL_HMACSHA224,
++ quotemeta AUTH_PROTOCOL_HMACSHA224,AUTH_PROTOCOL_HMACSHA224,
++ '(?:hmac-)?sha(?:-?256)?', AUTH_PROTOCOL_HMACSHA256,
++ 'usmHMAC192SHA256AuthProtocol', AUTH_PROTOCOL_HMACSHA256,
++ quotemeta AUTH_PROTOCOL_HMACSHA256,AUTH_PROTOCOL_HMACSHA256,
++ '(?:hmac-)?sha(?:-?384)?', AUTH_PROTOCOL_HMACSHA384,
++ 'usmHMAC256SHA384AuthProtocol', AUTH_PROTOCOL_HMACSHA384,
++ quotemeta AUTH_PROTOCOL_HMACSHA384,AUTH_PROTOCOL_HMACSHA384,
++ '(?:hmac-)?sha(?:-?512)?', AUTH_PROTOCOL_HMACSHA512,
++ 'usmHMAC384SHA512AuthProtocol', AUTH_PROTOCOL_HMACSHA512,
++ quotemeta AUTH_PROTOCOL_HMACSHA512,AUTH_PROTOCOL_HMACSHA512,
+ };
+
+ sub _auth_protocol
+@@ -1099,7 +1120,7 @@ sub _authenticate_outgoing_msg
+ }
+
+ # Set the msgAuthenticationParameters
+- substr ${$msg->reference}, -$auth_location, 12, $this->_auth_hmac($msg);
++ substr ${$msg->reference}, -$auth_location, $this->{_auth_maclen}, $this->_auth_hmac($msg);
+
+ return TRUE;
+ }
+@@ -1125,7 +1146,7 @@ sub _auth_hmac
+ return q{} if (!defined($this->{_auth_data}) || !defined $msg);
+
+ return substr
+- $this->{_auth_data}->reset()->add(${$msg->reference()})->digest(), 0, 12;
++ $this->{_auth_data}(${$msg->reference()}, $this->{_auth_key}), 0, $this->{_auth_maclen};
+ }
+
+ sub _auth_data_init
+@@ -1140,16 +1161,35 @@ sub _auth_data_init
+
+ if ($this->{_auth_protocol} eq AUTH_PROTOCOL_HMACMD5) {
+
+- $this->{_auth_data} =
+- Digest::HMAC->new($this->{_auth_key}, 'Digest::MD5');
++ $this->{_auth_data} = \&hmac_md5;
++ $this->{_auth_maclen} = 12;
+
+ } elsif ($this->{_auth_protocol} eq AUTH_PROTOCOL_HMACSHA) {
+
+- $this->{_auth_data} =
+- Digest::HMAC->new($this->{_auth_key}, 'Digest::SHA1');
++ $this->{_auth_data} = \&hmac_sha1;
++ $this->{_auth_maclen} = 12;
+
+- } else {
++ } elsif ($this->{_auth_protocol} eq AUTH_PROTOCOL_HMACSHA224) {
+
++ $this->{_auth_data} = \&hmac_sha224;
++ $this->{_auth_maclen} = 16;
++
++ } elsif ($this->{_auth_protocol} eq AUTH_PROTOCOL_HMACSHA256) {
++
++ $this->{_auth_data} = \&hmac_sha256;
++ $this->{_auth_maclen} = 24;
++
++ } elsif ($this->{_auth_protocol} eq AUTH_PROTOCOL_HMACSHA384) {
++
++ $this->{_auth_data} = \&hmac_sha384;
++ $this->{_auth_maclen} = 32;
++
++ } elsif ($this->{_auth_protocol} eq AUTH_PROTOCOL_HMACSHA512) {
++
++ $this->{_auth_data} = \&hmac_sha512;
++ $this->{_auth_maclen} = 48;
++
++ } else {
+ return $this->_error(
+ 'The authProtocol "%s" is unknown', $this->{_auth_protocol}
+ );
+@@ -1627,6 +1667,10 @@ sub _auth_key_validate
+ {
+ AUTH_PROTOCOL_HMACMD5, [ 16, 'HMAC-MD5' ],
+ AUTH_PROTOCOL_HMACSHA, [ 20, 'HMAC-SHA1' ],
++ AUTH_PROTOCOL_HMACSHA224, [ 28, 'HMAC-SHA224' ],
++ AUTH_PROTOCOL_HMACSHA256, [ 32, 'HMAC-SHA256' ],
++ AUTH_PROTOCOL_HMACSHA384, [ 48, 'HMAC-SHA384' ],
++ AUTH_PROTOCOL_HMACSHA512, [ 64, 'HMAC-SHA512' ],
+ };
+
+ if (!exists $key_len->{$this->{_auth_protocol}}) {
+@@ -1782,8 +1826,12 @@ sub _password_localize
+
+ my $digests =
+ {
+- AUTH_PROTOCOL_HMACMD5, 'Digest::MD5',
+- AUTH_PROTOCOL_HMACSHA, 'Digest::SHA1',
++ AUTH_PROTOCOL_HMACMD5, ['Digest::MD5', ],
++ AUTH_PROTOCOL_HMACSHA, ['Digest::SHA', 1],
++ AUTH_PROTOCOL_HMACSHA224, ['Digest::SHA', 224],
++ AUTH_PROTOCOL_HMACSHA256, ['Digest::SHA', 256],
++ AUTH_PROTOCOL_HMACSHA384, ['Digest::SHA', 384],
++ AUTH_PROTOCOL_HMACSHA512, ['Digest::SHA', 512],
+ };
+
+ if (!exists $digests->{$this->{_auth_protocol}}) {
+@@ -1792,7 +1840,12 @@ sub _password_localize
+ );
+ }
+
+- my $digest = $digests->{$this->{_auth_protocol}}->new;
++ my $digest;
++ if (!defined($digests->{$this->{_auth_protocol}}[1])) {
++ $digest = $digests->{$this->{_auth_protocol}}[0]->new;
++ } else {
++ $digest = $digests->{$this->{_auth_protocol}}[0]->new($digests->{$this->{_auth_protocol}}[1]);
++ }
+
+ # Create the initial digest using the password
+

No comments:

Post a Comment