]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/storage/prekeys/SignedPreKeyStore.java
074e581123f21b3e538060442fc81ff03b59b037
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / storage / prekeys / SignedPreKeyStore.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.SignedPreKeyRecord;
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 import java.util.Arrays;
15 import java.util.List;
16 import java.util.regex.Pattern;
17
18 public class SignedPreKeyStore implements org.whispersystems.libsignal.state.SignedPreKeyStore {
19
20 private final static Logger logger = LoggerFactory.getLogger(SignedPreKeyStore.class);
21
22 private final File signedPreKeysPath;
23
24 public SignedPreKeyStore(final File signedPreKeysPath) {
25 this.signedPreKeysPath = signedPreKeysPath;
26 }
27
28 @Override
29 public SignedPreKeyRecord loadSignedPreKey(int signedPreKeyId) throws InvalidKeyIdException {
30 final var file = getSignedPreKeyFile(signedPreKeyId);
31
32 if (!file.exists()) {
33 throw new InvalidKeyIdException("No such signed pre key record!");
34 }
35 return loadSignedPreKeyRecord(file);
36 }
37
38 final Pattern signedPreKeyFileNamePattern = Pattern.compile("([0-9]+)");
39
40 @Override
41 public List<SignedPreKeyRecord> loadSignedPreKeys() {
42 final var files = signedPreKeysPath.listFiles();
43 if (files == null) {
44 return List.of();
45 }
46 return Arrays.stream(files)
47 .filter(f -> signedPreKeyFileNamePattern.matcher(f.getName()).matches())
48 .map(this::loadSignedPreKeyRecord)
49 .toList();
50 }
51
52 @Override
53 public void storeSignedPreKey(int signedPreKeyId, SignedPreKeyRecord record) {
54 final var file = getSignedPreKeyFile(signedPreKeyId);
55 try {
56 try (var outputStream = new FileOutputStream(file)) {
57 outputStream.write(record.serialize());
58 }
59 } catch (IOException e) {
60 logger.warn("Failed to store signed pre key, trying to delete file and retry: {}", e.getMessage());
61 try {
62 Files.delete(file.toPath());
63 try (var outputStream = new FileOutputStream(file)) {
64 outputStream.write(record.serialize());
65 }
66 } catch (IOException e2) {
67 logger.error("Failed to store signed pre key file {}: {}", file, e2.getMessage());
68 }
69 }
70 }
71
72 @Override
73 public boolean containsSignedPreKey(int signedPreKeyId) {
74 final var file = getSignedPreKeyFile(signedPreKeyId);
75
76 return file.exists();
77 }
78
79 @Override
80 public void removeSignedPreKey(int signedPreKeyId) {
81 final var file = getSignedPreKeyFile(signedPreKeyId);
82
83 if (!file.exists()) {
84 return;
85 }
86 try {
87 Files.delete(file.toPath());
88 } catch (IOException e) {
89 logger.error("Failed to delete signed pre key file {}: {}", file, e.getMessage());
90 }
91 }
92
93 public void removeAllSignedPreKeys() {
94 final var files = signedPreKeysPath.listFiles();
95 if (files == null) {
96 return;
97 }
98
99 for (var file : files) {
100 try {
101 Files.delete(file.toPath());
102 } catch (IOException e) {
103 logger.error("Failed to delete signed pre key file {}: {}", file, e.getMessage());
104 }
105 }
106 }
107
108 private File getSignedPreKeyFile(int signedPreKeyId) {
109 try {
110 IOUtils.createPrivateDirectories(signedPreKeysPath);
111 } catch (IOException e) {
112 throw new AssertionError("Failed to create signed pre keys path", e);
113 }
114 return new File(signedPreKeysPath, String.valueOf(signedPreKeyId));
115 }
116
117 private SignedPreKeyRecord loadSignedPreKeyRecord(final File file) {
118 try (var inputStream = new FileInputStream(file)) {
119 return new SignedPreKeyRecord(inputStream.readAllBytes());
120 } catch (IOException e) {
121 logger.error("Failed to load signed pre key: {}", e.getMessage());
122 throw new AssertionError(e);
123 }
124 }
125 }