1 package org
.asamk
.signal
.manager
.helper
;
3 import org
.asamk
.signal
.manager
.util
.PinHashing
;
4 import org
.whispersystems
.libsignal
.InvalidKeyException
;
5 import org
.whispersystems
.signalservice
.api
.KbsPinData
;
6 import org
.whispersystems
.signalservice
.api
.KeyBackupService
;
7 import org
.whispersystems
.signalservice
.api
.KeyBackupServicePinException
;
8 import org
.whispersystems
.signalservice
.api
.KeyBackupSystemNoDataException
;
9 import org
.whispersystems
.signalservice
.api
.kbs
.MasterKey
;
10 import org
.whispersystems
.signalservice
.internal
.contacts
.crypto
.UnauthenticatedResponseException
;
11 import org
.whispersystems
.signalservice
.internal
.contacts
.entities
.TokenResponse
;
12 import org
.whispersystems
.signalservice
.internal
.push
.LockedException
;
14 import java
.io
.IOException
;
16 public class PinHelper
{
18 private final KeyBackupService keyBackupService
;
20 public PinHelper(final KeyBackupService keyBackupService
) {
21 this.keyBackupService
= keyBackupService
;
24 public void setRegistrationLockPin(
25 String pin
, MasterKey masterKey
26 ) throws IOException
{
27 final var pinChangeSession
= keyBackupService
.newPinChangeSession();
28 final var hashedPin
= PinHashing
.hashPin(pin
, pinChangeSession
);
31 pinChangeSession
.setPin(hashedPin
, masterKey
);
32 } catch (UnauthenticatedResponseException e
) {
33 throw new IOException(e
);
35 pinChangeSession
.enableRegistrationLock(masterKey
);
38 public void removeRegistrationLockPin() throws IOException
{
39 final var pinChangeSession
= keyBackupService
.newPinChangeSession();
40 pinChangeSession
.disableRegistrationLock();
42 pinChangeSession
.removePin();
43 } catch (UnauthenticatedResponseException e
) {
44 throw new IOException(e
);
48 public KbsPinData
getRegistrationLockData(
49 String pin
, LockedException e
50 ) throws IOException
, KeyBackupSystemNoDataException
, KeyBackupServicePinException
{
51 var basicStorageCredentials
= e
.getBasicStorageCredentials();
52 if (basicStorageCredentials
== null) {
56 return getRegistrationLockData(pin
, basicStorageCredentials
);
59 private KbsPinData
getRegistrationLockData(
60 String pin
, String basicStorageCredentials
61 ) throws IOException
, KeyBackupSystemNoDataException
, KeyBackupServicePinException
{
62 var tokenResponse
= keyBackupService
.getToken(basicStorageCredentials
);
63 if (tokenResponse
== null || tokenResponse
.getTries() == 0) {
64 throw new IOException("KBS Account locked, maximum pin attempts reached.");
67 var registrationLockData
= restoreMasterKey(pin
, basicStorageCredentials
, tokenResponse
);
68 if (registrationLockData
== null) {
69 throw new AssertionError("Failed to restore master key");
71 return registrationLockData
;
74 private KbsPinData
restoreMasterKey(
75 String pin
, String basicStorageCredentials
, TokenResponse tokenResponse
76 ) throws IOException
, KeyBackupSystemNoDataException
, KeyBackupServicePinException
{
77 if (pin
== null) return null;
79 if (basicStorageCredentials
== null) {
80 throw new AssertionError("Cannot restore KBS key, no storage credentials supplied");
83 var session
= keyBackupService
.newRegistrationSession(basicStorageCredentials
, tokenResponse
);
86 var hashedPin
= PinHashing
.hashPin(pin
, session
);
87 var kbsData
= session
.restorePin(hashedPin
);
88 if (kbsData
== null) {
89 throw new AssertionError("Null not expected");
92 } catch (UnauthenticatedResponseException
| InvalidKeyException e
) {
93 throw new IOException(e
);