Loading javasrc/adapter/org/etsi/its/adapter/IManagementLayers.java +97 −46 Original line number Diff line number Diff line Loading @@ -9,6 +9,8 @@ package org.etsi.its.adapter; import java.math.BigInteger; import org.etsi.its.adapter.ports.GnPort; /** Loading Loading @@ -71,4 +73,53 @@ public interface IManagementLayers { */ 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(); } javasrc/adapter/org/etsi/its/adapter/Management.java +334 −187 Original line number Diff line number Diff line Loading @@ -10,12 +10,16 @@ package org.etsi.its.adapter; import java.io.ByteArrayOutputStream; import java.math.BigInteger; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; 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.ITuple; import org.etsi.common.Tuple; Loading Loading @@ -58,6 +62,21 @@ public class Management implements IManagementTA, IManagementLayers { */ 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 */ Loading @@ -68,13 +87,54 @@ public class Management implements IManagementTA, IManagementLayers { */ 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 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)0x00, (byte)0x00}; byte[] lpv = new byte[] {(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, Loading Loading @@ -160,6 +220,7 @@ public class Management implements IManagementTA, IManagementLayers { @Override public byte[] getLongPositionVector(byte[] targetGnAddress) { byte[] mid = ByteHelper.extract(targetGnAddress, 2, 6); // System.out.println("getLongPositionVector: Looking for Loc Entry: " + ByteHelper.byteArrayToString(mid)); long key = ByteHelper.byteArrayToLong(mid); for(int i = 0; i < GET_LPV_TIMEOUT; ++i) { if (locTable.containsKey(key)) { Loading Loading @@ -209,7 +270,7 @@ public class Management implements IManagementTA, IManagementLayers { long key = ByteHelper.byteArrayToLong(mid); ITuple<Long, byte[]> entry = locTable.get(key); 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)); } } Loading Loading @@ -281,4 +342,90 @@ public class Management implements IManagementTA, IManagementLayers { 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 javasrc/adapter/org/etsi/its/adapter/PcapMultiplexer.java +6 −9 Original line number Diff line number Diff line Loading @@ -72,7 +72,7 @@ public class PcapMultiplexer implements Runnable { } device = alldevs.get(ifaceIndex); System.out.println("Listening: " + device.getName()); // System.out.println("Listening: " + device.getName()); } /** Loading @@ -84,13 +84,10 @@ public class PcapMultiplexer implements Runnable { } 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()) { System.out.println("First Client !"); // Open interface int snaplen = 64 * 1024; // Capture all packets, no truncation int flags = Pcap.MODE_PROMISCUOUS; // capture all packets int timeout = 10; // 10 millis Loading @@ -106,7 +103,7 @@ public class PcapMultiplexer implements Runnable { filter = ""; } else { System.out.println("Another Client !"); // System.out.println("Another Client !"); filter = filter + " and "; } Loading @@ -117,7 +114,7 @@ public class PcapMultiplexer implements Runnable { } filter = filter + "not ether src " + strMacAddress; System.out.println("New filter: " + filter); // System.out.println("New filter: " + filter); // Apply filter PcapBpfProgram bpfFilter = new PcapBpfProgram(); Loading @@ -125,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()); // System.out.println("Filter error: " + pcap.getErr()); } pcap.setFilter(bpfFilter); Loading javasrc/adapter/org/etsi/its/adapter/TestAdapter.java +272 −272 Original line number Diff line number Diff line Loading @@ -90,7 +90,7 @@ public class TestAdapter implements TriCommunicationSA, Observer { if (tsiPortId.getPortName().equals("acPort")) { port = new AdapterControlPort(portName, ComponentId); } else if (tsiPortId.getPortName().equals("utPort")) { } else if (tsiPortId.getPortName().toLowerCase().endsWith("utport")) { port = new UpperTesterPort(portName, ComponentId); } else { String componentName = compPortId.getComponent().getComponentName(); Loading javasrc/adapter/org/etsi/its/adapter/TlsHelper.java 0 → 100644 +77 −0 Original line number Diff line number Diff line /** * @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 Loading
javasrc/adapter/org/etsi/its/adapter/IManagementLayers.java +97 −46 Original line number Diff line number Diff line Loading @@ -9,6 +9,8 @@ package org.etsi.its.adapter; import java.math.BigInteger; import org.etsi.its.adapter.ports.GnPort; /** Loading Loading @@ -71,4 +73,53 @@ public interface IManagementLayers { */ 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(); }
javasrc/adapter/org/etsi/its/adapter/Management.java +334 −187 Original line number Diff line number Diff line Loading @@ -10,12 +10,16 @@ package org.etsi.its.adapter; import java.io.ByteArrayOutputStream; import java.math.BigInteger; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; 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.ITuple; import org.etsi.common.Tuple; Loading Loading @@ -58,6 +62,21 @@ public class Management implements IManagementTA, IManagementLayers { */ 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 */ Loading @@ -68,13 +87,54 @@ public class Management implements IManagementTA, IManagementLayers { */ 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 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)0x00, (byte)0x00}; byte[] lpv = new byte[] {(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, Loading Loading @@ -160,6 +220,7 @@ public class Management implements IManagementTA, IManagementLayers { @Override public byte[] getLongPositionVector(byte[] targetGnAddress) { byte[] mid = ByteHelper.extract(targetGnAddress, 2, 6); // System.out.println("getLongPositionVector: Looking for Loc Entry: " + ByteHelper.byteArrayToString(mid)); long key = ByteHelper.byteArrayToLong(mid); for(int i = 0; i < GET_LPV_TIMEOUT; ++i) { if (locTable.containsKey(key)) { Loading Loading @@ -209,7 +270,7 @@ public class Management implements IManagementTA, IManagementLayers { long key = ByteHelper.byteArrayToLong(mid); ITuple<Long, byte[]> entry = locTable.get(key); 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)); } } Loading Loading @@ -281,4 +342,90 @@ public class Management implements IManagementTA, IManagementLayers { 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
javasrc/adapter/org/etsi/its/adapter/PcapMultiplexer.java +6 −9 Original line number Diff line number Diff line Loading @@ -72,7 +72,7 @@ public class PcapMultiplexer implements Runnable { } device = alldevs.get(ifaceIndex); System.out.println("Listening: " + device.getName()); // System.out.println("Listening: " + device.getName()); } /** Loading @@ -84,13 +84,10 @@ public class PcapMultiplexer implements Runnable { } 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()) { System.out.println("First Client !"); // Open interface int snaplen = 64 * 1024; // Capture all packets, no truncation int flags = Pcap.MODE_PROMISCUOUS; // capture all packets int timeout = 10; // 10 millis Loading @@ -106,7 +103,7 @@ public class PcapMultiplexer implements Runnable { filter = ""; } else { System.out.println("Another Client !"); // System.out.println("Another Client !"); filter = filter + " and "; } Loading @@ -117,7 +114,7 @@ public class PcapMultiplexer implements Runnable { } filter = filter + "not ether src " + strMacAddress; System.out.println("New filter: " + filter); // System.out.println("New filter: " + filter); // Apply filter PcapBpfProgram bpfFilter = new PcapBpfProgram(); Loading @@ -125,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()); // System.out.println("Filter error: " + pcap.getErr()); } pcap.setFilter(bpfFilter); Loading
javasrc/adapter/org/etsi/its/adapter/TestAdapter.java +272 −272 Original line number Diff line number Diff line Loading @@ -90,7 +90,7 @@ public class TestAdapter implements TriCommunicationSA, Observer { if (tsiPortId.getPortName().equals("acPort")) { port = new AdapterControlPort(portName, ComponentId); } else if (tsiPortId.getPortName().equals("utPort")) { } else if (tsiPortId.getPortName().toLowerCase().endsWith("utport")) { port = new UpperTesterPort(portName, ComponentId); } else { String componentName = compPortId.getComponent().getComponentName(); Loading
javasrc/adapter/org/etsi/its/adapter/TlsHelper.java 0 → 100644 +77 −0 Original line number Diff line number Diff line /** * @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