From e4e8fadb0ffd7f9e8366382daacec64620a59f1a Mon Sep 17 00:00:00 2001 From: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com> Date: Mon, 30 Jun 2025 11:43:41 -0700 Subject: [PATCH] Update libsignal-client to 0.76.0 --- .github/workflows/ci.yml | 2 +- ACKNOWLEDGMENTS.md | 635 +----------------- app/attachment_channel.ts | 2 +- package.json | 2 +- pnpm-lock.yaml | 10 +- ts/Crypto.ts | 20 +- ts/Curve.ts | 22 +- ts/LibSignalStores.ts | 2 +- ts/SignalProtocolStore.ts | 43 +- ts/jobs/helpers/sendResendRequest.ts | 3 +- ts/jobs/helpers/sendSavedProto.ts | 3 +- ts/services/backups/credentials.ts | 17 +- ts/services/backups/crypto.ts | 8 +- ts/services/backups/import.ts | 12 +- ts/services/backups/index.ts | 2 +- ts/services/backups/validator.ts | 2 +- ts/services/calling.ts | 20 +- ts/services/groupCredentialFetcher.ts | 13 +- ts/services/username.ts | 15 +- ts/services/usernameIntegrity.ts | 3 +- ts/test-electron/backup/integration_test.ts | 2 +- ts/test-helpers/generateBackup.ts | 10 +- ts/textsecure/AccountManager.ts | 4 +- ts/textsecure/MessageReceiver.ts | 28 +- ts/textsecure/OutgoingMessage.ts | 11 +- ts/textsecure/ProvisioningCipher.ts | 2 +- ts/textsecure/SendMessage.ts | 4 +- ts/textsecure/WebAPI.ts | 27 +- ts/textsecure/cds/CDSISocket.ts | 18 +- ts/textsecure/cds/CDSSocketBase.ts | 19 +- ts/textsecure/getKeysForServiceId.ts | 19 +- ts/textsecure/processDataMessage.ts | 2 +- ts/updater/curve.ts | 10 +- ts/updater/signature.ts | 14 +- ts/util/ServiceId.ts | 8 +- ts/util/groupSendEndorsements.ts | 11 +- ts/util/handleMessageSend.ts | 2 +- ts/util/handleRetry.ts | 2 +- ts/util/lookupConversationWithoutServiceId.ts | 2 +- ts/util/pemToDer.ts | 6 +- ts/util/safetyNumber.ts | 8 +- ts/util/sendToGroup.ts | 17 +- ts/util/zkgroup.ts | 66 +- 43 files changed, 245 insertions(+), 883 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c290699f7b9..a66b4686c02 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -234,7 +234,7 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 with: repository: 'signalapp/Signal-Message-Backup-Tests' - ref: '57807422c347f53cfa8d5a1423c382992a8fc199' + ref: '316c3d5eb15ffc923b5ce2925094fd49b34e8203' path: 'backup-integration-tests' - run: xvfb-run --auto-servernum pnpm run test-electron diff --git a/ACKNOWLEDGMENTS.md b/ACKNOWLEDGMENTS.md index 307e4a019f4..1ec4a1e746f 100644 --- a/ACKNOWLEDGMENTS.md +++ b/ACKNOWLEDGMENTS.md @@ -5961,7 +5961,7 @@ For more information on this, and how to apply and follow the GNU AGPL, see ``` -## libsignal-account-keys, attest, libsignal-ffi, libsignal-jni, libsignal-jni-impl, libsignal-jni-testing, libsignal-node, signal-neon-futures, signal-neon-futures-tests, libsignal-bridge, libsignal-bridge-macros, libsignal-bridge-testing, libsignal-bridge-types, libsignal-cli-utils, libsignal-core, signal-crypto, device-transfer, libsignal-keytrans, signal-media, libsignal-message-backup, libsignal-message-backup-macros, libsignal-net, libsignal-net-chat, libsignal-net-infra, poksho, libsignal-protocol, usernames, zkcredential, zkgroup +## libsignal-account-keys, attest, libsignal-node, signal-neon-futures, libsignal-bridge, libsignal-bridge-macros, libsignal-bridge-testing, libsignal-bridge-types, libsignal-core, signal-crypto, device-transfer, libsignal-keytrans, signal-media, libsignal-message-backup, libsignal-message-backup-macros, libsignal-net, libsignal-net-chat, libsignal-net-infra, poksho, libsignal-protocol, usernames, zkcredential, zkgroup ``` GNU AFFERO GENERAL PUBLIC LICENSE @@ -8360,7 +8360,7 @@ THIS SOFTWARE. ``` -## rustls-webpki 0.102.8, rustls-webpki 0.103.1 +## rustls-webpki 0.103.1 ``` Except as otherwise noted, this project is licensed under the following @@ -8385,7 +8385,7 @@ third-party/chromium/LICENSE. ``` -## windows-core 0.61.0, windows-implement 0.60.0, windows-interface 0.59.1, windows-link 0.1.1, windows-result 0.3.2, windows-strings 0.4.0, windows-sys 0.45.0, windows-sys 0.52.0, windows-sys 0.59.0, windows-targets 0.42.2, windows-targets 0.52.6, windows_aarch64_msvc 0.42.2, windows_aarch64_msvc 0.52.6, windows_x86_64_gnu 0.52.6, windows_x86_64_msvc 0.42.2, windows_x86_64_msvc 0.52.6 +## windows-core 0.61.0, windows-implement 0.60.0, windows-interface 0.59.1, windows-link 0.1.1, windows-result 0.3.2, windows-strings 0.4.0, windows-sys 0.52.0, windows-sys 0.59.0, windows-targets 0.52.6, windows_aarch64_msvc 0.52.6, windows_x86_64_gnu 0.52.6, windows_x86_64_msvc 0.52.6 ``` MIT License @@ -8626,7 +8626,7 @@ DEALINGS IN THE SOFTWARE. ``` -## backtrace 0.3.74, cc 1.2.18, cfg-if 1.0.0, cmake 0.1.48, openssl-probe 0.1.6, pkg-config 0.3.32, rustc-demangle 0.1.24, scoped-tls 1.0.1, socket2 0.5.9 +## backtrace 0.3.74, cc 1.2.18, cfg-if 1.0.0, cmake 0.1.48, openssl-probe 0.1.6, rustc-demangle 0.1.24, socket2 0.5.9 ``` Copyright (c) 2014 Alex Crichton @@ -8689,38 +8689,6 @@ DEALINGS IN THE SOFTWARE. ``` -## libz-sys 1.1.22 - -``` -Copyright (c) 2014 Alex Crichton -Copyright (c) 2020 Josh Triplett - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -``` - ## mio 1.0.3 ``` @@ -8775,32 +8743,6 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -``` - -## mime 0.3.17 - -``` -Copyright (c) 2014 Sean McArthur - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - ``` ## base64ct 1.6.0 @@ -8896,32 +8838,6 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -``` - -## unicase 2.8.1 - -``` -Copyright (c) 2014-2017 Sean McArthur - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - ``` ## nom 7.1.3 @@ -8948,32 +8864,6 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -``` - -## headers-core 0.2.0, headers 0.3.9 - -``` -Copyright (c) 2014-2019 Sean McArthur - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - ``` ## libc 0.2.171 @@ -9007,31 +8897,6 @@ DEALINGS IN THE SOFTWARE. ``` -## hyper 0.14.32 - -``` -Copyright (c) 2014-2021 Sean McArthur - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -``` - ## flate2 1.1.1 ``` @@ -9287,31 +9152,6 @@ SOFTWARE. ``` -## jni-sys 0.3.0 - -``` -Copyright (c) 2015 The rust-jni-sys Developers - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -``` - ## which 4.4.2 ``` @@ -9615,37 +9455,6 @@ DEALINGS IN THE SOFTWARE. ``` -## serde_urlencoded 0.7.1 - -``` -Copyright (c) 2016 Anthony Ramine - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -``` - ## intmap 3.1.0 ``` @@ -9720,7 +9529,7 @@ DEALINGS IN THE SOFTWARE. ``` -## rustls-native-certs 0.8.1, rustls-pemfile 2.2.0, rustls 0.22.4, rustls 0.23.25 +## rustls-native-certs 0.8.1, rustls 0.23.25 ``` Copyright (c) 2016 Joseph Birr-Pixton @@ -9782,31 +9591,6 @@ DEALINGS IN THE SOFTWARE. ``` -## httpdate 1.0.3 - -``` -Copyright (c) 2016 Pyfisch - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -``` - ## rustc_version 0.4.1 ``` @@ -10081,7 +9865,7 @@ DEALINGS IN THE SOFTWARE. ``` -## tungstenite 0.21.0, tungstenite 0.26.2 +## tungstenite 0.26.2 ``` Copyright (c) 2017 Alexey Galakhov @@ -10200,7 +9984,7 @@ DEALINGS IN THE SOFTWARE. ``` -## tokio-tungstenite 0.21.0, tokio-tungstenite 0.26.2 +## tokio-tungstenite 0.26.2 ``` Copyright (c) 2017 Daniel Abramov @@ -10250,38 +10034,6 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -``` - -## vcpkg 0.2.15 - -``` -Copyright (c) 2017 Jim McGrath - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - - ``` ## stable_deref_trait 1.2.0 @@ -10339,7 +10091,7 @@ SOFTWARE. ``` -## h2 0.3.26, h2 0.4.8 +## h2 0.4.8 ``` Copyright (c) 2017 h2 authors @@ -10370,7 +10122,7 @@ DEALINGS IN THE SOFTWARE. ``` -## http 0.2.12, http 1.3.1 +## http 1.3.1 ``` Copyright (c) 2017 http-rs authors @@ -10401,37 +10153,6 @@ DEALINGS IN THE SOFTWARE. ``` -## tokio-rustls 0.25.0 - -``` -Copyright (c) 2017 quininer kel - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -``` - ## aes 0.8.4 ``` @@ -10642,32 +10363,6 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -``` - -## warp 0.3.7 - -``` -Copyright (c) 2018-2020 Sean McArthur - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - ``` ## cbc 0.1.2, ctr 0.9.2 @@ -10886,37 +10581,6 @@ DEALINGS IN THE SOFTWARE. ``` -## http-body 0.4.6 - -``` -Copyright (c) 2019 Hyper Contributors - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -``` - ## ghash 0.5.1 ``` @@ -11066,7 +10730,7 @@ DEALINGS IN THE SOFTWARE. ``` -## aes-gcm-siv 0.11.1, aes-gcm 0.10.3, chacha20poly1305 0.10.1 +## aes-gcm-siv 0.11.1, chacha20poly1305 0.10.1 ``` Copyright (c) 2019 The RustCrypto Project Developers @@ -11160,37 +10824,6 @@ DEALINGS IN THE SOFTWARE. ``` -## tower-service 0.3.3 - -``` -Copyright (c) 2019 Tower Contributors - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. - -``` - ## universal-hash 0.5.1 ``` @@ -11971,7 +11604,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI ``` -## rand 0.8.5, rand 0.9.0, rand_chacha 0.3.1, rand_chacha 0.9.0, rand_core 0.6.4, rand_core 0.9.3 +## rand 0.9.0, rand_chacha 0.9.0, rand_core 0.6.4, rand_core 0.9.3 ``` Copyright 2018 Developers of the Rand project @@ -12511,33 +12144,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` -## multer 2.1.0 - -``` -MIT License - -Copyright (c) 2020 Rousan Ali - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -``` - ## snow 0.9.6 ``` @@ -12619,7 +12225,7 @@ SOFTWARE. ``` -## rustls-platform-verifier-android 0.1.1, rustls-platform-verifier 0.5.1 +## rustls-platform-verifier 0.5.1 ``` MIT License @@ -12673,30 +12279,6 @@ SOFTWARE. ``` -## cesu8 1.1.0 - -``` -MIT License - -Copyright (c) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the -following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial -portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT -LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO -EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -USE OR OTHER DEALINGS IN THE SOFTWARE. - -``` - ## tokio-stream 0.1.17, tokio-util 0.7.14, tokio 1.45.0 ``` @@ -12724,33 +12306,6 @@ SOFTWARE. ``` -## android-tzdata 0.1.1 - -``` -MIT License - -Copyright (c) [year] [fullname] - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -``` - ## miniz_oxide 0.8.7 ``` @@ -12860,58 +12415,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` -## android_system_properties 0.1.5 - -``` -The MIT License (MIT) - -Copyright (c) 2013 Nicolas Silva - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -``` - -## spin 0.9.8 - -``` -The MIT License (MIT) - -Copyright (c) 2014 Mathijs van de Nes - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -``` - ## typenum 1.18.0 ``` @@ -12965,7 +12468,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` -## base64 0.21.7, base64 0.22.1 +## base64 0.22.1 ``` The MIT License (MIT) @@ -12992,7 +12495,7 @@ THE SOFTWARE. ``` -## aho-corasick 1.1.3, byteorder 1.5.0, jiff 0.2.5, memchr 2.7.4, walkdir 2.5.0 +## aho-corasick 1.1.3, jiff 0.2.5, memchr 2.7.4 ``` The MIT License (MIT) @@ -13046,34 +12549,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -``` - -## combine 4.6.7 - -``` -The MIT License (MIT) - -Copyright (c) 2015 Markus Westerlind - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - ``` ## shlex 1.3.0 @@ -13211,33 +12686,6 @@ SOFTWARE. ``` -## jni 0.21.1 - -``` -The MIT License (MIT) - -Copyright (c) 2016 Prevoty, Inc. and jni-rs contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -``` - ## derive_builder 0.20.2, derive_builder_core 0.20.2, derive_builder_macro 0.20.2 ``` @@ -13265,33 +12713,6 @@ SOFTWARE. ``` -## same-file 1.0.6, winapi-util 0.1.9 - -``` -The MIT License (MIT) - -Copyright (c) 2017 Andrew Gallant - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -``` - ## async-compression 0.4.22 ``` @@ -13490,34 +12911,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -``` - -## mime_guess 2.0.5 - -``` -The MIT License (MIT) - -Copyright (c) 2015 Austin Bonander - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - ``` ## generic-array 0.14.7 diff --git a/app/attachment_channel.ts b/app/attachment_channel.ts index b5fc8b2845f..5b92f6ff2f7 100644 --- a/app/attachment_channel.ts +++ b/app/attachment_channel.ts @@ -108,7 +108,7 @@ type RangeFinderContextType = Readonly< type DigestLRUEntryType = Readonly<{ key: Buffer; - digest: Buffer; + digest: Uint8Array; }>; const digestLRU = new LRUCache({ diff --git a/package.json b/package.json index c5e4c91f33a..214072951f5 100644 --- a/package.json +++ b/package.json @@ -120,7 +120,7 @@ "@react-aria/utils": "3.25.3", "@react-spring/web": "9.7.5", "@react-types/shared": "3.27.0", - "@signalapp/libsignal-client": "0.74.1", + "@signalapp/libsignal-client": "0.76.0", "@signalapp/quill-cjs": "2.1.2", "@signalapp/ringrtc": "2.53.0", "@signalapp/sqlcipher": "2.0.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d2a5d080821..0ab6cd11c71 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -129,8 +129,8 @@ importers: specifier: 3.27.0 version: 3.27.0(react@18.3.1) '@signalapp/libsignal-client': - specifier: 0.74.1 - version: 0.74.1 + specifier: 0.76.0 + version: 0.76.0 '@signalapp/quill-cjs': specifier: 2.1.2 version: 2.1.2 @@ -2767,8 +2767,8 @@ packages: '@signalapp/libsignal-client@0.60.2': resolution: {integrity: sha512-tU4kNP/yCwkFntb2ahXOSQJtzdy+YifAB2yv5hw0qyKSidRHLn6bYiz4Zo2tjxLDRoBLAUxCRsQramStiqNZdA==} - '@signalapp/libsignal-client@0.74.1': - resolution: {integrity: sha512-PEJou0yrBvxaAGg7JjONlRNM/t3PCBuY96wu7W6+57e38/7Mibo9kAMfE5B8DgVv+DUNMW9AgJhx5McCoIXYew==} + '@signalapp/libsignal-client@0.76.0': + resolution: {integrity: sha512-wQZFC79GAUeee8pf+aDK5Gii0HbQoCAv/oTn1Ht7d5mFq2pw/L0jRcv3j9DgVYodzCOlnanfto3apfA6eN/Whw==} '@signalapp/mock-server@13.0.1': resolution: {integrity: sha512-1rT0fYyqEad64GnZRrFVhNsgKpPS+pvyyk8iOGUHqnqnf818yLIYHblS/5m/cNcvHyC/BBqdtgRHAsfGNqkuZw==} @@ -12460,7 +12460,7 @@ snapshots: type-fest: 4.26.1 uuid: 8.3.2 - '@signalapp/libsignal-client@0.74.1': + '@signalapp/libsignal-client@0.76.0': dependencies: node-gyp-build: 4.8.4 type-fest: 4.26.1 diff --git a/ts/Crypto.ts b/ts/Crypto.ts index 7f41f2caeff..7a0aeec605e 100644 --- a/ts/Crypto.ts +++ b/ts/Crypto.ts @@ -1,7 +1,6 @@ // Copyright 2020 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import { Buffer } from 'buffer'; import Long from 'long'; import { sample } from 'lodash'; import { Aci, Pni, hkdf } from '@signalapp/libsignal-client'; @@ -58,12 +57,7 @@ export function deriveSecrets( salt: Uint8Array, info: Uint8Array ): [Uint8Array, Uint8Array, Uint8Array] { - const output = hkdf( - 3 * 32, - Buffer.from(input), - Buffer.from(info), - Buffer.from(salt) - ); + const output = hkdf(3 * 32, input, info, salt); return [ output.subarray(0, 32), output.subarray(32, 64), @@ -198,12 +192,12 @@ export function deriveStorageItemKey({ return hkdf( STORAGE_SERVICE_ITEM_KEY_LEN, - Buffer.from(recordIkm), - Buffer.concat([ - Buffer.from(STORAGE_SERVICE_ITEM_KEY_INFO_PREFIX), - Buffer.from(key), + recordIkm, + Bytes.concatenate([ + Bytes.fromString(STORAGE_SERVICE_ITEM_KEY_INFO_PREFIX), + key, ]), - Buffer.alloc(0) + new Uint8Array(0) ); } @@ -547,7 +541,7 @@ export function padAndEncryptAttachment({ // We generate the plaintext hash here for forwards-compatibility with streaming // attachment encryption, which may be the only place that the whole attachment flows // through memory - plaintextHash: Buffer.from(sha256(plaintext)).toString('hex'), + plaintextHash: Bytes.toHex(sha256(plaintext)), }; } diff --git a/ts/Curve.ts b/ts/Curve.ts index 3015a7c197a..968c2a800b3 100644 --- a/ts/Curve.ts +++ b/ts/Curve.ts @@ -69,12 +69,7 @@ export function generateKyberPreKey( identityKeyPair.privateKey, keyPair.getPublicKey().serialize() ); - return client.KyberPreKeyRecord.new( - keyId, - Date.now(), - keyPair, - Buffer.from(signature) - ); + return client.KyberPreKeyRecord.new(keyId, Date.now(), keyPair, signature); } export function generateKeyPair(): KeyPairType { @@ -91,13 +86,11 @@ export function createKeyPair(incomingKey: Uint8Array): KeyPairType { log.warn('createKeyPair: incoming private key was not clamped!'); } - const incomingKeyBuffer = Buffer.from(incomingKey); - - if (incomingKeyBuffer.length !== 32) { + if (incomingKey.length !== 32) { throw new Error('key must be 32 bytes long'); } - const privKey = client.PrivateKey.deserialize(incomingKeyBuffer); + const privKey = client.PrivateKey.deserialize(incomingKey); const pubKey = privKey.getPublicKey(); return new client.IdentityKeyPair(pubKey, privKey); @@ -122,19 +115,14 @@ export function verifySignature( message: Uint8Array, signature: Uint8Array ): boolean { - const messageBuffer = Buffer.from(message); - const signatureBuffer = Buffer.from(signature); - - return pubKey.verify(messageBuffer, signatureBuffer); + return pubKey.verify(message, signature); } export function calculateSignature( privKey: client.PrivateKey, plaintext: Uint8Array ): Uint8Array { - const plaintextBuffer = Buffer.from(plaintext); - - return privKey.sign(plaintextBuffer); + return privKey.sign(plaintext); } function validatePubKeyFormat(pubKey: Uint8Array): Uint8Array { diff --git a/ts/LibSignalStores.ts b/ts/LibSignalStores.ts index 8aac5355216..c6c022de8ac 100644 --- a/ts/LibSignalStores.ts +++ b/ts/LibSignalStores.ts @@ -143,7 +143,7 @@ export class IdentityKeys extends IdentityKeyStore { return null; } - return PublicKey.deserialize(Buffer.from(key)); + return PublicKey.deserialize(key); } async saveIdentity( diff --git a/ts/SignalProtocolStore.ts b/ts/SignalProtocolStore.ts index a36cf657b61..00ba1b491f1 100644 --- a/ts/SignalProtocolStore.ts +++ b/ts/SignalProtocolStore.ts @@ -180,23 +180,23 @@ async function _fillCaches, HydratedType>( } export function hydrateSession(session: SessionType): SessionRecord { - return SessionRecord.deserialize(Buffer.from(session.record)); + return SessionRecord.deserialize(session.record); } export function hydratePublicKey(identityKey: IdentityKeyType): PublicKey { - return PublicKey.deserialize(Buffer.from(identityKey.publicKey)); + return PublicKey.deserialize(identityKey.publicKey); } export function hydratePreKey(preKey: PreKeyType): PreKeyRecord { - const publicKey = PublicKey.deserialize(Buffer.from(preKey.publicKey)); - const privateKey = PrivateKey.deserialize(Buffer.from(preKey.privateKey)); + const publicKey = PublicKey.deserialize(preKey.publicKey); + const privateKey = PrivateKey.deserialize(preKey.privateKey); return PreKeyRecord.new(preKey.keyId, publicKey, privateKey); } export function hydrateSignedPreKey( signedPreKey: SignedPreKeyType ): SignedPreKeyRecord { const createdAt = signedPreKey.created_at; - const pubKey = PublicKey.deserialize(Buffer.from(signedPreKey.publicKey)); - const privKey = PrivateKey.deserialize(Buffer.from(signedPreKey.privateKey)); - const signature = Buffer.from([]); + const pubKey = PublicKey.deserialize(signedPreKey.publicKey); + const privKey = PrivateKey.deserialize(signedPreKey.privateKey); + const signature = new Uint8Array(0); return SignedPreKeyRecord.new( signedPreKey.keyId, @@ -277,8 +277,8 @@ export class SignalProtocolStore extends EventEmitter { 'Invalid identity key serviceId' ); const { privKey, pubKey } = map.value[serviceId]; - const privateKey = PrivateKey.deserialize(Buffer.from(privKey)); - const publicKey = PublicKey.deserialize(Buffer.from(pubKey)); + const privateKey = PrivateKey.deserialize(privKey); + const publicKey = PublicKey.deserialize(pubKey); this.#ourIdentityKeys.set( serviceId, new IdentityKeyPair(publicKey, privateKey) @@ -374,7 +374,7 @@ export class SignalProtocolStore extends EventEmitter { return entry; } - const item = KyberPreKeyRecord.deserialize(Buffer.from(entry.fromDB.data)); + const item = KyberPreKeyRecord.deserialize(entry.fromDB.data); const newEntry = { hydrated: true as const, fromDB: entry.fromDB, @@ -932,9 +932,7 @@ export class SignalProtocolStore extends EventEmitter { return entry.item; } - const item = SenderKeyRecord.deserialize( - Buffer.from(entry.fromDB.data) - ); + const item = SenderKeyRecord.deserialize(entry.fromDB.data); this.senderKeys.set(id, { hydrated: true, item, @@ -2485,14 +2483,10 @@ export class SignalProtocolStore extends EventEmitter { const logId = `SignalProtocolStore.updateOurPniKeyMaterial(${pni})`; log.info(`${logId}: starting...`); - const identityKeyPair = IdentityKeyPair.deserialize( - Buffer.from(identityBytes) - ); - const signedPreKey = SignedPreKeyRecord.deserialize( - Buffer.from(signedPreKeyBytes) - ); + const identityKeyPair = IdentityKeyPair.deserialize(identityBytes); + const signedPreKey = SignedPreKeyRecord.deserialize(signedPreKeyBytes); const lastResortKyberPreKey = lastResortKyberPreKeyBytes - ? KyberPreKeyRecord.deserialize(Buffer.from(lastResortKyberPreKeyBytes)) + ? KyberPreKeyRecord.deserialize(lastResortKyberPreKeyBytes) : undefined; const { storage } = window; @@ -2636,13 +2630,10 @@ export class SignalProtocolStore extends EventEmitter { return false; } - const aciPublicKey = PublicKey.deserialize(Buffer.from(aciPublicKeyBytes)); - const pniPublicKey = PublicKey.deserialize(Buffer.from(pniPublicKeyBytes)); + const aciPublicKey = PublicKey.deserialize(aciPublicKeyBytes); + const pniPublicKey = PublicKey.deserialize(pniPublicKeyBytes); - return pniPublicKey.verifyAlternateIdentity( - aciPublicKey, - Buffer.from(signature) - ); + return pniPublicKey.verifyAlternateIdentity(aciPublicKey, signature); } #_getAllSessions(): Array { diff --git a/ts/jobs/helpers/sendResendRequest.ts b/ts/jobs/helpers/sendResendRequest.ts index 05c815d6bc1..eb0ae39777d 100644 --- a/ts/jobs/helpers/sendResendRequest.ts +++ b/ts/jobs/helpers/sendResendRequest.ts @@ -27,6 +27,7 @@ import { strictAssert } from '../../util/assert'; import type { DecryptionErrorEventData } from '../../textsecure/messageReceiverEvents'; import type { LoggerType } from '../../types/Logging'; import { startAutomaticSessionReset } from '../../util/handleRetry'; +import * as Bytes from '../../Bytes'; function failoverToLocalReset( logger: LoggerType, @@ -95,7 +96,7 @@ export async function sendResendRequest( } const plaintext = PlaintextContent.deserialize( - Buffer.from(plaintextBase64, 'base64') + Bytes.fromBase64(plaintextBase64) ); const { ContentHint } = Proto.UnidentifiedSenderMessage.Message; diff --git a/ts/jobs/helpers/sendSavedProto.ts b/ts/jobs/helpers/sendSavedProto.ts index 13ae726751c..55043549ace 100644 --- a/ts/jobs/helpers/sendSavedProto.ts +++ b/ts/jobs/helpers/sendSavedProto.ts @@ -20,6 +20,7 @@ import { OutgoingIdentityKeyError, UnregisteredUserError, } from '../../textsecure/Errors'; +import * as Bytes from '../../Bytes'; export async function sendSavedProto( conversation: ConversationModel, @@ -77,7 +78,7 @@ export async function sendSavedProto( const sendType = 'resendFromLog'; try { - const proto = Proto.Content.decode(Buffer.from(protoBase64, 'base64')); + const proto = Proto.Content.decode(Bytes.fromBase64(protoBase64)); await handleMessageSend( messaging.sendMessageProtoAndWait({ contentHint, diff --git a/ts/services/backups/credentials.ts b/ts/services/backups/credentials.ts index fe395cc79ac..3f5c66a40fa 100644 --- a/ts/services/backups/credentials.ts +++ b/ts/services/backups/credentials.ts @@ -11,6 +11,7 @@ import { } from '@signalapp/libsignal-client/zkgroup'; import { type BackupKey } from '@signalapp/libsignal-client/dist/AccountKeys'; +import * as Bytes from '../../Bytes'; import { createLogger } from '../../logging/log'; import { strictAssert } from '../../util/assert'; import { drop } from '../../util/drop'; @@ -92,20 +93,18 @@ export class BackupCredentials { ); } - const cred = new BackupAuthCredential( - Buffer.from(result.credential, 'base64') - ); + const cred = new BackupAuthCredential(Bytes.fromBase64(result.credential)); const serverPublicParams = new GenericServerPublicParams( - Buffer.from(window.getBackupServerPublicParams(), 'base64') + Bytes.fromBase64(window.getBackupServerPublicParams()) ); const presentation = cred.present(serverPublicParams).serialize(); const signature = signatureKey.sign(presentation); const headers = { - 'X-Signal-ZK-Auth': presentation.toString('base64'), - 'X-Signal-ZK-Auth-Signature': signature.toString('base64'), + 'X-Signal-ZK-Auth': Bytes.toBase64(presentation), + 'X-Signal-ZK-Auth-Signature': Bytes.toBase64(signature), }; const info = { headers, level: result.level }; @@ -274,7 +273,7 @@ export class BackupCredentials { ); const serverPublicParams = new GenericServerPublicParams( - Buffer.from(window.getBackupServerPublicParams(), 'base64') + Bytes.fromBase64(window.getBackupServerPublicParams()) ); const result = new Array(); @@ -300,7 +299,7 @@ export class BackupCredentials { credential: buf, redemptionTime, } of allCredentials) { - const credentialRes = new BackupAuthCredentialResponse(Buffer.from(buf)); + const credentialRes = new BackupAuthCredentialResponse(buf); const redemptionTimeMs = DurationInSeconds.toMillis(redemptionTime); strictAssert( @@ -326,7 +325,7 @@ export class BackupCredentials { result.push({ type, - credential: credential.serialize().toString('base64'), + credential: Bytes.toBase64(credential.serialize()), level: credential.getBackupLevel(), redemptionTimeMs, }); diff --git a/ts/services/backups/crypto.ts b/ts/services/backups/crypto.ts index 2b77b39572f..b0b79698c3c 100644 --- a/ts/services/backups/crypto.ts +++ b/ts/services/backups/crypto.ts @@ -28,7 +28,7 @@ export function getBackupMediaRootKey(): BackupKey { const rootKey = window.storage.get('backupMediaRootKey'); strictAssert(rootKey, 'Media root key not available'); - return new BackupKey(Buffer.from(rootKey)); + return new BackupKey(rootKey); } const getMemoizedBackupSignatureKey = memoizee( @@ -94,7 +94,7 @@ export function deriveBackupMediaKeyMaterial( throw new Error('deriveBackupMediaKeyMaterial: mediaId missing'); } - const material = mediaRootKey.deriveMediaEncryptionKey(Buffer.from(mediaId)); + const material = mediaRootKey.deriveMediaEncryptionKey(mediaId); return { macKey: material.subarray(0, BACKUP_MEDIA_MAC_KEY_LEN), @@ -113,9 +113,7 @@ export function deriveBackupThumbnailTransitKeyMaterial( throw new Error('deriveBackupThumbnailTransitKeyMaterial: mediaId missing'); } - const material = mediaRootKey.deriveThumbnailTransitEncryptionKey( - Buffer.from(mediaId) - ); + const material = mediaRootKey.deriveThumbnailTransitEncryptionKey(mediaId); return { macKey: material.subarray(0, BACKUP_MEDIA_MAC_KEY_LEN), diff --git a/ts/services/backups/import.ts b/ts/services/backups/import.ts index f2266ac0153..a27a394c4a5 100644 --- a/ts/services/backups/import.ts +++ b/ts/services/backups/import.ts @@ -1130,7 +1130,7 @@ export class BackupImportStream extends Writable { strictAssert(Bytes.isNotEmpty(userId), 'Empty gv2 member userId'); const serviceId = fromServiceIdObject( - ServiceId.parseFromServiceIdBinary(Buffer.from(userId)) + ServiceId.parseFromServiceIdBinary(userId) ); return { @@ -1163,7 +1163,7 @@ export class BackupImportStream extends Writable { // in the Contact frame const serviceId = fromServiceIdObject( - ServiceId.parseFromServiceIdBinary(Buffer.from(userId)) + ServiceId.parseFromServiceIdBinary(userId) ); return { @@ -2164,9 +2164,7 @@ export class BackupImportStream extends Writable { bodyRanges.map(range => ({ ...range, mentionAci: range.mentionAci - ? Aci.parseFromServiceIdBinary( - Buffer.from(range.mentionAci) - ).getServiceIdString() + ? Aci.parseFromServiceIdBinary(range.mentionAci).getServiceIdString() : undefined, })) ); @@ -2422,7 +2420,7 @@ export class BackupImportStream extends Writable { } const receipt = new ReceiptCredentialPresentation( - Buffer.from(giftBadge.receiptCredentialPresentation) + giftBadge.receiptCredentialPresentation ); return { @@ -2901,7 +2899,7 @@ export class BackupImportStream extends Writable { details.push({ type: 'pending-add-one', serviceId: fromServiceIdObject( - ServiceId.parseFromServiceIdBinary(Buffer.from(inviteeServiceId)) + ServiceId.parseFromServiceIdBinary(inviteeServiceId) ), }); } diff --git a/ts/services/backups/index.ts b/ts/services/backups/index.ts index e73731e4a94..8aa3a490818 100644 --- a/ts/services/backups/index.ts +++ b/ts/services/backups/index.ts @@ -579,7 +579,7 @@ export class BackupsService { ); if (backupType === BackupType.Ciphertext) { const { aesKey, macKey } = getKeyMaterial( - ephemeralKey ? new BackupKey(Buffer.from(ephemeralKey)) : undefined + ephemeralKey ? new BackupKey(ephemeralKey) : undefined ); // First pass - don't decrypt, only verify mac diff --git a/ts/services/backups/validator.ts b/ts/services/backups/validator.ts index 51bba6a6e18..92d01be4ab6 100644 --- a/ts/services/backups/validator.ts +++ b/ts/services/backups/validator.ts @@ -61,7 +61,7 @@ export async function validateBackupStream( frameCount += 1; const reader = new Reader(delimitedFrame); - const frame = Buffer.from(reader.bytes()); + const frame = reader.bytes(); // Info frame if (frameCount === 1) { diff --git a/ts/services/calling.ts b/ts/services/calling.ts index 283602984ea..69c676df042 100644 --- a/ts/services/calling.ts +++ b/ts/services/calling.ts @@ -764,11 +764,11 @@ export class CallingClass { ); const response = new CreateCallLinkCredentialResponse( - Buffer.from(credentialBase64, 'base64') + Bytes.fromBase64(credentialBase64) ); const genericServerPublicParams = new GenericServerPublicParams( - Buffer.from(window.getGenericServerPublicParams(), 'base64') + Bytes.fromBase64(window.getGenericServerPublicParams()) ); const credential = context.receive( response, @@ -785,10 +785,10 @@ export class CallingClass { const result = await RingRTC.createCallLink( sfuUrl, - credentialPresentation, + Buffer.from(credentialPresentation), rootKey, adminKey, - serializedPublicParams, + Buffer.from(serializedPublicParams), CallLinkRestrictions.AdminApproval ); @@ -832,7 +832,7 @@ export class CallingClass { const result = await RingRTC.deleteCallLink( sfuUrl, - authCredentialPresentation.serialize(), + Buffer.from(authCredentialPresentation.serialize()), callLinkRootKey, undefined, callLinkAdminKey @@ -869,7 +869,7 @@ export class CallingClass { await getCallLinkAuthCredentialPresentation(callLinkRootKey); const result = await RingRTC.updateCallLinkName( sfuUrl, - authCredentialPresentation.serialize(), + Buffer.from(authCredentialPresentation.serialize()), callLinkRootKey, undefined, callLinkAdminKey, @@ -915,7 +915,7 @@ export class CallingClass { const result = await RingRTC.updateCallLinkRestrictions( sfuUrl, - authCredentialPresentation.serialize(), + Buffer.from(authCredentialPresentation.serialize()), callLinkRootKey, undefined, callLinkAdminKey, @@ -950,7 +950,7 @@ export class CallingClass { const result = await RingRTC.readCallLink( this._sfuUrl, - authCredentialPresentation.serialize(), + Buffer.from(authCredentialPresentation.serialize()), callLinkRootKey, undefined ); @@ -1246,7 +1246,7 @@ export class CallingClass { const result = await RingRTC.peekCallLinkCall( this._sfuUrl, - authCredentialPresentation.serialize(), + Buffer.from(authCredentialPresentation.serialize()), callLinkRootKey, undefined ); @@ -1380,7 +1380,7 @@ export class CallingClass { const outerGroupCall = RingRTC.getCallLinkCall( this._sfuUrl, - authCredentialPresentation.serialize(), + Buffer.from(authCredentialPresentation.serialize()), callLinkRootKey, undefined, adminPasskey, diff --git a/ts/services/groupCredentialFetcher.ts b/ts/services/groupCredentialFetcher.ts index 37cda953931..c04069a09ac 100644 --- a/ts/services/groupCredentialFetcher.ts +++ b/ts/services/groupCredentialFetcher.ts @@ -19,6 +19,7 @@ import { toDayMillis } from '../util/timestamp'; import { toTaggedPni } from '../types/ServiceId'; import { toPniObject, toAciObject } from '../util/ServiceId'; import { createLogger } from '../logging/log'; +import * as Bytes from '../Bytes'; const log = createLogger('groupCredentialFetcher'); @@ -221,11 +222,9 @@ export async function maybeFetchNewCredentials(): Promise { toAciObject(aci), toPniObject(pni), item.redemptionTime, - new AuthCredentialWithPniResponse( - Buffer.from(item.credential, 'base64') - ) + new AuthCredentialWithPniResponse(Bytes.fromBase64(item.credential)) ); - const credential = authCredential.serialize().toString('base64'); + const credential = Bytes.toBase64(authCredential.serialize()); return { redemptionTime: item.redemptionTime * durations.SECOND, @@ -237,21 +236,21 @@ export async function maybeFetchNewCredentials(): Promise { sortCredentials(rawCredentials).map(formatCredential); const genericServerPublicParamsBase64 = window.getGenericServerPublicParams(); const genericServerPublicParams = new GenericServerPublicParams( - Buffer.from(genericServerPublicParamsBase64, 'base64') + Bytes.fromBase64(genericServerPublicParamsBase64) ); function formatCallingCredential( item: GroupCredentialType ): GroupCredentialType { const response = new CallLinkAuthCredentialResponse( - Buffer.from(item.credential, 'base64') + Bytes.fromBase64(item.credential) ); const authCredential = response.receive( toAciObject(aci), item.redemptionTime, genericServerPublicParams ); - const credential = authCredential.serialize().toString('base64'); + const credential = Bytes.toBase64(authCredential.serialize()); return { redemptionTime: item.redemptionTime * durations.SECOND, diff --git a/ts/services/username.ts b/ts/services/username.ts index 807f810db2c..511fdc78aa3 100644 --- a/ts/services/username.ts +++ b/ts/services/username.ts @@ -119,7 +119,7 @@ export async function reserveUsername( abortSignal, }); - const index = hashes.findIndex(hash => hash.equals(usernameHash)); + const index = hashes.findIndex(hash => Bytes.areEqual(hash, usernameHash)); if (index === -1) { log.warn('reserveUsername: failed to find username hash in the response'); return { ok: false, error: ReserveUsernameError.Unprocessable }; @@ -244,7 +244,10 @@ export async function confirmUsername( } const { hash } = reservation; - strictAssert(usernames.hash(username).equals(hash), 'username hash mismatch'); + strictAssert( + Bytes.areEqual(usernames.hash(username), hash), + 'username hash mismatch' + ); const wasCorrupted = window.storage.get('usernameCorrupted'); @@ -252,13 +255,13 @@ export async function confirmUsername( await window.storage.remove('usernameLink'); let serverIdString: string; - let entropy: Buffer; + let entropy: Uint8Array; if (previousLink && isCaseChange(reservation)) { log.info('confirmUsername: updating link only'); const updatedLink = usernames.createUsernameLink( username, - Buffer.from(previousLink.entropy) + previousLink.entropy ); ({ entropy } = updatedLink); @@ -401,8 +404,8 @@ export async function resolveUsernameByLink({ await server.resolveUsernameLink(serverId); return usernames.decryptUsernameLink({ - entropy: Buffer.from(entropy), - encryptedUsername: Buffer.from(usernameLinkEncryptedValue), + entropy, + encryptedUsername: usernameLinkEncryptedValue, }); } catch (error) { if (error instanceof HTTPError && error.code === 404) { diff --git a/ts/services/usernameIntegrity.ts b/ts/services/usernameIntegrity.ts index 30012d46f00..8e207605390 100644 --- a/ts/services/usernameIntegrity.ts +++ b/ts/services/usernameIntegrity.ts @@ -17,6 +17,7 @@ import { getProfile } from '../util/getProfile'; import { isSharingPhoneNumberWithEverybody } from '../util/phoneNumberSharingMode'; import { bytesToUuid } from '../util/uuidToBytes'; import { createLogger } from '../logging/log'; +import * as Bytes from '../Bytes'; import { runStorageServiceSyncJob } from './storage'; import { writeProfile } from './writeProfile'; @@ -101,7 +102,7 @@ class UsernameIntegrityService { let failed = false; - if (remoteHash !== usernames.hash(username).toString('base64url')) { + if (remoteHash !== Bytes.toBase64url(usernames.hash(username))) { log.error('remote username mismatch'); await window.storage.put('usernameCorrupted', true); failed = true; diff --git a/ts/test-electron/backup/integration_test.ts b/ts/test-electron/backup/integration_test.ts index 8e3b3eb98d1..72d83aa5718 100644 --- a/ts/test-electron/backup/integration_test.ts +++ b/ts/test-electron/backup/integration_test.ts @@ -41,7 +41,7 @@ describe('backup/integration', () => { const files = readdirSync(BACKUP_INTEGRATION_DIR) .filter(file => file.endsWith('.binproto')) // TODO: DESKTOP-8906 - .filter(file => file !== 'chat_item_view_once_00.binproto') + .filter(file => file !== 'chat_item_view_once_07.binproto') .map(file => join(BACKUP_INTEGRATION_DIR, file)); if (files.length === 0) { diff --git a/ts/test-helpers/generateBackup.ts b/ts/test-helpers/generateBackup.ts index bb2beb71659..78ec2246c4c 100644 --- a/ts/test-helpers/generateBackup.ts +++ b/ts/test-helpers/generateBackup.ts @@ -25,17 +25,17 @@ import { Backups } from '../protobuf'; export type BackupGeneratorConfigType = Readonly< { aci: AciString; - profileKey: Buffer; + profileKey: Uint8Array; conversations: number; conversationAcis?: ReadonlyArray; messages: number; - mediaRootBackupKey: Buffer; + mediaRootBackupKey: Uint8Array; } & ( | { accountEntropyPool: string; } | { - backupKey: Buffer; + backupKey: Uint8Array; } ) >; @@ -43,7 +43,7 @@ export type BackupGeneratorConfigType = Readonly< const IV_LENGTH = 16; export type GenerateBackupResultType = Readonly<{ - backupId: Buffer; + backupId: Uint8Array; stream: Readable; }>; @@ -145,7 +145,7 @@ function* createRecords({ const chats = new Array<{ id: Long; - aci: Buffer; + aci: Uint8Array; }>(); for (let i = 1; i <= conversations; i += 1) { diff --git a/ts/textsecure/AccountManager.ts b/ts/textsecure/AccountManager.ts index 7dd07406dcd..c8b687c6641 100644 --- a/ts/textsecure/AccountManager.ts +++ b/ts/textsecure/AccountManager.ts @@ -289,9 +289,7 @@ export default class AccountManager extends EventTarget { const name = decryptDeviceName( { - ephemeralPublic: PublicKey.deserialize( - Buffer.from(proto.ephemeralPublic) - ), + ephemeralPublic: PublicKey.deserialize(proto.ephemeralPublic), syntheticIv: proto.syntheticIv, ciphertext: proto.ciphertext, }, diff --git a/ts/textsecure/MessageReceiver.ts b/ts/textsecure/MessageReceiver.ts index 84094348459..7ab4864b6a7 100644 --- a/ts/textsecure/MessageReceiver.ts +++ b/ts/textsecure/MessageReceiver.ts @@ -321,7 +321,7 @@ export default class MessageReceiver throw new Error('Server trust root is required!'); } this.#serverTrustRoot = PublicKey.deserialize( - Buffer.from(Bytes.fromBase64(serverTrustRoot)) + Bytes.fromBase64(serverTrustRoot) ); this.#incomingQueue = new PQueue({ @@ -1351,7 +1351,7 @@ export default class MessageReceiver log.info(`unsealEnvelope(${logId}): unidentified message`); const messageContent = await sealedSenderDecryptToUsmc( - Buffer.from(ciphertext), + ciphertext, stores.identityKeyStore ); @@ -1362,6 +1362,8 @@ export default class MessageReceiver const originalSource = envelope.source; const originalSourceUuid = envelope.sourceServiceId; + const groupId = messageContent.groupId(); + const newEnvelope: UnsealedEnvelope = { ...envelope, @@ -1379,7 +1381,7 @@ export default class MessageReceiver // UnsealedEnvelope-only fields unidentifiedDeliveryReceived: !(originalSource || originalSourceUuid), contentHint: messageContent.contentHint(), - groupId: messageContent.groupId()?.toString('base64'), + groupId: groupId ? Bytes.toBase64(groupId) : undefined, certificate, unsealedContent: messageContent, }; @@ -1845,8 +1847,7 @@ export default class MessageReceiver if (envelope.type === envelopeTypeEnum.PLAINTEXT_CONTENT) { log.info(`decrypt/${logId}: plaintext message`); - const buffer = Buffer.from(ciphertext); - const plaintextContent = PlaintextContent.deserialize(buffer); + const plaintextContent = PlaintextContent.deserialize(ciphertext); return { plaintext: this.#unpad(plaintextContent.body()), @@ -1865,7 +1866,7 @@ export default class MessageReceiver 'MessageReceiver.innerDecrypt: No sourceDevice for CIPHERTEXT message' ); } - const signalMessage = SignalMessage.deserialize(Buffer.from(ciphertext)); + const signalMessage = SignalMessage.deserialize(ciphertext); const plaintext = await this.#storage.protocol.enqueueSessionJob( address, @@ -1894,9 +1895,7 @@ export default class MessageReceiver 'MessageReceiver.innerDecrypt: No sourceDevice for PREKEY_BUNDLE message' ); } - const preKeySignalMessage = PreKeySignalMessage.deserialize( - Buffer.from(ciphertext) - ); + const preKeySignalMessage = PreKeySignalMessage.deserialize(ciphertext); const plaintext = await this.#storage.protocol.enqueueSessionJob( address, @@ -2619,8 +2618,7 @@ export default class MessageReceiver logUnexpectedUrgentValue(envelope, 'retryRequest'); - const buffer = Buffer.from(decryptionError); - const request = DecryptionErrorMessage.deserialize(buffer); + const request = DecryptionErrorMessage.deserialize(decryptionError); const { sourceServiceId: sourceAci, sourceDevice } = envelope; if (!sourceAci || !sourceDevice) { @@ -2672,9 +2670,7 @@ export default class MessageReceiver const sender = ProtocolAddress.new(sourceServiceId, sourceDevice); const senderKeyDistributionMessage = - SenderKeyDistributionMessage.deserialize( - Buffer.from(distributionMessage) - ); + SenderKeyDistributionMessage.deserialize(distributionMessage); const { destinationServiceId } = envelope; const address = new QualifiedAddress( destinationServiceId, @@ -2708,7 +2704,7 @@ export default class MessageReceiver const { pni: pniBytes, signature } = pniSignatureMessage; strictAssert(Bytes.isNotEmpty(pniBytes), `${logId}: missing PNI bytes`); - const pni = fromPniObject(Pni.fromUuidBytes(Buffer.from(pniBytes))); + const pni = fromPniObject(Pni.fromUuidBytes(pniBytes)); strictAssert(pni, `${logId}: missing PNI`); strictAssert(Bytes.isNotEmpty(signature), `${logId}: empty signature`); strictAssert(isAciString(aci), `${logId}: invalid ACI`); @@ -4153,7 +4149,7 @@ function processConversationIdentifier( if (threadGroupId) { return { type: 'group' as const, - groupId: Buffer.from(threadGroupId).toString('base64'), + groupId: Bytes.toBase64(threadGroupId), }; } if (threadE164) { diff --git a/ts/textsecure/OutgoingMessage.ts b/ts/textsecure/OutgoingMessage.ts index a90710806be..4dfbec35c99 100644 --- a/ts/textsecure/OutgoingMessage.ts +++ b/ts/textsecure/OutgoingMessage.ts @@ -44,6 +44,7 @@ import { SignalService as Proto } from '../protobuf'; import { createLogger } from '../logging/log'; import type { GroupSendToken } from '../types/GroupSendEndorsements'; import { isSignalServiceId } from '../util/isSignalConversation'; +import * as Bytes from '../Bytes'; const log = createLogger('OutgoingMessage'); @@ -388,7 +389,7 @@ export default class OutgoingMessage { if (message instanceof Proto.Content) { return signalEncrypt( - Buffer.from(this.getPlaintext()), + this.getPlaintext(), protocolAddress, sessionStore, identityKeyStore @@ -472,10 +473,10 @@ export default class OutgoingMessage { }); const certificate = SenderCertificate.deserialize( - Buffer.from(senderCertificate.serialized) + senderCertificate.serialized ); const groupIdBuffer = this.groupId - ? Buffer.from(this.groupId, 'base64') + ? Bytes.fromBase64(this.groupId) : null; const content = UnidentifiedSenderMessageContent.new( @@ -495,7 +496,7 @@ export default class OutgoingMessage { type: Proto.Envelope.Type.UNIDENTIFIED_SENDER, destinationDeviceId, destinationRegistrationId, - content: buffer.toString('base64'), + content: Bytes.toBase64(buffer), }; } @@ -508,7 +509,7 @@ export default class OutgoingMessage { ciphertextMessage.type() ); - const content = ciphertextMessage.serialize().toString('base64'); + const content = Bytes.toBase64(ciphertextMessage.serialize()); return { type, diff --git a/ts/textsecure/ProvisioningCipher.ts b/ts/textsecure/ProvisioningCipher.ts index f05426652d8..a003b7867a0 100644 --- a/ts/textsecure/ProvisioningCipher.ts +++ b/ts/textsecure/ProvisioningCipher.ts @@ -67,7 +67,7 @@ class ProvisioningCipherInner { } const ecRes = calculateAgreement( - PublicKey.deserialize(Buffer.from(masterEphemeral)), + PublicKey.deserialize(masterEphemeral), this.keyPair.privateKey ); const keys = deriveSecrets( diff --git a/ts/textsecure/SendMessage.ts b/ts/textsecure/SendMessage.ts index 7f90304703f..f8937fd2c68 100644 --- a/ts/textsecure/SendMessage.ts +++ b/ts/textsecure/SendMessage.ts @@ -2176,7 +2176,7 @@ export default class MessageSender { }: Readonly<{ contentHint: number; messageId?: string; - proto: Buffer; + proto: Uint8Array; sendType: SendTypesType; timestamp: number; urgent: boolean; @@ -2402,7 +2402,7 @@ export default class MessageSender { serviceIds.length > 1 ? this.makeSendLogCallback({ contentHint: contentHint ?? ContentHint.IMPLICIT, - proto: Buffer.from(Proto.Content.encode(contentMessage).finish()), + proto: Proto.Content.encode(contentMessage).finish(), sendType: 'senderKeyDistributionMessage', timestamp, urgent, diff --git a/ts/textsecure/WebAPI.ts b/ts/textsecure/WebAPI.ts index e899c394d71..781e3bb477a 100644 --- a/ts/textsecure/WebAPI.ts +++ b/ts/textsecure/WebAPI.ts @@ -3235,10 +3235,14 @@ export function initialize({ keyId: number; publicKey: K; signature: Uint8Array; - }): { id: () => number; publicKey: () => K; signature: () => Buffer } { + }): { + id: () => number; + publicKey: () => K; + signature: () => Uint8Array; + } { return { id: () => key.keyId, - signature: () => Buffer.from(key.signature), + signature: () => key.signature, publicKey: () => key.publicKey, }; } @@ -4093,22 +4097,21 @@ export function initialize({ ].join(CRLF); const end = `${CRLF}--${boundaryString}--${CRLF}`; - const startBuffer = Buffer.from(start, 'utf8'); - const attachmentBuffer = Buffer.from(encryptedBin); - const endBuffer = Buffer.from(end, 'utf8'); + const startBuffer = Bytes.fromString(start); + const attachmentBuffer = encryptedBin; + const endBuffer = Bytes.fromString(end); - const contentLength = - startBuffer.length + attachmentBuffer.length + endBuffer.length; - const data = Buffer.concat( - [startBuffer, attachmentBuffer, endBuffer], - contentLength - ); + const data = Bytes.concatenate([ + startBuffer, + attachmentBuffer, + endBuffer, + ]); return { data, contentType: `multipart/form-data; boundary=${boundaryString}`, headers: { - 'Content-Length': contentLength.toString(), + 'Content-Length': data.length.toString(), }, }; } diff --git a/ts/textsecure/cds/CDSISocket.ts b/ts/textsecure/cds/CDSISocket.ts index 90a9cfcbaa4..d71b1e6217d 100644 --- a/ts/textsecure/cds/CDSISocket.ts +++ b/ts/textsecure/cds/CDSISocket.ts @@ -9,7 +9,7 @@ import { CDSSocketBase, CDSSocketState } from './CDSSocketBase'; import type { CDSSocketBaseOptionsType } from './CDSSocketBase'; export type CDSISocketOptionsType = Readonly<{ - mrenclave: Buffer; + mrenclave: Uint8Array; }> & CDSSocketBaseOptionsType; @@ -41,7 +41,7 @@ export class CDSISocket extends CDSSocketBase { ); } - this.socket.sendBytes(this.#cdsClient.initialRequest()); + this.socket.sendBytes(Buffer.from(this.#cdsClient.initialRequest())); { const { done, value: message } = await this.socketIterator.next(); @@ -55,9 +55,11 @@ export class CDSISocket extends CDSSocketBase { protected override async sendRequest( _version: number, - request: Buffer + request: Uint8Array ): Promise { - this.socket.sendBytes(this.#cdsClient.establishedSend(request)); + this.socket.sendBytes( + Buffer.from(this.#cdsClient.establishedSend(request)) + ); const { done, value: ciphertext } = await this.socketIterator.next(); strictAssert(!done, 'CDSISocket.sendRequest(): expected token message'); @@ -70,8 +72,8 @@ export class CDSISocket extends CDSSocketBase { strictAssert(token, 'CDSISocket.sendRequest(): expected token'); this.socket.sendBytes( - this.#cdsClient.establishedSend( - Buffer.from( + Buffer.from( + this.#cdsClient.establishedSend( Proto.CDSClientRequest.encode({ tokenAck: true, }).finish() @@ -81,8 +83,8 @@ export class CDSISocket extends CDSSocketBase { } protected override async decryptResponse( - ciphertext: Buffer - ): Promise { + ciphertext: Uint8Array + ): Promise { return this.#cdsClient.establishedRecv(ciphertext); } diff --git a/ts/textsecure/cds/CDSSocketBase.ts b/ts/textsecure/cds/CDSSocketBase.ts index 28117c2bf87..8f085bd1675 100644 --- a/ts/textsecure/cds/CDSSocketBase.ts +++ b/ts/textsecure/cds/CDSSocketBase.ts @@ -47,7 +47,7 @@ export abstract class CDSSocketBase< protected readonly logger: LoggerType; - protected readonly socketIterator: AsyncIterator; + protected readonly socketIterator: AsyncIterator; constructor(protected readonly options: Options) { super(); @@ -87,18 +87,18 @@ export abstract class CDSSocketBase< ); const request = Proto.CDSClientRequest.encode({ - newE164s: Buffer.concat( + newE164s: Bytes.concatenate( e164s.map(e164 => { // Long.fromString handles numbers with or without a leading '+' return new Uint8Array(Long.fromString(e164).toBytesBE()); }) ), - aciUakPairs: Buffer.concat(aciUakPairs), + aciUakPairs: Bytes.concatenate(aciUakPairs), returnAcisWithoutUaks, }).finish(); log.info(`CDSSocket.request(): sending version=${version} request`); - await this.sendRequest(version, Buffer.from(request)); + await this.sendRequest(version, request); const resultMap: Map = new Map(); @@ -129,9 +129,14 @@ export abstract class CDSSocketBase< public abstract handshake(): Promise; - protected abstract sendRequest(version: number, data: Buffer): Promise; + protected abstract sendRequest( + version: number, + data: Uint8Array + ): Promise; - protected abstract decryptResponse(ciphertext: Buffer): Promise; + protected abstract decryptResponse( + ciphertext: Uint8Array + ): Promise; // EventEmitter types @@ -161,7 +166,7 @@ export abstract class CDSSocketBase< // Private // - #iterateSocket(): AsyncIterator { + #iterateSocket(): AsyncIterator { const stream = new Readable({ read: noop, objectMode: true }); this.socket.on('message', ({ type, binaryData }) => { diff --git a/ts/textsecure/getKeysForServiceId.ts b/ts/textsecure/getKeysForServiceId.ts index d2366596a47..ee6eb658900 100644 --- a/ts/textsecure/getKeysForServiceId.ts +++ b/ts/textsecure/getKeysForServiceId.ts @@ -152,20 +152,13 @@ async function handleServerKeys( const protocolAddress = ProtocolAddress.new(serviceId, deviceId); const preKeyId = preKey?.keyId || null; const preKeyObject = preKey - ? PublicKey.deserialize(Buffer.from(preKey.publicKey)) + ? PublicKey.deserialize(preKey.publicKey) : null; - const signedPreKeyObject = PublicKey.deserialize( - Buffer.from(signedPreKey.publicKey) - ); - const identityKey = PublicKey.deserialize( - Buffer.from(response.identityKey) - ); + const signedPreKeyObject = PublicKey.deserialize(signedPreKey.publicKey); + const identityKey = PublicKey.deserialize(response.identityKey); - const pqPreKeyId = pqPreKey.keyId; - const pqPreKeyPublic = KEMPublicKey.deserialize( - Buffer.from(pqPreKey.publicKey) - ); - const pqPreKeySignature = Buffer.from(pqPreKey.signature); + const { keyId: pqPreKeyId, signature: pqPreKeySignature } = pqPreKey; + const pqPreKeyPublic = KEMPublicKey.deserialize(pqPreKey.publicKey); const preKeyBundle = PreKeyBundle.new( registrationId, @@ -174,7 +167,7 @@ async function handleServerKeys( preKeyObject, signedPreKey.keyId, signedPreKeyObject, - Buffer.from(signedPreKey.signature), + signedPreKey.signature, identityKey, pqPreKeyId, pqPreKeyPublic, diff --git a/ts/textsecure/processDataMessage.ts b/ts/textsecure/processDataMessage.ts index 600dbfbe704..a40f656677f 100644 --- a/ts/textsecure/processDataMessage.ts +++ b/ts/textsecure/processDataMessage.ts @@ -333,7 +333,7 @@ export function processGiftBadge( } const receipt = new ReceiptCredentialPresentation( - Buffer.from(giftBadge.receiptCredentialPresentation) + giftBadge.receiptCredentialPresentation ); return { diff --git a/ts/updater/curve.ts b/ts/updater/curve.ts index 352dda1ec3d..1e7fb945693 100644 --- a/ts/updater/curve.ts +++ b/ts/updater/curve.ts @@ -3,7 +3,7 @@ import { PrivateKey, PublicKey } from '@signalapp/libsignal-client'; -export function keyPair(): Record { +export function keyPair(): Record { const privKey = PrivateKey.generate(); const pubKey = privKey.getPublicKey(); @@ -13,16 +13,16 @@ export function keyPair(): Record { }; } -export function sign(privateKey: Buffer, message: Buffer): Buffer { +export function sign(privateKey: Uint8Array, message: Uint8Array): Uint8Array { const privKeyObj = PrivateKey.deserialize(privateKey); const signature = privKeyObj.sign(message); return signature; } export function verify( - publicKey: Buffer, - message: Buffer, - signature: Buffer + publicKey: Uint8Array, + message: Uint8Array, + signature: Uint8Array ): boolean { const pubKeyObj = PublicKey.deserialize(publicKey); const result = pubKeyObj.verify(message, signature); diff --git a/ts/updater/signature.ts b/ts/updater/signature.ts index 0a5294636ce..a33849d09af 100644 --- a/ts/updater/signature.ts +++ b/ts/updater/signature.ts @@ -21,7 +21,7 @@ export async function generateSignature( updatePackagePath: string, version: string, privateKeyPath: string -): Promise { +): Promise { const privateKey = await loadHexFromPath(privateKeyPath); const message = await generateMessage(updatePackagePath, version); @@ -31,8 +31,8 @@ export async function generateSignature( export async function verifySignature( updatePackagePath: string, version: string, - signature: Buffer, - publicKey: Buffer + signature: Uint8Array, + publicKey: Uint8Array ): Promise { const message = await generateMessage(updatePackagePath, version); @@ -44,7 +44,7 @@ export async function verifySignature( async function generateMessage( updatePackagePath: string, version: string -): Promise { +): Promise { const hash = await _getFileHash(updatePackagePath); const messageString = `${Buffer.from(hash).toString('hex')}-${version}`; @@ -55,7 +55,7 @@ export async function writeSignature( updatePackagePath: string, version: string, privateKeyPath: string -): Promise { +): Promise { const signaturePath = getSignaturePath(updatePackagePath); const signature = await generateSignature( updatePackagePath, @@ -90,7 +90,7 @@ export function hexToBinary(target: string): Buffer { return Buffer.from(target, 'hex'); } -export function binaryToHex(data: Buffer): string { +export function binaryToHex(data: Uint8Array): string { return Buffer.from(data).toString('hex'); } @@ -102,7 +102,7 @@ export async function loadHexFromPath(target: string): Promise { export async function writeHexToPath( target: string, - data: Buffer + data: Uint8Array ): Promise { await writeFile(target, binaryToHex(data)); } diff --git a/ts/util/ServiceId.ts b/ts/util/ServiceId.ts index 0ebd08aae12..083bd141ccb 100644 --- a/ts/util/ServiceId.ts +++ b/ts/util/ServiceId.ts @@ -45,9 +45,7 @@ export function fromServiceIdBinaryOrString( context: string ): ServiceIdString | undefined { if (Bytes.isNotEmpty(bytes)) { - return fromServiceIdObject( - ServiceId.parseFromServiceIdBinary(Buffer.from(bytes)) - ); + return fromServiceIdObject(ServiceId.parseFromServiceIdBinary(bytes)); } if (fallback) { return normalizeServiceId(fallback, context); @@ -65,7 +63,7 @@ export function fromAciUuidBytes( bytes: Uint8Array | undefined | null ): AciString | undefined { if (Bytes.isNotEmpty(bytes)) { - return fromAciObject(Aci.fromUuidBytes(Buffer.from(bytes))); + return fromAciObject(Aci.fromUuidBytes(bytes)); } return undefined; } @@ -102,7 +100,7 @@ export function fromPniUuidBytesOrUntaggedString( context: string ): PniString | undefined { if (Bytes.isNotEmpty(bytes)) { - return fromPniObject(Pni.fromUuidBytes(Buffer.from(bytes))); + return fromPniObject(Pni.fromUuidBytes(bytes)); } if (fallback && isUntaggedPniString(fallback)) { return normalizePni(toTaggedPni(fallback), context); diff --git a/ts/util/groupSendEndorsements.ts b/ts/util/groupSendEndorsements.ts index 8606121140c..dd7252bee00 100644 --- a/ts/util/groupSendEndorsements.ts +++ b/ts/util/groupSendEndorsements.ts @@ -31,6 +31,7 @@ import { isNightly } from './version'; import { parseStrict } from './schemas'; import { DataReader } from '../sql/Client'; import { maybeUpdateGroup } from '../groups'; +import * as Bytes from '../Bytes'; import { isGroupV2 } from './whatTypeOfConversation'; const log = createLogger('groupSendEndorsements'); @@ -59,7 +60,7 @@ export function decodeGroupSendEndorsementResponse({ ); const response = new GroupSendEndorsementsResponse( - Buffer.from(groupSendEndorsementResponse) + groupSendEndorsementResponse ); const expiration = response.getExpiration().getTime() / 1000; @@ -69,11 +70,11 @@ export function decodeGroupSendEndorsementResponse({ ); const groupSecretParams = new GroupSecretParams( - Buffer.from(groupSecretParamsBase64, 'base64') + Bytes.fromBase64(groupSecretParamsBase64) ); const serverPublicParams = new ServerPublicParams( - Buffer.from(window.getServerPublicParams(), 'base64') + Bytes.fromBase64(window.getServerPublicParams()) ); const groupMembers = groupMembersV2.map(member => { @@ -193,7 +194,7 @@ export class GroupSendEndorsementState { #toEndorsement(contents: Uint8Array): GroupSendEndorsement { let endorsement = this.#endorsementCache.get(contents); if (endorsement == null) { - endorsement = new GroupSendEndorsement(Buffer.from(contents)); + endorsement = new GroupSendEndorsement(contents); this.#endorsementCache.set(contents, endorsement); } return endorsement; @@ -201,7 +202,7 @@ export class GroupSendEndorsementState { #toToken(endorsement: GroupSendEndorsement): GroupSendToken { const groupSecretParams = new GroupSecretParams( - Buffer.from(this.#groupSecretParamsBase64, 'base64') + Bytes.fromBase64(this.#groupSecretParamsBase64) ); const expiration = this.getExpiration(); diff --git a/ts/util/handleMessageSend.ts b/ts/util/handleMessageSend.ts index 9fca8971f43..57022fb5b90 100644 --- a/ts/util/handleMessageSend.ts +++ b/ts/util/handleMessageSend.ts @@ -269,7 +269,7 @@ async function maybeSaveToSendLog( await insertSentProto( { timestamp, - proto: Buffer.from(contentProto), + proto: contentProto, contentHint, urgent: isBoolean(urgent) ? urgent : true, hasPniSignatureMessage: Boolean(hasPniSignatureMessage), diff --git a/ts/util/handleRetry.ts b/ts/util/handleRetry.ts index 07476943bde..bf68c0ab870 100644 --- a/ts/util/handleRetry.ts +++ b/ts/util/handleRetry.ts @@ -678,7 +678,7 @@ async function requestResend(decryptionError: DecryptionErrorEventData) { } const message = DecryptionErrorMessage.forOriginal( - Buffer.from(cipherTextBytes), + cipherTextBytes, cipherTextType, timestamp, senderDevice diff --git a/ts/util/lookupConversationWithoutServiceId.ts b/ts/util/lookupConversationWithoutServiceId.ts index 02322debfdf..be5c64c430e 100644 --- a/ts/util/lookupConversationWithoutServiceId.ts +++ b/ts/util/lookupConversationWithoutServiceId.ts @@ -143,7 +143,7 @@ export async function lookupConversationWithoutServiceId( export async function checkForUsername( username: string ): Promise { - let hash: Buffer; + let hash: Uint8Array; let fixedUsername = username; if (fixedUsername.startsWith('@')) { fixedUsername = fixedUsername.slice(1); diff --git a/ts/util/pemToDer.ts b/ts/util/pemToDer.ts index 12040e56568..40c9126c61b 100644 --- a/ts/util/pemToDer.ts +++ b/ts/util/pemToDer.ts @@ -1,11 +1,13 @@ // Copyright 2024 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -export function pemToDer(pem: string): Buffer { +import * as Bytes from '../Bytes'; + +export function pemToDer(pem: string): Uint8Array { const pemContent = pem .replace(/-----BEGIN [^-]+-----/, '') .replace(/-----END [^-]+-----/, '') .replace(/\s+/g, ''); - const derBuffer = Buffer.from(pemContent, 'base64'); + const derBuffer = Bytes.fromBase64(pemContent); return derBuffer; } diff --git a/ts/util/safetyNumber.ts b/ts/util/safetyNumber.ts index ad95f8a198d..a9b4d839e3f 100644 --- a/ts/util/safetyNumber.ts +++ b/ts/util/safetyNumber.ts @@ -46,16 +46,16 @@ export async function generateSafetyNumber( throw new Error('Could not load their key'); } - const ourKey = PublicKey.deserialize(Buffer.from(ourKeyBuffer)); - const theirKey = PublicKey.deserialize(Buffer.from(theirKeyBuffer)); + const ourKey = PublicKey.deserialize(ourKeyBuffer); + const theirKey = PublicKey.deserialize(theirKeyBuffer); assertDev(theirAci, 'Should have their serviceId'); const fingerprint = Fingerprint.new( ITERATION_COUNT, SERVICE_ID_VERSION, - Buffer.from(uuidToBytes(ourAci)), + uuidToBytes(ourAci), ourKey, - Buffer.from(uuidToBytes(theirAci)), + uuidToBytes(theirAci), theirKey ); diff --git a/ts/util/sendToGroup.ts b/ts/util/sendToGroup.ts index 8c689ae7e44..3e6090b953e 100644 --- a/ts/util/sendToGroup.ts +++ b/ts/util/sendToGroup.ts @@ -26,6 +26,7 @@ import { DataWriter } from '../sql/Client'; import { getValue } from '../RemoteConfig'; import type { ServiceIdString } from '../types/ServiceId'; import { ServiceIdKind } from '../types/ServiceId'; +import * as Bytes from '../Bytes'; import { isRecord } from './isRecord'; import { isOlderThan } from './timestamp'; @@ -235,7 +236,7 @@ export async function sendContentMessageToGroup( const sendLogCallback = window.textsecure.messaging.makeSendLogCallback({ contentHint, messageId, - proto: Buffer.from(Proto.Content.encode(contentMessage).finish()), + proto: Proto.Content.encode(contentMessage).finish(), sendType, timestamp, urgent, @@ -583,7 +584,7 @@ export async function sendToGroupViaSenderKey( sendLogId = await DataWriter.insertSentProto( { contentHint, - proto: Buffer.from(Proto.Content.encode(contentMessage).finish()), + proto: Proto.Content.encode(contentMessage).finish(), timestamp, urgent, hasPniSignatureMessage: false, @@ -667,7 +668,7 @@ export async function sendToGroupViaSenderKey( contentHint, timestamp, - contentProto: Buffer.from(Proto.Content.encode(contentMessage).finish()), + contentProto: Proto.Content.encode(contentMessage).finish(), recipients: senderKeyRecipientsWithDevices, urgent, }; @@ -1100,7 +1101,7 @@ function getXorOfAccessKeys( 'Cannot be endorsement in getXorOfAccessKeys' ); - const accessKeyBuffer = Buffer.from(accessKey, 'base64'); + const accessKeyBuffer = Bytes.fromBase64(accessKey); if (accessKeyBuffer.length !== ACCESS_KEY_LENGTH) { throw new Error( `getXorOfAccessKeys: Access key for ${uuid} had length ${accessKeyBuffer.length}` @@ -1128,7 +1129,7 @@ async function encryptForSenderKey({ devices: Array; distributionId: string; groupId?: string; -}): Promise { +}): Promise { const ourAci = window.textsecure.storage.user.getCheckedAci(); const ourDeviceId = window.textsecure.storage.user.getDeviceId(); if (!ourDeviceId) { @@ -1146,7 +1147,7 @@ async function encryptForSenderKey({ ourServiceId: ourAci, zone: GLOBAL_ZONE, }); - const message = Buffer.from(padMessage(contentMessage)); + const message = padMessage(contentMessage); const ciphertextMessage = await window.textsecure.storage.protocol.enqueueSenderKeyJob( @@ -1154,7 +1155,7 @@ async function encryptForSenderKey({ () => groupEncrypt(sender, distributionId, senderKeyStore, message) ); - const groupIdBuffer = groupId ? Buffer.from(groupId, 'base64') : null; + const groupIdBuffer = groupId ? Bytes.fromBase64(groupId) : null; const senderCertificateObject = await senderCertificateService.get( SenderCertificateMode.WithoutE164 ); @@ -1163,7 +1164,7 @@ async function encryptForSenderKey({ } const senderCertificate = SenderCertificate.deserialize( - Buffer.from(senderCertificateObject.serialized) + senderCertificateObject.serialized ); const content = UnidentifiedSenderMessageContent.new( ciphertextMessage, diff --git a/ts/util/zkgroup.ts b/ts/util/zkgroup.ts index 75af7608a30..f1aa13160b0 100644 --- a/ts/util/zkgroup.ts +++ b/ts/util/zkgroup.ts @@ -25,6 +25,7 @@ import { fromAciObject, fromPniObject, } from '../types/ServiceId'; +import * as Bytes from '../Bytes'; import { toServiceIdObject } from './ServiceId'; import { strictAssert } from './assert'; @@ -36,15 +37,13 @@ export function decryptGroupBlob( clientZkGroupCipher: ClientZkGroupCipher, ciphertext: Uint8Array ): Uint8Array { - return clientZkGroupCipher.decryptBlob(Buffer.from(ciphertext)); + return clientZkGroupCipher.decryptBlob(ciphertext); } export function decodeProfileKeyCredentialPresentation( presentationBuffer: Uint8Array ): { profileKey: Uint8Array; userId: Uint8Array } { - const presentation = new ProfileKeyCredentialPresentation( - Buffer.from(presentationBuffer) - ); + const presentation = new ProfileKeyCredentialPresentation(presentationBuffer); const userId = presentation.getUuidCiphertext().serialize(); const profileKey = presentation.getProfileKeyCiphertext().serialize(); @@ -61,7 +60,7 @@ export function decryptProfileKey( serviceId: ServiceIdString ): Uint8Array { const profileKeyCiphertext = new ProfileKeyCiphertext( - Buffer.from(profileKeyCiphertextBuffer) + profileKeyCiphertextBuffer ); const profileKey = clientZkGroupCipher.decryptProfileKey( @@ -76,7 +75,7 @@ function decryptServiceIdObj( clientZkGroupCipher: ClientZkGroupCipher, uuidCiphertextBuffer: Uint8Array ): ServiceId { - const uuidCiphertext = new UuidCiphertext(Buffer.from(uuidCiphertextBuffer)); + const uuidCiphertext = new UuidCiphertext(uuidCiphertextBuffer); return clientZkGroupCipher.decryptServiceId(uuidCiphertext); } @@ -112,7 +111,7 @@ export function deriveProfileKeyVersion( profileKeyBase64: string, serviceId: ServiceIdString ): string { - const profileKeyArray = Buffer.from(profileKeyBase64, 'base64'); + const profileKeyArray = Bytes.fromBase64(profileKeyBase64); const profileKey = new ProfileKey(profileKeyArray); const profileKeyVersion = profileKey.getProfileKeyVersion( @@ -125,17 +124,13 @@ export function deriveProfileKeyVersion( export function deriveGroupPublicParams( groupSecretParamsBuffer: Uint8Array ): Uint8Array { - const groupSecretParams = new GroupSecretParams( - Buffer.from(groupSecretParamsBuffer) - ); + const groupSecretParams = new GroupSecretParams(groupSecretParamsBuffer); return groupSecretParams.getPublicParams().serialize(); } export function deriveGroupID(groupSecretParamsBuffer: Uint8Array): Uint8Array { - const groupSecretParams = new GroupSecretParams( - Buffer.from(groupSecretParamsBuffer) - ); + const groupSecretParams = new GroupSecretParams(groupSecretParamsBuffer); return groupSecretParams.getPublicParams().getGroupIdentifier().serialize(); } @@ -143,7 +138,7 @@ export function deriveGroupID(groupSecretParamsBuffer: Uint8Array): Uint8Array { export function deriveGroupSecretParams( masterKeyBuffer: Uint8Array ): Uint8Array { - const masterKey = new GroupMasterKey(Buffer.from(masterKeyBuffer)); + const masterKey = new GroupMasterKey(masterKeyBuffer); const groupSecretParams = GroupSecretParams.deriveFromMasterKey(masterKey); return groupSecretParams.serialize(); @@ -153,7 +148,7 @@ export function encryptGroupBlob( clientZkGroupCipher: ClientZkGroupCipher, plaintext: Uint8Array ): Uint8Array { - return clientZkGroupCipher.encryptBlob(Buffer.from(plaintext)); + return clientZkGroupCipher.encryptBlob(plaintext); } export function encryptServiceId( @@ -172,7 +167,7 @@ export function generateProfileKeyCredentialRequest( serviceId: ServiceIdString, profileKeyBase64: string ): { context: ProfileKeyCredentialRequestContext; requestHex: string } { - const profileKeyArray = Buffer.from(profileKeyBase64, 'base64'); + const profileKeyArray = Bytes.fromBase64(profileKeyBase64); const profileKey = new ProfileKey(profileKeyArray); const context = @@ -185,7 +180,7 @@ export function generateProfileKeyCredentialRequest( return { context, - requestHex: requestArray.toString('hex'), + requestHex: Bytes.toHex(requestArray), }; } @@ -195,10 +190,10 @@ export function getAuthCredentialPresentation( groupSecretParamsBase64: string ): Uint8Array { const authCredential = new AuthCredentialWithPni( - Buffer.from(authCredentialBase64, 'base64') + Bytes.fromBase64(authCredentialBase64) ); const secretParams = new GroupSecretParams( - Buffer.from(groupSecretParamsBase64, 'base64') + Bytes.fromBase64(groupSecretParamsBase64) ); const presentation = @@ -214,15 +209,14 @@ export function createProfileKeyCredentialPresentation( profileKeyCredentialBase64: string, groupSecretParamsBase64: string ): Uint8Array { - const profileKeyCredentialArray = Buffer.from( - profileKeyCredentialBase64, - 'base64' + const profileKeyCredentialArray = Bytes.fromBase64( + profileKeyCredentialBase64 ); const profileKeyCredential = new ExpiringProfileKeyCredential( profileKeyCredentialArray ); const secretParams = new GroupSecretParams( - Buffer.from(groupSecretParamsBase64, 'base64') + Bytes.fromBase64(groupSecretParamsBase64) ); const presentation = @@ -238,7 +232,7 @@ export function getClientZkAuthOperations( serverPublicParamsBase64: string ): ClientZkAuthOperations { const serverPublicParams = new ServerPublicParams( - Buffer.from(serverPublicParamsBase64, 'base64') + Bytes.fromBase64(serverPublicParamsBase64) ); return new ClientZkAuthOperations(serverPublicParams); @@ -248,7 +242,7 @@ export function getClientZkGroupCipher( groupSecretParamsBase64: string ): ClientZkGroupCipher { const serverPublicParams = new GroupSecretParams( - Buffer.from(groupSecretParamsBase64, 'base64') + Bytes.fromBase64(groupSecretParamsBase64) ); return new ClientZkGroupCipher(serverPublicParams); @@ -258,7 +252,7 @@ export function getClientZkProfileOperations( serverPublicParamsBase64: string ): ClientZkProfileOperations { const serverPublicParams = new ServerPublicParams( - Buffer.from(serverPublicParamsBase64, 'base64') + Bytes.fromBase64(serverPublicParamsBase64) ); return new ClientZkProfileOperations(serverPublicParams); @@ -270,7 +264,7 @@ export function handleProfileKeyCredential( responseBase64: string ): { credential: string; expiration: number } { const response = new ExpiringProfileKeyCredentialResponse( - Buffer.from(responseBase64, 'base64') + Bytes.fromBase64(responseBase64) ); const profileKeyCredential = clientZkProfileCipher.receiveExpiringProfileKeyCredential( @@ -281,7 +275,7 @@ export function handleProfileKeyCredential( const credentialArray = profileKeyCredential.serialize(); return { - credential: credentialArray.toString('base64'), + credential: Bytes.toBase64(credentialArray), expiration: profileKeyCredential.getExpirationTime().getTime(), }; } @@ -290,12 +284,14 @@ export function deriveProfileKeyCommitment( profileKeyBase64: string, serviceId: ServiceIdString ): string { - const profileKeyArray = Buffer.from(profileKeyBase64, 'base64'); + const profileKeyArray = Bytes.fromBase64(profileKeyBase64); const profileKey = new ProfileKey(profileKeyArray); - return profileKey - .getCommitment(toServiceIdObject(serviceId)) - .contents.toString('base64'); + const commitment = profileKey.getCommitment( + toServiceIdObject(serviceId) + ).contents; + + return Bytes.toBase64(commitment); } export function verifyNotarySignature( @@ -304,10 +300,10 @@ export function verifyNotarySignature( signature: Uint8Array ): void { const serverPublicParams = new ServerPublicParams( - Buffer.from(serverPublicParamsBase64, 'base64') + Bytes.fromBase64(serverPublicParamsBase64) ); - const notarySignature = new NotarySignature(Buffer.from(signature)); + const notarySignature = new NotarySignature(signature); - serverPublicParams.verifySignature(Buffer.from(message), notarySignature); + serverPublicParams.verifySignature(message, notarySignature); }