diff --git a/RISE-V2G-EVCC/src/main/java/org/eclipse/risev2g/evcc/session/V2GCommunicationSessionHandlerEVCC.java b/RISE-V2G-EVCC/src/main/java/org/eclipse/risev2g/evcc/session/V2GCommunicationSessionHandlerEVCC.java index 0ba8953..7cbe29a 100644 --- a/RISE-V2G-EVCC/src/main/java/org/eclipse/risev2g/evcc/session/V2GCommunicationSessionHandlerEVCC.java +++ b/RISE-V2G-EVCC/src/main/java/org/eclipse/risev2g/evcc/session/V2GCommunicationSessionHandlerEVCC.java @@ -51,7 +51,7 @@ public class V2GCommunicationSessionHandlerEVCC implements Observer { private Thread transportLayerThread; private StatefulTransportLayerClient transportLayerClient; - public V2GCommunicationSessionHandlerEVCC() { + public V2GCommunicationSessionHandlerEVCC() { setMessageHandler(new MessageHandler()); setSecurity( diff --git a/RISE-V2G-EVCC/src/main/java/org/eclipse/risev2g/evcc/transportLayer/TLSClient.java b/RISE-V2G-EVCC/src/main/java/org/eclipse/risev2g/evcc/transportLayer/TLSClient.java index 51ac2d9..5440ebc 100644 --- a/RISE-V2G-EVCC/src/main/java/org/eclipse/risev2g/evcc/transportLayer/TLSClient.java +++ b/RISE-V2G-EVCC/src/main/java/org/eclipse/risev2g/evcc/transportLayer/TLSClient.java @@ -20,6 +20,7 @@ import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import org.eclipse.risev2g.shared.enumerations.GlobalValues; +import org.eclipse.risev2g.shared.misc.TimeRestrictions; import org.eclipse.risev2g.shared.misc.V2GTPMessage; import org.eclipse.risev2g.shared.utils.SecurityUtils; @@ -78,7 +79,9 @@ public class TLSClient extends StatefulTransportLayerClient { GlobalValues.PASSPHRASE_FOR_CERTIFICATES_AND_KEYS.toString()); SSLSocketFactory sslSocketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault(); + getLogger().debug("Creating socket to TLS server ..."); setTlsSocketToServer((SSLSocket) sslSocketFactory.createSocket(host, port)); + getLogger().debug("TLS socket to server created"); setInStream(getTlsSocketToServer().getInputStream()); setOutStream(getTlsSocketToServer().getOutputStream()); @@ -95,7 +98,17 @@ public class TLSClient extends StatefulTransportLayerClient { String[] enabledProtocols = {"TLSv1.2"}; getTlsSocketToServer().setEnabledProtocols(enabledProtocols); + /* + * The communication session setup timeout needs to be set here in case there is any problem with the + * TLS handshake. + * The timeout value will be overwritten with every new message being sent + */ + getTlsSocketToServer().setSoTimeout(TimeRestrictions.V2G_EVCC_COMMUNICATION_SETUP_TIMEOUT); + + getLogger().debug("Starting TLS handshake ..."); getTlsSocketToServer().startHandshake(); + getLogger().debug("TLS handshake finished"); + Certificate[] seccCertificates = getTlsSocketToServer().getSession().getPeerCertificates(); X509Certificate seccLeafCertificate = (X509Certificate) seccCertificates[0]; @@ -116,11 +129,13 @@ public class TLSClient extends StatefulTransportLayerClient { getLogger().error("TLS client connection failed (UnknownHostException)!", e); } catch (SSLHandshakeException e) { getLogger().error("TLS client connection failed (SSLHandshakeException)", e); + } catch (SocketTimeoutException e) { + getLogger().fatal("TLS client connection failed (SocketTimeoutException) due to session setup timeout", e); } catch (IOException e) { getLogger().error("TLS client connection failed (IOException)!", e); } catch (NullPointerException e) { getLogger().fatal("NullPointerException while trying to set keystores, resource path to keystore/truststore might be incorrect"); - } + } return false; } diff --git a/RISE-V2G-SECC/src/main/java/org/eclipse/risev2g/secc/session/V2GCommunicationSessionHandlerSECC.java b/RISE-V2G-SECC/src/main/java/org/eclipse/risev2g/secc/session/V2GCommunicationSessionHandlerSECC.java index b0096a2..fef7c8a 100644 --- a/RISE-V2G-SECC/src/main/java/org/eclipse/risev2g/secc/session/V2GCommunicationSessionHandlerSECC.java +++ b/RISE-V2G-SECC/src/main/java/org/eclipse/risev2g/secc/session/V2GCommunicationSessionHandlerSECC.java @@ -123,42 +123,46 @@ public class V2GCommunicationSessionHandlerSECC implements Observer { private void processSECCDiscoveryReq(DatagramPacket udpClientPacket) { setV2gTpMessage(new V2GTPMessage(udpClientPacket.getData())); - if (getMessageHandler().isV2GTPMessageValid(getV2gTpMessage()) && - Arrays.equals(getV2gTpMessage().getPayloadType(), GlobalValues.V2GTP_PAYLOAD_TYPE_SDP_REQUEST_MESSAGE.getByteArrayValue())) { - - SECCDiscoveryReq seccDiscoveryReq = new SECCDiscoveryReq(getV2gTpMessage().getPayload()); - setSecurity(seccDiscoveryReq.getSecurity()); - getLogger().debug("SECCDiscoveryReq received"); - - /* - * The TCP and TLS server ports are created upon initialization of the TCP/TLS server and will - * remain the same for every connected EV. Only TCP or TLS are allowed as transport - * protocols for further communication beyond the SECCDiscoveryReq/-Res handshake (not UDP). - * - * One might implement further decision rules for dealing with the security level (TCP or TLS) - * requested by the EVCC (see also Table 3 and 4 of ISO/IEC 15118-2). For now, the requested - * security level of the EVCC will always be accepted. - */ - byte[] seccAddress = (isSecureCommunication()) ? TLSServer.getInstance().getServerAddress().getAddress() : TCPServer.getInstance().getServerAddress().getAddress(); - int seccPort = (isSecureCommunication()) ? TLSServer.getInstance().getServerPort() : TCPServer.getInstance().getServerPort(); - - SECCDiscoveryRes seccDiscoveryRes = new SECCDiscoveryRes( - seccAddress, - ByteUtils.toByteArrayFromInt(seccPort, true), - getSecurity(), - GlobalValues.V2G_TRANSPORT_PROTOCOL_TCP.getByteValue() - ); - - setV2gTpMessage(new V2GTPMessage(GlobalValues.V2GTP_VERSION_1_IS.getByteValue(), - GlobalValues.V2GTP_PAYLOAD_TYPE_SDP_RESPONSE_MESSAGE.getByteArrayValue(), - seccDiscoveryRes.getPayload())); - - getLogger().debug("Preparing to send SECCDiscoveryRes ..."); - - // The SECCDiscoveryRes must be sent via UDP before the requested TCP/TLS server can be used - UDPServer.getInstance().send(getV2gTpMessage(), (Inet6Address) udpClientPacket.getAddress(), udpClientPacket.getPort()); - } else { - getLogger().warn("Incoming DatagramPacket could not be identified as a SECCDiscoveryReq"); + try { + if (getMessageHandler().isV2GTPMessageValid(getV2gTpMessage()) && + Arrays.equals(getV2gTpMessage().getPayloadType(), GlobalValues.V2GTP_PAYLOAD_TYPE_SDP_REQUEST_MESSAGE.getByteArrayValue())) { + + SECCDiscoveryReq seccDiscoveryReq = new SECCDiscoveryReq(getV2gTpMessage().getPayload()); + setSecurity(seccDiscoveryReq.getSecurity()); + getLogger().debug("SECCDiscoveryReq received"); + + /* + * The TCP and TLS server ports are created upon initialization of the TCP/TLS server and will + * remain the same for every connected EV. Only TCP or TLS are allowed as transport + * protocols for further communication beyond the SECCDiscoveryReq/-Res handshake (not UDP). + * + * One might implement further decision rules for dealing with the security level (TCP or TLS) + * requested by the EVCC (see also Table 3 and 4 of ISO/IEC 15118-2). For now, the requested + * security level of the EVCC will always be accepted. + */ + byte[] seccAddress = (isSecureCommunication()) ? TLSServer.getInstance().getServerAddress().getAddress() : TCPServer.getInstance().getServerAddress().getAddress(); + int seccPort = (isSecureCommunication()) ? TLSServer.getInstance().getServerPort() : TCPServer.getInstance().getServerPort(); + + SECCDiscoveryRes seccDiscoveryRes = new SECCDiscoveryRes( + seccAddress, + ByteUtils.toByteArrayFromInt(seccPort, true), + getSecurity(), + GlobalValues.V2G_TRANSPORT_PROTOCOL_TCP.getByteValue() + ); + + setV2gTpMessage(new V2GTPMessage(GlobalValues.V2GTP_VERSION_1_IS.getByteValue(), + GlobalValues.V2GTP_PAYLOAD_TYPE_SDP_RESPONSE_MESSAGE.getByteArrayValue(), + seccDiscoveryRes.getPayload())); + + getLogger().debug("Preparing to send SECCDiscoveryRes ..."); + + // The SECCDiscoveryRes must be sent via UDP before the requested TCP/TLS server can be used + UDPServer.getInstance().send(getV2gTpMessage(), (Inet6Address) udpClientPacket.getAddress(), udpClientPacket.getPort()); + } else { + getLogger().warn("Incoming DatagramPacket could not be identified as a SECCDiscoveryReq"); + } + } catch (NullPointerException e) { + getLogger().error("NullPointerException occurred while processing SECCDiscoveryReq", e); } } diff --git a/RISE-V2G-SECC/src/main/java/org/eclipse/risev2g/secc/transportLayer/TCPServer.java b/RISE-V2G-SECC/src/main/java/org/eclipse/risev2g/secc/transportLayer/TCPServer.java index ae996a5..411aa70 100644 --- a/RISE-V2G-SECC/src/main/java/org/eclipse/risev2g/secc/transportLayer/TCPServer.java +++ b/RISE-V2G-SECC/src/main/java/org/eclipse/risev2g/secc/transportLayer/TCPServer.java @@ -31,7 +31,7 @@ public final class TCPServer extends StatefulTransportLayerServer { public boolean initialize() { super.initialize(); - + try { setTcpServerSocket(new ServerSocket(getServerPort(), 50, getServerAddress())); getLogger().debug("TCP server initialized at link-local address " + diff --git a/RISE-V2G-SECC/src/main/java/org/eclipse/risev2g/secc/transportLayer/TLSServer.java b/RISE-V2G-SECC/src/main/java/org/eclipse/risev2g/secc/transportLayer/TLSServer.java index ae4818c..0690121 100644 --- a/RISE-V2G-SECC/src/main/java/org/eclipse/risev2g/secc/transportLayer/TLSServer.java +++ b/RISE-V2G-SECC/src/main/java/org/eclipse/risev2g/secc/transportLayer/TLSServer.java @@ -50,7 +50,7 @@ public final class TLSServer extends StatefulTransportLayerServer { GlobalValues.SECC_KEYSTORE_FILEPATH.toString(), GlobalValues.SECC_TRUSTSTORE_FILEPATH.toString(), GlobalValues.PASSPHRASE_FOR_CERTIFICATES_AND_KEYS.toString()); - + SSLServerSocketFactory tlsServerSocketFactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); setTlsServerSocket((SSLServerSocket) tlsServerSocketFactory @@ -94,7 +94,7 @@ public final class TLSServer extends StatefulTransportLayerServer { getLogger().debug("TLS client connection with IP address " + getTlsClientSocket().getInetAddress().getHostAddress() + " and port " + getTlsClientSocket().getPort()); - + ConnectionHandler connectionHandler = new ConnectionHandler(tlsClientSocket); // Notify the V2GCommunicationSessionHandlerSECC about a newly connected TCP client Socket diff --git a/RISE-V2G-Shared/src/main/java/org/eclipse/risev2g/shared/enumerations/GlobalValues.java b/RISE-V2G-Shared/src/main/java/org/eclipse/risev2g/shared/enumerations/GlobalValues.java index b2d22c0..921bf2d 100644 --- a/RISE-V2G-Shared/src/main/java/org/eclipse/risev2g/shared/enumerations/GlobalValues.java +++ b/RISE-V2G-Shared/src/main/java/org/eclipse/risev2g/shared/enumerations/GlobalValues.java @@ -27,7 +27,7 @@ public enum GlobalValues { */ PASSPHRASE_FOR_CERTIFICATES_AND_KEYS("123456"), - // Aliases for contract certificate chain and OEM provisioning certficiate chain + // Aliases for contract certificate chain and OEM provisioning certificate chain ALIAS_CONTRACT_CERTIFICATE("contract_cert"), ALIAS_OEM_PROV_CERTIFICATE("oem_prov_cert"),