feat: Ability to login directly with hashed password (#10811)

This commit is contained in:
Igor Sirotin 2023-05-31 16:06:23 +03:00 committed by GitHub
parent 5678d86a54
commit 92bd3e4999
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 22 additions and 32 deletions

View File

@ -12,7 +12,7 @@ import ../../../app_service/service/keychain/service as keychain_service
import ../../../app_service/service/profile/service as profile_service
import ../../../app_service/service/keycard/service as keycard_service
import ../../../app_service/service/devices/service as devices_service
import ../../../app_service/common/account_constants
import ../../../app_service/common/[account_constants, utils]
import ../shared_modules/keycard_popup/io_interface as keycard_shared_module
@ -445,7 +445,7 @@ proc isSelectedAccountAKeycardAccount*(self: Controller): bool =
proc login*(self: Controller) =
self.delegate.moveToLoadingAppState()
let selectedAccount = self.getSelectedLoginAccount()
self.accountsService.login(selectedAccount, self.tmpPassword)
self.accountsService.login(selectedAccount, hashPassword(self.tmpPassword))
proc loginAccountKeycard*(self: Controller, storeToKeychainValue: string, syncWalletAfterLogin = false) =
if syncWalletAfterLogin:

View File

@ -18,6 +18,9 @@ proc hashPassword*(password: string, lower: bool = true): string =
return hashed
proc hashedPasswordToUpperCase*(hashedPassword: string): string =
return "0x" & hashedPassword[2 .. ^1].toUpperAscii()
proc prefix*(methodName: string, isExt:bool = true): string =
result = "waku"
result = result & (if isExt: "ext_" else: "_")
@ -83,4 +86,4 @@ proc isPathOutOfTheDefaultStatusDerivationTree*(path: string): bool =
return false
proc contractUniqueKey*(chainId: int, contractAddress: string): string =
return $chainId & "_" & contractAddress
return $chainId & "_" & contractAddress

View File

@ -66,7 +66,6 @@ QtObject:
keyStoreDir: string
defaultWalletEmoji: string
tmpAccount: AccountDto
tmpPassword: string
tmpHashedPassword: string
tmpThumbnailImage: string
tmpLargeImage: string
@ -618,9 +617,8 @@ QtObject:
self.loggedInAccount = account
self.setLocalAccountSettingsFile()
proc login*(self: Service, account: AccountDto, password: string) =
proc login*(self: Service, account: AccountDto, hashedPassword: string) =
try:
let hashedPassword = hashPassword(password)
var thumbnailImage: string
var largeImage: string
for img in account.images:
@ -634,7 +632,7 @@ QtObject:
os.createDir(keyStoreDir)
status_core.migrateKeyStoreDir($ %* {
"key-uid": account.keyUid
}, password, main_constants.ROOTKEYSTOREDIR, keyStoreDir)
}, hashedPassword, main_constants.ROOTKEYSTOREDIR, keyStoreDir)
self.setKeyStoreDir(account.keyUid)
# This is moved from `status-lib` here
@ -691,15 +689,14 @@ QtObject:
"RendezvousNodes": @[],
"DiscV5BootstrapNodes": @[]
}
let isOldHashPassword = self.verifyDatabasePassword(account.keyUid, hashPassword(password, lower=false))
let isOldHashPassword = self.verifyDatabasePassword(account.keyUid, hashedPasswordToUpperCase(hashedPassword))
if isOldHashPassword:
# Start loading screen with warning
self.events.emit(SIGNAL_REENCRYPTION_PROCESS_STARTED, Args())
# Save tmp properties so that we can login after the timer
self.tmpAccount = account
self.tmpPassword = password
self.tmpHashedPassword = hashedPassword
self.tmpThumbnailImage = thumbnailImage
self.tmpLargeImage = largeImage
@ -722,9 +719,8 @@ QtObject:
proc onWaitForReencryptionTimeout(self: Service, response: string) {.slot.} =
# Reencryption (can freeze and take up to 30 minutes)
let pwd = self.tmpPassword
self.tmpPassword = "" # Clear the password from memory as fast as possible
discard status_privacy.lowerDatabasePassword(self.tmpAccount.keyUid, pwd)
let oldHashedPassword = hashedPasswordToUpperCase(self.tmpHashedPassword)
discard status_privacy.changeDatabaseHashedPassword(self.tmpAccount.keyUid, oldHashedPassword, self.tmpHashedPassword)
# Normal login after reencryption
self.doLogin(self.tmpAccount, self.tmpHashedPassword, self.tmpThumbnailImage, self.tmpLargeImage, self.tmpNodeCfg)
@ -833,4 +829,4 @@ QtObject:
return false
proc getKdfIterations*(self: Service): int =
return KDF_ITERATIONS
return KDF_ITERATIONS

View File

@ -78,11 +78,10 @@ proc sendTransaction*(chainId: int, inputJSON: string, password: string): RpcRes
raise newException(RpcException, e.msg)
proc migrateKeyStoreDir*(account: string, password: string, oldKeystoreDir: string, multiaccountKeystoreDir: string)
proc migrateKeyStoreDir*(account: string, hashedPassword: string, oldKeystoreDir: string, multiaccountKeystoreDir: string)
{.raises: [RpcException, ValueError, Defect, SerializationError].} =
try:
var hashed_password = "0x" & $keccak_256.digest(password)
discard status_go.migrateKeyStoreDir(account, hashed_password, oldKeystoreDir, multiaccountKeystoreDir)
discard status_go.migrateKeyStoreDir(account, hashedPassword, oldKeystoreDir, multiaccountKeystoreDir)
except Exception as e:
error "error migrating keystore dir", account, exception=e.msg
raise newException(RpcException, e.msg)

View File

@ -9,29 +9,21 @@ export response_type
logScope:
topics = "rpc-privacy"
proc changeDatabasePassword*(keyUID: string, password: string, newPassword: string): RpcResponse[JsonNode]
proc changeDatabaseHashedPassword*(keyUID: string, oldHashedPassword: string, newHashedPassword: string): RpcResponse[JsonNode]
{.raises: [Exception].} =
try:
let hashedPassword = hashPassword(password)
let hashedNewPassword = hashPassword(newPassword)
let response = status_go.changeDatabasePassword(keyUID, hashedPassword, hashedNewPassword)
let response = status_go.changeDatabasePassword(keyUID, oldHashedPassword, newHashedPassword)
result.result = Json.decode(response, JsonNode)
except RpcException as e:
error "error", methodName = "changeDatabasePassword", exception=e.msg
raise newException(RpcException, e.msg)
proc lowerDatabasePassword*(keyUID: string, password: string): RpcResponse[JsonNode]
proc changeDatabasePassword*(keyUID: string, password: string, newPassword: string): RpcResponse[JsonNode]
{.raises: [Exception].} =
try:
let hashedPassword = hashPassword(password, lower=false)
let hashedNewPassword = hashPassword(password)
let response = status_go.changeDatabasePassword(keyUID, hashedPassword, hashedNewPassword)
result.result = Json.decode(response, JsonNode)
except RpcException as e:
error "error", methodName = "lowerDatabasePassword", exception=e.msg
raise newException(RpcException, e.msg)
let hashedPassword = hashPassword(password)
let hashedNewPassword = hashPassword(newPassword)
return changeDatabaseHashedPassword(keyUID, hashedPassword, hashedNewPassword)
proc getLinkPreviewWhitelist*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
result = callPrivateRPC("getLinkPreviewWhitelist".prefix, payload)
result = callPrivateRPC("getLinkPreviewWhitelist".prefix, payload)