]> nmode's Git Repositories - signal-cli/blob - src/main/java/org/asamk/signal/storage/protocol/JsonSignedPreKeyStore.java
edad8e7ec727974193b01f9b33fd5ba6e4e5848e
[signal-cli] / src / main / java / org / asamk / signal / storage / protocol / JsonSignedPreKeyStore.java
1 package org.asamk.signal.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.whispersystems.libsignal.InvalidKeyIdException;
12 import org.whispersystems.libsignal.state.SignedPreKeyRecord;
13 import org.whispersystems.libsignal.state.SignedPreKeyStore;
14 import org.whispersystems.util.Base64;
15
16 import java.io.IOException;
17 import java.util.HashMap;
18 import java.util.LinkedList;
19 import java.util.List;
20 import java.util.Map;
21
22 class JsonSignedPreKeyStore implements SignedPreKeyStore {
23
24 private final Map<Integer, byte[]> store = new HashMap<>();
25
26 public JsonSignedPreKeyStore() {
27
28 }
29
30 private void addSignedPreKeys(Map<Integer, byte[]> preKeys) {
31 store.putAll(preKeys);
32 }
33
34 @Override
35 public SignedPreKeyRecord loadSignedPreKey(int signedPreKeyId) throws InvalidKeyIdException {
36 try {
37 if (!store.containsKey(signedPreKeyId)) {
38 throw new InvalidKeyIdException("No such signedprekeyrecord! " + signedPreKeyId);
39 }
40
41 return new SignedPreKeyRecord(store.get(signedPreKeyId));
42 } catch (IOException e) {
43 throw new AssertionError(e);
44 }
45 }
46
47 @Override
48 public List<SignedPreKeyRecord> loadSignedPreKeys() {
49 try {
50 List<SignedPreKeyRecord> results = new LinkedList<>();
51
52 for (byte[] serialized : store.values()) {
53 results.add(new SignedPreKeyRecord(serialized));
54 }
55
56 return results;
57 } catch (IOException e) {
58 throw new AssertionError(e);
59 }
60 }
61
62 @Override
63 public void storeSignedPreKey(int signedPreKeyId, SignedPreKeyRecord record) {
64 store.put(signedPreKeyId, record.serialize());
65 }
66
67 @Override
68 public boolean containsSignedPreKey(int signedPreKeyId) {
69 return store.containsKey(signedPreKeyId);
70 }
71
72 @Override
73 public void removeSignedPreKey(int signedPreKeyId) {
74 store.remove(signedPreKeyId);
75 }
76
77 public static class JsonSignedPreKeyStoreDeserializer extends JsonDeserializer<JsonSignedPreKeyStore> {
78
79 @Override
80 public JsonSignedPreKeyStore deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
81 JsonNode node = jsonParser.getCodec().readTree(jsonParser);
82
83 Map<Integer, byte[]> preKeyMap = new HashMap<>();
84 if (node.isArray()) {
85 for (JsonNode preKey : node) {
86 Integer preKeyId = preKey.get("id").asInt();
87 try {
88 preKeyMap.put(preKeyId, Base64.decode(preKey.get("record").asText()));
89 } catch (IOException e) {
90 System.out.println(String.format("Error while decoding prekey for: %s", preKeyId));
91 }
92 }
93 }
94
95 JsonSignedPreKeyStore keyStore = new JsonSignedPreKeyStore();
96 keyStore.addSignedPreKeys(preKeyMap);
97
98 return keyStore;
99
100 }
101 }
102
103 public static class JsonSignedPreKeyStoreSerializer extends JsonSerializer<JsonSignedPreKeyStore> {
104
105 @Override
106 public void serialize(JsonSignedPreKeyStore jsonPreKeyStore, JsonGenerator json, SerializerProvider serializerProvider) throws IOException {
107 json.writeStartArray();
108 for (Map.Entry<Integer, byte[]> signedPreKey : jsonPreKeyStore.store.entrySet()) {
109 json.writeStartObject();
110 json.writeNumberField("id", signedPreKey.getKey());
111 json.writeStringField("record", Base64.encodeBytes(signedPreKey.getValue()));
112 json.writeEndObject();
113 }
114 json.writeEndArray();
115 }
116 }
117 }