Update libsignal-client to 0.76.0

This commit is contained in:
Fedor Indutny 2025-06-30 11:43:41 -07:00 committed by GitHub
commit e4e8fadb0f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
43 changed files with 245 additions and 883 deletions

View file

@ -234,7 +234,7 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with: with:
repository: 'signalapp/Signal-Message-Backup-Tests' repository: 'signalapp/Signal-Message-Backup-Tests'
ref: '57807422c347f53cfa8d5a1423c382992a8fc199' ref: '316c3d5eb15ffc923b5ce2925094fd49b34e8203'
path: 'backup-integration-tests' path: 'backup-integration-tests'
- run: xvfb-run --auto-servernum pnpm run test-electron - run: xvfb-run --auto-servernum pnpm run test-electron

View file

@ -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 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 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 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 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 ## 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 IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE. 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 ## 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 IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE. 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 ## 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 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 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 ## 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 ## 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 ## 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 ## 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 <jpixton@gmail.com> Copyright (c) 2016 Joseph Birr-Pixton <jpixton@gmail.com>
@ -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 ## 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 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 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 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 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 ## 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 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 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 ## 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 IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE. 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 ## 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 ## 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 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 ## 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 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. 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 ## 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 MIT License
@ -12673,30 +12279,6 @@ SOFTWARE.
``` ```
## cesu8 1.1.0
```
MIT License
Copyright (c) <year> <copyright holders>
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 ## 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 ## 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 ## 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. THE SOFTWARE.
``` ```
## base64 0.21.7, base64 0.22.1 ## base64 0.22.1
``` ```
The MIT License (MIT) 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) 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. 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 ## 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 ## 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 ## 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 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. 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 ## generic-array 0.14.7

View file

@ -108,7 +108,7 @@ type RangeFinderContextType = Readonly<
type DigestLRUEntryType = Readonly<{ type DigestLRUEntryType = Readonly<{
key: Buffer; key: Buffer;
digest: Buffer; digest: Uint8Array;
}>; }>;
const digestLRU = new LRUCache<string, DigestLRUEntryType>({ const digestLRU = new LRUCache<string, DigestLRUEntryType>({

View file

@ -120,7 +120,7 @@
"@react-aria/utils": "3.25.3", "@react-aria/utils": "3.25.3",
"@react-spring/web": "9.7.5", "@react-spring/web": "9.7.5",
"@react-types/shared": "3.27.0", "@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/quill-cjs": "2.1.2",
"@signalapp/ringrtc": "2.53.0", "@signalapp/ringrtc": "2.53.0",
"@signalapp/sqlcipher": "2.0.3", "@signalapp/sqlcipher": "2.0.3",

10
pnpm-lock.yaml generated
View file

@ -129,8 +129,8 @@ importers:
specifier: 3.27.0 specifier: 3.27.0
version: 3.27.0(react@18.3.1) version: 3.27.0(react@18.3.1)
'@signalapp/libsignal-client': '@signalapp/libsignal-client':
specifier: 0.74.1 specifier: 0.76.0
version: 0.74.1 version: 0.76.0
'@signalapp/quill-cjs': '@signalapp/quill-cjs':
specifier: 2.1.2 specifier: 2.1.2
version: 2.1.2 version: 2.1.2
@ -2767,8 +2767,8 @@ packages:
'@signalapp/libsignal-client@0.60.2': '@signalapp/libsignal-client@0.60.2':
resolution: {integrity: sha512-tU4kNP/yCwkFntb2ahXOSQJtzdy+YifAB2yv5hw0qyKSidRHLn6bYiz4Zo2tjxLDRoBLAUxCRsQramStiqNZdA==} resolution: {integrity: sha512-tU4kNP/yCwkFntb2ahXOSQJtzdy+YifAB2yv5hw0qyKSidRHLn6bYiz4Zo2tjxLDRoBLAUxCRsQramStiqNZdA==}
'@signalapp/libsignal-client@0.74.1': '@signalapp/libsignal-client@0.76.0':
resolution: {integrity: sha512-PEJou0yrBvxaAGg7JjONlRNM/t3PCBuY96wu7W6+57e38/7Mibo9kAMfE5B8DgVv+DUNMW9AgJhx5McCoIXYew==} resolution: {integrity: sha512-wQZFC79GAUeee8pf+aDK5Gii0HbQoCAv/oTn1Ht7d5mFq2pw/L0jRcv3j9DgVYodzCOlnanfto3apfA6eN/Whw==}
'@signalapp/mock-server@13.0.1': '@signalapp/mock-server@13.0.1':
resolution: {integrity: sha512-1rT0fYyqEad64GnZRrFVhNsgKpPS+pvyyk8iOGUHqnqnf818yLIYHblS/5m/cNcvHyC/BBqdtgRHAsfGNqkuZw==} resolution: {integrity: sha512-1rT0fYyqEad64GnZRrFVhNsgKpPS+pvyyk8iOGUHqnqnf818yLIYHblS/5m/cNcvHyC/BBqdtgRHAsfGNqkuZw==}
@ -12460,7 +12460,7 @@ snapshots:
type-fest: 4.26.1 type-fest: 4.26.1
uuid: 8.3.2 uuid: 8.3.2
'@signalapp/libsignal-client@0.74.1': '@signalapp/libsignal-client@0.76.0':
dependencies: dependencies:
node-gyp-build: 4.8.4 node-gyp-build: 4.8.4
type-fest: 4.26.1 type-fest: 4.26.1

View file

@ -1,7 +1,6 @@
// Copyright 2020 Signal Messenger, LLC // Copyright 2020 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import { Buffer } from 'buffer';
import Long from 'long'; import Long from 'long';
import { sample } from 'lodash'; import { sample } from 'lodash';
import { Aci, Pni, hkdf } from '@signalapp/libsignal-client'; import { Aci, Pni, hkdf } from '@signalapp/libsignal-client';
@ -58,12 +57,7 @@ export function deriveSecrets(
salt: Uint8Array, salt: Uint8Array,
info: Uint8Array info: Uint8Array
): [Uint8Array, Uint8Array, Uint8Array] { ): [Uint8Array, Uint8Array, Uint8Array] {
const output = hkdf( const output = hkdf(3 * 32, input, info, salt);
3 * 32,
Buffer.from(input),
Buffer.from(info),
Buffer.from(salt)
);
return [ return [
output.subarray(0, 32), output.subarray(0, 32),
output.subarray(32, 64), output.subarray(32, 64),
@ -198,12 +192,12 @@ export function deriveStorageItemKey({
return hkdf( return hkdf(
STORAGE_SERVICE_ITEM_KEY_LEN, STORAGE_SERVICE_ITEM_KEY_LEN,
Buffer.from(recordIkm), recordIkm,
Buffer.concat([ Bytes.concatenate([
Buffer.from(STORAGE_SERVICE_ITEM_KEY_INFO_PREFIX), Bytes.fromString(STORAGE_SERVICE_ITEM_KEY_INFO_PREFIX),
Buffer.from(key), 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 // We generate the plaintext hash here for forwards-compatibility with streaming
// attachment encryption, which may be the only place that the whole attachment flows // attachment encryption, which may be the only place that the whole attachment flows
// through memory // through memory
plaintextHash: Buffer.from(sha256(plaintext)).toString('hex'), plaintextHash: Bytes.toHex(sha256(plaintext)),
}; };
} }

View file

@ -69,12 +69,7 @@ export function generateKyberPreKey(
identityKeyPair.privateKey, identityKeyPair.privateKey,
keyPair.getPublicKey().serialize() keyPair.getPublicKey().serialize()
); );
return client.KyberPreKeyRecord.new( return client.KyberPreKeyRecord.new(keyId, Date.now(), keyPair, signature);
keyId,
Date.now(),
keyPair,
Buffer.from(signature)
);
} }
export function generateKeyPair(): KeyPairType { export function generateKeyPair(): KeyPairType {
@ -91,13 +86,11 @@ export function createKeyPair(incomingKey: Uint8Array): KeyPairType {
log.warn('createKeyPair: incoming private key was not clamped!'); log.warn('createKeyPair: incoming private key was not clamped!');
} }
const incomingKeyBuffer = Buffer.from(incomingKey); if (incomingKey.length !== 32) {
if (incomingKeyBuffer.length !== 32) {
throw new Error('key must be 32 bytes long'); 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(); const pubKey = privKey.getPublicKey();
return new client.IdentityKeyPair(pubKey, privKey); return new client.IdentityKeyPair(pubKey, privKey);
@ -122,19 +115,14 @@ export function verifySignature(
message: Uint8Array, message: Uint8Array,
signature: Uint8Array signature: Uint8Array
): boolean { ): boolean {
const messageBuffer = Buffer.from(message); return pubKey.verify(message, signature);
const signatureBuffer = Buffer.from(signature);
return pubKey.verify(messageBuffer, signatureBuffer);
} }
export function calculateSignature( export function calculateSignature(
privKey: client.PrivateKey, privKey: client.PrivateKey,
plaintext: Uint8Array plaintext: Uint8Array
): Uint8Array { ): Uint8Array {
const plaintextBuffer = Buffer.from(plaintext); return privKey.sign(plaintext);
return privKey.sign(plaintextBuffer);
} }
function validatePubKeyFormat(pubKey: Uint8Array): Uint8Array { function validatePubKeyFormat(pubKey: Uint8Array): Uint8Array {

View file

@ -143,7 +143,7 @@ export class IdentityKeys extends IdentityKeyStore {
return null; return null;
} }
return PublicKey.deserialize(Buffer.from(key)); return PublicKey.deserialize(key);
} }
async saveIdentity( async saveIdentity(

View file

@ -180,23 +180,23 @@ async function _fillCaches<ID, T extends HasIdType<ID>, HydratedType>(
} }
export function hydrateSession(session: SessionType): SessionRecord { export function hydrateSession(session: SessionType): SessionRecord {
return SessionRecord.deserialize(Buffer.from(session.record)); return SessionRecord.deserialize(session.record);
} }
export function hydratePublicKey(identityKey: IdentityKeyType): PublicKey { export function hydratePublicKey(identityKey: IdentityKeyType): PublicKey {
return PublicKey.deserialize(Buffer.from(identityKey.publicKey)); return PublicKey.deserialize(identityKey.publicKey);
} }
export function hydratePreKey(preKey: PreKeyType): PreKeyRecord { export function hydratePreKey(preKey: PreKeyType): PreKeyRecord {
const publicKey = PublicKey.deserialize(Buffer.from(preKey.publicKey)); const publicKey = PublicKey.deserialize(preKey.publicKey);
const privateKey = PrivateKey.deserialize(Buffer.from(preKey.privateKey)); const privateKey = PrivateKey.deserialize(preKey.privateKey);
return PreKeyRecord.new(preKey.keyId, publicKey, privateKey); return PreKeyRecord.new(preKey.keyId, publicKey, privateKey);
} }
export function hydrateSignedPreKey( export function hydrateSignedPreKey(
signedPreKey: SignedPreKeyType signedPreKey: SignedPreKeyType
): SignedPreKeyRecord { ): SignedPreKeyRecord {
const createdAt = signedPreKey.created_at; const createdAt = signedPreKey.created_at;
const pubKey = PublicKey.deserialize(Buffer.from(signedPreKey.publicKey)); const pubKey = PublicKey.deserialize(signedPreKey.publicKey);
const privKey = PrivateKey.deserialize(Buffer.from(signedPreKey.privateKey)); const privKey = PrivateKey.deserialize(signedPreKey.privateKey);
const signature = Buffer.from([]); const signature = new Uint8Array(0);
return SignedPreKeyRecord.new( return SignedPreKeyRecord.new(
signedPreKey.keyId, signedPreKey.keyId,
@ -277,8 +277,8 @@ export class SignalProtocolStore extends EventEmitter {
'Invalid identity key serviceId' 'Invalid identity key serviceId'
); );
const { privKey, pubKey } = map.value[serviceId]; const { privKey, pubKey } = map.value[serviceId];
const privateKey = PrivateKey.deserialize(Buffer.from(privKey)); const privateKey = PrivateKey.deserialize(privKey);
const publicKey = PublicKey.deserialize(Buffer.from(pubKey)); const publicKey = PublicKey.deserialize(pubKey);
this.#ourIdentityKeys.set( this.#ourIdentityKeys.set(
serviceId, serviceId,
new IdentityKeyPair(publicKey, privateKey) new IdentityKeyPair(publicKey, privateKey)
@ -374,7 +374,7 @@ export class SignalProtocolStore extends EventEmitter {
return entry; return entry;
} }
const item = KyberPreKeyRecord.deserialize(Buffer.from(entry.fromDB.data)); const item = KyberPreKeyRecord.deserialize(entry.fromDB.data);
const newEntry = { const newEntry = {
hydrated: true as const, hydrated: true as const,
fromDB: entry.fromDB, fromDB: entry.fromDB,
@ -932,9 +932,7 @@ export class SignalProtocolStore extends EventEmitter {
return entry.item; return entry.item;
} }
const item = SenderKeyRecord.deserialize( const item = SenderKeyRecord.deserialize(entry.fromDB.data);
Buffer.from(entry.fromDB.data)
);
this.senderKeys.set(id, { this.senderKeys.set(id, {
hydrated: true, hydrated: true,
item, item,
@ -2485,14 +2483,10 @@ export class SignalProtocolStore extends EventEmitter {
const logId = `SignalProtocolStore.updateOurPniKeyMaterial(${pni})`; const logId = `SignalProtocolStore.updateOurPniKeyMaterial(${pni})`;
log.info(`${logId}: starting...`); log.info(`${logId}: starting...`);
const identityKeyPair = IdentityKeyPair.deserialize( const identityKeyPair = IdentityKeyPair.deserialize(identityBytes);
Buffer.from(identityBytes) const signedPreKey = SignedPreKeyRecord.deserialize(signedPreKeyBytes);
);
const signedPreKey = SignedPreKeyRecord.deserialize(
Buffer.from(signedPreKeyBytes)
);
const lastResortKyberPreKey = lastResortKyberPreKeyBytes const lastResortKyberPreKey = lastResortKyberPreKeyBytes
? KyberPreKeyRecord.deserialize(Buffer.from(lastResortKyberPreKeyBytes)) ? KyberPreKeyRecord.deserialize(lastResortKyberPreKeyBytes)
: undefined; : undefined;
const { storage } = window; const { storage } = window;
@ -2636,13 +2630,10 @@ export class SignalProtocolStore extends EventEmitter {
return false; return false;
} }
const aciPublicKey = PublicKey.deserialize(Buffer.from(aciPublicKeyBytes)); const aciPublicKey = PublicKey.deserialize(aciPublicKeyBytes);
const pniPublicKey = PublicKey.deserialize(Buffer.from(pniPublicKeyBytes)); const pniPublicKey = PublicKey.deserialize(pniPublicKeyBytes);
return pniPublicKey.verifyAlternateIdentity( return pniPublicKey.verifyAlternateIdentity(aciPublicKey, signature);
aciPublicKey,
Buffer.from(signature)
);
} }
#_getAllSessions(): Array<SessionCacheEntry> { #_getAllSessions(): Array<SessionCacheEntry> {

View file

@ -27,6 +27,7 @@ import { strictAssert } from '../../util/assert';
import type { DecryptionErrorEventData } from '../../textsecure/messageReceiverEvents'; import type { DecryptionErrorEventData } from '../../textsecure/messageReceiverEvents';
import type { LoggerType } from '../../types/Logging'; import type { LoggerType } from '../../types/Logging';
import { startAutomaticSessionReset } from '../../util/handleRetry'; import { startAutomaticSessionReset } from '../../util/handleRetry';
import * as Bytes from '../../Bytes';
function failoverToLocalReset( function failoverToLocalReset(
logger: LoggerType, logger: LoggerType,
@ -95,7 +96,7 @@ export async function sendResendRequest(
} }
const plaintext = PlaintextContent.deserialize( const plaintext = PlaintextContent.deserialize(
Buffer.from(plaintextBase64, 'base64') Bytes.fromBase64(plaintextBase64)
); );
const { ContentHint } = Proto.UnidentifiedSenderMessage.Message; const { ContentHint } = Proto.UnidentifiedSenderMessage.Message;

View file

@ -20,6 +20,7 @@ import {
OutgoingIdentityKeyError, OutgoingIdentityKeyError,
UnregisteredUserError, UnregisteredUserError,
} from '../../textsecure/Errors'; } from '../../textsecure/Errors';
import * as Bytes from '../../Bytes';
export async function sendSavedProto( export async function sendSavedProto(
conversation: ConversationModel, conversation: ConversationModel,
@ -77,7 +78,7 @@ export async function sendSavedProto(
const sendType = 'resendFromLog'; const sendType = 'resendFromLog';
try { try {
const proto = Proto.Content.decode(Buffer.from(protoBase64, 'base64')); const proto = Proto.Content.decode(Bytes.fromBase64(protoBase64));
await handleMessageSend( await handleMessageSend(
messaging.sendMessageProtoAndWait({ messaging.sendMessageProtoAndWait({
contentHint, contentHint,

View file

@ -11,6 +11,7 @@ import {
} from '@signalapp/libsignal-client/zkgroup'; } from '@signalapp/libsignal-client/zkgroup';
import { type BackupKey } from '@signalapp/libsignal-client/dist/AccountKeys'; import { type BackupKey } from '@signalapp/libsignal-client/dist/AccountKeys';
import * as Bytes from '../../Bytes';
import { createLogger } from '../../logging/log'; import { createLogger } from '../../logging/log';
import { strictAssert } from '../../util/assert'; import { strictAssert } from '../../util/assert';
import { drop } from '../../util/drop'; import { drop } from '../../util/drop';
@ -92,20 +93,18 @@ export class BackupCredentials {
); );
} }
const cred = new BackupAuthCredential( const cred = new BackupAuthCredential(Bytes.fromBase64(result.credential));
Buffer.from(result.credential, 'base64')
);
const serverPublicParams = new GenericServerPublicParams( const serverPublicParams = new GenericServerPublicParams(
Buffer.from(window.getBackupServerPublicParams(), 'base64') Bytes.fromBase64(window.getBackupServerPublicParams())
); );
const presentation = cred.present(serverPublicParams).serialize(); const presentation = cred.present(serverPublicParams).serialize();
const signature = signatureKey.sign(presentation); const signature = signatureKey.sign(presentation);
const headers = { const headers = {
'X-Signal-ZK-Auth': presentation.toString('base64'), 'X-Signal-ZK-Auth': Bytes.toBase64(presentation),
'X-Signal-ZK-Auth-Signature': signature.toString('base64'), 'X-Signal-ZK-Auth-Signature': Bytes.toBase64(signature),
}; };
const info = { headers, level: result.level }; const info = { headers, level: result.level };
@ -274,7 +273,7 @@ export class BackupCredentials {
); );
const serverPublicParams = new GenericServerPublicParams( const serverPublicParams = new GenericServerPublicParams(
Buffer.from(window.getBackupServerPublicParams(), 'base64') Bytes.fromBase64(window.getBackupServerPublicParams())
); );
const result = new Array<BackupCredentialWrapperType>(); const result = new Array<BackupCredentialWrapperType>();
@ -300,7 +299,7 @@ export class BackupCredentials {
credential: buf, credential: buf,
redemptionTime, redemptionTime,
} of allCredentials) { } of allCredentials) {
const credentialRes = new BackupAuthCredentialResponse(Buffer.from(buf)); const credentialRes = new BackupAuthCredentialResponse(buf);
const redemptionTimeMs = DurationInSeconds.toMillis(redemptionTime); const redemptionTimeMs = DurationInSeconds.toMillis(redemptionTime);
strictAssert( strictAssert(
@ -326,7 +325,7 @@ export class BackupCredentials {
result.push({ result.push({
type, type,
credential: credential.serialize().toString('base64'), credential: Bytes.toBase64(credential.serialize()),
level: credential.getBackupLevel(), level: credential.getBackupLevel(),
redemptionTimeMs, redemptionTimeMs,
}); });

View file

@ -28,7 +28,7 @@ export function getBackupMediaRootKey(): BackupKey {
const rootKey = window.storage.get('backupMediaRootKey'); const rootKey = window.storage.get('backupMediaRootKey');
strictAssert(rootKey, 'Media root key not available'); strictAssert(rootKey, 'Media root key not available');
return new BackupKey(Buffer.from(rootKey)); return new BackupKey(rootKey);
} }
const getMemoizedBackupSignatureKey = memoizee( const getMemoizedBackupSignatureKey = memoizee(
@ -94,7 +94,7 @@ export function deriveBackupMediaKeyMaterial(
throw new Error('deriveBackupMediaKeyMaterial: mediaId missing'); throw new Error('deriveBackupMediaKeyMaterial: mediaId missing');
} }
const material = mediaRootKey.deriveMediaEncryptionKey(Buffer.from(mediaId)); const material = mediaRootKey.deriveMediaEncryptionKey(mediaId);
return { return {
macKey: material.subarray(0, BACKUP_MEDIA_MAC_KEY_LEN), macKey: material.subarray(0, BACKUP_MEDIA_MAC_KEY_LEN),
@ -113,9 +113,7 @@ export function deriveBackupThumbnailTransitKeyMaterial(
throw new Error('deriveBackupThumbnailTransitKeyMaterial: mediaId missing'); throw new Error('deriveBackupThumbnailTransitKeyMaterial: mediaId missing');
} }
const material = mediaRootKey.deriveThumbnailTransitEncryptionKey( const material = mediaRootKey.deriveThumbnailTransitEncryptionKey(mediaId);
Buffer.from(mediaId)
);
return { return {
macKey: material.subarray(0, BACKUP_MEDIA_MAC_KEY_LEN), macKey: material.subarray(0, BACKUP_MEDIA_MAC_KEY_LEN),

View file

@ -1130,7 +1130,7 @@ export class BackupImportStream extends Writable {
strictAssert(Bytes.isNotEmpty(userId), 'Empty gv2 member userId'); strictAssert(Bytes.isNotEmpty(userId), 'Empty gv2 member userId');
const serviceId = fromServiceIdObject( const serviceId = fromServiceIdObject(
ServiceId.parseFromServiceIdBinary(Buffer.from(userId)) ServiceId.parseFromServiceIdBinary(userId)
); );
return { return {
@ -1163,7 +1163,7 @@ export class BackupImportStream extends Writable {
// in the Contact frame // in the Contact frame
const serviceId = fromServiceIdObject( const serviceId = fromServiceIdObject(
ServiceId.parseFromServiceIdBinary(Buffer.from(userId)) ServiceId.parseFromServiceIdBinary(userId)
); );
return { return {
@ -2164,9 +2164,7 @@ export class BackupImportStream extends Writable {
bodyRanges.map(range => ({ bodyRanges.map(range => ({
...range, ...range,
mentionAci: range.mentionAci mentionAci: range.mentionAci
? Aci.parseFromServiceIdBinary( ? Aci.parseFromServiceIdBinary(range.mentionAci).getServiceIdString()
Buffer.from(range.mentionAci)
).getServiceIdString()
: undefined, : undefined,
})) }))
); );
@ -2422,7 +2420,7 @@ export class BackupImportStream extends Writable {
} }
const receipt = new ReceiptCredentialPresentation( const receipt = new ReceiptCredentialPresentation(
Buffer.from(giftBadge.receiptCredentialPresentation) giftBadge.receiptCredentialPresentation
); );
return { return {
@ -2901,7 +2899,7 @@ export class BackupImportStream extends Writable {
details.push({ details.push({
type: 'pending-add-one', type: 'pending-add-one',
serviceId: fromServiceIdObject( serviceId: fromServiceIdObject(
ServiceId.parseFromServiceIdBinary(Buffer.from(inviteeServiceId)) ServiceId.parseFromServiceIdBinary(inviteeServiceId)
), ),
}); });
} }

View file

@ -579,7 +579,7 @@ export class BackupsService {
); );
if (backupType === BackupType.Ciphertext) { if (backupType === BackupType.Ciphertext) {
const { aesKey, macKey } = getKeyMaterial( const { aesKey, macKey } = getKeyMaterial(
ephemeralKey ? new BackupKey(Buffer.from(ephemeralKey)) : undefined ephemeralKey ? new BackupKey(ephemeralKey) : undefined
); );
// First pass - don't decrypt, only verify mac // First pass - don't decrypt, only verify mac

View file

@ -61,7 +61,7 @@ export async function validateBackupStream(
frameCount += 1; frameCount += 1;
const reader = new Reader(delimitedFrame); const reader = new Reader(delimitedFrame);
const frame = Buffer.from(reader.bytes()); const frame = reader.bytes();
// Info frame // Info frame
if (frameCount === 1) { if (frameCount === 1) {

View file

@ -764,11 +764,11 @@ export class CallingClass {
); );
const response = new CreateCallLinkCredentialResponse( const response = new CreateCallLinkCredentialResponse(
Buffer.from(credentialBase64, 'base64') Bytes.fromBase64(credentialBase64)
); );
const genericServerPublicParams = new GenericServerPublicParams( const genericServerPublicParams = new GenericServerPublicParams(
Buffer.from(window.getGenericServerPublicParams(), 'base64') Bytes.fromBase64(window.getGenericServerPublicParams())
); );
const credential = context.receive( const credential = context.receive(
response, response,
@ -785,10 +785,10 @@ export class CallingClass {
const result = await RingRTC.createCallLink( const result = await RingRTC.createCallLink(
sfuUrl, sfuUrl,
credentialPresentation, Buffer.from(credentialPresentation),
rootKey, rootKey,
adminKey, adminKey,
serializedPublicParams, Buffer.from(serializedPublicParams),
CallLinkRestrictions.AdminApproval CallLinkRestrictions.AdminApproval
); );
@ -832,7 +832,7 @@ export class CallingClass {
const result = await RingRTC.deleteCallLink( const result = await RingRTC.deleteCallLink(
sfuUrl, sfuUrl,
authCredentialPresentation.serialize(), Buffer.from(authCredentialPresentation.serialize()),
callLinkRootKey, callLinkRootKey,
undefined, undefined,
callLinkAdminKey callLinkAdminKey
@ -869,7 +869,7 @@ export class CallingClass {
await getCallLinkAuthCredentialPresentation(callLinkRootKey); await getCallLinkAuthCredentialPresentation(callLinkRootKey);
const result = await RingRTC.updateCallLinkName( const result = await RingRTC.updateCallLinkName(
sfuUrl, sfuUrl,
authCredentialPresentation.serialize(), Buffer.from(authCredentialPresentation.serialize()),
callLinkRootKey, callLinkRootKey,
undefined, undefined,
callLinkAdminKey, callLinkAdminKey,
@ -915,7 +915,7 @@ export class CallingClass {
const result = await RingRTC.updateCallLinkRestrictions( const result = await RingRTC.updateCallLinkRestrictions(
sfuUrl, sfuUrl,
authCredentialPresentation.serialize(), Buffer.from(authCredentialPresentation.serialize()),
callLinkRootKey, callLinkRootKey,
undefined, undefined,
callLinkAdminKey, callLinkAdminKey,
@ -950,7 +950,7 @@ export class CallingClass {
const result = await RingRTC.readCallLink( const result = await RingRTC.readCallLink(
this._sfuUrl, this._sfuUrl,
authCredentialPresentation.serialize(), Buffer.from(authCredentialPresentation.serialize()),
callLinkRootKey, callLinkRootKey,
undefined undefined
); );
@ -1246,7 +1246,7 @@ export class CallingClass {
const result = await RingRTC.peekCallLinkCall( const result = await RingRTC.peekCallLinkCall(
this._sfuUrl, this._sfuUrl,
authCredentialPresentation.serialize(), Buffer.from(authCredentialPresentation.serialize()),
callLinkRootKey, callLinkRootKey,
undefined undefined
); );
@ -1380,7 +1380,7 @@ export class CallingClass {
const outerGroupCall = RingRTC.getCallLinkCall( const outerGroupCall = RingRTC.getCallLinkCall(
this._sfuUrl, this._sfuUrl,
authCredentialPresentation.serialize(), Buffer.from(authCredentialPresentation.serialize()),
callLinkRootKey, callLinkRootKey,
undefined, undefined,
adminPasskey, adminPasskey,

View file

@ -19,6 +19,7 @@ import { toDayMillis } from '../util/timestamp';
import { toTaggedPni } from '../types/ServiceId'; import { toTaggedPni } from '../types/ServiceId';
import { toPniObject, toAciObject } from '../util/ServiceId'; import { toPniObject, toAciObject } from '../util/ServiceId';
import { createLogger } from '../logging/log'; import { createLogger } from '../logging/log';
import * as Bytes from '../Bytes';
const log = createLogger('groupCredentialFetcher'); const log = createLogger('groupCredentialFetcher');
@ -221,11 +222,9 @@ export async function maybeFetchNewCredentials(): Promise<void> {
toAciObject(aci), toAciObject(aci),
toPniObject(pni), toPniObject(pni),
item.redemptionTime, item.redemptionTime,
new AuthCredentialWithPniResponse( new AuthCredentialWithPniResponse(Bytes.fromBase64(item.credential))
Buffer.from(item.credential, 'base64')
)
); );
const credential = authCredential.serialize().toString('base64'); const credential = Bytes.toBase64(authCredential.serialize());
return { return {
redemptionTime: item.redemptionTime * durations.SECOND, redemptionTime: item.redemptionTime * durations.SECOND,
@ -237,21 +236,21 @@ export async function maybeFetchNewCredentials(): Promise<void> {
sortCredentials(rawCredentials).map(formatCredential); sortCredentials(rawCredentials).map(formatCredential);
const genericServerPublicParamsBase64 = window.getGenericServerPublicParams(); const genericServerPublicParamsBase64 = window.getGenericServerPublicParams();
const genericServerPublicParams = new GenericServerPublicParams( const genericServerPublicParams = new GenericServerPublicParams(
Buffer.from(genericServerPublicParamsBase64, 'base64') Bytes.fromBase64(genericServerPublicParamsBase64)
); );
function formatCallingCredential( function formatCallingCredential(
item: GroupCredentialType item: GroupCredentialType
): GroupCredentialType { ): GroupCredentialType {
const response = new CallLinkAuthCredentialResponse( const response = new CallLinkAuthCredentialResponse(
Buffer.from(item.credential, 'base64') Bytes.fromBase64(item.credential)
); );
const authCredential = response.receive( const authCredential = response.receive(
toAciObject(aci), toAciObject(aci),
item.redemptionTime, item.redemptionTime,
genericServerPublicParams genericServerPublicParams
); );
const credential = authCredential.serialize().toString('base64'); const credential = Bytes.toBase64(authCredential.serialize());
return { return {
redemptionTime: item.redemptionTime * durations.SECOND, redemptionTime: item.redemptionTime * durations.SECOND,

View file

@ -119,7 +119,7 @@ export async function reserveUsername(
abortSignal, abortSignal,
}); });
const index = hashes.findIndex(hash => hash.equals(usernameHash)); const index = hashes.findIndex(hash => Bytes.areEqual(hash, usernameHash));
if (index === -1) { if (index === -1) {
log.warn('reserveUsername: failed to find username hash in the response'); log.warn('reserveUsername: failed to find username hash in the response');
return { ok: false, error: ReserveUsernameError.Unprocessable }; return { ok: false, error: ReserveUsernameError.Unprocessable };
@ -244,7 +244,10 @@ export async function confirmUsername(
} }
const { hash } = reservation; 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'); const wasCorrupted = window.storage.get('usernameCorrupted');
@ -252,13 +255,13 @@ export async function confirmUsername(
await window.storage.remove('usernameLink'); await window.storage.remove('usernameLink');
let serverIdString: string; let serverIdString: string;
let entropy: Buffer; let entropy: Uint8Array;
if (previousLink && isCaseChange(reservation)) { if (previousLink && isCaseChange(reservation)) {
log.info('confirmUsername: updating link only'); log.info('confirmUsername: updating link only');
const updatedLink = usernames.createUsernameLink( const updatedLink = usernames.createUsernameLink(
username, username,
Buffer.from(previousLink.entropy) previousLink.entropy
); );
({ entropy } = updatedLink); ({ entropy } = updatedLink);
@ -401,8 +404,8 @@ export async function resolveUsernameByLink({
await server.resolveUsernameLink(serverId); await server.resolveUsernameLink(serverId);
return usernames.decryptUsernameLink({ return usernames.decryptUsernameLink({
entropy: Buffer.from(entropy), entropy,
encryptedUsername: Buffer.from(usernameLinkEncryptedValue), encryptedUsername: usernameLinkEncryptedValue,
}); });
} catch (error) { } catch (error) {
if (error instanceof HTTPError && error.code === 404) { if (error instanceof HTTPError && error.code === 404) {

View file

@ -17,6 +17,7 @@ import { getProfile } from '../util/getProfile';
import { isSharingPhoneNumberWithEverybody } from '../util/phoneNumberSharingMode'; import { isSharingPhoneNumberWithEverybody } from '../util/phoneNumberSharingMode';
import { bytesToUuid } from '../util/uuidToBytes'; import { bytesToUuid } from '../util/uuidToBytes';
import { createLogger } from '../logging/log'; import { createLogger } from '../logging/log';
import * as Bytes from '../Bytes';
import { runStorageServiceSyncJob } from './storage'; import { runStorageServiceSyncJob } from './storage';
import { writeProfile } from './writeProfile'; import { writeProfile } from './writeProfile';
@ -101,7 +102,7 @@ class UsernameIntegrityService {
let failed = false; let failed = false;
if (remoteHash !== usernames.hash(username).toString('base64url')) { if (remoteHash !== Bytes.toBase64url(usernames.hash(username))) {
log.error('remote username mismatch'); log.error('remote username mismatch');
await window.storage.put('usernameCorrupted', true); await window.storage.put('usernameCorrupted', true);
failed = true; failed = true;

View file

@ -41,7 +41,7 @@ describe('backup/integration', () => {
const files = readdirSync(BACKUP_INTEGRATION_DIR) const files = readdirSync(BACKUP_INTEGRATION_DIR)
.filter(file => file.endsWith('.binproto')) .filter(file => file.endsWith('.binproto'))
// TODO: DESKTOP-8906 // 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)); .map(file => join(BACKUP_INTEGRATION_DIR, file));
if (files.length === 0) { if (files.length === 0) {

View file

@ -25,17 +25,17 @@ import { Backups } from '../protobuf';
export type BackupGeneratorConfigType = Readonly< export type BackupGeneratorConfigType = Readonly<
{ {
aci: AciString; aci: AciString;
profileKey: Buffer; profileKey: Uint8Array;
conversations: number; conversations: number;
conversationAcis?: ReadonlyArray<AciString>; conversationAcis?: ReadonlyArray<AciString>;
messages: number; messages: number;
mediaRootBackupKey: Buffer; mediaRootBackupKey: Uint8Array;
} & ( } & (
| { | {
accountEntropyPool: string; accountEntropyPool: string;
} }
| { | {
backupKey: Buffer; backupKey: Uint8Array;
} }
) )
>; >;
@ -43,7 +43,7 @@ export type BackupGeneratorConfigType = Readonly<
const IV_LENGTH = 16; const IV_LENGTH = 16;
export type GenerateBackupResultType = Readonly<{ export type GenerateBackupResultType = Readonly<{
backupId: Buffer; backupId: Uint8Array;
stream: Readable; stream: Readable;
}>; }>;
@ -145,7 +145,7 @@ function* createRecords({
const chats = new Array<{ const chats = new Array<{
id: Long; id: Long;
aci: Buffer; aci: Uint8Array;
}>(); }>();
for (let i = 1; i <= conversations; i += 1) { for (let i = 1; i <= conversations; i += 1) {

View file

@ -289,9 +289,7 @@ export default class AccountManager extends EventTarget {
const name = decryptDeviceName( const name = decryptDeviceName(
{ {
ephemeralPublic: PublicKey.deserialize( ephemeralPublic: PublicKey.deserialize(proto.ephemeralPublic),
Buffer.from(proto.ephemeralPublic)
),
syntheticIv: proto.syntheticIv, syntheticIv: proto.syntheticIv,
ciphertext: proto.ciphertext, ciphertext: proto.ciphertext,
}, },

View file

@ -321,7 +321,7 @@ export default class MessageReceiver
throw new Error('Server trust root is required!'); throw new Error('Server trust root is required!');
} }
this.#serverTrustRoot = PublicKey.deserialize( this.#serverTrustRoot = PublicKey.deserialize(
Buffer.from(Bytes.fromBase64(serverTrustRoot)) Bytes.fromBase64(serverTrustRoot)
); );
this.#incomingQueue = new PQueue({ this.#incomingQueue = new PQueue({
@ -1351,7 +1351,7 @@ export default class MessageReceiver
log.info(`unsealEnvelope(${logId}): unidentified message`); log.info(`unsealEnvelope(${logId}): unidentified message`);
const messageContent = await sealedSenderDecryptToUsmc( const messageContent = await sealedSenderDecryptToUsmc(
Buffer.from(ciphertext), ciphertext,
stores.identityKeyStore stores.identityKeyStore
); );
@ -1362,6 +1362,8 @@ export default class MessageReceiver
const originalSource = envelope.source; const originalSource = envelope.source;
const originalSourceUuid = envelope.sourceServiceId; const originalSourceUuid = envelope.sourceServiceId;
const groupId = messageContent.groupId();
const newEnvelope: UnsealedEnvelope = { const newEnvelope: UnsealedEnvelope = {
...envelope, ...envelope,
@ -1379,7 +1381,7 @@ export default class MessageReceiver
// UnsealedEnvelope-only fields // UnsealedEnvelope-only fields
unidentifiedDeliveryReceived: !(originalSource || originalSourceUuid), unidentifiedDeliveryReceived: !(originalSource || originalSourceUuid),
contentHint: messageContent.contentHint(), contentHint: messageContent.contentHint(),
groupId: messageContent.groupId()?.toString('base64'), groupId: groupId ? Bytes.toBase64(groupId) : undefined,
certificate, certificate,
unsealedContent: messageContent, unsealedContent: messageContent,
}; };
@ -1845,8 +1847,7 @@ export default class MessageReceiver
if (envelope.type === envelopeTypeEnum.PLAINTEXT_CONTENT) { if (envelope.type === envelopeTypeEnum.PLAINTEXT_CONTENT) {
log.info(`decrypt/${logId}: plaintext message`); log.info(`decrypt/${logId}: plaintext message`);
const buffer = Buffer.from(ciphertext); const plaintextContent = PlaintextContent.deserialize(ciphertext);
const plaintextContent = PlaintextContent.deserialize(buffer);
return { return {
plaintext: this.#unpad(plaintextContent.body()), plaintext: this.#unpad(plaintextContent.body()),
@ -1865,7 +1866,7 @@ export default class MessageReceiver
'MessageReceiver.innerDecrypt: No sourceDevice for CIPHERTEXT message' '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( const plaintext = await this.#storage.protocol.enqueueSessionJob(
address, address,
@ -1894,9 +1895,7 @@ export default class MessageReceiver
'MessageReceiver.innerDecrypt: No sourceDevice for PREKEY_BUNDLE message' 'MessageReceiver.innerDecrypt: No sourceDevice for PREKEY_BUNDLE message'
); );
} }
const preKeySignalMessage = PreKeySignalMessage.deserialize( const preKeySignalMessage = PreKeySignalMessage.deserialize(ciphertext);
Buffer.from(ciphertext)
);
const plaintext = await this.#storage.protocol.enqueueSessionJob( const plaintext = await this.#storage.protocol.enqueueSessionJob(
address, address,
@ -2619,8 +2618,7 @@ export default class MessageReceiver
logUnexpectedUrgentValue(envelope, 'retryRequest'); logUnexpectedUrgentValue(envelope, 'retryRequest');
const buffer = Buffer.from(decryptionError); const request = DecryptionErrorMessage.deserialize(decryptionError);
const request = DecryptionErrorMessage.deserialize(buffer);
const { sourceServiceId: sourceAci, sourceDevice } = envelope; const { sourceServiceId: sourceAci, sourceDevice } = envelope;
if (!sourceAci || !sourceDevice) { if (!sourceAci || !sourceDevice) {
@ -2672,9 +2670,7 @@ export default class MessageReceiver
const sender = ProtocolAddress.new(sourceServiceId, sourceDevice); const sender = ProtocolAddress.new(sourceServiceId, sourceDevice);
const senderKeyDistributionMessage = const senderKeyDistributionMessage =
SenderKeyDistributionMessage.deserialize( SenderKeyDistributionMessage.deserialize(distributionMessage);
Buffer.from(distributionMessage)
);
const { destinationServiceId } = envelope; const { destinationServiceId } = envelope;
const address = new QualifiedAddress( const address = new QualifiedAddress(
destinationServiceId, destinationServiceId,
@ -2708,7 +2704,7 @@ export default class MessageReceiver
const { pni: pniBytes, signature } = pniSignatureMessage; const { pni: pniBytes, signature } = pniSignatureMessage;
strictAssert(Bytes.isNotEmpty(pniBytes), `${logId}: missing PNI bytes`); 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(pni, `${logId}: missing PNI`);
strictAssert(Bytes.isNotEmpty(signature), `${logId}: empty signature`); strictAssert(Bytes.isNotEmpty(signature), `${logId}: empty signature`);
strictAssert(isAciString(aci), `${logId}: invalid ACI`); strictAssert(isAciString(aci), `${logId}: invalid ACI`);
@ -4153,7 +4149,7 @@ function processConversationIdentifier(
if (threadGroupId) { if (threadGroupId) {
return { return {
type: 'group' as const, type: 'group' as const,
groupId: Buffer.from(threadGroupId).toString('base64'), groupId: Bytes.toBase64(threadGroupId),
}; };
} }
if (threadE164) { if (threadE164) {

View file

@ -44,6 +44,7 @@ import { SignalService as Proto } from '../protobuf';
import { createLogger } from '../logging/log'; import { createLogger } from '../logging/log';
import type { GroupSendToken } from '../types/GroupSendEndorsements'; import type { GroupSendToken } from '../types/GroupSendEndorsements';
import { isSignalServiceId } from '../util/isSignalConversation'; import { isSignalServiceId } from '../util/isSignalConversation';
import * as Bytes from '../Bytes';
const log = createLogger('OutgoingMessage'); const log = createLogger('OutgoingMessage');
@ -388,7 +389,7 @@ export default class OutgoingMessage {
if (message instanceof Proto.Content) { if (message instanceof Proto.Content) {
return signalEncrypt( return signalEncrypt(
Buffer.from(this.getPlaintext()), this.getPlaintext(),
protocolAddress, protocolAddress,
sessionStore, sessionStore,
identityKeyStore identityKeyStore
@ -472,10 +473,10 @@ export default class OutgoingMessage {
}); });
const certificate = SenderCertificate.deserialize( const certificate = SenderCertificate.deserialize(
Buffer.from(senderCertificate.serialized) senderCertificate.serialized
); );
const groupIdBuffer = this.groupId const groupIdBuffer = this.groupId
? Buffer.from(this.groupId, 'base64') ? Bytes.fromBase64(this.groupId)
: null; : null;
const content = UnidentifiedSenderMessageContent.new( const content = UnidentifiedSenderMessageContent.new(
@ -495,7 +496,7 @@ export default class OutgoingMessage {
type: Proto.Envelope.Type.UNIDENTIFIED_SENDER, type: Proto.Envelope.Type.UNIDENTIFIED_SENDER,
destinationDeviceId, destinationDeviceId,
destinationRegistrationId, destinationRegistrationId,
content: buffer.toString('base64'), content: Bytes.toBase64(buffer),
}; };
} }
@ -508,7 +509,7 @@ export default class OutgoingMessage {
ciphertextMessage.type() ciphertextMessage.type()
); );
const content = ciphertextMessage.serialize().toString('base64'); const content = Bytes.toBase64(ciphertextMessage.serialize());
return { return {
type, type,

View file

@ -67,7 +67,7 @@ class ProvisioningCipherInner {
} }
const ecRes = calculateAgreement( const ecRes = calculateAgreement(
PublicKey.deserialize(Buffer.from(masterEphemeral)), PublicKey.deserialize(masterEphemeral),
this.keyPair.privateKey this.keyPair.privateKey
); );
const keys = deriveSecrets( const keys = deriveSecrets(

View file

@ -2176,7 +2176,7 @@ export default class MessageSender {
}: Readonly<{ }: Readonly<{
contentHint: number; contentHint: number;
messageId?: string; messageId?: string;
proto: Buffer; proto: Uint8Array;
sendType: SendTypesType; sendType: SendTypesType;
timestamp: number; timestamp: number;
urgent: boolean; urgent: boolean;
@ -2402,7 +2402,7 @@ export default class MessageSender {
serviceIds.length > 1 serviceIds.length > 1
? this.makeSendLogCallback({ ? this.makeSendLogCallback({
contentHint: contentHint ?? ContentHint.IMPLICIT, contentHint: contentHint ?? ContentHint.IMPLICIT,
proto: Buffer.from(Proto.Content.encode(contentMessage).finish()), proto: Proto.Content.encode(contentMessage).finish(),
sendType: 'senderKeyDistributionMessage', sendType: 'senderKeyDistributionMessage',
timestamp, timestamp,
urgent, urgent,

View file

@ -3235,10 +3235,14 @@ export function initialize({
keyId: number; keyId: number;
publicKey: K; publicKey: K;
signature: Uint8Array; signature: Uint8Array;
}): { id: () => number; publicKey: () => K; signature: () => Buffer } { }): {
id: () => number;
publicKey: () => K;
signature: () => Uint8Array;
} {
return { return {
id: () => key.keyId, id: () => key.keyId,
signature: () => Buffer.from(key.signature), signature: () => key.signature,
publicKey: () => key.publicKey, publicKey: () => key.publicKey,
}; };
} }
@ -4093,22 +4097,21 @@ export function initialize({
].join(CRLF); ].join(CRLF);
const end = `${CRLF}--${boundaryString}--${CRLF}`; const end = `${CRLF}--${boundaryString}--${CRLF}`;
const startBuffer = Buffer.from(start, 'utf8'); const startBuffer = Bytes.fromString(start);
const attachmentBuffer = Buffer.from(encryptedBin); const attachmentBuffer = encryptedBin;
const endBuffer = Buffer.from(end, 'utf8'); const endBuffer = Bytes.fromString(end);
const contentLength = const data = Bytes.concatenate([
startBuffer.length + attachmentBuffer.length + endBuffer.length; startBuffer,
const data = Buffer.concat( attachmentBuffer,
[startBuffer, attachmentBuffer, endBuffer], endBuffer,
contentLength ]);
);
return { return {
data, data,
contentType: `multipart/form-data; boundary=${boundaryString}`, contentType: `multipart/form-data; boundary=${boundaryString}`,
headers: { headers: {
'Content-Length': contentLength.toString(), 'Content-Length': data.length.toString(),
}, },
}; };
} }

View file

@ -9,7 +9,7 @@ import { CDSSocketBase, CDSSocketState } from './CDSSocketBase';
import type { CDSSocketBaseOptionsType } from './CDSSocketBase'; import type { CDSSocketBaseOptionsType } from './CDSSocketBase';
export type CDSISocketOptionsType = Readonly<{ export type CDSISocketOptionsType = Readonly<{
mrenclave: Buffer; mrenclave: Uint8Array;
}> & }> &
CDSSocketBaseOptionsType; CDSSocketBaseOptionsType;
@ -41,7 +41,7 @@ export class CDSISocket extends CDSSocketBase<CDSISocketOptionsType> {
); );
} }
this.socket.sendBytes(this.#cdsClient.initialRequest()); this.socket.sendBytes(Buffer.from(this.#cdsClient.initialRequest()));
{ {
const { done, value: message } = await this.socketIterator.next(); const { done, value: message } = await this.socketIterator.next();
@ -55,9 +55,11 @@ export class CDSISocket extends CDSSocketBase<CDSISocketOptionsType> {
protected override async sendRequest( protected override async sendRequest(
_version: number, _version: number,
request: Buffer request: Uint8Array
): Promise<void> { ): Promise<void> {
this.socket.sendBytes(this.#cdsClient.establishedSend(request)); this.socket.sendBytes(
Buffer.from(this.#cdsClient.establishedSend(request))
);
const { done, value: ciphertext } = await this.socketIterator.next(); const { done, value: ciphertext } = await this.socketIterator.next();
strictAssert(!done, 'CDSISocket.sendRequest(): expected token message'); strictAssert(!done, 'CDSISocket.sendRequest(): expected token message');
@ -70,8 +72,8 @@ export class CDSISocket extends CDSSocketBase<CDSISocketOptionsType> {
strictAssert(token, 'CDSISocket.sendRequest(): expected token'); strictAssert(token, 'CDSISocket.sendRequest(): expected token');
this.socket.sendBytes( this.socket.sendBytes(
this.#cdsClient.establishedSend( Buffer.from(
Buffer.from( this.#cdsClient.establishedSend(
Proto.CDSClientRequest.encode({ Proto.CDSClientRequest.encode({
tokenAck: true, tokenAck: true,
}).finish() }).finish()
@ -81,8 +83,8 @@ export class CDSISocket extends CDSSocketBase<CDSISocketOptionsType> {
} }
protected override async decryptResponse( protected override async decryptResponse(
ciphertext: Buffer ciphertext: Uint8Array
): Promise<Buffer> { ): Promise<Uint8Array> {
return this.#cdsClient.establishedRecv(ciphertext); return this.#cdsClient.establishedRecv(ciphertext);
} }

View file

@ -47,7 +47,7 @@ export abstract class CDSSocketBase<
protected readonly logger: LoggerType; protected readonly logger: LoggerType;
protected readonly socketIterator: AsyncIterator<Buffer>; protected readonly socketIterator: AsyncIterator<Uint8Array>;
constructor(protected readonly options: Options) { constructor(protected readonly options: Options) {
super(); super();
@ -87,18 +87,18 @@ export abstract class CDSSocketBase<
); );
const request = Proto.CDSClientRequest.encode({ const request = Proto.CDSClientRequest.encode({
newE164s: Buffer.concat( newE164s: Bytes.concatenate(
e164s.map(e164 => { e164s.map(e164 => {
// Long.fromString handles numbers with or without a leading '+' // Long.fromString handles numbers with or without a leading '+'
return new Uint8Array(Long.fromString(e164).toBytesBE()); return new Uint8Array(Long.fromString(e164).toBytesBE());
}) })
), ),
aciUakPairs: Buffer.concat(aciUakPairs), aciUakPairs: Bytes.concatenate(aciUakPairs),
returnAcisWithoutUaks, returnAcisWithoutUaks,
}).finish(); }).finish();
log.info(`CDSSocket.request(): sending version=${version} request`); log.info(`CDSSocket.request(): sending version=${version} request`);
await this.sendRequest(version, Buffer.from(request)); await this.sendRequest(version, request);
const resultMap: Map<string, CDSResponseEntryType> = new Map(); const resultMap: Map<string, CDSResponseEntryType> = new Map();
@ -129,9 +129,14 @@ export abstract class CDSSocketBase<
public abstract handshake(): Promise<void>; public abstract handshake(): Promise<void>;
protected abstract sendRequest(version: number, data: Buffer): Promise<void>; protected abstract sendRequest(
version: number,
data: Uint8Array
): Promise<void>;
protected abstract decryptResponse(ciphertext: Buffer): Promise<Buffer>; protected abstract decryptResponse(
ciphertext: Uint8Array
): Promise<Uint8Array>;
// EventEmitter types // EventEmitter types
@ -161,7 +166,7 @@ export abstract class CDSSocketBase<
// Private // Private
// //
#iterateSocket(): AsyncIterator<Buffer> { #iterateSocket(): AsyncIterator<Uint8Array> {
const stream = new Readable({ read: noop, objectMode: true }); const stream = new Readable({ read: noop, objectMode: true });
this.socket.on('message', ({ type, binaryData }) => { this.socket.on('message', ({ type, binaryData }) => {

View file

@ -152,20 +152,13 @@ async function handleServerKeys(
const protocolAddress = ProtocolAddress.new(serviceId, deviceId); const protocolAddress = ProtocolAddress.new(serviceId, deviceId);
const preKeyId = preKey?.keyId || null; const preKeyId = preKey?.keyId || null;
const preKeyObject = preKey const preKeyObject = preKey
? PublicKey.deserialize(Buffer.from(preKey.publicKey)) ? PublicKey.deserialize(preKey.publicKey)
: null; : null;
const signedPreKeyObject = PublicKey.deserialize( const signedPreKeyObject = PublicKey.deserialize(signedPreKey.publicKey);
Buffer.from(signedPreKey.publicKey) const identityKey = PublicKey.deserialize(response.identityKey);
);
const identityKey = PublicKey.deserialize(
Buffer.from(response.identityKey)
);
const pqPreKeyId = pqPreKey.keyId; const { keyId: pqPreKeyId, signature: pqPreKeySignature } = pqPreKey;
const pqPreKeyPublic = KEMPublicKey.deserialize( const pqPreKeyPublic = KEMPublicKey.deserialize(pqPreKey.publicKey);
Buffer.from(pqPreKey.publicKey)
);
const pqPreKeySignature = Buffer.from(pqPreKey.signature);
const preKeyBundle = PreKeyBundle.new( const preKeyBundle = PreKeyBundle.new(
registrationId, registrationId,
@ -174,7 +167,7 @@ async function handleServerKeys(
preKeyObject, preKeyObject,
signedPreKey.keyId, signedPreKey.keyId,
signedPreKeyObject, signedPreKeyObject,
Buffer.from(signedPreKey.signature), signedPreKey.signature,
identityKey, identityKey,
pqPreKeyId, pqPreKeyId,
pqPreKeyPublic, pqPreKeyPublic,

View file

@ -333,7 +333,7 @@ export function processGiftBadge(
} }
const receipt = new ReceiptCredentialPresentation( const receipt = new ReceiptCredentialPresentation(
Buffer.from(giftBadge.receiptCredentialPresentation) giftBadge.receiptCredentialPresentation
); );
return { return {

View file

@ -3,7 +3,7 @@
import { PrivateKey, PublicKey } from '@signalapp/libsignal-client'; import { PrivateKey, PublicKey } from '@signalapp/libsignal-client';
export function keyPair(): Record<string, Buffer> { export function keyPair(): Record<string, Uint8Array> {
const privKey = PrivateKey.generate(); const privKey = PrivateKey.generate();
const pubKey = privKey.getPublicKey(); const pubKey = privKey.getPublicKey();
@ -13,16 +13,16 @@ export function keyPair(): Record<string, Buffer> {
}; };
} }
export function sign(privateKey: Buffer, message: Buffer): Buffer { export function sign(privateKey: Uint8Array, message: Uint8Array): Uint8Array {
const privKeyObj = PrivateKey.deserialize(privateKey); const privKeyObj = PrivateKey.deserialize(privateKey);
const signature = privKeyObj.sign(message); const signature = privKeyObj.sign(message);
return signature; return signature;
} }
export function verify( export function verify(
publicKey: Buffer, publicKey: Uint8Array,
message: Buffer, message: Uint8Array,
signature: Buffer signature: Uint8Array
): boolean { ): boolean {
const pubKeyObj = PublicKey.deserialize(publicKey); const pubKeyObj = PublicKey.deserialize(publicKey);
const result = pubKeyObj.verify(message, signature); const result = pubKeyObj.verify(message, signature);

View file

@ -21,7 +21,7 @@ export async function generateSignature(
updatePackagePath: string, updatePackagePath: string,
version: string, version: string,
privateKeyPath: string privateKeyPath: string
): Promise<Buffer> { ): Promise<Uint8Array> {
const privateKey = await loadHexFromPath(privateKeyPath); const privateKey = await loadHexFromPath(privateKeyPath);
const message = await generateMessage(updatePackagePath, version); const message = await generateMessage(updatePackagePath, version);
@ -31,8 +31,8 @@ export async function generateSignature(
export async function verifySignature( export async function verifySignature(
updatePackagePath: string, updatePackagePath: string,
version: string, version: string,
signature: Buffer, signature: Uint8Array,
publicKey: Buffer publicKey: Uint8Array
): Promise<boolean> { ): Promise<boolean> {
const message = await generateMessage(updatePackagePath, version); const message = await generateMessage(updatePackagePath, version);
@ -44,7 +44,7 @@ export async function verifySignature(
async function generateMessage( async function generateMessage(
updatePackagePath: string, updatePackagePath: string,
version: string version: string
): Promise<Buffer> { ): Promise<Uint8Array> {
const hash = await _getFileHash(updatePackagePath); const hash = await _getFileHash(updatePackagePath);
const messageString = `${Buffer.from(hash).toString('hex')}-${version}`; const messageString = `${Buffer.from(hash).toString('hex')}-${version}`;
@ -55,7 +55,7 @@ export async function writeSignature(
updatePackagePath: string, updatePackagePath: string,
version: string, version: string,
privateKeyPath: string privateKeyPath: string
): Promise<Buffer> { ): Promise<Uint8Array> {
const signaturePath = getSignaturePath(updatePackagePath); const signaturePath = getSignaturePath(updatePackagePath);
const signature = await generateSignature( const signature = await generateSignature(
updatePackagePath, updatePackagePath,
@ -90,7 +90,7 @@ export function hexToBinary(target: string): Buffer {
return Buffer.from(target, 'hex'); return Buffer.from(target, 'hex');
} }
export function binaryToHex(data: Buffer): string { export function binaryToHex(data: Uint8Array): string {
return Buffer.from(data).toString('hex'); return Buffer.from(data).toString('hex');
} }
@ -102,7 +102,7 @@ export async function loadHexFromPath(target: string): Promise<Buffer> {
export async function writeHexToPath( export async function writeHexToPath(
target: string, target: string,
data: Buffer data: Uint8Array
): Promise<void> { ): Promise<void> {
await writeFile(target, binaryToHex(data)); await writeFile(target, binaryToHex(data));
} }

View file

@ -45,9 +45,7 @@ export function fromServiceIdBinaryOrString(
context: string context: string
): ServiceIdString | undefined { ): ServiceIdString | undefined {
if (Bytes.isNotEmpty(bytes)) { if (Bytes.isNotEmpty(bytes)) {
return fromServiceIdObject( return fromServiceIdObject(ServiceId.parseFromServiceIdBinary(bytes));
ServiceId.parseFromServiceIdBinary(Buffer.from(bytes))
);
} }
if (fallback) { if (fallback) {
return normalizeServiceId(fallback, context); return normalizeServiceId(fallback, context);
@ -65,7 +63,7 @@ export function fromAciUuidBytes(
bytes: Uint8Array | undefined | null bytes: Uint8Array | undefined | null
): AciString | undefined { ): AciString | undefined {
if (Bytes.isNotEmpty(bytes)) { if (Bytes.isNotEmpty(bytes)) {
return fromAciObject(Aci.fromUuidBytes(Buffer.from(bytes))); return fromAciObject(Aci.fromUuidBytes(bytes));
} }
return undefined; return undefined;
} }
@ -102,7 +100,7 @@ export function fromPniUuidBytesOrUntaggedString(
context: string context: string
): PniString | undefined { ): PniString | undefined {
if (Bytes.isNotEmpty(bytes)) { if (Bytes.isNotEmpty(bytes)) {
return fromPniObject(Pni.fromUuidBytes(Buffer.from(bytes))); return fromPniObject(Pni.fromUuidBytes(bytes));
} }
if (fallback && isUntaggedPniString(fallback)) { if (fallback && isUntaggedPniString(fallback)) {
return normalizePni(toTaggedPni(fallback), context); return normalizePni(toTaggedPni(fallback), context);

View file

@ -31,6 +31,7 @@ import { isNightly } from './version';
import { parseStrict } from './schemas'; import { parseStrict } from './schemas';
import { DataReader } from '../sql/Client'; import { DataReader } from '../sql/Client';
import { maybeUpdateGroup } from '../groups'; import { maybeUpdateGroup } from '../groups';
import * as Bytes from '../Bytes';
import { isGroupV2 } from './whatTypeOfConversation'; import { isGroupV2 } from './whatTypeOfConversation';
const log = createLogger('groupSendEndorsements'); const log = createLogger('groupSendEndorsements');
@ -59,7 +60,7 @@ export function decodeGroupSendEndorsementResponse({
); );
const response = new GroupSendEndorsementsResponse( const response = new GroupSendEndorsementsResponse(
Buffer.from(groupSendEndorsementResponse) groupSendEndorsementResponse
); );
const expiration = response.getExpiration().getTime() / 1000; const expiration = response.getExpiration().getTime() / 1000;
@ -69,11 +70,11 @@ export function decodeGroupSendEndorsementResponse({
); );
const groupSecretParams = new GroupSecretParams( const groupSecretParams = new GroupSecretParams(
Buffer.from(groupSecretParamsBase64, 'base64') Bytes.fromBase64(groupSecretParamsBase64)
); );
const serverPublicParams = new ServerPublicParams( const serverPublicParams = new ServerPublicParams(
Buffer.from(window.getServerPublicParams(), 'base64') Bytes.fromBase64(window.getServerPublicParams())
); );
const groupMembers = groupMembersV2.map(member => { const groupMembers = groupMembersV2.map(member => {
@ -193,7 +194,7 @@ export class GroupSendEndorsementState {
#toEndorsement(contents: Uint8Array): GroupSendEndorsement { #toEndorsement(contents: Uint8Array): GroupSendEndorsement {
let endorsement = this.#endorsementCache.get(contents); let endorsement = this.#endorsementCache.get(contents);
if (endorsement == null) { if (endorsement == null) {
endorsement = new GroupSendEndorsement(Buffer.from(contents)); endorsement = new GroupSendEndorsement(contents);
this.#endorsementCache.set(contents, endorsement); this.#endorsementCache.set(contents, endorsement);
} }
return endorsement; return endorsement;
@ -201,7 +202,7 @@ export class GroupSendEndorsementState {
#toToken(endorsement: GroupSendEndorsement): GroupSendToken { #toToken(endorsement: GroupSendEndorsement): GroupSendToken {
const groupSecretParams = new GroupSecretParams( const groupSecretParams = new GroupSecretParams(
Buffer.from(this.#groupSecretParamsBase64, 'base64') Bytes.fromBase64(this.#groupSecretParamsBase64)
); );
const expiration = this.getExpiration(); const expiration = this.getExpiration();

View file

@ -269,7 +269,7 @@ async function maybeSaveToSendLog(
await insertSentProto( await insertSentProto(
{ {
timestamp, timestamp,
proto: Buffer.from(contentProto), proto: contentProto,
contentHint, contentHint,
urgent: isBoolean(urgent) ? urgent : true, urgent: isBoolean(urgent) ? urgent : true,
hasPniSignatureMessage: Boolean(hasPniSignatureMessage), hasPniSignatureMessage: Boolean(hasPniSignatureMessage),

View file

@ -678,7 +678,7 @@ async function requestResend(decryptionError: DecryptionErrorEventData) {
} }
const message = DecryptionErrorMessage.forOriginal( const message = DecryptionErrorMessage.forOriginal(
Buffer.from(cipherTextBytes), cipherTextBytes,
cipherTextType, cipherTextType,
timestamp, timestamp,
senderDevice senderDevice

View file

@ -143,7 +143,7 @@ export async function lookupConversationWithoutServiceId(
export async function checkForUsername( export async function checkForUsername(
username: string username: string
): Promise<FoundUsernameType | undefined> { ): Promise<FoundUsernameType | undefined> {
let hash: Buffer; let hash: Uint8Array;
let fixedUsername = username; let fixedUsername = username;
if (fixedUsername.startsWith('@')) { if (fixedUsername.startsWith('@')) {
fixedUsername = fixedUsername.slice(1); fixedUsername = fixedUsername.slice(1);

View file

@ -1,11 +1,13 @@
// Copyright 2024 Signal Messenger, LLC // Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only // 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 const pemContent = pem
.replace(/-----BEGIN [^-]+-----/, '') .replace(/-----BEGIN [^-]+-----/, '')
.replace(/-----END [^-]+-----/, '') .replace(/-----END [^-]+-----/, '')
.replace(/\s+/g, ''); .replace(/\s+/g, '');
const derBuffer = Buffer.from(pemContent, 'base64'); const derBuffer = Bytes.fromBase64(pemContent);
return derBuffer; return derBuffer;
} }

View file

@ -46,16 +46,16 @@ export async function generateSafetyNumber(
throw new Error('Could not load their key'); throw new Error('Could not load their key');
} }
const ourKey = PublicKey.deserialize(Buffer.from(ourKeyBuffer)); const ourKey = PublicKey.deserialize(ourKeyBuffer);
const theirKey = PublicKey.deserialize(Buffer.from(theirKeyBuffer)); const theirKey = PublicKey.deserialize(theirKeyBuffer);
assertDev(theirAci, 'Should have their serviceId'); assertDev(theirAci, 'Should have their serviceId');
const fingerprint = Fingerprint.new( const fingerprint = Fingerprint.new(
ITERATION_COUNT, ITERATION_COUNT,
SERVICE_ID_VERSION, SERVICE_ID_VERSION,
Buffer.from(uuidToBytes(ourAci)), uuidToBytes(ourAci),
ourKey, ourKey,
Buffer.from(uuidToBytes(theirAci)), uuidToBytes(theirAci),
theirKey theirKey
); );

View file

@ -26,6 +26,7 @@ import { DataWriter } from '../sql/Client';
import { getValue } from '../RemoteConfig'; import { getValue } from '../RemoteConfig';
import type { ServiceIdString } from '../types/ServiceId'; import type { ServiceIdString } from '../types/ServiceId';
import { ServiceIdKind } from '../types/ServiceId'; import { ServiceIdKind } from '../types/ServiceId';
import * as Bytes from '../Bytes';
import { isRecord } from './isRecord'; import { isRecord } from './isRecord';
import { isOlderThan } from './timestamp'; import { isOlderThan } from './timestamp';
@ -235,7 +236,7 @@ export async function sendContentMessageToGroup(
const sendLogCallback = window.textsecure.messaging.makeSendLogCallback({ const sendLogCallback = window.textsecure.messaging.makeSendLogCallback({
contentHint, contentHint,
messageId, messageId,
proto: Buffer.from(Proto.Content.encode(contentMessage).finish()), proto: Proto.Content.encode(contentMessage).finish(),
sendType, sendType,
timestamp, timestamp,
urgent, urgent,
@ -583,7 +584,7 @@ export async function sendToGroupViaSenderKey(
sendLogId = await DataWriter.insertSentProto( sendLogId = await DataWriter.insertSentProto(
{ {
contentHint, contentHint,
proto: Buffer.from(Proto.Content.encode(contentMessage).finish()), proto: Proto.Content.encode(contentMessage).finish(),
timestamp, timestamp,
urgent, urgent,
hasPniSignatureMessage: false, hasPniSignatureMessage: false,
@ -667,7 +668,7 @@ export async function sendToGroupViaSenderKey(
contentHint, contentHint,
timestamp, timestamp,
contentProto: Buffer.from(Proto.Content.encode(contentMessage).finish()), contentProto: Proto.Content.encode(contentMessage).finish(),
recipients: senderKeyRecipientsWithDevices, recipients: senderKeyRecipientsWithDevices,
urgent, urgent,
}; };
@ -1100,7 +1101,7 @@ function getXorOfAccessKeys(
'Cannot be endorsement in getXorOfAccessKeys' 'Cannot be endorsement in getXorOfAccessKeys'
); );
const accessKeyBuffer = Buffer.from(accessKey, 'base64'); const accessKeyBuffer = Bytes.fromBase64(accessKey);
if (accessKeyBuffer.length !== ACCESS_KEY_LENGTH) { if (accessKeyBuffer.length !== ACCESS_KEY_LENGTH) {
throw new Error( throw new Error(
`getXorOfAccessKeys: Access key for ${uuid} had length ${accessKeyBuffer.length}` `getXorOfAccessKeys: Access key for ${uuid} had length ${accessKeyBuffer.length}`
@ -1128,7 +1129,7 @@ async function encryptForSenderKey({
devices: Array<DeviceType>; devices: Array<DeviceType>;
distributionId: string; distributionId: string;
groupId?: string; groupId?: string;
}): Promise<Buffer> { }): Promise<Uint8Array> {
const ourAci = window.textsecure.storage.user.getCheckedAci(); const ourAci = window.textsecure.storage.user.getCheckedAci();
const ourDeviceId = window.textsecure.storage.user.getDeviceId(); const ourDeviceId = window.textsecure.storage.user.getDeviceId();
if (!ourDeviceId) { if (!ourDeviceId) {
@ -1146,7 +1147,7 @@ async function encryptForSenderKey({
ourServiceId: ourAci, ourServiceId: ourAci,
zone: GLOBAL_ZONE, zone: GLOBAL_ZONE,
}); });
const message = Buffer.from(padMessage(contentMessage)); const message = padMessage(contentMessage);
const ciphertextMessage = const ciphertextMessage =
await window.textsecure.storage.protocol.enqueueSenderKeyJob( await window.textsecure.storage.protocol.enqueueSenderKeyJob(
@ -1154,7 +1155,7 @@ async function encryptForSenderKey({
() => groupEncrypt(sender, distributionId, senderKeyStore, message) () => 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( const senderCertificateObject = await senderCertificateService.get(
SenderCertificateMode.WithoutE164 SenderCertificateMode.WithoutE164
); );
@ -1163,7 +1164,7 @@ async function encryptForSenderKey({
} }
const senderCertificate = SenderCertificate.deserialize( const senderCertificate = SenderCertificate.deserialize(
Buffer.from(senderCertificateObject.serialized) senderCertificateObject.serialized
); );
const content = UnidentifiedSenderMessageContent.new( const content = UnidentifiedSenderMessageContent.new(
ciphertextMessage, ciphertextMessage,

View file

@ -25,6 +25,7 @@ import {
fromAciObject, fromAciObject,
fromPniObject, fromPniObject,
} from '../types/ServiceId'; } from '../types/ServiceId';
import * as Bytes from '../Bytes';
import { toServiceIdObject } from './ServiceId'; import { toServiceIdObject } from './ServiceId';
import { strictAssert } from './assert'; import { strictAssert } from './assert';
@ -36,15 +37,13 @@ export function decryptGroupBlob(
clientZkGroupCipher: ClientZkGroupCipher, clientZkGroupCipher: ClientZkGroupCipher,
ciphertext: Uint8Array ciphertext: Uint8Array
): Uint8Array { ): Uint8Array {
return clientZkGroupCipher.decryptBlob(Buffer.from(ciphertext)); return clientZkGroupCipher.decryptBlob(ciphertext);
} }
export function decodeProfileKeyCredentialPresentation( export function decodeProfileKeyCredentialPresentation(
presentationBuffer: Uint8Array presentationBuffer: Uint8Array
): { profileKey: Uint8Array; userId: Uint8Array } { ): { profileKey: Uint8Array; userId: Uint8Array } {
const presentation = new ProfileKeyCredentialPresentation( const presentation = new ProfileKeyCredentialPresentation(presentationBuffer);
Buffer.from(presentationBuffer)
);
const userId = presentation.getUuidCiphertext().serialize(); const userId = presentation.getUuidCiphertext().serialize();
const profileKey = presentation.getProfileKeyCiphertext().serialize(); const profileKey = presentation.getProfileKeyCiphertext().serialize();
@ -61,7 +60,7 @@ export function decryptProfileKey(
serviceId: ServiceIdString serviceId: ServiceIdString
): Uint8Array { ): Uint8Array {
const profileKeyCiphertext = new ProfileKeyCiphertext( const profileKeyCiphertext = new ProfileKeyCiphertext(
Buffer.from(profileKeyCiphertextBuffer) profileKeyCiphertextBuffer
); );
const profileKey = clientZkGroupCipher.decryptProfileKey( const profileKey = clientZkGroupCipher.decryptProfileKey(
@ -76,7 +75,7 @@ function decryptServiceIdObj(
clientZkGroupCipher: ClientZkGroupCipher, clientZkGroupCipher: ClientZkGroupCipher,
uuidCiphertextBuffer: Uint8Array uuidCiphertextBuffer: Uint8Array
): ServiceId { ): ServiceId {
const uuidCiphertext = new UuidCiphertext(Buffer.from(uuidCiphertextBuffer)); const uuidCiphertext = new UuidCiphertext(uuidCiphertextBuffer);
return clientZkGroupCipher.decryptServiceId(uuidCiphertext); return clientZkGroupCipher.decryptServiceId(uuidCiphertext);
} }
@ -112,7 +111,7 @@ export function deriveProfileKeyVersion(
profileKeyBase64: string, profileKeyBase64: string,
serviceId: ServiceIdString serviceId: ServiceIdString
): string { ): string {
const profileKeyArray = Buffer.from(profileKeyBase64, 'base64'); const profileKeyArray = Bytes.fromBase64(profileKeyBase64);
const profileKey = new ProfileKey(profileKeyArray); const profileKey = new ProfileKey(profileKeyArray);
const profileKeyVersion = profileKey.getProfileKeyVersion( const profileKeyVersion = profileKey.getProfileKeyVersion(
@ -125,17 +124,13 @@ export function deriveProfileKeyVersion(
export function deriveGroupPublicParams( export function deriveGroupPublicParams(
groupSecretParamsBuffer: Uint8Array groupSecretParamsBuffer: Uint8Array
): Uint8Array { ): Uint8Array {
const groupSecretParams = new GroupSecretParams( const groupSecretParams = new GroupSecretParams(groupSecretParamsBuffer);
Buffer.from(groupSecretParamsBuffer)
);
return groupSecretParams.getPublicParams().serialize(); return groupSecretParams.getPublicParams().serialize();
} }
export function deriveGroupID(groupSecretParamsBuffer: Uint8Array): Uint8Array { export function deriveGroupID(groupSecretParamsBuffer: Uint8Array): Uint8Array {
const groupSecretParams = new GroupSecretParams( const groupSecretParams = new GroupSecretParams(groupSecretParamsBuffer);
Buffer.from(groupSecretParamsBuffer)
);
return groupSecretParams.getPublicParams().getGroupIdentifier().serialize(); return groupSecretParams.getPublicParams().getGroupIdentifier().serialize();
} }
@ -143,7 +138,7 @@ export function deriveGroupID(groupSecretParamsBuffer: Uint8Array): Uint8Array {
export function deriveGroupSecretParams( export function deriveGroupSecretParams(
masterKeyBuffer: Uint8Array masterKeyBuffer: Uint8Array
): Uint8Array { ): Uint8Array {
const masterKey = new GroupMasterKey(Buffer.from(masterKeyBuffer)); const masterKey = new GroupMasterKey(masterKeyBuffer);
const groupSecretParams = GroupSecretParams.deriveFromMasterKey(masterKey); const groupSecretParams = GroupSecretParams.deriveFromMasterKey(masterKey);
return groupSecretParams.serialize(); return groupSecretParams.serialize();
@ -153,7 +148,7 @@ export function encryptGroupBlob(
clientZkGroupCipher: ClientZkGroupCipher, clientZkGroupCipher: ClientZkGroupCipher,
plaintext: Uint8Array plaintext: Uint8Array
): Uint8Array { ): Uint8Array {
return clientZkGroupCipher.encryptBlob(Buffer.from(plaintext)); return clientZkGroupCipher.encryptBlob(plaintext);
} }
export function encryptServiceId( export function encryptServiceId(
@ -172,7 +167,7 @@ export function generateProfileKeyCredentialRequest(
serviceId: ServiceIdString, serviceId: ServiceIdString,
profileKeyBase64: string profileKeyBase64: string
): { context: ProfileKeyCredentialRequestContext; requestHex: string } { ): { context: ProfileKeyCredentialRequestContext; requestHex: string } {
const profileKeyArray = Buffer.from(profileKeyBase64, 'base64'); const profileKeyArray = Bytes.fromBase64(profileKeyBase64);
const profileKey = new ProfileKey(profileKeyArray); const profileKey = new ProfileKey(profileKeyArray);
const context = const context =
@ -185,7 +180,7 @@ export function generateProfileKeyCredentialRequest(
return { return {
context, context,
requestHex: requestArray.toString('hex'), requestHex: Bytes.toHex(requestArray),
}; };
} }
@ -195,10 +190,10 @@ export function getAuthCredentialPresentation(
groupSecretParamsBase64: string groupSecretParamsBase64: string
): Uint8Array { ): Uint8Array {
const authCredential = new AuthCredentialWithPni( const authCredential = new AuthCredentialWithPni(
Buffer.from(authCredentialBase64, 'base64') Bytes.fromBase64(authCredentialBase64)
); );
const secretParams = new GroupSecretParams( const secretParams = new GroupSecretParams(
Buffer.from(groupSecretParamsBase64, 'base64') Bytes.fromBase64(groupSecretParamsBase64)
); );
const presentation = const presentation =
@ -214,15 +209,14 @@ export function createProfileKeyCredentialPresentation(
profileKeyCredentialBase64: string, profileKeyCredentialBase64: string,
groupSecretParamsBase64: string groupSecretParamsBase64: string
): Uint8Array { ): Uint8Array {
const profileKeyCredentialArray = Buffer.from( const profileKeyCredentialArray = Bytes.fromBase64(
profileKeyCredentialBase64, profileKeyCredentialBase64
'base64'
); );
const profileKeyCredential = new ExpiringProfileKeyCredential( const profileKeyCredential = new ExpiringProfileKeyCredential(
profileKeyCredentialArray profileKeyCredentialArray
); );
const secretParams = new GroupSecretParams( const secretParams = new GroupSecretParams(
Buffer.from(groupSecretParamsBase64, 'base64') Bytes.fromBase64(groupSecretParamsBase64)
); );
const presentation = const presentation =
@ -238,7 +232,7 @@ export function getClientZkAuthOperations(
serverPublicParamsBase64: string serverPublicParamsBase64: string
): ClientZkAuthOperations { ): ClientZkAuthOperations {
const serverPublicParams = new ServerPublicParams( const serverPublicParams = new ServerPublicParams(
Buffer.from(serverPublicParamsBase64, 'base64') Bytes.fromBase64(serverPublicParamsBase64)
); );
return new ClientZkAuthOperations(serverPublicParams); return new ClientZkAuthOperations(serverPublicParams);
@ -248,7 +242,7 @@ export function getClientZkGroupCipher(
groupSecretParamsBase64: string groupSecretParamsBase64: string
): ClientZkGroupCipher { ): ClientZkGroupCipher {
const serverPublicParams = new GroupSecretParams( const serverPublicParams = new GroupSecretParams(
Buffer.from(groupSecretParamsBase64, 'base64') Bytes.fromBase64(groupSecretParamsBase64)
); );
return new ClientZkGroupCipher(serverPublicParams); return new ClientZkGroupCipher(serverPublicParams);
@ -258,7 +252,7 @@ export function getClientZkProfileOperations(
serverPublicParamsBase64: string serverPublicParamsBase64: string
): ClientZkProfileOperations { ): ClientZkProfileOperations {
const serverPublicParams = new ServerPublicParams( const serverPublicParams = new ServerPublicParams(
Buffer.from(serverPublicParamsBase64, 'base64') Bytes.fromBase64(serverPublicParamsBase64)
); );
return new ClientZkProfileOperations(serverPublicParams); return new ClientZkProfileOperations(serverPublicParams);
@ -270,7 +264,7 @@ export function handleProfileKeyCredential(
responseBase64: string responseBase64: string
): { credential: string; expiration: number } { ): { credential: string; expiration: number } {
const response = new ExpiringProfileKeyCredentialResponse( const response = new ExpiringProfileKeyCredentialResponse(
Buffer.from(responseBase64, 'base64') Bytes.fromBase64(responseBase64)
); );
const profileKeyCredential = const profileKeyCredential =
clientZkProfileCipher.receiveExpiringProfileKeyCredential( clientZkProfileCipher.receiveExpiringProfileKeyCredential(
@ -281,7 +275,7 @@ export function handleProfileKeyCredential(
const credentialArray = profileKeyCredential.serialize(); const credentialArray = profileKeyCredential.serialize();
return { return {
credential: credentialArray.toString('base64'), credential: Bytes.toBase64(credentialArray),
expiration: profileKeyCredential.getExpirationTime().getTime(), expiration: profileKeyCredential.getExpirationTime().getTime(),
}; };
} }
@ -290,12 +284,14 @@ export function deriveProfileKeyCommitment(
profileKeyBase64: string, profileKeyBase64: string,
serviceId: ServiceIdString serviceId: ServiceIdString
): string { ): string {
const profileKeyArray = Buffer.from(profileKeyBase64, 'base64'); const profileKeyArray = Bytes.fromBase64(profileKeyBase64);
const profileKey = new ProfileKey(profileKeyArray); const profileKey = new ProfileKey(profileKeyArray);
return profileKey const commitment = profileKey.getCommitment(
.getCommitment(toServiceIdObject(serviceId)) toServiceIdObject(serviceId)
.contents.toString('base64'); ).contents;
return Bytes.toBase64(commitment);
} }
export function verifyNotarySignature( export function verifyNotarySignature(
@ -304,10 +300,10 @@ export function verifyNotarySignature(
signature: Uint8Array signature: Uint8Array
): void { ): void {
const serverPublicParams = new ServerPublicParams( 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);
} }