TLS TCP Manager and Client

Howdy! Thanks for the add! I hope I can contribute, but have to ask forgiveness on “newb” level ahead of time.

I’m trying to add TLS over TCP for an inherited manager application which currently uses USM with DES. I’ve followed the example at [https://doc.snmp.app/pages/viewpage.action?pageId=3834144](http://How to configure SNMP4J for TLS usage?)

and having some success with keystore and trustore operations and even getting a proper TLS handshake, but alas I’ve got to be missing something obvious as I get the following error on manager side dispatch:

5111 [TLSTM_0.0.0.0/7836] INFO org.snmp4j.MessageDispatcherImpl - Message from 127.0.0.1/55618 not dispatched, reason: statusInfo=noError, status=1602

In following what a 1602 is, I’ve only uncovered its a static constant stating:

SnmpConstants.SNMPv3_TSM_INVALID_CACHES;

This is where my newb igornance kicks in… Any and all help understanding what an invalid cache is most appreciated!

Root problem seems to be DefaultTlsTmSecurityCallback does not have any SecurityNameMapping instances in securityNameMapping collection.

From example I’ve set security name within a CertifiedTarget and I’ve created a DefaultTlsTmSecurityCallback and set the callback to the TLSTM… but I’m not seeing how these assignments get translated into an instance of a SecurityNameMapping?

When in doubt, follow the source!!! Found that I’m not properly passing the security name. Will fix and follow-up with this thread.

Further information, I tried to add Secuirty Name Mapping when setting Security Callback into the TLSTSM, but when DefaultTlsTmSecurityCallback does it’s comparison in getSecurityName, I now have a SecurityNameMapping but still no fingerprint.

So I’m assuming I’m missing how I pull the certificate fingerprint when the manager server initializes TLSTM? And assuming it would be the fingerprint of the certificate from my keystore for the created alias/securityName?

Please use the CertifiedTaget constructor with server and client fingerprints. The server fingerprint will then be compared with the server’s certificate fingerprint.

Awesome! Thanks and noticed your edit on the example too! Truly appreciated! If I could burden you again… Is there any interface that I can use when setting up the CertifiedTarget during instantiation of TLSTM that will return my server fingerprint? As of now, I’m only seeing the keystore accessed when I invoke listen?

Tried

// use the CertifiedTaget constructor with server and client fingerprints
CertifiedTarget ct = new CertifiedTarget(address, securityName,
OctetString.fromHexString(“5E:0E:……”),
//Client fingerprint could be empty string (no check)
new OctetString());

But alas DefaultTlsTmSecurityCallback did not have a map entry. So I used:

CertifiedTarget ct = new CertifiedTarget(new OctetString(ipAddress));
securityCallback.addSecurityNameMapping(
OctetString.fromHexString(“5E:…”),
null,
null, securityName);

And the map entry was there and comparison worked. Is this an issue because I’m on snmp4j-2.7.0? I’m stuck using framework compliant with java 8 for now…

Please upgrade SNMP4J to 2.8.0 because it contains several TLS related (security) fixes.

Last issue was not giving a CertMappingType.SANDNSName in my addSecurityNameMapping create. Now getting the following which seems to be proper. I’ll continue trying to get the proper pdu requests into the transport and see if ye ole application will init!!

Sincere thanks for helping me work this through and your amazing snmp4j!

] with type SANDNSName and date null
43722 [TLSTM_0.0.0.0/7836] DEBUG org.snmp4j.transport.tls.DefaultTlsTmSecurityCallback - Matched security name: localhost
43723 [TLSTM_0.0.0.0/7836] DEBUG org.snmp4j.transport.TLSTM - Received message from 127.0.0.1/56839 with length 68: 30:42:02:01:03:30:10:02:03:00:c1:de:02:03:00:80:00:04:01:07:02:01:04:04:00:30:29:04:05:80:00:00:00:06:04:00:a0:1e:02:04:3e:bc:b9:6c:02:01:00:02:01:00:30:10:30:0e:06:0a:2b:06:01:06:03:0a:02:01:01:00:05:00
43726 [TLSTM_0.0.0.0/7836] DEBUG org.snmp4j.mp.MPv3 - SNMPv3 header decoded: msgId=49630, msgMaxSize=32768, msgFlags=07, secModel=4

FYI… tried with 2.8.0 release and alas all the same behaviors. Now that I’m past the cert comparison, now I’m receiving:

77238 [TLSTM_0.0.0.0/7835] DEBUG org.snmp4j.transport.tls.DefaultTlsTmSecurityCallback - Getting security name for peer certificate chain: [[

77238 [TLSTM_0.0.0.0/7835] DEBUG org.snmp4j.transport.tls.DefaultTlsTmSecurityCallback - Matching peer cert fingerprint

with type null and date null
java.lang.NullPointerException
77250 [TLSTM_0.0.0.0/7835] WARN org.snmp4j.transport.TLSTM - NullPointerException within select()?
77250 [TLSTM_0.0.0.0/7835] DEBUG org.snmp4j.transport.TLSTM - Worker task finished: org.snmp4j.transport.TLSTM$ServerThread
at org.snmp4j.transport.tls.DefaultTlsTmSecurityCallback.mapCertToTSN(DefaultTlsTmSecurityCallback.java:99)
at org.snmp4j.transport.tls.DefaultTlsTmSecurityCallback.getSecurityName(DefaultTlsTmSecurityCallback.java:77)
at org.snmp4j.transport.tls.DefaultTlsTmSecurityCallback.getSecurityName(DefaultTlsTmSecurityCallback.java:48)
at org.snmp4j.transport.TLSTM$SocketEntry.checkTransportStateReference(TLSTM.java:777)
at org.snmp4j.transport.TLSTM$ServerThread.readMessage(TLSTM.java:1521)
at org.snmp4j.transport.TLSTM$ServerThread.run(TLSTM.java:1310)
at java.lang.Thread.run(Thread.java:748)

It’s getting obvious to me at least :wink: how newb on this I am… I’ve got to be missing something obvious…

You need to specify a mapping type and mapping data for the cert-to-tls-security-name mapping. Both values are null, that’s why you get the NPE.

Howdy! Almost there… I promise :wink:

After figuring out I had to explicitly set the context Engine ID on a Scoped PDU request, I now have my getBulk request processing on the manager side. However, it’s a balancing act that I cannot find for how many repetitions on a given oid I can perform without manager or trap client giving MPv3 parse error or a MessageDispatcherImpl - java.io.IOException: Unexpected end of input stream at position 1

IE:
Request one for 600 reps on OID xxxx allows request to be processed on manager side but then client receives response:

540 [TLSTM_192.168.17.9/0] DEBUG org.snmp4j.transport.TLSTM - Received message from 127.0.0.1/7835 with length 16385: 30:82:42:38:…
543 [TLSTM_192.168.17.9/0] WARN org.snmp4j.mp.MPv3 - MPv3 parse error: The encoded length 16952 exceeds the number of bytes left in input at position 4 which actually is 16385
java.io.IOException: The encoded length 16952 exceeds the number of bytes left in input at position 4 which actually is 16385
at org.snmp4j.asn1.BER.checkLength(BER.java:1005)
at org.snmp4j.asn1.BER.decodeLength(BER.java:611)
at org.snmp4j.asn1.BER.decodeHeader(BER.java:650)
at org.snmp4j.asn1.BER.decodeHeader(BER.java:677)
at org.snmp4j.mp.MPv3.prepareDataElements(MPv3.java:1117)
at org.snmp4j.MessageDispatcherImpl.dispatchMessage(MessageDispatcherImpl.java:278)
at org.snmp4j.MessageDispatcherImpl.processMessage(MessageDispatcherImpl.java:390)
at org.snmp4j.MessageDispatcherImpl.processMessage(MessageDispatcherImpl.java:350)
at org.snmp4j.transport.AbstractTransportMapping.fireProcessMessage(AbstractTransportMapping.java:76)
at org.snmp4j.transport.TLSTM$ServerThread.dispatchMessage(TLSTM.java:1578)
at org.snmp4j.transport.TLSTM$ServerThread.readMessage(TLSTM.java:1522)
at org.snmp4j.transport.TLSTM$ServerThread.run(TLSTM.java:1310)
at java.lang.Thread.run(Thread.java:748)
545 [TLSTM_192.168.17.9/0] INFO org.snmp4j.MessageDispatcherImpl - Message from 127.0.0.1/7835 not dispatched, reason: statusInfo=noError, status=-1408

If I bring the 600 any lower then manager gives:

954241 [TLSTM_0.0.0.0/7835] DEBUG org.snmp4j.transport.TLSTM - Running delegated task on SocketEntry[peerAddress=127.0.0.1/55753,socket=Socket[addr=127.0.0.1/127.0.0.1,port=55753,localport=7835],lastUse=Mon Jan 19 12:38:03 CST 1970,inNetBuffer=java.nio.HeapByteBuffer[pos=117 lim=32768 cap=32768],inAppBuffer=java.nio.HeapByteBuffer[pos=1 lim=32768 cap=32768],outNetBuffer=java.nio.HeapByteBuffer[pos=0 lim=32768 cap=32768],socketTimeout=null]: Status = OK HandshakeStatus = NOT_HANDSHAKING
bytesConsumed = 37 bytesProduced = 1
954241 [TLSTM_0.0.0.0/7835] DEBUG org.snmp4j.transport.TLSTM - Reading inappBuffer=java.nio.HeapByteBuffer[pos=0 lim=1 cap=32768]
954241 [TLSTM_0.0.0.0/7835] DEBUG org.snmp4j.transport.TLSTM - Received message from 127.0.0.1/55753 with length 1: 30
java.io.IOException: Unexpected end of input stream at position 1
954241 [TLSTM_0.0.0.0/7835] WARN org.snmp4j.MessageDispatcherImpl - java.io.IOException: Unexpected end of input stream at position 1
at org.snmp4j.asn1.BERInputStream.read(BERInputStream.java:59)
at org.snmp4j.asn1.BER.decodeLength(BER.java:585)
at org.snmp4j.asn1.BER.decodeHeader(BER.java:650)
at org.snmp4j.MessageDispatcherImpl.processMessage(MessageDispatcherImpl.java:370)
at org.snmp4j.MessageDispatcherImpl.processMessage(MessageDispatcherImpl.java:350)
at org.snmp4j.transport.AbstractTransportMapping.fireProcessMessage(AbstractTransportMapping.java:76)
at org.snmp4j.transport.TLSTM$ServerThread.dispatchMessage(TLSTM.java:1578)
at org.snmp4j.transport.TLSTM$ServerThread.readMessage(TLSTM.java:1522)
at org.snmp4j.transport.TLSTM$ServerThread.run(TLSTM.java:1310)
at java.lang.Thread.run(Thread.java:748)

Running on a windows box right now, so don’t have any jumbo frame issues like I would have on linux with very large bulk rep requests and if I go back to UDP transport, no issues…

Thanks for your help and considerations!

What you encounter is probably an incorrectly executed TLS packet fragmentation. A TLS packet is fragmented into 16KByte (16384 bytes) data transmissions. In your case, the total data length 16389 (16385+4) exceeds the 16384 byte fragment limit and therefore the fragmentation is not detected by the TLSTM (and no merge/reassembling takes place)

What TLS stack is used by the command responder you are using? What TLS version are you using?

Was able to find and set

System.setProperty(SnmpConfigurator.P_TLS_VERSION, “TLSv1.2”);

Made sure that my Auth Protocol is AuthHMAC256SHA384 and now I’m successful with my first getBulk and response. No fragmentation issues!!! Thanks for the nudge! I’ve finally got my new TLS Transport working with my legacy app!!! You and your framework are amazing and sincerely appreciate your help!!!

Sincere thanks for your reply. Using SNMP4J 2.8.0. When initialized, logs showing TLSTM - Configured SSL engine, enabled protocols are [TLSv1] and due to java 8 + 2.8.0 this is TLS-TCP not DTLS.