Failed to parse snmp V3 messages with "Invalid constructed identifier"
I was trying rasn-snmp crate however I couldn't parse any v3 message. For example see the following test:
#[test]
fn check_message() {
let input = hex::decode("303d020103301002041d750e01020205c00401040201030410300e0400020100020100040004000400301404000400a00e02042edfbfdc0201000201003000").unwrap();
let _: rasn_snmp::v3::Message = rasn::ber::decode(&input).unwrap();
}
The previous test fails with the following output.
running 1 test
thread 'test::check_message' panicked at 'called `Result::unwrap()` on an `Err` value: FieldError { name: "NestedMessage.security_parameters", error: "Invalid constructed identifier" }', src/lib.rs:64:67
stack backtrace:
0: rust_begin_unwind
at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/panicking.rs:584:5
1: core::panicking::panic_fmt
at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/core/src/panicking.rs:142:14
2: core::result::unwrap_failed
at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/core/src/result.rs:1805:5
3: core::result::Result<T,E>::unwrap
at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/core/src/result.rs:1098:23
4: snmp_agent::test::check_message
at ./src/lib.rs:64:41
5: snmp_agent::test::check_message::{{closure}}
at ./src/lib.rs:62:5
6: core::ops::function::FnOnce::call_once
at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/core/src/ops/function.rs:248:5
7: core::ops::function::FnOnce::call_once
at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/core/src/ops/function.rs:248:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
test test::check_message ... FAILED
The content of the packet used in the test is generated by the following command (I have tried many commands, none worked, this one here is for example):
snmpstatus -v3 -l authNoPriv -u USERNAME -a MD5 -A PASSWORD localhost
I have used online ber decoder and it seems to me the packet is fine? I am still not sure what is missing and I am currently investigating this.
Thank you for your issue! Yeah I'm not sure off the top of my head, and won't be able to look at this soon, but if you find the cause I can review a PR.
I have tried encoding using snmp_rasn to find the diference. There is only 1 bit difference, it is the tag resulting from Nested<T> (used for USMSecurityParameters) It is the third bit which indicate whether the type is primitive or constructed.
In packets generated by netsnmp the tag is not set which make it primitive type while in snmp_rasn the bit set which make the type structured. It seems in SNMP resources I found octet string is treated as primitive type. However, Nested<T> set the third bit which make it constructed type.
I have run into the same issue. As mentioned SNMP implementations (net-snmp snmpd, snmpsim) will not parse snmpv3 packets where USMSecurityParameters OctetString is set as constructed (bit 6).
one option would to allow the constructed/primitive type to be overridden by a macro similar to the class/tag option. ie #[rasn(primitive(tag(universal, 4)))] this does not look like a simple fix.