1 /* 2 * Copyright (C) 2020 Finn Herzfeld 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 package io.finn.signald.util; 19 20 import io.finn.signald.db.Recipient; 21 import org.whispersystems.libsignal.IdentityKey; 22 import org.whispersystems.libsignal.fingerprint.Fingerprint; 23 import org.whispersystems.libsignal.fingerprint.NumericFingerprintGenerator; 24 import org.whispersystems.signalservice.api.util.UuidUtil; 25 26 public class SafetyNumberHelper { 27 // It seems like the official Signal apps don't use v2 safety numbers yet, so this is disabled for now. 28 public static boolean UseV2SafetyNumbers = false; 29 30 // computeSafetyNumber derived from signal-cli (computeSafetyNumber in src/main/java/org/asamk/signal/manager/Common.java) computeFingerprint(Recipient self, IdentityKey ownIdentityKey, Recipient recipient, IdentityKey theirIdentityKey)31 public static Fingerprint computeFingerprint(Recipient self, IdentityKey ownIdentityKey, Recipient recipient, IdentityKey theirIdentityKey) { 32 int version; 33 byte[] ownId; 34 byte[] theirId; 35 36 if (UseV2SafetyNumbers && self.getUUID() != null && recipient.getUUID() != null) { 37 // Version 2: UUID user 38 version = 2; 39 ownId = UuidUtil.toByteArray(self.getUUID()); 40 theirId = UuidUtil.toByteArray(recipient.getUUID()); 41 } else { 42 // Version 1: E164 user 43 version = 1; 44 if (!self.getAddress().getNumber().isPresent() || !recipient.getAddress().getNumber().isPresent()) { 45 return null; 46 } 47 ownId = self.getAddress().getNumber().get().getBytes(); 48 theirId = recipient.getAddress().getNumber().get().getBytes(); 49 } 50 51 return new NumericFingerprintGenerator(5200).createFor(version, ownId, ownIdentityKey, theirId, theirIdentityKey); 52 } 53 computeSafetyNumber(Recipient self, IdentityKey ownIdentityKey, Recipient recipient, IdentityKey theirIdentityKey)54 public static String computeSafetyNumber(Recipient self, IdentityKey ownIdentityKey, Recipient recipient, IdentityKey theirIdentityKey) { 55 Fingerprint fingerprint = computeFingerprint(self, ownIdentityKey, recipient, theirIdentityKey); 56 if (fingerprint == null) { 57 return "INVALID ID"; 58 } 59 return fingerprint.getDisplayableFingerprint().getDisplayText(); 60 } 61 } 62