mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-07-07 14:35:29 +01:00
Upgrade libsignal to 0.32.1
This commit is contained in:
+1
@@ -144,6 +144,7 @@ class ConversationItemPreviewer {
|
||||
1024,
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
0,
|
||||
Optional.of("/not-there.jpg"),
|
||||
false,
|
||||
false,
|
||||
|
||||
@@ -149,6 +149,7 @@ object TestMessages {
|
||||
1024,
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
0,
|
||||
Optional.of("/not-there.jpg"),
|
||||
false,
|
||||
false,
|
||||
@@ -171,6 +172,7 @@ object TestMessages {
|
||||
1024,
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
0,
|
||||
Optional.of("/not-there.aac"),
|
||||
true,
|
||||
false,
|
||||
|
||||
@@ -48,6 +48,7 @@ public abstract class Attachment {
|
||||
private final int height;
|
||||
private final boolean quote;
|
||||
private final long uploadTimestamp;
|
||||
private final int incrementalMacChunkSize;
|
||||
|
||||
@Nullable
|
||||
private final String caption;
|
||||
@@ -80,6 +81,7 @@ public abstract class Attachment {
|
||||
boolean videoGif,
|
||||
int width,
|
||||
int height,
|
||||
int incrementalMacChunkSize,
|
||||
boolean quote,
|
||||
long uploadTimestamp,
|
||||
@Nullable String caption,
|
||||
@@ -88,29 +90,30 @@ public abstract class Attachment {
|
||||
@Nullable AudioHash audioHash,
|
||||
@Nullable TransformProperties transformProperties)
|
||||
{
|
||||
this.contentType = contentType;
|
||||
this.transferState = transferState;
|
||||
this.size = size;
|
||||
this.fileName = fileName;
|
||||
this.cdnNumber = cdnNumber;
|
||||
this.location = location;
|
||||
this.key = key;
|
||||
this.relay = relay;
|
||||
this.digest = digest;
|
||||
this.incrementalDigest = incrementalDigest;
|
||||
this.fastPreflightId = fastPreflightId;
|
||||
this.voiceNote = voiceNote;
|
||||
this.borderless = borderless;
|
||||
this.videoGif = videoGif;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.quote = quote;
|
||||
this.uploadTimestamp = uploadTimestamp;
|
||||
this.stickerLocator = stickerLocator;
|
||||
this.caption = caption;
|
||||
this.blurHash = blurHash;
|
||||
this.audioHash = audioHash;
|
||||
this.transformProperties = transformProperties != null ? transformProperties : TransformProperties.empty();
|
||||
this.contentType = contentType;
|
||||
this.transferState = transferState;
|
||||
this.size = size;
|
||||
this.fileName = fileName;
|
||||
this.cdnNumber = cdnNumber;
|
||||
this.location = location;
|
||||
this.key = key;
|
||||
this.relay = relay;
|
||||
this.digest = digest;
|
||||
this.incrementalDigest = incrementalDigest;
|
||||
this.fastPreflightId = fastPreflightId;
|
||||
this.voiceNote = voiceNote;
|
||||
this.borderless = borderless;
|
||||
this.videoGif = videoGif;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.incrementalMacChunkSize = incrementalMacChunkSize;
|
||||
this.quote = quote;
|
||||
this.uploadTimestamp = uploadTimestamp;
|
||||
this.stickerLocator = stickerLocator;
|
||||
this.caption = caption;
|
||||
this.blurHash = blurHash;
|
||||
this.audioHash = audioHash;
|
||||
this.transformProperties = transformProperties != null ? transformProperties : TransformProperties.empty();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -200,6 +203,10 @@ public abstract class Attachment {
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getIncrementalMacChunkSize() {
|
||||
return incrementalMacChunkSize;
|
||||
}
|
||||
|
||||
public boolean isQuote() {
|
||||
return quote;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ public class DatabaseAttachment extends Attachment {
|
||||
String relay,
|
||||
byte[] digest,
|
||||
byte[] incrementalDigest,
|
||||
int incrementalMacChunkSize,
|
||||
String fastPreflightId,
|
||||
boolean voiceNote,
|
||||
boolean borderless,
|
||||
@@ -50,7 +51,7 @@ public class DatabaseAttachment extends Attachment {
|
||||
int displayOrder,
|
||||
long uploadTimestamp)
|
||||
{
|
||||
super(contentType, transferProgress, size, fileName, cdnNumber, location, key, relay, digest, incrementalDigest, fastPreflightId, voiceNote, borderless, videoGif, width, height, quote, uploadTimestamp, caption, stickerLocator, blurHash, audioHash, transformProperties);
|
||||
super(contentType, transferProgress, size, fileName, cdnNumber, location, key, relay, digest, incrementalDigest, fastPreflightId, voiceNote, borderless, videoGif, width, height, incrementalMacChunkSize, quote, uploadTimestamp, caption, stickerLocator, blurHash, audioHash, transformProperties);
|
||||
this.attachmentId = attachmentId;
|
||||
this.hasData = hasData;
|
||||
this.hasThumbnail = hasThumbnail;
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ import org.thoughtcrime.securesms.database.MessageTable;
|
||||
public class MmsNotificationAttachment extends Attachment {
|
||||
|
||||
public MmsNotificationAttachment(int status, long size) {
|
||||
super("application/mms", getTransferStateFromStatus(status), size, null, 0, null, null, null, null, null, null, false, false, false, 0, 0, false, 0, null, null, null, null, null);
|
||||
super("application/mms", getTransferStateFromStatus(status), size, null, 0, null, null, null, null, null, null, false, false, false, 0, 0, 0, false, 0, null, null, null, null, null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -31,6 +31,7 @@ public class PointerAttachment extends Attachment {
|
||||
@Nullable String relay,
|
||||
@Nullable byte[] digest,
|
||||
@Nullable byte[] incrementalDigest,
|
||||
int incrementalMacChunkSize,
|
||||
@Nullable String fastPreflightId,
|
||||
boolean voiceNote,
|
||||
boolean borderless,
|
||||
@@ -42,7 +43,7 @@ public class PointerAttachment extends Attachment {
|
||||
@Nullable StickerLocator stickerLocator,
|
||||
@Nullable BlurHash blurHash)
|
||||
{
|
||||
super(contentType, transferState, size, fileName, cdnNumber, location, key, relay, digest, incrementalDigest, fastPreflightId, voiceNote, borderless, videoGif, width, height, false, uploadTimestamp, caption, stickerLocator, blurHash, null, null);
|
||||
super(contentType, transferState, size, fileName, cdnNumber, location, key, relay, digest, incrementalDigest, fastPreflightId, voiceNote, borderless, videoGif, width, height, incrementalMacChunkSize, false, uploadTimestamp, caption, stickerLocator, blurHash, null, null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -111,9 +112,11 @@ public class PointerAttachment extends Attachment {
|
||||
pointer.get().asPointer().getFileName().orElse(null),
|
||||
pointer.get().asPointer().getCdnNumber(),
|
||||
pointer.get().asPointer().getRemoteId().toString(),
|
||||
encodedKey, null,
|
||||
encodedKey,
|
||||
null,
|
||||
pointer.get().asPointer().getDigest().orElse(null),
|
||||
pointer.get().asPointer().getIncrementalDigest().orElse(null),
|
||||
pointer.get().asPointer().getIncrementalMacChunkSize(),
|
||||
fastPreflightId,
|
||||
pointer.get().asPointer().getVoiceNote(),
|
||||
pointer.get().asPointer().isBorderless(),
|
||||
@@ -140,6 +143,7 @@ public class PointerAttachment extends Attachment {
|
||||
null,
|
||||
thumbnail != null ? thumbnail.asPointer().getDigest().orElse(null) : null,
|
||||
thumbnail != null ? thumbnail.asPointer().getIncrementalDigest().orElse(null) : null,
|
||||
thumbnail != null ? thumbnail.asPointer().getIncrementalMacChunkSize() : 0,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
@@ -170,6 +174,7 @@ public class PointerAttachment extends Attachment {
|
||||
null,
|
||||
thumbnail != null ? thumbnail.asPointer().getDigest().orElse(null) : null,
|
||||
thumbnail != null ? thumbnail.asPointer().getIncrementalDigest().orElse(null) : null,
|
||||
thumbnail != null ? thumbnail.asPointer().getIncrementalMacChunkSize() : 0,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
|
||||
@@ -16,7 +16,7 @@ import org.thoughtcrime.securesms.database.AttachmentTable;
|
||||
public class TombstoneAttachment extends Attachment {
|
||||
|
||||
public TombstoneAttachment(@NonNull String contentType, boolean quote) {
|
||||
super(contentType, AttachmentTable.TRANSFER_PROGRESS_DONE, 0, null, 0, null, null, null, null, null, null, false, false, false, 0, 0, quote, 0, null, null, null, null, null);
|
||||
super(contentType, AttachmentTable.TRANSFER_PROGRESS_DONE, 0, null, 0, null, null, null, null, null, null, false, false, false, 0, 0, 0, quote, 0, null, null, null, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -52,7 +52,7 @@ public class UriAttachment extends Attachment {
|
||||
@Nullable AudioHash audioHash,
|
||||
@Nullable TransformProperties transformProperties)
|
||||
{
|
||||
super(contentType, transferState, size, fileName, 0, null, null, null, null, null, fastPreflightId, voiceNote, borderless, videoGif, width, height, quote, 0, caption, stickerLocator, blurHash, audioHash, transformProperties);
|
||||
super(contentType, transferState, size, fileName, 0, null, null, null, null, null, fastPreflightId, voiceNote, borderless, videoGif, width, height, 0, quote, 0, caption, stickerLocator, blurHash, audioHash, transformProperties);
|
||||
this.dataUri = Objects.requireNonNull(dataUri);
|
||||
}
|
||||
|
||||
|
||||
@@ -92,41 +92,42 @@ public class AttachmentTable extends DatabaseTable {
|
||||
|
||||
public static final String TAG = Log.tag(AttachmentTable.class);
|
||||
|
||||
public static final String TABLE_NAME = "part";
|
||||
public static final String ROW_ID = "_id";
|
||||
static final String ATTACHMENT_JSON_ALIAS = "attachment_json";
|
||||
public static final String MMS_ID = "mid";
|
||||
static final String CONTENT_TYPE = "ct";
|
||||
static final String NAME = "name";
|
||||
static final String CONTENT_DISPOSITION = "cd";
|
||||
static final String CONTENT_LOCATION = "cl";
|
||||
public static final String DATA = "_data";
|
||||
static final String TRANSFER_STATE = "pending_push";
|
||||
public static final String TRANSFER_FILE = "transfer_file";
|
||||
public static final String SIZE = "data_size";
|
||||
static final String FILE_NAME = "file_name";
|
||||
public static final String UNIQUE_ID = "unique_id";
|
||||
static final String DIGEST = "digest";
|
||||
static final String VOICE_NOTE = "voice_note";
|
||||
static final String BORDERLESS = "borderless";
|
||||
static final String VIDEO_GIF = "video_gif";
|
||||
static final String QUOTE = "quote";
|
||||
public static final String STICKER_PACK_ID = "sticker_pack_id";
|
||||
public static final String STICKER_PACK_KEY = "sticker_pack_key";
|
||||
static final String STICKER_ID = "sticker_id";
|
||||
static final String STICKER_EMOJI = "sticker_emoji";
|
||||
static final String FAST_PREFLIGHT_ID = "fast_preflight_id";
|
||||
public static final String DATA_RANDOM = "data_random";
|
||||
static final String WIDTH = "width";
|
||||
static final String HEIGHT = "height";
|
||||
static final String CAPTION = "caption";
|
||||
static final String DATA_HASH = "data_hash";
|
||||
static final String VISUAL_HASH = "blur_hash";
|
||||
static final String TRANSFORM_PROPERTIES = "transform_properties";
|
||||
static final String DISPLAY_ORDER = "display_order";
|
||||
static final String UPLOAD_TIMESTAMP = "upload_timestamp";
|
||||
static final String CDN_NUMBER = "cdn_number";
|
||||
static final String MAC_DIGEST = "incremental_mac_digest";
|
||||
public static final String TABLE_NAME = "part";
|
||||
public static final String ROW_ID = "_id";
|
||||
static final String ATTACHMENT_JSON_ALIAS = "attachment_json";
|
||||
public static final String MMS_ID = "mid";
|
||||
static final String CONTENT_TYPE = "ct";
|
||||
static final String NAME = "name";
|
||||
static final String CONTENT_DISPOSITION = "cd";
|
||||
static final String CONTENT_LOCATION = "cl";
|
||||
public static final String DATA = "_data";
|
||||
static final String TRANSFER_STATE = "pending_push";
|
||||
public static final String TRANSFER_FILE = "transfer_file";
|
||||
public static final String SIZE = "data_size";
|
||||
static final String FILE_NAME = "file_name";
|
||||
public static final String UNIQUE_ID = "unique_id";
|
||||
static final String DIGEST = "digest";
|
||||
static final String VOICE_NOTE = "voice_note";
|
||||
static final String BORDERLESS = "borderless";
|
||||
static final String VIDEO_GIF = "video_gif";
|
||||
static final String QUOTE = "quote";
|
||||
public static final String STICKER_PACK_ID = "sticker_pack_id";
|
||||
public static final String STICKER_PACK_KEY = "sticker_pack_key";
|
||||
static final String STICKER_ID = "sticker_id";
|
||||
static final String STICKER_EMOJI = "sticker_emoji";
|
||||
static final String FAST_PREFLIGHT_ID = "fast_preflight_id";
|
||||
public static final String DATA_RANDOM = "data_random";
|
||||
static final String WIDTH = "width";
|
||||
static final String HEIGHT = "height";
|
||||
static final String CAPTION = "caption";
|
||||
static final String DATA_HASH = "data_hash";
|
||||
static final String VISUAL_HASH = "blur_hash";
|
||||
static final String TRANSFORM_PROPERTIES = "transform_properties";
|
||||
static final String DISPLAY_ORDER = "display_order";
|
||||
static final String UPLOAD_TIMESTAMP = "upload_timestamp";
|
||||
static final String CDN_NUMBER = "cdn_number";
|
||||
static final String MAC_DIGEST = "incremental_mac_digest";
|
||||
static final String INCREMENTAL_MAC_CHUNK_SIZE = "incremental_mac_chunk_size";
|
||||
|
||||
private static final String DIRECTORY = "parts";
|
||||
|
||||
@@ -144,53 +145,54 @@ public class AttachmentTable extends DatabaseTable {
|
||||
private static final String[] PROJECTION = new String[] {ROW_ID,
|
||||
MMS_ID, CONTENT_TYPE, NAME, CONTENT_DISPOSITION,
|
||||
CDN_NUMBER, CONTENT_LOCATION, DATA,
|
||||
TRANSFER_STATE, SIZE, FILE_NAME, UNIQUE_ID, DIGEST, MAC_DIGEST,
|
||||
TRANSFER_STATE, SIZE, FILE_NAME, UNIQUE_ID, DIGEST, MAC_DIGEST, INCREMENTAL_MAC_CHUNK_SIZE,
|
||||
FAST_PREFLIGHT_ID, VOICE_NOTE, BORDERLESS, VIDEO_GIF, QUOTE, DATA_RANDOM,
|
||||
WIDTH, HEIGHT, CAPTION, STICKER_PACK_ID,
|
||||
STICKER_PACK_KEY, STICKER_ID, STICKER_EMOJI, DATA_HASH, VISUAL_HASH,
|
||||
TRANSFORM_PROPERTIES, TRANSFER_FILE, DISPLAY_ORDER,
|
||||
UPLOAD_TIMESTAMP };
|
||||
|
||||
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ROW_ID + " INTEGER PRIMARY KEY, " +
|
||||
MMS_ID + " INTEGER, " +
|
||||
"seq" + " INTEGER DEFAULT 0, " +
|
||||
CONTENT_TYPE + " TEXT, " +
|
||||
NAME + " TEXT, " +
|
||||
"chset" + " INTEGER, " +
|
||||
CONTENT_DISPOSITION + " TEXT, " +
|
||||
"fn" + " TEXT, " +
|
||||
"cid" + " TEXT, " +
|
||||
CONTENT_LOCATION + " TEXT, " +
|
||||
"ctt_s" + " INTEGER, " +
|
||||
"ctt_t" + " TEXT, " +
|
||||
"encrypted" + " INTEGER, " +
|
||||
TRANSFER_STATE + " INTEGER, " +
|
||||
DATA + " TEXT, " +
|
||||
SIZE + " INTEGER, " +
|
||||
FILE_NAME + " TEXT, " +
|
||||
UNIQUE_ID + " INTEGER NOT NULL, " +
|
||||
DIGEST + " BLOB, " +
|
||||
FAST_PREFLIGHT_ID + " TEXT, " +
|
||||
VOICE_NOTE + " INTEGER DEFAULT 0, " +
|
||||
BORDERLESS + " INTEGER DEFAULT 0, " +
|
||||
VIDEO_GIF + " INTEGER DEFAULT 0, " +
|
||||
DATA_RANDOM + " BLOB, " +
|
||||
QUOTE + " INTEGER DEFAULT 0, " +
|
||||
WIDTH + " INTEGER DEFAULT 0, " +
|
||||
HEIGHT + " INTEGER DEFAULT 0, " +
|
||||
CAPTION + " TEXT DEFAULT NULL, " +
|
||||
STICKER_PACK_ID + " TEXT DEFAULT NULL, " +
|
||||
STICKER_PACK_KEY + " DEFAULT NULL, " +
|
||||
STICKER_ID + " INTEGER DEFAULT -1, " +
|
||||
STICKER_EMOJI + " STRING DEFAULT NULL, " +
|
||||
DATA_HASH + " TEXT DEFAULT NULL, " +
|
||||
VISUAL_HASH + " TEXT DEFAULT NULL, " +
|
||||
TRANSFORM_PROPERTIES + " TEXT DEFAULT NULL, " +
|
||||
TRANSFER_FILE + " TEXT DEFAULT NULL, " +
|
||||
DISPLAY_ORDER + " INTEGER DEFAULT 0, " +
|
||||
UPLOAD_TIMESTAMP + " INTEGER DEFAULT 0, " +
|
||||
CDN_NUMBER + " INTEGER DEFAULT 0, " +
|
||||
MAC_DIGEST + " BLOB);";
|
||||
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ROW_ID + " INTEGER PRIMARY KEY, " +
|
||||
MMS_ID + " INTEGER, " +
|
||||
"seq" + " INTEGER DEFAULT 0, " +
|
||||
CONTENT_TYPE + " TEXT, " +
|
||||
NAME + " TEXT, " +
|
||||
"chset" + " INTEGER, " +
|
||||
CONTENT_DISPOSITION + " TEXT, " +
|
||||
"fn" + " TEXT, " +
|
||||
"cid" + " TEXT, " +
|
||||
CONTENT_LOCATION + " TEXT, " +
|
||||
"ctt_s" + " INTEGER, " +
|
||||
"ctt_t" + " TEXT, " +
|
||||
"encrypted" + " INTEGER, " +
|
||||
TRANSFER_STATE + " INTEGER, " +
|
||||
DATA + " TEXT, " +
|
||||
SIZE + " INTEGER, " +
|
||||
FILE_NAME + " TEXT, " +
|
||||
UNIQUE_ID + " INTEGER NOT NULL, " +
|
||||
DIGEST + " BLOB, " +
|
||||
FAST_PREFLIGHT_ID + " TEXT, " +
|
||||
VOICE_NOTE + " INTEGER DEFAULT 0, " +
|
||||
BORDERLESS + " INTEGER DEFAULT 0, " +
|
||||
VIDEO_GIF + " INTEGER DEFAULT 0, " +
|
||||
DATA_RANDOM + " BLOB, " +
|
||||
QUOTE + " INTEGER DEFAULT 0, " +
|
||||
WIDTH + " INTEGER DEFAULT 0, " +
|
||||
HEIGHT + " INTEGER DEFAULT 0, " +
|
||||
CAPTION + " TEXT DEFAULT NULL, " +
|
||||
STICKER_PACK_ID + " TEXT DEFAULT NULL, " +
|
||||
STICKER_PACK_KEY + " DEFAULT NULL, " +
|
||||
STICKER_ID + " INTEGER DEFAULT -1, " +
|
||||
STICKER_EMOJI + " STRING DEFAULT NULL, " +
|
||||
DATA_HASH + " TEXT DEFAULT NULL, " +
|
||||
VISUAL_HASH + " TEXT DEFAULT NULL, " +
|
||||
TRANSFORM_PROPERTIES + " TEXT DEFAULT NULL, " +
|
||||
TRANSFER_FILE + " TEXT DEFAULT NULL, " +
|
||||
DISPLAY_ORDER + " INTEGER DEFAULT 0, " +
|
||||
UPLOAD_TIMESTAMP + " INTEGER DEFAULT 0, " +
|
||||
CDN_NUMBER + " INTEGER DEFAULT 0, " +
|
||||
MAC_DIGEST + " BLOB, " +
|
||||
INCREMENTAL_MAC_CHUNK_SIZE + " INTEGER DEFAULT 0);";
|
||||
|
||||
public static final String[] CREATE_INDEXS = {
|
||||
"CREATE INDEX IF NOT EXISTS part_mms_id_index ON " + TABLE_NAME + " (" + MMS_ID + ");",
|
||||
@@ -728,6 +730,7 @@ public class AttachmentTable extends DatabaseTable {
|
||||
contentValues.put(CONTENT_LOCATION, sourceAttachment.getLocation());
|
||||
contentValues.put(DIGEST, sourceAttachment.getDigest());
|
||||
contentValues.put(MAC_DIGEST, sourceAttachment.getIncrementalDigest());
|
||||
contentValues.put(INCREMENTAL_MAC_CHUNK_SIZE, sourceAttachment.getIncrementalMacChunkSize());
|
||||
contentValues.put(CONTENT_DISPOSITION, sourceAttachment.getKey());
|
||||
contentValues.put(NAME, sourceAttachment.getRelay());
|
||||
contentValues.put(SIZE, sourceAttachment.getSize());
|
||||
@@ -777,6 +780,7 @@ public class AttachmentTable extends DatabaseTable {
|
||||
values.put(CONTENT_LOCATION, attachment.getLocation());
|
||||
values.put(DIGEST, attachment.getDigest());
|
||||
values.put(MAC_DIGEST, attachment.getIncrementalDigest());
|
||||
values.put(INCREMENTAL_MAC_CHUNK_SIZE, attachment.getIncrementalMacChunkSize());
|
||||
values.put(CONTENT_DISPOSITION, attachment.getKey());
|
||||
values.put(NAME, attachment.getRelay());
|
||||
values.put(SIZE, attachment.getSize());
|
||||
@@ -1309,6 +1313,7 @@ public class AttachmentTable extends DatabaseTable {
|
||||
object.getString(NAME),
|
||||
null,
|
||||
null,
|
||||
0,
|
||||
object.getString(FAST_PREFLIGHT_ID),
|
||||
object.getInt(VOICE_NOTE) == 1,
|
||||
object.getInt(BORDERLESS) == 1,
|
||||
@@ -1357,6 +1362,7 @@ public class AttachmentTable extends DatabaseTable {
|
||||
cursor.getString(cursor.getColumnIndexOrThrow(NAME)),
|
||||
cursor.getBlob(cursor.getColumnIndexOrThrow(DIGEST)),
|
||||
cursor.getBlob(cursor.getColumnIndexOrThrow(MAC_DIGEST)),
|
||||
cursor.getInt(cursor.getColumnIndexOrThrow(INCREMENTAL_MAC_CHUNK_SIZE)),
|
||||
cursor.getString(cursor.getColumnIndexOrThrow(FAST_PREFLIGHT_ID)),
|
||||
cursor.getInt(cursor.getColumnIndexOrThrow(VOICE_NOTE)) == 1,
|
||||
cursor.getInt(cursor.getColumnIndexOrThrow(BORDERLESS)) == 1,
|
||||
@@ -1429,6 +1435,7 @@ public class AttachmentTable extends DatabaseTable {
|
||||
contentValues.put(CONTENT_LOCATION, useTemplateUpload ? template.getLocation() : attachment.getLocation());
|
||||
contentValues.put(DIGEST, useTemplateUpload ? template.getDigest() : attachment.getDigest());
|
||||
contentValues.put(MAC_DIGEST, useTemplateUpload ? template.getIncrementalDigest() : attachment.getIncrementalDigest());
|
||||
contentValues.put(INCREMENTAL_MAC_CHUNK_SIZE, useTemplateUpload ? template.getIncrementalMacChunkSize() : attachment.getIncrementalMacChunkSize());
|
||||
contentValues.put(CONTENT_DISPOSITION, useTemplateUpload ? template.getKey() : attachment.getKey());
|
||||
contentValues.put(NAME, useTemplateUpload ? template.getRelay() : attachment.getRelay());
|
||||
contentValues.put(FILE_NAME, StorageUtil.getCleanFileName(attachment.getFileName()));
|
||||
|
||||
@@ -50,6 +50,7 @@ class MediaTable internal constructor(context: Context?, databaseHelper: SignalD
|
||||
${AttachmentTable.TABLE_NAME}.${AttachmentTable.NAME},
|
||||
${AttachmentTable.TABLE_NAME}.${AttachmentTable.UPLOAD_TIMESTAMP},
|
||||
${AttachmentTable.TABLE_NAME}.${AttachmentTable.MAC_DIGEST},
|
||||
${AttachmentTable.TABLE_NAME}.${AttachmentTable.INCREMENTAL_MAC_CHUNK_SIZE},
|
||||
${MessageTable.TABLE_NAME}.${MessageTable.TYPE},
|
||||
${MessageTable.TABLE_NAME}.${MessageTable.DATE_SENT},
|
||||
${MessageTable.TABLE_NAME}.${MessageTable.DATE_RECEIVED},
|
||||
@@ -57,7 +58,7 @@ class MediaTable internal constructor(context: Context?, databaseHelper: SignalD
|
||||
${MessageTable.TABLE_NAME}.${MessageTable.THREAD_ID},
|
||||
${MessageTable.TABLE_NAME}.${MessageTable.FROM_RECIPIENT_ID},
|
||||
${ThreadTable.TABLE_NAME}.${ThreadTable.RECIPIENT_ID} as $THREAD_RECIPIENT_ID
|
||||
FROM
|
||||
FROM
|
||||
${AttachmentTable.TABLE_NAME}
|
||||
LEFT JOIN ${MessageTable.TABLE_NAME} ON ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MMS_ID} = ${MessageTable.TABLE_NAME}.${MessageTable.ID}
|
||||
LEFT JOIN ${ThreadTable.TABLE_NAME} ON ${ThreadTable.TABLE_NAME}.${ThreadTable.ID} = ${MessageTable.TABLE_NAME}.${MessageTable.THREAD_ID}
|
||||
|
||||
+6
-1
@@ -62,6 +62,7 @@ import org.thoughtcrime.securesms.database.helpers.migration.V203_PreKeyStaleTim
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V204_GroupForeignKeyMigration
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V205_DropPushTable
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V206_AddConversationCountIndex
|
||||
import org.thoughtcrime.securesms.database.helpers.migration.V207_AddChunkSizeColumn
|
||||
|
||||
/**
|
||||
* Contains all of the database migrations for [SignalDatabase]. Broken into a separate file for cleanliness.
|
||||
@@ -70,7 +71,7 @@ object SignalDatabaseMigrations {
|
||||
|
||||
val TAG: String = Log.tag(SignalDatabaseMigrations.javaClass)
|
||||
|
||||
const val DATABASE_VERSION = 206
|
||||
const val DATABASE_VERSION = 207
|
||||
|
||||
@JvmStatic
|
||||
fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
@@ -305,6 +306,10 @@ object SignalDatabaseMigrations {
|
||||
if (oldVersion < 206) {
|
||||
V206_AddConversationCountIndex.migrate(context, db, oldVersion, newVersion)
|
||||
}
|
||||
|
||||
if (oldVersion < 207) {
|
||||
V207_AddChunkSizeColumn.migrate(context, db, oldVersion, newVersion)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.database.helpers.migration
|
||||
|
||||
import android.app.Application
|
||||
import net.zetetic.database.sqlcipher.SQLiteDatabase
|
||||
|
||||
/**
|
||||
* New field migration.
|
||||
*/
|
||||
@Suppress("ClassName")
|
||||
object V207_AddChunkSizeColumn : SignalDatabaseMigration {
|
||||
override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
db.execSQL("ALTER TABLE part ADD COLUMN incremental_mac_chunk_size INTEGER DEFAULT 0")
|
||||
}
|
||||
}
|
||||
@@ -248,6 +248,7 @@ public final class AttachmentDownloadJob extends BaseJob {
|
||||
0, 0,
|
||||
Optional.ofNullable(attachment.getDigest()),
|
||||
Optional.ofNullable(attachment.getIncrementalDigest()),
|
||||
attachment.getIncrementalMacChunkSize(),
|
||||
Optional.ofNullable(attachment.getFileName()),
|
||||
attachment.isVoiceNote(),
|
||||
attachment.isBorderless(),
|
||||
|
||||
@@ -85,7 +85,7 @@ public final class AvatarGroupsV1DownloadJob extends BaseJob {
|
||||
attachment.deleteOnExit();
|
||||
|
||||
SignalServiceMessageReceiver receiver = ApplicationDependencies.getSignalServiceMessageReceiver();
|
||||
SignalServiceAttachmentPointer pointer = new SignalServiceAttachmentPointer(0, new SignalServiceAttachmentRemoteId(avatarId), contentType, key, Optional.of(0), Optional.empty(), 0, 0, digest, Optional.empty(), fileName, false, false, false, Optional.empty(), Optional.empty(), System.currentTimeMillis());
|
||||
SignalServiceAttachmentPointer pointer = new SignalServiceAttachmentPointer(0, new SignalServiceAttachmentRemoteId(avatarId), contentType, key, Optional.of(0), Optional.empty(), 0, 0, digest, Optional.empty(), 0, fileName, false, false, false, Optional.empty(), Optional.empty(), System.currentTimeMillis());
|
||||
InputStream inputStream = receiver.retrieveAttachment(pointer, attachment, AvatarHelper.AVATAR_DOWNLOAD_FAILSAFE_MAX_SIZE);
|
||||
|
||||
AvatarHelper.setAvatar(context, record.get().getRecipientId(), inputStream);
|
||||
|
||||
@@ -284,6 +284,7 @@ public abstract class PushSendJob extends SendJob {
|
||||
height,
|
||||
Optional.ofNullable(attachment.getDigest()),
|
||||
Optional.ofNullable(attachment.getIncrementalDigest()),
|
||||
attachment.getIncrementalMacChunkSize(),
|
||||
Optional.ofNullable(attachment.getFileName()),
|
||||
attachment.isVoiceNote(),
|
||||
attachment.isBorderless(),
|
||||
|
||||
+9
-8
@@ -7,7 +7,6 @@ import com.bumptech.glide.load.DataSource;
|
||||
import com.bumptech.glide.load.data.DataFetcher;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.signal.libsignal.protocol.InvalidMacException;
|
||||
import org.signal.libsignal.protocol.InvalidMessageException;
|
||||
import org.whispersystems.signalservice.api.crypto.AttachmentCipherInputStream;
|
||||
|
||||
@@ -24,23 +23,25 @@ class AttachmentStreamLocalUriFetcher implements DataFetcher<InputStream> {
|
||||
private final byte[] key;
|
||||
private final Optional<byte[]> digest;
|
||||
private final Optional<byte[]> incrementalDigest;
|
||||
private final int incrementalMacChunkSize;
|
||||
private final long plaintextLength;
|
||||
|
||||
private InputStream is;
|
||||
|
||||
AttachmentStreamLocalUriFetcher(File attachment, long plaintextLength, byte[] key, Optional<byte[]> digest, Optional<byte[]> incrementalDigest) {
|
||||
this.attachment = attachment;
|
||||
this.plaintextLength = plaintextLength;
|
||||
this.digest = digest;
|
||||
this.incrementalDigest = incrementalDigest;
|
||||
this.key = key;
|
||||
AttachmentStreamLocalUriFetcher(File attachment, long plaintextLength, byte[] key, Optional<byte[]> digest, Optional<byte[]> incrementalDigest, int incrementalMacChunkSize) {
|
||||
this.attachment = attachment;
|
||||
this.plaintextLength = plaintextLength;
|
||||
this.digest = digest;
|
||||
this.incrementalDigest = incrementalDigest;
|
||||
this.incrementalMacChunkSize = incrementalMacChunkSize;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadData(@NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) {
|
||||
try {
|
||||
if (!digest.isPresent()) throw new InvalidMessageException("No attachment digest!");
|
||||
is = AttachmentCipherInputStream.createForAttachment(attachment, plaintextLength, key, digest.get(), incrementalDigest.orElse(null));
|
||||
is = AttachmentCipherInputStream.createForAttachment(attachment, plaintextLength, key, digest.get(), incrementalDigest.orElse(null), incrementalMacChunkSize);
|
||||
callback.onDataReady(is);
|
||||
} catch (IOException | InvalidMessageException e) {
|
||||
callback.onLoadFailed(e);
|
||||
|
||||
@@ -20,7 +20,7 @@ public class AttachmentStreamUriLoader implements ModelLoader<AttachmentModel, I
|
||||
|
||||
@Override
|
||||
public @Nullable LoadData<InputStream> buildLoadData(@NonNull AttachmentModel attachmentModel, int width, int height, @NonNull Options options) {
|
||||
return new LoadData<>(attachmentModel, new AttachmentStreamLocalUriFetcher(attachmentModel.attachment, attachmentModel.plaintextLength, attachmentModel.key, attachmentModel.digest, attachmentModel.incrementalDigest));
|
||||
return new LoadData<>(attachmentModel, new AttachmentStreamLocalUriFetcher(attachmentModel.attachment, attachmentModel.plaintextLength, attachmentModel.key, attachmentModel.digest, attachmentModel.incrementalDigest, attachmentModel.incrementalMacChunkSize));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -46,19 +46,22 @@ public class AttachmentStreamUriLoader implements ModelLoader<AttachmentModel, I
|
||||
public @NonNull byte[] key;
|
||||
public @NonNull Optional<byte[]> digest;
|
||||
public @NonNull Optional<byte[]> incrementalDigest;
|
||||
public int incrementalMacChunkSize;
|
||||
public long plaintextLength;
|
||||
|
||||
public AttachmentModel(@NonNull File attachment,
|
||||
@NonNull byte[] key,
|
||||
long plaintextLength,
|
||||
@NonNull Optional<byte[]> digest,
|
||||
@NonNull Optional<byte[]> incrementalDigest)
|
||||
@NonNull Optional<byte[]> incrementalDigest,
|
||||
int incrementalMacChunkSize)
|
||||
{
|
||||
this.attachment = attachment;
|
||||
this.key = key;
|
||||
this.digest = digest;
|
||||
this.incrementalDigest = incrementalDigest;
|
||||
this.plaintextLength = plaintextLength;
|
||||
this.attachment = attachment;
|
||||
this.key = key;
|
||||
this.digest = digest;
|
||||
this.incrementalDigest = incrementalDigest;
|
||||
this.incrementalMacChunkSize = incrementalMacChunkSize;
|
||||
this.plaintextLength = plaintextLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -45,6 +45,7 @@ object ReleaseChannel {
|
||||
mediaHeight,
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
0,
|
||||
Optional.of(media),
|
||||
false,
|
||||
false,
|
||||
|
||||
@@ -13,7 +13,6 @@ import androidx.media3.datasource.TransferListener;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.signal.libsignal.protocol.InvalidMessageException;
|
||||
import org.signal.libsignal.protocol.incrementalmac.ChunkSizeChoice;
|
||||
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
|
||||
import org.thoughtcrime.securesms.database.AttachmentTable;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
@@ -65,7 +64,7 @@ class PartDataSource implements DataSource {
|
||||
final byte[] decode = Base64.decode(attachmentKey);
|
||||
final File transferFile = attachmentDatabase.getOrCreateTransferFile(attachment.getAttachmentId());
|
||||
try {
|
||||
this.inputStream = AttachmentCipherInputStream.createForAttachment(transferFile, attachment.getSize(), decode, attachment.getDigest(), attachment.getIncrementalDigest());
|
||||
this.inputStream = AttachmentCipherInputStream.createForAttachment(transferFile, attachment.getSize(), decode, attachment.getDigest(), attachment.getIncrementalDigest(), attachment.getIncrementalMacChunkSize());
|
||||
|
||||
long skipped = 0;
|
||||
while (skipped < dataSpec.position) {
|
||||
|
||||
@@ -243,6 +243,7 @@ class UploadDependencyGraphTest {
|
||||
attachment.relay,
|
||||
attachment.digest,
|
||||
attachment.incrementalDigest,
|
||||
attachment.incrementalMacChunkSize,
|
||||
attachment.fastPreflightId,
|
||||
attachment.isVoiceNote,
|
||||
attachment.isBorderless,
|
||||
|
||||
@@ -41,6 +41,7 @@ object FakeMessageRecords {
|
||||
relay: String = "",
|
||||
digest: ByteArray = byteArrayOf(),
|
||||
incrementalDigest: ByteArray = byteArrayOf(),
|
||||
incrementalMacChunkSize: Int = 0,
|
||||
fastPreflightId: String = "",
|
||||
voiceNote: Boolean = false,
|
||||
borderless: Boolean = false,
|
||||
@@ -71,6 +72,7 @@ object FakeMessageRecords {
|
||||
relay,
|
||||
digest,
|
||||
incrementalDigest,
|
||||
incrementalMacChunkSize,
|
||||
fastPreflightId,
|
||||
voiceNote,
|
||||
borderless,
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ dependencyResolutionManagement {
|
||||
version('exoplayer', '2.19.0')
|
||||
version('glide', '4.15.1')
|
||||
version('kotlin', '1.8.10')
|
||||
version('libsignal-client', '0.32.0')
|
||||
version('libsignal-client', '0.32.1')
|
||||
version('mp4parser', '1.9.39')
|
||||
version('android-gradle-plugin', '8.0.2')
|
||||
version('accompanist', '0.28.0')
|
||||
|
||||
@@ -5333,20 +5333,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html
|
||||
<sha256 value="6eb4422e8a618b3b76cb2096a3619d251f9e27989dc68307a1e5414c3710f2d1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.signal" name="libsignal-android" version="0.32.0">
|
||||
<artifact name="libsignal-android-0.32.0.aar">
|
||||
<sha256 value="35f042d6b69750e875aa0fe89310aab9dea6ea59c55c49e22cdecd015e82b01b" origin="Generated by Gradle"/>
|
||||
<component group="org.signal" name="libsignal-android" version="0.32.1">
|
||||
<artifact name="libsignal-android-0.32.1.aar">
|
||||
<sha256 value="94dbb2d94666c2553247d8507390f362e022e99e7dfbe2291a8182aac432fb8b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libsignal-android-0.32.0.module">
|
||||
<sha256 value="a41851712342885abf15acc0ac811e89e5b0101468e088d348b1e9a3ed6bb644" origin="Generated by Gradle"/>
|
||||
<artifact name="libsignal-android-0.32.1.module">
|
||||
<sha256 value="e7784caba5caf1f483cc8b1173270cc9fb535a4c6f6c67597fe4aba9a73883c0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.signal" name="libsignal-client" version="0.32.0">
|
||||
<artifact name="libsignal-client-0.32.0.jar">
|
||||
<sha256 value="e2fbf91dd897e4e568ab4ad4411ed8a4b680e6fb449a7438ef0ceaa92c7f465b" origin="Generated by Gradle"/>
|
||||
<component group="org.signal" name="libsignal-client" version="0.32.1">
|
||||
<artifact name="libsignal-client-0.32.1.jar">
|
||||
<sha256 value="80576f48e8dc6c04c650e0160743b2f9074208be7a56f4d9c7a9bed4d81c9091" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="libsignal-client-0.32.0.module">
|
||||
<sha256 value="d96f4ed38e88199a6442a9c4789291a6f0df48a18c35ce464b2fa049f692dc56" origin="Generated by Gradle"/>
|
||||
<artifact name="libsignal-client-0.32.1.module">
|
||||
<sha256 value="f0c442464e4a9f279cbe7751b83941a01d935559228a2b7e29ac28dce34b6434" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.signal" name="ringrtc-android" version="2.32.0">
|
||||
|
||||
+1
-1
@@ -159,7 +159,7 @@ public class SignalServiceMessageReceiver {
|
||||
if (!pointer.getDigest().isPresent()) throw new InvalidMessageException("No attachment digest!");
|
||||
|
||||
socket.retrieveAttachment(pointer.getCdnNumber(), pointer.getRemoteId(), destination, maxSizeBytes, listener);
|
||||
return AttachmentCipherInputStream.createForAttachment(destination, pointer.getSize().orElse(0), pointer.getKey(), pointer.getDigest().get(), null);
|
||||
return AttachmentCipherInputStream.createForAttachment(destination, pointer.getSize().orElse(0), pointer.getKey(), pointer.getDigest().get(), null, 0);
|
||||
}
|
||||
|
||||
public InputStream retrieveSticker(byte[] packId, byte[] packKey, int stickerId)
|
||||
|
||||
+2
-1
@@ -20,7 +20,6 @@ import org.signal.libsignal.protocol.message.SenderKeyDistributionMessage;
|
||||
import org.signal.libsignal.protocol.state.PreKeyBundle;
|
||||
import org.signal.libsignal.protocol.util.Pair;
|
||||
import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations;
|
||||
import org.whispersystems.signalservice.api.crypto.AttachmentCipherOutputStream;
|
||||
import org.whispersystems.signalservice.api.crypto.AttachmentCipherStreamUtil;
|
||||
import org.whispersystems.signalservice.api.crypto.ContentHint;
|
||||
import org.whispersystems.signalservice.api.crypto.EnvelopeContent;
|
||||
@@ -833,6 +832,7 @@ public class SignalServiceMessageSender {
|
||||
attachment.getWidth(), attachment.getHeight(),
|
||||
Optional.of(attachmentIdAndDigest.second().getDigest()),
|
||||
Optional.of(attachmentIdAndDigest.second().getIncrementalDigest()),
|
||||
attachmentIdAndDigest.second().getIncrementalMacChunkSize(),
|
||||
attachment.getFileName(),
|
||||
attachment.getVoiceNote(),
|
||||
attachment.isBorderless(),
|
||||
@@ -874,6 +874,7 @@ public class SignalServiceMessageSender {
|
||||
attachment.getHeight(),
|
||||
Optional.of(digest.getDigest()),
|
||||
Optional.ofNullable(digest.getIncrementalDigest()),
|
||||
digest.getIncrementalMacChunkSize(),
|
||||
attachment.getFileName(),
|
||||
attachment.getVoiceNote(),
|
||||
attachment.isBorderless(),
|
||||
|
||||
+27
-23
@@ -11,8 +11,6 @@ import org.signal.libsignal.protocol.InvalidMessageException;
|
||||
import org.signal.libsignal.protocol.incrementalmac.ChunkSizeChoice;
|
||||
import org.signal.libsignal.protocol.incrementalmac.IncrementalMacInputStream;
|
||||
import org.signal.libsignal.protocol.kdf.HKDFv3;
|
||||
import org.signal.libsignal.protocol.logging.Log;
|
||||
import org.whispersystems.signalservice.internal.crypto.PaddingInputStream;
|
||||
import org.whispersystems.signalservice.internal.util.ContentLengthInputStream;
|
||||
import org.whispersystems.signalservice.internal.util.Util;
|
||||
|
||||
@@ -55,7 +53,7 @@ public class AttachmentCipherInputStream extends FilterInputStream {
|
||||
private long totalRead;
|
||||
private byte[] overflowBuffer;
|
||||
|
||||
public static InputStream createForAttachment(File file, long plaintextLength, byte[] combinedKeyMaterial, byte[] digest, byte[] incrementalDigest)
|
||||
public static InputStream createForAttachment(File file, long plaintextLength, byte[] combinedKeyMaterial, byte[] digest, byte[] incrementalDigest, int incrementalMacChunkSize)
|
||||
throws InvalidMessageException, IOException
|
||||
{
|
||||
try {
|
||||
@@ -73,19 +71,18 @@ public class AttachmentCipherInputStream extends FilterInputStream {
|
||||
|
||||
|
||||
final InputStream wrappedStream;
|
||||
boolean hasIncrementalMac = incrementalDigest != null && incrementalDigest.length > 0;
|
||||
final boolean hasIncrementalMac = incrementalDigest != null && incrementalDigest.length > 0 && incrementalMacChunkSize > 0;
|
||||
|
||||
if (!hasIncrementalMac) {
|
||||
try (FileInputStream macVerificationStream = new FileInputStream(file)) {
|
||||
verifyMac(macVerificationStream, file.length(), mac, digest);
|
||||
}
|
||||
wrappedStream = new FileInputStream(file);
|
||||
} else {
|
||||
final int dataSize = Math.toIntExact(AttachmentCipherStreamUtil.getCiphertextLength(PaddingInputStream.getPaddedSize(plaintextLength)));
|
||||
final ChunkSizeChoice sizeChoice = ChunkSizeChoice.inferChunkSize(dataSize);
|
||||
wrappedStream = new IncrementalMacInputStream(
|
||||
new FileInputStream(file),
|
||||
parts[1],
|
||||
sizeChoice,
|
||||
ChunkSizeChoice.everyNthByte(incrementalMacChunkSize),
|
||||
incrementalDigest);
|
||||
}
|
||||
InputStream inputStream = new AttachmentCipherInputStream(wrappedStream, parts[0], file.length() - BLOCK_SIZE - mac.getMacLength());
|
||||
@@ -153,7 +150,7 @@ public class AttachmentCipherInputStream extends FilterInputStream {
|
||||
int read;
|
||||
|
||||
//noinspection StatementWithEmptyBody
|
||||
while ((read = read(buffer)) == 0);
|
||||
while ((read = read(buffer)) == 0) ;
|
||||
|
||||
return (read == -1) ? -1 : ((int) buffer[0]) & 0xFF;
|
||||
}
|
||||
@@ -165,9 +162,13 @@ public class AttachmentCipherInputStream extends FilterInputStream {
|
||||
|
||||
@Override
|
||||
public int read(byte[] buffer, int offset, int length) throws IOException {
|
||||
if (totalRead != totalDataSize) return readIncremental(buffer, offset, length);
|
||||
else if (!done) return readFinal(buffer, offset, length);
|
||||
else return -1;
|
||||
if (totalRead != totalDataSize) {
|
||||
return readIncremental(buffer, offset, length);
|
||||
} else if (!done) {
|
||||
return readFinal(buffer, offset, length);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -179,7 +180,7 @@ public class AttachmentCipherInputStream extends FilterInputStream {
|
||||
public long skip(long byteCount) throws IOException {
|
||||
long skipped = 0L;
|
||||
while (skipped < byteCount) {
|
||||
byte[] buf = new byte[Math.min(4096, (int)(byteCount-skipped))];
|
||||
byte[] buf = new byte[Math.min(4096, (int) (byteCount - skipped))];
|
||||
int read = read(buf);
|
||||
|
||||
skipped += read;
|
||||
@@ -190,8 +191,8 @@ public class AttachmentCipherInputStream extends FilterInputStream {
|
||||
|
||||
private int readFinal(byte[] buffer, int offset, int length) throws IOException {
|
||||
try {
|
||||
byte[] internal = new byte[buffer.length];
|
||||
int actualLength = Math.min(length, cipher.doFinal(internal, 0));
|
||||
byte[] internal = new byte[buffer.length];
|
||||
int actualLength = Math.min(length, cipher.doFinal(internal, 0));
|
||||
System.arraycopy(internal, 0, buffer, offset, actualLength);
|
||||
|
||||
done = true;
|
||||
@@ -222,11 +223,11 @@ public class AttachmentCipherInputStream extends FilterInputStream {
|
||||
}
|
||||
|
||||
if (length + totalRead > totalDataSize)
|
||||
length = (int)(totalDataSize - totalRead);
|
||||
length = (int) (totalDataSize - totalRead);
|
||||
|
||||
byte[] internalBuffer = new byte[length];
|
||||
int read = super.read(internalBuffer, 0, internalBuffer.length <= cipher.getBlockSize() ? internalBuffer.length : internalBuffer.length - cipher.getBlockSize());
|
||||
totalRead += read;
|
||||
int read = super.read(internalBuffer, 0, internalBuffer.length <= cipher.getBlockSize() ? internalBuffer.length : internalBuffer.length - cipher.getBlockSize());
|
||||
totalRead += read;
|
||||
|
||||
try {
|
||||
int outputLen = cipher.getOutputSize(read);
|
||||
@@ -256,9 +257,9 @@ public class AttachmentCipherInputStream extends FilterInputStream {
|
||||
throws InvalidMacException
|
||||
{
|
||||
try {
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA256");
|
||||
int remainingData = Util.toIntExact(length) - mac.getMacLength();
|
||||
byte[] buffer = new byte[4096];
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA256");
|
||||
int remainingData = Util.toIntExact(length) - mac.getMacLength();
|
||||
byte[] buffer = new byte[4096];
|
||||
|
||||
while (remainingData > 0) {
|
||||
int read = inputStream.read(buffer, 0, Math.min(buffer.length, remainingData));
|
||||
@@ -291,11 +292,14 @@ public class AttachmentCipherInputStream extends FilterInputStream {
|
||||
private void readFully(byte[] buffer) throws IOException {
|
||||
int offset = 0;
|
||||
|
||||
for (;;) {
|
||||
for (; ; ) {
|
||||
int read = super.read(buffer, offset, buffer.length - offset);
|
||||
|
||||
if (read + offset < buffer.length) offset += read;
|
||||
else return;
|
||||
if (read + offset < buffer.length) {
|
||||
offset += read;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+23
-16
@@ -26,6 +26,7 @@ public class SignalServiceAttachmentPointer extends SignalServiceAttachment {
|
||||
private final Optional<byte[]> preview;
|
||||
private final Optional<byte[]> digest;
|
||||
private final Optional<byte[]> incrementalDigest;
|
||||
private final int incrementalMacChunkSize;
|
||||
private final Optional<String> fileName;
|
||||
private final boolean voiceNote;
|
||||
private final boolean borderless;
|
||||
@@ -46,6 +47,7 @@ public class SignalServiceAttachmentPointer extends SignalServiceAttachment {
|
||||
int height,
|
||||
Optional<byte[]> digest,
|
||||
Optional<byte[]> incrementalDigest,
|
||||
int incrementalMacChunkSize,
|
||||
Optional<String> fileName,
|
||||
boolean voiceNote,
|
||||
boolean borderless,
|
||||
@@ -55,22 +57,23 @@ public class SignalServiceAttachmentPointer extends SignalServiceAttachment {
|
||||
long uploadTimestamp)
|
||||
{
|
||||
super(contentType);
|
||||
this.cdnNumber = cdnNumber;
|
||||
this.remoteId = remoteId;
|
||||
this.key = key;
|
||||
this.size = size;
|
||||
this.preview = preview;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.digest = digest;
|
||||
this.incrementalDigest = incrementalDigest;
|
||||
this.fileName = fileName;
|
||||
this.voiceNote = voiceNote;
|
||||
this.borderless = borderless;
|
||||
this.caption = caption;
|
||||
this.blurHash = blurHash;
|
||||
this.uploadTimestamp = uploadTimestamp;
|
||||
this.gif = gif;
|
||||
this.cdnNumber = cdnNumber;
|
||||
this.remoteId = remoteId;
|
||||
this.key = key;
|
||||
this.size = size;
|
||||
this.preview = preview;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.incrementalMacChunkSize = incrementalMacChunkSize;
|
||||
this.digest = digest;
|
||||
this.incrementalDigest = incrementalDigest;
|
||||
this.fileName = fileName;
|
||||
this.voiceNote = voiceNote;
|
||||
this.borderless = borderless;
|
||||
this.caption = caption;
|
||||
this.blurHash = blurHash;
|
||||
this.uploadTimestamp = uploadTimestamp;
|
||||
this.gif = gif;
|
||||
}
|
||||
|
||||
public int getCdnNumber() {
|
||||
@@ -135,6 +138,10 @@ public class SignalServiceAttachmentPointer extends SignalServiceAttachment {
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getIncrementalMacChunkSize() {
|
||||
return incrementalMacChunkSize;
|
||||
}
|
||||
|
||||
public Optional<String> getCaption() {
|
||||
return caption;
|
||||
}
|
||||
|
||||
+1
@@ -28,6 +28,7 @@ public final class AttachmentPointerUtil {
|
||||
pointer.height != null ? pointer.height : 0,
|
||||
pointer.digest != null ? Optional.of(pointer.digest.toByteArray()) : Optional.empty(),
|
||||
pointer.incrementalDigest != null ? Optional.of(pointer.incrementalDigest.toByteArray()) : Optional.empty(),
|
||||
pointer.incrementalMacChunkSize != null ? pointer.incrementalMacChunkSize : 0,
|
||||
pointer.fileName != null ? Optional.of(pointer.fileName) : Optional.empty(),
|
||||
((pointer.flags != null ? pointer.flags : 0) & FlagUtil.toBinaryFlag(AttachmentPointer.Flags.VOICE_MESSAGE.getValue())) != 0,
|
||||
((pointer.flags != null ? pointer.flags : 0) & FlagUtil.toBinaryFlag(AttachmentPointer.Flags.BORDERLESS.getValue())) != 0,
|
||||
|
||||
+1
-1
@@ -5,4 +5,4 @@
|
||||
|
||||
package org.whispersystems.signalservice.internal.crypto
|
||||
|
||||
data class AttachmentDigest(val digest: ByteArray, val incrementalDigest: ByteArray?)
|
||||
data class AttachmentDigest(val digest: ByteArray, val incrementalDigest: ByteArray?, val incrementalMacChunkSize: Int)
|
||||
|
||||
+1
-2
@@ -27,13 +27,12 @@ class AttachmentCipherOutputStreamFactory(private val key: ByteArray, private va
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun createIncrementalFor(wrap: OutputStream?, length: Long, incrementalDigestOut: OutputStream?): DigestingOutputStream {
|
||||
fun createIncrementalFor(wrap: OutputStream?, length: Long, sizeChoice: ChunkSizeChoice, incrementalDigestOut: OutputStream?): DigestingOutputStream {
|
||||
if (length > Int.MAX_VALUE) {
|
||||
throw IllegalArgumentException("Attachment length overflows int!")
|
||||
}
|
||||
|
||||
val privateKey = key.sliceArray(AES_KEY_LENGTH until key.size)
|
||||
val sizeChoice = ChunkSizeChoice.inferChunkSize(length.toInt())
|
||||
val incrementalStream = IncrementalMacOutputStream(wrap, privateKey, sizeChoice, incrementalDigestOut)
|
||||
return createFor(incrementalStream)
|
||||
}
|
||||
|
||||
+10
-10
@@ -4,6 +4,7 @@ import okhttp3.MediaType
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.internal.http.UnrepeatableRequestBody
|
||||
import okio.BufferedSink
|
||||
import org.signal.libsignal.protocol.incrementalmac.ChunkSizeChoice
|
||||
import org.signal.libsignal.protocol.logging.Log
|
||||
import org.whispersystems.signalservice.api.crypto.DigestingOutputStream
|
||||
import org.whispersystems.signalservice.api.crypto.SkippingOutputStream
|
||||
@@ -25,10 +26,7 @@ class DigestingRequestBody(
|
||||
private val cancelationSignal: CancelationSignal?,
|
||||
private val contentStart: Long
|
||||
) : RequestBody(), UnrepeatableRequestBody {
|
||||
lateinit var transmittedDigest: ByteArray
|
||||
private set
|
||||
var incrementalDigest: ByteArray? = null
|
||||
private set
|
||||
var attachmentDigest: AttachmentDigest? = null
|
||||
|
||||
init {
|
||||
require(contentLength >= contentStart)
|
||||
@@ -44,8 +42,9 @@ class DigestingRequestBody(
|
||||
val digestStream = ByteArrayOutputStream()
|
||||
val inner = SkippingOutputStream(contentStart, sink.outputStream())
|
||||
val isIncremental = outputStreamFactory is AttachmentCipherOutputStreamFactory
|
||||
val sizeChoice: ChunkSizeChoice = ChunkSizeChoice.inferChunkSize(contentLength.toInt())
|
||||
val outputStream: DigestingOutputStream = if (isIncremental) {
|
||||
(outputStreamFactory as AttachmentCipherOutputStreamFactory).createIncrementalFor(inner, contentLength, digestStream)
|
||||
(outputStreamFactory as AttachmentCipherOutputStreamFactory).createIncrementalFor(inner, contentLength, sizeChoice, digestStream)
|
||||
} else {
|
||||
outputStreamFactory.createFor(inner)
|
||||
}
|
||||
@@ -65,7 +64,7 @@ class DigestingRequestBody(
|
||||
|
||||
outputStream.flush()
|
||||
|
||||
if (isIncremental) {
|
||||
val incrementalDigest: ByteArray = if (isIncremental) {
|
||||
if (contentLength != total) {
|
||||
Log.w(TAG, "Content uploaded ${logMessage(total, contentLength)} bytes compared to expected!")
|
||||
} else {
|
||||
@@ -73,17 +72,18 @@ class DigestingRequestBody(
|
||||
}
|
||||
outputStream.close()
|
||||
digestStream.close()
|
||||
incrementalDigest = digestStream.toByteArray()
|
||||
digestStream.toByteArray()
|
||||
} else {
|
||||
ByteArray(0)
|
||||
}
|
||||
transmittedDigest = outputStream.transmittedDigest
|
||||
|
||||
attachmentDigest = AttachmentDigest(outputStream.transmittedDigest, incrementalDigest, sizeChoice.sizeInBytes)
|
||||
}
|
||||
|
||||
override fun contentLength(): Long {
|
||||
return if (contentLength > 0) contentLength - contentStart else -1
|
||||
}
|
||||
|
||||
fun getAttachmentDigest(): AttachmentDigest = AttachmentDigest(transmittedDigest, incrementalDigest)
|
||||
|
||||
private fun logMessage(actual: Long, expected: Long): String {
|
||||
val difference = actual - expected
|
||||
return if (difference > 0) {
|
||||
|
||||
@@ -670,21 +670,22 @@ message AttachmentPointer {
|
||||
fixed64 cdnId = 1;
|
||||
string cdnKey = 15;
|
||||
}
|
||||
optional string contentType = 2;
|
||||
optional bytes key = 3;
|
||||
optional uint32 size = 4;
|
||||
optional bytes thumbnail = 5;
|
||||
optional bytes digest = 6;
|
||||
optional bytes incrementalDigest = 16;
|
||||
optional string fileName = 7;
|
||||
optional uint32 flags = 8;
|
||||
optional uint32 width = 9;
|
||||
optional uint32 height = 10;
|
||||
optional string caption = 11;
|
||||
optional string blurHash = 12;
|
||||
optional uint64 uploadTimestamp = 13;
|
||||
optional uint32 cdnNumber = 14;
|
||||
// Next ID: 17
|
||||
optional string contentType = 2;
|
||||
optional bytes key = 3;
|
||||
optional uint32 size = 4;
|
||||
optional bytes thumbnail = 5;
|
||||
optional bytes digest = 6;
|
||||
optional bytes incrementalDigest = 16;
|
||||
optional uint32 incrementalMacChunkSize = 17;
|
||||
optional string fileName = 7;
|
||||
optional uint32 flags = 8;
|
||||
optional uint32 width = 9;
|
||||
optional uint32 height = 10;
|
||||
optional string caption = 11;
|
||||
optional string blurHash = 12;
|
||||
optional uint64 uploadTimestamp = 13;
|
||||
optional uint32 cdnNumber = 14;
|
||||
// Next ID: 18
|
||||
}
|
||||
|
||||
message GroupContext {
|
||||
|
||||
+35
-29
@@ -3,6 +3,7 @@ package org.whispersystems.signalservice.api.crypto;
|
||||
import org.conscrypt.Conscrypt;
|
||||
import org.junit.Test;
|
||||
import org.signal.libsignal.protocol.InvalidMessageException;
|
||||
import org.signal.libsignal.protocol.incrementalmac.ChunkSizeChoice;
|
||||
import org.signal.libsignal.protocol.incrementalmac.InvalidMacException;
|
||||
import org.signal.libsignal.protocol.kdf.HKDFv3;
|
||||
import org.whispersystems.signalservice.internal.crypto.PaddingInputStream;
|
||||
@@ -33,12 +34,12 @@ public final class AttachmentCipherTest {
|
||||
|
||||
@Test
|
||||
public void attachment_encryptDecrypt() throws IOException, InvalidMessageException {
|
||||
byte[] key = Util.getSecretBytes(64);
|
||||
byte[] plaintextInput = "Peter Parker".getBytes();
|
||||
EncryptResult encryptResult = encryptData(plaintextInput, key, false);
|
||||
File cipherFile = writeToFile(encryptResult.ciphertext);
|
||||
InputStream inputStream = AttachmentCipherInputStream.createForAttachment(cipherFile, plaintextInput.length, key, encryptResult.digest, encryptResult.incrementalDigest);
|
||||
byte[] plaintextOutput = readInputStreamFully(inputStream);
|
||||
byte[] key = Util.getSecretBytes(64);
|
||||
byte[] plaintextInput = "Peter Parker".getBytes();
|
||||
EncryptResult encryptResult = encryptData(plaintextInput, key, false);
|
||||
File cipherFile = writeToFile(encryptResult.ciphertext);
|
||||
InputStream inputStream = AttachmentCipherInputStream.createForAttachment(cipherFile, plaintextInput.length, key, encryptResult.digest, encryptResult.incrementalDigest, encryptResult.chunkSizeChoice);
|
||||
byte[] plaintextOutput = readInputStreamFully(inputStream);
|
||||
|
||||
assertArrayEquals(plaintextInput, plaintextOutput);
|
||||
|
||||
@@ -47,12 +48,12 @@ public final class AttachmentCipherTest {
|
||||
|
||||
@Test
|
||||
public void attachment_encryptDecryptEmpty() throws IOException, InvalidMessageException {
|
||||
byte[] key = Util.getSecretBytes(64);
|
||||
byte[] plaintextInput = "".getBytes();
|
||||
EncryptResult encryptResult = encryptData(plaintextInput, key, true);
|
||||
File cipherFile = writeToFile(encryptResult.ciphertext);
|
||||
InputStream inputStream = AttachmentCipherInputStream.createForAttachment(cipherFile, plaintextInput.length, key, encryptResult.digest, encryptResult.incrementalDigest);
|
||||
byte[] plaintextOutput = readInputStreamFully(inputStream);
|
||||
byte[] key = Util.getSecretBytes(64);
|
||||
byte[] plaintextInput = "".getBytes();
|
||||
EncryptResult encryptResult = encryptData(plaintextInput, key, true);
|
||||
File cipherFile = writeToFile(encryptResult.ciphertext);
|
||||
InputStream inputStream = AttachmentCipherInputStream.createForAttachment(cipherFile, plaintextInput.length, key, encryptResult.digest, encryptResult.incrementalDigest, encryptResult.chunkSizeChoice);
|
||||
byte[] plaintextOutput = readInputStreamFully(inputStream);
|
||||
|
||||
assertArrayEquals(plaintextInput, plaintextOutput);
|
||||
|
||||
@@ -72,7 +73,7 @@ public final class AttachmentCipherTest {
|
||||
|
||||
cipherFile = writeToFile(encryptResult.ciphertext);
|
||||
|
||||
AttachmentCipherInputStream.createForAttachment(cipherFile, plaintextInput.length, badKey, encryptResult.digest, null);
|
||||
AttachmentCipherInputStream.createForAttachment(cipherFile, plaintextInput.length, badKey, encryptResult.digest, null, 0);
|
||||
} catch (InvalidMessageException e) {
|
||||
hitCorrectException = true;
|
||||
} finally {
|
||||
@@ -97,7 +98,7 @@ public final class AttachmentCipherTest {
|
||||
|
||||
cipherFile = writeToFile(encryptResult.ciphertext);
|
||||
|
||||
AttachmentCipherInputStream.createForAttachment(cipherFile, plaintextInput.length, key, badDigest, null);
|
||||
AttachmentCipherInputStream.createForAttachment(cipherFile, plaintextInput.length, key, badDigest, null, 0);
|
||||
} catch (InvalidMessageException e) {
|
||||
hitCorrectException = true;
|
||||
} finally {
|
||||
@@ -126,7 +127,7 @@ public final class AttachmentCipherTest {
|
||||
cipherFile = writeToFile(encryptResult.ciphertext);
|
||||
|
||||
|
||||
InputStream decryptedStream = AttachmentCipherInputStream.createForAttachment(cipherFile, plaintextInput.length, key, encryptResult.digest, badDigest);
|
||||
InputStream decryptedStream = AttachmentCipherInputStream.createForAttachment(cipherFile, plaintextInput.length, key, encryptResult.digest, badDigest, encryptResult.chunkSizeChoice);
|
||||
byte[] plaintextOutput = readInputStreamFully(decryptedStream);
|
||||
fail();
|
||||
} catch (InvalidMacException e) {
|
||||
@@ -153,11 +154,12 @@ public final class AttachmentCipherTest {
|
||||
plaintextInput[i] = (byte) 0x97;
|
||||
}
|
||||
|
||||
byte[] key = Util.getSecretBytes(64);
|
||||
byte[] iv = Util.getSecretBytes(16);
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(plaintextInput);
|
||||
InputStream paddedInputStream = new PaddingInputStream(inputStream, length);
|
||||
ByteArrayOutputStream destinationOutputStream = new ByteArrayOutputStream();
|
||||
byte[] key = Util.getSecretBytes(64);
|
||||
byte[] iv = Util.getSecretBytes(16);
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(plaintextInput);
|
||||
InputStream paddedInputStream = new PaddingInputStream(inputStream, length);
|
||||
ByteArrayOutputStream destinationOutputStream = new ByteArrayOutputStream();
|
||||
|
||||
DigestingOutputStream encryptingOutputStream = new AttachmentCipherOutputStreamFactory(key, iv).createFor(destinationOutputStream);
|
||||
|
||||
Util.copy(paddedInputStream, encryptingOutputStream);
|
||||
@@ -170,7 +172,7 @@ public final class AttachmentCipherTest {
|
||||
|
||||
File cipherFile = writeToFile(encryptedData);
|
||||
|
||||
InputStream decryptedStream = AttachmentCipherInputStream.createForAttachment(cipherFile, length, key, digest, null);
|
||||
InputStream decryptedStream = AttachmentCipherInputStream.createForAttachment(cipherFile, length, key, digest, null, 0);
|
||||
byte[] plaintextOutput = readInputStreamFully(decryptedStream);
|
||||
|
||||
assertArrayEquals(plaintextInput, plaintextOutput);
|
||||
@@ -187,11 +189,12 @@ public final class AttachmentCipherTest {
|
||||
try {
|
||||
byte[] key = Util.getSecretBytes(64);
|
||||
byte[] plaintextInput = "Aunt May".getBytes();
|
||||
ChunkSizeChoice sizeChoice = ChunkSizeChoice.inferChunkSize(plaintextInput.length);
|
||||
EncryptResult encryptResult = encryptData(plaintextInput, key, true);
|
||||
|
||||
cipherFile = writeToFile(encryptResult.ciphertext);
|
||||
|
||||
AttachmentCipherInputStream.createForAttachment(cipherFile, plaintextInput.length, key, null, encryptResult.incrementalDigest);
|
||||
AttachmentCipherInputStream.createForAttachment(cipherFile, plaintextInput.length, key, null, encryptResult.incrementalDigest, encryptResult.chunkSizeChoice);
|
||||
} catch (InvalidMessageException e) {
|
||||
hitCorrectException = true;
|
||||
} finally {
|
||||
@@ -218,7 +221,7 @@ public final class AttachmentCipherTest {
|
||||
|
||||
cipherFile = writeToFile(badMacCiphertext);
|
||||
|
||||
AttachmentCipherInputStream.createForAttachment(cipherFile, plaintextInput.length, key, encryptResult.digest, null);
|
||||
AttachmentCipherInputStream.createForAttachment(cipherFile, plaintextInput.length, key, encryptResult.digest, null, encryptResult.chunkSizeChoice);
|
||||
fail();
|
||||
} catch (InvalidMessageException e) {
|
||||
hitCorrectException = true;
|
||||
@@ -306,8 +309,9 @@ public final class AttachmentCipherTest {
|
||||
AttachmentCipherOutputStreamFactory factory = new AttachmentCipherOutputStreamFactory(keyMaterial, iv);
|
||||
|
||||
DigestingOutputStream encryptStream;
|
||||
final ChunkSizeChoice sizeChoice = ChunkSizeChoice.inferChunkSize(data.length);
|
||||
if (withIncremental) {
|
||||
encryptStream = factory.createIncrementalFor(outputStream, data.length, incrementalDigestOut);
|
||||
encryptStream = factory.createIncrementalFor(outputStream, data.length, sizeChoice, incrementalDigestOut);
|
||||
} else {
|
||||
encryptStream = factory.createFor(outputStream);
|
||||
}
|
||||
@@ -318,7 +322,7 @@ public final class AttachmentCipherTest {
|
||||
encryptStream.close();
|
||||
incrementalDigestOut.close();
|
||||
|
||||
return new EncryptResult(outputStream.toByteArray(), encryptStream.getTransmittedDigest(), incrementalDigestOut.toByteArray());
|
||||
return new EncryptResult(outputStream.toByteArray(), encryptStream.getTransmittedDigest(), incrementalDigestOut.toByteArray(), sizeChoice.getSizeInBytes());
|
||||
}
|
||||
|
||||
private static File writeToFile(byte[] data) throws IOException {
|
||||
@@ -343,11 +347,13 @@ public final class AttachmentCipherTest {
|
||||
final byte[] ciphertext;
|
||||
final byte[] digest;
|
||||
final byte[] incrementalDigest;
|
||||
final int chunkSizeChoice;
|
||||
|
||||
private EncryptResult(byte[] ciphertext, byte[] digest, byte[] incrementalDigest) {
|
||||
this.ciphertext = ciphertext;
|
||||
this.digest = digest;
|
||||
this.incrementalDigest = incrementalDigest;
|
||||
private EncryptResult(byte[] ciphertext, byte[] digest, byte[] incrementalDigest, int chunkSizeChoice) {
|
||||
this.ciphertext = ciphertext;
|
||||
this.digest = digest;
|
||||
this.incrementalDigest = incrementalDigest;
|
||||
this.chunkSizeChoice = chunkSizeChoice;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-3
@@ -1,8 +1,8 @@
|
||||
package org.whispersystems.signalservice.internal.push.http;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.whispersystems.signalservice.api.crypto.AttachmentCipherOutputStream;
|
||||
import org.whispersystems.signalservice.api.crypto.AttachmentCipherStreamUtil;
|
||||
import org.whispersystems.signalservice.internal.crypto.AttachmentDigest;
|
||||
import org.whispersystems.signalservice.internal.util.Util;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -11,6 +11,8 @@ import okio.Buffer;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class DigestingRequestBodyTest {
|
||||
|
||||
@@ -36,8 +38,14 @@ public class DigestingRequestBodyTest {
|
||||
fromMiddle.writeTo(buffer);
|
||||
}
|
||||
|
||||
assertArrayEquals(fromStart.getTransmittedDigest(), fromMiddle.getTransmittedDigest());
|
||||
assertArrayEquals(fromStart.getIncrementalDigest(), fromMiddle.getIncrementalDigest());
|
||||
final AttachmentDigest fullResult = fromStart.getAttachmentDigest();
|
||||
assertNotNull(fullResult);
|
||||
|
||||
final AttachmentDigest partialResult = fromMiddle.getAttachmentDigest();
|
||||
assertNotNull(partialResult);
|
||||
|
||||
assertArrayEquals(fullResult.getDigest(), partialResult.getDigest());
|
||||
assertArrayEquals(fullResult.getIncrementalDigest(), partialResult.getIncrementalDigest());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user