mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 18:40:39 +00:00
Add support for new safety numbers, that replace the hex fingerprint
This commit is contained in:
parent
086bdb937a
commit
f97b0c0faa
2 changed files with 74 additions and 12 deletions
|
@ -458,13 +458,13 @@ public class Main {
|
||||||
if (ns.get("number") == null) {
|
if (ns.get("number") == null) {
|
||||||
for (Map.Entry<String, List<JsonIdentityKeyStore.Identity>> keys : m.getIdentities().entrySet()) {
|
for (Map.Entry<String, List<JsonIdentityKeyStore.Identity>> keys : m.getIdentities().entrySet()) {
|
||||||
for (JsonIdentityKeyStore.Identity id : keys.getValue()) {
|
for (JsonIdentityKeyStore.Identity id : keys.getValue()) {
|
||||||
System.out.println(String.format("%s: %s Added: %s Fingerprint: %s", keys.getKey(), id.trustLevel, id.added, Hex.toStringCondensed(id.getFingerprint())));
|
printIdentityFingerprint(m, keys.getKey(), id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
String number = ns.getString("number");
|
String number = ns.getString("number");
|
||||||
for (JsonIdentityKeyStore.Identity id : m.getIdentities(number)) {
|
for (JsonIdentityKeyStore.Identity id : m.getIdentities(number)) {
|
||||||
System.out.println(String.format("%s: %s Added: %s Fingerprint: %s", number, id.trustLevel, id.added, Hex.toStringCondensed(id.getFingerprint())));
|
printIdentityFingerprint(m, number, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -487,16 +487,28 @@ public class Main {
|
||||||
} else {
|
} else {
|
||||||
String fingerprint = ns.getString("verified_fingerprint");
|
String fingerprint = ns.getString("verified_fingerprint");
|
||||||
if (fingerprint != null) {
|
if (fingerprint != null) {
|
||||||
byte[] fingerprintBytes;
|
fingerprint = fingerprint.replaceAll(" ", "");
|
||||||
try {
|
if (fingerprint.length() == 66) {
|
||||||
fingerprintBytes = Hex.toByteArray(fingerprint.replaceAll(" ", "").toLowerCase(Locale.ROOT));
|
byte[] fingerprintBytes;
|
||||||
} catch (Exception e) {
|
try {
|
||||||
System.err.println("Failed to parse the fingerprint, make sure the fingerprint is a correctly encoded hex string without additional characters.");
|
fingerprintBytes = Hex.toByteArray(fingerprint.toLowerCase(Locale.ROOT));
|
||||||
return 1;
|
} catch (Exception e) {
|
||||||
}
|
System.err.println("Failed to parse the fingerprint, make sure the fingerprint is a correctly encoded hex string without additional characters.");
|
||||||
boolean res = m.trustIdentityVerified(number, fingerprintBytes);
|
return 1;
|
||||||
if (!res) {
|
}
|
||||||
System.err.println("Failed to set the trust for the fingerprint of this number, make sure the number and the fingerprint are correct.");
|
boolean res = m.trustIdentityVerified(number, fingerprintBytes);
|
||||||
|
if (!res) {
|
||||||
|
System.err.println("Failed to set the trust for the fingerprint of this number, make sure the number and the fingerprint are correct.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (fingerprint.length() == 60) {
|
||||||
|
boolean res = m.trustIdentityVerifiedSafetyNumber(number, fingerprint);
|
||||||
|
if (!res) {
|
||||||
|
System.err.println("Failed to set the trust for the safety number of this phone number, make sure the phone number and the safety number are correct.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.err.println("Fingerprint has invalid format, either specify the old hex fingerprint or the new safety number");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -555,6 +567,22 @@ public class Main {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void printIdentityFingerprint(Manager m, String theirUsername, JsonIdentityKeyStore.Identity theirId) {
|
||||||
|
String digits = formatSafetyNumber(m.computeSafetyNumber(theirUsername, theirId.identityKey));
|
||||||
|
System.out.println(String.format("%s: %s Added: %s Fingerprint: %s Safety Number: %s", theirUsername,
|
||||||
|
theirId.trustLevel, theirId.added, Hex.toStringCondensed(theirId.getFingerprint()), digits));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String formatSafetyNumber(String digits) {
|
||||||
|
final int partCount = 12;
|
||||||
|
int partSize = digits.length() / partCount;
|
||||||
|
StringBuilder f = new StringBuilder(digits.length() + partCount);
|
||||||
|
for (int i = 0; i < partCount; i++) {
|
||||||
|
f.append(digits.substring(i * partSize, (i * partSize) + partSize)).append(" ");
|
||||||
|
}
|
||||||
|
return f.toString();
|
||||||
|
}
|
||||||
|
|
||||||
private static void handleGroupNotFoundException(GroupNotFoundException e) {
|
private static void handleGroupNotFoundException(GroupNotFoundException e) {
|
||||||
System.err.println("Failed to send to group: " + e.getMessage());
|
System.err.println("Failed to send to group: " + e.getMessage());
|
||||||
System.err.println("Aborting sending.");
|
System.err.println("Aborting sending.");
|
||||||
|
|
|
@ -31,6 +31,8 @@ import org.whispersystems.libsignal.*;
|
||||||
import org.whispersystems.libsignal.ecc.Curve;
|
import org.whispersystems.libsignal.ecc.Curve;
|
||||||
import org.whispersystems.libsignal.ecc.ECKeyPair;
|
import org.whispersystems.libsignal.ecc.ECKeyPair;
|
||||||
import org.whispersystems.libsignal.ecc.ECPublicKey;
|
import org.whispersystems.libsignal.ecc.ECPublicKey;
|
||||||
|
import org.whispersystems.libsignal.fingerprint.Fingerprint;
|
||||||
|
import org.whispersystems.libsignal.fingerprint.NumericFingerprintGenerator;
|
||||||
import org.whispersystems.libsignal.state.PreKeyRecord;
|
import org.whispersystems.libsignal.state.PreKeyRecord;
|
||||||
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
|
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
|
||||||
import org.whispersystems.libsignal.util.KeyHelper;
|
import org.whispersystems.libsignal.util.KeyHelper;
|
||||||
|
@ -125,6 +127,10 @@ class Manager implements Signal {
|
||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IdentityKey getIdentity() {
|
||||||
|
return signalProtocolStore.getIdentityKeyPair().getPublicKey();
|
||||||
|
}
|
||||||
|
|
||||||
public int getDeviceId() {
|
public int getDeviceId() {
|
||||||
return deviceId;
|
return deviceId;
|
||||||
}
|
}
|
||||||
|
@ -1330,6 +1336,29 @@ class Manager implements Signal {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trust this the identity with this safety number
|
||||||
|
*
|
||||||
|
* @param name username of the identity
|
||||||
|
* @param safetyNumber Safety number
|
||||||
|
*/
|
||||||
|
public boolean trustIdentityVerifiedSafetyNumber(String name, String safetyNumber) {
|
||||||
|
List<JsonIdentityKeyStore.Identity> ids = signalProtocolStore.getIdentities(name);
|
||||||
|
if (ids == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (JsonIdentityKeyStore.Identity id : ids) {
|
||||||
|
if (!safetyNumber.equals(computeSafetyNumber(name, id.identityKey))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
signalProtocolStore.saveIdentity(name, id.identityKey, TrustLevel.TRUSTED_VERIFIED);
|
||||||
|
save();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trust all keys of this identity without verification
|
* Trust all keys of this identity without verification
|
||||||
*
|
*
|
||||||
|
@ -1348,4 +1377,9 @@ class Manager implements Signal {
|
||||||
save();
|
save();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String computeSafetyNumber(String theirUsername, IdentityKey theirIdentityKey) {
|
||||||
|
Fingerprint fingerprint = new NumericFingerprintGenerator(5200).createFor(username, getIdentity(), theirUsername, theirIdentityKey);
|
||||||
|
return fingerprint.getDisplayableFingerprint().getDisplayText();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue