mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-24 04:58:45 +00:00
Revert "Fix contact photo upload failure."
This reverts commit 06dc8ccbdd.
This commit is contained in:
committed by
Cody Henthorne
parent
61b97fd09b
commit
b5f82beb46
@@ -213,7 +213,6 @@ public final class AttachmentUploadJob extends BaseJob {
|
||||
.withCaption(attachment.getCaption())
|
||||
.withCancelationSignal(this::isCanceled)
|
||||
.withResumableUploadSpec(resumableUploadSpec)
|
||||
.withIncremental(attachment.getIncrementalDigest() != null)
|
||||
.withListener((total, progress) -> {
|
||||
EventBus.getDefault().postSticky(new PartProgressEvent(attachment, PartProgressEvent.Type.NETWORK, total, progress));
|
||||
if (notification != null) {
|
||||
|
||||
@@ -366,8 +366,7 @@ public abstract class PushSendJob extends SendJob {
|
||||
.withHeight(thumbnailData.getHeight())
|
||||
.withLength(thumbnailData.getData().length)
|
||||
.withStream(new ByteArrayInputStream(thumbnailData.getData()))
|
||||
.withResumableUploadSpec(ApplicationDependencies.getSignalServiceMessageSender().getResumableUploadSpec())
|
||||
.withIncremental(attachment.getIncrementalDigest() != null);
|
||||
.withResumableUploadSpec(ApplicationDependencies.getSignalServiceMessageSender().getResumableUploadSpec());
|
||||
|
||||
thumbnail = builder.build();
|
||||
}
|
||||
|
||||
@@ -65,8 +65,8 @@ import org.whispersystems.signalservice.api.messages.multidevice.ViewOnceOpenMes
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.ViewedMessage;
|
||||
import org.whispersystems.signalservice.api.messages.shared.SharedContact;
|
||||
import org.whispersystems.signalservice.api.push.DistributionId;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId.PNI;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.MalformedResponseException;
|
||||
@@ -123,10 +123,8 @@ import org.whispersystems.signalservice.internal.push.exceptions.GroupStaleDevic
|
||||
import org.whispersystems.signalservice.internal.push.exceptions.InvalidUnidentifiedAccessHeaderException;
|
||||
import org.whispersystems.signalservice.internal.push.exceptions.MismatchedDevicesException;
|
||||
import org.whispersystems.signalservice.internal.push.exceptions.StaleDevicesException;
|
||||
import org.whispersystems.signalservice.internal.push.http.AttachmentCipherOutputStreamFactory;
|
||||
import org.whispersystems.signalservice.internal.push.http.CancelationSignal;
|
||||
import org.whispersystems.signalservice.internal.push.http.IncrementalAttachmentCipherOutputStreamFactory;
|
||||
import org.whispersystems.signalservice.internal.push.http.LegacyAttachmentCipherOutputStreamFactory;
|
||||
import org.whispersystems.signalservice.internal.push.http.OutputStreamFactory;
|
||||
import org.whispersystems.signalservice.internal.push.http.PartialSendBatchCompleteListener;
|
||||
import org.whispersystems.signalservice.internal.push.http.PartialSendCompleteListener;
|
||||
import org.whispersystems.signalservice.internal.push.http.ResumableUploadSpec;
|
||||
@@ -784,20 +782,18 @@ public class SignalServiceMessageSender {
|
||||
}
|
||||
|
||||
public SignalServiceAttachmentPointer uploadAttachment(SignalServiceAttachmentStream attachment) throws IOException {
|
||||
byte[] attachmentKey = attachment.getResumableUploadSpec().map(ResumableUploadSpec::getSecretKey).orElseGet(() -> Util.getSecretBytes(64));
|
||||
byte[] attachmentIV = attachment.getResumableUploadSpec().map(ResumableUploadSpec::getIV).orElseGet(() -> Util.getSecretBytes(16));
|
||||
long paddedLength = PaddingInputStream.getPaddedSize(attachment.getLength());
|
||||
InputStream dataStream = new PaddingInputStream(attachment.getInputStream(), attachment.getLength());
|
||||
long ciphertextLength = AttachmentCipherOutputStream.getCiphertextLength(paddedLength);
|
||||
OutputStreamFactory outputStreamFactory = attachment.isIncremental() ? new IncrementalAttachmentCipherOutputStreamFactory(attachmentKey, attachmentIV)
|
||||
: new LegacyAttachmentCipherOutputStreamFactory(attachmentKey, attachmentIV);
|
||||
PushAttachmentData attachmentData = new PushAttachmentData(attachment.getContentType(),
|
||||
dataStream,
|
||||
ciphertextLength,
|
||||
outputStreamFactory,
|
||||
attachment.getListener(),
|
||||
attachment.getCancelationSignal(),
|
||||
attachment.getResumableUploadSpec().orElse(null));
|
||||
byte[] attachmentKey = attachment.getResumableUploadSpec().map(ResumableUploadSpec::getSecretKey).orElseGet(() -> Util.getSecretBytes(64));
|
||||
byte[] attachmentIV = attachment.getResumableUploadSpec().map(ResumableUploadSpec::getIV).orElseGet(() -> Util.getSecretBytes(16));
|
||||
long paddedLength = PaddingInputStream.getPaddedSize(attachment.getLength());
|
||||
InputStream dataStream = new PaddingInputStream(attachment.getInputStream(), attachment.getLength());
|
||||
long ciphertextLength = AttachmentCipherOutputStream.getCiphertextLength(paddedLength);
|
||||
PushAttachmentData attachmentData = new PushAttachmentData(attachment.getContentType(),
|
||||
dataStream,
|
||||
ciphertextLength,
|
||||
new AttachmentCipherOutputStreamFactory(attachmentKey, attachmentIV),
|
||||
attachment.getListener(),
|
||||
attachment.getCancelationSignal(),
|
||||
attachment.getResumableUploadSpec().orElse(null));
|
||||
|
||||
if (attachment.getResumableUploadSpec().isPresent()) {
|
||||
return uploadAttachmentV3(attachment, attachmentKey, attachmentData);
|
||||
@@ -835,7 +831,7 @@ public class SignalServiceMessageSender {
|
||||
attachment.getPreview(),
|
||||
attachment.getWidth(), attachment.getHeight(),
|
||||
Optional.of(attachmentIdAndDigest.second().getDigest()),
|
||||
Optional.ofNullable(attachmentIdAndDigest.second().getIncrementalDigest()),
|
||||
Optional.of(attachmentIdAndDigest.second().getIncrementalDigest()),
|
||||
attachment.getFileName(),
|
||||
attachment.getVoiceNote(),
|
||||
attachment.isBorderless(),
|
||||
|
||||
@@ -62,7 +62,6 @@ public abstract class SignalServiceAttachment {
|
||||
private String blurHash;
|
||||
private long uploadTimestamp;
|
||||
private ResumableUploadSpec resumableUploadSpec;
|
||||
private boolean isIncremental;
|
||||
|
||||
private Builder() {}
|
||||
|
||||
@@ -141,11 +140,6 @@ public abstract class SignalServiceAttachment {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withIncremental(boolean isIncremental) {
|
||||
this.isIncremental = isIncremental;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SignalServiceAttachmentStream build() {
|
||||
if (inputStream == null) throw new IllegalArgumentException("Must specify stream!");
|
||||
if (contentType == null) throw new IllegalArgumentException("No content type specified!");
|
||||
@@ -166,8 +160,7 @@ public abstract class SignalServiceAttachment {
|
||||
Optional.ofNullable(blurHash),
|
||||
listener,
|
||||
cancelationSignal,
|
||||
Optional.ofNullable(resumableUploadSpec),
|
||||
isIncremental);
|
||||
Optional.ofNullable(resumableUploadSpec));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ public class SignalServiceAttachmentStream extends SignalServiceAttachment imple
|
||||
private final Optional<String> caption;
|
||||
private final Optional<String> blurHash;
|
||||
private final Optional<ResumableUploadSpec> resumableUploadSpec;
|
||||
private final boolean isIncremental;
|
||||
|
||||
public SignalServiceAttachmentStream(InputStream inputStream,
|
||||
String contentType,
|
||||
@@ -47,7 +46,7 @@ public class SignalServiceAttachmentStream extends SignalServiceAttachment imple
|
||||
ProgressListener listener,
|
||||
CancelationSignal cancelationSignal)
|
||||
{
|
||||
this(inputStream, contentType, length, fileName, voiceNote, borderless, gif, Optional.empty(), 0, 0, System.currentTimeMillis(), Optional.empty(), Optional.empty(), listener, cancelationSignal, Optional.empty(), false);
|
||||
this(inputStream, contentType, length, fileName, voiceNote, borderless, gif, Optional.empty(), 0, 0, System.currentTimeMillis(), Optional.empty(), Optional.empty(), listener, cancelationSignal, Optional.empty());
|
||||
}
|
||||
|
||||
public SignalServiceAttachmentStream(InputStream inputStream,
|
||||
@@ -65,8 +64,7 @@ public class SignalServiceAttachmentStream extends SignalServiceAttachment imple
|
||||
Optional<String> blurHash,
|
||||
ProgressListener listener,
|
||||
CancelationSignal cancelationSignal,
|
||||
Optional<ResumableUploadSpec> resumableUploadSpec,
|
||||
boolean isIncremental)
|
||||
Optional<ResumableUploadSpec> resumableUploadSpec)
|
||||
{
|
||||
super(contentType);
|
||||
this.inputStream = inputStream;
|
||||
@@ -84,7 +82,6 @@ public class SignalServiceAttachmentStream extends SignalServiceAttachment imple
|
||||
this.blurHash = blurHash;
|
||||
this.cancelationSignal = cancelationSignal;
|
||||
this.resumableUploadSpec = resumableUploadSpec;
|
||||
this.isIncremental = isIncremental;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -157,10 +154,6 @@ public class SignalServiceAttachmentStream extends SignalServiceAttachment imple
|
||||
return resumableUploadSpec;
|
||||
}
|
||||
|
||||
public boolean isIncremental() {
|
||||
return isIncremental;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
inputStream.close();
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.signalservice.internal.push.http
|
||||
|
||||
import org.signal.libsignal.protocol.incrementalmac.ChunkSizeChoice
|
||||
import org.signal.libsignal.protocol.incrementalmac.IncrementalMacOutputStream
|
||||
import org.whispersystems.signalservice.api.crypto.AttachmentCipherOutputStream
|
||||
import org.whispersystems.signalservice.api.crypto.DigestingOutputStream
|
||||
import java.io.IOException
|
||||
import java.io.OutputStream
|
||||
@@ -14,21 +10,24 @@ import java.io.OutputStream
|
||||
/**
|
||||
* Creates [AttachmentCipherOutputStream] using the provided [key] and [iv].
|
||||
*
|
||||
* [createFor] is straightforward, and is the legacy behavior.
|
||||
* [createIncrementalFor] first wraps the stream in an [IncrementalMacOutputStream] to calculate MAC digests on chunks as the stream is written to.
|
||||
*
|
||||
* @property key
|
||||
* @property iv
|
||||
*/
|
||||
class IncrementalAttachmentCipherOutputStreamFactory(private val key: ByteArray, private val iv: ByteArray) : IncrementalOutputStreamFactory {
|
||||
|
||||
private val legacyDelegate = LegacyAttachmentCipherOutputStreamFactory(key, iv)
|
||||
|
||||
class AttachmentCipherOutputStreamFactory(private val key: ByteArray, private val iv: ByteArray) : OutputStreamFactory {
|
||||
companion object {
|
||||
private const val AES_KEY_LENGTH = 32
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun createIncrementalFor(wrap: OutputStream?, length: Long, incrementalDigestOut: OutputStream?): DigestingOutputStream {
|
||||
override fun createFor(wrap: OutputStream): DigestingOutputStream {
|
||||
return AttachmentCipherOutputStream(key, iv, wrap)
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun createIncrementalFor(wrap: OutputStream?, length: Long, incrementalDigestOut: OutputStream?): DigestingOutputStream {
|
||||
if (length > Int.MAX_VALUE) {
|
||||
throw IllegalArgumentException("Attachment length overflows int!")
|
||||
}
|
||||
@@ -36,6 +35,6 @@ class IncrementalAttachmentCipherOutputStreamFactory(private val key: ByteArray,
|
||||
val privateKey = key.sliceArray(AES_KEY_LENGTH until key.size)
|
||||
val chunkSizeChoice = ChunkSizeChoice.inferChunkSize(length.toInt().coerceAtLeast(1))
|
||||
val incrementalStream = IncrementalMacOutputStream(wrap, privateKey, chunkSizeChoice, incrementalDigestOut)
|
||||
return legacyDelegate.createFor(incrementalStream)
|
||||
return createFor(incrementalStream)
|
||||
}
|
||||
}
|
||||
@@ -41,9 +41,9 @@ class DigestingRequestBody(
|
||||
override fun writeTo(sink: BufferedSink) {
|
||||
val digestStream = ByteArrayOutputStream()
|
||||
val inner = SkippingOutputStream(contentStart, sink.outputStream())
|
||||
val isIncremental = outputStreamFactory is IncrementalOutputStreamFactory
|
||||
val isIncremental = outputStreamFactory is AttachmentCipherOutputStreamFactory
|
||||
val outputStream: DigestingOutputStream = if (isIncremental) {
|
||||
(outputStreamFactory as IncrementalOutputStreamFactory).createIncrementalFor(inner, contentLength, digestStream)
|
||||
(outputStreamFactory as AttachmentCipherOutputStreamFactory).createIncrementalFor(inner, contentLength, digestStream)
|
||||
} else {
|
||||
outputStreamFactory.createFor(inner)
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.signalservice.internal.push.http
|
||||
|
||||
import org.whispersystems.signalservice.api.crypto.DigestingOutputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
interface IncrementalOutputStreamFactory : OutputStreamFactory {
|
||||
|
||||
override fun createFor(wrap: OutputStream?): DigestingOutputStream = error("Use createIncrementalFor instead.")
|
||||
|
||||
fun createIncrementalFor(wrap: OutputStream?, length: Long, incrementalDigestOut: OutputStream?): DigestingOutputStream
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.signalservice.internal.push.http
|
||||
|
||||
import org.whispersystems.signalservice.api.crypto.AttachmentCipherOutputStream
|
||||
import org.whispersystems.signalservice.api.crypto.DigestingOutputStream
|
||||
import java.io.IOException
|
||||
import java.io.OutputStream
|
||||
|
||||
/**
|
||||
* Creates [AttachmentCipherOutputStream] using the provided [key] and [iv].
|
||||
*
|
||||
* [createFor] is straightforward, and is the legacy behavior.
|
||||
*
|
||||
* @property key
|
||||
* @property iv
|
||||
*/
|
||||
class LegacyAttachmentCipherOutputStreamFactory(private val key: ByteArray, private val iv: ByteArray) : OutputStreamFactory {
|
||||
@Throws(IOException::class)
|
||||
override fun createFor(wrap: OutputStream): DigestingOutputStream {
|
||||
return AttachmentCipherOutputStream(key, iv, wrap)
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,7 @@ import org.signal.libsignal.protocol.InvalidMessageException;
|
||||
import org.signal.libsignal.protocol.incrementalmac.InvalidMacException;
|
||||
import org.signal.libsignal.protocol.kdf.HKDFv3;
|
||||
import org.whispersystems.signalservice.internal.crypto.PaddingInputStream;
|
||||
import org.whispersystems.signalservice.internal.push.http.IncrementalAttachmentCipherOutputStreamFactory;
|
||||
import org.whispersystems.signalservice.internal.push.http.LegacyAttachmentCipherOutputStreamFactory;
|
||||
import org.whispersystems.signalservice.internal.push.http.AttachmentCipherOutputStreamFactory;
|
||||
import org.whispersystems.signalservice.internal.util.Util;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@@ -160,7 +159,7 @@ public final class AttachmentCipherTest {
|
||||
InputStream paddedInputStream = new PaddingInputStream(inputStream, length);
|
||||
ByteArrayOutputStream destinationOutputStream = new ByteArrayOutputStream();
|
||||
ByteArrayOutputStream incrementalDigestOutputStream = new ByteArrayOutputStream();
|
||||
DigestingOutputStream encryptingOutputStream = new IncrementalAttachmentCipherOutputStreamFactory(key, iv).createIncrementalFor(destinationOutputStream, length, incrementalDigestOutputStream);
|
||||
DigestingOutputStream encryptingOutputStream = new AttachmentCipherOutputStreamFactory(key, iv).createIncrementalFor(destinationOutputStream, length, incrementalDigestOutputStream);
|
||||
|
||||
Util.copy(paddedInputStream, encryptingOutputStream);
|
||||
|
||||
@@ -302,15 +301,16 @@ public final class AttachmentCipherTest {
|
||||
}
|
||||
|
||||
private static EncryptResult encryptData(byte[] data, byte[] keyMaterial, boolean withIncremental) throws IOException {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
ByteArrayOutputStream incrementalDigestOut = new ByteArrayOutputStream();
|
||||
byte[] iv = Util.getSecretBytes(16);
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
ByteArrayOutputStream incrementalDigestOut = new ByteArrayOutputStream();
|
||||
byte[] iv = Util.getSecretBytes(16);
|
||||
AttachmentCipherOutputStreamFactory factory = new AttachmentCipherOutputStreamFactory(keyMaterial, iv);
|
||||
|
||||
DigestingOutputStream encryptStream;
|
||||
if (withIncremental) {
|
||||
encryptStream = new IncrementalAttachmentCipherOutputStreamFactory(keyMaterial, iv).createIncrementalFor(outputStream, data.length, incrementalDigestOut);
|
||||
encryptStream = factory.createIncrementalFor(outputStream, data.length, incrementalDigestOut);
|
||||
} else {
|
||||
encryptStream = new LegacyAttachmentCipherOutputStreamFactory(keyMaterial, iv).createFor(outputStream);
|
||||
encryptStream = factory.createFor(outputStream);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ public class DigestingRequestBodyTest {
|
||||
private final byte[] attachmentIV = Util.getSecretBytes(16);
|
||||
private final byte[] input = Util.getSecretBytes(CONTENT_LENGTH);
|
||||
|
||||
private final OutputStreamFactory outputStreamFactory = new LegacyAttachmentCipherOutputStreamFactory(attachmentKey, attachmentIV);
|
||||
private final OutputStreamFactory outputStreamFactory = new AttachmentCipherOutputStreamFactory(attachmentKey, attachmentIV);
|
||||
|
||||
@Test
|
||||
public void givenSameKeyAndIV_whenIWriteToBuffer_thenIExpectSameDigests() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user