package org.snmp4j.transport;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.CancelledKeyException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TimerTask;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import javax.security.auth.x500.X500Principal;
import org.snmp4j.SNMP4JSettings;
import org.snmp4j.TransportStateReference;
import org.snmp4j.event.CounterEvent;
import org.snmp4j.log.LogAdapter;
import org.snmp4j.log.LogFactory;
import org.snmp4j.mp.CounterSupport;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.security.SecurityLevel;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.IpAddress;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.TcpAddress;
import org.snmp4j.smi.TlsAddress;
import org.snmp4j.transport.tls.TlsTmSecurityCallback;
import org.snmp4j.util.CommonTimer;
import org.snmp4j.util.SnmpConfigurator;
import org.snmp4j.util.WorkerTask;

/* JADX INFO: loaded from: classes.dex */
public class TLSTM extends TcpTransportMapping {
    public static final String DEFAULT_TLSTM_PROTOCOLS = "TLSv1";
    public static final int MAX_TLS_PAYLOAD_SIZE = 32768;
    private static final LogAdapter logger = LogFactory.getLogger(TLSTM.class);
    private long connectionTimeout;
    private CounterSupport counterSupport;
    private String keyStore;
    private String keyStorePassword;
    private String localCertificateAlias;
    private long nextSessionID;
    private TlsTmSecurityCallback<X509Certificate> securityCallback;
    private WorkerTask server;
    private boolean serverEnabled;
    private ServerThread serverThread;
    private CommonTimer socketCleaner;
    private Map<Address, SocketEntry> sockets;
    private SSLEngineConfigurator sslEngineConfigurator;
    private String[] tlsProtocols;
    private TLSTMTrustManagerFactory trustManagerFactory;

    /* JADX INFO: renamed from: org.snmp4j.transport.TLSTM$1, reason: invalid class name */
    static /* synthetic */ class AnonymousClass1 {
        static final /* synthetic */ int[] $SwitchMap$javax$net$ssl$SSLEngineResult$HandshakeStatus;
        static final /* synthetic */ int[] $SwitchMap$javax$net$ssl$SSLEngineResult$Status;

        static {
            int[] iArr = new int[SSLEngineResult.HandshakeStatus.values().length];
            $SwitchMap$javax$net$ssl$SSLEngineResult$HandshakeStatus = iArr;
            try {
                iArr[SSLEngineResult.HandshakeStatus.NEED_WRAP.ordinal()] = 1;
            } catch (NoSuchFieldError unused) {
            }
            try {
                $SwitchMap$javax$net$ssl$SSLEngineResult$HandshakeStatus[SSLEngineResult.HandshakeStatus.NEED_UNWRAP.ordinal()] = 2;
            } catch (NoSuchFieldError unused2) {
            }
            try {
                $SwitchMap$javax$net$ssl$SSLEngineResult$HandshakeStatus[SSLEngineResult.HandshakeStatus.FINISHED.ordinal()] = 3;
            } catch (NoSuchFieldError unused3) {
            }
            try {
                $SwitchMap$javax$net$ssl$SSLEngineResult$HandshakeStatus[SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING.ordinal()] = 4;
            } catch (NoSuchFieldError unused4) {
            }
            int[] iArr2 = new int[SSLEngineResult.Status.values().length];
            $SwitchMap$javax$net$ssl$SSLEngineResult$Status = iArr2;
            try {
                iArr2[SSLEngineResult.Status.BUFFER_UNDERFLOW.ordinal()] = 1;
            } catch (NoSuchFieldError unused5) {
            }
            try {
                $SwitchMap$javax$net$ssl$SSLEngineResult$Status[SSLEngineResult.Status.BUFFER_OVERFLOW.ordinal()] = 2;
            } catch (NoSuchFieldError unused6) {
            }
            try {
                $SwitchMap$javax$net$ssl$SSLEngineResult$Status[SSLEngineResult.Status.CLOSED.ordinal()] = 3;
            } catch (NoSuchFieldError unused7) {
            }
            try {
                $SwitchMap$javax$net$ssl$SSLEngineResult$Status[SSLEngineResult.Status.OK.ordinal()] = 4;
            } catch (NoSuchFieldError unused8) {
            }
        }
    }

    protected class DefaultSSLEngineConfiguration implements SSLEngineConfigurator {
        private TrustManager[] trustManagers;

        protected DefaultSSLEngineConfiguration() {
        }

        private void filterCertificates(KeyStore keyStore, TransportStateReference transportStateReference) {
            String localCertificateAlias = TLSTM.this.localCertificateAlias;
            if (TLSTM.this.securityCallback != null && transportStateReference != null && (localCertificateAlias = TLSTM.this.securityCallback.getLocalCertificateAlias(transportStateReference.getAddress())) == null) {
                localCertificateAlias = TLSTM.this.localCertificateAlias;
            }
            if (localCertificateAlias != null) {
                try {
                    Certificate[] certificateChain = keyStore.getCertificateChain(localCertificateAlias);
                    if (certificateChain == null) {
                        TLSTM.logger.warn("Local certificate with alias '" + localCertificateAlias + "' not found. Known aliases are: " + Collections.list(keyStore.aliases()));
                        return;
                    }
                    ArrayList arrayList = new ArrayList(certificateChain.length);
                    for (Certificate certificate : certificateChain) {
                        String certificateAlias = keyStore.getCertificateAlias(certificate);
                        if (certificateAlias != null) {
                            arrayList.add(certificateAlias);
                        }
                    }
                    for (String str : Collections.list(keyStore.aliases())) {
                        if (arrayList.contains(str)) {
                            keyStore.deleteEntry(str);
                        }
                    }
                } catch (KeyStoreException e2) {
                    TLSTM.logger.error("Failed to get certificate chain for alias " + localCertificateAlias + ": " + e2.getMessage(), e2);
                }
            }
        }

        @Override // org.snmp4j.transport.TLSTM.SSLEngineConfigurator
        public void configure(SSLEngine sSLEngine) {
            TLSTM.logger.debug("Configuring SSL engine, supported protocols are " + Arrays.asList(sSLEngine.getSupportedProtocols()) + ", supported ciphers are " + Arrays.asList(sSLEngine.getSupportedCipherSuites()) + ", https defaults are " + System.getProperty("https.cipherSuites"));
            String[] enabledCipherSuites = sSLEngine.getEnabledCipherSuites();
            ArrayList arrayList = new ArrayList(enabledCipherSuites.length);
            for (String str : enabledCipherSuites) {
                if (!str.contains("_anon_") && !str.contains("_NULL_")) {
                    arrayList.add(str);
                }
            }
            sSLEngine.setEnabledCipherSuites((String[]) arrayList.toArray(new String[arrayList.size()]));
            sSLEngine.setEnabledProtocols(TLSTM.this.getTlsProtocols());
            if (!sSLEngine.getUseClientMode()) {
                sSLEngine.setNeedClientAuth(true);
                sSLEngine.setWantClientAuth(true);
                TLSTM.logger.info("Need client authentication set to true");
            }
            TLSTM.logger.info("Configured SSL engine, enabled protocols are " + Arrays.asList(sSLEngine.getEnabledProtocols()) + ", enabled ciphers are " + Arrays.asList(sSLEngine.getEnabledCipherSuites()));
        }

        @Override // org.snmp4j.transport.TLSTM.SSLEngineConfigurator
        public SSLContext getSSLContext(boolean z, TransportStateReference transportStateReference) {
            try {
                String str = TLSTM.DEFAULT_TLSTM_PROTOCOLS;
                if (TLSTM.this.getTlsProtocols() != null && TLSTM.this.getTlsProtocols().length > 0) {
                    str = TLSTM.this.getTlsProtocols()[0];
                }
                SSLContext sSLContext = SSLContext.getInstance(str);
                TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunPKIX");
                try {
                    try {
                        try {
                            KeyStore keyStore = KeyStore.getInstance("JKS");
                            FileInputStream fileInputStream = new FileInputStream(TLSTM.this.getKeyStore());
                            keyStore.load(fileInputStream, TLSTM.this.getKeyStorePassword() != null ? TLSTM.this.getKeyStorePassword().toCharArray() : null);
                            if (TLSTM.logger.isInfoEnabled()) {
                                TLSTM.logger.info("KeyStore '" + fileInputStream + "' contains: " + Collections.list(keyStore.aliases()));
                            }
                            filterCertificates(keyStore, transportStateReference);
                            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
                            keyManagerFactory.init(keyStore, TLSTM.this.getKeyStorePassword() != null ? TLSTM.this.getKeyStorePassword().toCharArray() : null);
                            trustManagerFactory.init(keyStore);
                            this.trustManagers = trustManagerFactory.getTrustManagers();
                            if (TLSTM.logger.isDebugEnabled()) {
                                TLSTM.logger.debug("SSL context initializing with TrustManagers: " + Arrays.asList(this.trustManagers) + " and factory " + TLSTM.this.trustManagerFactory.getClass().getName());
                            }
                            sSLContext.init(keyManagerFactory.getKeyManagers(), new TrustManager[]{TLSTM.this.trustManagerFactory.create((X509TrustManager) this.trustManagers[0], z, transportStateReference)}, null);
                            return sSLContext;
                        } catch (FileNotFoundException e2) {
                            TLSTM.logger.error("Failed to initialize SSLContext because of a FileNotFoundException: " + e2.getMessage(), e2);
                            return null;
                        } catch (KeyManagementException e3) {
                            TLSTM.logger.error("Failed to initialize SSLContext because of a KeyManagementException: " + e3.getMessage(), e3);
                            return null;
                        }
                    } catch (IOException e4) {
                        TLSTM.logger.error("Failed to initialize SSLContext because of an IOException: " + e4.getMessage(), e4);
                        return null;
                    } catch (UnrecoverableKeyException e5) {
                        TLSTM.logger.error("Failed to initialize SSLContext because of an UnrecoverableKeyException: " + e5.getMessage(), e5);
                        return null;
                    }
                } catch (KeyStoreException e6) {
                    TLSTM.logger.error("Failed to initialize SSLContext because of a KeyStoreException: " + e6.getMessage(), e6);
                    return null;
                } catch (CertificateException e7) {
                    TLSTM.logger.error("Failed to initialize SSLContext because of a CertificateException: " + e7.getMessage(), e7);
                    return null;
                }
            } catch (NoSuchAlgorithmException e8) {
                TLSTM.logger.error("Failed to initialize SSLContext because of an NoSuchAlgorithmException: " + e8.getMessage(), e8);
            }
        }
    }

    private class DefaultTLSTMTrustManagerFactory implements TLSTMTrustManagerFactory {
        private DefaultTLSTMTrustManagerFactory() {
        }

        @Override // org.snmp4j.transport.TLSTM.TLSTMTrustManagerFactory
        public X509TrustManager create(X509TrustManager x509TrustManager, boolean z, TransportStateReference transportStateReference) {
            return TLSTM.this.new TlsTrustManager(x509TrustManager, z, transportStateReference);
        }

        /* synthetic */ DefaultTLSTMTrustManagerFactory(TLSTM tlstm, AnonymousClass1 anonymousClass1) {
            this();
        }
    }

    interface SSLEngineConfigurator {
        void configure(SSLEngine sSLEngine);

        SSLContext getSSLContext(boolean z, TransportStateReference transportStateReference);
    }

    class ServerThread implements WorkerTask {
        static final /* synthetic */ boolean $assertionsDisabled = false;
        private ServerSocketChannel ssc;
        private volatile boolean stop = false;
        private Throwable lastError = null;
        private LinkedList<SocketEntry> pending = new LinkedList<>();
        private BlockingQueue<SocketEntry> outQueue = new LinkedBlockingQueue();
        private BlockingQueue<SocketEntry> inQueue = new LinkedBlockingQueue();
        private Selector selector = Selector.open();

        public ServerThread() throws NoSuchAlgorithmException, IOException {
            if (TLSTM.this.serverEnabled) {
                ServerSocketChannel serverSocketChannelOpen = ServerSocketChannel.open();
                this.ssc = serverSocketChannelOpen;
                serverSocketChannelOpen.configureBlocking(false);
                InetSocketAddress inetSocketAddress = new InetSocketAddress(TLSTM.this.tcpAddress.getInetAddress(), TLSTM.this.tcpAddress.getPort());
                TLSTM.this.setSocketOptions(this.ssc.socket());
                this.ssc.socket().bind(inetSocketAddress);
                this.ssc.register(this.selector, 16);
            }
        }

        private void closeChannel(SelectableChannel selectableChannel) {
            try {
                selectableChannel.close();
            } catch (IOException e2) {
                TLSTM.logger.warn(e2);
            }
        }

        private void connectChannel(SelectionKey selectionKey, TcpAddress tcpAddress) {
            SocketEntry socketEntry = (SocketEntry) selectionKey.attachment();
            try {
                SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                if (!socketChannel.isConnected()) {
                    if (socketChannel.finishConnect()) {
                        socketChannel.configureBlocking(false);
                        TLSTM.logger.debug("Connected to " + socketEntry.getPeerAddress());
                        TLSTM.this.timeoutSocket(socketEntry);
                        socketEntry.removeRegistration(this.selector, 8);
                        socketEntry.addRegistration(this.selector, 4);
                    } else {
                        socketEntry = null;
                    }
                }
                if (socketEntry != null) {
                    if (tcpAddress == null) {
                        tcpAddress = socketEntry.getPeerAddress();
                    }
                    TLSTM.logger.debug("Fire connected event for " + tcpAddress);
                    TLSTM.this.fireConnectionStateChanged(new TransportStateEvent(TLSTM.this, tcpAddress, 1, null));
                }
            } catch (IOException e2) {
                TLSTM.logger.warn(e2);
                selectionKey.cancel();
                closeChannel(selectionKey.channel());
                if (socketEntry != null) {
                    this.pending.remove(socketEntry);
                }
            }
        }

        private ByteBuffer createBufferCopy(ByteBuffer byteBuffer) {
            byte[] bArr = new byte[byteBuffer.limit()];
            int iLimit = byteBuffer.limit() - byteBuffer.remaining();
            byteBuffer.flip();
            byteBuffer.get(bArr, 0, iLimit);
            ByteBuffer byteBufferWrap = ByteBuffer.wrap(bArr);
            byteBufferWrap.position(iLimit);
            return byteBufferWrap;
        }

        private void dispatchMessage(TcpAddress tcpAddress, ByteBuffer byteBuffer, long j2, Object obj, TransportStateReference transportStateReference) {
            ByteBuffer byteBufferWrap;
            byteBuffer.flip();
            if (TLSTM.logger.isDebugEnabled()) {
                TLSTM.logger.debug("Received message from " + tcpAddress + " with length " + j2 + ": " + new OctetString(byteBuffer.array(), 0, (int) j2).toHexString());
            }
            if (TLSTM.this.isAsyncMsgProcessingSupported()) {
                int i2 = (int) j2;
                byte[] bArr = new byte[i2];
                System.arraycopy(byteBuffer.array(), 0, bArr, 0, i2);
                byteBufferWrap = ByteBuffer.wrap(bArr);
            } else {
                byteBufferWrap = ByteBuffer.wrap(byteBuffer.array(), 0, (int) j2);
            }
            TLSTM.this.fireProcessMessage(tcpAddress, byteBufferWrap, transportStateReference);
        }

        private void processPending() {
            synchronized (this.pending) {
                for (int i2 = 0; i2 < this.pending.size(); i2++) {
                    SocketEntry first = this.pending.getFirst();
                    try {
                        if (!first.getSocket().isConnected()) {
                            first.addRegistration(this.selector, 8);
                        } else if (first.isHandshakeFinished()) {
                            first.addRegistration(this.selector, 4);
                        }
                    } catch (IOException e2) {
                        TLSTM.logger.error(e2);
                        this.pending.remove(first);
                        try {
                            first.getSocket().getChannel().close();
                            TLSTM.this.fireConnectionStateChanged(new TransportStateEvent(TLSTM.this, first.getPeerAddress(), 4, e2));
                        } catch (IOException e3) {
                            TLSTM.logger.error(e3);
                        }
                        this.lastError = e2;
                        if (SNMP4JSettings.isForwardRuntimeExceptions()) {
                            throw new RuntimeException(e2);
                        }
                    } catch (CancelledKeyException e4) {
                        TLSTM.logger.warn(e4);
                        this.pending.remove(first);
                        try {
                            first.getSocket().getChannel().close();
                            TLSTM.this.fireConnectionStateChanged(new TransportStateEvent(TLSTM.this, first.getPeerAddress(), 4, null));
                        } catch (IOException e5) {
                            TLSTM.logger.error(e5);
                        }
                    }
                }
            }
        }

        private synchronized void processQueues() {
            SocketEntry socketEntryTake;
            IOException e2;
            SocketEntry socketEntryTake2;
            while (true) {
                if (!this.outQueue.isEmpty() || !this.inQueue.isEmpty()) {
                    while (!this.outQueue.isEmpty()) {
                        try {
                            try {
                                socketEntryTake2 = this.outQueue.take();
                                try {
                                    SSLEngineResult sSLEngineResultSendNetMessage = TLSTM.this.sendNetMessage(socketEntryTake2);
                                    if (sSLEngineResultSendNetMessage != null && runDelegatedTasks(sSLEngineResultSendNetMessage, socketEntryTake2) && socketEntryTake2.isAppOutPending()) {
                                        writeMessage(socketEntryTake2, socketEntryTake2.getSocket().getChannel());
                                    }
                                } catch (IOException e3) {
                                    e2 = e3;
                                    TLSTM.logger.error("IO exception caught while SSL processing: " + e2.getMessage(), e2);
                                    while (this.inQueue.remove(socketEntryTake2)) {
                                    }
                                }
                            } catch (IOException e4) {
                                e2 = e4;
                                socketEntryTake2 = null;
                            }
                        } catch (InterruptedException e5) {
                            TLSTM.logger.error("SSL processing interrupted: " + e5.getMessage(), e5);
                            return;
                        }
                    }
                    while (!this.inQueue.isEmpty()) {
                        try {
                            try {
                                socketEntryTake = this.inQueue.take();
                                try {
                                    synchronized (socketEntryTake.inboundLock) {
                                        socketEntryTake.inNetBuffer.flip();
                                        TLSTM.logger.debug("TLS inNetBuffer = " + socketEntryTake.inNetBuffer);
                                        SSLEngineResult sSLEngineResultUnwrap = socketEntryTake.sslEngine.unwrap(socketEntryTake.inNetBuffer, socketEntryTake.inAppBuffer);
                                        TLSTM.this.adjustInNetBuffer(socketEntryTake, sSLEngineResultUnwrap);
                                        if (runDelegatedTasks(sSLEngineResultUnwrap, socketEntryTake)) {
                                            int i2 = AnonymousClass1.$SwitchMap$javax$net$ssl$SSLEngineResult$Status[sSLEngineResultUnwrap.getStatus().ordinal()];
                                            if (i2 == 1) {
                                                socketEntryTake.inNetBuffer.limit(socketEntryTake.inNetBuffer.capacity());
                                                socketEntryTake.addRegistration(this.selector, 1);
                                            } else if (i2 != 3) {
                                                if (i2 == 4) {
                                                    if (socketEntryTake.isAppOutPending()) {
                                                        writeMessage(socketEntryTake, socketEntryTake.getSocket().getChannel());
                                                    }
                                                    socketEntryTake.inAppBuffer.flip();
                                                    TLSTM.logger.debug("Dispatching inAppBuffer=" + socketEntryTake.inAppBuffer);
                                                    if (socketEntryTake.inAppBuffer.limit() > 0) {
                                                        dispatchMessage(socketEntryTake.getPeerAddress(), socketEntryTake.inAppBuffer, socketEntryTake.inAppBuffer.limit(), Long.valueOf(socketEntryTake.sessionID), socketEntryTake.tmStateReference);
                                                    }
                                                    socketEntryTake.inAppBuffer.clear();
                                                }
                                            }
                                        }
                                    }
                                } catch (IOException e6) {
                                    e = e6;
                                    TLSTM.logger.error("IO exception caught while SSL processing: " + e.getMessage(), e);
                                    while (this.inQueue.remove(socketEntryTake)) {
                                    }
                                }
                            } catch (InterruptedException e7) {
                                TLSTM.logger.error("SSL processing interrupted: " + e7.getMessage(), e7);
                                return;
                            }
                        } catch (IOException e8) {
                            e = e8;
                            socketEntryTake = null;
                        }
                    }
                }
            }
        }

        private void readMessage(SelectionKey selectionKey, SocketChannel socketChannel, TcpAddress tcpAddress, SocketEntry socketEntry) throws IOException {
            SocketEntry socketEntry2 = (SocketEntry) selectionKey.attachment();
            if (socketEntry2 != null) {
                socketEntry = socketEntry2;
            }
            if (socketEntry == null) {
                TLSTM.logger.error("SocketEntry null in readMessage");
            }
            socketEntry.used();
            ByteBuffer inNetBuffer = socketEntry.getInNetBuffer();
            ByteBuffer inAppBuffer = socketEntry.getInAppBuffer();
            try {
                long j2 = socketChannel.read(inNetBuffer);
                inNetBuffer.flip();
                if (TLSTM.logger.isDebugEnabled()) {
                    TLSTM.logger.debug("Read " + j2 + " bytes from " + tcpAddress);
                    LogAdapter logAdapter = TLSTM.logger;
                    StringBuilder sb = new StringBuilder();
                    sb.append("TLS inNetBuffer: ");
                    sb.append(inNetBuffer);
                    logAdapter.debug(sb.toString());
                }
                if (j2 < 0) {
                    TLSTM.logger.debug("Socket closed remotely");
                    selectionKey.cancel();
                    socketChannel.close();
                    TLSTM.this.fireConnectionStateChanged(new TransportStateEvent(TLSTM.this, tcpAddress, 2, null));
                    return;
                }
                if (j2 == 0) {
                    socketEntry.inNetBuffer.clear();
                    return;
                }
                synchronized (socketEntry.inboundLock) {
                    SSLEngineResult sSLEngineResultUnwrap = socketEntry.sslEngine.unwrap(inNetBuffer, inAppBuffer);
                    TLSTM.this.adjustInNetBuffer(socketEntry, sSLEngineResultUnwrap);
                    if (AnonymousClass1.$SwitchMap$javax$net$ssl$SSLEngineResult$Status[sSLEngineResultUnwrap.getStatus().ordinal()] == 2) {
                        System.err.println("BUFFER_OVERFLOW");
                        throw new IOException("BUFFER_OVERFLOW");
                    }
                    if (runDelegatedTasks(sSLEngineResultUnwrap, socketEntry)) {
                        TLSTM.logger.info("SSL session established");
                        if (sSLEngineResultUnwrap.bytesProduced() > 0) {
                            socketEntry.inAppBuffer.flip();
                            TLSTM.logger.debug("SSL established, dispatching inappBuffer=" + socketEntry.inAppBuffer);
                            socketEntry.checkTransportStateReference();
                            dispatchMessage(tcpAddress, inAppBuffer, (long) inAppBuffer.limit(), Long.valueOf(socketEntry.sessionID), socketEntry.tmStateReference);
                            socketEntry.getInAppBuffer().clear();
                        } else if (socketEntry.isAppOutPending()) {
                            writeMessage(socketEntry, socketEntry.getSocket().getChannel());
                        }
                    }
                }
            } catch (ClosedChannelException unused) {
                selectionKey.cancel();
                if (TLSTM.logger.isDebugEnabled()) {
                    TLSTM.logger.debug("Read channel not open, no bytes read from " + tcpAddress);
                }
            }
        }

        private TcpAddress writeData(SelectionKey selectionKey, TcpAddress tcpAddress) {
            TcpAddress tcpAddress2;
            IOException e2;
            SocketEntry socketEntry = (SocketEntry) selectionKey.attachment();
            try {
                SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                tcpAddress2 = new TcpAddress(socketChannel.socket().getInetAddress(), socketChannel.socket().getPort());
                if (socketEntry != null) {
                    try {
                        if (!socketEntry.hasMessage()) {
                            synchronized (this.pending) {
                                this.pending.remove(socketEntry);
                                socketEntry.removeRegistration(this.selector, 4);
                            }
                        }
                    } catch (IOException e3) {
                        e2 = e3;
                        TLSTM.logger.warn(e2);
                        TLSTM.this.fireConnectionStateChanged(new TransportStateEvent(TLSTM.this, tcpAddress2, 2, e2));
                        closeChannel(selectionKey.channel());
                    }
                }
                if (socketEntry != null) {
                    writeMessage(socketEntry, socketChannel);
                }
            } catch (IOException e4) {
                tcpAddress2 = tcpAddress;
                e2 = e4;
            }
            return tcpAddress2;
        }

        private void writeMessage(SocketEntry socketEntry, SocketChannel socketChannel) throws IOException {
            synchronized (socketEntry.outboundLock) {
                if (socketEntry.outAppBuffer == null) {
                    byte[] bArrNextMessage = socketEntry.nextMessage();
                    if (bArrNextMessage == null) {
                        socketEntry.removeRegistration(this.selector, 4);
                        if (socketEntry.hasMessage() && !socketEntry.isRegistered(4)) {
                            socketEntry.addRegistration(this.selector, 4);
                            TLSTM.logger.debug("Waking up selector");
                            this.selector.wakeup();
                        }
                        socketEntry.addRegistration(this.selector, 1);
                        return;
                    }
                    socketEntry.outAppBuffer = ByteBuffer.wrap(bArrNextMessage);
                    if (TLSTM.logger.isDebugEnabled()) {
                        TLSTM.logger.debug("Sending message with length " + bArrNextMessage.length + " to " + socketEntry.getPeerAddress() + ": " + new OctetString(bArrNextMessage).toHexString());
                    }
                }
                SSLEngineResult sSLEngineResultWrap = socketEntry.sslEngine.wrap(socketEntry.outAppBuffer, socketEntry.outNetBuffer);
                if (sSLEngineResultWrap.getStatus() == SSLEngineResult.Status.OK) {
                    if (sSLEngineResultWrap.bytesProduced() > 0) {
                        writeNetBuffer(socketEntry, socketChannel);
                    }
                } else if (runDelegatedTasks(sSLEngineResultWrap, socketEntry)) {
                    TLSTM.logger.debug("SSL session OK");
                }
                if (sSLEngineResultWrap.bytesConsumed() >= socketEntry.outAppBuffer.limit()) {
                    TLSTM.logger.debug("Payload sent completely");
                    socketEntry.outAppBuffer = null;
                }
                socketEntry.addRegistration(this.selector, 1);
            }
        }

        private void writeNetBuffer(SocketEntry socketEntry, SocketChannel socketChannel) throws IOException {
            socketEntry.outNetBuffer.flip();
            while (socketEntry.outNetBuffer.hasRemaining()) {
                TLSTM.logger.debug("Writing TLS outNetBuffer(PAYLOAD): " + socketEntry.outNetBuffer);
                int iWrite = socketChannel.write(socketEntry.outNetBuffer);
                TLSTM.logger.debug("Wrote TLS " + iWrite + " bytes from outNetBuffer(PAYLOAD)");
                if (iWrite == -1) {
                    throw new IOException("TLS connection closed");
                }
                if (iWrite == 0) {
                    socketEntry.outNetBuffer.compact();
                    return;
                }
            }
            socketEntry.outNetBuffer.clear();
        }

        public void close() {
            this.stop = true;
            WorkerTask workerTask = TLSTM.this.server;
            if (workerTask != null) {
                workerTask.terminate();
            }
        }

        public Throwable getLastError() {
            return this.lastError;
        }

        @Override // org.snmp4j.util.WorkerTask
        public void interrupt() {
            this.stop = true;
            if (TLSTM.logger.isDebugEnabled()) {
                TLSTM.logger.debug("Interrupting worker task: " + ServerThread.class.getName());
            }
            this.selector.wakeup();
        }

        @Override // org.snmp4j.util.WorkerTask
        public void join() {
            if (TLSTM.logger.isDebugEnabled()) {
                TLSTM.logger.debug("Joining worker task: " + ServerThread.class.getName());
            }
        }

        @Override // java.lang.Runnable
        public void run() {
            SocketChannel channel;
            TcpAddress tcpAddress;
            SocketEntry socketEntry;
            while (!this.stop) {
                try {
                    try {
                        processQueues();
                        if (this.selector.select() <= 0) {
                            continue;
                        } else {
                            if (this.stop) {
                                break;
                            }
                            Iterator<SelectionKey> it = this.selector.selectedKeys().iterator();
                            while (it.hasNext()) {
                                try {
                                    SelectionKey next = it.next();
                                    it.remove();
                                    if (next.isAcceptable()) {
                                        TLSTM.logger.debug("Key is acceptable");
                                        Socket socket = ((ServerSocketChannel) next.channel()).accept().socket();
                                        channel = socket.getChannel();
                                        channel.configureBlocking(false);
                                        tcpAddress = new TcpAddress(socket.getInetAddress(), socket.getPort());
                                        socketEntry = TLSTM.this.new SocketEntry(tcpAddress, socket, false, null);
                                        socketEntry.addRegistration(this.selector, 1);
                                        TLSTM.this.sockets.put(tcpAddress, socketEntry);
                                        TLSTM.this.timeoutSocket(socketEntry);
                                        TransportStateEvent transportStateEvent = new TransportStateEvent(TLSTM.this, tcpAddress, 1, null);
                                        TLSTM.this.fireConnectionStateChanged(transportStateEvent);
                                        if (transportStateEvent.isCancelled()) {
                                            TLSTM.logger.warn("Incoming connection cancelled");
                                            socket.close();
                                            TLSTM.this.sockets.remove(tcpAddress);
                                            channel = null;
                                        }
                                    } else if (next.isWritable()) {
                                        TLSTM.logger.debug("Key is writable");
                                        tcpAddress = writeData(next, null);
                                        channel = null;
                                        socketEntry = null;
                                    } else if (next.isReadable()) {
                                        TLSTM.logger.debug("Key is readable");
                                        channel = (SocketChannel) next.channel();
                                        tcpAddress = new TcpAddress(channel.socket().getInetAddress(), channel.socket().getPort());
                                        socketEntry = null;
                                    } else {
                                        if (next.isConnectable()) {
                                            TLSTM.logger.debug("Key is connectable");
                                            connectChannel(next, null);
                                        }
                                        channel = null;
                                        tcpAddress = null;
                                        socketEntry = null;
                                    }
                                    if (channel != null) {
                                        TLSTM.logger.debug("Key is reading");
                                        try {
                                            readMessage(next, channel, tcpAddress, socketEntry);
                                        } catch (IOException e2) {
                                            TLSTM.logger.warn(e2);
                                            e2.printStackTrace();
                                            next.cancel();
                                            channel.close();
                                            TLSTM.this.fireConnectionStateChanged(new TransportStateEvent(TLSTM.this, tcpAddress, 2, e2));
                                        }
                                    }
                                } catch (CancelledKeyException unused) {
                                    if (TLSTM.logger.isDebugEnabled()) {
                                        TLSTM.logger.debug("Selection key cancelled, skipping it");
                                    }
                                } catch (NoSuchAlgorithmException e3) {
                                    TLSTM.logger.error("NoSuchAlgorithm while reading from server socket: " + e3.getMessage(), e3);
                                }
                            }
                        }
                    } catch (NullPointerException e4) {
                        e4.printStackTrace();
                        TLSTM.logger.warn("NullPointerException within select()?");
                        this.stop = true;
                    }
                    processPending();
                } catch (IOException e5) {
                    TLSTM.logger.error(e5);
                    this.lastError = e5;
                }
            }
            if (this.ssc != null) {
                this.ssc.close();
            }
            if (this.selector != null) {
                this.selector.close();
            }
            if (!this.stop) {
                this.stop = true;
                synchronized (TLSTM.this) {
                    TLSTM.this.server = null;
                }
            }
            if (TLSTM.logger.isDebugEnabled()) {
                TLSTM.logger.debug("Worker task finished: " + ServerThread.class.getName());
            }
        }

        /* JADX WARN: Code restructure failed: missing block: B:25:0x00af, code lost:
        
            if (r0 != 4) goto L34;
         */
        /*
            Code decompiled incorrectly, please refer to instructions dump.
            To view partially-correct add '--show-bad-code' argument
        */
        public boolean runDelegatedTasks(javax.net.ssl.SSLEngineResult r6, org.snmp4j.transport.TLSTM.SocketEntry r7) throws java.io.IOException {
            /*
                Method dump skipped, instruction units count: 274
                To view this dump add '--comments-level debug' option
            */
            throw new UnsupportedOperationException("Method not decompiled: org.snmp4j.transport.TLSTM.ServerThread.runDelegatedTasks(javax.net.ssl.SSLEngineResult, org.snmp4j.transport.TLSTM$SocketEntry):boolean");
        }

        public void sendMessage(Address address, byte[] bArr, TransportStateReference transportStateReference) throws IOException {
            Socket socket;
            SocketChannel socketChannelOpen;
            SocketEntry socketEntry = (SocketEntry) TLSTM.this.sockets.get(address);
            if (TLSTM.logger.isDebugEnabled()) {
                TLSTM.logger.debug("Looking up connection for destination '" + address + "' returned: " + socketEntry);
                TLSTM.logger.debug(TLSTM.this.sockets.toString());
            }
            if (socketEntry == null) {
                socket = null;
            } else {
                if (transportStateReference != null && transportStateReference.getSessionID() != null && !transportStateReference.getSessionID().equals(Long.valueOf(socketEntry.getSessionID()))) {
                    TLSTM.this.counterSupport.fireIncrementCounter(new CounterEvent(this, SnmpConstants.snmpTlstmSessionNoSessions));
                    throw new IOException("Session " + transportStateReference.getSessionID() + " not available");
                }
                socket = socketEntry.getSocket();
            }
            if (socket != null && !socket.isClosed() && socket.isConnected()) {
                if (TLSTM.this.matchingStateReferences(transportStateReference, socketEntry.tmStateReference)) {
                    socketEntry.addMessage(bArr);
                    synchronized (this.pending) {
                        this.pending.addFirst(socketEntry);
                    }
                    TLSTM.logger.debug("Waking up selector for new message");
                    this.selector.wakeup();
                    return;
                }
                TLSTM.logger.error("TransportStateReferences refNew=" + transportStateReference + ",refOld=" + socketEntry.tmStateReference + " do not match, message dropped");
                throw new IOException("Transport state reference does not match existing reference for this session/target");
            }
            if (TLSTM.logger.isDebugEnabled()) {
                TLSTM.logger.debug("Socket for address '" + address + "' is closed, opening it...");
            }
            synchronized (this.pending) {
                this.pending.remove(socketEntry);
            }
            try {
                InetSocketAddress inetSocketAddress = new InetSocketAddress(((TcpAddress) address).getInetAddress(), ((TcpAddress) address).getPort());
                if (socket == null || socket.isClosed()) {
                    socketChannelOpen = SocketChannel.open();
                    socketChannelOpen.configureBlocking(false);
                    socketChannelOpen.connect(inetSocketAddress);
                    TLSTM.this.counterSupport.fireIncrementCounter(new CounterEvent(this, SnmpConstants.snmpTlstmSessionOpens));
                } else {
                    socketChannelOpen = socket.getChannel();
                    socketChannelOpen.configureBlocking(false);
                    if (socketChannelOpen.isConnectionPending()) {
                        if (TLSTM.this.matchingStateReferences(transportStateReference, socketEntry.tmStateReference)) {
                            socketEntry.addMessage(bArr);
                            synchronized (this.pending) {
                                this.pending.add(socketEntry);
                            }
                            this.selector.wakeup();
                            return;
                        }
                        TLSTM.logger.error("TransportStateReferences refNew=" + transportStateReference + ",refOld=" + socketEntry.tmStateReference + " do not match, message dropped");
                        throw new IOException("Transport state reference does not match existing reference for this session/target");
                    }
                    socketChannelOpen.connect(inetSocketAddress);
                    TLSTM.this.counterSupport.fireIncrementCounter(new CounterEvent(this, SnmpConstants.snmpTlstmSessionOpens));
                }
                SocketEntry socketEntry2 = TLSTM.this.new SocketEntry((TcpAddress) address, socketChannelOpen.socket(), true, transportStateReference);
                socketEntry2.addMessage(bArr);
                TLSTM.this.sockets.put(address, socketEntry2);
                synchronized (this.pending) {
                    this.pending.add(socketEntry2);
                }
                this.selector.wakeup();
                TLSTM.logger.debug("Trying to connect to " + address);
            } catch (IOException e2) {
                TLSTM.logger.error(e2);
                throw e2;
            } catch (NoSuchAlgorithmException e3) {
                TLSTM.logger.error("NoSuchAlgorithmException while sending message to " + address + ": " + e3.getMessage(), e3);
            }
        }

        @Override // org.snmp4j.util.WorkerTask
        public void terminate() {
            this.stop = true;
            if (TLSTM.logger.isDebugEnabled()) {
                TLSTM.logger.debug("Terminated worker task: " + ServerThread.class.getName());
            }
        }
    }

    class SocketEntry {
        private boolean handshakeFinished;
        private ByteBuffer inAppBuffer;
        private ByteBuffer inNetBuffer;
        private ByteBuffer outAppBuffer;
        private ByteBuffer outNetBuffer;
        private TcpAddress peerAddress;
        private long sessionID;
        private Socket socket;
        private SSLEngine sslEngine;
        private TransportStateReference tmStateReference;
        private LinkedList<byte[]> message = new LinkedList<>();
        private volatile int registrations = 0;
        private final Object outboundLock = new Object();
        private final Object inboundLock = new Object();
        private long lastUse = System.nanoTime();

        public SocketEntry(TcpAddress tcpAddress, Socket socket, boolean z, TransportStateReference transportStateReference) throws NoSuchAlgorithmException {
            this.inAppBuffer = ByteBuffer.allocate(TLSTM.this.getMaxInboundMessageSize());
            this.inNetBuffer = ByteBuffer.allocate(TLSTM.this.getMaxInboundMessageSize());
            this.outNetBuffer = ByteBuffer.allocate(TLSTM.this.getMaxInboundMessageSize());
            this.peerAddress = tcpAddress;
            this.tmStateReference = transportStateReference;
            this.socket = socket;
            if (transportStateReference == null) {
                TLSTM.this.counterSupport.fireIncrementCounter(new CounterEvent(this, SnmpConstants.snmpTlstmSessionAccepts));
            }
            SSLEngine sSLEngineCreateSSLEngine = TLSTM.this.sslEngineConfigurator.getSSLContext(z, transportStateReference).createSSLEngine(tcpAddress.getInetAddress().getHostName(), tcpAddress.getPort());
            this.sslEngine = sSLEngineCreateSSLEngine;
            sSLEngineCreateSSLEngine.setUseClientMode(z);
            TLSTM.this.sslEngineConfigurator.configure(this.sslEngine);
            synchronized (TLSTM.this) {
                this.sessionID = TLSTM.access$308(TLSTM.this);
            }
        }

        public synchronized void addMessage(byte[] bArr) {
            this.message.add(bArr);
        }

        public synchronized void addRegistration(Selector selector, int i2) throws ClosedChannelException {
            if ((this.registrations & i2) == 0) {
                this.registrations |= i2;
                if (TLSTM.logger.isDebugEnabled()) {
                    TLSTM.logger.debug("Adding operation " + i2 + " for: " + toString());
                }
                this.socket.getChannel().register(selector, this.registrations, this);
            } else if (!this.socket.getChannel().isRegistered()) {
                this.registrations = i2;
                if (TLSTM.logger.isDebugEnabled()) {
                    TLSTM.logger.debug("Registering new operation " + i2 + " for: " + toString());
                }
                this.socket.getChannel().register(selector, i2, this);
            }
        }

        public void checkTransportStateReference() {
            TransportStateReference transportStateReference = this.tmStateReference;
            if (transportStateReference != null) {
                if (transportStateReference.getTransportSecurityLevel().equals(SecurityLevel.undefined)) {
                    this.tmStateReference.setTransportSecurityLevel(SecurityLevel.authPriv);
                    return;
                }
                return;
            }
            TLSTM tlstm = TLSTM.this;
            TcpAddress tcpAddress = this.peerAddress;
            OctetString octetString = new OctetString();
            SecurityLevel securityLevel = SecurityLevel.authPriv;
            this.tmStateReference = new TransportStateReference(tlstm, tcpAddress, octetString, securityLevel, securityLevel, true, Long.valueOf(this.sessionID));
            OctetString securityName = null;
            if (TLSTM.this.securityCallback != null) {
                try {
                    securityName = TLSTM.this.securityCallback.getSecurityName((X509Certificate[]) this.sslEngine.getSession().getPeerCertificates());
                } catch (SSLPeerUnverifiedException e2) {
                    TLSTM.logger.error("SSL peer '" + this.peerAddress + "' is not verified: " + e2.getMessage(), e2);
                    this.sslEngine.setEnableSessionCreation(false);
                }
            }
            this.tmStateReference.setSecurityName(securityName);
        }

        public void closeSession() {
            SSLEngineResult sSLEngineResultSendNetMessage;
            this.sslEngine.closeOutbound();
            TLSTM.this.counterSupport.fireIncrementCounter(new CounterEvent(this, SnmpConstants.snmpTlstmSessionServerCloses));
            do {
                try {
                    sSLEngineResultSendNetMessage = TLSTM.this.sendNetMessage(this);
                    if (sSLEngineResultSendNetMessage.getStatus() == SSLEngineResult.Status.CLOSED) {
                        return;
                    }
                } catch (IOException e2) {
                    TLSTM.logger.error("IOException while closing outbound channel of " + this + ": " + e2.getMessage(), e2);
                    return;
                }
            } while (sSLEngineResultSendNetMessage.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_WRAP);
        }

        public ByteBuffer getInAppBuffer() {
            return this.inAppBuffer;
        }

        public ByteBuffer getInNetBuffer() {
            return this.inNetBuffer;
        }

        public long getLastUse() {
            return this.lastUse;
        }

        public ByteBuffer getOutNetBuffer() {
            return this.outNetBuffer;
        }

        public TcpAddress getPeerAddress() {
            return this.peerAddress;
        }

        public long getSessionID() {
            return this.sessionID;
        }

        public Socket getSocket() {
            return this.socket;
        }

        public synchronized boolean hasMessage() {
            return !this.message.isEmpty();
        }

        public boolean isAppOutPending() {
            boolean z;
            synchronized (this.outboundLock) {
                z = this.outAppBuffer != null && this.outAppBuffer.limit() > 0;
            }
            return z;
        }

        public boolean isHandshakeFinished() {
            return this.handshakeFinished;
        }

        public synchronized boolean isRegistered(int i2) {
            return (this.registrations & i2) == i2;
        }

        public synchronized byte[] nextMessage() {
            if (this.message.size() <= 0) {
                return null;
            }
            return this.message.removeFirst();
        }

        public synchronized void removeRegistration(Selector selector, int i2) throws ClosedChannelException {
            if ((this.registrations & i2) == i2) {
                this.registrations = (i2 ^ (-1)) & this.registrations;
                this.socket.getChannel().register(selector, this.registrations, this);
            }
        }

        public void setHandshakeFinished(boolean z) {
            this.handshakeFinished = z;
        }

        public void setInAppBuffer(ByteBuffer byteBuffer) {
            this.inAppBuffer = byteBuffer;
        }

        public void setInNetBuffer(ByteBuffer byteBuffer) {
            this.inNetBuffer = byteBuffer;
        }

        public void setOutNetBuffer(ByteBuffer byteBuffer) {
            this.outNetBuffer = byteBuffer;
        }

        public String toString() {
            return "SocketEntry[peerAddress=" + this.peerAddress + ",socket=" + this.socket + ",lastUse=" + new Date(this.lastUse / 1000000) + ",inNetBuffer=" + this.inNetBuffer + ",inAppBuffer=" + this.inAppBuffer + ",outNetBuffer=" + this.outNetBuffer + "]";
        }

        public void used() {
            this.lastUse = System.nanoTime();
        }
    }

    class SocketTimeout extends TimerTask {
        private SocketEntry entry;

        public SocketTimeout(SocketEntry socketEntry) {
            this.entry = socketEntry;
        }

        @Override // java.util.TimerTask
        public boolean cancel() {
            boolean zCancel = super.cancel();
            this.entry = null;
            return zCancel;
        }

        @Override // java.util.TimerTask, java.lang.Runnable
        public void run() {
            long jNanoTime = System.nanoTime();
            if (TLSTM.this.socketCleaner != null && (jNanoTime - this.entry.getLastUse()) / 1000000 < TLSTM.this.connectionTimeout) {
                long jCurrentTimeMillis = System.currentTimeMillis() + ((jNanoTime - this.entry.getLastUse()) / 1000000) + TLSTM.this.connectionTimeout;
                if (TLSTM.logger.isDebugEnabled()) {
                    TLSTM.logger.debug("Scheduling " + jCurrentTimeMillis);
                }
                TLSTM.this.socketCleaner.schedule(TLSTM.this.new SocketTimeout(this.entry), jCurrentTimeMillis);
                return;
            }
            if (TLSTM.logger.isDebugEnabled()) {
                TLSTM.logger.debug("Socket has not been used for " + (jNanoTime - this.entry.getLastUse()) + " milliseconds, closing it");
            }
            TLSTM.this.sockets.remove(this.entry.getPeerAddress());
            SocketEntry socketEntry = this.entry;
            try {
                synchronized (socketEntry) {
                    socketEntry.getSocket().close();
                }
                TLSTM.logger.info("Socket to " + socketEntry.getPeerAddress() + " closed due to timeout");
            } catch (IOException e2) {
                TLSTM.logger.error(e2);
            }
        }
    }

    public interface TLSTMTrustManagerFactory {
        X509TrustManager create(X509TrustManager x509TrustManager, boolean z, TransportStateReference transportStateReference);
    }

    protected class TlsTrustManager implements X509TrustManager {
        private TransportStateReference tmStateReference;
        X509TrustManager trustManager;
        private boolean useClientMode;

        protected TlsTrustManager(X509TrustManager x509TrustManager, boolean z, TransportStateReference transportStateReference) {
            this.trustManager = x509TrustManager;
            this.useClientMode = z;
            this.tmStateReference = transportStateReference;
        }

        private boolean isMatchingFingerprint(X509Certificate[] x509CertificateArr, OctetString octetString) {
            if (octetString != null && octetString.length() > 0) {
                for (X509Certificate x509Certificate : x509CertificateArr) {
                    OctetString fingerprint = TLSTM.getFingerprint(x509Certificate);
                    if (TLSTM.logger.isDebugEnabled()) {
                        TLSTM.logger.debug("Comparing certificate fingerprint " + fingerprint + " with " + octetString);
                    }
                    if (fingerprint == null) {
                        TLSTM.logger.error("Failed to determine fingerprint for certificate " + x509Certificate + " and algorithm " + x509Certificate.getSigAlgName());
                    } else if (fingerprint.equals(octetString)) {
                        if (!TLSTM.logger.isInfoEnabled()) {
                            return true;
                        }
                        TLSTM.logger.info("Peer is trusted by fingerprint '" + octetString + "' of certificate: '" + x509Certificate + "'");
                        return true;
                    }
                }
            }
            return false;
        }

        @Override // javax.net.ssl.X509TrustManager
        public void checkClientTrusted(X509Certificate[] x509CertificateArr, String str) throws CertificateException {
            TransportStateReference transportStateReference = this.tmStateReference;
            if (transportStateReference == null || transportStateReference.getCertifiedIdentity() == null || !isMatchingFingerprint(x509CertificateArr, this.tmStateReference.getCertifiedIdentity().getClientFingerprint())) {
                TlsTmSecurityCallback tlsTmSecurityCallback = TLSTM.this.securityCallback;
                if (!this.useClientMode && tlsTmSecurityCallback != null && tlsTmSecurityCallback.isClientCertificateAccepted(x509CertificateArr[0])) {
                    if (TLSTM.logger.isInfoEnabled()) {
                        TLSTM.logger.info("Client is trusted with certificate '" + x509CertificateArr[0] + "'");
                        return;
                    }
                    return;
                }
                try {
                    this.trustManager.checkClientTrusted(x509CertificateArr, str);
                } catch (CertificateException e2) {
                    TLSTM.this.counterSupport.fireIncrementCounter(new CounterEvent(this, SnmpConstants.snmpTlstmSessionOpenErrors));
                    TLSTM.this.counterSupport.fireIncrementCounter(new CounterEvent(this, SnmpConstants.snmpTlstmSessionInvalidClientCertificates));
                    TLSTM.logger.warn("Client certificate validation failed for '" + x509CertificateArr[0] + "'");
                    throw e2;
                }
            }
        }

        @Override // javax.net.ssl.X509TrustManager
        public void checkServerTrusted(X509Certificate[] x509CertificateArr, String str) throws CertificateException {
            X500Principal subjectX500Principal;
            if (this.tmStateReference.getCertifiedIdentity() == null || !isMatchingFingerprint(x509CertificateArr, this.tmStateReference.getCertifiedIdentity().getServerFingerprint())) {
                Object name = null;
                try {
                    name = TLSTM.getSubjAltName(x509CertificateArr[0].getSubjectAlternativeNames(), 2);
                } catch (CertificateParsingException unused) {
                    TLSTM.logger.error("CertificateParsingException while verifying server certificate " + Arrays.asList(x509CertificateArr));
                }
                if (name == null && (subjectX500Principal = x509CertificateArr[0].getSubjectX500Principal()) != null) {
                    name = subjectX500Principal.getName();
                }
                if (name != null) {
                    String lowerCase = ((String) name).toLowerCase();
                    String canonicalHostName = ((IpAddress) this.tmStateReference.getAddress()).getInetAddress().getCanonicalHostName();
                    if (lowerCase.length() > 0) {
                        if (lowerCase.charAt(0) == '*') {
                            canonicalHostName = canonicalHostName.substring(canonicalHostName.indexOf(46));
                            lowerCase = lowerCase.substring(1);
                        }
                        if (canonicalHostName.equalsIgnoreCase(lowerCase)) {
                            if (TLSTM.logger.isInfoEnabled()) {
                                TLSTM.logger.info("Peer hostname " + canonicalHostName + " matches dNSName " + lowerCase);
                                return;
                            }
                            return;
                        }
                    }
                    if (TLSTM.logger.isDebugEnabled()) {
                        TLSTM.logger.debug("Peer hostname " + canonicalHostName + " did not match dNSName " + lowerCase);
                    }
                }
                try {
                    this.trustManager.checkServerTrusted(x509CertificateArr, str);
                    TlsTmSecurityCallback tlsTmSecurityCallback = TLSTM.this.securityCallback;
                    if (!this.useClientMode || tlsTmSecurityCallback == null || tlsTmSecurityCallback.isServerCertificateAccepted(x509CertificateArr)) {
                        return;
                    }
                    TLSTM.logger.info("Server is NOT trusted with certificate '" + Arrays.asList(x509CertificateArr) + "'");
                    throw new CertificateException("Server's certificate is not trusted by this application (although it was trusted by the JRE): " + Arrays.asList(x509CertificateArr));
                } catch (CertificateException e2) {
                    TLSTM.this.counterSupport.fireIncrementCounter(new CounterEvent(this, SnmpConstants.snmpTlstmSessionOpenErrors));
                    TLSTM.this.counterSupport.fireIncrementCounter(new CounterEvent(this, SnmpConstants.snmpTlstmSessionUnknownServerCertificate));
                    TLSTM.logger.warn("Server certificate validation failed for '" + x509CertificateArr[0] + "'");
                    throw e2;
                }
            }
        }

        @Override // javax.net.ssl.X509TrustManager
        public X509Certificate[] getAcceptedIssuers() {
            TlsTmSecurityCallback tlsTmSecurityCallback = TLSTM.this.securityCallback;
            X509Certificate[] acceptedIssuers = this.trustManager.getAcceptedIssuers();
            if (acceptedIssuers == null || tlsTmSecurityCallback == null) {
                return acceptedIssuers;
            }
            ArrayList arrayList = new ArrayList(acceptedIssuers.length);
            for (X509Certificate x509Certificate : acceptedIssuers) {
                if (tlsTmSecurityCallback.isAcceptedIssuer(x509Certificate)) {
                    arrayList.add(x509Certificate);
                }
            }
            return (X509Certificate[]) arrayList.toArray(new X509Certificate[arrayList.size()]);
        }
    }

    public TLSTM() throws UnknownHostException {
        super(new TlsAddress(InetAddress.getLocalHost(), 0));
        this.sockets = new Hashtable();
        this.connectionTimeout = 60000L;
        this.serverEnabled = false;
        this.nextSessionID = 1L;
        this.sslEngineConfigurator = new DefaultSSLEngineConfiguration();
        this.trustManagerFactory = new DefaultTLSTMTrustManagerFactory(this, null);
        this.counterSupport = CounterSupport.getInstance();
        this.maxInboundMessageSize = MAX_TLS_PAYLOAD_SIZE;
    }

    static /* synthetic */ long access$308(TLSTM tlstm) {
        long j2 = tlstm.nextSessionID;
        tlstm.nextSessionID = 1 + j2;
        return j2;
    }

    /* JADX INFO: Access modifiers changed from: private */
    public void adjustInNetBuffer(SocketEntry socketEntry, SSLEngineResult sSLEngineResult) {
        if (sSLEngineResult.bytesConsumed() == socketEntry.inNetBuffer.limit()) {
            socketEntry.inNetBuffer.clear();
        } else if (sSLEngineResult.bytesConsumed() > 0) {
            socketEntry.inNetBuffer.compact();
        }
    }

    public static OctetString getFingerprint(X509Certificate x509Certificate) {
        try {
            String sigAlgName = x509Certificate.getSigAlgName();
            if (sigAlgName.contains("with")) {
                sigAlgName = sigAlgName.substring(0, sigAlgName.indexOf("with"));
            }
            MessageDigest messageDigest = MessageDigest.getInstance(sigAlgName);
            messageDigest.update(x509Certificate.getEncoded());
            return new OctetString(messageDigest.digest());
        } catch (NoSuchAlgorithmException e2) {
            logger.error("No such digest algorithm exception while getting fingerprint from " + x509Certificate + ": " + e2.getMessage(), e2);
            return null;
        } catch (CertificateEncodingException e3) {
            logger.error("Certificate encoding exception while getting fingerprint from " + x509Certificate + ": " + e3.getMessage(), e3);
            return null;
        }
    }

    public static Object getSubjAltName(Collection<List<?>> collection, int i2) {
        if (collection == null) {
            return null;
        }
        for (List<?> list : collection) {
            if (((Integer) list.get(0)).intValue() == i2) {
                return list.get(1);
            }
        }
        return null;
    }

    /* JADX INFO: Access modifiers changed from: private */
    public boolean matchingStateReferences(TransportStateReference transportStateReference, TransportStateReference transportStateReference2) {
        if (transportStateReference2 == null || transportStateReference == null) {
            logger.error("Failed to compare TransportStateReferences refNew=" + transportStateReference + ",refOld=" + transportStateReference2);
            return false;
        }
        if (transportStateReference.getSecurityName() != null && transportStateReference2.getSecurityName() != null) {
            return transportStateReference.getSecurityName().equals(transportStateReference2.getSecurityName());
        }
        logger.error("Could not match TransportStateReferences refNew=" + transportStateReference + ",refOld=" + transportStateReference2);
        return false;
    }

    /* JADX INFO: Access modifiers changed from: private */
    public SSLEngineResult sendNetMessage(SocketEntry socketEntry) throws IOException {
        synchronized (socketEntry.outboundLock) {
            if (!socketEntry.outNetBuffer.hasRemaining()) {
                return null;
            }
            SSLEngineResult sSLEngineResultWrap = socketEntry.sslEngine.wrap(ByteBuffer.allocate(0), socketEntry.outNetBuffer);
            socketEntry.outNetBuffer.flip();
            logger.debug("TLS outNetBuffer = " + socketEntry.outNetBuffer);
            socketEntry.socket.getChannel().write(socketEntry.outNetBuffer);
            socketEntry.outNetBuffer.clear();
            return sSLEngineResultWrap;
        }
    }

    /* JADX INFO: Access modifiers changed from: private */
    public synchronized void timeoutSocket(SocketEntry socketEntry) {
        if (this.connectionTimeout > 0) {
            this.socketCleaner.schedule(new SocketTimeout(socketEntry), this.connectionTimeout);
        }
    }

    public long getConnectionTimeout() {
        return this.connectionTimeout;
    }

    public CounterSupport getCounterSupport() {
        return this.counterSupport;
    }

    public String getKeyStore() {
        String str = this.keyStore;
        return str == null ? System.getProperty("javax.net.ssl.keyStore") : str;
    }

    public String getKeyStorePassword() {
        String str = this.keyStorePassword;
        return str == null ? System.getProperty("javax.net.ssl.keyStorePassword") : str;
    }

    public String getLocalCertificateAlias() {
        String str = this.localCertificateAlias;
        return str == null ? System.getProperty(SnmpConfigurator.P_TLS_LOCAL_ID, null) : str;
    }

    @Override // org.snmp4j.transport.AbstractTransportMapping, org.snmp4j.TransportMapping
    public int getMaxInboundMessageSize() {
        return super.getMaxInboundMessageSize();
    }

    @Override // org.snmp4j.transport.TcpTransportMapping, org.snmp4j.transport.ConnectionOrientedTransportMapping
    public MessageLengthDecoder getMessageLengthDecoder() {
        return null;
    }

    public TlsTmSecurityCallback<X509Certificate> getSecurityCallback() {
        return this.securityCallback;
    }

    @Override // org.snmp4j.transport.TcpTransportMapping, org.snmp4j.transport.AbstractTransportMapping, org.snmp4j.TransportMapping
    public Class<? extends Address> getSupportedAddressClass() {
        return TlsAddress.class;
    }

    public String getThreadName() {
        Object obj = this.server;
        if (obj != null) {
            return ((Thread) obj).getName();
        }
        return null;
    }

    public String[] getTlsProtocols() {
        String[] strArr = this.tlsProtocols;
        return strArr == null ? System.getProperty(SnmpConfigurator.P_TLS_VERSION, DEFAULT_TLSTM_PROTOCOLS).split(",") : strArr;
    }

    public TLSTMTrustManagerFactory getTrustManagerFactory() {
        return this.trustManagerFactory;
    }

    @Override // org.snmp4j.TransportMapping
    public boolean isListening() {
        return this.server != null;
    }

    public boolean isServerEnabled() {
        return this.serverEnabled;
    }

    @Override // org.snmp4j.transport.TcpTransportMapping, org.snmp4j.transport.AbstractTransportMapping, org.snmp4j.TransportMapping
    public synchronized void listen() throws IOException {
        if (this.server != null) {
            throw new SocketException("Port already listening");
        }
        try {
            this.serverThread = new ServerThread();
            this.server = SNMP4JSettings.getThreadFactory().createWorkerThread("TLSTM_" + getAddress(), this.serverThread, true);
            if (this.connectionTimeout > 0) {
                this.socketCleaner = SNMP4JSettings.getTimerFactory().createTimer();
            }
            this.server.run();
        } catch (NoSuchAlgorithmException e2) {
            throw new IOException("SSL not available: " + e2.getMessage(), e2);
        }
    }

    @Override // org.snmp4j.transport.TcpTransportMapping, org.snmp4j.transport.ConnectionOrientedTransportMapping
    public void setConnectionTimeout(long j2) {
        this.connectionTimeout = j2;
    }

    public void setKeyStore(String str) {
        this.keyStore = str;
    }

    public void setKeyStorePassword(String str) {
        this.keyStorePassword = str;
    }

    public void setLocalCertificateAlias(String str) {
        this.localCertificateAlias = str;
    }

    public void setMaxInboundMessageSize(int i2) {
        this.maxInboundMessageSize = i2;
    }

    @Override // org.snmp4j.transport.TcpTransportMapping, org.snmp4j.transport.ConnectionOrientedTransportMapping
    public void setMessageLengthDecoder(MessageLengthDecoder messageLengthDecoder) {
    }

    public void setSecurityCallback(TlsTmSecurityCallback<X509Certificate> tlsTmSecurityCallback) {
        this.securityCallback = tlsTmSecurityCallback;
    }

    public void setServerEnabled(boolean z) {
        this.serverEnabled = z;
    }

    protected void setSocketOptions(ServerSocket serverSocket) {
    }

    public void setThreadName(String str) {
        Object obj = this.server;
        if (obj instanceof Thread) {
            ((Thread) obj).setName(str);
        }
    }

    public void setTlsProtocols(String[] strArr) {
        this.tlsProtocols = strArr;
    }

    public void setTrustManagerFactory(TLSTMTrustManagerFactory tLSTMTrustManagerFactory) {
        if (tLSTMTrustManagerFactory == null) {
            throw null;
        }
        this.trustManagerFactory = tLSTMTrustManagerFactory;
    }

    @Override // org.snmp4j.transport.TcpTransportMapping, org.snmp4j.transport.AbstractTransportMapping, org.snmp4j.TransportMapping
    public void close() {
        Iterator<SocketEntry> it = this.sockets.values().iterator();
        while (it.hasNext()) {
            it.next().closeSession();
        }
        WorkerTask workerTask = this.server;
        if (workerTask != null) {
            workerTask.terminate();
            workerTask.interrupt();
            try {
                workerTask.join();
            } catch (InterruptedException e2) {
                logger.warn(e2);
            }
            this.server = null;
            for (SocketEntry socketEntry : this.sockets.values()) {
                Socket socket = socketEntry.getSocket();
                if (socket != null) {
                    try {
                        SocketChannel channel = socket.getChannel();
                        socket.close();
                        if (logger.isDebugEnabled()) {
                            logger.debug("Socket to " + socketEntry.getPeerAddress() + " closed");
                        }
                        if (channel != null) {
                            channel.close();
                            if (logger.isDebugEnabled()) {
                                logger.debug("Socket channel to " + socketEntry.getPeerAddress() + " closed");
                            }
                        }
                    } catch (IOException e3) {
                        logger.debug(e3);
                    }
                }
            }
            CommonTimer commonTimer = this.socketCleaner;
            if (commonTimer != null) {
                commonTimer.cancel();
            }
            this.socketCleaner = null;
        }
    }

    @Override // org.snmp4j.transport.TcpTransportMapping, org.snmp4j.transport.AbstractTransportMapping, org.snmp4j.TransportMapping
    public void sendMessage(TcpAddress tcpAddress, byte[] bArr, TransportStateReference transportStateReference) throws IOException {
        if (this.server == null) {
            listen();
        }
        this.serverThread.sendMessage(tcpAddress, bArr, transportStateReference);
    }

    public TLSTM(TlsAddress tlsAddress) throws IOException {
        super(tlsAddress);
        this.sockets = new Hashtable();
        this.connectionTimeout = 60000L;
        this.serverEnabled = false;
        this.nextSessionID = 1L;
        this.sslEngineConfigurator = new DefaultSSLEngineConfiguration();
        this.trustManagerFactory = new DefaultTLSTMTrustManagerFactory(this, null);
        this.maxInboundMessageSize = MAX_TLS_PAYLOAD_SIZE;
        this.serverEnabled = true;
        this.counterSupport = CounterSupport.getInstance();
        try {
            if (Class.forName("javax.net.ssl.X509ExtendedTrustManager") != null) {
                setTrustManagerFactory((TLSTMTrustManagerFactory) Class.forName("org.snmp4j.transport.tls.TLSTMExtendedTrustManagerFactory").getConstructors()[0].newInstance(this));
            }
        } catch (ClassNotFoundException unused) {
        } catch (IllegalAccessException e2) {
            throw new IOException("Failed to init TLSTMTrustManagerFactory: " + e2.getMessage(), e2);
        } catch (IllegalArgumentException e3) {
            throw new IOException("Failed to setup TLSTMTrustManagerFactory: " + e3.getMessage(), e3);
        } catch (InstantiationException e4) {
            throw new IOException("Failed to instantiate TLSTMTrustManagerFactory: " + e4.getMessage(), e4);
        } catch (InvocationTargetException e5) {
            throw new IOException("Failed to init TLSTMTrustManagerFactory: " + e5.getMessage(), e5);
        }
    }

    @Override // org.snmp4j.transport.ConnectionOrientedTransportMapping
    public synchronized boolean close(TcpAddress tcpAddress) throws IOException {
        if (logger.isDebugEnabled()) {
            logger.debug("Closing socket for peer address " + tcpAddress);
        }
        SocketEntry socketEntryRemove = this.sockets.remove(tcpAddress);
        if (socketEntryRemove == null) {
            return false;
        }
        if (socketEntryRemove.getSocket() != null) {
            SocketChannel channel = socketEntryRemove.getSocket().getChannel();
            socketEntryRemove.getSocket().close();
            if (logger.isInfoEnabled()) {
                logger.info("Socket to " + socketEntryRemove.getPeerAddress() + " closed");
            }
            if (channel != null) {
                channel.close();
                if (logger.isDebugEnabled()) {
                    logger.debug("Closed socket channel for peer address " + tcpAddress);
                }
            }
        }
        return true;
    }

    public TLSTM(TlsTmSecurityCallback<X509Certificate> tlsTmSecurityCallback, TlsAddress tlsAddress) throws IOException {
        this(tlsTmSecurityCallback, tlsAddress, CounterSupport.getInstance());
    }

    public TLSTM(TlsTmSecurityCallback<X509Certificate> tlsTmSecurityCallback, TlsAddress tlsAddress, CounterSupport counterSupport) throws IOException {
        super(tlsAddress);
        this.sockets = new Hashtable();
        this.connectionTimeout = 60000L;
        this.serverEnabled = false;
        this.nextSessionID = 1L;
        this.sslEngineConfigurator = new DefaultSSLEngineConfiguration();
        this.trustManagerFactory = new DefaultTLSTMTrustManagerFactory(this, null);
        this.maxInboundMessageSize = MAX_TLS_PAYLOAD_SIZE;
        this.serverEnabled = true;
        this.securityCallback = tlsTmSecurityCallback;
        this.counterSupport = counterSupport;
    }
}
