use of org.whispersystems.signalservice.internal.crypto.PaddingInputStream 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.crypto.PaddingInputStream 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.crypto.PaddingInputStream in project libsignal-service-java by signalapp.
the class SignalServiceMessageSender method uploadAttachment.
public SignalServiceAttachmentPointer uploadAttachment(SignalServiceAttachmentStream attachment) throws IOException {
byte[] attachmentKey = Util.getSecretBytes(64);
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), attachment.getListener());
AttachmentUploadAttributes uploadAttributes = null;
if (pipe.get().isPresent()) {
Log.d(TAG, "Using pipe to retrieve attachment upload attributes...");
try {
uploadAttributes = pipe.get().get().getAttachmentUploadAttributes();
} catch (IOException e) {
Log.w(TAG, "Failed to retrieve attachment upload attributes using pipe. Falling back...");
}
}
if (uploadAttributes == null) {
Log.d(TAG, "Not using pipe to retrieve attachment upload attributes...");
uploadAttributes = socket.getAttachmentUploadAttributes();
}
Pair<Long, byte[]> attachmentIdAndDigest = socket.uploadAttachment(attachmentData, uploadAttributes);
return new SignalServiceAttachmentPointer(attachmentIdAndDigest.first(), attachment.getContentType(), attachmentKey, Optional.of(Util.toIntExact(attachment.getLength())), attachment.getPreview(), attachment.getWidth(), attachment.getHeight(), Optional.of(attachmentIdAndDigest.second()), attachment.getFileName(), attachment.getVoiceNote(), attachment.getCaption(), attachment.getBlurHash());
}
use of org.whispersystems.signalservice.internal.crypto.PaddingInputStream in project Signal-Android by signalapp.
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();
}
}
use of org.whispersystems.signalservice.internal.crypto.PaddingInputStream in project Signal-Android by signalapp.
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);
}
}
Aggregations