1
2
3
4
5
6
7 package org.mule.transport.ssl;
8
9 import org.mule.api.MuleMessage;
10 import org.mule.api.construct.FlowConstruct;
11 import org.mule.api.endpoint.InboundEndpoint;
12 import org.mule.api.lifecycle.CreateException;
13 import org.mule.api.transport.Connector;
14 import org.mule.config.i18n.CoreMessages;
15 import org.mule.transport.AbstractMessageReceiver;
16 import org.mule.transport.ConnectException;
17 import org.mule.transport.tcp.TcpMessageReceiver;
18 import org.mule.util.StringUtils;
19
20 import java.io.IOException;
21 import java.net.Socket;
22 import java.security.cert.Certificate;
23
24 import javax.net.ssl.HandshakeCompletedEvent;
25 import javax.net.ssl.HandshakeCompletedListener;
26 import javax.net.ssl.SSLPeerUnverifiedException;
27 import javax.net.ssl.SSLSocket;
28 import javax.resource.spi.work.Work;
29
30 import edu.emory.mathcs.backport.java.util.concurrent.CountDownLatch;
31 import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
32
33
34 public class SslMessageReceiver extends TcpMessageReceiver implements HandshakeCompletedListener
35 {
36
37
38
39
40
41 private CountDownLatch handshakeComplete = new CountDownLatch(1);
42
43 private Certificate[] peerCertificateChain;
44 private Certificate[] localCertificateChain;
45
46 public SslMessageReceiver(Connector connector, FlowConstruct flowConstruct, InboundEndpoint endpoint)
47 throws CreateException
48 {
49 super(connector, flowConstruct, endpoint);
50 }
51
52 @Override
53 protected void doConnect() throws ConnectException
54 {
55 checkKeyStore();
56 super.doConnect();
57 }
58
59 protected void checkKeyStore() throws ConnectException
60 {
61 SslConnector sslConnector = (SslConnector) connector;
62 String keyStore = sslConnector.getKeyStore();
63 if (StringUtils.isBlank(keyStore))
64 {
65 throw new ConnectException(CoreMessages.objectIsNull("tls-key-store"), this);
66 }
67 }
68
69 @Override
70 protected Work createWork(Socket socket) throws IOException
71 {
72 return new SslWorker(socket, this);
73 }
74
75 private void preRoute(MuleMessage message) throws Exception
76 {
77 long sslHandshakeTimeout = ((SslConnector) getConnector()).getSslHandshakeTimeout();
78 boolean rc = handshakeComplete.await(sslHandshakeTimeout, TimeUnit.MILLISECONDS);
79 if (rc == false)
80 {
81 throw new IllegalStateException("Handshake did not complete");
82 }
83
84 if (peerCertificateChain != null)
85 {
86 message.setOutboundProperty(SslConnector.PEER_CERTIFICATES, peerCertificateChain);
87 }
88 if (localCertificateChain != null)
89 {
90 message.setOutboundProperty(SslConnector.LOCAL_CERTIFICATES, localCertificateChain);
91 }
92 }
93
94 public void handshakeCompleted(HandshakeCompletedEvent event)
95 {
96 try
97 {
98 localCertificateChain = event.getLocalCertificates();
99 try
100 {
101 peerCertificateChain = event.getPeerCertificates();
102 }
103 catch (SSLPeerUnverifiedException e)
104 {
105 logger.debug("Cannot get peer certificate chain: "+ e.getMessage());
106 }
107 }
108 finally
109 {
110 handshakeComplete.countDown();
111 }
112 }
113
114 protected class SslWorker extends TcpWorker
115 {
116 public SslWorker(Socket socket, AbstractMessageReceiver receiver) throws IOException
117 {
118 super(socket, receiver);
119 ((SSLSocket) socket).addHandshakeCompletedListener(SslMessageReceiver.this);
120 }
121
122 @Override
123 protected void preRouteMuleMessage(MuleMessage message) throws Exception
124 {
125 super.preRouteMuleMessage(message);
126
127 preRoute(message);
128 }
129
130 @Override
131 protected void shutdownSocket() throws IOException
132 {
133
134 }
135 }
136
137 }