📄 tlsconn.java
字号:
setHandshakeState(HandshakeState.HANDSHAKESTARTED); // this starts a handshake SSLSession newSession = ssls.getSession(); if("SSL_NULL_WITH_NULL_NULL".equals( newSession.getCipherSuite())) { setHandshakeState(HandshakeState.HANDSHAKEFAILED); throw new IOException("Handshake failed"); } setHandshakeState(HandshakeState.HANDSHAKEFINISHED); if (LOG.isEnabledFor(Level.INFO)) { long hsTime = TimeUtils.toRelativeTimeMillis(TimeUtils.timeNow(), startTime) / TimeUtils.ASECOND; LOG.info((client ? "Client:" : "Server:") + "Handshake DONE in " + hsTime + " secs"); } // set up plain text i/o // writes to be encrypted plaintext_out = new BufferedOutputStream(ssls.getOutputStream(), BOSIZE); // Start reader thread readerThread = new PlaintextMessageReader(ssls.getInputStream()); } /** * Close this connection. * * @param finalstate state that the connection will be in after close. **/ void close(HandshakeState finalstate) throws IOException { synchronized(lastAccessedLock) { lastAccessed = Long.MIN_VALUE; } synchronized(closeLock) { closing = true; if (LOG.isEnabledFor(Level.INFO)) { LOG.info("Shutting down " + this); } setHandshakeState(HandshakeState.CONNECTIONCLOSING); try { if (null != tlsSocket) { try { tlsSocket.close(); } catch (IOException ignored) { ; } } if (null != ssls) { try { ssls.close(); } catch (IOException ignored) { ; } ssls = null; } if (null != outBoundMessenger) { outBoundMessenger.close(); outBoundMessenger = null; } } catch (Throwable failed) { if (LOG.isEnabledFor(Level.INFO)) { LOG.info("Throwable during close " + this, failed); } IOException failure = new IOException("Throwable during close()"); failure.initCause(failed); } finally { closeLock.notifyAll(); closing = false; setHandshakeState(finalstate); } } } /** * Used by the TlsManager and the TlsConn in order to send a message, * either a TLS connection establishement, or TLS fragments to the remote TLS. * * @param message message to send to the remote TLS peer. * @return if true then message was sent, otherwise false. * @throws IOException if there was a problem sending the message. **/ boolean sendToRemoteTls(Message msg) throws IOException { synchronized (acquireMessengerLock) { if ((null == outBoundMessenger) || outBoundMessenger.isClosed()) { if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("Getting messenger for " + destAddr); } EndpointAddress realAddr = new EndpointAddress(destAddr, JTlsDefs.ServiceName, null); // Get a messenger. outBoundMessenger = transport.endpoint.getMessenger(realAddr); if (outBoundMessenger == null) { if (LOG.isEnabledFor(Level.ERROR)) { LOG.error("Could not get messenger for " + realAddr); } return false; } } } if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("Sending " + msg + " to endpoint " + destAddr); } // Good we have a messenger. Send the message. return outBoundMessenger.sendMessage(msg); } /** * sendMessage is called by the TlsMessenger each time a service or * an application sends a new message over a TLS connection. * IOException is thrown when something goes wrong. * * <p/>The message is encrypted by TLS ultimately calling * JTlsOutputStream.write(byte[], int, int); with the resulting TLS * Record(s). * * @param msg The plaintext message to be sent via this connection. * @throws IOException for errors in sending the message. **/ void sendMessage(Message msg) throws IOException { try { WireFormatMessage serialed = WireFormatMessageFactory.toWire(msg, JTlsDefs.MTYPE, (MimeMediaType[]) null); serialed.sendToStream(new IgnoreFlushFilterOutputStream(plaintext_out)); plaintext_out.flush(); } catch (IOException failed) { if (LOG.isEnabledFor(Level.INFO)) { LOG.info("Closing " + this + " due to exception ", failed); } close(HandshakeState.CONNECTIONDEAD); throw failed; } } /** * This is our message reader thread. This reads from the plaintext input * stream and dispatches messages received to the endpoint. **/ private class PlaintextMessageReader implements Runnable { InputStream ptin = null; Thread workerThread = null; public PlaintextMessageReader( InputStream ptin ) { this.ptin = ptin; // start our thread workerThread = new Thread( TlsConn.this.transport.myThreadGroup, this, "JXTA TLS Plaintext Reader for " + TlsConn.this.destAddr ); workerThread.setDaemon(true); workerThread.start(); if (LOG.isEnabledFor(Level.INFO)) { LOG.info("Started ReadPlaintextMessage thread for " + TlsConn.this.destAddr); } } /** * @inheritDoc **/ public void run() { try { while (true) { try { Message msg = WireFormatMessageFactory.fromWire(ptin, JTlsDefs.MTYPE, null ); if( null == msg ) { break; } // dispatch it to TlsTransport for demuxing if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("Dispatching " + msg + " to TlsTransport"); } TlsConn.this.transport.processReceivedMessage(msg); synchronized (TlsConn.this.lastAccessedLock) { TlsConn.this.lastAccessed = TimeUtils.timeNow(); // update idle timer } } catch (IOException iox) { if (LOG.isEnabledFor(Level.WARN)) { LOG.warn("I/O error while reading decrypted Message", iox); } break; } } } catch (Throwable all) { if (LOG.isEnabledFor(Level.FATAL)) { LOG.fatal("Uncaught Throwable in thread :" + Thread.currentThread().getName(), all); } } finally { workerThread = null; } if (LOG.isEnabledFor(Level.INFO)) { LOG.info("Finishing ReadPlaintextMessage thread"); } } } /** * A private key manager which selects based on the key and cert chain found * in a PSE Credential. * * <p/>TODO Promote this class to a full featured interface for all of the * active PSECredentials. Currently the alias "theone" is used to refer to * the **/ private static class PSECredentialKeyManager implements javax.net.ssl.X509KeyManager { PSECredential cred; KeyStore trusted; public PSECredentialKeyManager( PSECredential useCred, KeyStore trusted ) { this.cred = useCred; this.trusted = trusted; } /** * {@inheritDoc} **/ public String chooseClientAlias(String[] keyType, java.security.Principal[] issuers, java.net.Socket socket) { Iterator eachKeyType = Arrays.asList( keyType ).iterator(); while( eachKeyType.hasNext() ) { String aKeyType = (String) eachKeyType.next(); String result = chooseServerAlias( aKeyType, issuers, socket ); if( null != result ) { return result; } } return null; } /** * {@inheritDoc} **/ public String chooseServerAlias(String keyType, java.security.Principal[] issuers, java.net.Socket socket) { String [] available = getServerAliases( keyType, issuers ); if( null != available ) { return available[0]; } else { return null; } } /** * {@inheritDoc} **/ public X509Certificate[] getCertificateChain(String alias) { if( alias.equals( "theone" ) ) { return cred.getCertificateChain(); } else { try { return (X509Certificate[]) trusted.getCertificateChain( alias ); } catch( KeyStoreException ignored ) { return null; } } } /** * {@inheritDoc} **/ public String[] getClientAliases(String keyType, java.security.Principal[] issuers) { List clientAliases = new ArrayList(); try { Enumeration eachAlias = trusted.aliases(); Collection allIssuers = null; if( null != issuers ) { allIssuers = Arrays.asList( issuers ); } while( eachAlias.hasMoreElements() ) { String anAlias = (String) eachAlias.nextElement(); if( trusted.isCertificateEntry( anAlias ) ) { try { X509Certificate aCert = (X509Certificate) trusted.getCertificate( anAlias ); if( null == aCert ) { // strange... it should have been there... continue; } if( !aCert.getPublicKey().getAlgorithm().equals( keyType ) ) { continue; } if( null != allIssuers ) { if( allIssuers.contains(aCert.getIssuerDN()) ) { clientAliases.add( anAlias ); } } else { clientAliases.add( anAlias ); } } catch( KeyStoreException ignored ) { ; } } } } catch( KeyStoreException ignored ) { ; } return (String[]) clientAliases.toArray(new String[clientAliases.size()]); } /** * {@inheritDoc} **/ public java.security.PrivateKey getPrivateKey(String alias) { if( alias.equals( "theone" ) ) { return cred.getPrivateKey(); } else { return null; } } /** * {@inheritDoc} **/ public String[] getServerAliases(String keyType, java.security.Principal[] issuers) { if( keyType.equals( cred.getCertificate().getPublicKey().getAlgorithm() ) ) { if( null == issuers ) { return new String[] { "theone" }; } else { Collection allIssuers = Arrays.asList( issuers ); if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug( "Looking for : " + cred.getCertificate().getIssuerX500Principal() ); LOG.debug( "Issuers : " + allIssuers ); java.security.Principal prin = cred.getCertificate().getIssuerX500Principal(); LOG.debug( " Principal Type :" + prin.getClass().getName()); Iterator it = allIssuers.iterator(); while (it.hasNext()) { java.security.Principal tmp = (java.security.Principal) it.next(); LOG.debug( "Issuer Type : " + tmp.getClass().getName()); LOG.debug( "Issuer value : " + tmp); LOG.debug( "tmp.equals(prin) : " + tmp.equals(prin)); } } if( allIssuers.contains( cred.getCertificate().getIssuerX500Principal() ) ) { return new String[] { "theone" }; } else { return null; } } } else { return null; } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -