📄 tlsconn.java
字号:
if (Logging.SHOW_INFO && LOG.isLoggable(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 (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.log(Level.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 establishment, or TLS fragments to the remote TLS. * * @param msg 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 (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) { LOG.fine("Getting messenger for " + destAddr); } EndpointAddress realAddr = new EndpointAddress(destAddr, JTlsDefs.ServiceName, null); // Get a messenger. outBoundMessenger = transport.endpoint.getMessenger(realAddr); if (outBoundMessenger == null) { if (Logging.SHOW_SEVERE && LOG.isLoggable(Level.SEVERE)) { LOG.severe("Could not get messenger for " + realAddr); } return false; } } } if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) { LOG.fine("Sending " + msg + " to " + 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 (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) { LOG.log(Level.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 (Logging.SHOW_INFO && LOG.isLoggable(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 (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) { LOG.fine("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 (Logging.SHOW_WARNING && LOG.isLoggable(Level.WARNING)) { LOG.log(Level.WARNING, "I/O error while reading decrypted Message", iox); } break; } } } catch (Throwable all) { if (Logging.SHOW_SEVERE && LOG.isLoggable(Level.SEVERE)) { LOG.log(Level.SEVERE, "Uncaught Throwable in thread :" + Thread.currentThread().getName(), all); } } finally { workerThread = null; } if (Logging.SHOW_INFO && LOG.isLoggable(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) { for (String aKeyType : Arrays.asList(keyType)) { String result = checkTheOne(aKeyType, Arrays.asList(issuers)); if (null != result) { return result; } } return null; } /** * Checks to see if a peer that trusts the given issuers would trust the * special alias THE_ONE, returning it if so, and null otherwise. * * @param keyType the type of key a Certificate must use to be considered * @param issuers the issuers trusted by the other peer * @return "theone" if one of the Certificates in this peer's PSECredential's * Certificate chain matches the given keyType and one of the issuers, * or <code>null</code> */ private String checkTheOne(String keyType, Collection<java.security.Principal> allIssuers) { List<X509Certificate> certificates = Arrays.asList(cred.getCertificateChain()); for (X509Certificate certificate : certificates) { if (!certificate.getPublicKey().getAlgorithm().equals(keyType)) { continue; } if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) { LOG.fine("CHECKING: " + certificate.getIssuerX500Principal() + " in " + allIssuers); } if (allIssuers.contains(certificate.getIssuerX500Principal())) { return "theone"; } } 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.getIssuerX500Principal())) { 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 (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) { LOG.fine("Looking for : " + cred.getCertificate().getIssuerX500Principal()); LOG.fine("Issuers : " + allIssuers); java.security.Principal prin = cred.getCertificate().getIssuerX500Principal(); LOG.fine(" Principal Type :" + prin.getClass().getName()); Iterator it = allIssuers.iterator(); while (it.hasNext()) { java.security.Principal tmp = (java.security.Principal) it.next(); LOG.fine("Issuer Type : " + tmp.getClass().getName()); LOG.fine("Issuer value : " + tmp); LOG.fine("tmp.equals(prin) : " + tmp.equals(prin)); } } X509Certificate[] chain = cred.getCertificateChain(); for (X509Certificate aCert : Arrays.asList(chain)) { if (allIssuers.contains(aCert.getIssuerX500Principal())) { return new String[]{"theone"}; } } } } return null; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -