]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/storage/prekeys/PreKeyStore.java
ccdea42246b3ca0f79e3c3941c6baf3f62fba993
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / storage / prekeys / PreKeyStore.java
1 package org.asamk.signal.manager.storage.prekeys;
2
3 import org.asamk.signal.manager.util.IOUtils;
4 import org.slf4j.Logger;
5 import org.slf4j.LoggerFactory;
6 import org.whispersystems.libsignal.InvalidKeyIdException;
7 import org.whispersystems.libsignal.state.PreKeyRecord;
8
9 import java.io.File;
10 import java.io.FileInputStream;
11 import java.io.FileOutputStream;
12 import java.io.IOException;
13 import java.nio.file.Files;
14
15 public class PreKeyStore implements org.whispersystems.libsignal.state.PreKeyStore {
16
17 private final static Logger logger = LoggerFactory.getLogger(PreKeyStore.class);
18
19 private final File preKeysPath;
20
21 public PreKeyStore(final File preKeysPath) {
22 this.preKeysPath = preKeysPath;
23 }
24
25 @Override
26 public PreKeyRecord loadPreKey(int preKeyId) throws InvalidKeyIdException {
27 final var file = getPreKeyFile(preKeyId);
28
29 if (!file.exists()) {
30 throw new InvalidKeyIdException("No such pre key record!");
31 }
32 try (var inputStream = new FileInputStream(file)) {
33 return new PreKeyRecord(inputStream.readAllBytes());
34 } catch (IOException e) {
35 logger.error("Failed to load pre key: {}", e.getMessage());
36 throw new AssertionError(e);
37 }
38 }
39
40 @Override
41 public void storePreKey(int preKeyId, PreKeyRecord record) {
42 final var file = getPreKeyFile(preKeyId);
43 try {
44 try (var outputStream = new FileOutputStream(file)) {
45 outputStream.write(record.serialize());
46 }
47 } catch (IOException e) {
48 logger.warn("Failed to store pre key, trying to delete file and retry: {}", e.getMessage());
49 try {
50 Files.delete(file.toPath());
51 try (var outputStream = new FileOutputStream(file)) {
52 outputStream.write(record.serialize());
53 }
54 } catch (IOException e2) {
55 logger.error("Failed to store pre key file {}: {}", file, e2.getMessage());
56 }
57 }
58 }
59
60 @Override
61 public boolean containsPreKey(int preKeyId) {
62 final var file = getPreKeyFile(preKeyId);
63
64 return file.exists();
65 }
66
67 @Override
68 public void removePreKey(int preKeyId) {
69 final var file = getPreKeyFile(preKeyId);
70
71 if (!file.exists()) {
72 return;
73 }
74 try {
75 Files.delete(file.toPath());
76 } catch (IOException e) {
77 logger.error("Failed to delete pre key file {}: {}", file, e.getMessage());
78 }
79 }
80
81 public void removeAllPreKeys() {
82 final var files = preKeysPath.listFiles();
83 if (files == null) {
84 return;
85 }
86
87 for (var file : files) {
88 try {
89 Files.delete(file.toPath());
90 } catch (IOException e) {
91 logger.error("Failed to delete pre key file {}: {}", file, e.getMessage());
92 }
93 }
94 }
95
96 private File getPreKeyFile(int preKeyId) {
97 try {
98 IOUtils.createPrivateDirectories(preKeysPath);
99 } catch (IOException e) {
100 throw new AssertionError("Failed to create pre keys path", e);
101 }
102 return new File(preKeysPath, String.valueOf(preKeyId));
103 }
104 }