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