1 package org
.asamk
.signal
.manager
.helper
;
3 import org
.asamk
.signal
.manager
.config
.ServiceConfig
;
4 import org
.asamk
.signal
.manager
.internal
.SignalDependencies
;
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
;
14 import java
.io
.IOException
;
15 import java
.util
.List
;
17 public class PreKeyHelper
{
19 private final static Logger logger
= LoggerFactory
.getLogger(PreKeyHelper
.class);
21 private final SignalAccount account
;
22 private final SignalDependencies dependencies
;
25 final SignalAccount account
, final SignalDependencies dependencies
27 this.account
= account
;
28 this.dependencies
= dependencies
;
31 public void refreshPreKeysIfNecessary() throws IOException
{
32 refreshPreKeysIfNecessary(ServiceIdType
.ACI
);
33 refreshPreKeysIfNecessary(ServiceIdType
.PNI
);
36 public void refreshPreKeysIfNecessary(ServiceIdType serviceIdType
) throws IOException
{
37 if (dependencies
.getAccountManager().getPreKeysCount(serviceIdType
) < ServiceConfig
.PREKEY_MINIMUM_COUNT
) {
38 refreshPreKeys(serviceIdType
);
42 public void refreshPreKeys() throws IOException
{
43 refreshPreKeys(ServiceIdType
.ACI
);
44 refreshPreKeys(ServiceIdType
.PNI
);
47 public void refreshPreKeys(ServiceIdType serviceIdType
) throws IOException
{
48 final var identityKeyPair
= account
.getIdentityKeyPair(serviceIdType
);
49 if (identityKeyPair
== null) {
52 final var accountId
= account
.getAccountId(serviceIdType
);
53 if (accountId
== null) {
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
);
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
);
71 dependencies
.getAccountManager()
72 .setPreKeys(serviceIdType
, identityKeyPair
.getPublicKey(), signedPreKeyRecord
, oneTimePreKeys
);
75 private List
<PreKeyRecord
> generatePreKeys(ServiceIdType serviceIdType
) {
76 final var offset
= account
.getPreKeyIdOffset(serviceIdType
);
78 var records
= KeyUtils
.generatePreKeyRecords(offset
, ServiceConfig
.PREKEY_BATCH_SIZE
);
79 account
.addPreKeys(serviceIdType
, records
);
84 private SignedPreKeyRecord
generateSignedPreKey(ServiceIdType serviceIdType
, IdentityKeyPair identityKeyPair
) {
85 final var signedPreKeyId
= account
.getNextSignedPreKeyId(serviceIdType
);
87 var record = KeyUtils
.generateSignedPreKeyRecord(identityKeyPair
, signedPreKeyId
);
88 account
.addSignedPreKey(serviceIdType
, record);