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
;
13 import java
.util
.ArrayList
;
14 import java
.util
.HashMap
;
15 import java
.util
.List
;
18 class JsonIdentityKeyStore
implements IdentityKeyStore
{
20 private final Map
<String
, List
<Identity
>> trustedKeys
= new HashMap
<>();
22 private final IdentityKeyPair identityKeyPair
;
23 private final int localRegistrationId
;
26 public JsonIdentityKeyStore(IdentityKeyPair identityKeyPair
, int localRegistrationId
) {
27 this.identityKeyPair
= identityKeyPair
;
28 this.localRegistrationId
= localRegistrationId
;
32 public IdentityKeyPair
getIdentityKeyPair() {
33 return identityKeyPair
;
37 public int getLocalRegistrationId() {
38 return localRegistrationId
;
42 public void saveIdentity(String name
, IdentityKey identityKey
) {
43 saveIdentity(name
, identityKey
, TrustLevel
.TRUSTED_UNVERIFIED
);
46 public void saveIdentity(String name
, IdentityKey identityKey
, TrustLevel trustLevel
) {
47 List
<Identity
> identities
= trustedKeys
.get(name
);
48 if (identities
== null) {
49 identities
= new ArrayList
<>();
50 trustedKeys
.put(name
, identities
);
52 for (Identity id
: identities
) {
53 if (!id
.identityKey
.equals(identityKey
))
56 id
.trustLevel
= trustLevel
;
60 identities
.add(new Identity(identityKey
, trustLevel
));
64 public boolean isTrustedIdentity(String name
, IdentityKey identityKey
) {
65 List
<Identity
> identities
= trustedKeys
.get(name
);
66 if (identities
== null) {
71 for (Identity id
: identities
) {
72 if (id
.identityKey
.equals(identityKey
)) {
73 return id
.isTrusted();
80 public static class JsonIdentityKeyStoreDeserializer
extends JsonDeserializer
<JsonIdentityKeyStore
> {
83 public JsonIdentityKeyStore
deserialize(JsonParser jsonParser
, DeserializationContext deserializationContext
) throws IOException
, JsonProcessingException
{
84 JsonNode node
= jsonParser
.getCodec().readTree(jsonParser
);
87 int localRegistrationId
= node
.get("registrationId").asInt();
88 IdentityKeyPair identityKeyPair
= new IdentityKeyPair(Base64
.decode(node
.get("identityKey").asText()));
91 JsonIdentityKeyStore keyStore
= new JsonIdentityKeyStore(identityKeyPair
, localRegistrationId
);
93 JsonNode trustedKeysNode
= node
.get("trustedKeys");
94 if (trustedKeysNode
.isArray()) {
95 for (JsonNode trustedKey
: trustedKeysNode
) {
96 String trustedKeyName
= trustedKey
.get("name").asText();
98 IdentityKey id
= new IdentityKey(Base64
.decode(trustedKey
.get("identityKey").asText()), 0);
99 TrustLevel trustLevel
= trustedKey
.has("trustLevel") ? TrustLevel
.fromInt(trustedKey
.get("trustLevel").asInt()) : TrustLevel
.TRUSTED_UNVERIFIED
;
100 keyStore
.saveIdentity(trustedKeyName
, id
, trustLevel
);
101 } catch (InvalidKeyException
| IOException e
) {
102 System
.out
.println(String
.format("Error while decoding key for: %s", trustedKeyName
));
108 } catch (InvalidKeyException e
) {
109 throw new IOException(e
);
114 public static class JsonIdentityKeyStoreSerializer
extends JsonSerializer
<JsonIdentityKeyStore
> {
117 public void serialize(JsonIdentityKeyStore jsonIdentityKeyStore
, JsonGenerator json
, SerializerProvider serializerProvider
) throws IOException
, JsonProcessingException
{
118 json
.writeStartObject();
119 json
.writeNumberField("registrationId", jsonIdentityKeyStore
.getLocalRegistrationId());
120 json
.writeStringField("identityKey", Base64
.encodeBytes(jsonIdentityKeyStore
.getIdentityKeyPair().serialize()));
121 json
.writeArrayFieldStart("trustedKeys");
122 for (Map
.Entry
<String
, List
<Identity
>> trustedKey
: jsonIdentityKeyStore
.trustedKeys
.entrySet()) {
123 for (Identity id
: trustedKey
.getValue()) {
124 json
.writeStartObject();
125 json
.writeStringField("name", trustedKey
.getKey());
126 json
.writeStringField("identityKey", Base64
.encodeBytes(id
.identityKey
.serialize()));
127 json
.writeNumberField("trustLevel", id
.trustLevel
.ordinal());
128 json
.writeEndObject();
131 json
.writeEndArray();
132 json
.writeEndObject();
136 private enum TrustLevel
{
141 private static TrustLevel
[] cachedValues
= null;
143 public static TrustLevel
fromInt(int i
) {
144 if (TrustLevel
.cachedValues
== null) {
145 TrustLevel
.cachedValues
= TrustLevel
.values();
147 return TrustLevel
.cachedValues
[i
];
151 private class Identity
{
152 IdentityKey identityKey
;
153 TrustLevel trustLevel
;
155 public Identity(IdentityKey identityKey
, TrustLevel trustLevel
) {
156 this.identityKey
= identityKey
;
157 this.trustLevel
= trustLevel
;
160 public boolean isTrusted() {
161 return trustLevel
== TrustLevel
.TRUSTED_UNVERIFIED
||
162 trustLevel
== TrustLevel
.TRUSTED_VERIFIED
;