]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/helper/PreKeyHelper.java
30ab919e08b0454ff94871562805611c206cf3ea
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / helper / PreKeyHelper.java
1 package org.asamk.signal.manager.helper;
2
3 import org.asamk.signal.manager.SignalDependencies;
4 import org.asamk.signal.manager.config.ServiceConfig;
5 import org.asamk.signal.manager.storage.SignalAccount;
6 import org.asamk.signal.manager.util.KeyUtils;
7 import org.signal.libsignal.protocol.IdentityKeyPair;
8 import org.signal.libsignal.protocol.state.PreKeyRecord;
9 import org.signal.libsignal.protocol.state.SignedPreKeyRecord;
10 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory;
12 import org.whispersystems.signalservice.api.push.ServiceIdType;
13
14 import java.io.IOException;
15 import java.util.List;
16
17 public class PreKeyHelper {
18
19 private final static Logger logger = LoggerFactory.getLogger(PreKeyHelper.class);
20
21 private final SignalAccount account;
22 private final SignalDependencies dependencies;
23
24 public PreKeyHelper(
25 final SignalAccount account, final SignalDependencies dependencies
26 ) {
27 this.account = account;
28 this.dependencies = dependencies;
29 }
30
31 public void refreshPreKeysIfNecessary() throws IOException {
32 refreshPreKeysIfNecessary(ServiceIdType.ACI);
33 refreshPreKeysIfNecessary(ServiceIdType.PNI);
34 }
35
36 public void refreshPreKeysIfNecessary(ServiceIdType serviceIdType) throws IOException {
37 if (dependencies.getAccountManager().getPreKeysCount(serviceIdType) < ServiceConfig.PREKEY_MINIMUM_COUNT) {
38 refreshPreKeys(serviceIdType);
39 }
40 }
41
42 public void refreshPreKeys() throws IOException {
43 refreshPreKeys(ServiceIdType.ACI);
44 refreshPreKeys(ServiceIdType.PNI);
45 }
46
47 public void refreshPreKeys(ServiceIdType serviceIdType) throws IOException {
48 final var identityKeyPair = account.getIdentityKeyPair(serviceIdType);
49 if (identityKeyPair == null) {
50 return;
51 }
52 final var accountId = account.getAccountId(serviceIdType);
53 if (accountId == null) {
54 return;
55 }
56 try {
57 refreshPreKeys(serviceIdType, identityKeyPair);
58 } catch (Exception e) {
59 logger.warn("Failed to store new pre keys, resetting preKey id offset", e);
60 account.resetPreKeyOffsets(serviceIdType);
61 refreshPreKeys(serviceIdType, identityKeyPair);
62 }
63 }
64
65 private void refreshPreKeys(
66 final ServiceIdType serviceIdType, final IdentityKeyPair identityKeyPair
67 ) throws IOException {
68 final var oneTimePreKeys = generatePreKeys(serviceIdType);
69 final var signedPreKeyRecord = generateSignedPreKey(serviceIdType, identityKeyPair);
70
71 dependencies.getAccountManager()
72 .setPreKeys(serviceIdType, identityKeyPair.getPublicKey(), signedPreKeyRecord, oneTimePreKeys);
73 }
74
75 private List<PreKeyRecord> generatePreKeys(ServiceIdType serviceIdType) {
76 final var offset = account.getPreKeyIdOffset(serviceIdType);
77
78 var records = KeyUtils.generatePreKeyRecords(offset, ServiceConfig.PREKEY_BATCH_SIZE);
79 account.addPreKeys(serviceIdType, records);
80
81 return records;
82 }
83
84 private SignedPreKeyRecord generateSignedPreKey(ServiceIdType serviceIdType, IdentityKeyPair identityKeyPair) {
85 final var signedPreKeyId = account.getNextSignedPreKeyId(serviceIdType);
86
87 var record = KeyUtils.generateSignedPreKeyRecord(identityKeyPair, signedPreKeyId);
88 account.addSignedPreKey(serviceIdType, record);
89
90 return record;
91 }
92 }