Commit 01097524 authored by garciay's avatar garciay

Merge with C2C project

Add AcSecPrimitive/AcSecResponse support for CAM (DENM & GN to be done)
parent 964ca145
......@@ -60,4 +60,15 @@ public interface ITERequired {
* @return Value associated to the TA parameter
*/
Value getTaParameter(String param);
/**
* Logs the debug message.
*/
void logDebug(String debugMessage);
/**
* Logs the error message.
*/
void logError(String errorMessage);
}
......@@ -12,6 +12,7 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Observer;
import org.etsi.adapter.TERFactory;
import org.etsi.common.ITuple;
import org.etsi.common.Tuple;
import org.etsi.its.adapter.ports.IObservable;
......@@ -58,7 +59,7 @@ public class ComponentMgr{
public void addComponent(TriComponentId component) {
// Sanity check
if(component == null) {
System.err.println("Error: Trying to add null component");
TERFactory.getInstance().logError("Error: Trying to add null component");
return;
}
......@@ -81,11 +82,11 @@ public class ComponentMgr{
public void addPort(final String componentName, final TriPortId ttcnPort, final IPort port) {
// Sanity checks
if(componentName.isEmpty() || (ttcnPort == null) || (port == null)) {
System.err.println("Wrong parameters");
TERFactory.getInstance().logError("Wrong parameters");
return;
}
if(!mapCompNameToTriComp.containsKey(componentName)) {
System.err.println("Error: Trying to add port to unknown component");
TERFactory.getInstance().logError("Error: Trying to add port to unknown component");
return;
}
if(!mapTriPortToTuple.containsKey(componentName)) {
......@@ -110,7 +111,7 @@ public class ComponentMgr{
// Sanity checks
if(componentName == null || componentName.isEmpty()) {
System.err.println("Invalid component");
TERFactory.getInstance().logError("Invalid component");
return null;
}
......@@ -127,15 +128,15 @@ public class ComponentMgr{
// Sanity checks
if(componentName.isEmpty() || portName.isEmpty()) {
System.err.println("Wrong parameters");
TERFactory.getInstance().logError("Wrong parameters");
return null;
}
if(!mapCompNameToTriComp.containsKey(componentName)) {
System.err.println("Unknown component");
TERFactory.getInstance().logError("Unknown component");
return null;
}
if(!mapTriPortToTuple.containsKey(componentName)) {
System.err.println("No port list entry");
TERFactory.getInstance().logError("No port list entry");
return null;
}
......@@ -160,15 +161,15 @@ public class ComponentMgr{
// Sanity checks
if(componentName.isEmpty() || portName.isEmpty()) {
System.err.println("Wrong parameters");
TERFactory.getInstance().logError("Wrong parameters");
return null;
}
if(!mapCompNameToTriComp.containsKey(componentName)) {
System.err.println("Unknown component");
TERFactory.getInstance().logError("Unknown component");
return null;
}
if(!mapTriPortToTuple.containsKey(componentName)) {
System.err.println("No port list entry");
TERFactory.getInstance().logError("No port list entry");
return null;
}
......@@ -204,15 +205,15 @@ public class ComponentMgr{
// Sanity checks
if(componentName.isEmpty() || portName.isEmpty()) {
System.err.println("Wrong parameters");
TERFactory.getInstance().logError("Wrong parameters");
return;
}
if(!mapCompNameToTriComp.containsKey(componentName)) {
System.err.println("Unknown component");
TERFactory.getInstance().logError("Unknown component");
return;
}
if(!mapTriPortToTuple.containsKey(componentName)) {
System.err.println("No port list entry");
TERFactory.getInstance().logError("No port list entry");
return;
}
......
......@@ -48,7 +48,7 @@ public class Management implements IManagementTA, IManagementLayers {
/**
* Maximum time for getting Long position vector (in seconds)
*/
private static final int GET_LPV_TIMEOUT = 10;
private static final int GET_LPV_TIMEOUT = 10; //FIXME: Might be a parameter rather than a constant
/**
* Interval for polling the location table during GetLpv (in ms)
......@@ -353,6 +353,8 @@ public class Management implements IManagementTA, IManagementLayers {
// Ensure that management settings are reset
beaconHeader = null;
enqueueBeacon = null;
locTable.clear();
}
@Override
......
......@@ -49,7 +49,7 @@ public class PcapMultiplexer implements Runnable {
int r = Pcap.findAllDevs(alldevs, errbuf);
if (r == Pcap.NOT_OK || alldevs.isEmpty()) {
System.err.printf("Can't read list of devices, error is %s", errbuf.toString());
TERFactory.getInstance().logError("Can't read list of devices, error is %s" + errbuf.toString());
return;
}
......@@ -72,7 +72,7 @@ public class PcapMultiplexer implements Runnable {
}
device = alldevs.get(ifaceIndex);
System.out.println("Listening: " + device.getName());
// TERFactory.getInstance().logDebug("Listening: " + device.getName());
}
/**
......@@ -84,7 +84,7 @@ public class PcapMultiplexer implements Runnable {
}
public synchronized void register(Layer client, byte[] macAddress, short frameType) {
System.out.println(">>>PcapMultiplexer.registering: " + frameType);
// TERFactory.getInstance().logDebug(">>>PcapMultiplexer.registering: " + frameType);
if(clientsToMacs.isEmpty()) {
// Open interface
......@@ -94,7 +94,7 @@ public class PcapMultiplexer implements Runnable {
pcap = Pcap.openLive(device.getName(), snaplen, flags, timeout, errbuf);
if (pcap == null) {
System.err.printf("Error while opening device for capture: "
TERFactory.getInstance().logError("Error while opening device for capture: "
+ errbuf.toString());
return;
}
......@@ -103,7 +103,7 @@ public class PcapMultiplexer implements Runnable {
filter = "";
}
else {
System.out.println("Another Client !");
// TERFactory.getInstance().logDebug("Another Client !");
filter = filter + " and ";
}
......@@ -114,7 +114,7 @@ public class PcapMultiplexer implements Runnable {
}
filter = filter + "not ether src " + strMacAddress;
System.out.println("New filter: " + filter);
// TERFactory.getInstance().logDebug("New filter: " + filter);
// Apply filter
PcapBpfProgram bpfFilter = new PcapBpfProgram();
......@@ -122,7 +122,7 @@ public class PcapMultiplexer implements Runnable {
int netmask = 0;
int r = pcap.compile(bpfFilter, filter, optimize, netmask);
if (r != Pcap.OK) {
System.out.println("Filter error: " + pcap.getErr());
// TERFactory.getInstance().logDebug("Filter error: " + pcap.getErr());
}
pcap.setFilter(bpfFilter);
......
......@@ -23,108 +23,108 @@ public class BtpLayer extends Layer {
/**
* Parameter name for BTP packet type
*/
public static final String BTP_TYPE = "BtpType";
public static final String BTP_TYPE = "BtpType";
/**
* Parameter name for BTP destination port
*/
public static final String BTP_DSTPORT = "BtpDstPort";
*/
public static final String BTP_DSTPORT = "BtpDstPort";
/**
* Parameter name for BTP source port
*/
public static final String BTP_SRCPORT = "BtpSrcPort";
*/
public static final String BTP_SRCPORT = "BtpSrcPort";
/**
* Parameter name for BTP destination port information
*/
public static final String BTP_DSTPORTINFO = "BtpDstPortInfo";
*/
public static final String BTP_DSTPORTINFO = "BtpDstPortInfo";
/**
* BTP packet type A
*/
public static final int TYPE_A = 0;
public static final int TYPE_A = 0;
/**
* BTP packet type B
*/
public static final int TYPE_B = 1;
*/
public static final int TYPE_B = 1;
/**
* Constructor
* @param management Layer management instance
* @param lowerStack Lower protocol stack
*/
public BtpLayer(IManagementLayers management, Stack<String> lowerStack) {
super(management, lowerStack);
}
public BtpLayer(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) {
// Destination Port (16 bits)
int dstPort;
try {
dstPort = (Integer)params.get(BTP_DSTPORT);
}
catch (NullPointerException e) {
dstPort = 0;
}
byte[] encapsulated = ByteHelper.intToByteArray(dstPort, 2);
if(params.get(BTP_TYPE).equals(TYPE_A)) {
// Source Port (16 bits)
int srcPort;
try {
srcPort = (Integer)params.get(BTP_SRCPORT);
}
catch (NullPointerException e) {
srcPort = 0;
}
encapsulated = ByteHelper.concat(encapsulated, ByteHelper.intToByteArray(srcPort, 2));
}
else {
// Destination port info (16 bits)
int dstPortInfo;
try {
dstPortInfo = (Integer)params.get(BTP_DSTPORTINFO);
}
catch (NullPointerException e) {
dstPortInfo = 0;
}
encapsulated = ByteHelper.concat(encapsulated, ByteHelper.intToByteArray(dstPortInfo, 2));
}
/* (non-Javadoc)
* @see org.etsi.its.adapter.layers.Layer#send(byte[], java.util.Map)
*/
@Override
public boolean send(byte[] message, Map<String, Object> params) {
// Destination Port (16 bits)
int dstPort;
try {
dstPort = (Integer)params.get(BTP_DSTPORT);
}
catch (NullPointerException e) {
dstPort = 0;
}
byte[] encapsulated = ByteHelper.intToByteArray(dstPort, 2);
if(params.get(BTP_TYPE).equals(TYPE_A)) {
// Source Port (16 bits)
int srcPort;
try {
srcPort = (Integer)params.get(BTP_SRCPORT);
}
catch (NullPointerException e) {
srcPort = 0;
}
encapsulated = ByteHelper.concat(encapsulated, ByteHelper.intToByteArray(srcPort, 2));
}
else {
// Destination port info (16 bits)
int dstPortInfo;
try {
dstPortInfo = (Integer)params.get(BTP_DSTPORTINFO);
}
catch (NullPointerException e) {
dstPortInfo = 0;
}
encapsulated = ByteHelper.concat(encapsulated, ByteHelper.intToByteArray(dstPortInfo, 2));
}
// Update params
// if(lowerLayerName != null && lowerLayerName.equals("GN")) {
// params.put(GnLayer.GN_NEXTHEADER, "BTP-A"); // TODO Alex to confirm removal
// }
return super.send(ByteHelper.concat(encapsulated, message), params);
}
/* (non-Javadoc)
* @see org.etsi.its.adapter.layers.Layer#receive(byte[])
*/
@Override
public void receive(byte[] message, Map<String, Object> lowerInfo) {
byte[] dstPort = new byte[2];
System.arraycopy(message, 0, dstPort, 0, 2);
byte[] srcPort = new byte[2];
System.arraycopy(message, 2, srcPort, 0, 2);
int payloadLength = message.length - 4;
byte[] payload = new byte[payloadLength];
System.arraycopy(message, 4, payload, 0, payloadLength);
// Update params
// if(lowerLayerName != null && lowerLayerName.equals("GN")) {
// params.put(GnLayer.GN_NEXTHEADER, "BTP-A"); // TODO Alex to confirm removal
// }
return super.send(ByteHelper.concat(encapsulated, message), params);
}
/* (non-Javadoc)
* @see org.etsi.its.adapter.layers.Layer#receive(byte[])
*/
@Override
public void receive(byte[] message, Map<String, Object> lowerInfo) {
byte[] dstPort = new byte[2];
System.arraycopy(message, 0, dstPort, 0, 2);
byte[] srcPort = new byte[2];
System.arraycopy(message, 2, srcPort, 0, 2);
int payloadLength = message.length - 4;
byte[] payload = new byte[payloadLength];
System.arraycopy(message, 4, payload, 0, payloadLength);
lowerInfo.put(BTP_DSTPORT, dstPort);
lowerInfo.put(BTP_DSTPORTINFO, srcPort);
super.receive(payload, lowerInfo);
}
super.receive(payload, lowerInfo);
}
}
......@@ -90,7 +90,7 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific {
* Parameter name for packet's lifetime
*/
public static final String GN_LIFETIME = "GnLifetime";
/**
* GeoNetworking header type for unknown messages
*/
......@@ -237,7 +237,7 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific {
*/
@Override
public boolean send(byte[] message, Map<String, Object> params) {
System.out.println(">>> GnLayer.send: " + ByteHelper.byteArrayToString(message));
// TERFactory.getInstance().logDebug(">>> GnLayer.send: " + ByteHelper.byteArrayToString(message));
byte [] extHdr = null;
int ht;
......@@ -299,7 +299,7 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific {
toBeSent = createSecuredMessage(basicHdr, commonHdr, extHdr, message);
}
System.out.println("<<< GnLayer.send: " + ByteHelper.byteArrayToString(toBeSent));
// TERFactory.getInstance().logDebug("<<< GnLayer.send: " + ByteHelper.byteArrayToString(toBeSent));
return super.send(toBeSent, params);
}
......@@ -308,7 +308,7 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific {
*/
@Override
public void receive(byte[] message, Map<String, Object> lowerInfo) {
System.out.println(">>> GnLayer.receive: " + ByteHelper.byteArrayToString(message));
// TERFactory.getInstance().logDebug(">>> GnLayer.receive: " + ByteHelper.byteArrayToString(message));
byte[] basicHdr = new byte[4];
System.arraycopy(message, 0, basicHdr, 0, 4);
......@@ -350,7 +350,7 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific {
params.put(GN_DEPV, depv);
params.put(GN_TYPE, HT_LS);
params.put(GN_SUBTYPE, HST_LSREPLY);
System.out.println("GnLayer.receive: Send LS_REPLAY in unsecured mode");
// TERFactory.getInstance().logDebug("GnLayer.receive: Send LS_REPLAY in unsecured mode");
send(null, params);
}
}
......@@ -371,13 +371,16 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific {
super.receive(payload, lowerInfo);
}
}
// Security disable, null will be translated into omit
lowerInfo.put(SecurityHelper.SEC_SSP, null);
lowerInfo.put(SecurityHelper.SEC_ITS_AID, null);
} else if (nextHeader == 0x02) { // Secured tag
byte[] payload = SecurityHelper.getInstance().checkSecuredProfileAndExtractPayload(message, basicHdr.length, management.isEnforceSecuredModeSet(), management.getItsAidOther());
byte[] payload = SecurityHelper.getInstance().checkSecuredProfileAndExtractPayload(message, basicHdr.length, management.isEnforceSecuredModeSet(), management.getItsAidOther(), lowerInfo);
if (payload != null) {
// System.out.println("GnLayer.receive: payload=" + ByteHelper.byteArrayToString(payload));
// TERFactory.getInstance().logDebug("GnLayer.receive: payload=" + ByteHelper.byteArrayToString(payload));
byte[] commonHdr = new byte[8];
System.arraycopy(payload, 0, commonHdr, 0, 8);
// System.out.println("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]);
......@@ -408,7 +411,7 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific {
params.put(GN_DEPV, depv);
params.put(GN_TYPE, HT_LS);
params.put(GN_SUBTYPE, HST_LSREPLY);
System.out.println("GnLayer.receive: Send LS_REPLAY in secured mode");
TERFactory.getInstance().logDebug("GnLayer.receive: Send LS_REPLAY in secured mode");
send(null, params);
}
} else {
......@@ -430,7 +433,9 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific {
}
} else {
// Drop it
System.err.println("GnLayer.receive: Invalid basic header type");
// //FIXME as long as the cert chain is not complete, it should not be seen as error -> raise CR
// TERFactory.getInstance().logError("GnLayer.receive: Invalid basic header type");
TERFactory.getInstance().logDebug("GnLayer.receive: Invalid basic header type");
return;
}
}
......@@ -634,7 +639,7 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific {
}
private byte[] createSecuredMessage(final byte[] basicHdr, final byte[] commonHdr, final byte[] extHdr, final byte[] message) {
System.out.println(">>> GnLayer.createSecuredMessage: "+ ByteHelper.byteArrayToString(message));
// TERFactory.getInstance().logDebug(">>> GnLayer.createSecuredMessage");
// SecuredMessage payload length
int payloadLength = commonHdr.length + extHdr.length + message.length;
......@@ -642,7 +647,7 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific {
// Build the generation time value
long curtime = System.currentTimeMillis();
byte[] generationTime = ByteHelper.longToByteArray((long)(curtime - 1072915200000L) * 1000L, Long.SIZE / Byte.SIZE); // In microseconds
System.out.println("GnLayer.createSecuredMessage: generationTime=" + ByteHelper.byteArrayToString(generationTime));
// TERFactory.getInstance().logDebug("GnLayer.createSecuredMessage: generationTime=" + ByteHelper.byteArrayToString(generationTime));
// Build the payload to be signed
byte[] headersField = ByteHelper.concat(
ByteHelper.concat( // SecuredMessage HeaderFields
......@@ -727,16 +732,16 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific {
new byte[] { (byte)0x01 }, // Signature
new byte[] { (byte)0x43 } // Signature length
);
System.out.println("GnLayer.createSecuredMessage: toBeSignedData=" + ByteHelper.byteArrayToString(toBeSignedData));
// TERFactory.getInstance().logDebug("GnLayer.createSecuredMessage: toBeSignedData=" + ByteHelper.byteArrayToString(toBeSignedData));
byte[] toBeSent = null;
try {
// Calculate the hash
byte[] hash = CryptoLib.hashWithSha256(toBeSignedData);
System.out.println("GnLayer.createSecuredMessage: hash=" + ByteHelper.byteArrayToString(hash));
// TERFactory.getInstance().logDebug("GnLayer.createSecuredMessage: hash=" + ByteHelper.byteArrayToString(hash));
// Signed the hash
byte[] signatureBytes = CryptoLib.signWithEcdsaNistp256WithSha256(hash, management.getSigningPrivateKey());
System.out.println("GnLayer.createSecuredMessage: signatureBytes=" + ByteHelper.byteArrayToString(signatureBytes));
// TERFactory.getInstance().logDebug("GnLayer.createSecuredMessage: signatureBytes=" + ByteHelper.byteArrayToString(signatureBytes));
// Add signature
toBeSent = ByteHelper.concat(
basicHdr,
......@@ -748,7 +753,7 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific {
e.printStackTrace();
}
System.out.println("GnLayer.createSecuredMessage: toBeSent=" + ByteHelper.byteArrayToString(toBeSent));
// TERFactory.getInstance().logDebug("GnLayer.createSecuredMessage: toBeSent=" + ByteHelper.byteArrayToString(toBeSent));
return toBeSent;
}
......
......@@ -13,14 +13,8 @@ import java.util.Map;
import java.util.Stack;
import java.util.TreeMap;
import org.etsi.adapter.TERFactory;
import org.etsi.its.adapter.IManagementLayers;
import org.etsi.its.adapter.layers.test.BtpSourceLayer;
import org.etsi.its.adapter.layers.test.CamSourceLayer;
import org.etsi.its.adapter.layers.test.DebugLayer;
import org.etsi.its.adapter.layers.test.DenmSourceLayer;
import org.etsi.its.adapter.layers.test.Gn6SourceLayer;
import org.etsi.its.adapter.layers.test.GnSourceLayer;
import org.etsi.its.adapter.layers.test.LoopbackLayer;
/**
* Layer factory (Singleton)
......@@ -72,7 +66,7 @@ public class LayerFactory {
* @return Protocol port instance
*/
public Layer createLayer(IManagementLayers management, String layerName, Stack<String> lowerStack) {
// System.out.println(">>> LayerFactory.createLayer: " + layerName);
//TERFactory.getInstance().logDebug(">>> LayerFactory.createLayer: " + layerName);
Layer layer = null;
Class<?>[] ctorParams = {IManagementLayers.class, lowerStack.getClass()};
......
......@@ -9,6 +9,7 @@ import java.util.Map;
import java.util.Stack;
import org.etsi.common.ByteHelper;
import org.etsi.adapter.TERFactory;
import org.etsi.its.adapter.IManagementLayers;
public class UdpIpLayer extends Layer {
......@@ -41,7 +42,7 @@ public class UdpIpLayer extends Layer {
super.register(upperLayer);
try {
iutAddress = InetAddress.getByName("127.0.0.1");
//System.out.println("IUT Address: " + iutAddress.getHostAddress());
//TERFactory.getInstance().logDebug("IUT Address: " + iutAddress.getHostAddress());
iutPort = 3750;
iutSocket = new DatagramSocket(3751);
iutThread = new UdpThread(iutSocket);
......
......@@ -26,12 +26,14 @@ public class AdapterControlPort extends AdapterPort implements IPort, IObservabl
private static final byte AcGnPrimitive = 0;
private static final byte AcGn6Primitive = 1;
private static final byte AcGnssPrimitive = 2;
private static final byte AcSecPrimitive = 3;
/* AdapterControl Response */
private static final byte AcGnResponse = 0;
//private static final byte AcGn6Response = 1;
public static final byte AcGnssResponse = 2;
public static final byte AcGnssDistanceCovered = 3;
public static final byte AcSecResponse = 4;
/* GN Commands */
private static final byte AcStartBeaconing = 0;
......@@ -41,9 +43,7 @@ public class AdapterControlPort extends AdapterPort implements IPort, IObservabl
private static final byte AcStartBeaconingMultipleNeighbour = 4;
private static final byte AcStopBeaconingMultipleNeighbour = 5;
private static final byte AcGetLongPosVector = 6;
private static final byte AcEnableSecurity = 7;
private static final byte AcDisableSecurity = 8;
/* GN Responses */
protected static final byte AcGnResponseFailure = 0;
protected static final byte AcLongPosVector = 6;
......@@ -56,6 +56,11 @@ public class AdapterControlPort extends AdapterPort implements IPort, IObservabl
private static final byte AcChangeSpead = 0x74;
private static final byte AcChangeHeading = 0x75;
/* Set the certificate to be used by the Test Adapter */
private static final byte AcEnableSecurity = 0x7a;
private static final byte AcDisableSecurity = 0x7b;
public static final byte AcTrue = 0x01;
public static final byte AcFalse = 0x00;
......@@ -112,12 +117,6 @@ public class AdapterControlPort extends AdapterPort implements IPort, IObservabl
case AcStopBeaconingMultipleNeighbour:
// TODO
break;
case AcEnableSecurity:
Management.getInstance(getComponentName()).setSecuredMode(data);
break;
case AcDisableSecurity:
Management.getInstance(getComponentName()).unsetSecuredMode();
break;
}
}
break;
......@@ -180,6 +179,17 @@ public class AdapterControlPort extends AdapterPort implements IPort, IObservabl
result = false;
}
break;
case AcSecPrimitive:
switch (message[1]) {
case AcEnableSecurity:
byte[] data = ByteHelper.extract(message, 2, message.length - 2);
ProcessAcEnableSecurity(data);
break;
case AcDisableSecurity:
ProcessAcDisableSecurity();
break;
} // End of 'switch' statement
break;
default:
ByteHelper.dump("Unsupported AC primitive", message);
break;
......@@ -283,6 +293,32 @@ public class AdapterControlPort extends AdapterPort implements IPort, IObservabl
}).start();
}
private void ProcessAcEnableSecurity(final byte[] data) {
new Thread(new Runnable() {
@Override
public void run() {
Management.getInstance(getComponentName()).setSecuredMode(data);
byte[] response = {(byte)AcSecResponse, (byte)AcTrue };
setChanged();