]> nmode's Git Repositories - signal-cli/blob - src/main/java/org/asamk/signal/manager/storage/protocol/JsonPreKeyStore.java
4d884c3e483168ee755f3f1f102709c1240bb409
[signal-cli] / src / main / java / org / asamk / signal / manager / storage / protocol / JsonPreKeyStore.java
1 package org.asamk.signal.manager.storage.protocol;
2
3 import com.fasterxml.jackson.core.JsonGenerator;
4 import com.fasterxml.jackson.core.JsonParser;
5 import com.fasterxml.jackson.databind.DeserializationContext;
6 import com.fasterxml.jackson.databind.JsonDeserializer;
7 import com.fasterxml.jackson.databind.JsonNode;
8 import com.fasterxml.jackson.databind.JsonSerializer;
9 import com.fasterxml.jackson.databind.SerializerProvider;
10
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13 import org.whispersystems.libsignal.InvalidKeyIdException;
14 import org.whispersystems.libsignal.state.PreKeyRecord;
15 import org.whispersystems.libsignal.state.PreKeyStore;
16 import org.whispersystems.util.Base64;
17
18 import java.io.IOException;
19 import java.util.HashMap;
20 import java.util.Map;
21
22 class JsonPreKeyStore implements PreKeyStore {
23
24 final static Logger logger = LoggerFactory.getLogger(JsonPreKeyStore.class);
25
26 private final Map<Integer, byte[]> store = new HashMap<>();
27
28 public JsonPreKeyStore() {
29
30 }
31
32 private void addPreKeys(Map<Integer, byte[]> preKeys) {
33 store.putAll(preKeys);
34 }
35
36 @Override
37 public PreKeyRecord loadPreKey(int preKeyId) throws InvalidKeyIdException {
38 try {
39 if (!store.containsKey(preKeyId)) {
40 throw new InvalidKeyIdException("No such prekeyrecord!");
41 }
42
43 return new PreKeyRecord(store.get(preKeyId));
44 } catch (IOException e) {
45 throw new AssertionError(e);
46 }
47 }
48
49 @Override
50 public void storePreKey(int preKeyId, PreKeyRecord record) {
51 store.put(preKeyId, record.serialize());
52 }
53
54 @Override
55 public boolean containsPreKey(int preKeyId) {
56 return store.containsKey(preKeyId);
57 }
58
59 @Override
60 public void removePreKey(int preKeyId) {
61 store.remove(preKeyId);
62 }
63
64 public static class JsonPreKeyStoreDeserializer extends JsonDeserializer<JsonPreKeyStore> {
65
66 @Override
67 public JsonPreKeyStore deserialize(
68 JsonParser jsonParser, DeserializationContext deserializationContext
69 ) throws IOException {
70 JsonNode node = jsonParser.getCodec().readTree(jsonParser);
71
72 Map<Integer, byte[]> preKeyMap = new HashMap<>();
73 if (node.isArray()) {
74 for (JsonNode preKey : node) {
75 Integer preKeyId = preKey.get("id").asInt();
76 try {
77 preKeyMap.put(preKeyId, Base64.decode(preKey.get("record").asText()));
78 } catch (IOException e) {
79 logger.warn("Error while decoding prekey for {}: {}", preKeyId, e.getMessage());
80 }
81 }
82 }
83
84 JsonPreKeyStore keyStore = new JsonPreKeyStore();
85 keyStore.addPreKeys(preKeyMap);
86
87 return keyStore;
88
89 }
90 }
91
92 public static class JsonPreKeyStoreSerializer extends JsonSerializer<JsonPreKeyStore> {
93
94 @Override
95 public void serialize(
96 JsonPreKeyStore jsonPreKeyStore, JsonGenerator json, SerializerProvider serializerProvider
97 ) throws IOException {
98 json.writeStartArray();
99 for (Map.Entry<Integer, byte[]> preKey : jsonPreKeyStore.store.entrySet()) {
100 json.writeStartObject();
101 json.writeNumberField("id", preKey.getKey());
102 json.writeStringField("record", Base64.encodeBytes(preKey.getValue()));
103 json.writeEndObject();
104 }
105 json.writeEndArray();
106 }
107 }
108 }