New GV2 internal prefix and scrubber.

This commit is contained in:
Alan Evans 2020-05-01 16:25:26 -03:00 committed by Greyson Parrelli
parent 456857bbbd
commit ff28d72db6
4 changed files with 61 additions and 30 deletions

View file

@ -14,11 +14,12 @@ import java.security.SecureRandom;
public abstract class GroupId {
private static final String ENCODED_SIGNAL_GROUP_PREFIX = "__textsecure_group__!";
private static final String ENCODED_MMS_GROUP_PREFIX = "__signal_mms_group__!";
private static final int MMS_BYTE_LENGTH = 16;
private static final int V1_MMS_BYTE_LENGTH = 16;
private static final int V2_BYTE_LENGTH = GroupIdentifier.SIZE;
private static final String ENCODED_SIGNAL_GROUP_V1_PREFIX = "__textsecure_group__!";
private static final String ENCODED_SIGNAL_GROUP_V2_PREFIX = "__signal_group__v2__!";
private static final String ENCODED_MMS_GROUP_PREFIX = "__signal_mms_group__!";
private static final int MMS_BYTE_LENGTH = 16;
private static final int V1_MMS_BYTE_LENGTH = 16;
private static final int V2_BYTE_LENGTH = GroupIdentifier.SIZE;
private final String encodedId;
@ -106,7 +107,11 @@ public abstract class GroupId {
byte[] bytes = extractDecodedId(encodedGroupId);
return encodedGroupId.startsWith(ENCODED_MMS_GROUP_PREFIX) ? mms(bytes) : push(bytes);
if (encodedGroupId.startsWith(ENCODED_SIGNAL_GROUP_V2_PREFIX)) return v2(bytes);
else if (encodedGroupId.startsWith(ENCODED_SIGNAL_GROUP_V1_PREFIX)) return v1(bytes);
else if (encodedGroupId.startsWith(ENCODED_MMS_GROUP_PREFIX)) return mms(bytes);
throw new BadGroupIdException();
} catch (IOException e) {
throw new BadGroupIdException(e);
}
@ -129,7 +134,9 @@ public abstract class GroupId {
}
public static boolean isEncodedGroup(@NonNull String groupId) {
return groupId.startsWith(ENCODED_SIGNAL_GROUP_PREFIX) || groupId.startsWith(ENCODED_MMS_GROUP_PREFIX);
return groupId.startsWith(ENCODED_SIGNAL_GROUP_V2_PREFIX) ||
groupId.startsWith(ENCODED_SIGNAL_GROUP_V1_PREFIX) ||
groupId.startsWith(ENCODED_MMS_GROUP_PREFIX);
}
private static byte[] extractDecodedId(@NonNull String encodedGroupId) throws IOException {
@ -220,8 +227,8 @@ public abstract class GroupId {
}
public static abstract class Push extends GroupId {
private Push(@NonNull byte[] bytes) {
super(ENCODED_SIGNAL_GROUP_PREFIX, bytes);
private Push(@NonNull String prefix, @NonNull byte[] bytes) {
super(prefix, bytes);
}
@Override
@ -238,7 +245,7 @@ public abstract class GroupId {
public static final class V1 extends GroupId.Push {
private V1(@NonNull byte[] bytes) {
super(bytes);
super(ENCODED_SIGNAL_GROUP_V1_PREFIX, bytes);
}
@Override
@ -255,7 +262,7 @@ public abstract class GroupId {
public static final class V2 extends GroupId.Push {
private V2(@NonNull byte[] bytes) {
super(bytes);
super(ENCODED_SIGNAL_GROUP_V2_PREFIX, bytes);
}
@Override

View file

@ -17,8 +17,6 @@
package org.thoughtcrime.securesms.logsubmit.util;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import java.util.regex.Matcher;
@ -49,8 +47,14 @@ public final class Scrubber {
/**
* The middle group will be censored.
*/
private static final Pattern GROUP_ID_PATTERN = Pattern.compile("(__)(textsecure_group__![^\\s]+)([^\\s]{2})");
private static final String GROUP_ID_CENSOR = "...group...";
private static final Pattern GROUP_ID_V1_PATTERN = Pattern.compile("(__)(textsecure_group__![^\\s]+)([^\\s]{2})");
private static final String GROUP_ID_V1_CENSOR = "...group...";
/**
* The middle group will be censored.
*/
private static final Pattern GROUP_ID_V2_PATTERN = Pattern.compile("(__)(signal_group__v2__![^\\s]+)([^\\s]{2})");
private static final String GROUP_ID_V2_CENSOR = "...group_v2...";
/**
* The middle group will be censored.
@ -62,7 +66,8 @@ public final class Scrubber {
in = scrubE164(in);
in = scrubEmail(in);
in = scrubGroups(in);
in = scrubGroupsV1(in);
in = scrubGroupsV2(in);
in = scrubUuids(in);
return in;
@ -83,11 +88,19 @@ public final class Scrubber {
.append(EMAIL_CENSOR));
}
private static CharSequence scrubGroups(@NonNull CharSequence in) {
private static CharSequence scrubGroupsV1(@NonNull CharSequence in) {
return scrub(in,
GROUP_ID_PATTERN,
GROUP_ID_V1_PATTERN,
(matcher, output) -> output.append(matcher.group(1))
.append(GROUP_ID_CENSOR)
.append(GROUP_ID_V1_CENSOR)
.append(matcher.group(3)));
}
private static CharSequence scrubGroupsV2(@NonNull CharSequence in) {
return scrub(in,
GROUP_ID_V2_PATTERN,
(matcher, output) -> output.append(matcher.group(1))
.append(GROUP_ID_V2_CENSOR)
.append(matcher.group(3)));
}

View file

@ -45,7 +45,7 @@ public final class GroupIdTest {
public void can_create_for_gv2_from_GroupIdentifier() throws IOException, InvalidInputException {
GroupId.V2 groupId = GroupId.v2(new GroupIdentifier(Hex.fromStringCondensed("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")));
assertEquals("__textsecure_group__!0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", groupId.toString());
assertEquals("__signal_group__v2__!0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", groupId.toString());
assertFalse(groupId.isMms());
assertFalse(groupId.isV1());
assertTrue(groupId.isV2());
@ -58,7 +58,7 @@ public final class GroupIdTest {
GroupId.V2 groupId = GroupId.v2(new GroupMasterKey(Hex.fromStringCondensed("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")));
assertEquals("__textsecure_group__!9f475f59b2518bff6df22e820803f0e3585bd99e686fa7e7fbfc2f92fd5d953e", groupId.toString());
assertEquals("__signal_group__v2__!9f475f59b2518bff6df22e820803f0e3585bd99e686fa7e7fbfc2f92fd5d953e", groupId.toString());
assertFalse(groupId.isMms());
assertFalse(groupId.isV1());
assertTrue(groupId.isV2());
@ -67,9 +67,9 @@ public final class GroupIdTest {
@Test
public void can_parse_gv2() throws IOException {
GroupId groupId = GroupId.parseOrThrow("__textsecure_group__!9f475f59b2518bff6df22e820803f0e3585bd99e686fa7e7fbfc2f92fd5d953e");
GroupId groupId = GroupId.parseOrThrow("__signal_group__v2__!9f475f59b2518bff6df22e820803f0e3585bd99e686fa7e7fbfc2f92fd5d953e");
assertEquals("__textsecure_group__!9f475f59b2518bff6df22e820803f0e3585bd99e686fa7e7fbfc2f92fd5d953e", groupId.toString());
assertEquals("__signal_group__v2__!9f475f59b2518bff6df22e820803f0e3585bd99e686fa7e7fbfc2f92fd5d953e", groupId.toString());
assertArrayEquals(Hex.fromStringCondensed("9f475f59b2518bff6df22e820803f0e3585bd99e686fa7e7fbfc2f92fd5d953e"), groupId.getDecodedId());
assertFalse(groupId.isMms());
assertFalse(groupId.isV1());
@ -145,6 +145,11 @@ public final class GroupIdTest {
GroupId.parseOrThrow("__textsecure_group__!0001020305060708090b0c0d0e0fODD_HEX");
}
@Test(expected = BadGroupIdException.class)
public void bad_encoding__gv2_prefix_with_wrong_length() throws BadGroupIdException {
GroupId.parse("__signal_group__v2__!000102030405060708090a0b0c0d0e0f");
}
@Test
public void get_bytes() {
byte[] bytes = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
@ -212,7 +217,7 @@ public final class GroupIdTest {
@Test
public void require_v2_and_push() {
GroupId groupId = GroupId.parseOrThrow("__textsecure_group__!9f475f59b2518bff6df22e820803f0e3585bd99e686fa7e7fbfc2f92fd5d953e");
GroupId groupId = GroupId.parseOrThrow("__signal_group__v2__!9f475f59b2518bff6df22e820803f0e3585bd99e686fa7e7fbfc2f92fd5d953e");
GroupId.V2 v2 = groupId.requireV2();
GroupId.Push push = groupId.requirePush();
@ -244,7 +249,7 @@ public final class GroupIdTest {
@Test(expected = AssertionError.class)
public void cannot_require_v1_of_v2() throws BadGroupIdException {
GroupId groupId = GroupId.parse("__textsecure_group__!9f475f59b2518bff6df22e820803f0e3585bd99e686fa7e7fbfc2f92fd5d953e");
GroupId groupId = GroupId.parse("__signal_group__v2__!9f475f59b2518bff6df22e820803f0e3585bd99e686fa7e7fbfc2f92fd5d953e");
groupId.requireV1();
}
@ -298,6 +303,6 @@ public final class GroupIdTest {
public void parse_bytes_to_v2_via_by_push() throws BadGroupIdException {
GroupId.V2 v2 = GroupId.push(new byte[]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }).requireV2();
assertEquals("__textsecure_group__!000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f", v2.toString());
assertEquals("__signal_group__v2__!000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f", v2.toString());
}
}

View file

@ -58,11 +58,17 @@ public final class ScrubberTest {
{ "An email and a number abc@def.com +155556789012345",
"An email and a number a...@... +*************45" },
{ "__textsecure_group__!abcdefg1234567890",
"__...group...90" },
{ "__textsecure_group__!000102030405060708090a0b0c0d0e0f",
"__...group...0f" },
{ "A group id __textsecure_group__!abcdefg0987654321 surrounded with text",
"A group id __...group...21 surrounded with text" },
{ "A group id __textsecure_group__!000102030405060708090a0b0c0d0e1a surrounded with text",
"A group id __...group...1a surrounded with text" },
{ "__signal_group__v2__!0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"__...group_v2...ef" },
{ "A group v2 id __signal_group__v2__!23456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01 surrounded with text",
"A group v2 id __...group_v2...01 surrounded with text" },
{ "a37cb654-c9e0-4c1e-93df-3d11ca3c97f4",
"********-****-****-****-**********f4" },