TLS TCP to local netsnmp server is giving SSL errors

Hi,

we are looking for some documentation on how the java code can be written to send the traps using (TSM) tls tcp traffic to netsnmp manager using java snmp4j.

We are using the below code that we came across from one of the post and we are running into SSL errors and while capturing the tcp dump we could see that java application is not initiating the tls handshake. please suggest.

Note: we arent java experts here.

package snmp;
import org.snmp4j.;
import org.snmp4j.mp.MPv3;
import org.snmp4j.mp.MessageProcessingModel;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.
;
import org.snmp4j.smi.*;
import org.snmp4j.transport.AbstractTransportMapping;
import org.snmp4j.transport.DefaultTcpTransportMapping;
import org.snmp4j.transport.TLSTM;
import org.snmp4j.transport.tls.DefaultTlsTmSecurityCallback;
import org.snmp4j.transport.tls.SecurityNameMapping.CertMappingType;
import org.snmp4j.transport.tls.TlsTmSecurityCallback;
import org.snmp4j.util.MultiThreadedMessageDispatcher;
import org.snmp4j.util.ThreadPool;

import java.io.File;
import java.io.IOException;

public class TlsTrapSender {

public static void main(String args) {
try {

  System.setProperty("javax.net.ssl.keyStore", "src/main/resources/net-snmp.jks");
  System.setProperty("javax.net.ssl.keyStorePassword", "abcd1234");
  System.setProperty("javax.net.ssl.trustStore", "src/main/resources/truststore.jks");
  System.setProperty("javax.net.ssl.trustStorePassword", "abcd1234");
  AbstractTransportMapping transport = new TLSTM(new TlsAddress("127.0.0.1/11163"));
  ((TLSTM)transport).setLocalCertificateAlias("tutorial-agent");
   
  // set the security callback (only required for command responder,
  // but also recommended for command generators) -
  // the callback will be configured later:
  DefaultTlsTmSecurityCallback securityCallback = new DefaultTlsTmSecurityCallback();
  ((TLSTM)transport).setSecurityCallback(securityCallback);
  securityCallback.addAcceptedSubjectDN("C=US, ST=CA, O=Net-SNMP, OU=Development, CN=qaz/emailAddress=admin@net-snmp.org");

  MessageDispatcher md = new MessageDispatcherImpl();
  // we need MPv3 for TLSTM:
  
  MessageProcessingModel mp = new MPv3();
  md.addMessageProcessingModel(mp);
   
  
  Snmp snmp = new Snmp(md, transport);
   USM usm = new USM(SecurityProtocols.getInstance(),new OctetString("tls:127.0.0.1/11163"),0);
   SecurityModels.getInstance().addSecurityModel(usm);
   SecurityModels.getInstance().addSecurityModel(new TSM(new OctetString("tls:127.0.0.1/11163"), false));
   ThreadPool threadPool = ThreadPool.create("trap-thread", 2);
   MessageDispatcher dispatcher = new MultiThreadedMessageDispatcher(threadPool, new MessageDispatcherImpl());
   
  // do not forget to listen for responses:
  try {
  	snmp.listen();
  } catch (IOException e) {
  	// TODO Auto-generated catch block
  	e.printStackTrace();
  }
  
  String sn = "qaz";
  CertifiedTarget ct = new CertifiedTarget(GenericAddress.parse("tls:127.0.0.1/10162"), new OctetString(sn),
      // server fingerprint (replace with the fingerprint of the server's certificate):
      OctetString.fromHexString("25:F9:3F:D8:D1:73:21:CA:69:50:F6:D0:E4:54:5F:86:9D:E4:C1:55:92:92:92:59:E6:0F:72:4F:52:E2:02:61"),
      // Client fingerprint could be empty string (no check)
       OctetString.fromHexString("47:66:13:02:D3:2C:72:B5:B4:D3:5C:3E:46:47:BB:31:EB:EB:50:84:5F:50:5D:53:70:96:FF:A7:55:7C:BC:47"));
  
  ct.setVersion(SnmpConstants.version3);
  ct.setSecurityModel(SecurityModel.SECURITY_MODEL_TSM);
  ct.setSecurityName(new OctetString("qaz"));
  ct.setTimeout(15000);
  
  
  ct.setSecurityModel(SecurityModel.SECURITY_MODEL_TSM);
  securityCallback.addSecurityNameMapping(new OctetString("030611d10155adaf697b4a08aa8cf3e99a00f6bb"), CertMappingType.SANDNSName, null, new OctetString("foobar"));
  securityCallback.addAcceptedIssuerDN("foobar");
  securityCallback.addAcceptedIssuerDN("master");
  securityCallback.addAcceptedSubjectDN("C=US, ST=CA, O=Net-SNMP, OU=Development, CN=qaz/emailAddress=admin@net-snmp.org");
  securityCallback.addLocalCertMapping(ct.getAddress(), "tutorial-agent");

// UsmUser user = new UsmUser (new OctetString(“noenguser”), AuthSHA.ID, new OctetString(“authPass”), PrivAES128.ID, new OctetString(“privPass”));
// snmp.getUSM().addUser (user.getSecurityName(), user);

   // Print the local engine ID
  // System.out.println("Local Engine ID: " + localEngineID.toHexString());

   // Create PDU (Trap)
   ScopedPDU trap = new ScopedPDU();
   trap.setType(PDU.TRAP);

   // Add variable bindings (OIDs and values)
   trap.add(new VariableBinding(SnmpConstants.sysUpTime, new TimeTicks(100)));
   trap.add(new VariableBinding(SnmpConstants.snmpTrapOID, new OID("1.3.6.1.4.1.0.1")));
   trap.add(new VariableBinding(new OID(".1.3.6.1.2.1.1.1.0"), new OctetString("Test Trap from Java")));

   // Send the trap
   snmp.send(trap, ct);
   System.out.println("snmp:"+snmp);
   System.out.println("snmp trap:"+trap);

   System.out.println("SNMPv3 trap sent.");

//
}catch(Exception e) {
e.printStackTrace();
}

}

output from java:
snmp:org.snmp4j.Snmp@64729b1e

snmp trap:TRAP[{contextEngineID=80:00:13:70:01:c0:a8:01:67:5b:7f:e8:f9, contextName=}, requestID=554796606, errorStatus=0, errorIndex=0, VBS[1.3.6.1.2.1.1.3.0 = 0:00:01.00; 1.3.6.1.6.3.1.1.4.1.0 = 1.3.6.1.4.1.0.1; 1.3.6.1.2.1.1.1.0 = Test Trap from Java]]

SNMPv3 trap sent.

keytool output

PS C:\Users\pavithra\eclipse-workspace\snmp\src\main\resources> keytool -list -keystore .\net-snmp.jks -storepass abcd1234
Keystore type: PKCS12
Keystore provider: SUN

Your keystore contains 3 entries

1, 31-Mar-2025, PrivateKeyEntry,
Certificate fingerprint (SHA-256): 47:66:13:02:D3:2C:72:B5:B4:D3:5C:3E:46:47:BB:31:EB:EB:50:84:5F:50:5D:53:70:96:FF:A7:55:7C:BC:47
tutorial-agent, 07-Apr-2025, trustedCertEntry,
Certificate fingerprint (SHA-256): 47:66:13:02:D3:2C:72:B5:B4:D3:5C:3E:46:47:BB:31:EB:EB:50:84:5F:50:5D:53:70:96:FF:A7:55:7C:BC:47
tutorial-ca, 07-Apr-2025, trustedCertEntry,
Certificate fingerprint (SHA-256): 25:F9:3F:D8:D1:73:21:CA:69:50:F6:D0:E4:54:5F:86:9D:E4:C1:55:92:92:92:59:E6:0F:72:4F:52:E2:02:61
PS C:\Users\pavithra\eclipse-workspace\snmp\src\main\resources>

To be able to help you finding the cause of the communication problem, you need to active DEBUG logging in SNMP4J and post the output here.
If TLS handshake is not started, the TLS protocol versions or cipher negotiation is failing already.

snmp Manager logs:
Set tlsMinVersion to ‘tls1_1’
Set tlsMaxVersion to ‘tls1_3’
set SSL cipher list to ‘DHE-RSA-AES256-SHA:AES256-SHA:DES-CBC3-SHA’
NET-SNMP version 5.10

java application logs
Context engine ID of unconfirmed scoped PDU is empty! Setting it to local engine ID

Adding cache entry: StateReference[msgID=1148976372,pduHandle=PduHandle[95426829],securityEngineID=80:00:13:70:01:c0:a8:01:67:af:d7:b8:8f,securityModel=org.snmp4j.security.TSM@ba4d54,securityName=qaz,securityLevel=1,contextEngineID=80:00:13:70:01:c0:a8:01:67:af:d7:b8:8f,contextName=,retryMsgIDs=null]

Looking up connection for destination ‘127.0.0.1/10162’ returned: null

{}

Socket for address ‘127.0.0.1/10162’ is closed, opening it…

KeyStore ‘java.io.FileInputStream@4667ae56’ contains: [1, tutorial-agent, tutorial-ca]

Local certificate with alias ‘tutorial-agent’ not found. Known aliases are: [1, tutorial-agent, tutorial-ca]

SSL context initializing with TrustManagers: [sun.security.ssl.X509TrustManagerImpl@6500df86] and factory org.snmp4j.transport.TLSTM$DefaultTLSTMTrustManagerFactory

Configuring SSL engine, supported protocols are [TLSv1.3, TLSv1.2, TLSv1.1, TLSv1, SSLv3, SSLv2Hello], supported ciphers are [TLS_AES_256_GCM_SHA384, TLS_AES_128_GCM_SHA256, TLS_CHACHA20_POLY1305_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV], https defaults are TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:TLS_DHE_RSA_WITH_AES_256_CBC_SHA

Configured SSL engine, enabled protocols are [TLSv1], enabled ciphers are

Trying to connect to 127.0.0.1/10162

snmp:org.snmp4j.Snmp@184f6be2

snmp trap:TRAP[{contextEngineID=80:00:13:70:01:c0:a8:01:67:af:d7:b8:8f, contextName=}, requestID=95426829, errorStatus=0, errorIndex=0, VBS[1.3.6.1.2.1.1.3.0 = 0:00:01.00; 1.3.6.1.6.3.1.1.4.1.0 = 1.3.6.1.4.1.0.1; 1.3.6.1.2.1.1.1.0 = Test Trap from Java]]

SNMPv3 trap sent.

Adding operation 8 for: SocketEntry[peerAddress=127.0.0.1/10162,socket=Socket[unconnected],lastUse=Mon Jan 05 08:34:12 IST 1970,inNetBuffer=java.nio.HeapByteBuffer[pos=0 lim=32768 cap=32768],inAppBuffer=java.nio.HeapByteBuffer[pos=0 lim=32768 cap=32768],outNetBuffer=java.nio.HeapByteBuffer[pos=0 lim=32768 cap=32768]]

Key is connectable

Connected to 127.0.0.1/10162

Adding operation 4 for: SocketEntry[peerAddress=127.0.0.1/10162,socket=Socket[addr=127.0.0.1/127.0.0.1,port=10162,localport=51714],lastUse=Mon Jan 05 08:34:12 IST 1970,inNetBuffer=java.nio.HeapByteBuffer[pos=0 lim=32768 cap=32768],inAppBuffer=java.nio.HeapByteBuffer[pos=0 lim=32768 cap=32768],outNetBuffer=java.nio.HeapByteBuffer[pos=0 lim=32768 cap=32768]]

Fire connected event for 127.0.0.1/10162

Firing transport state event: org.snmp4j.transport.TransportStateEvent[source=org.snmp4j.transport.TLSTM@5f152693,peerAddress=127.0.0.1/10162,newState=1,cancelled=false,causingException=null]

Key is writable

Sending message with length 133 to 127.0.0.1/10162: 30:81:82:02:01:03:30:11:02:04:44:7b:fc:f4:02:03:00:80:00:04:01:00:02:01:04:04:00:30:68:04:0d:80:00:13:70:01:c0:a8:01:67:af:d7:b8:8f:04:00:a7:55:02:04:05:b0:19:0d:02:01:00:02:01:00:30:47:30:0d:06:08:2b:06:01:02:01:01:03:00:43:01:64:30:15:06:0a:2b:06:01:06:03:01:01:04:01:00:06:07:2b:06:01:04:01:00:01:30:1f:06:08:2b:06:01:02:01:01:01:00:04:13:54:65:73:74:20:54:72:61:70:20:66:72:6f:6d:20:4a:61:76:61

javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

Firing transport state event: org.snmp4j.transport.TransportStateEvent[source=org.snmp4j.transport.TLSTM@5f152693,peerAddress=127.0.0.1/10162,newState=2,cancelled=false,causingException=javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)]

Adding operation 8 for: SocketEntry[peerAddress=127.0.0.1/10162,socket=Socket[unconnected],lastUse=Mon Jan 05 08:34:12 IST 1970,inNetBuffer=java.nio.HeapByteBuffer[pos=0 lim=32768 cap=32768],inAppBuffer=java.nio.HeapByteBuffer[pos=0 lim=32768 cap=32768],outNetBuffer=java.nio.HeapByteBuffer[pos=0 lim=32768 cap=32768]]

java.nio.channels.ClosedChannelException

Firing transport state event: org.snmp4j.transport.TransportStateEvent[source=org.snmp4j.transport.TLSTM@5f152693,peerAddress=127.0.0.1/10162,newState=4,cancelled=false,causingException=java.nio.channels.ClosedChannelException]

Socket has not been used for 60224332000 milliseconds, closing it

Socket to 127.0.0.1/10162 closed due to timeout

Ok, as previously stated, you did not configure matching ciphers (and protocol) in both ends.

can you please let me know how should i configure ciphers at the client side (SNMP4j/java)? i tried to set the system property but i dont see much of the impact it gives the same error ?

System.setProperty(“https.protocols”, “TLSv1.2”);
System.setProperty(“https.cipherSuites”, “TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:TLS_DHE_RSA_WITH_AES_256_CBC_SHA”);

Logs:
KeyStore ‘java.io.FileInputStream@4667ae56’ contains: [1, tutorial-agent, tutorial-ca]

Local certificate with alias ‘tutorial-agent’ not found. Known aliases are: [1, tutorial-agent, tutorial-ca]

SSL context initializing with TrustManagers: [sun.security.ssl.X509TrustManagerImpl@6500df86] and factory org.snmp4j.transport.TLSTM$DefaultTLSTMTrustManagerFactory

Configuring SSL engine, supported protocols are [TLSv1.3, TLSv1.2, TLSv1.1, TLSv1, SSLv3, SSLv2Hello], supported ciphers are [TLS_AES_256_GCM_SHA384, TLS_AES_128_GCM_SHA256, TLS_CHACHA20_POLY1305_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV], https defaults are TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:TLS_DHE_RSA_WITH_AES_256_CBC_SHA

Configured SSL engine, enabled protocols are [TLSv1], enabled ciphers are []

@AGENTPP any suggestions here?

DHE-RSA-AES256-SHA is NOT equal to TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 using string compare although that OpenSSH cipher is technically the same as the IANA cipher used by Java (see Mapping OpenSSL cipher suite names to IANA names).

To be able to communicate, the cipher names have to string match. See tomcat - How to map a OpenSSL's cipher list to Java JSSE - Stack Overflow on how to map OpenSSH to IANA.