Java Code Examples for org.thoughtcrime.securesms.util.Hex

The following examples show how to use org.thoughtcrime.securesms.util.Hex. These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source Project: mollyim-android   Author: mollyim   File: UpdateApkReadyListener.java    License: GNU General Public License v3.0 6 votes vote down vote up
private boolean isMatchingDigest(Context context, long downloadId, String theirEncodedDigest) {
  try {
    if (theirEncodedDigest == null) return false;

    byte[]          theirDigest     = Hex.fromStringCondensed(theirEncodedDigest);
    DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
    FileInputStream fin             = new FileInputStream(downloadManager.openDownloadedFile(downloadId).getFileDescriptor());
    byte[]          ourDigest       = FileUtils.getFileDigest(fin);

    fin.close();

    return MessageDigest.isEqual(ourDigest, theirDigest);
  } catch (IOException e) {
    Log.w(TAG, e);
    return false;
  }
}
 
Example #2
Source Project: mollyim-android   Author: mollyim   File: MultiDeviceStickerPackSyncJob.java    License: GNU General Public License v3.0 6 votes vote down vote up
@Override
protected void onRun() throws Exception {
  if (!TextSecurePreferences.isMultiDevice(context)) {
    Log.i(TAG, "Not multi device, aborting...");
    return;
  }

  List<StickerPackOperationMessage> operations = new LinkedList<>();

  try (StickerPackRecordReader reader = new StickerPackRecordReader(DatabaseFactory.getStickerDatabase(context).getInstalledStickerPacks())) {
    StickerPackRecord pack;
    while ((pack = reader.getNext()) != null) {
      byte[] packIdBytes  = Hex.fromStringCondensed(pack.getPackId());
      byte[] packKeyBytes = Hex.fromStringCondensed(pack.getPackKey());

      operations.add(new StickerPackOperationMessage(packIdBytes, packKeyBytes, StickerPackOperationMessage.Type.INSTALL));
    }
  }

  SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender();
  messageSender.sendMessage(SignalServiceSyncMessage.forStickerPackOperations(operations),
                            UnidentifiedAccessUtil.getAccessForSync(context));
}
 
Example #3
Source Project: mollyim-android   Author: mollyim   File: PushSendJob.java    License: GNU General Public License v3.0 6 votes vote down vote up
protected Optional<SignalServiceDataMessage.Sticker> getStickerFor(OutgoingMediaMessage message) {
  Attachment stickerAttachment = Stream.of(message.getAttachments()).filter(Attachment::isSticker).findFirst().orElse(null);

  if (stickerAttachment == null) {
    return Optional.absent();
  }

  try {
    byte[]                  packId     = Hex.fromStringCondensed(stickerAttachment.getSticker().getPackId());
    byte[]                  packKey    = Hex.fromStringCondensed(stickerAttachment.getSticker().getPackKey());
    int                     stickerId  = stickerAttachment.getSticker().getStickerId();
    SignalServiceAttachment attachment = getAttachmentPointerFor(stickerAttachment);

    return Optional.of(new SignalServiceDataMessage.Sticker(packId, packKey, stickerId, attachment));
  } catch (IOException e) {
    Log.w(TAG, "Failed to decode sticker id/key", e);
    return Optional.absent();
  }
}
 
Example #4
Source Project: mollyim-android   Author: mollyim   File: StickerDownloadJob.java    License: GNU General Public License v3.0 6 votes vote down vote up
@Override
protected void onRun() throws Exception {
  StickerDatabase db = DatabaseFactory.getStickerDatabase(context);

  if (db.getSticker(sticker.getPackId(), sticker.getStickerId(), sticker.isCover()) != null) {
    Log.w(TAG, "Sticker already downloaded.");
    return;
  }

  if (!db.isPackInstalled(sticker.getPackId()) && !sticker.isCover()) {
    Log.w(TAG, "Pack is no longer installed.");
    return;
  }

  SignalServiceMessageReceiver receiver     = ApplicationDependencies.getSignalServiceMessageReceiver();
  byte[]                       packIdBytes  = Hex.fromStringCondensed(sticker.getPackId ());
  byte[]                       packKeyBytes = Hex.fromStringCondensed(sticker.getPackKey());
  InputStream                  stream       = receiver.retrieveSticker(packIdBytes, packKeyBytes, sticker.getStickerId());

  db.insertSticker(sticker, stream, notify);
}
 
Example #5
Source Project: mollyim-android   Author: mollyim   File: UpdateApkJob.java    License: GNU General Public License v3.0 6 votes vote down vote up
private void handleDownloadStart(String uri, String versionName, byte[] digest) {
  clearPreviousDownloads(context);

  DownloadManager         downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
  DownloadManager.Request downloadRequest = new DownloadManager.Request(Uri.parse(uri));

  downloadRequest.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
  downloadRequest.setTitle("Downloading Signal update");
  downloadRequest.setDescription("Downloading Signal " + versionName);
  downloadRequest.setVisibleInDownloadsUi(false);
  downloadRequest.setDestinationInExternalFilesDir(context, null, "signal-update.apk");
  downloadRequest.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);

  long downloadId = downloadManager.enqueue(downloadRequest);
  TextSecurePreferences.setUpdateApkDownloadId(context, downloadId);
  TextSecurePreferences.setUpdateApkDigest(context, Hex.toStringCondensed(digest));
}
 
Example #6
Source Project: mollyim-android   Author: mollyim   File: PushProcessMessageJob.java    License: GNU General Public License v3.0 6 votes vote down vote up
private void handleSynchronizeStickerPackOperation(@NonNull List<StickerPackOperationMessage> stickerPackOperations) {
  JobManager jobManager = ApplicationDependencies.getJobManager();

  for (StickerPackOperationMessage operation : stickerPackOperations) {
    if (operation.getPackId().isPresent() && operation.getPackKey().isPresent() && operation.getType().isPresent()) {
      String packId  = Hex.toStringCondensed(operation.getPackId().get());
      String packKey = Hex.toStringCondensed(operation.getPackKey().get());

      switch (operation.getType().get()) {
        case INSTALL:
          jobManager.add(StickerPackDownloadJob.forInstall(packId, packKey, false));
          break;
        case REMOVE:
          DatabaseFactory.getStickerDatabase(context).uninstallPack(packId);
          break;
      }
    } else {
      Log.w(TAG, "Received incomplete sticker pack operation sync.");
    }
  }
}
 
Example #7
@Override
protected void onRun() throws Exception {
  if (!TextSecurePreferences.isMultiDevice(context)) {
    Log.i(TAG, "Not multi device, aborting...");
    return;
  }

  byte[] packIdBytes  = Hex.fromStringCondensed(packId);
  byte[] packKeyBytes = Hex.fromStringCondensed(packKey);

  StickerPackOperationMessage.Type remoteType;

  switch (type) {
    case INSTALL: remoteType = StickerPackOperationMessage.Type.INSTALL; break;
    case REMOVE:  remoteType = StickerPackOperationMessage.Type.REMOVE; break;
    default:      throw new AssertionError("No matching type?");
  }

  SignalServiceMessageSender  messageSender        = ApplicationDependencies.getSignalServiceMessageSender();
  StickerPackOperationMessage stickerPackOperation = new StickerPackOperationMessage(packIdBytes, packKeyBytes, remoteType);

  messageSender.sendMessage(SignalServiceSyncMessage.forStickerPackOperations(Collections.singletonList(stickerPackOperation)),
                            UnidentifiedAccessUtil.getAccessForSync(context));
}
 
Example #8
Source Project: mollyim-android   Author: mollyim   File: PinHashing_hashPin_Test.java    License: GNU General Public License v3.0 6 votes vote down vote up
@Test
public void argon2_hashed_pin_password() throws IOException {
  String    pin       = "password";
  byte[]    backupId  = Hex.fromStringCondensed("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f");
  MasterKey masterKey = new MasterKey(Hex.fromStringCondensed("202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"));

  HashedPin hashedPin = PinHashing.hashPin(pin, () -> backupId);
  KbsData   kbsData   = hashedPin.createNewKbsData(masterKey);

  assertArrayEquals(hashedPin.getKbsAccessKey(), kbsData.getKbsAccessKey());
  assertArrayEquals(Hex.fromStringCondensed("ab7e8499d21f80a6600b3b9ee349ac6d72c07e3359fe885a934ba7aa844429f8"), kbsData.getKbsAccessKey());
  assertArrayEquals(Hex.fromStringCondensed("3f33ce58eb25b40436592a30eae2a8fabab1899095f4e2fba6e2d0dc43b4a2d9cac5a3931748522393951e0e54dec769"), kbsData.getCipherText());
  assertEquals(masterKey, kbsData.getMasterKey());

  String localPinHash = PinHashing.localPinHash(pin);
  assertTrue(PinHashing.verifyLocalPinHash(localPinHash, pin));
}
 
Example #9
Source Project: mollyim-android   Author: mollyim   File: PinHashing_hashPin_Test.java    License: GNU General Public License v3.0 6 votes vote down vote up
@Test
public void argon2_hashed_pin_another_password() throws IOException {
  String    pin       = "anotherpassword";
  byte[]    backupId  = Hex.fromStringCondensed("202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f");
  MasterKey masterKey = new MasterKey(Hex.fromStringCondensed("88a787415a2ecd79da0d1016a82a27c5c695c9a19b88b0aa1d35683280aa9a67"));

  HashedPin hashedPin = PinHashing.hashPin(pin, () -> backupId);
  KbsData   kbsData   = hashedPin.createNewKbsData(masterKey);

  assertArrayEquals(hashedPin.getKbsAccessKey(), kbsData.getKbsAccessKey());
  assertArrayEquals(Hex.fromStringCondensed("301d9dd1e96f20ce51083f67d3298fd37b97525de8324d5e12ed2d407d3d927b"), kbsData.getKbsAccessKey());
  assertArrayEquals(Hex.fromStringCondensed("9d9b05402ea39c17ff1c9298c8a0e86784a352aa02a74943bf8bcf07ec0f4b574a5b786ad0182c8d308d9eb06538b8c9"), kbsData.getCipherText());
  assertEquals(masterKey, kbsData.getMasterKey());

  String localPinHash = PinHashing.localPinHash(pin);
  assertTrue(PinHashing.verifyLocalPinHash(localPinHash, pin));
}
 
Example #10
Source Project: mollyim-android   Author: mollyim   File: PinHashing_hashPin_Test.java    License: GNU General Public License v3.0 6 votes vote down vote up
@Test
public void argon2_hashed_pin_password_with_spaces_diacritics_and_non_arabic_numerals() throws IOException {
  String    pin       = " Pass६örd ";
  byte[]    backupId  = Hex.fromStringCondensed("cba811749042b303a6a7efa5ccd160aea5e3ea243c8d2692bd13d515732f51a8");
  MasterKey masterKey = new MasterKey(Hex.fromStringCondensed("9571f3fde1e58588ba49bcf82be1b301ca3859a6f59076f79a8f47181ef952bf"));

  HashedPin hashedPin = PinHashing.hashPin(pin, () -> backupId);
  KbsData   kbsData   = hashedPin.createNewKbsData(masterKey);

  assertArrayEquals(hashedPin.getKbsAccessKey(), kbsData.getKbsAccessKey());
  assertArrayEquals(Hex.fromStringCondensed("ab645acdccc1652a48a34b2ac6926340ff35c03034013f68760f20013f028dd8"), kbsData.getKbsAccessKey());
  assertArrayEquals(Hex.fromStringCondensed("11c0ba1834db15e47c172f6c987c64bd4cfc69c6047dd67a022afeec0165a10943f204d5b8f37b3cb7bab21c6dfc39c8"), kbsData.getCipherText());
  assertEquals(masterKey, kbsData.getMasterKey());

  assertEquals("577939bccb2b6638c39222d5a97998a867c5e154e30b82cc120f2dd07a3de987", kbsData.getMasterKey().deriveRegistrationLock());

  String localPinHash = PinHashing.localPinHash(pin);
  assertTrue(PinHashing.verifyLocalPinHash(localPinHash, pin));
}
 
Example #11
Source Project: mollyim-android   Author: mollyim   File: PinHashing_hashPin_Test.java    License: GNU General Public License v3.0 6 votes vote down vote up
@Test
public void argon2_hashed_pin_password_with_just_non_arabic_numerals() throws IOException {
  String    pin       = " ६१८ ";
  byte[]    backupId  = Hex.fromStringCondensed("717dc111a98423a57196512606822fca646c653facd037c10728f14ba0be2ab3");
  MasterKey masterKey = new MasterKey(Hex.fromStringCondensed("0432d735b32f66d0e3a70d4f9cc821a8529521a4937d26b987715d8eff4e4c54"));

  HashedPin hashedPin = PinHashing.hashPin(pin, () -> backupId);
  KbsData   kbsData   = hashedPin.createNewKbsData(masterKey);


  assertArrayEquals(hashedPin.getKbsAccessKey(), kbsData.getKbsAccessKey());
  assertArrayEquals(Hex.fromStringCondensed("d2fedabd0d4c17a371491c9722578843a26be3b4923e28d452ab2fc5491e794b"), kbsData.getKbsAccessKey());
  assertArrayEquals(Hex.fromStringCondensed("877ef871ef1fc668401c717ef21aa12e8523579fb1ff4474b76f28c2293537c80cc7569996c9e0229bea7f378e3a824e"), kbsData.getCipherText());
  assertEquals(masterKey, kbsData.getMasterKey());

  assertEquals("23a75cb1df1a87df45cc2ed167c2bdc85ab1220b847c88761b0005cac907fce5", kbsData.getMasterKey().deriveRegistrationLock());

  String localPinHash = PinHashing.localPinHash(pin);
  assertTrue(PinHashing.verifyLocalPinHash(localPinHash, pin));
}
 
Example #12
Source Project: mollyim-android   Author: mollyim   File: PublicKey.java    License: GNU General Public License v3.0 5 votes vote down vote up
public byte[] serialize() {
  byte[] keyIdBytes      = Conversions.mediumToByteArray(id);
  byte[] serializedPoint = publicKey.serialize();

  Log.i(TAG, "Serializing public key point: " + Hex.toString(serializedPoint));

  return Util.combine(keyIdBytes, serializedPoint);
}
 
Example #13
Source Project: mollyim-android   Author: mollyim   File: UpdateApkJob.java    License: GNU General Public License v3.0 5 votes vote down vote up
@Override
public void onRun() throws IOException, PackageManager.NameNotFoundException {
  if (!BuildConfig.AUTOMATIC_UPDATES) return;

  Log.i(TAG, "Checking for APK update...");

  OkHttpClient client  = new OkHttpClient();
  Request      request = new Request.Builder().url(String.format("%s/latest.json", BuildConfig.NOPLAY_UPDATE_URL)).build();

  Response response = client.newCall(request).execute();

  if (!response.isSuccessful()) {
    throw new IOException("Bad response: " + response.message());
  }

  UpdateDescriptor updateDescriptor = JsonUtils.fromJson(response.body().string(), UpdateDescriptor.class);
  byte[]           digest           = Hex.fromStringCondensed(updateDescriptor.getDigest());

  Log.i(TAG, "Got descriptor: " + updateDescriptor);

  if (updateDescriptor.getVersionCode() > getVersionCode()) {
    DownloadStatus downloadStatus = getDownloadStatus(updateDescriptor.getUrl(), digest);

    Log.i(TAG, "Download status: "  + downloadStatus.getStatus());

    if (downloadStatus.getStatus() == DownloadStatus.Status.COMPLETE) {
      Log.i(TAG, "Download status complete, notifying...");
      handleDownloadNotify(downloadStatus.getDownloadId());
    } else if (downloadStatus.getStatus() == DownloadStatus.Status.MISSING) {
      Log.i(TAG, "Download status missing, starting download...");
      handleDownloadStart(updateDescriptor.getUrl(), updateDescriptor.getVersionName(), digest);
    }
  }
}
 
Example #14
Source Project: mollyim-android   Author: mollyim   File: UpdateApkJob.java    License: GNU General Public License v3.0 5 votes vote down vote up
private @Nullable byte[] getPendingDigest(Context context) {
  try {
    String encodedDigest = TextSecurePreferences.getUpdateApkDigest(context);

    if (encodedDigest == null) return null;

    return Hex.fromStringCondensed(encodedDigest);
  } catch (IOException e) {
    Log.w(TAG, e);
    return null;
  }
}
 
Example #15
Source Project: mollyim-android   Author: mollyim   File: WakeGroupV2Job.java    License: GNU General Public License v3.0 5 votes vote down vote up
@Override
public @NonNull WakeGroupV2Job create(@NonNull Parameters parameters, @NonNull Data data) {
  try {
    return new WakeGroupV2Job(parameters,
                              new GroupMasterKey(Hex.fromStringCondensed(data.getString(KEY_GROUP_MASTER_KEY))));
  } catch (InvalidInputException | IOException e) {
    throw new AssertionError(e);
  }
}
 
Example #16
Source Project: mollyim-android   Author: mollyim   File: AttachmentDownloadJob.java    License: GNU General Public License v3.0 5 votes vote down vote up
private SignalServiceAttachmentPointer createAttachmentPointer(Attachment attachment) throws InvalidPartException {
  if (TextUtils.isEmpty(attachment.getLocation())) {
    throw new InvalidPartException("empty content id");
  }

  if (TextUtils.isEmpty(attachment.getKey())) {
    throw new InvalidPartException("empty encrypted key");
  }

  try {
    final SignalServiceAttachmentRemoteId remoteId = SignalServiceAttachmentRemoteId.from(attachment.getLocation());
    final byte[]                          key      = Base64.decode(attachment.getKey());

    if (attachment.getDigest() != null) {
      Log.i(TAG, "Downloading attachment with digest: " + Hex.toString(attachment.getDigest()));
    } else {
      Log.i(TAG, "Downloading attachment with no digest...");
    }

    return new SignalServiceAttachmentPointer(attachment.getCdnNumber(), remoteId, null, key,
                                              Optional.of(Util.toIntExact(attachment.getSize())),
                                              Optional.absent(),
                                              0, 0,
                                              Optional.fromNullable(attachment.getDigest()),
                                              Optional.fromNullable(attachment.getFileName()),
                                              attachment.isVoiceNote(),
                                              Optional.absent(),
                                              Optional.fromNullable(attachment.getBlurHash()).transform(BlurHash::getHash),
                                              attachment.getUploadTimestamp());
  } catch (IOException | ArithmeticException e) {
    Log.w(TAG, e);
    throw new InvalidPartException(e);
  }
}
 
Example #17
Source Project: mollyim-android   Author: mollyim   File: PushProcessMessageJob.java    License: GNU General Public License v3.0 5 votes vote down vote up
private Optional<Attachment> getStickerAttachment(Optional<SignalServiceDataMessage.Sticker> sticker) {
  if (!sticker.isPresent()) {
    return Optional.absent();
  }

  if (sticker.get().getPackId() == null || sticker.get().getPackKey() == null || sticker.get().getAttachment() == null) {
    Log.w(TAG, "Malformed sticker!");
    return Optional.absent();
  }

  String          packId          = Hex.toStringCondensed(sticker.get().getPackId());
  String          packKey         = Hex.toStringCondensed(sticker.get().getPackKey());
  int             stickerId       = sticker.get().getStickerId();
  StickerLocator  stickerLocator  = new StickerLocator(packId, packKey, stickerId);
  StickerDatabase stickerDatabase = DatabaseFactory.getStickerDatabase(context);
  StickerRecord   stickerRecord   = stickerDatabase.getSticker(stickerLocator.getPackId(), stickerLocator.getStickerId(), false);

  if (stickerRecord != null) {
    return Optional.of(new UriAttachment(stickerRecord.getUri(),
                                         stickerRecord.getUri(),
                                         MediaUtil.IMAGE_WEBP,
                                         AttachmentDatabase.TRANSFER_PROGRESS_DONE,
                                         stickerRecord.getSize(),
                                         StickerSlide.WIDTH,
                                         StickerSlide.HEIGHT,
                                         null,
                                         String.valueOf(new SecureRandom().nextLong()),
                                         false,
                                         false,
                                         null,
                                         stickerLocator,
                                         null,
                                         null,
                                         null));
  } else {
    return Optional.of(PointerAttachment.forPointer(Optional.of(sticker.get().getAttachment()), stickerLocator).get());
  }
}
 
Example #18
Source Project: mollyim-android   Author: mollyim   File: GroupIdTest.java    License: GNU General Public License v3.0 5 votes vote down vote up
@Test
public void can_create_for_gv2_from_GroupIdentifier() throws IOException, InvalidInputException {
  GroupId.V2 groupId = GroupId.v2(new GroupIdentifier(Hex.fromStringCondensed("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")));

  assertEquals("__signal_group__v2__!0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", groupId.toString());
  assertFalse(groupId.isMms());
  assertFalse(groupId.isV1());
  assertTrue(groupId.isV2());
  assertTrue(groupId.isPush());
}
 
Example #19
Source Project: mollyim-android   Author: mollyim   File: GroupIdTest.java    License: GNU General Public License v3.0 5 votes vote down vote up
@Test
public void can_create_for_gv2_from_GroupMasterKey() throws IOException, InvalidInputException {
  assumeZkGroupSupportedOnOS();

  GroupId.V2 groupId = GroupId.v2(new GroupMasterKey(Hex.fromStringCondensed("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")));

  assertEquals("__signal_group__v2__!8c4a5ec277691282f64b965b1b9affc0285380c993c413f7560967d502dcf2e6", groupId.toString());
  assertFalse(groupId.isMms());
  assertFalse(groupId.isV1());
  assertTrue(groupId.isV2());
  assertTrue(groupId.isPush());
}
 
Example #20
Source Project: mollyim-android   Author: mollyim   File: GroupIdTest.java    License: GNU General Public License v3.0 5 votes vote down vote up
@Test
public void can_parse_gv2() throws IOException {
  GroupId groupId = GroupId.parseOrThrow("__signal_group__v2__!9f475f59b2518bff6df22e820803f0e3585bd99e686fa7e7fbfc2f92fd5d953e");

  assertEquals("__signal_group__v2__!9f475f59b2518bff6df22e820803f0e3585bd99e686fa7e7fbfc2f92fd5d953e", groupId.toString());
  assertArrayEquals(Hex.fromStringCondensed("9f475f59b2518bff6df22e820803f0e3585bd99e686fa7e7fbfc2f92fd5d953e"), groupId.getDecodedId());
  assertFalse(groupId.isMms());
  assertFalse(groupId.isV1());
  assertTrue(groupId.isV2());
  assertTrue(groupId.isPush());
}
 
Example #21
Source Project: signald   Author: thefinn93   File: JsonStickerPackOperationMessage.java    License: GNU General Public License v3.0 5 votes vote down vote up
JsonStickerPackOperationMessage(StickerPackOperationMessage message) {
  if(message.getPackId().isPresent()) {
    packID = Hex.toStringCondensed(message.getPackId().get()); 
  }

  if(message.getPackKey().isPresent()) {
    packKey = Hex.toStringCondensed(message.getPackKey().get());
  }

  if(message.getType().isPresent()) {
    type = message.getType().get().toString();
  }
}
 
Example #22
Source Project: deltachat-android   Author: deltachat   File: AttachmentServer.java    License: GNU General Public License v3.0 5 votes vote down vote up
public AttachmentServer(Context context, Attachment attachment)
    throws IOException
{
  try {
    this.context      = context;
    this.attachment   = attachment;
    this.socket       = new ServerSocket(0, 0, InetAddress.getByAddress(new byte[]{127, 0, 0, 1}));
    this.port         = socket.getLocalPort();
    this.auth         = Hex.toStringCondensed(Util.getSecretBytes(16));

    this.socket.setSoTimeout(5000);
  } catch (UnknownHostException e) {
    throw new AssertionError(e);
  }
}
 
Example #23
Source Project: mollyim-android   Author: mollyim   File: GroupId.java    License: GNU General Public License v3.0 4 votes vote down vote up
private GroupId(@NonNull String prefix, @NonNull byte[] bytes) {
  this.encodedId = prefix + Hex.toStringCondensed(bytes);
}
 
Example #24
Source Project: mollyim-android   Author: mollyim   File: GroupId.java    License: GNU General Public License v3.0 4 votes vote down vote up
private static byte[] extractDecodedId(@NonNull String encodedGroupId) throws IOException {
  return Hex.fromStringCondensed(encodedGroupId.split("!", 2)[1]);
}
 
Example #25
Source Project: mollyim-android   Author: mollyim   File: DatabaseSecret.java    License: GNU General Public License v3.0 4 votes vote down vote up
public DatabaseSecret(@NonNull byte[] key) {
  this.key = key;
  this.encoded = Hex.toStringCondensed(key);
}
 
Example #26
Source Project: mollyim-android   Author: mollyim   File: DatabaseSecret.java    License: GNU General Public License v3.0 4 votes vote down vote up
public DatabaseSecret(@NonNull String encoded) throws IOException {
  this.key     = Hex.fromStringCondensed(encoded);
  this.encoded = encoded;
}
 
Example #27
Source Project: mollyim-android   Author: mollyim   File: PublicKey.java    License: GNU General Public License v3.0 4 votes vote down vote up
public String getFingerprint() {
  return Hex.toString(getFingerprintBytes());
}
 
Example #28
Source Project: mollyim-android   Author: mollyim   File: LinkPreviewRepository.java    License: GNU General Public License v3.0 4 votes vote down vote up
private RequestController fetchStickerPackLinkPreview(@NonNull Context context,
                                                      @NonNull String packUrl,
                                                      @NonNull Callback<Optional<LinkPreview>> callback)
{
  SignalExecutors.UNBOUNDED.execute(() -> {
    try {
      Pair<String, String> stickerParams = StickerUrl.parseShareLink(packUrl).or(new Pair<>("", ""));
      String               packIdString  = stickerParams.first();
      String               packKeyString = stickerParams.second();
      byte[]               packIdBytes   = Hex.fromStringCondensed(packIdString);
      byte[]               packKeyBytes  = Hex.fromStringCondensed(packKeyString);

      SignalServiceMessageReceiver receiver = ApplicationDependencies.getSignalServiceMessageReceiver();
      SignalServiceStickerManifest manifest = receiver.retrieveStickerManifest(packIdBytes, packKeyBytes);

      String                title        = manifest.getTitle().or(manifest.getAuthor()).or("");
      Optional<StickerInfo> firstSticker = Optional.fromNullable(manifest.getStickers().size() > 0 ? manifest.getStickers().get(0) : null);
      Optional<StickerInfo> cover        = manifest.getCover().or(firstSticker);

      if (cover.isPresent()) {
        Bitmap bitmap = GlideApp.with(context).asBitmap()
                                              .load(new StickerRemoteUri(packIdString, packKeyString, cover.get().getId()))
                                              .skipMemoryCache(true)
                                              .diskCacheStrategy(DiskCacheStrategy.NONE)
                                              .centerInside()
                                              .submit(512, 512)
                                              .get();

        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        bitmap.compress(Bitmap.CompressFormat.WEBP, 80, baos);

        byte[]               bytes     = baos.toByteArray();
        Uri                  uri       = BlobProvider.getInstance().forData(bytes).createForSingleSessionInMemory();
        Optional<Attachment> thumbnail = Optional.of(new UriAttachment(uri,
                                                     uri,
                                                     MediaUtil.IMAGE_WEBP,
                                                     AttachmentDatabase.TRANSFER_PROGRESS_STARTED,
                                                     bytes.length,
                                                     bitmap.getWidth(),
                                                     bitmap.getHeight(),
                                                     null,
                                                     null,
                                                     false,
                                                     false,
                                                     null,
                                                     null,
                                                     null,
                                                     null,
                                                     null));

        callback.onComplete(Optional.of(new LinkPreview(packUrl, title, thumbnail)));
      } else {
        callback.onComplete(Optional.absent());
      }
    } catch (IOException | InvalidMessageException | ExecutionException | InterruptedException e) {
      Log.w(TAG, "Failed to fetch sticker pack link preview.");
      callback.onComplete(Optional.absent());
    }
  });

  return () -> Log.i(TAG, "Cancelled sticker pack link preview fetch -- no effect.");
}
 
Example #29
Source Project: mollyim-android   Author: mollyim   File: StickerPackDownloadJob.java    License: GNU General Public License v3.0 4 votes vote down vote up
@Override
protected void onRun() throws IOException, InvalidMessageException {
  if (isReferencePack && !DatabaseFactory.getAttachmentDatabase(context).containsStickerPackId(packId) && !BlessedPacks.contains(packId)) {
    Log.w(TAG, "There are no attachments with the requested packId present for this reference pack. Skipping.");
    return;
  }

  if (isReferencePack && DatabaseFactory.getStickerDatabase(context).isPackAvailableAsReference(packId)) {
    Log.i(TAG, "Sticker pack already available for reference. Skipping.");
    return;
  }

  SignalServiceMessageReceiver receiver        = ApplicationDependencies.getSignalServiceMessageReceiver();
  JobManager                   jobManager      = ApplicationDependencies.getJobManager();
  StickerDatabase              stickerDatabase = DatabaseFactory.getStickerDatabase(context);
  byte[]                       packIdBytes     = Hex.fromStringCondensed(packId);
  byte[]                       packKeyBytes    = Hex.fromStringCondensed(packKey);
  SignalServiceStickerManifest manifest        = receiver.retrieveStickerManifest(packIdBytes, packKeyBytes);

  if (manifest.getStickers().isEmpty()) {
    Log.w(TAG, "No stickers in pack!");
    return;
  }

  if (!isReferencePack && stickerDatabase.isPackAvailableAsReference(packId)) {
    stickerDatabase.markPackAsInstalled(packId, notify);
  }

  StickerInfo      cover = manifest.getCover().or(manifest.getStickers().get(0));
  JobManager.Chain chain = jobManager.startChain(new StickerDownloadJob(new IncomingSticker(packId,
                                                                                            packKey,
                                                                                            manifest.getTitle().or(""),
                                                                                            manifest.getAuthor().or(""),
                                                                                            cover.getId(),
                                                                                            "",
                                                                                            true,
                                                                                            !isReferencePack),
                                                                        notify));



  if (!isReferencePack) {
    List<Job> jobs = new ArrayList<>(manifest.getStickers().size());

    for (StickerInfo stickerInfo : manifest.getStickers()) {
      jobs.add(new StickerDownloadJob(new IncomingSticker(packId,
                                                          packKey,
                                                          manifest.getTitle().or(""),
                                                          manifest.getAuthor().or(""),
                                                          stickerInfo.getId(),
                                                          stickerInfo.getEmoji(),
                                                          false,
                                                          true),
                                      notify));
    }

    chain.then(jobs);
  }

  chain.enqueue();
}
 
Example #30
Source Project: mollyim-android   Author: mollyim   File: AvatarGroupsV1DownloadJob.java    License: GNU General Public License v3.0 4 votes vote down vote up
@Override
public void onRun() throws IOException {
  GroupDatabase         database   = DatabaseFactory.getGroupDatabase(context);
  Optional<GroupRecord> record     = database.getGroup(groupId);
  File                  attachment = null;

  try {
    if (record.isPresent()) {
      long             avatarId    = record.get().getAvatarId();
      String           contentType = record.get().getAvatarContentType();
      byte[]           key         = record.get().getAvatarKey();
      String           relay       = record.get().getRelay();
      Optional<byte[]> digest      = Optional.fromNullable(record.get().getAvatarDigest());
      Optional<String> fileName    = Optional.absent();

      if (avatarId == -1 || key == null) {
        return;
      }

      if (digest.isPresent()) {
        Log.i(TAG, "Downloading group avatar with digest: " + Hex.toString(digest.get()));
      }

      attachment = File.createTempFile("avatar", "tmp", context.getCacheDir());
      attachment.deleteOnExit();

      SignalServiceMessageReceiver   receiver    = ApplicationDependencies.getSignalServiceMessageReceiver();
      SignalServiceAttachmentPointer pointer     = new SignalServiceAttachmentPointer(0, new SignalServiceAttachmentRemoteId(avatarId), contentType, key, Optional.of(0), Optional.absent(), 0, 0, digest, fileName, false, Optional.absent(), Optional.absent(), System.currentTimeMillis());
      InputStream                    inputStream = receiver.retrieveAttachment(pointer, attachment, AvatarHelper.AVATAR_DOWNLOAD_FAILSAFE_MAX_SIZE);

      AvatarHelper.setAvatar(context, record.get().getRecipientId(), inputStream);
      DatabaseFactory.getGroupDatabase(context).onAvatarUpdated(groupId, true);

      inputStream.close();
    }
  } catch (NonSuccessfulResponseCodeException | InvalidMessageException | MissingConfigurationException e) {
    Log.w(TAG, e);
  } finally {
    if (attachment != null)
      attachment.delete();
  }
}