use of org.whispersystems.signalservice.internal.push.http.AttachmentCipherOutputStreamFactory in project libsignal-service-java by signalapp.
the class SignalServiceMessageSender method createAttachmentPointer.
private AttachmentPointer createAttachmentPointer(SignalServiceAttachmentStream attachment) throws IOException {
byte[] attachmentKey = Util.getSecretBytes(64);
long paddedLength = PaddingInputStream.getPaddedSize(attachment.getLength());
long ciphertextLength = AttachmentCipherOutputStream.getCiphertextLength(paddedLength);
PushAttachmentData attachmentData = new PushAttachmentData(attachment.getContentType(), new PaddingInputStream(attachment.getInputStream(), attachment.getLength()), ciphertextLength, new AttachmentCipherOutputStreamFactory(attachmentKey), attachment.getListener());
Pair<Long, byte[]> attachmentIdAndDigest = socket.sendAttachment(attachmentData);
AttachmentPointer.Builder builder = AttachmentPointer.newBuilder().setContentType(attachment.getContentType()).setId(attachmentIdAndDigest.first()).setKey(ByteString.copyFrom(attachmentKey)).setDigest(ByteString.copyFrom(attachmentIdAndDigest.second())).setSize((int) attachment.getLength());
if (attachment.getFileName().isPresent()) {
builder.setFileName(attachment.getFileName().get());
}
if (attachment.getPreview().isPresent()) {
builder.setThumbnail(ByteString.copyFrom(attachment.getPreview().get()));
}
if (attachment.getWidth() > 0) {
builder.setWidth(attachment.getWidth());
}
if (attachment.getHeight() > 0) {
builder.setHeight(attachment.getHeight());
}
if (attachment.getVoiceNote()) {
builder.setFlags(AttachmentPointer.Flags.VOICE_MESSAGE_VALUE);
}
return builder.build();
}
use of org.whispersystems.signalservice.internal.push.http.AttachmentCipherOutputStreamFactory in project Signal-Android by WhisperSystems.
the class SignalServiceMessageSender method uploadAttachment.
public SignalServiceAttachmentPointer uploadAttachment(SignalServiceAttachmentStream attachment) throws IOException {
byte[] attachmentKey = attachment.getResumableUploadSpec().transform(ResumableUploadSpec::getSecretKey).or(() -> Util.getSecretBytes(64));
byte[] attachmentIV = attachment.getResumableUploadSpec().transform(ResumableUploadSpec::getIV).or(() -> 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().orNull());
if (attachment.getResumableUploadSpec().isPresent()) {
return uploadAttachmentV3(attachment, attachmentKey, attachmentData);
} else {
return uploadAttachmentV2(attachment, attachmentKey, attachmentData);
}
}
use of org.whispersystems.signalservice.internal.push.http.AttachmentCipherOutputStreamFactory in project Signal-Android by WhisperSystems.
the class AttachmentCipherTest method attachment_encryptDecryptPaddedContent.
@Test
public void attachment_encryptDecryptPaddedContent() throws IOException, InvalidMessageException {
int[] lengths = { 531, 600, 724, 1019, 1024 };
for (int length : lengths) {
byte[] plaintextInput = new byte[length];
for (int i = 0; i < length; i++) {
plaintextInput[i] = (byte) 0x97;
}
byte[] key = Util.getSecretBytes(64);
ByteArrayInputStream inputStream = new ByteArrayInputStream(plaintextInput);
InputStream dataStream = new PaddingInputStream(inputStream, length);
ByteArrayOutputStream encryptedStream = new ByteArrayOutputStream();
DigestingOutputStream digestStream = new AttachmentCipherOutputStreamFactory(key, null).createFor(encryptedStream);
Util.copy(dataStream, digestStream);
digestStream.flush();
byte[] digest = digestStream.getTransmittedDigest();
byte[] encryptedData = encryptedStream.toByteArray();
encryptedStream.close();
inputStream.close();
File cipherFile = writeToFile(encryptedData);
InputStream decryptedStream = AttachmentCipherInputStream.createForAttachment(cipherFile, length, key, digest);
byte[] plaintextOutput = readInputStreamFully(decryptedStream);
assertArrayEquals(plaintextInput, plaintextOutput);
cipherFile.delete();
}
}
Aggregations