1 package org
.asamk
.signal
;
3 import com
.fasterxml
.jackson
.core
.JsonGenerator
;
4 import com
.fasterxml
.jackson
.core
.JsonParser
;
5 import com
.fasterxml
.jackson
.core
.JsonProcessingException
;
6 import com
.fasterxml
.jackson
.databind
.*;
7 import org
.whispersystems
.libsignal
.IdentityKey
;
8 import org
.whispersystems
.libsignal
.IdentityKeyPair
;
9 import org
.whispersystems
.libsignal
.InvalidKeyException
;
10 import org
.whispersystems
.libsignal
.state
.IdentityKeyStore
;
12 import java
.io
.IOException
;
15 class JsonIdentityKeyStore
implements IdentityKeyStore
{
17 private final Map
<String
, List
<Identity
>> trustedKeys
= new HashMap
<>();
19 private final IdentityKeyPair identityKeyPair
;
20 private final int localRegistrationId
;
23 public JsonIdentityKeyStore(IdentityKeyPair identityKeyPair
, int localRegistrationId
) {
24 this.identityKeyPair
= identityKeyPair
;
25 this.localRegistrationId
= localRegistrationId
;
29 public IdentityKeyPair
getIdentityKeyPair() {
30 return identityKeyPair
;
34 public int getLocalRegistrationId() {
35 return localRegistrationId
;
39 public void saveIdentity(String name
, IdentityKey identityKey
) {
40 saveIdentity(name
, identityKey
, TrustLevel
.TRUSTED_UNVERIFIED
, null);
44 * Adds or updates the given identityKey for the user name and sets the trustLevel and added timestamp.
46 * @param name User name, i.e. phone number
47 * @param identityKey The user's public key
49 * @param added Added timestamp, if null and the key is newly added, the current time is used.
51 public void saveIdentity(String name
, IdentityKey identityKey
, TrustLevel trustLevel
, Date added
) {
52 List
<Identity
> identities
= trustedKeys
.get(name
);
53 if (identities
== null) {
54 identities
= new ArrayList
<>();
55 trustedKeys
.put(name
, identities
);
57 for (Identity id
: identities
) {
58 if (!id
.identityKey
.equals(identityKey
))
61 id
.trustLevel
= trustLevel
;
68 identities
.add(new Identity(identityKey
, trustLevel
, added
!= null ? added
: new Date()));
72 public boolean isTrustedIdentity(String name
, IdentityKey identityKey
) {
73 List
<Identity
> identities
= trustedKeys
.get(name
);
74 if (identities
== null) {
79 for (Identity id
: identities
) {
80 if (id
.identityKey
.equals(identityKey
)) {
81 return id
.isTrusted();
88 public Map
<String
, List
<Identity
>> getIdentities() {
93 public List
<Identity
> getIdentities(String name
) {
95 return trustedKeys
.get(name
);
98 public static class JsonIdentityKeyStoreDeserializer
extends JsonDeserializer
<JsonIdentityKeyStore
> {
101 public JsonIdentityKeyStore
deserialize(JsonParser jsonParser
, DeserializationContext deserializationContext
) throws IOException
, JsonProcessingException
{
102 JsonNode node
= jsonParser
.getCodec().readTree(jsonParser
);
105 int localRegistrationId
= node
.get("registrationId").asInt();
106 IdentityKeyPair identityKeyPair
= new IdentityKeyPair(Base64
.decode(node
.get("identityKey").asText()));
109 JsonIdentityKeyStore keyStore
= new JsonIdentityKeyStore(identityKeyPair
, localRegistrationId
);
111 JsonNode trustedKeysNode
= node
.get("trustedKeys");
112 if (trustedKeysNode
.isArray()) {
113 for (JsonNode trustedKey
: trustedKeysNode
) {
114 String trustedKeyName
= trustedKey
.get("name").asText();
116 IdentityKey id
= new IdentityKey(Base64
.decode(trustedKey
.get("identityKey").asText()), 0);
117 TrustLevel trustLevel
= trustedKey
.has("trustLevel") ? TrustLevel
.fromInt(trustedKey
.get("trustLevel").asInt()) : TrustLevel
.TRUSTED_UNVERIFIED
;
118 Date added
= trustedKey
.has("addedTimestamp") ?
new Date(trustedKey
.get("addedTimestamp").asLong()) : new Date();
119 keyStore
.saveIdentity(trustedKeyName
, id
, trustLevel
, added
);
120 } catch (InvalidKeyException
| IOException e
) {
121 System
.out
.println(String
.format("Error while decoding key for: %s", trustedKeyName
));
127 } catch (InvalidKeyException e
) {
128 throw new IOException(e
);
133 public static class JsonIdentityKeyStoreSerializer
extends JsonSerializer
<JsonIdentityKeyStore
> {
136 public void serialize(JsonIdentityKeyStore jsonIdentityKeyStore
, JsonGenerator json
, SerializerProvider serializerProvider
) throws IOException
, JsonProcessingException
{
137 json
.writeStartObject();
138 json
.writeNumberField("registrationId", jsonIdentityKeyStore
.getLocalRegistrationId());
139 json
.writeStringField("identityKey", Base64
.encodeBytes(jsonIdentityKeyStore
.getIdentityKeyPair().serialize()));
140 json
.writeArrayFieldStart("trustedKeys");
141 for (Map
.Entry
<String
, List
<Identity
>> trustedKey
: jsonIdentityKeyStore
.trustedKeys
.entrySet()) {
142 for (Identity id
: trustedKey
.getValue()) {
143 json
.writeStartObject();
144 json
.writeStringField("name", trustedKey
.getKey());
145 json
.writeStringField("identityKey", Base64
.encodeBytes(id
.identityKey
.serialize()));
146 json
.writeNumberField("trustLevel", id
.trustLevel
.ordinal());
147 json
.writeNumberField("addedTimestamp", id
.added
.getTime());
148 json
.writeEndObject();
151 json
.writeEndArray();
152 json
.writeEndObject();
156 public class Identity
{
157 IdentityKey identityKey
;
158 TrustLevel trustLevel
;
161 public Identity(IdentityKey identityKey
, TrustLevel trustLevel
) {
162 this.identityKey
= identityKey
;
163 this.trustLevel
= trustLevel
;
164 this.added
= new Date();
167 public Identity(IdentityKey identityKey
, TrustLevel trustLevel
, Date added
) {
168 this.identityKey
= identityKey
;
169 this.trustLevel
= trustLevel
;
173 public boolean isTrusted() {
174 return trustLevel
== TrustLevel
.TRUSTED_UNVERIFIED
||
175 trustLevel
== TrustLevel
.TRUSTED_VERIFIED
;
178 public byte[] getFingerprint() {
179 return identityKey
.getPublicKey().serialize();