mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 02:20:39 +00:00
Implement trustLevel for IdentityKeys
This commit is contained in:
parent
0f0d8a873a
commit
f2c2597379
1 changed files with 77 additions and 19 deletions
|
@ -10,12 +10,14 @@ import org.whispersystems.libsignal.InvalidKeyException;
|
|||
import org.whispersystems.libsignal.state.IdentityKeyStore;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
class JsonIdentityKeyStore implements IdentityKeyStore {
|
||||
|
||||
private final Map<String, IdentityKey> trustedKeys = new HashMap<>();
|
||||
private final Map<String, List<Identity>> trustedKeys = new HashMap<>();
|
||||
|
||||
private final IdentityKeyPair identityKeyPair;
|
||||
private final int localRegistrationId;
|
||||
|
@ -26,10 +28,6 @@ class JsonIdentityKeyStore implements IdentityKeyStore {
|
|||
this.localRegistrationId = localRegistrationId;
|
||||
}
|
||||
|
||||
public void addTrustedKeys(Map<String, IdentityKey> keyMap) {
|
||||
trustedKeys.putAll(keyMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IdentityKeyPair getIdentityKeyPair() {
|
||||
return identityKeyPair;
|
||||
|
@ -42,13 +40,41 @@ class JsonIdentityKeyStore implements IdentityKeyStore {
|
|||
|
||||
@Override
|
||||
public void saveIdentity(String name, IdentityKey identityKey) {
|
||||
trustedKeys.put(name, identityKey);
|
||||
saveIdentity(name, identityKey, TrustLevel.TRUSTED_UNVERIFIED);
|
||||
}
|
||||
|
||||
public void saveIdentity(String name, IdentityKey identityKey, TrustLevel trustLevel) {
|
||||
List<Identity> identities = trustedKeys.get(name);
|
||||
if (identities == null) {
|
||||
identities = new ArrayList<>();
|
||||
trustedKeys.put(name, identities);
|
||||
} else {
|
||||
for (Identity id : identities) {
|
||||
if (!id.identityKey.equals(identityKey))
|
||||
continue;
|
||||
|
||||
id.trustLevel = trustLevel;
|
||||
return;
|
||||
}
|
||||
}
|
||||
identities.add(new Identity(identityKey, trustLevel));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTrustedIdentity(String name, IdentityKey identityKey) {
|
||||
IdentityKey trusted = trustedKeys.get(name);
|
||||
return (trusted == null || trusted.equals(identityKey));
|
||||
List<Identity> identities = trustedKeys.get(name);
|
||||
if (identities == null) {
|
||||
// Trust on first use
|
||||
return true;
|
||||
}
|
||||
|
||||
for (Identity id : identities) {
|
||||
if (id.identityKey.equals(identityKey)) {
|
||||
return id.isTrusted();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class JsonIdentityKeyStoreDeserializer extends JsonDeserializer<JsonIdentityKeyStore> {
|
||||
|
@ -62,24 +88,23 @@ class JsonIdentityKeyStore implements IdentityKeyStore {
|
|||
IdentityKeyPair identityKeyPair = new IdentityKeyPair(Base64.decode(node.get("identityKey").asText()));
|
||||
|
||||
|
||||
Map<String, IdentityKey> trustedKeyMap = new HashMap<>();
|
||||
JsonIdentityKeyStore keyStore = new JsonIdentityKeyStore(identityKeyPair, localRegistrationId);
|
||||
|
||||
JsonNode trustedKeysNode = node.get("trustedKeys");
|
||||
if (trustedKeysNode.isArray()) {
|
||||
for (JsonNode trustedKey : trustedKeysNode) {
|
||||
String trustedKeyName = trustedKey.get("name").asText();
|
||||
try {
|
||||
trustedKeyMap.put(trustedKeyName, new IdentityKey(Base64.decode(trustedKey.get("identityKey").asText()), 0));
|
||||
IdentityKey id = new IdentityKey(Base64.decode(trustedKey.get("identityKey").asText()), 0);
|
||||
TrustLevel trustLevel = trustedKey.has("trustLevel") ? TrustLevel.fromInt(trustedKey.get("trustLevel").asInt()) : TrustLevel.TRUSTED_UNVERIFIED;
|
||||
keyStore.saveIdentity(trustedKeyName, id, trustLevel);
|
||||
} catch (InvalidKeyException | IOException e) {
|
||||
System.out.println(String.format("Error while decoding key for: %s", trustedKeyName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JsonIdentityKeyStore keyStore = new JsonIdentityKeyStore(identityKeyPair, localRegistrationId);
|
||||
keyStore.addTrustedKeys(trustedKeyMap);
|
||||
|
||||
return keyStore;
|
||||
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
@ -94,14 +119,47 @@ class JsonIdentityKeyStore implements IdentityKeyStore {
|
|||
json.writeNumberField("registrationId", jsonIdentityKeyStore.getLocalRegistrationId());
|
||||
json.writeStringField("identityKey", Base64.encodeBytes(jsonIdentityKeyStore.getIdentityKeyPair().serialize()));
|
||||
json.writeArrayFieldStart("trustedKeys");
|
||||
for (Map.Entry<String, IdentityKey> trustedKey : jsonIdentityKeyStore.trustedKeys.entrySet()) {
|
||||
json.writeStartObject();
|
||||
json.writeStringField("name", trustedKey.getKey());
|
||||
json.writeStringField("identityKey", Base64.encodeBytes(trustedKey.getValue().serialize()));
|
||||
json.writeEndObject();
|
||||
for (Map.Entry<String, List<Identity>> trustedKey : jsonIdentityKeyStore.trustedKeys.entrySet()) {
|
||||
for (Identity id : trustedKey.getValue()) {
|
||||
json.writeStartObject();
|
||||
json.writeStringField("name", trustedKey.getKey());
|
||||
json.writeStringField("identityKey", Base64.encodeBytes(id.identityKey.serialize()));
|
||||
json.writeNumberField("trustLevel", id.trustLevel.ordinal());
|
||||
json.writeEndObject();
|
||||
}
|
||||
}
|
||||
json.writeEndArray();
|
||||
json.writeEndObject();
|
||||
}
|
||||
}
|
||||
|
||||
private enum TrustLevel {
|
||||
UNTRUSTED,
|
||||
TRUSTED_UNVERIFIED,
|
||||
TRUSTED_VERIFIED;
|
||||
|
||||
private static TrustLevel[] cachedValues = null;
|
||||
|
||||
public static TrustLevel fromInt(int i) {
|
||||
if (TrustLevel.cachedValues == null) {
|
||||
TrustLevel.cachedValues = TrustLevel.values();
|
||||
}
|
||||
return TrustLevel.cachedValues[i];
|
||||
}
|
||||
}
|
||||
|
||||
private class Identity {
|
||||
IdentityKey identityKey;
|
||||
TrustLevel trustLevel;
|
||||
|
||||
public Identity(IdentityKey identityKey, TrustLevel trustLevel) {
|
||||
this.identityKey = identityKey;
|
||||
this.trustLevel = trustLevel;
|
||||
}
|
||||
|
||||
public boolean isTrusted() {
|
||||
return trustLevel == TrustLevel.TRUSTED_UNVERIFIED ||
|
||||
trustLevel == TrustLevel.TRUSTED_VERIFIED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue