Commit 4a7a5d77 authored by berge's avatar berge
Browse files

Merged branches/Security/javasrc (r1425-1803) to trunk.

This completes cleaning operation of r1821 by re-inserting non-STF455 specific changes in trunk
parent 7c515cdb
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
package org.etsi.its.adapter; package org.etsi.its.adapter;
import java.math.BigInteger;
import org.etsi.its.adapter.ports.GnPort; import org.etsi.its.adapter.ports.GnPort;
/** /**
...@@ -71,4 +73,53 @@ public interface IManagementLayers { ...@@ -71,4 +73,53 @@ public interface IManagementLayers {
*/ */
public byte[] getLongitude(); public byte[] getLongitude();
/**
* Enable the secured mode
* @param securityData data required to execute the signing process on beacons
*/
public void setSecuredMode(final byte[] securityData);
/**
* Disable the secured mode
*/
public void unsetSecuredMode();
/**
* Gets the secured mode status
* @return true if secured mode is set, false otherwise
*/
public boolean isSecuredModeSet();
/**
* Gets the private key for signing process
* @return The private key
*/
public BigInteger getSigningPrivateKey();
/**
* Gets the public key X for signing check
* @return The public key X
*/
public byte[] getSigningPublicKeyX();
/**
* Gets the public key Y for signing check
* @return The public key Y
*/
public byte[] getSigningPublicKeyY();
/**
* Gets the AT certificate value
* @return The AT certificate value
* @remark It shall not be used when secured mode is set by the test execution
*/
byte[] getAtCertificate();
/**
* Gets the Hashed8 value from the AT certificate
* @return The Hashed8 value
* @remark It shall not be used when secured mode is set by the test execution
*/
byte[] getAtCertificateDigest();
} }
...@@ -10,12 +10,16 @@ ...@@ -10,12 +10,16 @@
package org.etsi.its.adapter; package org.etsi.its.adapter;
import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import org.etsi.adapter.TERFactory; import org.etsi.adapter.TERFactory;
import org.etsi.certificates.CertificatesIOFactory;
import org.etsi.certificates.io.ICertificatesIO;
import org.etsi.common.ByteHelper; import org.etsi.common.ByteHelper;
import org.etsi.common.ITuple; import org.etsi.common.ITuple;
import org.etsi.common.Tuple; import org.etsi.common.Tuple;
...@@ -58,6 +62,21 @@ public class Management implements IManagementTA, IManagementLayers { ...@@ -58,6 +62,21 @@ public class Management implements IManagementTA, IManagementLayers {
*/ */
private static final int longitude = Integer.decode(((CharstringValue)TERFactory.getInstance().getTaParameter("TsLongitude")).getString()); private static final int longitude = Integer.decode(((CharstringValue)TERFactory.getInstance().getTaParameter("TsLongitude")).getString());
/**
* Secured mode status
*/
private static final String TsSecuredMode = ((CharstringValue)TERFactory.getInstance().getTaParameter("TsSecuredMode")).getString();
/**
* Secured root path to access certificates & private keys
*/
private static final String TsSecuredRootPath = ((CharstringValue)TERFactory.getInstance().getTaParameter("TsSecuredRootPath")).getString();
/**
* Secured configuration identifier
*/
private static final String TsSecuredConfiId = ((CharstringValue)TERFactory.getInstance().getTaParameter("TsSecuredConfiId")).getString();
/** /**
* Link-layer address of Component * Link-layer address of Component
*/ */
...@@ -68,13 +87,54 @@ public class Management implements IManagementTA, IManagementLayers { ...@@ -68,13 +87,54 @@ public class Management implements IManagementTA, IManagementLayers {
*/ */
private GnPort gnPort = null; private GnPort gnPort = null;
/**
* Set to true is secured mode is set
*/
private boolean securedMode = false;
/**
* The certificate identifier to used
*/
private String certificateId = "TA_CERT_A";
/**
* The AT certificate
*/
private byte[] atCertificate = null;
/**
* The certificate digest to used
*/
private byte[] atCertificateDigest = null;
/**
* The private signing key to used
*/
private byte[] signingPrivateKey = null;
/**
* The public signing key X to used
*/
private byte[] signingPublicKeyX = null;
/**
* The public signing key Y to used
*/
private byte[] signingPublicKeyY = null;
// private byte[] toBeSignedDataDigest = null;
// private byte[] toBeSignedDataCertificate = null;
/** /**
* Private constructor (Multiton pattern) * Private constructor (Multiton pattern)
*/ */
private Management() { private Management() {
//empty
// FIXME: For debug only: // Check for secured mode settings in TestAdapter configuration file
if (TsSecuredMode.equals("true")) {
setupSecuredMode();
}
// For debug only:
byte[] mid = new byte[] {(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, byte[] mid = new byte[] {(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x00}; (byte)0x00, (byte)0x00};
byte[] lpv = new byte[] {(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, byte[] lpv = new byte[] {(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
...@@ -160,6 +220,7 @@ public class Management implements IManagementTA, IManagementLayers { ...@@ -160,6 +220,7 @@ public class Management implements IManagementTA, IManagementLayers {
@Override @Override
public byte[] getLongPositionVector(byte[] targetGnAddress) { public byte[] getLongPositionVector(byte[] targetGnAddress) {
byte[] mid = ByteHelper.extract(targetGnAddress, 2, 6); byte[] mid = ByteHelper.extract(targetGnAddress, 2, 6);
// System.out.println("getLongPositionVector: Looking for Loc Entry: " + ByteHelper.byteArrayToString(mid));
long key = ByteHelper.byteArrayToLong(mid); long key = ByteHelper.byteArrayToLong(mid);
for(int i = 0; i < GET_LPV_TIMEOUT; ++i) { for(int i = 0; i < GET_LPV_TIMEOUT; ++i) {
if (locTable.containsKey(key)) { if (locTable.containsKey(key)) {
...@@ -209,7 +270,7 @@ public class Management implements IManagementTA, IManagementLayers { ...@@ -209,7 +270,7 @@ public class Management implements IManagementTA, IManagementLayers {
long key = ByteHelper.byteArrayToLong(mid); long key = ByteHelper.byteArrayToLong(mid);
ITuple<Long, byte[]> entry = locTable.get(key); ITuple<Long, byte[]> entry = locTable.get(key);
if(entry == null || entry.getA() < timestamp) { if(entry == null || entry.getA() < timestamp) {
//ByteHelper.dump("Adding Loc Entry for: ", mid); // System.out.println("gnUpdateLocTable: Adding Loc Entry for: " + ByteHelper.byteArrayToString(mid));
locTable.put(key, new Tuple<Long, byte[]>(timestamp, lpv)); locTable.put(key, new Tuple<Long, byte[]>(timestamp, lpv));
} }
} }
...@@ -281,4 +342,90 @@ public class Management implements IManagementTA, IManagementLayers { ...@@ -281,4 +342,90 @@ public class Management implements IManagementTA, IManagementLayers {
enqueueBeacon = null; enqueueBeacon = null;
} }
} @Override
public void setSecuredMode(final byte[] securityData) {
certificateId = ByteHelper.byteArrayWithLengthToString(ByteHelper.concat(ByteHelper.intToByteArray(securityData.length, 4), securityData));
setupSecuredMode();
}
@Override
public void unsetSecuredMode() {
securedMode = false;
signingPrivateKey = null;
signingPublicKeyX = null;
signingPublicKeyY = null;
atCertificate = null;
atCertificateDigest = null;
}
@Override
public boolean isSecuredModeSet() {
return securedMode;
}
@Override
public BigInteger getSigningPrivateKey() {
return new BigInteger(signingPrivateKey);
}
@Override
public byte[] getSigningPublicKeyX() {
return signingPublicKeyX;
}
@Override
public byte[] getSigningPublicKeyY() {
return signingPublicKeyY;
}
@Override
public byte[] getAtCertificate() {
return atCertificate;
}
@Override
public byte[] getAtCertificateDigest() {
return atCertificateDigest;
}
/**
* @desc This method setup secured mode according to the Test adapter settings (@see TsSecuredMode flags).
* The secured mode could be overrided by test case secured mode configuration through AC primitives
* @remark This method shall be called by the constructor only
*/
private void setupSecuredMode() {
// System.out.println(System.getProperty("user.dir"));
securedMode = true;
ICertificatesIO _certCache = CertificatesIOFactory.getInstance();
if (!_certCache.loadCertificates(TsSecuredRootPath, TsSecuredConfiId)) {
securedMode = false;
} else {
ByteArrayOutputStream certificate = new ByteArrayOutputStream();
_certCache.readCertificate(certificateId + ".AT_CERT", certificate);
// Extract public keys
atCertificate = certificate.toByteArray();
// System.out.println("Management.setupSecuredModeFromTaConfig: certificate=" + ByteHelper.byteArrayToString(value));
atCertificateDigest = new byte[8];
System.arraycopy(atCertificate, 3, atCertificateDigest, 0, 8);
// System.out.println("Management.setupSecuredModeFromTaConfig: atCertificateDigest=" + ByteHelper.byteArrayToString(atCertificateDigest));
int offset = 18;
// KeyX
signingPublicKeyX = new byte[32];
System.arraycopy(atCertificate, offset, signingPublicKeyX, 0, 32);
offset += 32;
// System.out.println("Management.setupSecuredModeFromTaConfig: certificate=" + ByteHelper.byteArrayToString(signingPublicKeyX));
// KeyY
signingPublicKeyY = new byte[32];
System.arraycopy(atCertificate, offset, signingPublicKeyY, 0, 32);
// System.out.println("Management.setupSecuredModeFromTaConfig: certificate=" + ByteHelper.byteArrayToString(signingPublicKeyY));
// Extract private keys
ByteArrayOutputStream signingPrivateKey = new ByteArrayOutputStream();
ByteArrayOutputStream encryptPrivateKey = new ByteArrayOutputStream();
_certCache.readPrivateKeys(certificateId + ".PRIVATE_KEYS", signingPrivateKey, encryptPrivateKey);
this.signingPrivateKey = signingPrivateKey.toByteArray().clone();
// System.out.println("Management.setupSecuredModeFromTaConfig: signingPrivateKey=" + ByteHelper.byteArrayToString(this.signingPrivateKey));
// TODO Add support of encryption
}
}
} // End of class Management
...@@ -72,7 +72,7 @@ public class PcapMultiplexer implements Runnable { ...@@ -72,7 +72,7 @@ public class PcapMultiplexer implements Runnable {
} }
device = alldevs.get(ifaceIndex); device = alldevs.get(ifaceIndex);
System.out.println("Listening: " + device.getName()); // System.out.println("Listening: " + device.getName());
} }
/** /**
...@@ -84,13 +84,10 @@ public class PcapMultiplexer implements Runnable { ...@@ -84,13 +84,10 @@ public class PcapMultiplexer implements Runnable {
} }
public synchronized void register(Layer client, byte[] macAddress, short frameType) { public synchronized void register(Layer client, byte[] macAddress, short frameType) {
// System.out.println(">>>PcapMultiplexer.registering: " + frameType);
System.out.println("Registering client, " + frameType);
if(clientsToMacs.isEmpty()) { if(clientsToMacs.isEmpty()) {
System.out.println("First Client !");
// Open interface // Open interface
int snaplen = 64 * 1024; // Capture all packets, no truncation int snaplen = 64 * 1024; // Capture all packets, no truncation
int flags = Pcap.MODE_PROMISCUOUS; // capture all packets int flags = Pcap.MODE_PROMISCUOUS; // capture all packets
int timeout = 10; // 10 millis int timeout = 10; // 10 millis
...@@ -106,7 +103,7 @@ public class PcapMultiplexer implements Runnable { ...@@ -106,7 +103,7 @@ public class PcapMultiplexer implements Runnable {
filter = ""; filter = "";
} }
else { else {
System.out.println("Another Client !"); // System.out.println("Another Client !");
filter = filter + " and "; filter = filter + " and ";
} }
...@@ -117,7 +114,7 @@ public class PcapMultiplexer implements Runnable { ...@@ -117,7 +114,7 @@ public class PcapMultiplexer implements Runnable {
} }
filter = filter + "not ether src " + strMacAddress; filter = filter + "not ether src " + strMacAddress;
System.out.println("New filter: " + filter); // System.out.println("New filter: " + filter);
// Apply filter // Apply filter
PcapBpfProgram bpfFilter = new PcapBpfProgram(); PcapBpfProgram bpfFilter = new PcapBpfProgram();
...@@ -125,7 +122,7 @@ public class PcapMultiplexer implements Runnable { ...@@ -125,7 +122,7 @@ public class PcapMultiplexer implements Runnable {
int netmask = 0; int netmask = 0;
int r = pcap.compile(bpfFilter, filter, optimize, netmask); int r = pcap.compile(bpfFilter, filter, optimize, netmask);
if (r != Pcap.OK) { if (r != Pcap.OK) {
System.out.println("Filter error: " + pcap.getErr()); // System.out.println("Filter error: " + pcap.getErr());
} }
pcap.setFilter(bpfFilter); pcap.setFilter(bpfFilter);
......
...@@ -90,7 +90,7 @@ public class TestAdapter implements TriCommunicationSA, Observer { ...@@ -90,7 +90,7 @@ public class TestAdapter implements TriCommunicationSA, Observer {
if (tsiPortId.getPortName().equals("acPort")) { if (tsiPortId.getPortName().equals("acPort")) {
port = new AdapterControlPort(portName, ComponentId); port = new AdapterControlPort(portName, ComponentId);
} else if (tsiPortId.getPortName().equals("utPort")) { } else if (tsiPortId.getPortName().toLowerCase().endsWith("utport")) {
port = new UpperTesterPort(portName, ComponentId); port = new UpperTesterPort(portName, ComponentId);
} else { } else {
String componentName = compPortId.getComponent().getComponentName(); String componentName = compPortId.getComponent().getComponentName();
......
/**
* @author ETSI / STF481 / Yann Garcia
* @version $URL$
* $Id$
*/
package org.etsi.its.adapter;
import java.io.ByteArrayInputStream;
import org.etsi.ttcn.common.ByteHelper;
public class TlsHelper {
private static TlsHelper Instance = new TlsHelper();
public static TlsHelper getInstance() { return Instance; }
private TlsHelper() {
}
public byte[] size2tls(final int length) {
byte[] result = null;
if (length < 128) { // One byte length
result = new byte[] { (byte)length };
} else {
long lv = length;
long bitLen = bitLength(lv);
long byteLen = byteLength(bitLen);
long flags = (long) ((byteLen | 1) << (byteLen * Byte.SIZE - bitLength(byteLen) - 1));
long len = (long) (byteLen << (byteLen * Byte.SIZE - bitLength(byteLen) - 1));
if ((flags & lv) != 0) { // We can encode the length on the MSB part
byteLen += 1;
len = (long) (byteLen << (byteLen * Byte.SIZE - bitLength(byteLen)) - 1);
}
result = ByteHelper.longToByteArray((long)(lv | len), (int) byteLen);
}
return result;
}
public long tls2size(final ByteArrayInputStream buf) {
// Sanity check
if (buf.available() == 0) {
return 0;
}
// Read the first byte
byte msb = (byte) buf.read();
if ((msb & 0x80) == 0x00) { // Integer < 128
return msb;
} else {
// Decode the length. The encoding of the length shall use at most 7 bits set to 1 (see Draft ETSI TS 103 097 V1.1.14 Clause 4.1 Presentation Language Table 1/8)
byte bit;
byte byteLen = 1;
do {
bit = (byte) ((byte) (msb << byteLen++) & 0x80);
} while (bit != 0x00);
// Set the IntX length
byte[] data = new byte[byteLen - 1];
buf.read(data, 0, byteLen - 1);
byte[] length = ByteHelper.concat(new byte[] { msb }, data);
length[0] &= (byte)(Math.pow(2.0, 8 - byteLen + 1) - 1);
long lv = ByteHelper.byteArrayToLong(length);
return lv;
}
}
public long bitLength(final long value) {
return (long) Math.ceil(Math.log(value) / Math.log(2));
}
public long byteLength(final long value) {
double d = value; // Convert int to double
return (long) Math.ceil(d / Byte.SIZE);
}
} // End of class TlsHelper
...@@ -18,6 +18,8 @@ import org.etsi.common.ByteHelper; ...@@ -18,6 +18,8 @@ import org.etsi.common.ByteHelper;
import org.etsi.its.adapter.IManagementLayers; import org.etsi.its.adapter.IManagementLayers;
import org.etsi.ttcn.tci.CharstringValue; import org.etsi.ttcn.tci.CharstringValue;
import de.fraunhofer.sit.c2x.CryptoLib;
/** /**
* Implementation of ITS GeoNetworking layer (background thread) * Implementation of ITS GeoNetworking layer (background thread)
*/ */
...@@ -274,10 +276,16 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific { ...@@ -274,10 +276,16 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific {
); );
} }
byte[] toBeSent = null;
byte[] basicHdr = createBasicHeader(); byte[] basicHdr = createBasicHeader();
byte[] commonHdr = createCommonHeader((String)params.get(GN_NEXTHEADER), ht, hst, (message == null)?0:message.length, hoplimit); byte[] commonHdr = createCommonHeader((String)params.get(GN_NEXTHEADER), ht, hst, (message == null)?0:message.length, hoplimit);
if (!management.isSecuredModeSet()) { // Secure mode disabled
toBeSent = ByteHelper.concat(basicHdr, commonHdr, extHdr, message);
} else {
toBeSent = createSecuredMessage(basicHdr, commonHdr, extHdr, message);
}
return super.send(ByteHelper.concat(basicHdr, commonHdr, extHdr, message), params); return super.send(toBeSent, params);
} }
/* (non-Javadoc) /* (non-Javadoc)
...@@ -285,14 +293,15 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific { ...@@ -285,14 +293,15 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific {
*/ */
@Override @Override
public void receive(byte[] message, Map<String, Object> lowerInfo) { public void receive(byte[] message, Map<String, Object> lowerInfo) {
// System.out.println(">>> GnLayer.receive: " + ByteHelper.byteArrayToString(message));
byte[] basicHdr = new byte[4]; // TODO To be removed byte[] basicHdr = new byte[4]; // TODO To be removed
System.arraycopy(message, 4, basicHdr, 0, 4); System.arraycopy(message, 4, basicHdr, 0, 4);
byte[] versionNh = new byte[1]; byte[] versionNh = new byte[1];
System.arraycopy(basicHdr, 0, versionNh, 0, 1); System.arraycopy(basicHdr, 0, versionNh, 0, 1);
int nextHeader = (int)(versionNh[0] & (byte)0x0F); int nextHeader = (int)(versionNh[0] & (byte)0x0F);
if (!management.isSecuredModeSet()) { // Secure mode disabled
byte[] commonHdr = new byte[8]; byte[] commonHdr = new byte[8];
System.arraycopy(message, 4, commonHdr, 0, 8); System.arraycopy(message, 4, commonHdr, 0, 8);
...@@ -337,7 +346,101 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific { ...@@ -337,7 +346,101 @@ public class GnLayer extends Layer implements Runnable, IEthernetSpecific {
super.receive(payload, lowerInfo); super.receive(payload, lowerInfo);
} }
} }
} else {
if ((basicHdr[0] & 0x0f) == 0x02) { // Secured tag
int offset = basicHdr.length + 1; // Version fields
int signerInfoTypeIndex = 0;
// Extract Header length (IntX type)
if ((message[offset] & 0x80) == 0x80) { // Integer >= 128
byte msb = message[offset]; // TODO Create a method decodeIntX
byte bit;
byte byteLen = 1;
do {
bit = (byte) ((byte) (msb << byteLen++) & 0x80);
} while (bit != 0x00);
// Set the IntX length
byte[] newBuf = ByteHelper.extract(message, offset, byteLen);
// Remove the length from the real integer value
newBuf[0] &= (byte)(Math.pow(2.0, 8 - byteLen + 1) - 1);
signerInfoTypeIndex = offset + byteLen;
offset += byteLen + ByteHelper.byteArrayToInt(newBuf);
} else {
signerInfoTypeIndex = offset + 1;
offset += message[offset] + 1;
}
offset += 1; // Skip Payload Type
// Extract Data Payload length (IntX type)
if ((message[offset] & 0x80) == 0x80) { // Integer >= 128
byte msb = message[offset];
byte bit;
byte byteLen = 1;
do {
bit = (byte) ((byte) (msb << byteLen++) & 0x80);
} while (bit != 0x00);
offset += byteLen;
} else {
offset +=1;
}
// Sanity check: Verify SignerInfo field
if (
((message[signerInfoTypeIndex] & 0x80) != 0x80) || // SignerInfo Type: certificate digest with ecdsap256 (1)