Commit dd203f30 authored by garciay's avatar garciay
Browse files

Bug fixed in message signature

Enhance Udp support 
parent d23f627a
package org.etsi.its.adapter;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;
import org.etsi.common.ByteHelper;
import org.etsi.its.adapter.UdpMultiplexer;
import org.etsi.its.adapter.layers.Layer;
public class UdpMultiplexer {
/**
* Parameter name for UDP port destination
*/
public static final String UDP_PORT_KEY = "Udport";
public String UdpAddress = "10.200.1.101"; // FIXME Use a generic way to retrieve UDP settings
public int UdpRecvPort = 18501; // FIXME Use a generic way to retrieve UDP settings
public int UdpSendPort = 18502; // FIXME Use a generic way to retrieve UDP settings
/**
* Unique instance of the factory
*/
private static final UdpMultiplexer instance = new UdpMultiplexer();
private Map<String, byte[]> clientsToMacs = new HashMap<String, byte[]>();
//private Map<String, Short> clientsToFrameTypes = new HashMap<String, Short>();
private HashMap<String, Layer> clientsToLayers = new HashMap<String, Layer>();
private DatagramSocket iutSocket;
private InetAddress iutAddress;
private int iutPort;
private Thread iutThread;
/**
* Gets the unique factory instance
* @return UdpMultiplexer instance
*/
public static UdpMultiplexer getInstance(){
return instance;
}
public UdpMultiplexer() {
}
public synchronized void register(Layer client, byte[] macAddress, short frameType) {
//TERFactory.getInstance().logDebug(">>>UdpMultiplexer.registering: " + frameType);
if(clientsToMacs.isEmpty()) {
try {
iutAddress = InetAddress.getByName(UdpAddress);
//TERFactory.getInstance().logDebug("UdpIpLayer.register: IUT Address: " + iutAddress.getHostAddress());
iutPort = UdpSendPort;
iutSocket = new DatagramSocket(UdpRecvPort);
iutThread = new UdpThread(iutSocket);
iutThread.start();
} catch (Exception e) {
e.printStackTrace();
}
}
// Register client
clientsToMacs.put(client.toString(), macAddress);
clientsToLayers.put(client.toString(), client);
//clientsToFrameTypes.put(client.toString(), frameType);
}
public synchronized void unregister(Layer client) {
if(clientsToMacs.containsKey(client.toString())) {
clientsToMacs.remove(client.toString());
//clientsToFrameTypes.remove(client.toString());
clientsToLayers.remove(client.toString());
if(clientsToMacs.isEmpty()) {
iutSocket.close();
iutThread.interrupt();
try {
iutThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public byte[] send(Layer client, byte[] dest, byte[] payload, Map<String, Object> params) {
if(clientsToMacs.containsKey(client.toString())) {
DatagramPacket packet = null;
if(params.containsKey(UDP_PORT_KEY)) {
packet = new DatagramPacket(payload, payload.length, iutAddress, Integer.parseInt((String) params.get(UDP_PORT_KEY)));
} else {
packet = new DatagramPacket(payload, payload.length, iutAddress, iutPort);
}
try {
iutSocket.send(packet);
return packet.getData();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
private class UdpThread extends Thread {
private DatagramSocket taSocket;
private boolean running = true;
public UdpThread(DatagramSocket taSocket) throws IOException {
this.taSocket = taSocket;
}
@Override
public void run() {
while(running) {
try {
byte[] buf = new byte[4096];
// receive packet
DatagramPacket packet = new DatagramPacket(buf, buf.length);
taSocket.receive(packet);
byte[] buffer = ByteHelper.extract(packet.getData(), packet.getOffset(), packet.getLength());
if(buffer.length < 28) {
continue;
}
Map<String, Object> lowerInfo = new HashMap<String, Object>();
lowerInfo.put(Layer.RECEPTION_TIMESTAMP, System.currentTimeMillis());
// Dispatch
for (String mapKey : clientsToMacs.keySet()) {
clientsToLayers.get(mapKey).receive(buffer, lowerInfo);
}
} catch (IOException e) {
running = false;
}
}
}
}
}
......@@ -133,7 +133,7 @@ public class CommsigniaLayer extends Layer implements IEthernetSpecific {
*/
@Override
public void receive(byte[] message, Map<String, Object> lowerInfo) {
TERFactory.getInstance().logDebug(">>> CommsigniaLayer.receive: " + ByteHelper.byteArrayToString(message));
//TERFactory.getInstance().logDebug(">>> CommsigniaLayer.receive: " + ByteHelper.byteArrayToString(message));
if (message.length <= 20+8+29+26) { // TODO To be refine
// Skip it
......
......@@ -388,7 +388,7 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific {
//TERFactory.getInstance().logDebug("GnLayer.receive: payload=" + ByteHelper.byteArrayToString(payload));
byte[] commonHdr = new byte[8];
System.arraycopy(payload, 0, commonHdr, 0, 8);
//TERFactory.getInstance().logDebug("GnLayer.receive: commonHdr=" + ByteHelper.byteArrayToString(commonHdr));
//TERFactory.getInstance().logDebug("GnLayer.receive: commonHdr=" + ByteHelper.byteArrayToString(commonHdr));
nextHeader = (byte)((commonHdr[0] & (byte)0xF0) >> 4);
int trafficClass = (int)(commonHdr[2]);
......@@ -400,7 +400,7 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific {
byte[] pl = new byte[2];
System.arraycopy(commonHdr, 4, pl , 0, 2);
int payloadLength = ByteHelper.byteArrayToInt(pl);
System.out.println("GnLayer.receive: Message payload length=" + payloadLength);
//TERFactory.getInstance().logDebug("GnLayer.receive: Message payload length=" + payloadLength);
if(headerType == HT_LS) {
// Process LS messages
......@@ -788,11 +788,8 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific {
byte[] toBeSent = null;
try {
// Calculate the hash
byte[] hash = CryptoLib.hashWithSha256(toBeSignedData);
//TERFactory.getInstance().logDebug("GnLayer.createSecuredMessage: hash=" + ByteHelper.byteArrayToString(hash));
// Signed the hash
byte[] signatureBytes = CryptoLib.signWithEcdsaNistp256WithSha256(hash, management.getSigningPrivateKey());
// Signed the data
byte[] signatureBytes = CryptoLib.signWithEcdsaNistp256WithSha256(toBeSignedData, management.getSigningPrivateKey());
//TERFactory.getInstance().logDebug("GnLayer.createSecuredMessage: signatureBytes=" + ByteHelper.byteArrayToString(signatureBytes));
// Add signature
toBeSent = ByteHelper.concat(
......
......@@ -41,6 +41,7 @@ public class LayerFactory {
layers.put("G5", G5Layer.class);
layers.put("ETH", EthernetLayer.class);
layers.put("UdpIp", UdpIpLayer.class);
layers.put("UdpIpCSG", UdpIpCommsigniaLayer.class);
layers.put("CSG", CommsigniaLayer.class);
// layers.put("Loopback", LoopbackLayer.class);
......
package org.etsi.its.adapter.layers;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import org.etsi.common.ByteHelper;
import org.etsi.its.adapter.IManagementLayers;
import org.etsi.its.adapter.UdpMultiplexer;
public class UdpIpCommsigniaLayer extends UdpIpLayer {
private static String UdpAddress = "80.98.62.165"; //"10.200.1.101"; // FIXME Use a generic way to retrieve UDP settings
private static int UdpRecvPort = 18501; // FIXME Use a generic way to retrieve UDP settings
private static int UdpSendPort = 18502; // FIXME Use a generic way to retrieve UDP settings
private Map<String, Short> clientsToFrameTypes = new HashMap<String, Short>();
public UdpIpCommsigniaLayer(IManagementLayers management, Stack<String> lowerStack) {
super(management, lowerStack);
UdpMultiplexer.getInstance().UdpAddress = UdpAddress;
UdpMultiplexer.getInstance().UdpRecvPort = UdpRecvPort;
UdpMultiplexer.getInstance().UdpSendPort = UdpSendPort;
}
/* (non-Javadoc)
* @see org.etsi.its.adapter.layers.Layer#register(org.etsi.its.adapter.layers.Layer)
*/
@Override
public void register(Layer upperLayer) {
if(registeredUpperLayer == null) {
super.register(upperLayer);
// Workaround for Commsignia CAM send module
Map<String, Object> lowerInfo = new HashMap<String, Object>();
lowerInfo.put(UdpMultiplexer.getInstance().UDP_PORT_KEY, new Integer(UdpRecvPort).toString());
super.send(new byte[] { (byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA }, lowerInfo);
} else {
super.register(upperLayer);
}
clientsToFrameTypes.put(this.toString(), upperLayerFrameType);
}
/* (non-Javadoc)
* @see org.etsi.its.adapter.layers.Layer#unregister(org.etsi.its.adapter.layers.Layer)
*/
@Override
public void unregister(Layer upperLayer) {
super.unregister(upperLayer);
clientsToFrameTypes.remove(this.toString(), upperLayerFrameType);
}
/* (non-Javadoc)
* @see org.etsi.its.adapter.layers.Layer#send(byte[], java.util.Map)
*/
@Override
public boolean send(byte[] message, Map<String, Object> params) {
//TERFactory.getInstance().logDebug("UdpIpLayer.send: " + ByteHelper.byteArrayToString(message));
byte[] dst = (byte[])params.get(LINK_LAYER_DESTINATION);
if(dst == null) {
dst = MAC_BROADCAST;
}
byte[] buffer = ByteHelper.concat(
new byte[] { (byte) 0xe0 },
localMacAddress,
dst,
ByteHelper.intToByteArray(message.length, Short.SIZE / Byte.SIZE) ,
message
);
return super.send(buffer, params);
}
public void receive(byte[] message, Map<String, Object> lowerInfo) {
//TERFactory.getInstance().logDebug(">>> UdpIpLayer.run: Receive packet from " + packet.getSocketAddress() + "/" + packet.getPort());
if (message.length < 36) {
// Skip it
return;
}
ByteBuffer byteBuffer = ByteBuffer.wrap(message);
//TERFactory.getInstance().logDebug("UdpIpLayer.run: Receive packet from " + ByteHelper.byteArrayToString(byteBuffer.array()));
// Skip IEEE 802.11L Layer: 88 00 00 00 00
byteBuffer.position(4);
// Extract Dst
byte[] dst = new byte[6];
byteBuffer.get(dst, 0, dst.length);
lowerInfo.put(EthernetLayer.LINK_LAYER_DESTINATION, dst);
// Skip Src
byteBuffer.position(byteBuffer.position() + 6);
// Skip LLC header
byteBuffer.position(byteBuffer.position() + 16);
// Extract FrameType info
byte[] rawFrameType = new byte[2];
byteBuffer.get(rawFrameType, 0, rawFrameType.length);
short frameType = ByteHelper.byteArrayToInt(rawFrameType).shortValue();
if (clientsToFrameTypes.containsKey(this.toString())) {
if(frameType == clientsToFrameTypes.get(this.toString())) {
if(Arrays.equals(dst, MAC_BROADCAST) || Arrays.equals(dst, localMacAddress)) {
if(registeredUpperLayer != null) {
// Extract Data
byte[] data = new byte[byteBuffer.remaining() - 4]; // Remove CRC added by the device
byteBuffer.get(data, 0, byteBuffer.remaining() - 4);
registeredUpperLayer.receive(data, lowerInfo);
}
}
}
}
}
}
/**
* Implementation of Udp layer using jpcap (background thread)
*
* @author ETSI / STF424
* @version $URL: https://forge.etsi.org/svn/ITS/branches/STF517/javasrc/adapter/org/etsi/its/adapter/layers/UdpIpLayer.java $
* $Id: UdpIpLayer.java 2518 2016-09-02 05:27:47Z garciay $
*
*/
package org.etsi.its.adapter.layers;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.HashMap;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Stack;
import org.etsi.common.ByteHelper;
import org.etsi.adapter.TERFactory;
import org.etsi.its.adapter.IManagementLayers;
import org.etsi.its.adapter.UdpMultiplexer;
/**
* Implementation of Udp layer using jpcap (background thread)
*/
public class UdpIpLayer extends Layer {
/**
* Well-known Udp broadcast address
*/
public static byte[] MAC_BROADCAST = new byte[]{(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF};
/**
* Parameter name for Link-Layer destination
*/
public static final String LINK_LAYER_DESTINATION = "LinkLayerDestination";
/**
* Constructor
* @param management Layer management instance
* @param lowerStack Lower protocol stack
*/
public UdpIpLayer(IManagementLayers management, Stack<String> lowerStack) {
super(management, lowerStack);
}
/* (non-Javadoc)
* @see org.etsi.its.adapter.layers.Layer#send(byte[], java.util.Map)
*/
@Override
public boolean send(byte[] message, Map<String, Object> params) {
DatagramPacket packet = new DatagramPacket(message, message.length, iutAddress, iutPort);
try {
iutSocket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
/* (non-Javadoc)
* @see org.etsi.its.adapter.layers.Layer#register(org.etsi.its.adapter.layers.Layer)
*/
......@@ -40,65 +47,64 @@ public class UdpIpLayer extends Layer {
public void register(Layer upperLayer) {
if(registeredUpperLayer == null) {
super.register(upperLayer);
try {
iutAddress = InetAddress.getByName("127.0.0.1");
//TERFactory.getInstance().logDebug("IUT Address: " + iutAddress.getHostAddress());
iutPort = 3750;
iutSocket = new DatagramSocket(3751);
iutThread = new UdpThread(iutSocket);
iutThread.start();
} catch (Exception e) {
Method getEthernetType = registeredUpperLayer.getClass().getMethod("getEthernetType", (Class<?>[])null);
if (getEthernetType != null) {
upperLayerFrameType = (Short) getEthernetType.invoke(registeredUpperLayer, (Object[]) null);
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
localMacAddress = management.getLinkLayerAddress();
UdpMultiplexer.getInstance().register(this, localMacAddress, upperLayerFrameType);
}
}
/* (non-Javadoc)
* @see org.etsi.its.adapter.layers.Layer#unregister(org.etsi.its.adapter.layers.Layer)
* @see org.etsi.its.adapter.layers.Layer#send(byte[], java.util.Map)
*/
@Override
public void unregister(Layer upperLayer) {
iutSocket.close();
iutThread.interrupt();
try {
iutThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
public boolean send(byte[] message, Map<String, Object> params) {
byte[] dst = (byte[])params.get(LINK_LAYER_DESTINATION);
if(dst == null) {
dst = MAC_BROADCAST;
}
super.unregister(upperLayer);
byte[] sent = UdpMultiplexer.getInstance().send(this, dst, message, params);
return super.send(sent, params);
}
private DatagramSocket iutSocket;
private InetAddress iutAddress;
private int iutPort;
private Thread iutThread;
private class UdpThread extends Thread {
private DatagramSocket taSocket;
private boolean running = true;
/* (non-Javadoc)
* @see org.etsi.its.adapter.layers.Layer#unregister(org.etsi.its.adapter.layers.Layer)
*/
@Override
public void unregister(Layer upperLayer) {
public UdpThread(DatagramSocket taSocket) throws IOException {
this.taSocket = taSocket;
}
@Override
public void run() {
while(running) {
try {
byte[] buf = new byte[4096];
Map<String, Object> lowerInfo = new HashMap<String, Object>();
// receive packet
DatagramPacket packet = new DatagramPacket(buf, buf.length);
taSocket.receive(packet);
lowerInfo.put(Layer.RECEPTION_TIMESTAMP, System.currentTimeMillis());
receive(ByteHelper.extract(packet.getData(), packet.getOffset(), packet.getLength()), lowerInfo);
} catch (IOException e) {
running = false;
}
}
}
UdpMultiplexer.getInstance().unregister(this);
}
/**
* Local Udp address
*/
protected byte[] localMacAddress;
/**
* Upper layer's frame type
*/
protected short upperLayerFrameType;
}
......@@ -232,14 +232,11 @@ public class GnPort extends ProtocolPort implements Runnable, IEthernetSpecific
private byte[] signSecuredMessage(final byte[] p_toBeSignedData) {
//TERFactory.getInstance().logDebug("GnPort.signSecuredMessage: toBeSignedData: " + ByteHelper.byteArrayToString(p_toBeSignedData));
// Calculate the hash
byte[] hash = CryptoLib.hashWithSha256(p_toBeSignedData);
//TERFactory.getInstance().logDebug("GnPort.signSecuredMessage: hash=" + ByteHelper.byteArrayToString(hash));
byte[] securedBeaconHeader = null;
// Signed the hash
// Signed the data
byte[] signatureBytes;
try {
signatureBytes = CryptoLib.signWithEcdsaNistp256WithSha256(hash, management.getSigningPrivateKey());
signatureBytes = CryptoLib.signWithEcdsaNistp256WithSha256(p_toBeSignedData, management.getSigningPrivateKey());
// //TERFactory.getInstance().logDebug("GnPort.signSecuredMessage: signatureBytes=" + ByteHelper.byteArrayToString(signatureBytes));
// Add signature
securedBeaconHeader = ByteHelper.concat(
......
package org.etsi.ttcn.codec.its.btp;
import org.etsi.ttcn.codec.CodecBuffer;
import org.etsi.ttcn.codec.MainCodec;
import org.etsi.ttcn.codec.generic.Union;
import org.etsi.ttcn.tci.Type;
import org.etsi.ttcn.tci.UnionValue;
import org.etsi.ttcn.tci.Value;
public class DecodedBtpPayload extends Union {
......
......@@ -88,13 +88,13 @@ public class Its_CodecProvider implements TciCDProvided, ChannelEventHandler, IT
e.printStackTrace();
}
} // End of 'for' loop
try { // This comes with 'with encode () "UpperTester"' for all UtxxxTrigger/UtxxxUpdate messages
_cf.setExternalCodec("per-basic-unaligned:1997", LibIts_asn1.class.newInstance());
} catch (InstantiationException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// TODO To be removed definitivelly
// try {
// _cf.setExternalCodec("per-basic-unaligned:1997", (TciCDProvided) Class.forName("org.etsi.its.tool.elvior.LibIts_asn1").newInstance());
// } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
// e.printStackTrace();
// }
}
public void run() {
......
# Debug level - Authorized values: OFF, ALL, INFO, SEVERE
DEBUG_ENABLED=ALL
DEBUG_ENABLED=OFF
# Define the port/layer configuration for CAM
camPort=BTP/GN/ETH
#camPort=BTP/GN/ETH
camPort=BTP/GN/UdpIpCSG
#camPort=BTP/GN/CSG
# Define the port/layer configuration for DENM
denmPort=BTP/GN/ETH
#denmPort=BTP/GN/ETH
denmPort=BTP/GN/UdpIpCSG
#denmPort=BTP/GN/CSG
# Define the port/layer configuration for MAPEM-SPATEM
mapemSpatemPort=BTP/GN/ETH
......@@ -18,7 +20,8 @@ sremSsemPort=BTP/GN/ETH
# Define the port/layer configuration for BTP
btpPort=GN/ETH
# Define the port/layer configuration for GeoNetworking
geoNetworkingPort=ETH
#geoNetworkingPort=ETH
geoNetworkingPort=UdpIpCSG
#geoNetworkingPort=CSG
# Define the port/layer configuration for GeoNetworking over IPv6
ipv6OverGeoNetworkingPort=Debug
......@@ -29,23 +32,34 @@ ipv6OverGeoNetworkingPort=Debug
#fsapPort=FSAP/UdpIp