From 6c9b9d07b2cb272e03f52eee67010024de2ba086 Mon Sep 17 00:00:00 2001 From: Daniel Krol Date: Mon, 8 Aug 2022 16:31:29 -0400 Subject: [PATCH] Pass root password directly to SDK again. Related to this: https://github.com/lbryio/wallet-sync-server/issues/4 Passing in a KDF output messes with the existing CLI UI for wallet locking. Also the SDK has its own encryption from password, may as well use it. --- test_client/README.md | 50 ++++++++++++++++++++------------------ test_client/gen-readme.py | 2 ++ test_client/test_client.py | 37 +++++++++++++++------------- 3 files changed, 48 insertions(+), 41 deletions(-) mode change 100644 => 100755 test_client/gen-readme.py diff --git a/test_client/README.md b/test_client/README.md index edc0abc..a945a21 100644 --- a/test_client/README.md +++ b/test_client/README.md @@ -24,7 +24,7 @@ Generating keys... Done generating keys Registered >>> c1.salt_seed -'fd7bcc62d7334fbf07aca5791783cb173e3aaef91e228f000a69e3ec8eef123e' +'1d52635c14b34f0fefcf86368d4e0b82e3555de9d3c93a6f22cd5500fd120c0d' ``` Set up the other client. See that it got the same salt seed from the server in the process, which it needs to make sure we have the correct encryption key and login password. @@ -34,16 +34,16 @@ Set up the other client. See that it got the same salt seed from the server in t Generating keys... Done generating keys >>> c2.salt_seed -'fd7bcc62d7334fbf07aca5791783cb173e3aaef91e228f000a69e3ec8eef123e' +'1d52635c14b34f0fefcf86368d4e0b82e3555de9d3c93a6f22cd5500fd120c0d' ``` Now that the account exists, grab an auth token with both clients. ``` >>> c1.get_auth_token() -Got auth token: 310077f33a9b8de99ee6c45ffbe4a06a7178683e4eb65500fc5ae26513f80928 +Got auth token: e52f6e893fe3fa92d677d85f32e77357d68afd313c303a91d3af176ec684aa0d >>> c2.get_auth_token() -Got auth token: cdd18033dc48aeefedc278d116a6abbef7f0fb525d7ddfb2e1804a817a212c4a +Got auth token: b9fc2620990447d5f0305ecafc9f75e2a5f928a31bd86806aa8989567cad57d0 ``` ## Syncing @@ -55,7 +55,7 @@ Create a new wallet + metadata (we'll wrap it in a struct we'll call `WalletStat >>> c1.update_remote_wallet() Successfully updated wallet state on server Synced walletState: -WalletState(sequence=1, encrypted_wallet='czo4MTkyOjE2OjE6KY46kZ0oRC9W8g/LVCe3V3sLdCHk0sWEBqPjzcKykl3dDJpQvRXtz8HFXlD+bgvs8M5jHw7KjJ9ODUOEq3VoSawrKyZpgc8AYIx+vC4w+q6cKC3LToxr7FlfyAoQKo9dCothik/90ySVMAPY1BBrBmQ8H46eFEoMWZ4nG2OWGew=') +WalletState(sequence=1, encrypted_wallet='czo4MTkyOjE2OjE6XBEQgEACPvxgUFW3MGnY9tG5VYh/Hx7iNG6DAX+q4zTbVZM17OQ/5D1+IOjxS7jxOB+dZmtxmo6qwGtizjc4+YBhNk/eKb+uIU8T6HQ4T3m+PiWpedLnBwF4RStPPBp1M2WNFTIZQPKirETPO3GqRQSzveB17A3iESqYTqHnGeE=') 'Success' ``` @@ -67,7 +67,7 @@ Now, call `init_wallet_state` with the other client. Then, we call `get_remote_w >>> c2.init_wallet_state() >>> c2.get_remote_wallet() Got latest walletState: -WalletState(sequence=1, encrypted_wallet='czo4MTkyOjE2OjE6KY46kZ0oRC9W8g/LVCe3V3sLdCHk0sWEBqPjzcKykl3dDJpQvRXtz8HFXlD+bgvs8M5jHw7KjJ9ODUOEq3VoSawrKyZpgc8AYIx+vC4w+q6cKC3LToxr7FlfyAoQKo9dCothik/90ySVMAPY1BBrBmQ8H46eFEoMWZ4nG2OWGew=') +WalletState(sequence=1, encrypted_wallet='czo4MTkyOjE2OjE6XBEQgEACPvxgUFW3MGnY9tG5VYh/Hx7iNG6DAX+q4zTbVZM17OQ/5D1+IOjxS7jxOB+dZmtxmo6qwGtizjc4+YBhNk/eKb+uIU8T6HQ4T3m+PiWpedLnBwF4RStPPBp1M2WNFTIZQPKirETPO3GqRQSzveB17A3iESqYTqHnGeE=') 'Success' ``` @@ -79,12 +79,12 @@ Push a new version, GET it with the other client. Even though we haven't edited >>> c2.update_remote_wallet() Successfully updated wallet state on server Synced walletState: -WalletState(sequence=2, encrypted_wallet='czo4MTkyOjE2OjE6pNxAvxzGvZZvlSuYhSdGFmHGvWImYJlEewOnp6iUBbqTo899MrCfgvvlOzBOuKwk4vpJYcQgEkb3u2+j7bnJ18OCFEUeDzq88JuoKNw6ppdAbpw8D7MIDZP4Tf+5O8LmjxKtbiMy/ztW0nUxi4Ls8uuJ436CdF0UwaevHOAvlOE=') +WalletState(sequence=2, encrypted_wallet='czo4MTkyOjE2OjE6gL9aGNjy4U+6mBQZRzx+GS+/1dhl54+5sBzVtBQz51az7HQ3HFI2PjUL7XkeTcjdsaPEKh3eFTQwly9fNFKJIya5YvmtY8zhxe8FCqCkTITrn2EPwZFYXF6E3Wi1gLaPMpZlb2EXIZ1E7Gbg1Uxcpj+s1CB4ttjIZdnFwUrfAw4=') 'Success' >>> c1.get_remote_wallet() Nothing to merge. Taking remote walletState as latest walletState. Got latest walletState: -WalletState(sequence=2, encrypted_wallet='czo4MTkyOjE2OjE6pNxAvxzGvZZvlSuYhSdGFmHGvWImYJlEewOnp6iUBbqTo899MrCfgvvlOzBOuKwk4vpJYcQgEkb3u2+j7bnJ18OCFEUeDzq88JuoKNw6ppdAbpw8D7MIDZP4Tf+5O8LmjxKtbiMy/ztW0nUxi4Ls8uuJ436CdF0UwaevHOAvlOE=') +WalletState(sequence=2, encrypted_wallet='czo4MTkyOjE2OjE6gL9aGNjy4U+6mBQZRzx+GS+/1dhl54+5sBzVtBQz51az7HQ3HFI2PjUL7XkeTcjdsaPEKh3eFTQwly9fNFKJIya5YvmtY8zhxe8FCqCkTITrn2EPwZFYXF6E3Wi1gLaPMpZlb2EXIZ1E7Gbg1Uxcpj+s1CB4ttjIZdnFwUrfAw4=') 'Success' ``` @@ -110,12 +110,12 @@ The wallet is synced between the clients. The client with the changed preference >>> c1.update_remote_wallet() Successfully updated wallet state on server Synced walletState: -WalletState(sequence=3, encrypted_wallet='czo4MTkyOjE2OjE6FvtBsBMaRvnY6+SnQiBab/FWjzC9mgu3OHFXRTcJm3MsByZWbrzkFz6y4FrPN1cC+/Rcw11oJNydyys2ZaPl6zNYP/uxV6anEmET1hTt1+E2NzUJ2K/K4BLN7AgLBLQDM8zAwVzCTeaT6MZvjTV/slYc7NEqlfCMgeId2WpBJp+BCbTLo0SjPWhHCsQvo3Hf') +WalletState(sequence=3, encrypted_wallet='czo4MTkyOjE2OjE6JwVggGDjqoLy9YUqFXzIltph5bvO46SwJoAbLydlLg1mjfoXksGm9NsWbmYYmBoiXmiIbJPIsj8xfOjO5JlCH+EHSdyjCXizzwClYwgM4UD1+/ltuv1TH7H59cXd6Kztefn4y9IL/97rs+2DxDHM6cb/AdYGohIc3VaCmYBSbYRQFjTbQHaaScW6ntYuXAyE') 'Success' >>> c2.get_remote_wallet() Nothing to merge. Taking remote walletState as latest walletState. Got latest walletState: -WalletState(sequence=3, encrypted_wallet='czo4MTkyOjE2OjE6FvtBsBMaRvnY6+SnQiBab/FWjzC9mgu3OHFXRTcJm3MsByZWbrzkFz6y4FrPN1cC+/Rcw11oJNydyys2ZaPl6zNYP/uxV6anEmET1hTt1+E2NzUJ2K/K4BLN7AgLBLQDM8zAwVzCTeaT6MZvjTV/slYc7NEqlfCMgeId2WpBJp+BCbTLo0SjPWhHCsQvo3Hf') +WalletState(sequence=3, encrypted_wallet='czo4MTkyOjE2OjE6JwVggGDjqoLy9YUqFXzIltph5bvO46SwJoAbLydlLg1mjfoXksGm9NsWbmYYmBoiXmiIbJPIsj8xfOjO5JlCH+EHSdyjCXizzwClYwgM4UD1+/ltuv1TH7H59cXd6Kztefn4y9IL/97rs+2DxDHM6cb/AdYGohIc3VaCmYBSbYRQFjTbQHaaScW6ntYuXAyE') 'Success' >>> c2.get_preferences() {'animal': 'cow', 'car': ''} @@ -142,7 +142,7 @@ One client POSTs its change first. >>> c1.update_remote_wallet() Successfully updated wallet state on server Synced walletState: -WalletState(sequence=4, encrypted_wallet='czo4MTkyOjE2OjE6rKE6TWvZxBp0No0S1CRrjW55i6w9pE6obS+9bwR76qaBBQ40lz0Ajd/2vXO1KBAQhxEHDJ6WJLPs15SgqhVspaNXmdwR1dYEHmJ8M+PW0KLv+vZoxxeGQ/5EBdrAZIfBhmI50SPF4RzmTzKTyw3VlSdqqhCutgi6FcXP+CLlsnH6qaLgjLDLISjwSMIwBd4y') +WalletState(sequence=4, encrypted_wallet='czo4MTkyOjE2OjE6xMKOvjQ9RBAWCac5Cj5d30YSI4PaMh3T+99fLdHKJC2RCcwrbhCurNIDBln6QJWCfa3gRp2/sY9k47XwZNsknCTrdIe4c3YJejvL/WCZTzoJ81m9QGbP/05DHQUV5c7z30taIESp4qOFwpSwYMB972gn6ZXOhn1iNDKSCLN3nSLHFnA0arjCAPQof//lJriz') 'Success' ``` @@ -154,7 +154,7 @@ Eventually, the client will be responsible (or at least more responsible) for me >>> c2.get_remote_wallet() Merging local changes with remote changes to create latest walletState. Got latest walletState: -WalletState(sequence=4, encrypted_wallet='czo4MTkyOjE2OjE6rKE6TWvZxBp0No0S1CRrjW55i6w9pE6obS+9bwR76qaBBQ40lz0Ajd/2vXO1KBAQhxEHDJ6WJLPs15SgqhVspaNXmdwR1dYEHmJ8M+PW0KLv+vZoxxeGQ/5EBdrAZIfBhmI50SPF4RzmTzKTyw3VlSdqqhCutgi6FcXP+CLlsnH6qaLgjLDLISjwSMIwBd4y') +WalletState(sequence=4, encrypted_wallet='czo4MTkyOjE2OjE6xMKOvjQ9RBAWCac5Cj5d30YSI4PaMh3T+99fLdHKJC2RCcwrbhCurNIDBln6QJWCfa3gRp2/sY9k47XwZNsknCTrdIe4c3YJejvL/WCZTzoJ81m9QGbP/05DHQUV5c7z30taIESp4qOFwpSwYMB972gn6ZXOhn1iNDKSCLN3nSLHFnA0arjCAPQof//lJriz') 'Success' >>> c2.get_preferences() {'animal': 'horse', 'car': 'Audi'} @@ -166,12 +166,12 @@ Finally, the client with the merged wallet pushes it to the server, and the othe >>> c2.update_remote_wallet() Successfully updated wallet state on server Synced walletState: -WalletState(sequence=5, encrypted_wallet='czo4MTkyOjE2OjE62Tub/EfwCMdYpZ9N9wCRwTB3Di+eA0oVpn44v/n1UgOB8jNEIEtQptCfBtBE7yfIJP8pw544SkhxAfR2Zy8/UrLIhKMUSVeCl8bJP78AoJCPpeJEQo4GOqPvluWYS2eOh1urZojn5yqB5nGRnK4hYhQ6lOwgg4jfRFtTzMKPYb263ONb3mx1SkeoCwmBeRoF') +WalletState(sequence=5, encrypted_wallet='czo4MTkyOjE2OjE6L+PCpF1qh1ayai/fqnc7kwa2eBJc1n6L6FuaLps8gdZhY9UdaBMc/BckvgUF9OXR7yOvndrFy73+5EzWxpmffBfZGqq42XjtbmHGScEERjuzra8UB2vLn+N2oe5s+e2O+7lJxPKYBD2pX4xKm3HjKqAso+D0MsWHMz9hqRLFekJfv5pVglUVkweW+h8yNxn1') 'Success' >>> c1.get_remote_wallet() Nothing to merge. Taking remote walletState as latest walletState. Got latest walletState: -WalletState(sequence=5, encrypted_wallet='czo4MTkyOjE2OjE62Tub/EfwCMdYpZ9N9wCRwTB3Di+eA0oVpn44v/n1UgOB8jNEIEtQptCfBtBE7yfIJP8pw544SkhxAfR2Zy8/UrLIhKMUSVeCl8bJP78AoJCPpeJEQo4GOqPvluWYS2eOh1urZojn5yqB5nGRnK4hYhQ6lOwgg4jfRFtTzMKPYb263ONb3mx1SkeoCwmBeRoF') +WalletState(sequence=5, encrypted_wallet='czo4MTkyOjE2OjE6L+PCpF1qh1ayai/fqnc7kwa2eBJc1n6L6FuaLps8gdZhY9UdaBMc/BckvgUF9OXR7yOvndrFy73+5EzWxpmffBfZGqq42XjtbmHGScEERjuzra8UB2vLn+N2oe5s+e2O+7lJxPKYBD2pX4xKm3HjKqAso+D0MsWHMz9hqRLFekJfv5pVglUVkweW+h8yNxn1') 'Success' >>> c1.get_preferences() {'animal': 'horse', 'car': 'Audi'} @@ -202,7 +202,7 @@ We try to POST both of them to the server. The second one fails because of the c >>> c2.update_remote_wallet() Successfully updated wallet state on server Synced walletState: -WalletState(sequence=6, encrypted_wallet='czo4MTkyOjE2OjE6ZNErNr5SrgjRMOBmK2pKtU2wu+jdwR8WO/thAf+VrGJ9237sKTjNX0aQILuj9dOzY836xYk2vB1Niypgf4PvlnXEAZ64pHO2FV8aR/0JcjsufkdUXUIJH2hxDhT5Ui8kS2tXPAuo0xDxfqQgqiJaVNfgyCo2fzqz5m5V3jBzivm7fN8TpuNaT94koI2GFPc3') +WalletState(sequence=6, encrypted_wallet='czo4MTkyOjE2OjE6HieQoVznUMTBF6x643Mg/AQUZadaikkiuRZsw3IaQsapK56WL3IBGrlemOjSH6uTfBWsWaLDMXEz+X7j5wqchSAt/wle2+I9dKgyDdFhWMOaEd61pT6r+lS8O8AbSKUJ6r5FSDgJRE/vz5l4xP/W9AVrK4l0u9ZqpvsKAet3UlfVV48cOnhwgPqlPoGBQ1xF') 'Success' >>> c1.update_remote_wallet() Submitted wallet is out of date. @@ -218,14 +218,14 @@ The client that is out of date will then call `get_remote_wallet`, which GETs an >>> c1.get_remote_wallet() Merging local changes with remote changes to create latest walletState. Got latest walletState: -WalletState(sequence=6, encrypted_wallet='czo4MTkyOjE2OjE6ZNErNr5SrgjRMOBmK2pKtU2wu+jdwR8WO/thAf+VrGJ9237sKTjNX0aQILuj9dOzY836xYk2vB1Niypgf4PvlnXEAZ64pHO2FV8aR/0JcjsufkdUXUIJH2hxDhT5Ui8kS2tXPAuo0xDxfqQgqiJaVNfgyCo2fzqz5m5V3jBzivm7fN8TpuNaT94koI2GFPc3') +WalletState(sequence=6, encrypted_wallet='czo4MTkyOjE2OjE6HieQoVznUMTBF6x643Mg/AQUZadaikkiuRZsw3IaQsapK56WL3IBGrlemOjSH6uTfBWsWaLDMXEz+X7j5wqchSAt/wle2+I9dKgyDdFhWMOaEd61pT6r+lS8O8AbSKUJ6r5FSDgJRE/vz5l4xP/W9AVrK4l0u9ZqpvsKAet3UlfVV48cOnhwgPqlPoGBQ1xF') 'Success' >>> c1.get_preferences() {'animal': 'beaver', 'car': 'Toyota'} >>> c1.update_remote_wallet() Successfully updated wallet state on server Synced walletState: -WalletState(sequence=7, encrypted_wallet='czo4MTkyOjE2OjE6csXFcg5GaaIXauqORyfoSo3rcKiWzmTE2M/YBIJ1wmdBafqtUnKSO8DE/3EeKA35ow8iXJy5mowe4Ar8R+7m6FHxDblkDohjoeP9uZ5ziEirMSPu4eZsOcpXLdBsHp/qcGpNKAFnwGqeSdrxjvyFDQCyjl204mduE/X9mh6mlyYIei1IkK08rSTmc7mCuxIj') +WalletState(sequence=7, encrypted_wallet='czo4MTkyOjE2OjE6ypuX2e/wjiVZZVrLQEwoEuHZH7xhs6B3/awzxH/5WZITlKOo7TvV2Mjke/MSdTk2/YyWhfN8U0e4IwGxKW9VIpnF3ElEtEZxvJBklzDXeDNh5pWMgeZkBH5EempDQ6VzT0206z89EeiCK+3QSofUv7Ob90xNVUOdJq5/OBrG4LAGFh2ZVrh5KnqDm1+d8/ls') 'Success' ``` @@ -243,7 +243,7 @@ Generating keys... Done generating keys Successfully updated password and wallet state on server Synced walletState: -WalletState(sequence=8, encrypted_wallet='czo4MTkyOjE2OjE6p5qwc7BWPjZE6sDI6To/dS5wVDMvzb6BA9oezrp3ecVryouLorggVTmnQLpcLdskBDNjE7/S5P4T4LT6hJCjAby2LCgeHuatDrySson8RHcs9rozLFoaPIQCDMkCPC8EGTN/g0aOAnDGvB6jaW/IsSLpMyXeth2OjloOtj2caT1hrihpThFrLPp4glBRLGL5') +WalletState(sequence=8, encrypted_wallet='czo4MTkyOjE2OjE6Kd/DnozNDXYia8yYqrVI6OJ56tDAo5X4/Il+Ein/E6GRQ6K8/niK8Sjx1Cmpf7ecru14QS51pTwlFpS9mbwNE7CZ1wjAZHoLlL5B+dAECkSCFBHgBvq/29cXt6gG7KP+TLRLxZzGtgQRQiq6fsMBIIirw1ZCmpUNQP/PCHIJRfjJS0MNAGN8+srlPv+eUXIn') 'Success' ``` @@ -251,7 +251,7 @@ We generate a new salt seed when we change the password ``` >>> c1.salt_seed -'9968ede44e397d7875c057e4ebe50fd1118dc43a3e404e134353be6224947aad' +'155b6e8a9a8c9406844b6b0c4a40c3204ab1f06668470faa89e28aa89fefe3cf' ``` This operation invalidates all of the user's auth tokens. This prevents other clients from accidentally pushing a wallet encrypted with the old password. @@ -271,17 +271,19 @@ The client that changed its password can easily get a new token because it has t ``` >>> c1.get_auth_token() -Got auth token: 796ea0575fe1ba5d6a43afec016f6ed2c9225a5180e76e744aad5b8857c8702b +Got auth token: 68a3db244e21709429e69e67352d02a3b26542c5ef2ac3377e19b17de71942d6 >>> c2.get_auth_token() Error 401 b'{"error":"Unauthorized: No match for email and/or password"}\n' +Failed to get the auth token. Do you need to update this client's password (set_local_password())? +Or, in the off-chance the user changed their password back and forth, try updating secrets (update_secrets()) to get the latest salt seed. >>> c2.set_local_password("eggsandwich") Generating keys... Done generating keys >>> c2.salt_seed -'9968ede44e397d7875c057e4ebe50fd1118dc43a3e404e134353be6224947aad' +'155b6e8a9a8c9406844b6b0c4a40c3204ab1f06668470faa89e28aa89fefe3cf' >>> c2.get_auth_token() -Got auth token: 61932e198643b6f8bf1cd42fd0d296ce01b9813b6c1f312826baca3d50f95d47 +Got auth token: 3917215675c5cc7fb5c5e24d583fddcd0a14c4370140e2274cf4c5da7eaae7bb ``` We don't allow password changes if we have pending wallet changes to push. This is to prevent a situation where the user has to merge local and remote changes in the middle of a password change. @@ -297,13 +299,13 @@ Local changes found. Update remote wallet before changing password. >>> c1.update_remote_wallet() Successfully updated wallet state on server Synced walletState: -WalletState(sequence=9, encrypted_wallet='czo4MTkyOjE2OjE6i9/lJoTH+8okCoczA7Q0o/X/X8MfVulO3qAq2GtKEKW9m4JH7Fcup62BOhwHtsNPOHIiMv9er5SpOx9pGBq3s9Bei4k2fNq4RXmXEPZX66p1T26VboJ0o53etIhnfQ9Q3pdLssiURjkK4OXpDDzbw1KsYXAPnJS50Nb8/A7+14BTgLoyJmGjW3nwjTxFjzRt') +WalletState(sequence=9, encrypted_wallet='czo4MTkyOjE2OjE6Hspn+wbfHEzSv+1zsM/sFUaJJZuLLP7jLtCl3Ou3OQhXGEpkC0pP7WcbdGdQ+4foakTaB/y/b9All85rJ1ZiGWFnaK8SS9Rd7JT1UCEHs0BhN5+SfIK58yukIefzP39ZlSGUomE3eifOqso8C/gY2FltO96TS8WXx6czxqm6M/dvLk6q10LpODCQEH5auTA6') 'Success' >>> c1.change_password("starboard") Generating keys... Done generating keys Successfully updated password and wallet state on server Synced walletState: -WalletState(sequence=10, encrypted_wallet='czo4MTkyOjE2OjE6D2TVSTbVugAqf8VSDmiIbArhQypf6o1LkQxAphJFlcbHHDtCQ4aqpmhsdWrkaf0Jd7+L2J12aWNf+XQGwS/kddTi9pplCwlAJB/RkTl4xeFPIRT5g5iVHrJcvCU2/gNa1BpRGtROn0fFb0SscS3WPxdQ5QA6jIGEblu1OY0KF/phpQt1DtNcuOS6rOz3NCmV') +WalletState(sequence=10, encrypted_wallet='czo4MTkyOjE2OjE6Cnditb9t+rU56hfcMq6gW+lx1ek3TzyBZ4633FoiWCzTxIenbMyapolU0gnpWHasP8olOoL56LfSGVzP8eKG4JoRsU9VmOYXjkpY9QZCcKomVC4fJ17jPq/e2gJWDSv03pA1xbDhRpXRnZr3wd+37znTUyLpYzRDRAHpb2IGDi9FforobQRNcZUhx0DY8WIR') 'Success' ``` diff --git a/test_client/gen-readme.py b/test_client/gen-readme.py old mode 100644 new mode 100755 index 5585ce9..eedfd93 --- a/test_client/gen-readme.py +++ b/test_client/gen-readme.py @@ -1,3 +1,5 @@ +#!/bin/python3 + # Generate the README since I want real behavior interspersed with comments # Come to think of it, this is accidentally a pretty okay integration test for client and server # NOTE - delete the database before running this, or else you'll get an error for registering. also we want the wallet to start empty diff --git a/test_client/test_client.py b/test_client/test_client.py index b899b6b..069ec55 100755 --- a/test_client/test_client.py +++ b/test_client/test_client.py @@ -248,7 +248,7 @@ def derive_secrets(root_password, email, salt_seed): scrypt_p = 1 key_length = 32 - num_keys = 3 + num_keys = 2 salt = generate_salt(email, salt_seed) @@ -268,14 +268,12 @@ def derive_secrets(root_password, email, salt_seed): parts = ( kdf_output[:key_length], kdf_output[key_length:key_length * 2], - kdf_output[key_length * 2:], ) lbry_id_password = base64.b64encode(parts[0]).decode('utf-8') - sync_password = base64.b64encode(parts[1]).decode('utf-8') - hmac_key = parts[2] + hmac_key = parts[1] - return lbry_id_password, sync_password, hmac_key + return lbry_id_password, hmac_key def create_hmac(wallet_state, hmac_key): input_str = str(wallet_state.sequence) + ':' + wallet_state.encrypted_wallet @@ -324,7 +322,7 @@ class Client(): # be a new seed if it's a new server. self.salt_seed = generate_salt_seed() - self.lbry_id_password, self.sync_password, self.hmac_key = derive_secrets( + self.lbry_id_password, self.hmac_key = derive_secrets( self.root_password, self.email, self.salt_seed) success = self.wallet_sync_api.register( @@ -350,7 +348,7 @@ class Client(): locally. """ self.salt_seed = self.wallet_sync_api.get_salt_seed(self.email) - self.lbry_id_password, self.sync_password, self.hmac_key = derive_secrets( + self.lbry_id_password, self.hmac_key = derive_secrets( self.root_password, self.email, self.salt_seed) # TODO - This does not deal with the question of tying accounts to wallets. @@ -495,7 +493,7 @@ class Client(): return "Error" submitted_wallet_state = WalletState( - encrypted_wallet=self.get_local_encrypted_wallet(self.sync_password), + encrypted_wallet=self.get_local_encrypted_wallet(self.root_password), sequence=self.synced_wallet_state.sequence + 1 ) hmac = create_hmac(submitted_wallet_state, self.hmac_key) @@ -525,8 +523,14 @@ class Client(): # Auditor - Should we be generating a *new* seed for every password change? self.salt_seed = generate_salt_seed() - new_lbry_id_password, new_sync_password, new_hmac_key = derive_secrets( + new_lbry_id_password, new_hmac_key = derive_secrets( new_root_password, self.email, self.salt_seed) + def set_secrets(): + # Only do this once we got a good response from the server. + # In a function because it can happen in two different places. + self.root_password, self.lbry_id_password, self.hmac_key = ( + new_root_password, new_lbry_id_password, new_hmac_key) + # TODO - Think of failure sequence in case of who knows what. We # could just get the old salt seed back from the server? # We can't lose it though. Keep the old one around? Kinda sucks. @@ -553,7 +557,7 @@ class Client(): # accepted by the server. submitted_wallet_state = WalletState( - encrypted_wallet=self.get_local_encrypted_wallet(new_sync_password), + encrypted_wallet=self.get_local_encrypted_wallet(new_root_password), sequence=self.synced_wallet_state.sequence + 1 ) hmac = create_hmac(submitted_wallet_state, new_hmac_key) @@ -562,9 +566,9 @@ class Client(): updated = self.wallet_sync_api.change_password_with_wallet(submitted_wallet_state, hmac, self.email, self.lbry_id_password, new_lbry_id_password, self.salt_seed) if updated: - # We updated it. Now it's synced and we mark it as such. Update everything in one command to keep local changes in sync! - self.synced_wallet_state, self.lbry_id_password, self.sync_password, self.hmac_key = ( - submitted_wallet_state, new_lbry_id_password, new_sync_password, new_hmac_key) + # We updated it. Now it's synced and we mark it as such. Update everything at once to keep local changes in sync! + self.synced_wallet_state = submitted_wallet_state + set_secrets() print ("Synced walletState:") pprint(self.synced_wallet_state) @@ -574,9 +578,8 @@ class Client(): updated = self.wallet_sync_api.change_password_no_wallet(self.email, self.lbry_id_password, new_lbry_id_password, self.salt_seed) if updated: - # We updated it. Now we mark it as such. Update everything in one command to keep local changes in sync! - self.lbry_id_password, self.sync_password, self.hmac_key = ( - new_lbry_id_password, new_sync_password, new_hmac_key) + # We updated it. Now we mark it as such. Update everything at once to keep local changes in sync! + set_secrets() return "Success" print ("Could not update wallet and password. Perhaps need to get new wallet and merge, perhaps something else.") @@ -603,7 +606,7 @@ class Client(): def update_local_encrypted_wallet(self, encrypted_wallet): # TODO - error checking - return LBRYSDK.update_wallet(self.wallet_id, self.sync_password, encrypted_wallet) + return LBRYSDK.update_wallet(self.wallet_id, self.root_password, encrypted_wallet) def get_local_encrypted_wallet(self, sync_password): # TODO - error checking