Commit f49de8ae authored by Cypres TAC's avatar Cypres TAC
Browse files

Merge branch 'update-locContactMsg' into 'master'

Update loc contact msg

See merge request !17
parents fe29e8d1 c95586a9
Pipeline #231629 passed with stages
in 3 minutes and 13 seconds
......@@ -84,11 +84,15 @@ int32_t clea_renew_qrcode(uint32_t *ptr_ct_periodStart, uint32_t *ptr_t_qrStart)
if (c->locContactMsgPresent)
{
loc_msg_start = cpt;
for (i = 0; i < sizeof(c->locationPhone); i++)
// Encode 56 first bits (7 bytes + 4 bits)
for (i = 0; i < sizeof(c->locationPhone) - 1; i++)
{
LSP[cpt++] = c->locationPhone[i];
}
// Encode the last 4 bits + 4 bits of padding
LSP[cpt++] = c->locationPhone[sizeof(c->locationPhone)-1] & 0xF0;
LSP[cpt++] = c->locationRegion & 0xFF;
for (i = 0; i < sizeof(c->locationPin); i++)
{
......
......@@ -34,8 +34,9 @@ typedef struct
uint8_t periodDuration; // 8 bits: period duration in hours
// Location contact
uint8_t locationPhone[8]; // 4 bits per digit, pad with 0xF
uint8_t locationPin[4]; // 4 bits per digit
uint8_t locationPhone[8]; // 60 bits, 4 bits per digit, pad with 0xF (=> 15 digits max)
uint8_t locationRegion; // 8 bits: coarse grain geographical information for the location
uint8_t locationPin[3]; // 4 bits per digit (=> 6 digits)
} clea_conf_t;
extern clea_conf_t clea_conf;
......
......@@ -18,7 +18,8 @@ clea_conf_t clea_conf =
.countryCode = 250, // France numeric code as defined in ISO3166-1
.periodDuration = 3, // 3 hours
.locationPhone = {0x33, 0x80, 0x01, 0x30, 0x00, 0x0F, 0xFF, 0xFF}, // +33 800 130 000
.locationPin = {0xDE, 0xAD, 0xBE, 0xEF} // "DEADBEEF"
.locationRegion = 11,
.locationPin = {0xDE, 0xAD, 0xBE} // "DEADBE"
};
uint8_t LSP_base64[LSP_BASE64_SIZE];
......
......@@ -32,7 +32,7 @@ void print_uuid(uint8_t uuid[16])
void usage(char *s, char *err)
{
printf("ERROR: %s\n\n", err);
printf("Usage: %s staff countryCode CRIexp venueType venueCategory1 venueCategory2 periodDuration PK_SA PK_MCTA SK_L [locationPhone locationPin]\n\n", s);
printf("Usage: %s staff countryCode CRIexp venueType venueCategory1 venueCategory2 periodDuration PK_SA PK_MCTA SK_L [locationPhone locationRegion locationPin]\n\n", s);
printf("locationPhone: 15-digit-max international phone number\n");
printf("locationPin: 8-digit-max pin code\n");
exit(1);
......@@ -49,10 +49,10 @@ int main(int argc, char *argv[])
uint32_t t_qrStart, ct_periodStart;
uint8_t LTId[16];
if ((argc == 13) || (argc == 11))
if ((argc == 14) || (argc == 11))
{
clea_conf.staff = atoi(argv[1]);
clea_conf.locContactMsgPresent = (argc == 13);
clea_conf.locContactMsgPresent = (argc == 14);
clea_conf.countryCode = atoi(argv[2]);
clea_conf.CRIexp = atoi(argv[3]);
clea_conf.venueType = atoi(argv[4]);
......@@ -70,7 +70,10 @@ int main(int argc, char *argv[])
{
USAGE("Too many digits in locationPhone");
}
if (parse_bcd(argv[12], clea_conf.locationPin, sizeof(clea_conf.locationPin)))
clea_conf.locationRegion = atoi(argv[12]);
if (parse_bcd(argv[13], clea_conf.locationPin, sizeof(clea_conf.locationPin)))
{
USAGE("Too many digits in locationPin");
}
......@@ -85,6 +88,7 @@ int main(int argc, char *argv[])
exit(r);
}
printf("=VALUES=");
print_qrcode();
print_uuid(LTId);
printf(" %lu %lu\n",ct_periodStart, t_qrStart);
......
......@@ -52,7 +52,7 @@ uint8_t parse_bcd(char *string, uint8_t *array, uint8_t size)
i++;
}
for(k = i / 2 + 1; k < size; k++)
for(k = i / 2 + i%2; k < size; k++)
{
array[k] = 0xFF;
}
......
......@@ -2,6 +2,8 @@ package fr.inria.clea.lsp;
import java.time.Instant;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
......@@ -18,16 +20,21 @@ import lombok.ToString;
@EqualsAndHashCode
@ToString
public class LocationContact {
public static final String PHONE_VALIDATION_MESSAGE = "Location phone is mandatory";
public static final String REGION_VALIDATION_MESSAGE = "Location phone is mandatory";
public static final String PIN_VALIDATION_MESSAGE = "Secret digit PIN must contain exactly 6 characters";
public static final String PERIOD_START_TIME_VALIDATION_MESSAGE = "Period start time must not be null";
/* Phone number of the location contact person, one digit = one character */
@NotBlank(message= PHONE_VALIDATION_MESSAGE)
String locationPhone;
/* Coarse grain geographical information for the location */
@Min(value = 0, message = REGION_VALIDATION_MESSAGE)
@Max(value = 255, message = REGION_VALIDATION_MESSAGE)
int locationRegion;
/* Secret 6 digit PIN, one digit = one character */
// TODO: set max to 6 when CSV files used for tests are updated
@Size(min = 6, max = 8,
@Size(min = 6, max = 6,
message = PIN_VALIDATION_MESSAGE)
String locationPin;
/* Starting time of the period in seconds */
......
......@@ -63,7 +63,7 @@ public class LocationContactMessageEncoder {
/**
* Encode the data locContactMsg in binary format:
* | locationPhone | locationPin | t_periodStart |
* | locationPhone | pad | locationRegion | locationPin | t_periodStart |
*
* @return message in binary format
*/
......@@ -71,19 +71,25 @@ public class LocationContactMessageEncoder {
BitUtils locationContactMessage = new BitUtils(8 * CleaEciesEncoder.LOC_BYTES_SIZE);
int digit, i, iend;
/* locationPhone: 8 bytes with 4-bit nibble by digit (0xf when empty) */
/* locationPhone: 60 bits with 4-bit nibble by digit (0xf when empty) */
for (i = 0; i < message.getLocationPhone().length(); i++) {
/* convert the char in its value */
digit = message.getLocationPhone().charAt(i) - 48;
locationContactMessage.setNextInteger(digit, 4);
}
/* 0xf for the remaining 4-bit nibbles up to sixteen */
/* 0xf for the remaining 4-bit nibbles up to fifteen */
iend = i;
for (i = iend; i < 16; i++) {
for (i = iend; i < 15; i++) {
locationContactMessage.setNextInteger(0x0f, 4);
}
/* padding (4 bits) */
locationContactMessage.setNextInteger(0x0, 4);
/* t_periodStart (8 bits) */
locationContactMessage.setNextInteger(message.getLocationRegion(), 8);
/* locationPIN: 4 bytes with 4-bit nibble by digit */
/* locationPIN: 3 bytes with 4-bit nibble by digit */
for (i = 0; i < message.getLocationPin().length(); i++) {
/* convert the char in its value */
digit = message.getLocationPin().charAt(i) - 48;
......@@ -110,32 +116,40 @@ public class LocationContactMessageEncoder {
int i, digit;
/*
* locationPhone: 8 bytes with 4-bit nibble by digit (0xf when empty) => 16
* locationPhone: 60 bits with 4-bit nibble by digit (0xf when empty) => 15
* digits max
*/
StringBuilder locationPhone = new StringBuilder(16);
for (i = 0; i < 16; i++) {
StringBuilder locationPhone = new StringBuilder(15);
for (i = 0; i < 15; i++) {
/* unpack the 4-bit nibbles */
digit = bitLocationContactMessage.getNextInteger(4);
if (digit != 0xf) {
locationPhone.append(digit);
}
}
/* padding (4 bits) */
int pad = bitLocationContactMessage.getNextInteger(4);
assert (pad == 0) : "LSP decoding, padding error";
/* locationRegion (1 octet) */
int locationRegion = bitLocationContactMessage.getNextInteger(8);
/* locationPIN: 4 bytes with 4-bit nibble by digit => 8 digits */
StringBuilder locationPin = new StringBuilder(8);
for (i = 0; i < 8; i++) {
/* locationPIN: 3 bytes with 4-bit nibble by digit => 6 digits */
StringBuilder locationPin = new StringBuilder(6);
for (i = 0; i < 6; i++) {
/* unpack the 4-bit nibbles */
locationPin.append(bitLocationContactMessage.getNextInteger(4));
}
/* t_periodStart (32 bits) */
long periodStartTime = bitLocationContactMessage.getNextLong(32);
LocationContact locationContact = new LocationContact(locationPhone.toString(),
locationPin.toString(), TimeUtils.instantFromTimestamp(periodStartTime));
locationRegion, locationPin.toString(), TimeUtils.instantFromTimestamp(periodStartTime));
this.validateMessage(locationContact);
return locationContact;
} catch (NoSuchAlgorithmException | InvalidKeySpecException | IllegalStateException | InvalidCipherTextException
| IOException e) {
throw new CleaEncryptionException(e);
......
......@@ -22,7 +22,7 @@ public class LspEncoderDecoder {
System.exit(0);
}
if ("encode".equals(args[0]) && ((args.length == 13) || (args.length == 11))) {
if ("encode".equals(args[0]) && ((args.length == 14) || (args.length == 11))) {
encodeLsp(args);
} else if ("decode".equals(args[0]) && args.length == 4) {
decodeLsp(args);
......@@ -38,14 +38,14 @@ public class LspEncoderDecoder {
LocationSpecificPartDecoder lspDecoder = new LocationSpecificPartDecoder(serverAuthoritySecretKey);
LocationSpecificPart lsp = lspDecoder.decrypt(lspBase64);
String valuesToreturn = (lsp.isStaff()? 1 : 0) + " " + lsp.getCountryCode() + " " + lsp.getQrCodeRenewalIntervalExponentCompact() + " " + lsp.getVenueType();
String valuesToreturn = "=VALUES="+ (lsp.isStaff()? 1 : 0) + " " + lsp.getCountryCode() + " " + lsp.getQrCodeRenewalIntervalExponentCompact() + " " + lsp.getVenueType();
valuesToreturn += " " + lsp.getVenueCategory1() + " " + lsp.getVenueCategory2() + " " + lsp.getPeriodDuration() + " " + lsp.getLocationTemporaryPublicId();
valuesToreturn += " " + Integer.toUnsignedString(lsp.getCompressedPeriodStartTime()) + " " + TimeUtils.ntpTimestampFromInstant(lsp.getQrCodeValidityStartTime());
if (lsp.isLocationContactMessagePresent()) {
LocationContactMessageEncoder contactMessageDecode = new LocationContactMessageEncoder(manualContactTracingAuthoritySecretKey);
LocationContact locationContact = contactMessageDecode.decode(lsp.getEncryptedLocationContactMessage());
valuesToreturn += " " + locationContact.getLocationPhone() + " " + locationContact.getLocationPin();
valuesToreturn += " " + locationContact.getLocationPhone() + " " + locationContact.getLocationRegion() + " " + locationContact.getLocationPin();
}
System.out.println(valuesToreturn);
}
......@@ -79,10 +79,11 @@ public class LspEncoderDecoder {
.serverAuthorityPublicKey(serverAuthorityPublicKey)
.permanentLocationSecretKey(permanentLocationSecretKey);
if (args.length == 13) {
if (args.length == 14) {
final String locationPhone = args[11];
final String locationPin = args[12];
locationBuilder.contact( new LocationContact(locationPhone, locationPin, periodStartTime));
final int locationRegion = Integer.parseInt(args[12]);
final String locationPin = args[13];
locationBuilder.contact( new LocationContact(locationPhone, locationRegion, locationPin, periodStartTime));
}
Location location = locationBuilder.build();
......@@ -92,7 +93,7 @@ public class LspEncoderDecoder {
String encryptedLocationSpecificPart = location.getLocationSpecificPartEncryptedBase64();
final String valuesToreturn = encryptedLocationSpecificPart + " "
final String valuesToreturn = "=VALUES=" + encryptedLocationSpecificPart + " "
+ location.getLocationSpecificPart().getLocationTemporaryPublicId() + " "
+ Integer.toUnsignedString(location.getLocationSpecificPart().getCompressedPeriodStartTime()) + " "
+ TimeUtils.ntpTimestampFromInstant(location.getLocationSpecificPart().getQrCodeValidityStartTime());
......
......@@ -84,7 +84,7 @@ class LocationSpecificPartTest {
@Test
public void testEncodinsAndDecodingOfALocationMessage() throws CleaCryptoException {
Instant periodStartTime = Instant.now().truncatedTo(ChronoUnit.HOURS);
LocationContact locationContact = new LocationContact("0612150292", "01234567", periodStartTime);
LocationContact locationContact = new LocationContact("33800130000", 12, "012345", periodStartTime);
Location location = Location.builder().contact(locationContact)
.manualContactTracingAuthorityPublicKey(manualContactTracingAuthorityKeyPair[1])
.permanentLocationSecretKey(permanentLocationSecretKey).build();
......@@ -99,7 +99,7 @@ class LocationSpecificPartTest {
@Test
public void testEncodingAndDecodingOfALocationSpecificPart() throws CleaCryptoException {
Instant periodStartTime = Instant.now().truncatedTo(ChronoUnit.HOURS);
LocationContact locationContact = new LocationContact("33800130000", "01234567", periodStartTime);
LocationContact locationContact = new LocationContact("33800130000", 12, "012345", periodStartTime);
/* Encode a LSP with location */
LocationSpecificPart lsp = LocationSpecificPart.builder().staff(true).countryCode(33)
.qrCodeRenewalIntervalExponentCompact(2).venueType(4).venueCategory1(0).venueCategory2(0)
......@@ -237,8 +237,9 @@ class LocationSpecificPartTest {
Random rn = new Random();
int nbDigits = rn.nextInt(6) + 10;
String phone = generateRandomDigits(nbDigits);
int region = rn.nextInt(255);
String pinCode = generateRandomDigits(6);
LocationContact locationContact = new LocationContact(phone, pinCode, myPeriodStartTime);
LocationContact locationContact = new LocationContact(phone, region, pinCode, myPeriodStartTime);
/* Encode a LSP with location */
LocationSpecificPart lsp = LocationSpecificPart.builder()
.staff(staff == 1)
......@@ -275,7 +276,7 @@ class LocationSpecificPartTest {
*/
@ParameterizedTest
@CsvFileSource(resources = "/testLocationDecoding.csv", numLinesToSkip = 1)
public void testDecodingOfLocationOnlyInBase64(String locationPhone, String locationPin, long t_periodStart,
public void testDecodingOfLocationOnlyInBase64(String locationPhone, int locationRegion, String locationPin, long t_periodStart,
String serverAuthoritySecretKey, String serverAuthorityPublicKey,
String manualContactTracingAuthoritySecretKey, String manualContactTracingAuthorityPublicKey,
String lspbase64) throws CleaCryptoException {
......@@ -290,6 +291,7 @@ class LocationSpecificPartTest {
System.out.println("decodedLocationContact= "+decodedLocationContact);
assertThat(decodedLocationContact.getLocationPhone()).isEqualTo(locationPhone);
assertThat(decodedLocationContact.getLocationRegion()).isEqualTo(locationRegion);
assertThat(decodedLocationContact.getLocationPin()).isEqualTo(locationPin);
assertThat(decodedLocationContact.getPeriodStartTime()).isEqualTo(TimeUtils.instantFromTimestamp(t_periodStart));
}
......
......@@ -32,7 +32,7 @@ public class LocationTest {
serverAuthorityKeyPair = cleaEciesEncoder.genKeysPair(true);
manualContactTracingAuthorityKeyPair = cleaEciesEncoder.genKeysPair(true);
periodStartTime = Instant.now().truncatedTo(ChronoUnit.HOURS);
locationContact = new LocationContact("0612150292", "01234567", periodStartTime);
locationContact = new LocationContact("33800130000", 10, "012345", periodStartTime);
}
@Test
......
staff, countryCode, LTId, CRIexp, venueType, venueCat1, venueCat2, periodDuration, ct_periodStart, t_qrStart, SK_SA, PK_SA, lsp_base64
0, 492, d5e7c7bb-39c1-5d05-d099-4af94c5e1508, 5, 12, 0, 0, 3, 1062551, 3825183806, 34af7f978c5a17772867d929e0b800dd2db74608322d73f2f0cfd19cdcaeccc8, 04c14d9db89a3dd8da8a366cf26cd67f1de468fb5dc15f240b0d2b96dbdb5f39af962cb0bdc0bafcc9e523bf5cd4eba420c51758f987457954d32f1003bbaaf1c5, ANXnx7s5wV0F0JlK+UxeFQhit4IeKD9oDNEJ3ICWC2r+V9+3lmivN0ASWJ2LY4J7JGhBe7no034i84J0sJAxgc7X/k/pRculBiPHXGi30bw2r+iXRZNQXLWsuNdO3Xz/wRbALxE/WEUyjXK1wPpwQK6gIqRN0wCen6UdKqjMm8RT/jPlQ4HC53WmDWtElwKG1cwMV8IvTqlKWHUB4S4JTHMwZuHeLkDq8M8+O2uodA==
1, 4095, d5e7c7bb-39c1-5d05-d099-4af94c5e1508, 31, 31, 15, 15, 255, 1062551, 3825183806, 34af7f978c5a17772867d929e0b800dd2db74608322d73f2f0cfd19cdcaeccc8, 04c14d9db89a3dd8da8a366cf26cd67f1de468fb5dc15f240b0d2b96dbdb5f39af962cb0bdc0bafcc9e523bf5cd4eba420c51758f987457954d32f1003bbaaf1c5, ANXnx7s5wV0F0JlK+UxeFQh4pkn9iw5HsbDWFhRGr/AMgxyDtCeFDNdcLDezLMKNXq+xWK6cZuTvsrRLF1t7rFl7kFxXMIJ385crApGR9dcSCudfurY/qyejYYPC8lXL5+RMZwmeJgiIbjditviTn5OJY2NB2Ppy/EMhKUfnyB9Z69Mu1K8zcFQ0upJwZQOqMaRnoi3B7bEy/YB1/a3zTBDfUUx2usoxeddLFxe0yw==
1, 592, d5e7c7bb-39c1-5d05-d099-4af94c5e1508, 31, 31, 15, 15, 255, 1062551, 3825183806, 3108f08b1485adb6f72cfba1b55c7484c906a2a3a0a027c78dcd991ca64c97bd, 045f802c016b2d14ef4d7ef01617c67c7506c0cd08aed3e4bcaf34ef5ffaddebb70a073d82c37bc874ce6705cec8b1c4a03b2ccd8f28b0c5034fb8774f2e97b1a4, ANXnx7s5wV0F0JlK+UxeFQgV9xGX/BNF8V7w8HYosVwROBC7hGPHtLsLtgNi8+AoSFlizStzODCWAG1RYxLvzdsqeBg16xuDmJPSuAwC8oLHWqgxzdlvBNCVj2DcZY7QDsutVwJLnR/mZRefSwc=
0, 492, d5e7c7bb-39c1-5d05-d099-4af94c5e1508, 5, 10, 3, 3, 5, 1062551, 3825183806, 34af7f978c5a17772867d929e0b800dd2db74608322d73f2f0cfd19cdcaeccc8, 04c14d9db89a3dd8da8a366cf26cd67f1de468fb5dc15f240b0d2b96dbdb5f39af962cb0bdc0bafcc9e523bf5cd4eba420c51758f987457954d32f1003bbaaf1c5, ANXnx7s5wV0F0JlK+UxeFQgVgfG98RQuDK0XKoD66X1m7sPtoqN+quHevsBQQYb0PdoTgJqFhK5d0ffWOVNOntfPHMckUnpoqraUOav4wYCjjhF39ZImldJgT6awp4PLDfglg5JqynANkg+0aFmmow61/NFw4nGlbEnoepMtRkxGmDZ9gxB+fUGZLt1yUgOdKzMy2CHuBwVu6XluiCMfbit+t2EsHUo2cO6o1aiIYg==
1, 202, d5e7c7bb-39c1-5d05-d099-4af94c5e1508, 5, 31, 3, 1, 10, 1062551, 3825183806, 34af7f978c5a17772867d929e0b800dd2db74608322d73f2f0cfd19cdcaeccc8, 04c14d9db89a3dd8da8a366cf26cd67f1de468fb5dc15f240b0d2b96dbdb5f39af962cb0bdc0bafcc9e523bf5cd4eba420c51758f987457954d32f1003bbaaf1c5, ANXnx7s5wV0F0JlK+UxeFQgjNbDa0UL0MlRp6PsAMJj/w32hx3y/VuysjaCYlraWJyst+YvqPjvoD2ebZMHdInWhWeQvYLxnqfaIG5Xu+LuXNNoXPxM7MsACQd00UUgrsqGcfRQMhO9+QbK6UJgXTcNtVdNKleqcZsXkDg3nrI/j6OIOrtccYaEhVGZlVwKiassL5jyiOrW8aDbWW1NRI1vAcdLpAR2YpZ548zW2NQ==
0, 492, 1839f2b2-4765-51fa-6581-3f31ec65f902, 5, 12, 0, 0, 3, 1062694, 3825699763, 34af7f978c5a17772867d929e0b800dd2db74608322d73f2f0cfd19cdcaeccc8, 04c14d9db89a3dd8da8a366cf26cd67f1de468fb5dc15f240b0d2b96dbdb5f39af962cb0bdc0bafcc9e523bf5cd4eba420c51758f987457954d32f1003bbaaf1c5, ABg58rJHZVH6ZYE/Mexl+QJurG0CYm+ONfqfQzxgaxcZo45q7DFGFbCePmkj4pqwPX3ULuF1/3Ze0Do/9DCoPLyltOyxKyvYiTQDBkwrFGu7Tf74vzyTXyWfpILQ78fQnKCEBzcL6EwKGoCT0JMj0hQpLx8Hz8/wMOYwJmBwS7V8RlJtzECWW0cXbBROEwN131bs49SI2SYJJD8/njXUbpZDbl2H8UsRKz+UJLeaUw==
1, 4095, 1839f2b2-4765-51fa-6581-3f31ec65f902, 31, 31, 15, 15, 255, 1062694, 3825699763, 34af7f978c5a17772867d929e0b800dd2db74608322d73f2f0cfd19cdcaeccc8, 04c14d9db89a3dd8da8a366cf26cd67f1de468fb5dc15f240b0d2b96dbdb5f39af962cb0bdc0bafcc9e523bf5cd4eba420c51758f987457954d32f1003bbaaf1c5, ABg58rJHZVH6ZYE/Mexl+QL1+2HNHa4/oxPunA511t5L6RuzvcYJVS1sHo9sElOU6lBM2Q7S2xk651WNcJ3QvDnZuEt91x4usoTYWTBDOG0luCrfs271MNtfl2O01Zf4h7YaYvS1KZ2CAv3gO0yevf/QkUxjtWbNhCFjuJBm2ncz0g+5SMnD9UBQma5ErwOT8cvd8zUjXSKkUzl7CjwkAVnvq/KnXEnxNYSzKOpBbQ==
1, 592, 1839f2b2-4765-51fa-6581-3f31ec65f902, 31, 31, 15, 15, 255, 1062694, 3825699763, 3108f08b1485adb6f72cfba1b55c7484c906a2a3a0a027c78dcd991ca64c97bd, 045f802c016b2d14ef4d7ef01617c67c7506c0cd08aed3e4bcaf34ef5ffaddebb70a073d82c37bc874ce6705cec8b1c4a03b2ccd8f28b0c5034fb8774f2e97b1a4, ABg58rJHZVH6ZYE/Mexl+QKfWe2c6gEJFbNt6CY9ex+NBD5Uw7FeZ4ih1vrOt1Uzjm4dUzJfP7mekEAgpeHiEOjaC0fV+4Oz8QOmhVcD3jmlGlYbmBhNfi2rQDOTJYCiVXeeAC1r+zPt3qveJaA=
0, 492, 1839f2b2-4765-51fa-6581-3f31ec65f902, 5, 10, 3, 3, 5, 1062694, 3825699763, 34af7f978c5a17772867d929e0b800dd2db74608322d73f2f0cfd19cdcaeccc8, 04c14d9db89a3dd8da8a366cf26cd67f1de468fb5dc15f240b0d2b96dbdb5f39af962cb0bdc0bafcc9e523bf5cd4eba420c51758f987457954d32f1003bbaaf1c5, ABg58rJHZVH6ZYE/Mexl+QIYbZTrqIUqb/nQ7T6KIlaSCOfRAYQiE1rW5jwKvnQkKvVoL/7jsMwoNMI1X4BV5+fLo+CzXA1aynoK8cLmWFx75ezbrMxCrGUIE4v7ztokMXe6oBbFRuN6Fy9WzfoPeP20V1FklzuW+3aftxhugsoBipF1UOyd8z6QciGJCgOJORQN4nIe110N1G16c6AMWXgxJ4kxlTV1UG0f2j36hA==
1, 202, 1839f2b2-4765-51fa-6581-3f31ec65f902, 5, 31, 3, 1, 10, 1062694, 3825699763, 34af7f978c5a17772867d929e0b800dd2db74608322d73f2f0cfd19cdcaeccc8, 04c14d9db89a3dd8da8a366cf26cd67f1de468fb5dc15f240b0d2b96dbdb5f39af962cb0bdc0bafcc9e523bf5cd4eba420c51758f987457954d32f1003bbaaf1c5, ABg58rJHZVH6ZYE/Mexl+QJsFq9cuuaa7C34SktDBQgKQRdrpLUgj9XqPJ5FUuj53FHCvNCvsAQ+QKO0VBNMlXSwbgRpBxioeskp4+GWMKUvFSSAW3bvECJWu1oF5copD0mig7+qYGObi5jBuVp18X8JZDLDYljmVALxXWlUNC87xl2I1JbeXn4Qxn8tGAN6A9wOMUsrxrJxB3MDmhpd3qKOmo7BX02hAGT0SlfRhg==
locationPhone, locationPin, t_periodStart, SK_SA, PK_SA, SK_MCTA, PK_MCTA, lsp_base64
33800130000, 01234567, 3825183600, 34af7f978c5a17772867d929e0b800dd2db74608322d73f2f0cfd19cdcaeccc8, 04c14d9db89a3dd8da8a366cf26cd67f1de468fb5dc15f240b0d2b96dbdb5f39af962cb0bdc0bafcc9e523bf5cd4eba420c51758f987457954d32f1003bbaaf1c5, 3108f08b1485adb6f72cfba1b55c7484c906a2a3a0a027c78dcd991ca64c97bd, 045f802c016b2d14ef4d7ef01617c67c7506c0cd08aed3e4bcaf34ef5ffaddebb70a073d82c37bc874ce6705cec8b1c4a03b2ccd8f28b0c5034fb8774f2e97b1a4, ANXnx7s5wV0F0JlK+UxeFQhit4IeKD9oDNEJ3ICWC2r+V9+3lmivN0ASWJ2LY4J7JGhBe7no034i84J0sJAxgc7X/k/pRculBiPHXGi30bw2r+iXRZNQXLWsuNdO3Xz/wRbALxE/WEUyjXK1wPpwQK6gIqRN0wCen6UdKqjMm8RT/jPlQ4HC53WmDWtElwKG1cwMV8IvTqlKWHUB4S4JTHMwZuHeLkDq8M8+O2uodA==
33800130000, 01234567, 3825183600, 34af7f978c5a17772867d929e0b800dd2db74608322d73f2f0cfd19cdcaeccc8, 04c14d9db89a3dd8da8a366cf26cd67f1de468fb5dc15f240b0d2b96dbdb5f39af962cb0bdc0bafcc9e523bf5cd4eba420c51758f987457954d32f1003bbaaf1c5, 3108f08b1485adb6f72cfba1b55c7484c906a2a3a0a027c78dcd991ca64c97bd, 045f802c016b2d14ef4d7ef01617c67c7506c0cd08aed3e4bcaf34ef5ffaddebb70a073d82c37bc874ce6705cec8b1c4a03b2ccd8f28b0c5034fb8774f2e97b1a4, ANXnx7s5wV0F0JlK+UxeFQh4pkn9iw5HsbDWFhRGr/AMgxyDtCeFDNdcLDezLMKNXq+xWK6cZuTvsrRLF1t7rFl7kFxXMIJ385crApGR9dcSCudfurY/qyejYYPC8lXL5+RMZwmeJgiIbjditviTn5OJY2NB2Ppy/EMhKUfnyB9Z69Mu1K8zcFQ0upJwZQOqMaRnoi3B7bEy/YB1/a3zTBDfUUx2usoxeddLFxe0yw==
33800130000, 01234567, 3825183600, 34af7f978c5a17772867d929e0b800dd2db74608322d73f2f0cfd19cdcaeccc8, 04c14d9db89a3dd8da8a366cf26cd67f1de468fb5dc15f240b0d2b96dbdb5f39af962cb0bdc0bafcc9e523bf5cd4eba420c51758f987457954d32f1003bbaaf1c5, 3108f08b1485adb6f72cfba1b55c7484c906a2a3a0a027c78dcd991ca64c97bd, 045f802c016b2d14ef4d7ef01617c67c7506c0cd08aed3e4bcaf34ef5ffaddebb70a073d82c37bc874ce6705cec8b1c4a03b2ccd8f28b0c5034fb8774f2e97b1a4, ANXnx7s5wV0F0JlK+UxeFQgVgfG98RQuDK0XKoD66X1m7sPtoqN+quHevsBQQYb0PdoTgJqFhK5d0ffWOVNOntfPHMckUnpoqraUOav4wYCjjhF39ZImldJgT6awp4PLDfglg5JqynANkg+0aFmmow61/NFw4nGlbEnoepMtRkxGmDZ9gxB+fUGZLt1yUgOdKzMy2CHuBwVu6XluiCMfbit+t2EsHUo2cO6o1aiIYg==
33800130000, 76543210, 3825183600, 34af7f978c5a17772867d929e0b800dd2db74608322d73f2f0cfd19cdcaeccc8, 04c14d9db89a3dd8da8a366cf26cd67f1de468fb5dc15f240b0d2b96dbdb5f39af962cb0bdc0bafcc9e523bf5cd4eba420c51758f987457954d32f1003bbaaf1c5, 3108f08b1485adb6f72cfba1b55c7484c906a2a3a0a027c78dcd991ca64c97bd, 045f802c016b2d14ef4d7ef01617c67c7506c0cd08aed3e4bcaf34ef5ffaddebb70a073d82c37bc874ce6705cec8b1c4a03b2ccd8f28b0c5034fb8774f2e97b1a4, ANXnx7s5wV0F0JlK+UxeFQgjNbDa0UL0MlRp6PsAMJj/w32hx3y/VuysjaCYlraWJyst+YvqPjvoD2ebZMHdInWhWeQvYLxnqfaIG5Xu+LuXNNoXPxM7MsACQd00UUgrsqGcfRQMhO9+QbK6UJgXTcNtVdNKleqcZsXkDg3nrI/j6OIOrtccYaEhVGZlVwKiassL5jyiOrW8aDbWW1NRI1vAcdLpAR2YpZ548zW2NQ==
locationPhone, locationRegion, locationPin, t_periodStart, SK_SA, PK_SA, SK_MCTA, PK_MCTA, lsp_base64
3380013000, 1, 012345, 3825698400, 34af7f978c5a17772867d929e0b800dd2db74608322d73f2f0cfd19cdcaeccc8, 04c14d9db89a3dd8da8a366cf26cd67f1de468fb5dc15f240b0d2b96dbdb5f39af962cb0bdc0bafcc9e523bf5cd4eba420c51758f987457954d32f1003bbaaf1c5, 3108f08b1485adb6f72cfba1b55c7484c906a2a3a0a027c78dcd991ca64c97bd, 045f802c016b2d14ef4d7ef01617c67c7506c0cd08aed3e4bcaf34ef5ffaddebb70a073d82c37bc874ce6705cec8b1c4a03b2ccd8f28b0c5034fb8774f2e97b1a4, ABg58rJHZVH6ZYE/Mexl+QJurG0CYm+ONfqfQzxgaxcZo45q7DFGFbCePmkj4pqwPX3ULuF1/3Ze0Do/9DCoPLyltOyxKyvYiTQDBkwrFGu7Tf74vzyTXyWfpILQ78fQnKCEBzcL6EwKGoCT0JMj0hQpLx8Hz8/wMOYwJmBwS7V8RlJtzECWW0cXbBROEwN131bs49SI2SYJJD8/njXUbpZDbl2H8UsRKz+UJLeaUw==
001122334455667, 255, 012345, 3825698400, 34af7f978c5a17772867d929e0b800dd2db74608322d73f2f0cfd19cdcaeccc8, 04c14d9db89a3dd8da8a366cf26cd67f1de468fb5dc15f240b0d2b96dbdb5f39af962cb0bdc0bafcc9e523bf5cd4eba420c51758f987457954d32f1003bbaaf1c5, 3108f08b1485adb6f72cfba1b55c7484c906a2a3a0a027c78dcd991ca64c97bd, 045f802c016b2d14ef4d7ef01617c67c7506c0cd08aed3e4bcaf34ef5ffaddebb70a073d82c37bc874ce6705cec8b1c4a03b2ccd8f28b0c5034fb8774f2e97b1a4, ABg58rJHZVH6ZYE/Mexl+QL1+2HNHa4/oxPunA511t5L6RuzvcYJVS1sHo9sElOU6lBM2Q7S2xk651WNcJ3QvDnZuEt91x4usoTYWTBDOG0luCrfs271MNtfl2O01Zf4h7YaYvS1KZ2CAv3gO0yevf/QkUxjtWbNhCFjuJBm2ncz0g+5SMnD9UBQma5ErwOT8cvd8zUjXSKkUzl7CjwkAVnvq/KnXEnxNYSzKOpBbQ==
33800130000, 21, 012345, 3825698400, 34af7f978c5a17772867d929e0b800dd2db74608322d73f2f0cfd19cdcaeccc8, 04c14d9db89a3dd8da8a366cf26cd67f1de468fb5dc15f240b0d2b96dbdb5f39af962cb0bdc0bafcc9e523bf5cd4eba420c51758f987457954d32f1003bbaaf1c5, 3108f08b1485adb6f72cfba1b55c7484c906a2a3a0a027c78dcd991ca64c97bd, 045f802c016b2d14ef4d7ef01617c67c7506c0cd08aed3e4bcaf34ef5ffaddebb70a073d82c37bc874ce6705cec8b1c4a03b2ccd8f28b0c5034fb8774f2e97b1a4, ABg58rJHZVH6ZYE/Mexl+QIYbZTrqIUqb/nQ7T6KIlaSCOfRAYQiE1rW5jwKvnQkKvVoL/7jsMwoNMI1X4BV5+fLo+CzXA1aynoK8cLmWFx75ezbrMxCrGUIE4v7ztokMXe6oBbFRuN6Fy9WzfoPeP20V1FklzuW+3aftxhugsoBipF1UOyd8z6QciGJCgOJORQN4nIe110N1G16c6AMWXgxJ4kxlTV1UG0f2j36hA==
33800130000, 12, 543210, 3825698400, 34af7f978c5a17772867d929e0b800dd2db74608322d73f2f0cfd19cdcaeccc8, 04c14d9db89a3dd8da8a366cf26cd67f1de468fb5dc15f240b0d2b96dbdb5f39af962cb0bdc0bafcc9e523bf5cd4eba420c51758f987457954d32f1003bbaaf1c5, 3108f08b1485adb6f72cfba1b55c7484c906a2a3a0a027c78dcd991ca64c97bd, 045f802c016b2d14ef4d7ef01617c67c7506c0cd08aed3e4bcaf34ef5ffaddebb70a073d82c37bc874ce6705cec8b1c4a03b2ccd8f28b0c5034fb8774f2e97b1a4, ABg58rJHZVH6ZYE/Mexl+QJsFq9cuuaa7C34SktDBQgKQRdrpLUgj9XqPJ5FUuj53FHCvNCvsAQ+QKO0VBNMlXSwbgRpBxioeskp4+GWMKUvFSSAW3bvECJWu1oF5copD0mig7+qYGObi5jBuVp18X8JZDLDYljmVALxXWlUNC87xl2I1JbeXn4Qxn8tGAN6A9wOMUsrxrJxB3MDmhpd3qKOmo7BX02hAGT0SlfRhg==
......@@ -105,9 +105,11 @@ async function cleaRenewLSP(config) {
if (config.locContactMsg) {
const phone = parseBcd(config.locContactMsg.locationPhone, 8);
loc_msg.set(phone, 0);
const pin = parseBcd(config.locContactMsg.locationPin, 4);
loc_msg.set(pin, 8);
// Max digit is 15, the last 4 bits are set to 0 (pad)
loc_msg[7] = loc_msg[7] & 0xF0;
loc_msg[8] = config.locContactMsg.locationRegion & 0xFF;
const pin = parseBcd(config.locContactMsg.locationPin, 3);
loc_msg.set(pin, 9);
encrypted_loc_msg = await encrypt(new Uint8Array(0), loc_msg, config.PK_MCTA);
msg.set(new Uint8Array(encrypted_loc_msg), 44);
}
......
......@@ -81,6 +81,18 @@
<label for="locationPhone">Location phone (optional):</label>
<input type="text" id="locationPhone" name="locationPhone"/>
</div>
<div>
<label for="locationRegion">Location Region (mandatory if location phone is present):</label>
<select id="locationRegion">
<option value="10">Auvergne Rhône-Alpes</option>
<option value="11">Bourgogne-Franche-Comté</option>
<option value="12">Centre-Val de Loire</option>
<option value="13">Corse</option>
<option value="14">Grand Est</option>
<option value="15">Hauts-de-France</option>
<option value="16">Ile-de-France</option>
</select>
</div>
<div>
<label for="locationPin">Location PIN (mandatory if location phone is present):</label>
<input type="text" id="locationPin" name="locationPin"/>
......
......@@ -35,7 +35,8 @@
if (phone) {
conf.locContactMsg = {
locationPhone: parseInt(phone),
locationPhone: parseInt(phone),
locationRegion: parseInt($("#locationRegion").val()),
locationPin: parseInt($("#locationPin").val())
}
}
......
......@@ -6,8 +6,9 @@
"venueCategory1": 0,
"venueCategory2": 0,
"periodDuration": 3,
"locationPhone": "33800130000",
"locationPIN": "01234567",
"locationPhone": "3380013000",
"locationRegion": 1,
"locationPIN": "012345",
"SK_SA": "34af7f978c5a17772867d929e0b800dd2db74608322d73f2f0cfd19cdcaeccc8",
"PK_SA": "04c14d9db89a3dd8da8a366cf26cd67f1de468fb5dc15f240b0d2b96dbdb5f39af962cb0bdc0bafcc9e523bf5cd4eba420c51758f987457954d32f1003bbaaf1c5",
"SK_MCTA": "3108f08b1485adb6f72cfba1b55c7484c906a2a3a0a027c78dcd991ca64c97bd",
......@@ -22,8 +23,9 @@
"venueCategory1": 15,
"venueCategory2": 15,
"periodDuration": 255,
"locationPhone": "33800130000",
"locationPIN": "01234567",
"locationPhone": "001122334455667",
"locationRegion": 255,
"locationPIN": "012345",
"SK_SA": "34af7f978c5a17772867d929e0b800dd2db74608322d73f2f0cfd19cdcaeccc8",
"PK_SA": "04c14d9db89a3dd8da8a366cf26cd67f1de468fb5dc15f240b0d2b96dbdb5f39af962cb0bdc0bafcc9e523bf5cd4eba420c51758f987457954d32f1003bbaaf1c5",
"SK_MCTA": "3108f08b1485adb6f72cfba1b55c7484c906a2a3a0a027c78dcd991ca64c97bd",
......@@ -54,7 +56,8 @@
"venueCategory2": 3,
"periodDuration": 5,
"locationPhone": "33800130000",
"locationPIN": "01234567",
"locationRegion": 21,
"locationPIN": "012345",
"SK_SA": "34af7f978c5a17772867d929e0b800dd2db74608322d73f2f0cfd19cdcaeccc8",
"PK_SA": "04c14d9db89a3dd8da8a366cf26cd67f1de468fb5dc15f240b0d2b96dbdb5f39af962cb0bdc0bafcc9e523bf5cd4eba420c51758f987457954d32f1003bbaaf1c5",
"SK_MCTA": "3108f08b1485adb6f72cfba1b55c7484c906a2a3a0a027c78dcd991ca64c97bd",
......@@ -70,7 +73,8 @@
"venueCategory2": 1,
"periodDuration": 10,
"locationPhone": "33800130000",
"locationPIN": "76543210",
"locationRegion": 12,
"locationPIN": "543210",
"SK_SA": "34af7f978c5a17772867d929e0b800dd2db74608322d73f2f0cfd19cdcaeccc8",
"PK_SA": "04c14d9db89a3dd8da8a366cf26cd67f1de468fb5dc15f240b0d2b96dbdb5f39af962cb0bdc0bafcc9e523bf5cd4eba420c51758f987457954d32f1003bbaaf1c5",
"SK_MCTA": "3108f08b1485adb6f72cfba1b55c7484c906a2a3a0a027c78dcd991ca64c97bd",
......
......@@ -23,9 +23,10 @@ async function generateLsps(conf_tests) {
conf.SK_L = hexToBytes(conf.SK_L);
conf.PK_SA = hexToBytes(conf.PK_SA);
conf.PK_MCTA = hexToBytes(conf.PK_MCTA);
if ((("locationPhone" in conf) == true) && (("locationPIN" in conf) == true)) {
if ((("locationPhone" in conf) == true) && (("locationRegion" in conf) == true) && (("locationPIN" in conf) == true)) {
conf['locContactMsg'] = {
locationPhone: conf.locationPhone,
locationRegion: conf.locationRegion,
locationPin: conf.locationPIN
}
}
......
......@@ -11,7 +11,7 @@ and Java LSP decoding
# Java executable can encode or decode
# a Clé location Specific Part (LSP)
CMD_JAVA = ['java', '-cp',
'../java/target/clea-lsp-0.0.1-SNAPSHOT-jar-with-dependencies.jar',
'../java/target/clea-crypto-0.0.1-SNAPSHOT-jar-with-dependencies.jar',
'fr.inria.clea.lsp.LspEncoderDecoder']
# C executable can encode t a Cléa LSP
CMD_C = ['../c/build/test_clea']
......@@ -33,7 +33,9 @@ def run_cmd(cmd_with_args):
subpro.wait()
out = subpro.stdout.read()
outs = out.decode().replace("\n", "")
results = outs.split(' ')
outs = outs.split('=VALUES=')
results = outs[1].split(' ')
return results
......@@ -66,9 +68,11 @@ def lsp_encode(cfg, java=False):
cmd.append(cfg['SK_L'])
phone = cfg.get('locationPhone')
region = cfg.get('locationRegion')
pin = cfg.get('locationPIN')
if (phone is not None and pin is not None):
if (phone is not None and region is not None and pin is not None):
cmd.append(str(phone))
cmd.append(str(region))
cmd.append(str(pin))
vals = run_cmd(cmd)
......@@ -102,7 +106,7 @@ def lsp_decode(cfg):
cmd.append(cfg['SK_SA'])
cmd.append(cfg['SK_MCTA'])
vals = run_cmd(cmd)
if len(vals) == 10 or len(vals) == 12:
if len(vals) == 10 or len(vals) == 13:
lsp_dict = {"staff": int(vals[0]),
"countryCode": int(vals[1]),
"CRIexp": int(vals[2]),
......@@ -115,9 +119,10 @@ def lsp_decode(cfg):
"t_qrStart": int(vals[9]),
"SK_SA": cfg['SK_SA'],
"SK_MCTA": cfg['SK_MCTA']}
if len(vals) == 12:
if len(vals) == 13:
lsp_dict["locationPhone"] = vals[10]
lsp_dict["locationPIN"] = vals[11]
lsp_dict["locationRegion"] = int(vals[11])
lsp_dict["locationPIN"] = vals[12]
else:
lsp_dict = {"Error": "lsp_decode failed"}
return lsp_dict
......@@ -190,10 +195,8 @@ def lsp_cmp(enc_in, enc_out, dec_out):
"""
testok = 0
nbtests = 10
if enc_in.get("Error") is not None or dec_out.get("Error") is not None:
return False
if enc_in['staff'] == dec_out['staff']:
testok += 1
if enc_in['CRIexp'] == dec_out['CRIexp']:
......@@ -215,19 +218,23 @@ def lsp_cmp(enc_in, enc_out, dec_out):
if enc_out['t_qrStart'] == dec_out['t_qrStart']:
testok += 1
nbr = int(enc_in.get('locationPhone') is not None) + \
int(enc_in.get('locationPhone') is not None) + \
int(enc_in.get('locationPIN') is not None) + \
int(enc_in.get('locationRegion') is not None) + \
int(dec_out.get('locationPhone') is not None) + \
int(dec_out.get('locationRegion') is not None) + \
int(dec_out.get('locationPIN') is not None)
if nbr == 4:
nbtests += 2
if nbr == 6:
nbtests += 3
if enc_in['locationPhone'] == dec_out['locationPhone']:
testok += 1
if enc_in['locationRegion'] == dec_out['locationRegion']:
testok += 1
if enc_in['locationPIN'] == dec_out['locationPIN']:
testok += 1
elif nbr != 0:
print('LocationMsg failed')
return False
return testok == nbtests
......@@ -239,8 +246,10 @@ def lsps_cmp(enc_in_file, enc_out_file, dec_out_file, csv_lsp_file, csv_loc_file
enc_out_file: output file in json of the lsp encoder with generated lsp
parameters (time, TLId)
dec_out_file: output file in json of the lsp decoder
csv_lsp_file: save LSP encoding/decoding results to be updated when necessary for junit5 test in ../java/src/test/resources
csv_loc_file: save location encoding/decoding results to be updated when necessary for junit5 test in ../java/src/test/resources
csv_lsp_file: save LSP encoding/decoding results to be updated when necessary
for junit5 test in ../java/src/test/resources
csv_loc_file: save location encoding/decoding results to be updated when necessary
for junit5 test in ../java/src/test/resources
Return
-------
True / False
......@@ -262,17 +271,23 @@ def lsps_cmp(enc_in_file, enc_out_file, dec_out_file, csv_lsp_file, csv_loc_file
if lsp_cmp(enc_in, enc_out, dec_out):
print('TEST PASS:', idx+1)
iok = iok + 1
SEP = ', '
sep = ', '
if csv_lsp_file is not None:
row = str(enc_in['staff']) + SEP + str(enc_in['countryCode']) + SEP + str(enc_out['LTId']) + SEP + str(enc_in['CRIexp']) + SEP
row += str(enc_in['venueType']) + SEP + str(enc_in['venueCategory1']) + SEP + str(enc_in['venueCategory2']) + SEP + str(enc_in['periodDuration']) + SEP
row += str(enc_out['ct_periodStart']) + SEP + str(enc_out['t_qrStart']) + SEP + str(enc_in['SK_SA']) + SEP + str(enc_in['PK_SA']) + SEP + str(enc_out['lsp_base64'])
csv_lsp_file.write(row+ '\n')
if csv_loc_file is not None and enc_in.get('locationPhone') is not None :
row = str(enc_in['locationPhone']) + SEP + str(enc_in['locationPIN']) + SEP + str(enc_out['ct_periodStart'