mirror of
https://github.com/mautrix/signal.git
synced 2026-09-16 07:42:05 -04:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7712f57b84 | ||
|
|
b618061a0a | ||
|
|
6ae9367ab5 |
191 changed files with 7030 additions and 49777 deletions
3
.github/ISSUE_TEMPLATE/bug.md
vendored
3
.github/ISSUE_TEMPLATE/bug.md
vendored
|
|
@ -11,8 +11,7 @@ type: Bug
|
||||||
|
|
||||||
### Checklist
|
### Checklist
|
||||||
|
|
||||||
<!-- All items below are mandatory. Issues not following the rules may be closed without comment. -->
|
<!-- Both items below are mandatory. Issues not following the rules may be closed without comment. -->
|
||||||
|
|
||||||
* [ ] This is an actual bug, not just a setup issue (see the [troubleshooting docs](https://docs.mau.fi/bridges/general/troubleshooting.html) or ask in the Matrix room for setup help).
|
* [ ] This is an actual bug, not just a setup issue (see the [troubleshooting docs](https://docs.mau.fi/bridges/general/troubleshooting.html) or ask in the Matrix room for setup help).
|
||||||
* [ ] I am certain that sufficient information is included. Ask in the Matrix room first if not.
|
* [ ] I am certain that sufficient information is included. Ask in the Matrix room first if not.
|
||||||
* [ ] The bug is still present on the main branch. The `!signal version` command output is: ``
|
|
||||||
|
|
|
||||||
16
.github/workflows/go.yml
vendored
16
.github/workflows/go.yml
vendored
|
|
@ -11,14 +11,14 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
go-version: ["1.26", "1.27"]
|
go-version: ["1.25", "1.26"]
|
||||||
name: Lint ${{ matrix.go-version == '1.27' && '(latest)' || '(old)' }}
|
name: Lint ${{ matrix.go-version == '1.26' && '(latest)' || '(old)' }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v7
|
- uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v7
|
uses: actions/setup-go@v6
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go-version }}
|
go-version: ${{ matrix.go-version }}
|
||||||
cache: true
|
cache: true
|
||||||
|
|
@ -40,14 +40,14 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
go-version: ["1.26", "1.27"]
|
go-version: ["1.25", "1.26"]
|
||||||
name: Test ${{ matrix.go-version == '1.27' && '(latest)' || '(old)' }}
|
name: Test ${{ matrix.go-version == '1.26' && '(latest)' || '(old)' }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v7
|
- uses: actions/checkout@v6
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v7
|
uses: actions/setup-go@v6
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go-version }}
|
go-version: ${{ matrix.go-version }}
|
||||||
cache: true
|
cache: true
|
||||||
|
|
|
||||||
43
CHANGELOG.md
43
CHANGELOG.md
|
|
@ -1,46 +1,3 @@
|
||||||
# v26.09
|
|
||||||
|
|
||||||
* Bumped minimum Go version to 1.26.
|
|
||||||
* Updated libsignal to v1.102.2.
|
|
||||||
* Fixed handling messages with invalid values in formatting body ranges.
|
|
||||||
* Fixed websocket request retrying not working correctly if the first attempt
|
|
||||||
times out.
|
|
||||||
* Fixed another potential race condition with edited message bridging.
|
|
||||||
|
|
||||||
# v26.08
|
|
||||||
|
|
||||||
* Updated libsignal to v0.100.0
|
|
||||||
* Added support for handling own profile key changes.
|
|
||||||
* Changed attachment bridging behavior to match Signal Desktop.
|
|
||||||
* Fixed edited messages being bridged twice if certain race conditions occurred.
|
|
||||||
|
|
||||||
# v26.07
|
|
||||||
|
|
||||||
* Updated Docker image to Alpine 3.24.
|
|
||||||
* Updated libsignal to v0.97.2.
|
|
||||||
* Added automatic retry when sender key send fails due to missing session.
|
|
||||||
* Fixed changing poll votes from Matrix.
|
|
||||||
|
|
||||||
# v26.06
|
|
||||||
|
|
||||||
* Updated libsignal to v0.94.4.
|
|
||||||
* Updated mrenclave to fix looking up phone numbers.
|
|
||||||
* Changed knock accept handling to auto-join the ghost user afterwards.
|
|
||||||
|
|
||||||
# v26.05
|
|
||||||
|
|
||||||
* Updated libsignal to v0.93.2.
|
|
||||||
* Added support for importing sticker packs from Signal.
|
|
||||||
|
|
||||||
# v26.04
|
|
||||||
|
|
||||||
* Updated libsignal to v0.92.1.
|
|
||||||
* Added support for admin message deletes from Signal.
|
|
||||||
* Added support for binary service IDs in storage service.
|
|
||||||
* Fixed `private_chat_portal_meta` option not setting DM room names correctly.
|
|
||||||
* Fixed panic if user is logged out during initial chat sync.
|
|
||||||
* Fixed avatar upload failing when creating new Signal group.
|
|
||||||
|
|
||||||
# v26.03
|
# v26.03
|
||||||
|
|
||||||
* Switched to sending binary service ID fields in outgoing messages.
|
* Switched to sending binary service ID fields in outgoing messages.
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
See <https://docs.mau.fi/bridges/general/contributing.html>
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# -- Build libsignal (with Rust) --
|
# -- Build libsignal (with Rust) --
|
||||||
FROM rust:1-alpine AS rust-builder
|
FROM rust:1-alpine AS rust-builder
|
||||||
RUN apk add --no-cache git make cmake protoc musl-dev g++ clang-dev protobuf-dev
|
RUN apk add --no-cache git make cmake protoc musl-dev g++ clang-dev
|
||||||
|
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
# Copy all files needed for Rust build, and no Go files
|
# Copy all files needed for Rust build, and no Go files
|
||||||
|
|
@ -10,7 +10,7 @@ COPY build-rust.sh .
|
||||||
RUN ./build-rust.sh
|
RUN ./build-rust.sh
|
||||||
|
|
||||||
# -- Build mautrix-signal (with Go) --
|
# -- Build mautrix-signal (with Go) --
|
||||||
FROM golang:1-alpine3.24 AS go-builder
|
FROM golang:1-alpine3.23 AS go-builder
|
||||||
RUN apk add --no-cache git ca-certificates build-base olm-dev zlib-dev
|
RUN apk add --no-cache git ca-certificates build-base olm-dev zlib-dev
|
||||||
|
|
||||||
WORKDIR /build
|
WORKDIR /build
|
||||||
|
|
@ -32,7 +32,7 @@ EOF
|
||||||
RUN ./build-go.sh
|
RUN ./build-go.sh
|
||||||
|
|
||||||
# -- Run mautrix-signal --
|
# -- Run mautrix-signal --
|
||||||
FROM alpine:3.24
|
FROM alpine:3.23
|
||||||
|
|
||||||
ENV UID=1337 \
|
ENV UID=1337 \
|
||||||
GID=1337
|
GID=1337
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
ARG DOCKER_HUB="docker.io"
|
ARG DOCKER_HUB="docker.io"
|
||||||
|
|
||||||
FROM ${DOCKER_HUB}/alpine:3.24
|
FROM ${DOCKER_HUB}/alpine:3.23
|
||||||
|
|
||||||
ENV UID=1337 \
|
ENV UID=1337 \
|
||||||
GID=1337
|
GID=1337
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ var m = mxmain.BridgeMain{
|
||||||
Name: "mautrix-signal",
|
Name: "mautrix-signal",
|
||||||
URL: "https://github.com/mautrix/signal",
|
URL: "https://github.com/mautrix/signal",
|
||||||
Description: "A Matrix-Signal puppeting bridge.",
|
Description: "A Matrix-Signal puppeting bridge.",
|
||||||
Version: "26.09",
|
Version: "26.03",
|
||||||
SemCalVer: true,
|
SemCalVer: true,
|
||||||
|
|
||||||
Connector: &connector.SignalConnector{},
|
Connector: &connector.SignalConnector{},
|
||||||
|
|
|
||||||
44
go.mod
44
go.mod
|
|
@ -1,51 +1,51 @@
|
||||||
module go.mau.fi/mautrix-signal
|
module go.mau.fi/mautrix-signal
|
||||||
|
|
||||||
go 1.26.0
|
go 1.25.0
|
||||||
|
|
||||||
toolchain go1.27.1
|
toolchain go1.26.1
|
||||||
|
|
||||||
tool go.mau.fi/util/cmd/maubuild
|
tool go.mau.fi/util/cmd/maubuild
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/coder/websocket v1.8.15
|
github.com/coder/websocket v1.8.14
|
||||||
github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff
|
github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/mattn/go-pointer v0.0.1
|
github.com/mattn/go-pointer v0.0.1
|
||||||
github.com/rs/zerolog v1.35.1
|
github.com/rs/zerolog v1.35.0
|
||||||
github.com/stretchr/testify v1.12.0
|
github.com/stretchr/testify v1.11.1
|
||||||
github.com/tidwall/gjson v1.19.0
|
github.com/tidwall/gjson v1.18.0
|
||||||
go.mau.fi/util v0.10.1
|
go.mau.fi/util v0.9.8-0.20260406161447-0300c476893a
|
||||||
golang.org/x/crypto v0.57.0
|
golang.org/x/crypto v0.49.0
|
||||||
golang.org/x/exp v0.0.0-20260908205506-85c1c2202aba
|
golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90
|
||||||
golang.org/x/net v0.59.0
|
golang.org/x/net v0.52.0
|
||||||
golang.org/x/sync v0.23.0
|
google.golang.org/protobuf v1.36.11
|
||||||
google.golang.org/grpc v1.83.2
|
|
||||||
google.golang.org/protobuf v1.36.12
|
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
maunium.net/go/mautrix v0.31.0
|
maunium.net/go/mautrix v0.26.5-0.20260410220226-744570e6f1f5
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
filippo.io/edwards25519 v1.2.0 // indirect
|
filippo.io/edwards25519 v1.2.0 // indirect
|
||||||
github.com/coreos/go-systemd/v22 v22.7.0 // indirect
|
github.com/coreos/go-systemd/v22 v22.7.0 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/kr/pretty v0.3.1 // indirect
|
github.com/kr/pretty v0.3.1 // indirect
|
||||||
github.com/lib/pq v1.12.3 // indirect
|
github.com/lib/pq v1.12.0 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/mattn/go-sqlite3 v1.14.52 // indirect
|
github.com/mattn/go-sqlite3 v1.14.37 // indirect
|
||||||
github.com/petermattis/goid v0.0.0-20260820044319-269ab09b5261 // indirect
|
github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/rogpeppe/go-internal v1.10.0 // indirect
|
github.com/rogpeppe/go-internal v1.10.0 // indirect
|
||||||
github.com/rs/xid v1.6.0 // indirect
|
github.com/rs/xid v1.6.0 // indirect
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
|
||||||
github.com/tidwall/match v1.2.0 // indirect
|
github.com/tidwall/match v1.2.0 // indirect
|
||||||
github.com/tidwall/pretty v1.2.1 // indirect
|
github.com/tidwall/pretty v1.2.1 // indirect
|
||||||
github.com/tidwall/sjson v1.2.5 // indirect
|
github.com/tidwall/sjson v1.2.5 // indirect
|
||||||
github.com/yuin/goldmark v1.8.6 // indirect
|
github.com/yuin/goldmark v1.8.2 // indirect
|
||||||
go.mau.fi/zeroconfig v0.2.0 // indirect
|
go.mau.fi/zeroconfig v0.2.0 // indirect
|
||||||
golang.org/x/mod v0.41.0 // indirect
|
golang.org/x/mod v0.34.0 // indirect
|
||||||
golang.org/x/sys v0.48.0 // indirect
|
golang.org/x/sync v0.20.0 // indirect
|
||||||
golang.org/x/text v0.42.0 // indirect
|
golang.org/x/sys v0.42.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect
|
golang.org/x/text v0.35.0 // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||||
maunium.net/go/mauflag v1.0.0 // indirect
|
maunium.net/go/mauflag v1.0.0 // indirect
|
||||||
|
|
|
||||||
102
go.sum
102
go.sum
|
|
@ -2,21 +2,15 @@ filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo=
|
||||||
filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc=
|
filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc=
|
||||||
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
|
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
|
||||||
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
|
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/coder/websocket v1.8.14 h1:9L0p0iKiNOibykf283eHkKUHHrpG7f65OE3BhhO7v9g=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/coder/websocket v1.8.14/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg=
|
||||||
github.com/coder/websocket v1.8.15 h1:6B2JPeOGlpff2Uz6vOEH1Vzpi0iUz20A+lPVhPHtNUA=
|
|
||||||
github.com/coder/websocket v1.8.15/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg=
|
|
||||||
github.com/coreos/go-systemd/v22 v22.7.0 h1:LAEzFkke61DFROc7zNLX/WA2i5J8gYqe0rSj9KI28KA=
|
github.com/coreos/go-systemd/v22 v22.7.0 h1:LAEzFkke61DFROc7zNLX/WA2i5J8gYqe0rSj9KI28KA=
|
||||||
github.com/coreos/go-systemd/v22 v22.7.0/go.mod h1:xNUYtjHu2EDXbsxz1i41wouACIwT7Ybq9o0BQhMwD0w=
|
github.com/coreos/go-systemd/v22 v22.7.0/go.mod h1:xNUYtjHu2EDXbsxz1i41wouACIwT7Ybq9o0BQhMwD0w=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff h1:4N8wnS3f1hNHSmFD5zgFkWCyA4L1kCDkImPAtK7D6tg=
|
github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff h1:4N8wnS3f1hNHSmFD5zgFkWCyA4L1kCDkImPAtK7D6tg=
|
||||||
github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff/go.mod h1:HMJKR5wlh/ziNp+sHEDV2ltblO4JD2+IdDOWtGcQBTM=
|
github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff/go.mod h1:HMJKR5wlh/ziNp+sHEDV2ltblO4JD2+IdDOWtGcQBTM=
|
||||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
|
||||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
|
||||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
|
||||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
|
||||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
|
||||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
|
||||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
|
|
@ -28,33 +22,35 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/lib/pq v1.12.3 h1:tTWxr2YLKwIvK90ZXEw8GP7UFHtcbTtty8zsI+YjrfQ=
|
github.com/lib/pq v1.12.0 h1:mC1zeiNamwKBecjHarAr26c/+d8V5w/u4J0I/yASbJo=
|
||||||
github.com/lib/pq v1.12.3/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA=
|
github.com/lib/pq v1.12.0/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA=
|
||||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0=
|
github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0=
|
||||||
github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
|
github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
|
||||||
github.com/mattn/go-sqlite3 v1.14.52 h1:wVbm2Qnf4OXkqhBTSPuCRZDRnxfbVrrmiCEroVdog8U=
|
github.com/mattn/go-sqlite3 v1.14.37 h1:3DOZp4cXis1cUIpCfXLtmlGolNLp2VEqhiB/PARNBIg=
|
||||||
github.com/mattn/go-sqlite3 v1.14.52/go.mod h1:6JTjA44L93a0QCyJef5YvlPoKXntQPjzWv5gtm9sB6w=
|
github.com/mattn/go-sqlite3 v1.14.37/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||||
github.com/petermattis/goid v0.0.0-20260820044319-269ab09b5261 h1:lcWAnrqr2nNfDiArwFNHCE4787Mw2tCdVSOXCru0/0E=
|
github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 h1:rh2lKw/P/EqHa724vYH2+VVQ1YnW4u6EOXl0PMAovZE=
|
||||||
github.com/petermattis/goid v0.0.0-20260820044319-269ab09b5261/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
|
github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
|
||||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||||
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
|
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
|
||||||
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||||
github.com/rs/zerolog v1.35.1 h1:m7xQeoiLIiV0BCEY4Hs+j2NG4Gp2o2KPKmhnnLiazKI=
|
github.com/rs/zerolog v1.35.0 h1:VD0ykx7HMiMJytqINBsKcbLS+BJ4WYjz+05us+LRTdI=
|
||||||
github.com/rs/zerolog v1.35.1/go.mod h1:EjML9kdfa/RMA7h/6z6pYmq1ykOuA8/mjWaEvGI+jcw=
|
github.com/rs/zerolog v1.35.0/go.mod h1:EjML9kdfa/RMA7h/6z6pYmq1ykOuA8/mjWaEvGI+jcw=
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
||||||
github.com/stretchr/testify v1.12.0 h1:K6Mr6jO9JICuend/5xzTM03ydSV3vdNRYAdPSukj8uI=
|
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||||
github.com/stretchr/testify v1.12.0/go.mod h1:bOYBZb5qJ00vPzWfIqBUZPaxK8jWiXc6d3ErP4Ca9Gw=
|
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||||
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
github.com/tidwall/gjson v1.19.0 h1:xwxm7n691Uf3u5OFjzngavjGTh55KX5q/9w9xHW88JU=
|
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
||||||
github.com/tidwall/gjson v1.19.0/go.mod h1:V37/opeE/JbLUOfH0QTXiNez2l0RUjYUhpT4szFQAfc=
|
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||||
github.com/tidwall/match v1.2.0 h1:0pt8FlkOwjN2fPt4bIl4BoNxb98gGHN2ObFEDkrfZnM=
|
github.com/tidwall/match v1.2.0 h1:0pt8FlkOwjN2fPt4bIl4BoNxb98gGHN2ObFEDkrfZnM=
|
||||||
github.com/tidwall/match v1.2.0/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
github.com/tidwall/match v1.2.0/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||||
|
|
@ -63,47 +59,29 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||||
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||||
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||||
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||||
github.com/yuin/goldmark v1.8.6 h1:d0VcaP1sx9GkFVkoW+KtggpGi2KZ965i14b0+bDQST4=
|
github.com/yuin/goldmark v1.8.2 h1:kEGpgqJXdgbkhcOgBxkC0X0PmoPG1ZyoZ117rDVp4zE=
|
||||||
github.com/yuin/goldmark v1.8.6/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
|
github.com/yuin/goldmark v1.8.2/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
|
||||||
go.mau.fi/util v0.10.1 h1:1oSqb4TwzLA0cUDY0aomyBPFKkZ3J5fqCmrXV3VH3GQ=
|
go.mau.fi/util v0.9.8-0.20260406161447-0300c476893a h1:OQQF3rTJH10l6+dcP0OKnYbNDMBTGoIZZINNJm8QBG8=
|
||||||
go.mau.fi/util v0.10.1/go.mod h1:40TDo7/ekSeOjgr8KAmX31Yf4zrOF94j83WQB+u5ZPc=
|
go.mau.fi/util v0.9.8-0.20260406161447-0300c476893a/go.mod h1:5T2f3ZWZFAGgmFwg3dGw7YK6kIsb9lryDzvynoR98pE=
|
||||||
go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU=
|
go.mau.fi/zeroconfig v0.2.0 h1:e/OGEERqVRRKlgaro7E6bh8xXiKFSXB3eNNIud7FUjU=
|
||||||
go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w=
|
go.mau.fi/zeroconfig v0.2.0/go.mod h1:J0Vn0prHNOm493oZoQ84kq83ZaNCYZnq+noI1b1eN8w=
|
||||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=
|
||||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=
|
||||||
go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
|
golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 h1:jiDhWWeC7jfWqR9c/uplMOqJ0sbNlNWv0UkzE0vX1MA=
|
||||||
go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
|
golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90/go.mod h1:xE1HEv6b+1SCZ5/uscMRjUBKtIxworgEcEi+/n9NQDQ=
|
||||||
go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=
|
golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI=
|
||||||
go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=
|
golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY=
|
||||||
go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58=
|
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
|
||||||
go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0=
|
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI=
|
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA=
|
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||||
go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
|
|
||||||
go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
|
|
||||||
golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M=
|
|
||||||
golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA=
|
|
||||||
golang.org/x/exp v0.0.0-20260908205506-85c1c2202aba h1:Ck8QetSgk912qxWLMCKxd0in+aiyBQyDSMae6e/xmpU=
|
|
||||||
golang.org/x/exp v0.0.0-20260908205506-85c1c2202aba/go.mod h1:50RgIsmK7OwqzTTeqcSXQW8SswW0o8fRcDxmqGluJ8E=
|
|
||||||
golang.org/x/mod v0.41.0 h1:qJmnOUb4YB+FsEuM3HcWucdZASCPGhsX6uljO6pog0c=
|
|
||||||
golang.org/x/mod v0.41.0/go.mod h1:Ek9pY8RKWXwsWvd3rQiHYtMqkjSUV+s1Rj7j4H5Ur6o=
|
|
||||||
golang.org/x/net v0.59.0 h1:5zfYln+w5XCxwrnMMJPufRgNoXEaGxl0wo5GqPXyues=
|
|
||||||
golang.org/x/net v0.59.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg=
|
|
||||||
golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk=
|
|
||||||
golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0=
|
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo=
|
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
|
||||||
golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=
|
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||||
golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI=
|
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
|
||||||
golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E=
|
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
|
||||||
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
|
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||||
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
|
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk=
|
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
|
||||||
google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU=
|
|
||||||
google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8=
|
|
||||||
google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
|
|
||||||
google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
|
|
@ -113,5 +91,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M=
|
maunium.net/go/mauflag v1.0.0 h1:YiaRc0tEI3toYtJMRIfjP+jklH45uDHtT80nUamyD4M=
|
||||||
maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA=
|
maunium.net/go/mauflag v1.0.0/go.mod h1:nLivPOpTpHnpzEh8jEdSL9UqO9+/KBJFmNRlwKfkPeA=
|
||||||
maunium.net/go/mautrix v0.31.0 h1:x6XNBSa0kOaBgcleI+ZBLkGvBdHIE0qdeY6TZ4wWUeI=
|
maunium.net/go/mautrix v0.26.5-0.20260410220226-744570e6f1f5 h1:icMEYdJZfRKWXf5AyPk/2jncA84DmfxzrjhCZ4Mm/PE=
|
||||||
maunium.net/go/mautrix v0.31.0/go.mod h1:vfPYtoGAjlTnIF+W8tl+rjX3yB4PEfqYR2sDXvQo4Co=
|
maunium.net/go/mautrix v0.26.5-0.20260410220226-744570e6f1f5/go.mod h1:MX4DQLiBe0c7sI/wizruqdxHinSOWs42/DYsP9GH7Q4=
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ func supportedIfFFmpeg() event.CapabilitySupportLevel {
|
||||||
}
|
}
|
||||||
|
|
||||||
func capID() string {
|
func capID() string {
|
||||||
base := "fi.mau.signal.capabilities.2026_07_22"
|
base := "fi.mau.signal.capabilities.2025_12_09"
|
||||||
if ffmpeg.Supported() {
|
if ffmpeg.Supported() {
|
||||||
return base + "+ffmpeg"
|
return base + "+ffmpeg"
|
||||||
}
|
}
|
||||||
|
|
@ -77,7 +77,6 @@ var signalCaps = &event.RoomFeatures{
|
||||||
"image/jpeg": event.CapLevelFullySupported,
|
"image/jpeg": event.CapLevelFullySupported,
|
||||||
"image/webp": event.CapLevelFullySupported,
|
"image/webp": event.CapLevelFullySupported,
|
||||||
"image/bmp": event.CapLevelFullySupported,
|
"image/bmp": event.CapLevelFullySupported,
|
||||||
"image/avif": event.CapLevelFullySupported,
|
|
||||||
},
|
},
|
||||||
MaxWidth: 4096,
|
MaxWidth: 4096,
|
||||||
MaxHeight: 4096,
|
MaxHeight: 4096,
|
||||||
|
|
@ -99,8 +98,6 @@ var signalCaps = &event.RoomFeatures{
|
||||||
MimeTypes: map[string]event.CapabilitySupportLevel{
|
MimeTypes: map[string]event.CapabilitySupportLevel{
|
||||||
"audio/aac": event.CapLevelFullySupported,
|
"audio/aac": event.CapLevelFullySupported,
|
||||||
"audio/mpeg": event.CapLevelFullySupported,
|
"audio/mpeg": event.CapLevelFullySupported,
|
||||||
"audio/mp3": event.CapLevelFullySupported,
|
|
||||||
"audio/flac": event.CapLevelFullySupported,
|
|
||||||
},
|
},
|
||||||
MaxSize: MaxFileSize,
|
MaxSize: MaxFileSize,
|
||||||
},
|
},
|
||||||
|
|
@ -114,8 +111,7 @@ var signalCaps = &event.RoomFeatures{
|
||||||
},
|
},
|
||||||
event.CapMsgSticker: {
|
event.CapMsgSticker: {
|
||||||
MimeTypes: map[string]event.CapabilitySupportLevel{
|
MimeTypes: map[string]event.CapabilitySupportLevel{
|
||||||
// Signal clients will only render static webp, so apng is preferred
|
"image/webp": event.CapLevelFullySupported,
|
||||||
"image/webp": event.CapLevelPartialSupport,
|
|
||||||
"image/png": event.CapLevelFullySupported,
|
"image/png": event.CapLevelFullySupported,
|
||||||
"image/apng": event.CapLevelFullySupported,
|
"image/apng": event.CapLevelFullySupported,
|
||||||
"image/gif": supportedIfFFmpeg(),
|
"image/gif": supportedIfFFmpeg(),
|
||||||
|
|
@ -154,23 +150,18 @@ var signalCaps = &event.RoomFeatures{
|
||||||
event.MemberActionBan: event.CapLevelFullySupported,
|
event.MemberActionBan: event.CapLevelFullySupported,
|
||||||
event.MemberActionKick: event.CapLevelFullySupported,
|
event.MemberActionKick: event.CapLevelFullySupported,
|
||||||
},
|
},
|
||||||
MaxTextLength: MaxTextLength, // TODO support arbitrary sized text messages with files
|
MaxTextLength: MaxTextLength, // TODO support arbitrary sized text messages with files
|
||||||
LocationMessage: event.CapLevelPartialSupport,
|
LocationMessage: event.CapLevelPartialSupport,
|
||||||
Poll: event.CapLevelFullySupported,
|
Poll: event.CapLevelRejected,
|
||||||
PollEnd: event.CapLevelUnsupported,
|
Thread: event.CapLevelUnsupported,
|
||||||
PollHiddenVotes: event.CapLevelUnsupported,
|
Reply: event.CapLevelFullySupported,
|
||||||
PollDuplicateOptions: event.CapLevelFullySupported,
|
Edit: event.CapLevelFullySupported,
|
||||||
PollMaxOptions: 10,
|
EditMaxCount: 10,
|
||||||
PollOptionMaxLength: 100,
|
EditMaxAge: ptr.Ptr(jsontime.S(24 * time.Hour)),
|
||||||
Thread: event.CapLevelUnsupported,
|
Delete: event.CapLevelFullySupported,
|
||||||
Reply: event.CapLevelFullySupported,
|
DeleteForMe: false,
|
||||||
Edit: event.CapLevelFullySupported,
|
DeleteMaxAge: ptr.Ptr(jsontime.S(24 * time.Hour)),
|
||||||
EditMaxCount: 10,
|
DisappearingTimer: signalDisappearingCap,
|
||||||
EditMaxAge: ptr.Ptr(jsontime.S(24 * time.Hour)),
|
|
||||||
Delete: event.CapLevelFullySupported,
|
|
||||||
DeleteForMe: false,
|
|
||||||
DeleteMaxAge: ptr.Ptr(jsontime.S(24 * time.Hour)),
|
|
||||||
DisappearingTimer: signalDisappearingCap,
|
|
||||||
|
|
||||||
Reaction: event.CapLevelFullySupported,
|
Reaction: event.CapLevelFullySupported,
|
||||||
ReactionCount: 1,
|
ReactionCount: 1,
|
||||||
|
|
@ -220,7 +211,6 @@ var signalGeneralCaps = &bridgev2.NetworkGeneralCapabilities{
|
||||||
AggressiveUpdateInfo: true,
|
AggressiveUpdateInfo: true,
|
||||||
ImplicitReadReceipts: true,
|
ImplicitReadReceipts: true,
|
||||||
Provisioning: bridgev2.ProvisioningCapabilities{
|
Provisioning: bridgev2.ProvisioningCapabilities{
|
||||||
ImagePackImport: true,
|
|
||||||
ResolveIdentifier: bridgev2.ResolveIdentifierCapabilities{
|
ResolveIdentifier: bridgev2.ResolveIdentifierCapabilities{
|
||||||
CreateDM: true,
|
CreateDM: true,
|
||||||
LookupPhone: true,
|
LookupPhone: true,
|
||||||
|
|
@ -245,5 +235,5 @@ func (s *SignalConnector) GetCapabilities() *bridgev2.NetworkGeneralCapabilities
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SignalConnector) GetBridgeInfoVersion() (info, capabilities int) {
|
func (s *SignalConnector) GetBridgeInfoVersion() (info, capabilities int) {
|
||||||
return 1, 11
|
return 1, 7
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -151,10 +151,7 @@ func (s *SignalClient) syncChats(ctx context.Context, cancel context.CancelFunc)
|
||||||
groupID := types.GroupIdentifier(base64.StdEncoding.EncodeToString(rawGroupID[:]))
|
groupID := types.GroupIdentifier(base64.StdEncoding.EncodeToString(rawGroupID[:]))
|
||||||
groupInfo, err := s.getGroupInfo(ctx, groupID, dest.Group.GetSnapshot().GetVersion(), chat)
|
groupInfo, err := s.getGroupInfo(ctx, groupID, dest.Group.GetSnapshot().GetVersion(), chat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zerolog.Ctx(ctx).Err(err).
|
zerolog.Ctx(ctx).Err(err).Msg("Failed to get full group info")
|
||||||
Uint64("recipient_id", recipient.Id).
|
|
||||||
Stringer("group_id", groupID).
|
|
||||||
Msg("Failed to get full group info")
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
resyncEvt.PortalKey = s.makePortalKey(string(groupID))
|
resyncEvt.PortalKey = s.makePortalKey(string(groupID))
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ import (
|
||||||
"maunium.net/go/mautrix/bridgev2"
|
"maunium.net/go/mautrix/bridgev2"
|
||||||
"maunium.net/go/mautrix/bridgev2/networkid"
|
"maunium.net/go/mautrix/bridgev2/networkid"
|
||||||
"maunium.net/go/mautrix/bridgev2/status"
|
"maunium.net/go/mautrix/bridgev2/status"
|
||||||
"maunium.net/go/mautrix/event"
|
|
||||||
|
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalid"
|
"go.mau.fi/mautrix-signal/pkg/signalid"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow"
|
"go.mau.fi/mautrix-signal/pkg/signalmeow"
|
||||||
|
|
@ -47,7 +46,6 @@ type SignalClient struct {
|
||||||
var (
|
var (
|
||||||
_ bridgev2.NetworkAPI = (*SignalClient)(nil)
|
_ bridgev2.NetworkAPI = (*SignalClient)(nil)
|
||||||
_ bridgev2.BackgroundSyncingNetworkAPI = (*SignalClient)(nil)
|
_ bridgev2.BackgroundSyncingNetworkAPI = (*SignalClient)(nil)
|
||||||
_ bridgev2.StickerImportingNetworkAPI = (*SignalClient)(nil)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var pushCfg = &bridgev2.PushConfig{
|
var pushCfg = &bridgev2.PushConfig{
|
||||||
|
|
@ -78,14 +76,6 @@ func (s *SignalClient) RegisterPushNotifications(ctx context.Context, pushType b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SignalClient) DownloadImagePack(ctx context.Context, url string) (*bridgev2.ImportedImagePack, error) {
|
|
||||||
return s.Main.MsgConv.DownloadImagePack(ctx, url)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SignalClient) ListImagePacks(ctx context.Context) ([]*event.ImagePackMetadata, error) {
|
|
||||||
return []*event.ImagePackMetadata{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SignalClient) LogoutRemote(ctx context.Context) {
|
func (s *SignalClient) LogoutRemote(ctx context.Context) {
|
||||||
if s.Client == nil {
|
if s.Client == nil {
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"maunium.net/go/mautrix/bridgev2"
|
"maunium.net/go/mautrix/bridgev2"
|
||||||
|
|
@ -29,7 +30,6 @@ func (s *SignalConnector) Download(ctx context.Context, mediaID networkid.MediaI
|
||||||
return nil, fmt.Errorf("failed to parse direct media id: %w", err)
|
return nil, fmt.Errorf("failed to parse direct media id: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var rawDataResp []byte
|
|
||||||
switch info := info.(type) {
|
switch info := info.(type) {
|
||||||
case *signalid.DirectMediaAttachment:
|
case *signalid.DirectMediaAttachment:
|
||||||
log.Info().
|
log.Info().
|
||||||
|
|
@ -76,11 +76,18 @@ func (s *SignalConnector) Download(ctx context.Context, mediaID networkid.MediaI
|
||||||
return nil, fmt.Errorf("failed to to get group master key: %w", err)
|
return nil, fmt.Errorf("failed to to get group master key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rawDataResp, err = client.Client.DownloadGroupAvatar(ctx, info.GroupAvatarPath, groupMasterKey)
|
return &mediaproxy.GetMediaResponseCallback{
|
||||||
if err != nil {
|
Callback: func(w io.Writer) (int64, error) {
|
||||||
log.Err(err).Msg("Direct download failed")
|
data, err := client.Client.DownloadGroupAvatar(ctx, info.GroupAvatarPath, groupMasterKey)
|
||||||
return nil, err
|
if err != nil {
|
||||||
}
|
log.Err(err).Msg("Direct download failed")
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = w.Write(data)
|
||||||
|
return int64(len(data)), err
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
case *signalid.DirectMediaProfileAvatar:
|
case *signalid.DirectMediaProfileAvatar:
|
||||||
log.Info().
|
log.Info().
|
||||||
Stringer("user_id", info.UserID).
|
Stringer("user_id", info.UserID).
|
||||||
|
|
@ -104,27 +111,19 @@ func (s *SignalConnector) Download(ctx context.Context, mediaID networkid.MediaI
|
||||||
return nil, fmt.Errorf("profile key not found")
|
return nil, fmt.Errorf("profile key not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
rawDataResp, err = client.Client.DownloadUserAvatar(ctx, info.ProfileAvatarPath, *profileKey)
|
return &mediaproxy.GetMediaResponseCallback{
|
||||||
if err != nil {
|
Callback: func(w io.Writer) (int64, error) {
|
||||||
log.Err(err).Msg("Direct download failed")
|
data, err := client.Client.DownloadUserAvatar(ctx, info.ProfileAvatarPath, *profileKey)
|
||||||
return nil, err
|
if err != nil {
|
||||||
}
|
log.Err(err).Msg("Direct download failed")
|
||||||
case *signalid.DirectMediaSticker:
|
return 0, err
|
||||||
log.Info().
|
}
|
||||||
Hex("pack_id", info.PackID).
|
|
||||||
Uint32("sticker_id", info.StickerID).
|
|
||||||
Msg("Direct downloading sticker")
|
|
||||||
|
|
||||||
rawDataResp, err = signalmeow.DownloadStickerPackItem(ctx, info.PackID, info.PackKey, info.StickerID)
|
_, err = w.Write(data)
|
||||||
if err != nil {
|
return int64(len(data)), err
|
||||||
log.Err(err).Msg("Direct download failed")
|
},
|
||||||
return nil, err
|
}, nil
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("no downloader for direct media type: %T", info)
|
return nil, fmt.Errorf("no downloader for direct media type: %T", info)
|
||||||
}
|
}
|
||||||
if rawDataResp == nil {
|
|
||||||
return nil, fmt.Errorf("unexpected fallthrough with no data")
|
|
||||||
}
|
|
||||||
return mediaproxy.GetMediaResponseRawData(rawDataResp), nil
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ import (
|
||||||
"go.mau.fi/mautrix-signal/pkg/libsignalgo"
|
"go.mau.fi/mautrix-signal/pkg/libsignalgo"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalid"
|
"go.mau.fi/mautrix-signal/pkg/signalid"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow"
|
"go.mau.fi/mautrix-signal/pkg/signalmeow"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/signalpb"
|
signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -137,7 +137,7 @@ func (s *SignalClient) doSendMessage(
|
||||||
}
|
}
|
||||||
msgID := signalid.MakeMessageID(s.Client.Store.ACI, ts)
|
msgID := signalid.MakeMessageID(s.Client.Store.ACI, ts)
|
||||||
msg.AddPendingToIgnore(networkid.TransactionID(msgID))
|
msg.AddPendingToIgnore(networkid.TransactionID(msgID))
|
||||||
err := s.sendMessage(ctx, msg.Portal.ID, signalmeow.WrapDataMessage(converted))
|
err := s.sendMessage(ctx, msg.Portal.ID, &signalpb.Content{DataMessage: converted})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, bridgev2.WrapErrorInStatus(err).WithSendNotice(true)
|
return nil, bridgev2.WrapErrorInStatus(err).WithSendNotice(true)
|
||||||
}
|
}
|
||||||
|
|
@ -173,55 +173,19 @@ func (s *SignalClient) HandleMatrixEdit(ctx context.Context, msg *bridgev2.Matri
|
||||||
}
|
}
|
||||||
ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender)
|
ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender)
|
||||||
converted.Timestamp = &ts
|
converted.Timestamp = &ts
|
||||||
err = s.sendMessage(ctx, msg.Portal.ID, signalmeow.WrapEditMessage(&signalpb.EditMessage{
|
err = s.sendMessage(ctx, msg.Portal.ID, &signalpb.Content{EditMessage: &signalpb.EditMessage{
|
||||||
TargetSentTimestamp: proto.Uint64(targetSentTimestamp),
|
TargetSentTimestamp: proto.Uint64(targetSentTimestamp),
|
||||||
DataMessage: converted,
|
DataMessage: converted,
|
||||||
}))
|
}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return bridgev2.WrapErrorInStatus(err).WithSendNotice(true)
|
return bridgev2.WrapErrorInStatus(err).WithSendNotice(true)
|
||||||
}
|
}
|
||||||
prevID := msg.EditTarget.ID
|
|
||||||
msg.EditTarget.ID = signalid.MakeMessageID(s.Client.Store.ACI, ts)
|
msg.EditTarget.ID = signalid.MakeMessageID(s.Client.Store.ACI, ts)
|
||||||
msg.EditTarget.Metadata = &signalid.MessageMetadata{ContainsAttachments: len(converted.Attachments) > 0}
|
msg.EditTarget.Metadata = &signalid.MessageMetadata{ContainsAttachments: len(converted.Attachments) > 0}
|
||||||
msg.EditTarget.EditCount++
|
msg.EditTarget.EditCount++
|
||||||
if prevID != msg.EditTarget.ID {
|
|
||||||
err = s.Main.Bridge.DB.DoTxn(ctx, nil, func(ctx context.Context) error {
|
|
||||||
err = s.Main.Bridge.DB.Message.Update(ctx, msg.EditTarget)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = saveEditStub(ctx, s.Main.Bridge, prevID, msg.EditTarget)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to save edit stub: %w", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
zerolog.Ctx(ctx).Err(err).
|
|
||||||
Str("prev_message_id", string(prevID)).
|
|
||||||
Str("message_id", string(msg.EditTarget.ID)).
|
|
||||||
Msg("Failed to save message after editing")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// saveEditStub saves a placeholder message row pointing at the pre-edit ID of a message, such that
|
|
||||||
// duplicate checks on incoming edits find it and are dropped. This is necessary because the first
|
|
||||||
// time we see an edit it modifies the ID in place.
|
|
||||||
func saveEditStub(ctx context.Context, bridge *bridgev2.Bridge, prevID networkid.MessageID, target *database.Message) error {
|
|
||||||
stub := &database.Message{
|
|
||||||
ID: prevID,
|
|
||||||
PartID: editStubPartID,
|
|
||||||
Room: target.Room,
|
|
||||||
SenderID: target.SenderID,
|
|
||||||
SenderMXID: target.SenderMXID,
|
|
||||||
Timestamp: target.Timestamp,
|
|
||||||
}
|
|
||||||
stub.SetFakeMXID()
|
|
||||||
return bridge.DB.Message.Insert(ctx, stub)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SignalClient) PreHandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (bridgev2.MatrixReactionPreResponse, error) {
|
func (s *SignalClient) PreHandleMatrixReaction(ctx context.Context, msg *bridgev2.MatrixReaction) (bridgev2.MatrixReactionPreResponse, error) {
|
||||||
return bridgev2.MatrixReactionPreResponse{
|
return bridgev2.MatrixReactionPreResponse{
|
||||||
SenderID: signalid.MakeUserID(s.Client.Store.ACI),
|
SenderID: signalid.MakeUserID(s.Client.Store.ACI),
|
||||||
|
|
@ -236,16 +200,19 @@ func (s *SignalClient) HandleMatrixReaction(ctx context.Context, msg *bridgev2.M
|
||||||
return nil, fmt.Errorf("failed to parse target message ID: %w", err)
|
return nil, fmt.Errorf("failed to parse target message ID: %w", err)
|
||||||
}
|
}
|
||||||
ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender)
|
ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender)
|
||||||
err = s.sendMessage(ctx, msg.Portal.ID, signalmeow.WrapDataMessage(&signalpb.DataMessage{
|
wrappedContent := &signalpb.Content{
|
||||||
Timestamp: proto.Uint64(ts),
|
DataMessage: &signalpb.DataMessage{
|
||||||
RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)),
|
Timestamp: proto.Uint64(ts),
|
||||||
Reaction: &signalpb.DataMessage_Reaction{
|
RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)),
|
||||||
Emoji: proto.String(msg.PreHandleResp.Emoji),
|
Reaction: &signalpb.DataMessage_Reaction{
|
||||||
Remove: proto.Bool(false),
|
Emoji: proto.String(msg.PreHandleResp.Emoji),
|
||||||
TargetAuthorAciBinary: targetAuthorACI[:],
|
Remove: proto.Bool(false),
|
||||||
TargetSentTimestamp: proto.Uint64(targetSentTimestamp),
|
TargetAuthorAciBinary: targetAuthorACI[:],
|
||||||
|
TargetSentTimestamp: proto.Uint64(targetSentTimestamp),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}))
|
}
|
||||||
|
err = s.sendMessage(ctx, msg.Portal.ID, wrappedContent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -258,16 +225,19 @@ func (s *SignalClient) HandleMatrixReactionRemove(ctx context.Context, msg *brid
|
||||||
return fmt.Errorf("failed to parse target message ID: %w", err)
|
return fmt.Errorf("failed to parse target message ID: %w", err)
|
||||||
}
|
}
|
||||||
ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender)
|
ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender)
|
||||||
err = s.sendMessage(ctx, msg.Portal.ID, signalmeow.WrapDataMessage(&signalpb.DataMessage{
|
wrappedContent := &signalpb.Content{
|
||||||
Timestamp: proto.Uint64(ts),
|
DataMessage: &signalpb.DataMessage{
|
||||||
RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)),
|
Timestamp: proto.Uint64(ts),
|
||||||
Reaction: &signalpb.DataMessage_Reaction{
|
RequiredProtocolVersion: proto.Uint32(uint32(signalpb.DataMessage_REACTIONS)),
|
||||||
Emoji: proto.String(msg.TargetReaction.Emoji),
|
Reaction: &signalpb.DataMessage_Reaction{
|
||||||
Remove: proto.Bool(true),
|
Emoji: proto.String(msg.TargetReaction.Emoji),
|
||||||
TargetAuthorAciBinary: targetAuthorACI[:],
|
Remove: proto.Bool(true),
|
||||||
TargetSentTimestamp: proto.Uint64(targetSentTimestamp),
|
TargetAuthorAciBinary: targetAuthorACI[:],
|
||||||
|
TargetSentTimestamp: proto.Uint64(targetSentTimestamp),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}))
|
}
|
||||||
|
err = s.sendMessage(ctx, msg.Portal.ID, wrappedContent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -282,12 +252,15 @@ func (s *SignalClient) HandleMatrixMessageRemove(ctx context.Context, msg *bridg
|
||||||
return fmt.Errorf("cannot delete other people's messages")
|
return fmt.Errorf("cannot delete other people's messages")
|
||||||
}
|
}
|
||||||
ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender)
|
ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender)
|
||||||
err = s.sendMessage(ctx, msg.Portal.ID, signalmeow.WrapDataMessage(&signalpb.DataMessage{
|
wrappedContent := &signalpb.Content{
|
||||||
Timestamp: proto.Uint64(ts),
|
DataMessage: &signalpb.DataMessage{
|
||||||
Delete: &signalpb.DataMessage_Delete{
|
Timestamp: proto.Uint64(ts),
|
||||||
TargetSentTimestamp: proto.Uint64(targetSentTimestamp),
|
Delete: &signalpb.DataMessage_Delete{
|
||||||
|
TargetSentTimestamp: proto.Uint64(targetSentTimestamp),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}))
|
}
|
||||||
|
err = s.sendMessage(ctx, msg.Portal.ID, wrappedContent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -574,7 +547,7 @@ func (s *SignalClient) HandleMatrixMembership(ctx context.Context, msg *bridgev2
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if (msg.Type == bridgev2.Invite || msg.Type == bridgev2.AcceptKnock) && targetSignalID.Type != libsignalgo.ServiceIDTypePNI {
|
if msg.Type == bridgev2.Invite && targetSignalID.Type != libsignalgo.ServiceIDTypePNI {
|
||||||
err = targetIntent.EnsureJoined(ctx, msg.Portal.MXID)
|
err = targetIntent.EnsureJoined(ctx, msg.Portal.MXID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -715,11 +688,13 @@ func (s *SignalClient) HandleMatrixDisappearingTimer(ctx context.Context, msg *b
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender)
|
ts := getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender)
|
||||||
res := s.Client.SendMessage(ctx, userID, signalmeow.WrapDataMessage(&signalpb.DataMessage{
|
res := s.Client.SendMessage(ctx, userID, &signalpb.Content{
|
||||||
Timestamp: ptr.Ptr(ts),
|
DataMessage: &signalpb.DataMessage{
|
||||||
Flags: ptr.Ptr(uint32(signalpb.DataMessage_EXPIRATION_TIMER_UPDATE)),
|
Timestamp: ptr.Ptr(ts),
|
||||||
ExpireTimer: ptr.Ptr(uint32(msg.Content.Timer.Seconds())),
|
Flags: ptr.Ptr(uint32(signalpb.DataMessage_EXPIRATION_TIMER_UPDATE)),
|
||||||
}))
|
ExpireTimer: ptr.Ptr(uint32(msg.Content.Timer.Seconds())),
|
||||||
|
},
|
||||||
|
})
|
||||||
if !res.WasSuccessful {
|
if !res.WasSuccessful {
|
||||||
return false, res.Error
|
return false, res.Error
|
||||||
}
|
}
|
||||||
|
|
@ -798,8 +773,8 @@ func (s *SignalClient) HandleMatrixDeleteChat(ctx context.Context, msg *bridgev2
|
||||||
|
|
||||||
recipientID := s.Client.Store.ACIServiceID()
|
recipientID := s.Client.Store.ACIServiceID()
|
||||||
// Send DeleteForMe sync message to self
|
// Send DeleteForMe sync message to self
|
||||||
result := s.Client.SendMessage(ctx, recipientID, signalmeow.WrapSyncMessage(&signalpb.SyncMessage{
|
result := s.Client.SendMessage(ctx, recipientID, &signalpb.Content{
|
||||||
Content: &signalpb.SyncMessage_DeleteForMe_{
|
SyncMessage: &signalpb.SyncMessage{
|
||||||
DeleteForMe: &signalpb.SyncMessage_DeleteForMe{
|
DeleteForMe: &signalpb.SyncMessage_DeleteForMe{
|
||||||
ConversationDeletes: []*signalpb.SyncMessage_DeleteForMe_ConversationDelete{{
|
ConversationDeletes: []*signalpb.SyncMessage_DeleteForMe_ConversationDelete{{
|
||||||
Conversation: conversationID,
|
Conversation: conversationID,
|
||||||
|
|
@ -808,7 +783,7 @@ func (s *SignalClient) HandleMatrixDeleteChat(ctx context.Context, msg *bridgev2
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}))
|
})
|
||||||
|
|
||||||
zerolog.Ctx(ctx).Debug().
|
zerolog.Ctx(ctx).Debug().
|
||||||
Str("portal_id", string(msg.Portal.ID)).
|
Str("portal_id", string(msg.Portal.ID)).
|
||||||
|
|
@ -847,8 +822,7 @@ func (s *SignalClient) HandleMatrixPollVote(ctx context.Context, msg *bridgev2.M
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
meta := msg.VoteTo.Metadata.(*signalid.MessageMetadata)
|
mxOptions := msg.VoteTo.Metadata.(*signalid.MessageMetadata).MatrixPollOptionIDs
|
||||||
mxOptions := meta.MatrixPollOptionIDs
|
|
||||||
optionIndexes := make([]uint32, len(msg.Content.Response.Answers))
|
optionIndexes := make([]uint32, len(msg.Content.Response.Answers))
|
||||||
for i, answer := range msg.Content.Response.Answers {
|
for i, answer := range msg.Content.Response.Answers {
|
||||||
if idx := slices.Index(mxOptions, answer); idx >= 0 {
|
if idx := slices.Index(mxOptions, answer); idx >= 0 {
|
||||||
|
|
@ -859,20 +833,12 @@ func (s *SignalClient) HandleMatrixPollVote(ctx context.Context, msg *bridgev2.M
|
||||||
return nil, fmt.Errorf("unknown poll answer ID: %s", answer)
|
return nil, fmt.Errorf("unknown poll answer ID: %s", answer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if meta.VoteCount == nil {
|
|
||||||
meta.VoteCount = make(map[string]uint32)
|
|
||||||
}
|
|
||||||
meta.VoteCount[s.Client.Store.ACI.String()]++
|
|
||||||
err = s.Main.Bridge.DB.Message.Update(ctx, msg.VoteTo)
|
|
||||||
if err != nil {
|
|
||||||
zerolog.Ctx(ctx).Warn().Err(err).Msg("Failed to update poll message with new vote count")
|
|
||||||
}
|
|
||||||
converted := &signalpb.DataMessage{
|
converted := &signalpb.DataMessage{
|
||||||
PollVote: &signalpb.DataMessage_PollVote{
|
PollVote: &signalpb.DataMessage_PollVote{
|
||||||
TargetAuthorAciBinary: senderACI[:],
|
TargetAuthorAciBinary: senderACI[:],
|
||||||
TargetSentTimestamp: &msgTS,
|
TargetSentTimestamp: &msgTS,
|
||||||
OptionIndexes: optionIndexes,
|
OptionIndexes: optionIndexes,
|
||||||
VoteCount: proto.Uint32(meta.VoteCount[s.Client.Store.ACI.String()]),
|
VoteCount: proto.Uint32(1), // TODO
|
||||||
},
|
},
|
||||||
RequiredProtocolVersion: proto.Uint32(0),
|
RequiredProtocolVersion: proto.Uint32(0),
|
||||||
}
|
}
|
||||||
|
|
@ -902,11 +868,11 @@ func (s *SignalClient) syncMessageRequestResponse(
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("invalid portal ID for message request response: %s", portal.ID)
|
return fmt.Errorf("invalid portal ID for message request response: %s", portal.ID)
|
||||||
}
|
}
|
||||||
res := s.Client.SendMessage(ctx, libsignalgo.NewACIServiceID(s.Client.Store.ACI), signalmeow.WrapSyncMessage(&signalpb.SyncMessage{
|
res := s.Client.SendMessage(ctx, libsignalgo.NewACIServiceID(s.Client.Store.ACI), &signalpb.Content{
|
||||||
Content: &signalpb.SyncMessage_MessageRequestResponse_{
|
SyncMessage: &signalpb.SyncMessage{
|
||||||
MessageRequestResponse: accept,
|
MessageRequestResponse: accept,
|
||||||
},
|
},
|
||||||
}))
|
})
|
||||||
if !res.WasSuccessful {
|
if !res.WasSuccessful {
|
||||||
return res.Error
|
return res.Error
|
||||||
}
|
}
|
||||||
|
|
@ -939,13 +905,13 @@ func (s *SignalClient) HandleMatrixAcceptMessageRequest(ctx context.Context, msg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res := s.Client.SendMessage(ctx, userID, &signalpb.Content{
|
res := s.Client.SendMessage(ctx, userID, &signalpb.Content{
|
||||||
Content: &signalpb.Content_DataMessage{DataMessage: &signalpb.DataMessage{
|
DataMessage: &signalpb.DataMessage{
|
||||||
Flags: proto.Uint32(uint32(signalpb.DataMessage_PROFILE_KEY_UPDATE)),
|
Flags: proto.Uint32(uint32(signalpb.DataMessage_PROFILE_KEY_UPDATE)),
|
||||||
ProfileKey: profileKey.Slice(),
|
ProfileKey: profileKey.Slice(),
|
||||||
Timestamp: proto.Uint64(getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender)),
|
Timestamp: proto.Uint64(getTimestampForEvent(msg.InputTransactionID, msg.Event, msg.OrigSender)),
|
||||||
|
|
||||||
RequiredProtocolVersion: proto.Uint32(0),
|
RequiredProtocolVersion: proto.Uint32(0),
|
||||||
}},
|
},
|
||||||
PniSignatureMessage: pniSig,
|
PniSignatureMessage: pniSig,
|
||||||
})
|
})
|
||||||
if !res.WasSuccessful {
|
if !res.WasSuccessful {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"slices"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -40,7 +39,7 @@ import (
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalid"
|
"go.mau.fi/mautrix-signal/pkg/signalid"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow"
|
"go.mau.fi/mautrix-signal/pkg/signalmeow"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/events"
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/events"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/signalpb"
|
signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/types"
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -185,7 +184,7 @@ func (evt *Bv2ChatEvent) GetType() bridgev2.RemoteEventType {
|
||||||
return bridgev2.RemoteEventReactionRemove
|
return bridgev2.RemoteEventReactionRemove
|
||||||
}
|
}
|
||||||
return bridgev2.RemoteEventReaction
|
return bridgev2.RemoteEventReaction
|
||||||
case innerEvt.Delete != nil, innerEvt.AdminDelete != nil:
|
case innerEvt.Delete != nil:
|
||||||
return bridgev2.RemoteEventMessageRemove
|
return bridgev2.RemoteEventMessageRemove
|
||||||
case innerEvt.GetGroupV2().GetGroupChange() != nil:
|
case innerEvt.GetGroupV2().GetGroupChange() != nil:
|
||||||
return bridgev2.RemoteEventChatInfoChange
|
return bridgev2.RemoteEventChatInfoChange
|
||||||
|
|
@ -304,11 +303,6 @@ func (evt *Bv2ChatEvent) GetTargetMessage() networkid.MessageID {
|
||||||
targetSentTS = innerEvt.Reaction.GetTargetSentTimestamp()
|
targetSentTS = innerEvt.Reaction.GetTargetSentTimestamp()
|
||||||
case innerEvt.Delete != nil:
|
case innerEvt.Delete != nil:
|
||||||
targetSentTS = innerEvt.Delete.GetTargetSentTimestamp()
|
targetSentTS = innerEvt.Delete.GetTargetSentTimestamp()
|
||||||
case innerEvt.AdminDelete != nil:
|
|
||||||
if len(innerEvt.AdminDelete.GetTargetAuthorAciBinary()) == 16 {
|
|
||||||
targetAuthorACI = uuid.UUID(innerEvt.AdminDelete.GetTargetAuthorAciBinary())
|
|
||||||
}
|
|
||||||
targetSentTS = innerEvt.AdminDelete.GetTargetSentTimestamp()
|
|
||||||
default:
|
default:
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
@ -359,52 +353,20 @@ func (evt *Bv2ChatEvent) ConvertMessage(ctx context.Context, portal *bridgev2.Po
|
||||||
return converted, nil
|
return converted, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const editStubPartID networkid.PartID = "editstub"
|
|
||||||
|
|
||||||
func isEditStub(msg *database.Message) bool {
|
|
||||||
return msg.PartID == editStubPartID
|
|
||||||
}
|
|
||||||
|
|
||||||
// editStubMessage returns a non-bridged message part which is saved as a placeholder row pointing
|
|
||||||
// at the pre-edit ID of a message, such that duplicate checks on incoming edits find it and are
|
|
||||||
// dropped. This is necessary because the first time we see an edit it modifies the ID in place.
|
|
||||||
func editStubMessage() *bridgev2.ConvertedMessage {
|
|
||||||
return &bridgev2.ConvertedMessage{
|
|
||||||
Parts: []*bridgev2.ConvertedMessagePart{{
|
|
||||||
ID: editStubPartID,
|
|
||||||
Type: event.EventMessage,
|
|
||||||
Content: &event.MessageEventContent{},
|
|
||||||
DontBridge: true,
|
|
||||||
}},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (evt *Bv2ChatEvent) ConvertEdit(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI, existing []*database.Message) (*bridgev2.ConvertedEdit, error) {
|
func (evt *Bv2ChatEvent) ConvertEdit(ctx context.Context, portal *bridgev2.Portal, intent bridgev2.MatrixAPI, existing []*database.Message) (*bridgev2.ConvertedEdit, error) {
|
||||||
editMsg, ok := evt.Event.(*signalpb.EditMessage)
|
editMsg, ok := evt.Event.(*signalpb.EditMessage)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("ConvertEdit() called for non-EditMessage event")
|
return nil, fmt.Errorf("ConvertEdit() called for non-EditMessage event")
|
||||||
}
|
}
|
||||||
existing = slices.DeleteFunc(slices.Clone(existing), isEditStub)
|
|
||||||
if len(existing) == 0 {
|
|
||||||
return nil, fmt.Errorf("%w: edit target has already been edited", bridgev2.ErrIgnoringRemoteEvent)
|
|
||||||
}
|
|
||||||
// TODO tell converter about existing parts to avoid reupload?
|
// TODO tell converter about existing parts to avoid reupload?
|
||||||
converted := evt.s.Main.MsgConv.ToMatrix(ctx, evt.s.Client, portal, evt.Info.Sender, intent, editMsg.GetDataMessage(), nil)
|
converted := evt.s.Main.MsgConv.ToMatrix(ctx, evt.s.Client, portal, evt.Info.Sender, intent, editMsg.GetDataMessage(), nil)
|
||||||
// TODO can anything other than the text be edited?
|
// TODO can anything other than the text be edited?
|
||||||
editPart := converted.Parts[len(converted.Parts)-1].ToEditPart(existing[len(existing)-1])
|
editPart := converted.Parts[len(converted.Parts)-1].ToEditPart(existing[len(existing)-1])
|
||||||
prevID := editPart.Part.ID
|
|
||||||
// Clone the database message struct to avoid mutating the ID.
|
|
||||||
// The ID from the original struct is used for AddedParts (we specifically want the old ID for that)
|
|
||||||
editPart.Part = ptr.Clone(editPart.Part)
|
|
||||||
editPart.Part.EditCount++
|
editPart.Part.EditCount++
|
||||||
editPart.Part.ID = signalid.MakeMessageID(evt.Info.Sender, editMsg.GetDataMessage().GetTimestamp())
|
editPart.Part.ID = signalid.MakeMessageID(evt.Info.Sender, editMsg.GetDataMessage().GetTimestamp())
|
||||||
convertedEdit := &bridgev2.ConvertedEdit{
|
return &bridgev2.ConvertedEdit{
|
||||||
ModifiedParts: []*bridgev2.ConvertedEditPart{editPart},
|
ModifiedParts: []*bridgev2.ConvertedEditPart{editPart},
|
||||||
}
|
}, nil
|
||||||
if prevID != editPart.Part.ID {
|
|
||||||
convertedEdit.AddedParts = editStubMessage()
|
|
||||||
}
|
|
||||||
return convertedEdit, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (evt *Bv2ChatEvent) GetStreamOrder() int64 {
|
func (evt *Bv2ChatEvent) GetStreamOrder() int64 {
|
||||||
|
|
@ -459,7 +421,7 @@ func (b *Bv2Receipt) GetReadUpTo() time.Time {
|
||||||
return time.Time{}
|
return time.Time{}
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ bridgev2.RemoteReadReceipt = (*Bv2Receipt)(nil)
|
var _ bridgev2.RemoteReceipt = (*Bv2Receipt)(nil)
|
||||||
|
|
||||||
func convertReceipts[T any](ctx context.Context, input []T, getMessageFunc func(ctx context.Context, msgID T) (*database.Message, error)) map[networkid.PortalKey]*Bv2Receipt {
|
func convertReceipts[T any](ctx context.Context, input []T, getMessageFunc func(ctx context.Context, msgID T) (*database.Message, error)) map[networkid.PortalKey]*Bv2Receipt {
|
||||||
log := zerolog.Ctx(ctx)
|
log := zerolog.Ctx(ctx)
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,9 @@ package connector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/coder/websocket"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"maunium.net/go/mautrix/bridgev2"
|
"maunium.net/go/mautrix/bridgev2"
|
||||||
"maunium.net/go/mautrix/bridgev2/database"
|
"maunium.net/go/mautrix/bridgev2/database"
|
||||||
|
|
@ -44,7 +41,7 @@ func (s *SignalConnector) GetLoginFlows() []bridgev2.LoginFlow {
|
||||||
|
|
||||||
func (s *SignalConnector) CreateLogin(ctx context.Context, user *bridgev2.User, flowID string) (bridgev2.LoginProcess, error) {
|
func (s *SignalConnector) CreateLogin(ctx context.Context, user *bridgev2.User, flowID string) (bridgev2.LoginProcess, error) {
|
||||||
if flowID != "qr" {
|
if flowID != "qr" {
|
||||||
return nil, bridgev2.ErrInvalidLoginFlowID
|
return nil, fmt.Errorf("invalid login flow ID")
|
||||||
}
|
}
|
||||||
return &QRLogin{User: user, Main: s}, nil
|
return &QRLogin{User: user, Main: s}, nil
|
||||||
}
|
}
|
||||||
|
|
@ -69,78 +66,10 @@ func (qr *QRLogin) Cancel() {
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LoginStepQR = "fi.mau.signal.login.qr"
|
LoginStepQR = "fi.mau.signal.login.qr"
|
||||||
|
LoginStepProcess = "fi.mau.signal.login.processing"
|
||||||
LoginStepComplete = "fi.mau.signal.login.complete"
|
LoginStepComplete = "fi.mau.signal.login.complete"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
qrRefreshInterval = 45 * time.Second
|
|
||||||
maxQRRefreshes = 20
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
ErrLoginTimedOut = bridgev2.RespError{
|
|
||||||
ErrCode: "FI.MAU.BRIDGE.LOGIN_TIMED_OUT",
|
|
||||||
Err: "The QR code wasn't scanned in time, please start a new login",
|
|
||||||
StatusCode: http.StatusGone,
|
|
||||||
}
|
|
||||||
ErrLoginCancelled = bridgev2.RespError{
|
|
||||||
ErrCode: "FI.MAU.BRIDGE.LOGIN_CANCELLED",
|
|
||||||
Err: "Login process was cancelled",
|
|
||||||
StatusCode: http.StatusGone,
|
|
||||||
}
|
|
||||||
ErrDeviceLinkMissingCapability = bridgev2.RespError{
|
|
||||||
ErrCode: "FI.MAU.SIGNAL.DEVICE_LINK_MISSING_CAPABILITY",
|
|
||||||
Err: "Signal rejected linking because the bridge is missing a capability required by your account's other devices. Please try again later",
|
|
||||||
StatusCode: http.StatusConflict,
|
|
||||||
}
|
|
||||||
ErrDeviceLimitReached = bridgev2.RespError{
|
|
||||||
ErrCode: "FI.MAU.SIGNAL.DEVICE_LIMIT_REACHED",
|
|
||||||
Err: "Your Signal account already has the maximum number of linked devices. Remove one in the Signal app and try again",
|
|
||||||
StatusCode: http.StatusBadRequest,
|
|
||||||
}
|
|
||||||
ErrDeviceLinkCodeInvalid = bridgev2.RespError{
|
|
||||||
ErrCode: "FI.MAU.SIGNAL.DEVICE_LINK_CODE_INVALID",
|
|
||||||
Err: "The scanned QR code was invalid or already used, please start a new login",
|
|
||||||
StatusCode: http.StatusForbidden,
|
|
||||||
}
|
|
||||||
ErrDeviceLinkRateLimited = bridgev2.RespError{
|
|
||||||
ErrCode: "FI.MAU.SIGNAL.DEVICE_LINK_RATE_LIMITED",
|
|
||||||
Err: "Signal rate-limited the linking attempt, please wait a few minutes and try again",
|
|
||||||
StatusCode: http.StatusTooManyRequests,
|
|
||||||
}
|
|
||||||
ErrDeviceLinkRejected = bridgev2.RespError{
|
|
||||||
ErrCode: "FI.MAU.SIGNAL.DEVICE_LINK_REJECTED",
|
|
||||||
Err: "Signal rejected linking the device",
|
|
||||||
StatusCode: http.StatusBadRequest,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Statuses of PUT /v1/devices/link, per Signal-Server's DeviceController
|
|
||||||
func wrapProvisioningError(err error) error {
|
|
||||||
var linkErr signalmeow.DeviceLinkError
|
|
||||||
if errors.As(err, &linkErr) {
|
|
||||||
switch linkErr.StatusCode {
|
|
||||||
case http.StatusConflict:
|
|
||||||
return ErrDeviceLinkMissingCapability
|
|
||||||
case http.StatusLengthRequired:
|
|
||||||
return ErrDeviceLimitReached
|
|
||||||
case http.StatusForbidden:
|
|
||||||
return ErrDeviceLinkCodeInvalid
|
|
||||||
case http.StatusTooManyRequests:
|
|
||||||
return ErrDeviceLinkRateLimited
|
|
||||||
default:
|
|
||||||
if linkErr.Message != "" {
|
|
||||||
return ErrDeviceLinkRejected.AppendMessage(" (HTTP %d: %s)", linkErr.StatusCode, linkErr.Message)
|
|
||||||
}
|
|
||||||
return ErrDeviceLinkRejected.AppendMessage(" (HTTP %d)", linkErr.StatusCode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if websocket.CloseStatus(err) == websocket.StatusGoingAway {
|
|
||||||
return ErrLoginTimedOut
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (qr *QRLogin) Start(ctx context.Context) (*bridgev2.LoginStep, error) {
|
func (qr *QRLogin) Start(ctx context.Context) (*bridgev2.LoginStep, error) {
|
||||||
log := qr.Main.Bridge.Log.With().
|
log := qr.Main.Bridge.Log.With().
|
||||||
Str("action", "login").
|
Str("action", "login").
|
||||||
|
|
@ -156,16 +85,14 @@ func (qr *QRLogin) Start(ctx context.Context) (*bridgev2.LoginStep, error) {
|
||||||
select {
|
select {
|
||||||
case resp = <-qr.ProvChan:
|
case resp = <-qr.ProvChan:
|
||||||
if resp.Err != nil {
|
if resp.Err != nil {
|
||||||
return nil, wrapProvisioningError(resp.Err)
|
return nil, resp.Err
|
||||||
} else if resp.State != signalmeow.StateProvisioningURLReceived {
|
} else if resp.State != signalmeow.StateProvisioningURLReceived {
|
||||||
return nil, fmt.Errorf("unexpected state %v", resp.State)
|
return nil, fmt.Errorf("unexpected state %v", resp.State)
|
||||||
}
|
}
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
cancel()
|
cancel()
|
||||||
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
|
return nil, ctx.Err()
|
||||||
return nil, ErrLoginTimedOut
|
// TODO separate timeout here?
|
||||||
}
|
|
||||||
return nil, ErrLoginCancelled
|
|
||||||
}
|
}
|
||||||
return &bridgev2.LoginStep{
|
return &bridgev2.LoginStep{
|
||||||
Type: bridgev2.LoginStepTypeDisplayAndWait,
|
Type: bridgev2.LoginStepTypeDisplayAndWait,
|
||||||
|
|
@ -187,7 +114,7 @@ func (qr *QRLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error) {
|
||||||
case resp := <-qr.ProvChan:
|
case resp := <-qr.ProvChan:
|
||||||
if resp.Err != nil {
|
if resp.Err != nil {
|
||||||
qr.cancelChan()
|
qr.cancelChan()
|
||||||
return nil, wrapProvisioningError(resp.Err)
|
return nil, resp.Err
|
||||||
} else if resp.State != signalmeow.StateProvisioningDataReceived {
|
} else if resp.State != signalmeow.StateProvisioningDataReceived {
|
||||||
qr.cancelChan()
|
qr.cancelChan()
|
||||||
return nil, fmt.Errorf("unexpected state %v", resp.State)
|
return nil, fmt.Errorf("unexpected state %v", resp.State)
|
||||||
|
|
@ -199,20 +126,17 @@ func (qr *QRLogin) Wait(ctx context.Context) (*bridgev2.LoginStep, error) {
|
||||||
|
|
||||||
// Server will timeout the request after 60 seconds, but Signal Desktop opens
|
// Server will timeout the request after 60 seconds, but Signal Desktop opens
|
||||||
// a new socket and gets a new QR code after 45 seconds. We should do the same.
|
// a new socket and gets a new QR code after 45 seconds. We should do the same.
|
||||||
case <-time.After(qrRefreshInterval):
|
case <-time.After(45 * time.Second):
|
||||||
qr.cancelChan()
|
qr.cancelChan()
|
||||||
qr.newQRCount++
|
qr.newQRCount++
|
||||||
if qr.newQRCount >= maxQRRefreshes {
|
if qr.newQRCount >= 6 {
|
||||||
return nil, ErrLoginTimedOut
|
return nil, fmt.Errorf("too many QR code refreshes")
|
||||||
}
|
}
|
||||||
return qr.Start(ctx)
|
return qr.Start(ctx)
|
||||||
|
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
qr.cancelChan()
|
qr.cancelChan()
|
||||||
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
|
return nil, ctx.Err()
|
||||||
return nil, ErrLoginTimedOut
|
|
||||||
}
|
|
||||||
return nil, ErrLoginCancelled
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,18 +20,18 @@ package libsignalgo
|
||||||
#include "./libsignal-ffi.h"
|
#include "./libsignal-ffi.h"
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
import "runtime"
|
import (
|
||||||
|
"runtime"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
type AccountEntropyPool string
|
type AccountEntropyPool string
|
||||||
type SVRKey = fixedArray32
|
|
||||||
|
|
||||||
func (aep AccountEntropyPool) DeriveSVRKey() ([]byte, error) {
|
func (aep AccountEntropyPool) DeriveSVRKey() ([]byte, error) {
|
||||||
var out SVRKey
|
var out [C.SignalSVR_KEY_LEN]byte
|
||||||
aepC, free := GoStringToCString(string(aep))
|
|
||||||
defer free()
|
|
||||||
signalFfiError := C.signal_account_entropy_pool_derive_svr_key(
|
signalFfiError := C.signal_account_entropy_pool_derive_svr_key(
|
||||||
out.cFixedArray(),
|
(*[C.SignalSVR_KEY_LEN]C.uint8_t)(unsafe.Pointer(&out)),
|
||||||
aepC,
|
C.CString(string(aep)),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(aep)
|
runtime.KeepAlive(aep)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
|
|
@ -41,12 +41,10 @@ func (aep AccountEntropyPool) DeriveSVRKey() ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (aep AccountEntropyPool) DeriveBackupKey() ([]byte, error) {
|
func (aep AccountEntropyPool) DeriveBackupKey() ([]byte, error) {
|
||||||
var out BackupKey
|
var out [C.SignalBACKUP_KEY_LEN]byte
|
||||||
aepC, free := GoStringToCString(string(aep))
|
|
||||||
defer free()
|
|
||||||
signalFfiError := C.signal_account_entropy_pool_derive_backup_key(
|
signalFfiError := C.signal_account_entropy_pool_derive_backup_key(
|
||||||
out.cFixedArray(),
|
(*[C.SignalBACKUP_KEY_LEN]C.uint8_t)(unsafe.Pointer(&out)),
|
||||||
aepC,
|
C.CString(string(aep)),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(aep)
|
runtime.KeepAlive(aep)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,7 @@ func NewUUIDAddressFromString(uuidStr string, deviceID uint) (*Address, error) {
|
||||||
|
|
||||||
func newAddress(name string, deviceID uint) (*Address, error) {
|
func newAddress(name string, deviceID uint) (*Address, error) {
|
||||||
var pa C.SignalMutPointerProtocolAddress
|
var pa C.SignalMutPointerProtocolAddress
|
||||||
nameStr, freeNameStr := GoStringToCString(name)
|
signalFfiError := C.signal_address_new(&pa, C.CString(name), C.uint(deviceID))
|
||||||
defer freeNameStr()
|
|
||||||
signalFfiError := C.signal_address_new(&pa, nameStr, C.uint(deviceID))
|
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
|
|
@ -83,7 +81,7 @@ func (pa *Address) CancelFinalizer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pa *Address) Name() (string, error) {
|
func (pa *Address) Name() (string, error) {
|
||||||
var name C.SignalCStringPtr
|
var name *C.char
|
||||||
signalFfiError := C.signal_address_get_name(&name, pa.constPtr())
|
signalFfiError := C.signal_address_get_name(&name, pa.constPtr())
|
||||||
runtime.KeepAlive(pa)
|
runtime.KeepAlive(pa)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,6 @@ func (aes *AES256_GCM_SIV) Decrypt(ciphertext, nonce, associatedData []byte) ([]
|
||||||
BytesToBuffer(nonce),
|
BytesToBuffer(nonce),
|
||||||
BytesToBuffer(associatedData),
|
BytesToBuffer(associatedData),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(aes)
|
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,17 +24,15 @@ package libsignalgo
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
// type AuthCredential [181]byte
|
// type AuthCredential [C.SignalAUTH_CREDENTIAL_LEN]byte
|
||||||
// type AuthCredentialResponse [361]byte
|
// type AuthCredentialResponse [C.SignalAUTH_CREDENTIAL_RESPONSE_LEN]byte
|
||||||
const AuthCredentialWithPniLength = 265
|
type AuthCredentialWithPni [C.SignalAUTH_CREDENTIAL_WITH_PNI_LEN]byte
|
||||||
const AuthCredentialWithPniResponseLength = 425
|
type AuthCredentialWithPniResponse [C.SignalAUTH_CREDENTIAL_WITH_PNI_RESPONSE_LEN]byte
|
||||||
|
|
||||||
type AuthCredentialWithPni [AuthCredentialWithPniLength]byte
|
|
||||||
type AuthCredentialWithPniResponse [AuthCredentialWithPniResponseLength]byte
|
|
||||||
type AuthCredentialPresentation []byte
|
type AuthCredentialPresentation []byte
|
||||||
|
|
||||||
func (ac *AuthCredentialWithPni) Slice() []byte {
|
func (ac *AuthCredentialWithPni) Slice() []byte {
|
||||||
|
|
@ -53,8 +51,8 @@ func ReceiveAuthCredentialWithPni(
|
||||||
signalFfiError := C.signal_server_public_params_receive_auth_credential_with_pni_as_service_id(
|
signalFfiError := C.signal_server_public_params_receive_auth_credential_with_pni_as_service_id(
|
||||||
&c_result,
|
&c_result,
|
||||||
C.SignalConstPointerServerPublicParams{serverPublicParams},
|
C.SignalConstPointerServerPublicParams{serverPublicParams},
|
||||||
NewACIServiceID(aci).cConstFixedArray(),
|
NewACIServiceID(aci).CFixedBytes(),
|
||||||
NewPNIServiceID(pni).cConstFixedArray(),
|
NewPNIServiceID(pni).CFixedBytes(),
|
||||||
C.uint64_t(redemptionTime),
|
C.uint64_t(redemptionTime),
|
||||||
BytesToBuffer(authCredResponse[:]),
|
BytesToBuffer(authCredResponse[:]),
|
||||||
)
|
)
|
||||||
|
|
@ -62,16 +60,13 @@ func ReceiveAuthCredentialWithPni(
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
resultBytes := CopySignalOwnedBufferToBytes(c_result)
|
resultBytes := CopySignalOwnedBufferToBytes(c_result)
|
||||||
if len(resultBytes) != AuthCredentialWithPniLength {
|
if len(resultBytes) != C.SignalAUTH_CREDENTIAL_WITH_PNI_LEN {
|
||||||
return nil, fmt.Errorf("invalid response length %d (expected %d)", len(resultBytes), AuthCredentialWithPniLength)
|
return nil, fmt.Errorf("invalid response length %d (expected %d)", len(resultBytes), C.SignalAUTH_CREDENTIAL_WITH_PNI_LEN)
|
||||||
}
|
}
|
||||||
return (*AuthCredentialWithPni)(resultBytes), nil
|
return (*AuthCredentialWithPni)(resultBytes), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAuthCredentialWithPniResponse(b []byte) (*AuthCredentialWithPniResponse, error) {
|
func NewAuthCredentialWithPniResponse(b []byte) (*AuthCredentialWithPniResponse, error) {
|
||||||
if len(b) != AuthCredentialWithPniResponseLength {
|
|
||||||
return nil, fmt.Errorf("invalid auth credential with pni response length %d (expected %d)", len(b), AuthCredentialWithPniResponseLength)
|
|
||||||
}
|
|
||||||
borrowedBuffer := BytesToBuffer(b)
|
borrowedBuffer := BytesToBuffer(b)
|
||||||
signalFfiError := C.signal_auth_credential_with_pni_response_check_valid_contents(borrowedBuffer)
|
signalFfiError := C.signal_auth_credential_with_pni_response_check_valid_contents(borrowedBuffer)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
|
|
@ -88,12 +83,14 @@ func CreateAuthCredentialWithPniPresentation(
|
||||||
authCredWithPni AuthCredentialWithPni,
|
authCredWithPni AuthCredentialWithPni,
|
||||||
) (*AuthCredentialPresentation, error) {
|
) (*AuthCredentialPresentation, error) {
|
||||||
var c_result C.SignalOwnedBuffer = C.SignalOwnedBuffer{}
|
var c_result C.SignalOwnedBuffer = C.SignalOwnedBuffer{}
|
||||||
|
c_randomness := (*[C.SignalRANDOMNESS_LEN]C.uchar)(unsafe.Pointer(&randomness[0]))
|
||||||
|
c_groupSecretParams := (*[C.SignalGROUP_SECRET_PARAMS_LEN]C.uchar)(unsafe.Pointer(&groupSecretParams[0]))
|
||||||
|
|
||||||
signalFfiError := C.signal_server_public_params_create_auth_credential_with_pni_presentation_deterministic(
|
signalFfiError := C.signal_server_public_params_create_auth_credential_with_pni_presentation_deterministic(
|
||||||
&c_result,
|
&c_result,
|
||||||
C.SignalConstPointerServerPublicParams{serverPublicParams},
|
C.SignalConstPointerServerPublicParams{serverPublicParams},
|
||||||
randomness.cConstFixedArray(),
|
c_randomness,
|
||||||
groupSecretParams.cConstFixedArray(),
|
c_groupSecretParams,
|
||||||
BytesToBuffer(authCredWithPni[:]),
|
BytesToBuffer(authCredWithPni[:]),
|
||||||
)
|
)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,7 @@ import (
|
||||||
"go.mau.fi/util/random"
|
"go.mau.fi/util/random"
|
||||||
)
|
)
|
||||||
|
|
||||||
const BackupKeyLength = 32
|
type BackupKey [C.SignalBACKUP_KEY_LEN]byte
|
||||||
|
|
||||||
type BackupKey [BackupKeyLength]byte
|
|
||||||
|
|
||||||
func (bk *BackupKey) Slice() []byte {
|
func (bk *BackupKey) Slice() []byte {
|
||||||
if bk == nil {
|
if bk == nil {
|
||||||
|
|
@ -40,25 +38,17 @@ func (bk *BackupKey) Slice() []byte {
|
||||||
|
|
||||||
const BackupIDLength = 16
|
const BackupIDLength = 16
|
||||||
|
|
||||||
type BackupID = fixedArray16
|
type BackupID [BackupIDLength]byte
|
||||||
type BackupMetadataKey = fixedArray32
|
type BackupMetadataKey [C.SignalLOCAL_BACKUP_METADATA_KEY_LEN]byte
|
||||||
type BackupMediaID = fixedArray15
|
type BackupMediaID [C.SignalMEDIA_ID_LEN]byte
|
||||||
type BackupMediaKey = fixedArray64
|
type BackupMediaKey [C.SignalMEDIA_ENCRYPTION_KEY_LEN]byte
|
||||||
|
|
||||||
func (bk *BackupKey) cFixedArray() *C.SignalType_FixedArray32_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray32_uint8_t)(unsafe.Pointer(bk))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bk *BackupKey) cConstFixedArray() cFixedArray32Compat {
|
|
||||||
return cFixedArray32Compat(bk.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func GenerateRandomBackupKey() *BackupKey {
|
func GenerateRandomBackupKey() *BackupKey {
|
||||||
return (*BackupKey)(random.Bytes(BackupKeyLength))
|
return (*BackupKey)(random.Bytes(C.SignalBACKUP_KEY_LEN))
|
||||||
}
|
}
|
||||||
|
|
||||||
func BytesToBackupKey(bytes []byte) *BackupKey {
|
func BytesToBackupKey(bytes []byte) *BackupKey {
|
||||||
if len(bytes) != BackupKeyLength {
|
if len(bytes) != C.SignalBACKUP_KEY_LEN {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return (*BackupKey)(bytes)
|
return (*BackupKey)(bytes)
|
||||||
|
|
@ -67,9 +57,9 @@ func BytesToBackupKey(bytes []byte) *BackupKey {
|
||||||
func (bk *BackupKey) DeriveBackupID(aci ServiceID) (*BackupID, error) {
|
func (bk *BackupKey) DeriveBackupID(aci ServiceID) (*BackupID, error) {
|
||||||
var out BackupID
|
var out BackupID
|
||||||
signalFfiError := C.signal_backup_key_derive_backup_id(
|
signalFfiError := C.signal_backup_key_derive_backup_id(
|
||||||
out.cFixedArray(),
|
(*[BackupIDLength]C.uint8_t)(unsafe.Pointer(&out)),
|
||||||
bk.cConstFixedArray(),
|
(*[C.SignalBACKUP_KEY_LEN]C.uint8_t)(unsafe.Pointer(bk)),
|
||||||
aci.cConstFixedArray(),
|
aci.CFixedBytes(),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(bk)
|
runtime.KeepAlive(bk)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
|
|
@ -82,8 +72,8 @@ func (bk *BackupKey) DeriveECKey(aci ServiceID) (*PrivateKey, error) {
|
||||||
var out C.SignalMutPointerPrivateKey
|
var out C.SignalMutPointerPrivateKey
|
||||||
signalFfiError := C.signal_backup_key_derive_ec_key(
|
signalFfiError := C.signal_backup_key_derive_ec_key(
|
||||||
&out,
|
&out,
|
||||||
bk.cConstFixedArray(),
|
(*[C.SignalBACKUP_KEY_LEN]C.uint8_t)(unsafe.Pointer(&bk)),
|
||||||
aci.cConstFixedArray(),
|
aci.CFixedBytes(),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(bk)
|
runtime.KeepAlive(bk)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
|
|
@ -95,8 +85,8 @@ func (bk *BackupKey) DeriveECKey(aci ServiceID) (*PrivateKey, error) {
|
||||||
func (bk *BackupKey) DeriveLocalBackupMetadataKey() (*BackupMetadataKey, error) {
|
func (bk *BackupKey) DeriveLocalBackupMetadataKey() (*BackupMetadataKey, error) {
|
||||||
var out BackupMetadataKey
|
var out BackupMetadataKey
|
||||||
signalFfiError := C.signal_backup_key_derive_local_backup_metadata_key(
|
signalFfiError := C.signal_backup_key_derive_local_backup_metadata_key(
|
||||||
out.cFixedArray(),
|
(*[C.SignalLOCAL_BACKUP_METADATA_KEY_LEN]C.uint8_t)(unsafe.Pointer(&out)),
|
||||||
bk.cConstFixedArray(),
|
(*[C.SignalBACKUP_KEY_LEN]C.uint8_t)(unsafe.Pointer(bk)),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(bk)
|
runtime.KeepAlive(bk)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
|
|
@ -107,12 +97,10 @@ func (bk *BackupKey) DeriveLocalBackupMetadataKey() (*BackupMetadataKey, error)
|
||||||
|
|
||||||
func (bk *BackupKey) DeriveMediaID(mediaName string) (*BackupMediaID, error) {
|
func (bk *BackupKey) DeriveMediaID(mediaName string) (*BackupMediaID, error) {
|
||||||
var out BackupMediaID
|
var out BackupMediaID
|
||||||
mediaNameStr, mediaNameFree := GoStringToCString(mediaName)
|
|
||||||
defer mediaNameFree()
|
|
||||||
signalFfiError := C.signal_backup_key_derive_media_id(
|
signalFfiError := C.signal_backup_key_derive_media_id(
|
||||||
out.cFixedArray(),
|
(*[C.SignalMEDIA_ID_LEN]C.uint8_t)(unsafe.Pointer(&out)),
|
||||||
bk.cConstFixedArray(),
|
(*[C.SignalBACKUP_KEY_LEN]C.uint8_t)(unsafe.Pointer(bk)),
|
||||||
mediaNameStr,
|
C.CString(mediaName),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(bk)
|
runtime.KeepAlive(bk)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
|
|
@ -124,9 +112,9 @@ func (bk *BackupKey) DeriveMediaID(mediaName string) (*BackupMediaID, error) {
|
||||||
func (bk *BackupKey) DeriveMediaEncryptionKey(mediaID *BackupMediaID) (*BackupMediaKey, error) {
|
func (bk *BackupKey) DeriveMediaEncryptionKey(mediaID *BackupMediaID) (*BackupMediaKey, error) {
|
||||||
var out BackupMediaKey
|
var out BackupMediaKey
|
||||||
signalFfiError := C.signal_backup_key_derive_media_encryption_key(
|
signalFfiError := C.signal_backup_key_derive_media_encryption_key(
|
||||||
out.cFixedArray(),
|
(*[C.SignalMEDIA_ENCRYPTION_KEY_LEN]C.uint8_t)(unsafe.Pointer(&out)),
|
||||||
bk.cConstFixedArray(),
|
(*[C.SignalBACKUP_KEY_LEN]C.uint8_t)(unsafe.Pointer(bk)),
|
||||||
mediaID.cConstFixedArray(),
|
(*[C.SignalMEDIA_ID_LEN]C.uint8_t)(unsafe.Pointer(mediaID)),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(bk)
|
runtime.KeepAlive(bk)
|
||||||
runtime.KeepAlive(mediaID)
|
runtime.KeepAlive(mediaID)
|
||||||
|
|
@ -139,9 +127,9 @@ func (bk *BackupKey) DeriveMediaEncryptionKey(mediaID *BackupMediaID) (*BackupMe
|
||||||
func (bk *BackupKey) DeriveThumbnailTransitEncryptionKey(mediaID *BackupMediaID) (*BackupMediaKey, error) {
|
func (bk *BackupKey) DeriveThumbnailTransitEncryptionKey(mediaID *BackupMediaID) (*BackupMediaKey, error) {
|
||||||
var out BackupMediaKey
|
var out BackupMediaKey
|
||||||
signalFfiError := C.signal_backup_key_derive_thumbnail_transit_encryption_key(
|
signalFfiError := C.signal_backup_key_derive_thumbnail_transit_encryption_key(
|
||||||
out.cFixedArray(),
|
(*[C.SignalMEDIA_ENCRYPTION_KEY_LEN]C.uint8_t)(unsafe.Pointer(&out)),
|
||||||
bk.cConstFixedArray(),
|
(*[C.SignalBACKUP_KEY_LEN]C.uint8_t)(unsafe.Pointer(bk)),
|
||||||
mediaID.cConstFixedArray(),
|
(*[C.SignalMEDIA_ID_LEN]C.uint8_t)(unsafe.Pointer(mediaID)),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(bk)
|
runtime.KeepAlive(bk)
|
||||||
runtime.KeepAlive(mediaID)
|
runtime.KeepAlive(mediaID)
|
||||||
|
|
|
||||||
|
|
@ -21,14 +21,12 @@ package libsignalgo
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BorrowedMutableBuffer(length int) C.SignalBorrowedMutableBuffer {
|
func BorrowedMutableBuffer(length int) C.SignalBorrowedMutableBuffer {
|
||||||
if length <= 0 {
|
|
||||||
return C.SignalBorrowedMutableBuffer{}
|
|
||||||
}
|
|
||||||
data := make([]byte, length)
|
data := make([]byte, length)
|
||||||
return C.SignalBorrowedMutableBuffer{
|
return C.SignalBorrowedMutableBuffer{
|
||||||
base: (*C.uchar)(unsafe.Pointer(&data[0])),
|
base: (*C.uchar)(unsafe.Pointer(&data[0])),
|
||||||
|
|
@ -50,9 +48,10 @@ func ManyBytesToBuffer[T ~[]byte](datas []T) (C.SignalBorrowedSliceOfBuffers, fu
|
||||||
buffers := make([]C.SignalBorrowedBuffer, len(datas))
|
buffers := make([]C.SignalBorrowedBuffer, len(datas))
|
||||||
var pinner runtime.Pinner
|
var pinner runtime.Pinner
|
||||||
for i, data := range datas {
|
for i, data := range datas {
|
||||||
if len(data) > 0 {
|
if len(data) == 0 {
|
||||||
pinner.Pin(&data[0])
|
panic(fmt.Errorf("empty slice passed to ManyBytesToBuffer at index %d", i))
|
||||||
}
|
}
|
||||||
|
pinner.Pin(&data[0])
|
||||||
buffers[i] = BytesToBuffer(data)
|
buffers[i] = BytesToBuffer(data)
|
||||||
}
|
}
|
||||||
return C.SignalBorrowedSliceOfBuffers{
|
return C.SignalBorrowedSliceOfBuffers{
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,3 @@ package libsignalgo
|
||||||
#cgo LDFLAGS: -lsignal_ffi -ldl -lm -lz -lstdc++
|
#cgo LDFLAGS: -lsignal_ffi -ldl -lm -lz -lstdc++
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
import (
|
|
||||||
"go.mau.fi/mautrix-signal/pkg/libsignalgo/signalversion"
|
|
||||||
)
|
|
||||||
|
|
||||||
const Version = signalversion.Version
|
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,6 @@ func NewCiphertextMessage(plaintext *PlaintextContent) (*CiphertextMessage, erro
|
||||||
&ciphertextMessage,
|
&ciphertextMessage,
|
||||||
plaintext.constPtr(),
|
plaintext.constPtr(),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(plaintext)
|
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,20 +18,12 @@ package libsignalgo
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#include "./libsignal-ffi.h"
|
#include "./libsignal-ffi.h"
|
||||||
#include <stdlib.h>
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
import "unsafe"
|
import "unsafe"
|
||||||
|
|
||||||
func GoStringToCString(str string) (C.SignalCStringPtr, func()) {
|
func CopyCStringToString(cString *C.char) (s string) {
|
||||||
cStr := C.CString(str)
|
s = C.GoString(cString)
|
||||||
return C.SignalCStringPtr(unsafe.Pointer(cStr)), func() {
|
|
||||||
C.free(unsafe.Pointer(cStr))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func CopyCStringToString(cString C.SignalCStringPtr) (s string) {
|
|
||||||
s = C.GoString((*C.char)(unsafe.Pointer(cString)))
|
|
||||||
C.signal_free_string(cString)
|
C.signal_free_string(cString)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,7 @@ func (dtk *DeviceTransferKey) PrivateKeyMaterial() []byte {
|
||||||
|
|
||||||
func (dtk *DeviceTransferKey) GenerateCertificate(name string, days int) ([]byte, error) {
|
func (dtk *DeviceTransferKey) GenerateCertificate(name string, days int) ([]byte, error) {
|
||||||
var resp C.SignalOwnedBuffer = C.SignalOwnedBuffer{}
|
var resp C.SignalOwnedBuffer = C.SignalOwnedBuffer{}
|
||||||
nameStr, freeNameStr := GoStringToCString(name)
|
signalFfiError := C.signal_device_transfer_generate_certificate(&resp, BytesToBuffer(dtk.privateKey), C.CString(name), C.uint32_t(days))
|
||||||
defer freeNameStr()
|
|
||||||
signalFfiError := C.signal_device_transfer_generate_certificate(&resp, BytesToBuffer(dtk.privateKey), nameStr, C.uint32_t(days))
|
|
||||||
runtime.KeepAlive(dtk)
|
runtime.KeepAlive(dtk)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ func wrapError(signalError *C.SignalFfiError) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func wrapSignalError(signalError *C.SignalFfiError, errorType C.uint32_t) error {
|
func wrapSignalError(signalError *C.SignalFfiError, errorType C.uint32_t) error {
|
||||||
var messageBytes C.SignalCStringPtr
|
var messageBytes *C.char
|
||||||
getMessageError := C.signal_error_get_message(&messageBytes, signalError)
|
getMessageError := C.signal_error_get_message(&messageBytes, signalError)
|
||||||
if getMessageError != nil {
|
if getMessageError != nil {
|
||||||
// Ignore any errors from this, it will just end up being an empty string.
|
// Ignore any errors from this, it will just end up being an empty string.
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,6 @@ func NewFingerprint(iterations, version FingerprintVersion, localIdentifier []by
|
||||||
BytesToBuffer(remoteIdentifier),
|
BytesToBuffer(remoteIdentifier),
|
||||||
remoteKey.constPtr(),
|
remoteKey.constPtr(),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(localKey)
|
|
||||||
runtime.KeepAlive(remoteKey)
|
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
|
|
@ -94,7 +92,7 @@ func (f *Fingerprint) ScannableEncoding() ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Fingerprint) DisplayString() (string, error) {
|
func (f *Fingerprint) DisplayString() (string, error) {
|
||||||
var displayString C.SignalCStringPtr
|
var displayString *C.char
|
||||||
signalFfiError := C.signal_fingerprint_display_string(&displayString, f.constPtr())
|
signalFfiError := C.signal_fingerprint_display_string(&displayString, f.constPtr())
|
||||||
runtime.KeepAlive(f)
|
runtime.KeepAlive(f)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
|
|
|
||||||
|
|
@ -1,159 +0,0 @@
|
||||||
// mautrix-signal - A Matrix-signal puppeting bridge.
|
|
||||||
// Copyright (C) 2026 Tulir Asokan
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Affero General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Affero General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package libsignalgo
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include "./libsignal-ffi.h"
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
type fixedArray15 [15]byte
|
|
||||||
type fixedArray16 [16]byte
|
|
||||||
type fixedArray17 [17]byte
|
|
||||||
type fixedArray32 [32]byte
|
|
||||||
type fixedArray64 [64]byte
|
|
||||||
type fixedArray65 [65]byte
|
|
||||||
type fixedArray97 [97]byte
|
|
||||||
type fixedArray129 [129]byte
|
|
||||||
type fixedArray153 [153]byte
|
|
||||||
type fixedArray177 [177]byte
|
|
||||||
type fixedArray289 [289]byte
|
|
||||||
type fixedArray329 [329]byte
|
|
||||||
type fixedArray409 [409]byte
|
|
||||||
type fixedArray473 [473]byte
|
|
||||||
type fixedArray497 [497]byte
|
|
||||||
|
|
||||||
func (a *fixedArray15) cFixedArray() *C.SignalType_FixedArray15_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray15_uint8_t)(unsafe.Pointer(a))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray15) cConstFixedArray() cFixedArray15Compat {
|
|
||||||
return cFixedArray15Compat(a.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray16) cFixedArray() *C.SignalType_FixedArray16_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray16_uint8_t)(unsafe.Pointer(a))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray16) cConstFixedArray() cFixedArray16Compat {
|
|
||||||
return cFixedArray16Compat(a.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray17) cFixedArray() *C.SignalType_FixedArray17_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray17_uint8_t)(unsafe.Pointer(a))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray17) cConstFixedArray() cFixedArray17Compat {
|
|
||||||
return cFixedArray17Compat(a.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray32) cFixedArray() *C.SignalType_FixedArray32_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray32_uint8_t)(unsafe.Pointer(a))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray32) cConstFixedArray() cFixedArray32Compat {
|
|
||||||
return cFixedArray32Compat(a.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray64) cFixedArray() *C.SignalType_FixedArray64_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray64_uint8_t)(unsafe.Pointer(a))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray64) cConstFixedArray() cFixedArray64Compat {
|
|
||||||
return cFixedArray64Compat(a.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray65) cFixedArray() *C.SignalType_FixedArray65_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray65_uint8_t)(unsafe.Pointer(a))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray65) cConstFixedArray() cFixedArray65Compat {
|
|
||||||
return cFixedArray65Compat(a.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray97) cFixedArray() *C.SignalType_FixedArray97_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray97_uint8_t)(unsafe.Pointer(a))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray97) cConstFixedArray() cFixedArray97Compat {
|
|
||||||
return cFixedArray97Compat(a.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray129) cFixedArray() *C.SignalType_FixedArray129_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray129_uint8_t)(unsafe.Pointer(a))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray129) cConstFixedArray() cFixedArray129Compat {
|
|
||||||
return cFixedArray129Compat(a.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray153) cFixedArray() *C.SignalType_FixedArray153_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray153_uint8_t)(unsafe.Pointer(a))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray153) cConstFixedArray() cFixedArray153Compat {
|
|
||||||
return cFixedArray153Compat(a.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray177) cFixedArray() *C.SignalType_FixedArray177_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray177_uint8_t)(unsafe.Pointer(a))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray177) cConstFixedArray() cFixedArray177Compat {
|
|
||||||
return cFixedArray177Compat(a.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray289) cFixedArray() *C.SignalType_FixedArray289_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray289_uint8_t)(unsafe.Pointer(a))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray289) cConstFixedArray() cFixedArray289Compat {
|
|
||||||
return cFixedArray289Compat(a.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray329) cFixedArray() *C.SignalType_FixedArray329_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray329_uint8_t)(unsafe.Pointer(a))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray329) cConstFixedArray() cFixedArray329Compat {
|
|
||||||
return cFixedArray329Compat(a.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray409) cFixedArray() *C.SignalType_FixedArray409_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray409_uint8_t)(unsafe.Pointer(a))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray409) cConstFixedArray() cFixedArray409Compat {
|
|
||||||
return cFixedArray409Compat(a.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray473) cFixedArray() *C.SignalType_FixedArray473_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray473_uint8_t)(unsafe.Pointer(a))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray473) cConstFixedArray() cFixedArray473Compat {
|
|
||||||
return cFixedArray473Compat(a.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray497) cFixedArray() *C.SignalType_FixedArray497_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray497_uint8_t)(unsafe.Pointer(a))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *fixedArray497) cConstFixedArray() cFixedArray497Compat {
|
|
||||||
return cFixedArray497Compat(a.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
//go:build darwin || android || ios || (windows && arm64)
|
|
||||||
|
|
||||||
package libsignalgo
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include "./libsignal-ffi.h"
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
type cFixedArray15Compat = *C.SignalType_FixedArray15_uint8_t
|
|
||||||
type cFixedArray16Compat = *C.SignalType_FixedArray16_uint8_t
|
|
||||||
type cFixedArray17Compat = *C.SignalType_FixedArray17_uint8_t
|
|
||||||
type cFixedArray32Compat = *C.SignalType_FixedArray32_uint8_t
|
|
||||||
type cFixedArray64Compat = *C.SignalType_FixedArray64_uint8_t
|
|
||||||
type cFixedArray65Compat = *C.SignalType_FixedArray65_uint8_t
|
|
||||||
type cFixedArray97Compat = *C.SignalType_FixedArray97_uint8_t
|
|
||||||
type cFixedArray129Compat = *C.SignalType_FixedArray129_uint8_t
|
|
||||||
type cFixedArray153Compat = *C.SignalType_FixedArray153_uint8_t
|
|
||||||
type cFixedArray177Compat = *C.SignalType_FixedArray177_uint8_t
|
|
||||||
type cFixedArray289Compat = *C.SignalType_FixedArray289_uint8_t
|
|
||||||
type cFixedArray329Compat = *C.SignalType_FixedArray329_uint8_t
|
|
||||||
type cFixedArray409Compat = *C.SignalType_FixedArray409_uint8_t
|
|
||||||
type cFixedArray473Compat = *C.SignalType_FixedArray473_uint8_t
|
|
||||||
type cFixedArray497Compat = *C.SignalType_FixedArray497_uint8_t
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
//go:build !(darwin || android || ios || (windows && arm64))
|
|
||||||
|
|
||||||
package libsignalgo
|
|
||||||
|
|
||||||
/*
|
|
||||||
#include "./libsignal-ffi.h"
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
// Hack for https://github.com/golang/go/issues/7270
|
|
||||||
// The clang version is more correct, but doesn't work with gcc.
|
|
||||||
type cFixedArray15Compat = *[15]C.uint8_t
|
|
||||||
type cFixedArray16Compat = *[16]C.uint8_t
|
|
||||||
type cFixedArray17Compat = *[17]C.uint8_t
|
|
||||||
type cFixedArray32Compat = *[32]C.uint8_t
|
|
||||||
type cFixedArray64Compat = *[64]C.uint8_t
|
|
||||||
type cFixedArray65Compat = *[65]C.uint8_t
|
|
||||||
type cFixedArray97Compat = *[97]C.uint8_t
|
|
||||||
type cFixedArray129Compat = *[129]C.uint8_t
|
|
||||||
type cFixedArray153Compat = *[153]C.uint8_t
|
|
||||||
type cFixedArray177Compat = *[177]C.uint8_t
|
|
||||||
type cFixedArray289Compat = *[289]C.uint8_t
|
|
||||||
type cFixedArray329Compat = *[329]C.uint8_t
|
|
||||||
type cFixedArray409Compat = *[409]C.uint8_t
|
|
||||||
type cFixedArray473Compat = *[473]C.uint8_t
|
|
||||||
type cFixedArray497Compat = *[497]C.uint8_t
|
|
||||||
|
|
@ -31,9 +31,7 @@ import (
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
const RandomnessLength = 32
|
type Randomness [C.SignalRANDOMNESS_LEN]byte
|
||||||
|
|
||||||
type Randomness = fixedArray32
|
|
||||||
|
|
||||||
func GenerateRandomness() Randomness {
|
func GenerateRandomness() Randomness {
|
||||||
var randomness Randomness
|
var randomness Randomness
|
||||||
|
|
@ -44,39 +42,14 @@ func GenerateRandomness() Randomness {
|
||||||
return randomness
|
return randomness
|
||||||
}
|
}
|
||||||
|
|
||||||
const GroupMasterKeyLength = 32
|
const GroupMasterKeyLength = C.SignalGROUP_MASTER_KEY_LEN
|
||||||
const GroupIdentifierLength = 32
|
const GroupIdentifierLength = C.SignalGROUP_IDENTIFIER_LEN
|
||||||
const GroupSecretParamsLength = 289
|
|
||||||
|
|
||||||
type GroupMasterKey [GroupMasterKeyLength]byte
|
type GroupMasterKey [GroupMasterKeyLength]byte
|
||||||
type GroupSecretParams [GroupSecretParamsLength]byte
|
type GroupSecretParams [C.SignalGROUP_SECRET_PARAMS_LEN]byte
|
||||||
type GroupPublicParams = fixedArray97
|
type GroupPublicParams [C.SignalGROUP_PUBLIC_PARAMS_LEN]byte
|
||||||
type GroupIdentifier [GroupIdentifierLength]byte
|
type GroupIdentifier [GroupIdentifierLength]byte
|
||||||
|
|
||||||
func (gmk *GroupMasterKey) cFixedArray() *C.SignalType_FixedArray32_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray32_uint8_t)(unsafe.Pointer(gmk))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gmk *GroupMasterKey) cConstFixedArray() cFixedArray32Compat {
|
|
||||||
return cFixedArray32Compat(gmk.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gsp *GroupSecretParams) cFixedArray() *C.SignalType_FixedArray289_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray289_uint8_t)(unsafe.Pointer(gsp))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gsp *GroupSecretParams) cConstFixedArray() cFixedArray289Compat {
|
|
||||||
return cFixedArray289Compat(gsp.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gid *GroupIdentifier) cFixedArray() *C.SignalType_FixedArray32_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray32_uint8_t)(unsafe.Pointer(gid))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gid *GroupIdentifier) cConstFixedArray() cFixedArray32Compat {
|
|
||||||
return cFixedArray32Compat(gid.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (gid *GroupIdentifier) String() string {
|
func (gid *GroupIdentifier) String() string {
|
||||||
if gid == nil {
|
if gid == nil {
|
||||||
return ""
|
return ""
|
||||||
|
|
@ -84,8 +57,8 @@ func (gid *GroupIdentifier) String() string {
|
||||||
return base64.StdEncoding.EncodeToString(gid[:])
|
return base64.StdEncoding.EncodeToString(gid[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
type UUIDCiphertext = fixedArray65
|
type UUIDCiphertext [C.SignalUUID_CIPHERTEXT_LEN]byte
|
||||||
type ProfileKeyCiphertext = fixedArray65
|
type ProfileKeyCiphertext [C.SignalPROFILE_KEY_CIPHERTEXT_LEN]byte
|
||||||
|
|
||||||
func GenerateGroupSecretParams() (GroupSecretParams, error) {
|
func GenerateGroupSecretParams() (GroupSecretParams, error) {
|
||||||
return GenerateGroupSecretParamsWithRandomness(GenerateRandomness())
|
return GenerateGroupSecretParamsWithRandomness(GenerateRandomness())
|
||||||
|
|
@ -108,43 +81,51 @@ func (gmk GroupMasterKey) SecretParams() (GroupSecretParams, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateGroupSecretParamsWithRandomness(randomness Randomness) (GroupSecretParams, error) {
|
func GenerateGroupSecretParamsWithRandomness(randomness Randomness) (GroupSecretParams, error) {
|
||||||
var params GroupSecretParams
|
var params [C.SignalGROUP_SECRET_PARAMS_LEN]C.uchar
|
||||||
signalFfiError := C.signal_group_secret_params_generate_deterministic(params.cFixedArray(), randomness.cConstFixedArray())
|
signalFfiError := C.signal_group_secret_params_generate_deterministic(¶ms, (*[C.SignalRANDOMNESS_LEN]C.uint8_t)(unsafe.Pointer(&randomness)))
|
||||||
runtime.KeepAlive(randomness)
|
runtime.KeepAlive(randomness)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return GroupSecretParams{}, wrapError(signalFfiError)
|
return GroupSecretParams{}, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
return params, nil
|
var groupSecretParams GroupSecretParams
|
||||||
|
copy(groupSecretParams[:], C.GoBytes(unsafe.Pointer(¶ms), C.int(C.SignalGROUP_SECRET_PARAMS_LEN)))
|
||||||
|
return groupSecretParams, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeriveGroupSecretParamsFromMasterKey(groupMasterKey GroupMasterKey) (GroupSecretParams, error) {
|
func DeriveGroupSecretParamsFromMasterKey(groupMasterKey GroupMasterKey) (GroupSecretParams, error) {
|
||||||
var params GroupSecretParams
|
var params [C.SignalGROUP_SECRET_PARAMS_LEN]C.uchar
|
||||||
signalFfiError := C.signal_group_secret_params_derive_from_master_key(params.cFixedArray(), groupMasterKey.cConstFixedArray())
|
signalFfiError := C.signal_group_secret_params_derive_from_master_key(¶ms, (*[C.SignalGROUP_MASTER_KEY_LEN]C.uint8_t)(unsafe.Pointer(&groupMasterKey)))
|
||||||
runtime.KeepAlive(groupMasterKey)
|
runtime.KeepAlive(groupMasterKey)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return GroupSecretParams{}, wrapError(signalFfiError)
|
return GroupSecretParams{}, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
return params, nil
|
var groupSecretParams GroupSecretParams
|
||||||
|
copy(groupSecretParams[:], C.GoBytes(unsafe.Pointer(¶ms), C.int(C.SignalGROUP_SECRET_PARAMS_LEN)))
|
||||||
|
return groupSecretParams, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gsp *GroupSecretParams) GetPublicParams() (*GroupPublicParams, error) {
|
func (gsp *GroupSecretParams) GetPublicParams() (*GroupPublicParams, error) {
|
||||||
var publicParams GroupPublicParams
|
var publicParams [C.SignalGROUP_PUBLIC_PARAMS_LEN]C.uchar
|
||||||
signalFfiError := C.signal_group_secret_params_get_public_params(publicParams.cFixedArray(), gsp.cConstFixedArray())
|
signalFfiError := C.signal_group_secret_params_get_public_params(&publicParams, (*[C.SignalGROUP_SECRET_PARAMS_LEN]C.uint8_t)(unsafe.Pointer(gsp)))
|
||||||
runtime.KeepAlive(gsp)
|
runtime.KeepAlive(gsp)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
return &publicParams, nil
|
var groupPublicParams GroupPublicParams
|
||||||
|
copy(groupPublicParams[:], C.GoBytes(unsafe.Pointer(&publicParams), C.int(C.SignalGROUP_PUBLIC_PARAMS_LEN)))
|
||||||
|
return &groupPublicParams, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetGroupIdentifier(groupPublicParams GroupPublicParams) (*GroupIdentifier, error) {
|
func GetGroupIdentifier(groupPublicParams GroupPublicParams) (*GroupIdentifier, error) {
|
||||||
var groupIdentifier GroupIdentifier
|
var groupIdentifier [C.SignalGROUP_IDENTIFIER_LEN]C.uchar
|
||||||
signalFfiError := C.signal_group_public_params_get_group_identifier(groupIdentifier.cFixedArray(), groupPublicParams.cConstFixedArray())
|
signalFfiError := C.signal_group_public_params_get_group_identifier(&groupIdentifier, (*[C.SignalGROUP_PUBLIC_PARAMS_LEN]C.uint8_t)(unsafe.Pointer(&groupPublicParams)))
|
||||||
runtime.KeepAlive(groupPublicParams)
|
runtime.KeepAlive(groupPublicParams)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
return &groupIdentifier, nil
|
var result GroupIdentifier
|
||||||
|
copy(result[:], C.GoBytes(unsafe.Pointer(&groupIdentifier), C.int(C.SignalGROUP_IDENTIFIER_LEN)))
|
||||||
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gsp *GroupSecretParams) DecryptBlobWithPadding(blob []byte) ([]byte, error) {
|
func (gsp *GroupSecretParams) DecryptBlobWithPadding(blob []byte) ([]byte, error) {
|
||||||
|
|
@ -152,7 +133,7 @@ func (gsp *GroupSecretParams) DecryptBlobWithPadding(blob []byte) ([]byte, error
|
||||||
borrowedBlob := BytesToBuffer(blob)
|
borrowedBlob := BytesToBuffer(blob)
|
||||||
signalFfiError := C.signal_group_secret_params_decrypt_blob_with_padding(
|
signalFfiError := C.signal_group_secret_params_decrypt_blob_with_padding(
|
||||||
&plaintext,
|
&plaintext,
|
||||||
gsp.cConstFixedArray(),
|
(*[C.SignalGROUP_SECRET_PARAMS_LEN]C.uint8_t)(unsafe.Pointer(gsp)),
|
||||||
borrowedBlob,
|
borrowedBlob,
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(gsp)
|
runtime.KeepAlive(gsp)
|
||||||
|
|
@ -168,8 +149,8 @@ func (gsp *GroupSecretParams) EncryptBlobWithPaddingDeterministic(randomness Ran
|
||||||
borrowedPlaintext := BytesToBuffer(plaintext)
|
borrowedPlaintext := BytesToBuffer(plaintext)
|
||||||
signalFfiError := C.signal_group_secret_params_encrypt_blob_with_padding_deterministic(
|
signalFfiError := C.signal_group_secret_params_encrypt_blob_with_padding_deterministic(
|
||||||
&ciphertext,
|
&ciphertext,
|
||||||
gsp.cConstFixedArray(),
|
(*[C.SignalGROUP_SECRET_PARAMS_LEN]C.uint8_t)(unsafe.Pointer(gsp)),
|
||||||
randomness.cConstFixedArray(),
|
(*[C.SignalRANDOMNESS_LEN]C.uint8_t)(unsafe.Pointer(&randomness)),
|
||||||
borrowedPlaintext,
|
borrowedPlaintext,
|
||||||
(C.uint32_t)(padding_len),
|
(C.uint32_t)(padding_len),
|
||||||
)
|
)
|
||||||
|
|
@ -184,11 +165,11 @@ func (gsp *GroupSecretParams) EncryptBlobWithPaddingDeterministic(randomness Ran
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gsp *GroupSecretParams) DecryptServiceID(ciphertextServiceID UUIDCiphertext) (ServiceID, error) {
|
func (gsp *GroupSecretParams) DecryptServiceID(ciphertextServiceID UUIDCiphertext) (ServiceID, error) {
|
||||||
var serviceIDBytes ServiceIDFixedBytes
|
u := C.SignalServiceIdFixedWidthBinaryBytes{}
|
||||||
signalFfiError := C.signal_group_secret_params_decrypt_service_id(
|
signalFfiError := C.signal_group_secret_params_decrypt_service_id(
|
||||||
serviceIDBytes.cFixedArray(),
|
&u,
|
||||||
gsp.cConstFixedArray(),
|
(*[C.SignalGROUP_SECRET_PARAMS_LEN]C.uint8_t)(unsafe.Pointer(gsp)),
|
||||||
ciphertextServiceID.cConstFixedArray(),
|
(*[C.SignalUUID_CIPHERTEXT_LEN]C.uint8_t)(unsafe.Pointer(&ciphertextServiceID)),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(gsp)
|
runtime.KeepAlive(gsp)
|
||||||
runtime.KeepAlive(ciphertextServiceID)
|
runtime.KeepAlive(ciphertextServiceID)
|
||||||
|
|
@ -196,31 +177,33 @@ func (gsp *GroupSecretParams) DecryptServiceID(ciphertextServiceID UUIDCiphertex
|
||||||
return EmptyServiceID, wrapError(signalFfiError)
|
return EmptyServiceID, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
|
|
||||||
serviceID := ServiceIDFromCFixedBytes(serviceIDBytes.cFixedArray())
|
serviceID := ServiceIDFromCFixedBytes(&u)
|
||||||
return serviceID, nil
|
return serviceID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gsp *GroupSecretParams) EncryptServiceID(serviceID ServiceID) (*UUIDCiphertext, error) {
|
func (gsp *GroupSecretParams) EncryptServiceID(serviceID ServiceID) (*UUIDCiphertext, error) {
|
||||||
var cipherTextServiceID UUIDCiphertext
|
var cipherTextServiceID [C.SignalUUID_CIPHERTEXT_LEN]C.uchar
|
||||||
signalFfiError := C.signal_group_secret_params_encrypt_service_id(
|
signalFfiError := C.signal_group_secret_params_encrypt_service_id(
|
||||||
cipherTextServiceID.cFixedArray(),
|
&cipherTextServiceID,
|
||||||
gsp.cConstFixedArray(),
|
(*[C.SignalGROUP_SECRET_PARAMS_LEN]C.uint8_t)(unsafe.Pointer(gsp)),
|
||||||
serviceID.cConstFixedArray(),
|
serviceID.CFixedBytes(),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(gsp)
|
runtime.KeepAlive(gsp)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
return &cipherTextServiceID, nil
|
var result UUIDCiphertext
|
||||||
|
copy(result[:], C.GoBytes(unsafe.Pointer(&cipherTextServiceID), C.int(C.SignalUUID_CIPHERTEXT_LEN)))
|
||||||
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gsp *GroupSecretParams) DecryptProfileKey(ciphertextProfileKey ProfileKeyCiphertext, u uuid.UUID) (*ProfileKey, error) {
|
func (gsp *GroupSecretParams) DecryptProfileKey(ciphertextProfileKey ProfileKeyCiphertext, u uuid.UUID) (*ProfileKey, error) {
|
||||||
var profileKey ProfileKey
|
profileKey := [C.SignalPROFILE_KEY_LEN]C.uchar{}
|
||||||
signalFfiError := C.signal_group_secret_params_decrypt_profile_key(
|
signalFfiError := C.signal_group_secret_params_decrypt_profile_key(
|
||||||
profileKey.cFixedArray(),
|
&profileKey,
|
||||||
gsp.cConstFixedArray(),
|
(*[C.SignalGROUP_SECRET_PARAMS_LEN]C.uint8_t)(unsafe.Pointer(gsp)),
|
||||||
ciphertextProfileKey.cConstFixedArray(),
|
(*[C.SignalPROFILE_KEY_CIPHERTEXT_LEN]C.uint8_t)(unsafe.Pointer(&ciphertextProfileKey)),
|
||||||
NewACIServiceID(u).cConstFixedArray(),
|
NewACIServiceID(u).CFixedBytes(),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(gsp)
|
runtime.KeepAlive(gsp)
|
||||||
runtime.KeepAlive(ciphertextProfileKey)
|
runtime.KeepAlive(ciphertextProfileKey)
|
||||||
|
|
@ -228,23 +211,27 @@ func (gsp *GroupSecretParams) DecryptProfileKey(ciphertextProfileKey ProfileKeyC
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
return &profileKey, nil
|
var result ProfileKey
|
||||||
|
copy(result[:], C.GoBytes(unsafe.Pointer(&profileKey), C.int(C.SignalPROFILE_KEY_LEN)))
|
||||||
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gsp *GroupSecretParams) EncryptProfileKey(profileKey ProfileKey, u uuid.UUID) (*ProfileKeyCiphertext, error) {
|
func (gsp *GroupSecretParams) EncryptProfileKey(profileKey ProfileKey, u uuid.UUID) (*ProfileKeyCiphertext, error) {
|
||||||
var ciphertextProfileKey ProfileKeyCiphertext
|
ciphertextProfileKey := [C.SignalPROFILE_KEY_CIPHERTEXT_LEN]C.uchar{}
|
||||||
signalFfiError := C.signal_group_secret_params_encrypt_profile_key(
|
signalFfiError := C.signal_group_secret_params_encrypt_profile_key(
|
||||||
ciphertextProfileKey.cFixedArray(),
|
&ciphertextProfileKey,
|
||||||
gsp.cConstFixedArray(),
|
(*[C.SignalGROUP_SECRET_PARAMS_LEN]C.uint8_t)(unsafe.Pointer(gsp)),
|
||||||
profileKey.cConstFixedArray(),
|
(*[C.SignalPROFILE_KEY_LEN]C.uint8_t)(unsafe.Pointer(&profileKey)),
|
||||||
NewACIServiceID(u).cConstFixedArray(),
|
NewACIServiceID(u).CFixedBytes(),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(gsp)
|
runtime.KeepAlive(gsp)
|
||||||
runtime.KeepAlive(profileKey)
|
runtime.KeepAlive(profileKey)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
return &ciphertextProfileKey, nil
|
var result ProfileKeyCiphertext
|
||||||
|
copy(result[:], C.GoBytes(unsafe.Pointer(&ciphertextProfileKey), C.int(C.SignalPROFILE_KEY_CIPHERTEXT_LEN)))
|
||||||
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gsp *GroupSecretParams) CreateExpiringProfileKeyCredentialPresentation(spp *ServerPublicParams, credential ExpiringProfileKeyCredential) (*ProfileKeyCredentialPresentation, error) {
|
func (gsp *GroupSecretParams) CreateExpiringProfileKeyCredentialPresentation(spp *ServerPublicParams, credential ExpiringProfileKeyCredential) (*ProfileKeyCredentialPresentation, error) {
|
||||||
|
|
@ -253,9 +240,9 @@ func (gsp *GroupSecretParams) CreateExpiringProfileKeyCredentialPresentation(spp
|
||||||
signalFfiError := C.signal_server_public_params_create_expiring_profile_key_credential_presentation_deterministic(
|
signalFfiError := C.signal_server_public_params_create_expiring_profile_key_credential_presentation_deterministic(
|
||||||
&out,
|
&out,
|
||||||
C.SignalConstPointerServerPublicParams{spp},
|
C.SignalConstPointerServerPublicParams{spp},
|
||||||
randomness.cConstFixedArray(),
|
(*[C.SignalRANDOMNESS_LEN]C.uint8_t)(unsafe.Pointer(&randomness)),
|
||||||
gsp.cConstFixedArray(),
|
(*[C.SignalGROUP_SECRET_PARAMS_LEN]C.uchar)(unsafe.Pointer(gsp)),
|
||||||
credential.cConstFixedArray(),
|
(*[C.SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN]C.uchar)(unsafe.Pointer(&credential)),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(gsp)
|
runtime.KeepAlive(gsp)
|
||||||
runtime.KeepAlive(credential)
|
runtime.KeepAlive(credential)
|
||||||
|
|
@ -269,14 +256,16 @@ func (gsp *GroupSecretParams) CreateExpiringProfileKeyCredentialPresentation(spp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gsp *GroupSecretParams) GetMasterKey() (*GroupMasterKey, error) {
|
func (gsp *GroupSecretParams) GetMasterKey() (*GroupMasterKey, error) {
|
||||||
var masterKey GroupMasterKey
|
masterKeyBytes := [C.SignalGROUP_MASTER_KEY_LEN]C.uchar{}
|
||||||
signalFfiError := C.signal_group_secret_params_get_master_key(
|
signalFfiError := C.signal_group_secret_params_get_master_key(
|
||||||
masterKey.cFixedArray(),
|
&masterKeyBytes,
|
||||||
gsp.cConstFixedArray(),
|
(*[C.SignalGROUP_SECRET_PARAMS_LEN]C.uchar)(unsafe.Pointer(gsp)),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(gsp)
|
runtime.KeepAlive(gsp)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
return &masterKey, nil
|
var groupMasterKey GroupMasterKey
|
||||||
|
copy(groupMasterKey[:], C.GoBytes(unsafe.Pointer(&masterKeyBytes), C.int(C.SignalGROUP_MASTER_KEY_LEN)))
|
||||||
|
return &groupMasterKey, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
type GroupSendFullToken []byte
|
type GroupSendFullToken []byte
|
||||||
|
|
@ -90,7 +91,7 @@ func (gse GroupSendEndorsement) ToToken(groupSecretParams *GroupSecretParams) (G
|
||||||
signalFfiError := C.signal_group_send_endorsement_to_token(
|
signalFfiError := C.signal_group_send_endorsement_to_token(
|
||||||
&token,
|
&token,
|
||||||
BytesToBuffer(gse),
|
BytesToBuffer(gse),
|
||||||
groupSecretParams.cConstFixedArray(),
|
(*[C.SignalGROUP_SECRET_PARAMS_LEN]C.uint8_t)(unsafe.Pointer(groupSecretParams)),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(gse)
|
runtime.KeepAlive(gse)
|
||||||
runtime.KeepAlive(groupSecretParams)
|
runtime.KeepAlive(groupSecretParams)
|
||||||
|
|
@ -179,17 +180,17 @@ func (gser GroupSendEndorsementsResponse) ReceiveWithServiceIDs(
|
||||||
groupMembers []ServiceID, localUser ServiceID, params *GroupSecretParams, spp *ServerPublicParams,
|
groupMembers []ServiceID, localUser ServiceID, params *GroupSecretParams, spp *ServerPublicParams,
|
||||||
) (GroupSendEndorsement, map[ServiceID]GroupSendEndorsement, error) {
|
) (GroupSendEndorsement, map[ServiceID]GroupSendEndorsement, error) {
|
||||||
var out C.SignalBytestringArray = C.SignalBytestringArray{}
|
var out C.SignalBytestringArray = C.SignalBytestringArray{}
|
||||||
concatenatedMembers := make([]byte, len(groupMembers)*ServiceIDFixedBytesLength)
|
concatenatedMembers := make([]byte, len(groupMembers)*17)
|
||||||
for i, member := range groupMembers {
|
for i, member := range groupMembers {
|
||||||
copy(concatenatedMembers[i*ServiceIDFixedBytesLength:(i+1)*ServiceIDFixedBytesLength], member.FixedBytes()[:])
|
copy(concatenatedMembers[i*17:(i+1)*17], member.FixedBytes()[:])
|
||||||
}
|
}
|
||||||
signalFfiError := C.signal_group_send_endorsements_response_receive_and_combine_with_service_ids(
|
signalFfiError := C.signal_group_send_endorsements_response_receive_and_combine_with_service_ids(
|
||||||
&out,
|
&out,
|
||||||
BytesToBuffer(gser),
|
BytesToBuffer(gser),
|
||||||
BytesToBuffer(concatenatedMembers),
|
BytesToBuffer(concatenatedMembers),
|
||||||
localUser.cConstFixedArray(),
|
localUser.CFixedBytes(),
|
||||||
C.uint64_t(time.Now().Unix()),
|
C.uint64_t(time.Now().Unix()),
|
||||||
params.cConstFixedArray(),
|
(*[C.SignalGROUP_SECRET_PARAMS_LEN]C.uint8_t)(unsafe.Pointer(params)),
|
||||||
C.SignalConstPointerServerPublicParams{spp},
|
C.SignalConstPointerServerPublicParams{spp},
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(gser)
|
runtime.KeepAlive(gser)
|
||||||
|
|
@ -206,13 +207,7 @@ func (gser GroupSendEndorsementsResponse) ReceiveWithServiceIDs(
|
||||||
memberEndorsements[member] = endorsements[i]
|
memberEndorsements[member] = endorsements[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nonEmptyEndorsements := make([]GroupSendEndorsement, 0, len(endorsements))
|
combined, err := GroupSendEndorsementCombine(endorsements...)
|
||||||
for _, endorsement := range endorsements {
|
|
||||||
if len(endorsement) > 0 {
|
|
||||||
nonEmptyEndorsements = append(nonEmptyEndorsements, endorsement)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
combined, err := GroupSendEndorsementCombine(nonEmptyEndorsements...)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, memberEndorsements, err
|
return nil, memberEndorsements, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ package libsignalgo
|
||||||
/*
|
/*
|
||||||
#include "./libsignal-ffi.h"
|
#include "./libsignal-ffi.h"
|
||||||
|
|
||||||
extern int signal_get_identity_key_pair_callback(void *store_ctx, SignalPairOfMutPointerPrivateKeyMutPointerPublicKey *keyp);
|
extern int signal_get_identity_key_pair_callback(void *store_ctx, SignalMutPointerPrivateKey *keyp);
|
||||||
extern int signal_get_local_registration_id_callback(void *store_ctx, uint32_t *idp);
|
extern int signal_get_local_registration_id_callback(void *store_ctx, uint32_t *idp);
|
||||||
extern int signal_save_identity_key_callback(void *store_ctx, uint8_t *out, SignalMutPointerProtocolAddress address, SignalMutPointerPublicKey public_key);
|
extern int signal_save_identity_key_callback(void *store_ctx, uint8_t *out, SignalMutPointerProtocolAddress address, SignalMutPointerPublicKey public_key);
|
||||||
extern int signal_get_identity_key_callback(void *store_ctx, SignalMutPointerPublicKey *public_keyp, SignalMutPointerProtocolAddress address);
|
extern int signal_get_identity_key_callback(void *store_ctx, SignalMutPointerPublicKey *public_keyp, SignalMutPointerProtocolAddress address);
|
||||||
|
|
@ -49,29 +49,22 @@ type IdentityKeyStore interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
//export signal_get_identity_key_pair_callback
|
//export signal_get_identity_key_pair_callback
|
||||||
func signal_get_identity_key_pair_callback(storeCtx unsafe.Pointer, keyp *C.SignalPairOfMutPointerPrivateKeyMutPointerPublicKey) C.int {
|
func signal_get_identity_key_pair_callback(storeCtx unsafe.Pointer, keyp *C.SignalMutPointerPrivateKey) C.int {
|
||||||
return wrapStoreCallback(storeCtx, func(store IdentityKeyStore, ctx context.Context) error {
|
return wrapStoreCallback(storeCtx, func(store IdentityKeyStore, ctx context.Context) error {
|
||||||
key, err := store.GetIdentityKeyPair(ctx)
|
key, err := store.GetIdentityKeyPair(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if key == nil {
|
if key == nil {
|
||||||
keyp.first.raw = nil
|
keyp.raw = nil
|
||||||
keyp.second.raw = nil
|
} else {
|
||||||
return nil
|
clone, err := key.privateKey.Clone()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
clone.CancelFinalizer()
|
||||||
|
keyp.raw = clone.ptr
|
||||||
}
|
}
|
||||||
privClone, err := key.privateKey.Clone()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
pubClone, err := key.publicKey.Clone()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
privClone.CancelFinalizer()
|
|
||||||
pubClone.CancelFinalizer()
|
|
||||||
keyp.first.raw = privClone.ptr
|
|
||||||
keyp.second.raw = pubClone.ptr
|
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -158,12 +151,12 @@ func signal_destroy_identity_key_store_callback(storeCtx unsafe.Pointer) {
|
||||||
|
|
||||||
func (ctx *CallbackContext) wrapIdentityKeyStore(store IdentityKeyStore) C.SignalConstPointerFfiIdentityKeyStoreStruct {
|
func (ctx *CallbackContext) wrapIdentityKeyStore(store IdentityKeyStore) C.SignalConstPointerFfiIdentityKeyStoreStruct {
|
||||||
return C.SignalConstPointerFfiIdentityKeyStoreStruct{&C.SignalIdentityKeyStore{
|
return C.SignalConstPointerFfiIdentityKeyStoreStruct{&C.SignalIdentityKeyStore{
|
||||||
ctx: wrapStore(ctx, store),
|
ctx: wrapStore(ctx, store),
|
||||||
get_local_identity_key_pair: C.SignalFfiIdentityKeyStoreGetLocalIdentityKeyPair(C.signal_get_identity_key_pair_callback),
|
get_local_identity_private_key: C.SignalFfiBridgeIdentityKeyStoreGetLocalIdentityPrivateKey(C.signal_get_identity_key_pair_callback),
|
||||||
get_local_registration_id: C.SignalFfiIdentityKeyStoreGetLocalRegistrationId(C.signal_get_local_registration_id_callback),
|
get_local_registration_id: C.SignalFfiBridgeIdentityKeyStoreGetLocalRegistrationId(C.signal_get_local_registration_id_callback),
|
||||||
get_identity_key: C.SignalFfiIdentityKeyStoreGetIdentityKey(C.signal_get_identity_key_callback),
|
get_identity_key: C.SignalFfiBridgeIdentityKeyStoreGetIdentityKey(C.signal_get_identity_key_callback),
|
||||||
save_identity_key: C.SignalFfiIdentityKeyStoreSaveIdentityKey(C.signal_save_identity_key_callback),
|
save_identity_key: C.SignalFfiBridgeIdentityKeyStoreSaveIdentityKey(C.signal_save_identity_key_callback),
|
||||||
is_trusted_identity: C.SignalFfiIdentityKeyStoreIsTrustedIdentity(C.signal_is_trusted_identity_callback),
|
is_trusted_identity: C.SignalFfiBridgeIdentityKeyStoreIsTrustedIdentity(C.signal_is_trusted_identity_callback),
|
||||||
destroy: C.SignalFfiIdentityKeyStoreDestroy(C.signal_destroy_identity_key_store_callback),
|
destroy: C.SignalFfiBridgeIdentityKeyStoreDestroy(C.signal_destroy_identity_key_store_callback),
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,9 +77,9 @@ func signal_destroy_kyber_pre_key_store_callback(storeCtx unsafe.Pointer) {
|
||||||
func (ctx *CallbackContext) wrapKyberPreKeyStore(store KyberPreKeyStore) C.SignalConstPointerFfiKyberPreKeyStoreStruct {
|
func (ctx *CallbackContext) wrapKyberPreKeyStore(store KyberPreKeyStore) C.SignalConstPointerFfiKyberPreKeyStoreStruct {
|
||||||
return C.SignalConstPointerFfiKyberPreKeyStoreStruct{&C.SignalKyberPreKeyStore{
|
return C.SignalConstPointerFfiKyberPreKeyStoreStruct{&C.SignalKyberPreKeyStore{
|
||||||
ctx: wrapStore(ctx, store),
|
ctx: wrapStore(ctx, store),
|
||||||
load_kyber_pre_key: C.SignalFfiKyberPreKeyStoreLoadKyberPreKey(C.signal_load_kyber_pre_key_callback),
|
load_kyber_pre_key: C.SignalFfiBridgeKyberPreKeyStoreLoadKyberPreKey(C.signal_load_kyber_pre_key_callback),
|
||||||
store_kyber_pre_key: C.SignalFfiKyberPreKeyStoreStoreKyberPreKey(C.signal_store_kyber_pre_key_callback),
|
store_kyber_pre_key: C.SignalFfiBridgeKyberPreKeyStoreStoreKyberPreKey(C.signal_store_kyber_pre_key_callback),
|
||||||
mark_kyber_pre_key_used: C.SignalFfiKyberPreKeyStoreMarkKyberPreKeyUsed(C.signal_mark_kyber_pre_key_used_callback),
|
mark_kyber_pre_key_used: C.SignalFfiBridgeKyberPreKeyStoreMarkKyberPreKeyUsed(C.signal_mark_kyber_pre_key_used_callback),
|
||||||
destroy: C.SignalFfiKyberPreKeyStoreDestroy(C.signal_destroy_kyber_pre_key_store_callback),
|
destroy: C.SignalFfiBridgeKyberPreKeyStoreDestroy(C.signal_destroy_kyber_pre_key_store_callback),
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 8fc2113bda042fc972a166a24b974b0d34155c6c
|
Subproject commit ffaa9f0435569d6775d8be636f268f882ed67ce3
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -19,9 +19,8 @@ package libsignalgo
|
||||||
/*
|
/*
|
||||||
#include <./libsignal-ffi.h>
|
#include <./libsignal-ffi.h>
|
||||||
|
|
||||||
extern int signal_log_callback(void *ctx, SignalLogLevel level, SignalCStringPtr file, uint32_t line, SignalCStringPtr message);
|
extern void signal_log_callback(void *ctx, SignalLogLevel level, char *file, uint32_t line, char *message);
|
||||||
extern int signal_log_flush_callback(void *ctx);
|
extern void signal_log_flush_callback(void *ctx);
|
||||||
extern void signal_log_destroy_callback(void *ctx);
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
|
|
@ -32,20 +31,13 @@ import (
|
||||||
var ffiLogger Logger
|
var ffiLogger Logger
|
||||||
|
|
||||||
//export signal_log_callback
|
//export signal_log_callback
|
||||||
func signal_log_callback(ctx unsafe.Pointer, level C.SignalLogLevel, file C.SignalCStringPtr, line C.uint32_t, message C.SignalCStringPtr) C.int {
|
func signal_log_callback(ctx unsafe.Pointer, level C.SignalLogLevel, file *C.char, line C.uint32_t, message *C.char) {
|
||||||
ffiLogger.Log(LogLevel(int(level)), CopyCStringToString(file), uint(line), CopyCStringToString(message))
|
ffiLogger.Log(LogLevel(int(level)), C.GoString(file), uint(line), C.GoString(message))
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//export signal_log_flush_callback
|
//export signal_log_flush_callback
|
||||||
func signal_log_flush_callback(ctx unsafe.Pointer) C.int {
|
func signal_log_flush_callback(ctx unsafe.Pointer) {
|
||||||
ffiLogger.Flush()
|
ffiLogger.Flush()
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
//export signal_log_destroy_callback
|
|
||||||
func signal_log_destroy_callback(ctx unsafe.Pointer) {
|
|
||||||
ffiLogger.Destroy()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type LogLevel int
|
type LogLevel int
|
||||||
|
|
@ -61,14 +53,12 @@ const (
|
||||||
type Logger interface {
|
type Logger interface {
|
||||||
Log(level LogLevel, file string, line uint, message string)
|
Log(level LogLevel, file string, line uint, message string)
|
||||||
Flush()
|
Flush()
|
||||||
Destroy()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitLogger(level LogLevel, logger Logger) {
|
func InitLogger(level LogLevel, logger Logger) {
|
||||||
ffiLogger = logger
|
ffiLogger = logger
|
||||||
C.signal_init_logger(C.SignalLogLevel(level), C.SignalFfiLoggerStruct{
|
C.signal_init_logger(C.SignalLogLevel(level), C.SignalFfiLogger{
|
||||||
log: C.SignalFfiLoggerLog(C.signal_log_callback),
|
log: C.SignalLogCallback(C.signal_log_callback),
|
||||||
flush: C.SignalFfiLoggerFlush(C.signal_log_flush_callback),
|
flush: C.SignalLogFlushCallback(C.signal_log_flush_callback),
|
||||||
destroy: C.SignalFfiLoggerDestroy(C.signal_log_destroy_callback),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Encrypt(ctx context.Context, plaintext []byte, forAddress, localAddress *Address, sessionStore SessionStore, identityKeyStore IdentityKeyStore) (*CiphertextMessage, error) {
|
func Encrypt(ctx context.Context, plaintext []byte, forAddress *Address, sessionStore SessionStore, identityKeyStore IdentityKeyStore) (*CiphertextMessage, error) {
|
||||||
var ciphertextMessage C.SignalMutPointerCiphertextMessage
|
var ciphertextMessage C.SignalMutPointerCiphertextMessage
|
||||||
var now C.uint64_t = C.uint64_t(time.Now().Unix())
|
var now C.uint64_t = C.uint64_t(time.Now().Unix())
|
||||||
callbackCtx := NewCallbackContext(ctx)
|
callbackCtx := NewCallbackContext(ctx)
|
||||||
|
|
@ -36,21 +36,19 @@ func Encrypt(ctx context.Context, plaintext []byte, forAddress, localAddress *Ad
|
||||||
&ciphertextMessage,
|
&ciphertextMessage,
|
||||||
BytesToBuffer(plaintext),
|
BytesToBuffer(plaintext),
|
||||||
forAddress.constPtr(),
|
forAddress.constPtr(),
|
||||||
localAddress.constPtr(),
|
|
||||||
callbackCtx.wrapSessionStore(sessionStore),
|
callbackCtx.wrapSessionStore(sessionStore),
|
||||||
callbackCtx.wrapIdentityKeyStore(identityKeyStore),
|
callbackCtx.wrapIdentityKeyStore(identityKeyStore),
|
||||||
now,
|
now,
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(plaintext)
|
runtime.KeepAlive(plaintext)
|
||||||
runtime.KeepAlive(forAddress)
|
runtime.KeepAlive(forAddress)
|
||||||
runtime.KeepAlive(localAddress)
|
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return nil, callbackCtx.wrapError(signalFfiError)
|
return nil, callbackCtx.wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
return wrapCiphertextMessage(ciphertextMessage.raw), nil
|
return wrapCiphertextMessage(ciphertextMessage.raw), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Decrypt(ctx context.Context, message *Message, fromAddress, localAddress *Address, sessionStore SessionStore, identityStore IdentityKeyStore) ([]byte, error) {
|
func Decrypt(ctx context.Context, message *Message, fromAddress *Address, sessionStore SessionStore, identityStore IdentityKeyStore) ([]byte, error) {
|
||||||
callbackCtx := NewCallbackContext(ctx)
|
callbackCtx := NewCallbackContext(ctx)
|
||||||
defer callbackCtx.Unref()
|
defer callbackCtx.Unref()
|
||||||
var decrypted C.SignalOwnedBuffer = C.SignalOwnedBuffer{}
|
var decrypted C.SignalOwnedBuffer = C.SignalOwnedBuffer{}
|
||||||
|
|
@ -58,13 +56,11 @@ func Decrypt(ctx context.Context, message *Message, fromAddress, localAddress *A
|
||||||
&decrypted,
|
&decrypted,
|
||||||
message.constPtr(),
|
message.constPtr(),
|
||||||
fromAddress.constPtr(),
|
fromAddress.constPtr(),
|
||||||
localAddress.constPtr(),
|
|
||||||
callbackCtx.wrapSessionStore(sessionStore),
|
callbackCtx.wrapSessionStore(sessionStore),
|
||||||
callbackCtx.wrapIdentityKeyStore(identityStore),
|
callbackCtx.wrapIdentityKeyStore(identityStore),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(message)
|
runtime.KeepAlive(message)
|
||||||
runtime.KeepAlive(fromAddress)
|
runtime.KeepAlive(fromAddress)
|
||||||
runtime.KeepAlive(localAddress)
|
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return nil, callbackCtx.wrapError(signalFfiError)
|
return nil, callbackCtx.wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
|
|
@ -73,10 +69,10 @@ func Decrypt(ctx context.Context, message *Message, fromAddress, localAddress *A
|
||||||
|
|
||||||
type Message struct {
|
type Message struct {
|
||||||
nc noCopy
|
nc noCopy
|
||||||
ptr *C.SignalSignalMessage
|
ptr *C.SignalMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
func wrapMessage(ptr *C.SignalSignalMessage) *Message {
|
func wrapMessage(ptr *C.SignalMessage) *Message {
|
||||||
message := &Message{ptr: ptr}
|
message := &Message{ptr: ptr}
|
||||||
runtime.SetFinalizer(message, (*Message).Destroy)
|
runtime.SetFinalizer(message, (*Message).Destroy)
|
||||||
return message
|
return message
|
||||||
|
|
@ -158,3 +154,22 @@ func (m *Message) GetCounter() (uint32, error) {
|
||||||
}
|
}
|
||||||
return uint32(counter), nil
|
return uint32(counter), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Message) VerifyMAC(sender, receiver *PublicKey, macKey []byte) (bool, error) {
|
||||||
|
var result C.bool
|
||||||
|
signalFfiError := C.signal_message_verify_mac(
|
||||||
|
&result,
|
||||||
|
m.constPtr(),
|
||||||
|
sender.constPtr(),
|
||||||
|
receiver.constPtr(),
|
||||||
|
BytesToBuffer(macKey),
|
||||||
|
)
|
||||||
|
runtime.KeepAlive(m)
|
||||||
|
runtime.KeepAlive(sender)
|
||||||
|
runtime.KeepAlive(receiver)
|
||||||
|
runtime.KeepAlive(macKey)
|
||||||
|
if signalFfiError != nil {
|
||||||
|
return false, wrapError(signalFfiError)
|
||||||
|
}
|
||||||
|
return bool(result), nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,17 +20,16 @@ package libsignalgo
|
||||||
#include "./libsignal-ffi.h"
|
#include "./libsignal-ffi.h"
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
import "runtime"
|
import (
|
||||||
|
"runtime"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
type MessageBackupKey struct {
|
type MessageBackupKey struct {
|
||||||
nc noCopy
|
nc noCopy
|
||||||
ptr *C.SignalMessageBackupKey
|
ptr *C.SignalMessageBackupKey
|
||||||
}
|
}
|
||||||
|
|
||||||
const MessageBackupKeyBytesLength = 32
|
|
||||||
|
|
||||||
type messageBackupKeyBytes = fixedArray32
|
|
||||||
|
|
||||||
func wrapMessageBackupKey(ptr *C.SignalMessageBackupKey) *MessageBackupKey {
|
func wrapMessageBackupKey(ptr *C.SignalMessageBackupKey) *MessageBackupKey {
|
||||||
backupKey := &MessageBackupKey{ptr: ptr}
|
backupKey := &MessageBackupKey{ptr: ptr}
|
||||||
runtime.SetFinalizer(backupKey, (*MessageBackupKey).Destroy)
|
runtime.SetFinalizer(backupKey, (*MessageBackupKey).Destroy)
|
||||||
|
|
@ -39,12 +38,10 @@ func wrapMessageBackupKey(ptr *C.SignalMessageBackupKey) *MessageBackupKey {
|
||||||
|
|
||||||
func MessageBackupKeyFromAccountEntropyPool(aep AccountEntropyPool, aci ServiceID) (*MessageBackupKey, error) {
|
func MessageBackupKeyFromAccountEntropyPool(aep AccountEntropyPool, aci ServiceID) (*MessageBackupKey, error) {
|
||||||
var bk C.SignalMutPointerMessageBackupKey
|
var bk C.SignalMutPointerMessageBackupKey
|
||||||
aepC, free := GoStringToCString(string(aep))
|
|
||||||
defer free()
|
|
||||||
signalFfiError := C.signal_message_backup_key_from_account_entropy_pool(
|
signalFfiError := C.signal_message_backup_key_from_account_entropy_pool(
|
||||||
&bk,
|
&bk,
|
||||||
aepC,
|
C.CString(string(aep)),
|
||||||
aci.cConstFixedArray(),
|
aci.CFixedBytes(),
|
||||||
nil, // TODO what's a forward secrecy token?
|
nil, // TODO what's a forward secrecy token?
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(aep)
|
runtime.KeepAlive(aep)
|
||||||
|
|
@ -58,8 +55,8 @@ func MessageBackupKeyFromBackupKeyAndID(backupKey *BackupKey, backupID *BackupID
|
||||||
var bk C.SignalMutPointerMessageBackupKey
|
var bk C.SignalMutPointerMessageBackupKey
|
||||||
signalFfiError := C.signal_message_backup_key_from_backup_key_and_backup_id(
|
signalFfiError := C.signal_message_backup_key_from_backup_key_and_backup_id(
|
||||||
&bk,
|
&bk,
|
||||||
backupKey.cConstFixedArray(),
|
(*[C.SignalBACKUP_KEY_LEN]C.uint8_t)(unsafe.Pointer(backupKey)),
|
||||||
backupID.cConstFixedArray(),
|
(*[BackupIDLength]C.uint8_t)(unsafe.Pointer(backupID)),
|
||||||
nil, // TODO what's a forward secrecy token?
|
nil, // TODO what's a forward secrecy token?
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(backupKey)
|
runtime.KeepAlive(backupKey)
|
||||||
|
|
@ -83,28 +80,26 @@ func (bk *MessageBackupKey) Destroy() error {
|
||||||
return wrapError(C.signal_message_backup_key_destroy(bk.mutPtr()))
|
return wrapError(C.signal_message_backup_key_destroy(bk.mutPtr()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bk *MessageBackupKey) GetHMACKey() ([MessageBackupKeyBytesLength]byte, error) {
|
func (bk *MessageBackupKey) GetHMACKey() ([32]byte, error) {
|
||||||
var out messageBackupKeyBytes
|
var out [32]byte
|
||||||
signalFfiError := C.signal_message_backup_key_get_hmac_key(
|
signalFfiError := C.signal_message_backup_key_get_hmac_key(
|
||||||
out.cFixedArray(),
|
(*[32]C.uint8_t)(unsafe.Pointer(&out)),
|
||||||
bk.constPtr(),
|
bk.constPtr(),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(bk)
|
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return [MessageBackupKeyBytesLength]byte(out), wrapError(signalFfiError)
|
return out, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
return [MessageBackupKeyBytesLength]byte(out), nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bk *MessageBackupKey) GetAESKey() ([MessageBackupKeyBytesLength]byte, error) {
|
func (bk *MessageBackupKey) GetAESKey() ([32]byte, error) {
|
||||||
var out messageBackupKeyBytes
|
var out [32]byte
|
||||||
signalFfiError := C.signal_message_backup_key_get_aes_key(
|
signalFfiError := C.signal_message_backup_key_get_aes_key(
|
||||||
out.cFixedArray(),
|
(*[32]C.uint8_t)(unsafe.Pointer(&out)),
|
||||||
bk.constPtr(),
|
bk.constPtr(),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(bk)
|
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return [MessageBackupKeyBytesLength]byte(out), wrapError(signalFfiError)
|
return out, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
return [MessageBackupKeyBytesLength]byte(out), nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
func DecryptPreKey(ctx context.Context, preKeyMessage *PreKeyMessage, fromAddress, localAddress *Address, sessionStore SessionStore, identityStore IdentityKeyStore, preKeyStore PreKeyStore, signedPreKeyStore SignedPreKeyStore, kyberPreKeyStore KyberPreKeyStore) ([]byte, error) {
|
func DecryptPreKey(ctx context.Context, preKeyMessage *PreKeyMessage, fromAddress *Address, sessionStore SessionStore, identityStore IdentityKeyStore, preKeyStore PreKeyStore, signedPreKeyStore SignedPreKeyStore, kyberPreKeyStore KyberPreKeyStore) ([]byte, error) {
|
||||||
callbackCtx := NewCallbackContext(ctx)
|
callbackCtx := NewCallbackContext(ctx)
|
||||||
defer callbackCtx.Unref()
|
defer callbackCtx.Unref()
|
||||||
var decrypted C.SignalOwnedBuffer = C.SignalOwnedBuffer{}
|
var decrypted C.SignalOwnedBuffer = C.SignalOwnedBuffer{}
|
||||||
|
|
@ -34,7 +34,6 @@ func DecryptPreKey(ctx context.Context, preKeyMessage *PreKeyMessage, fromAddres
|
||||||
&decrypted,
|
&decrypted,
|
||||||
preKeyMessage.constPtr(),
|
preKeyMessage.constPtr(),
|
||||||
fromAddress.constPtr(),
|
fromAddress.constPtr(),
|
||||||
localAddress.constPtr(),
|
|
||||||
callbackCtx.wrapSessionStore(sessionStore),
|
callbackCtx.wrapSessionStore(sessionStore),
|
||||||
callbackCtx.wrapIdentityKeyStore(identityStore),
|
callbackCtx.wrapIdentityKeyStore(identityStore),
|
||||||
callbackCtx.wrapPreKeyStore(preKeyStore),
|
callbackCtx.wrapPreKeyStore(preKeyStore),
|
||||||
|
|
@ -43,7 +42,6 @@ func DecryptPreKey(ctx context.Context, preKeyMessage *PreKeyMessage, fromAddres
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(preKeyMessage)
|
runtime.KeepAlive(preKeyMessage)
|
||||||
runtime.KeepAlive(fromAddress)
|
runtime.KeepAlive(fromAddress)
|
||||||
runtime.KeepAlive(localAddress)
|
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return nil, callbackCtx.wrapError(signalFfiError)
|
return nil, callbackCtx.wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,21 +27,19 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ProcessPreKeyBundle(ctx context.Context, bundle *PreKeyBundle, forAddress, localAddress *Address, sessionStore SessionStore, identityStore IdentityKeyStore) error {
|
func ProcessPreKeyBundle(ctx context.Context, bundle *PreKeyBundle, forAddress *Address, sessionStore SessionStore, identityStore IdentityKeyStore) error {
|
||||||
callbackCtx := NewCallbackContext(ctx)
|
callbackCtx := NewCallbackContext(ctx)
|
||||||
defer callbackCtx.Unref()
|
defer callbackCtx.Unref()
|
||||||
var now C.uint64_t = C.uint64_t(time.Now().Unix())
|
var now C.uint64_t = C.uint64_t(time.Now().Unix())
|
||||||
signalFfiError := C.signal_process_prekey_bundle(
|
signalFfiError := C.signal_process_prekey_bundle(
|
||||||
bundle.constPtr(),
|
bundle.constPtr(),
|
||||||
forAddress.constPtr(),
|
forAddress.constPtr(),
|
||||||
localAddress.constPtr(),
|
|
||||||
callbackCtx.wrapSessionStore(sessionStore),
|
callbackCtx.wrapSessionStore(sessionStore),
|
||||||
callbackCtx.wrapIdentityKeyStore(identityStore),
|
callbackCtx.wrapIdentityKeyStore(identityStore),
|
||||||
now,
|
now,
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(bundle)
|
runtime.KeepAlive(bundle)
|
||||||
runtime.KeepAlive(forAddress)
|
runtime.KeepAlive(forAddress)
|
||||||
runtime.KeepAlive(localAddress)
|
|
||||||
return callbackCtx.wrapError(signalFfiError)
|
return callbackCtx.wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,10 +117,10 @@ func (pkb *PreKeyBundle) constPtr() C.SignalConstPointerPreKeyBundle {
|
||||||
func (pkb *PreKeyBundle) Clone() (*PreKeyBundle, error) {
|
func (pkb *PreKeyBundle) Clone() (*PreKeyBundle, error) {
|
||||||
var cloned C.SignalMutPointerPreKeyBundle
|
var cloned C.SignalMutPointerPreKeyBundle
|
||||||
signalFfiError := C.signal_pre_key_bundle_clone(&cloned, pkb.constPtr())
|
signalFfiError := C.signal_pre_key_bundle_clone(&cloned, pkb.constPtr())
|
||||||
runtime.KeepAlive(pkb)
|
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
|
runtime.KeepAlive(pkb)
|
||||||
return wrapPreKeyBundle(cloned.raw), nil
|
return wrapPreKeyBundle(cloned.raw), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -138,9 +136,9 @@ func (pkb *PreKeyBundle) CancelFinalizer() {
|
||||||
func (pkb *PreKeyBundle) GetIdentityKey() (*IdentityKey, error) {
|
func (pkb *PreKeyBundle) GetIdentityKey() (*IdentityKey, error) {
|
||||||
var pk C.SignalMutPointerPublicKey
|
var pk C.SignalMutPointerPublicKey
|
||||||
signalFfiError := C.signal_pre_key_bundle_get_identity_key(&pk, pkb.constPtr())
|
signalFfiError := C.signal_pre_key_bundle_get_identity_key(&pk, pkb.constPtr())
|
||||||
runtime.KeepAlive(pkb)
|
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
|
runtime.KeepAlive(pkb)
|
||||||
return NewIdentityKeyFromPublicKey(wrapPublicKey(pk.raw))
|
return NewIdentityKeyFromPublicKey(wrapPublicKey(pk.raw))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,9 +76,9 @@ func signal_destroy_pre_key_store_callback(storeCtx unsafe.Pointer) {
|
||||||
func (ctx *CallbackContext) wrapPreKeyStore(store PreKeyStore) C.SignalConstPointerFfiPreKeyStoreStruct {
|
func (ctx *CallbackContext) wrapPreKeyStore(store PreKeyStore) C.SignalConstPointerFfiPreKeyStoreStruct {
|
||||||
return C.SignalConstPointerFfiPreKeyStoreStruct{&C.SignalPreKeyStore{
|
return C.SignalConstPointerFfiPreKeyStoreStruct{&C.SignalPreKeyStore{
|
||||||
ctx: wrapStore(ctx, store),
|
ctx: wrapStore(ctx, store),
|
||||||
load_pre_key: C.SignalFfiPreKeyStoreLoadPreKey(C.signal_load_pre_key_callback),
|
load_pre_key: C.SignalFfiBridgePreKeyStoreLoadPreKey(C.signal_load_pre_key_callback),
|
||||||
store_pre_key: C.SignalFfiPreKeyStoreStorePreKey(C.signal_store_pre_key_callback),
|
store_pre_key: C.SignalFfiBridgePreKeyStoreStorePreKey(C.signal_store_pre_key_callback),
|
||||||
remove_pre_key: C.SignalFfiPreKeyStoreRemovePreKey(C.signal_remove_pre_key_callback),
|
remove_pre_key: C.SignalFfiBridgePreKeyStoreRemovePreKey(C.signal_remove_pre_key_callback),
|
||||||
destroy: C.SignalFfiPreKeyStoreDestroy(C.signal_destroy_pre_key_store_callback),
|
destroy: C.SignalFfiBridgePreKeyStoreDestroy(C.signal_destroy_pre_key_store_callback),
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ import "C"
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
|
@ -33,38 +32,12 @@ import (
|
||||||
"go.mau.fi/util/random"
|
"go.mau.fi/util/random"
|
||||||
)
|
)
|
||||||
|
|
||||||
const ProfileKeyLength = 32
|
const ProfileKeyLength = C.SignalPROFILE_KEY_LEN
|
||||||
const AccessKeyLength = 16
|
|
||||||
const ProfileKeyVersionLength = 64
|
|
||||||
|
|
||||||
type ProfileKey [ProfileKeyLength]byte
|
type ProfileKey [ProfileKeyLength]byte
|
||||||
type ProfileKeyCommitment = fixedArray97
|
type ProfileKeyCommitment [C.SignalPROFILE_KEY_COMMITMENT_LEN]byte
|
||||||
type ProfileKeyVersion [ProfileKeyVersionLength]byte
|
type ProfileKeyVersion [C.SignalPROFILE_KEY_VERSION_ENCODED_LEN]byte
|
||||||
type AccessKey [AccessKeyLength]byte
|
type AccessKey [C.SignalACCESS_KEY_LEN]byte
|
||||||
|
|
||||||
func (pk *ProfileKey) cFixedArray() *C.SignalType_FixedArray32_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray32_uint8_t)(unsafe.Pointer(pk))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pk *ProfileKey) cConstFixedArray() cFixedArray32Compat {
|
|
||||||
return cFixedArray32Compat(pk.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pkv *ProfileKeyVersion) cFixedArray() *C.SignalType_FixedArray64_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray64_uint8_t)(unsafe.Pointer(pkv))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pkv *ProfileKeyVersion) cConstFixedArray() cFixedArray64Compat {
|
|
||||||
return cFixedArray64Compat(pkv.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ak *AccessKey) cFixedArray() *C.SignalType_FixedArray16_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray16_uint8_t)(unsafe.Pointer(ak))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ak *AccessKey) cConstFixedArray() cFixedArray16Compat {
|
|
||||||
return cFixedArray16Compat(ak.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func DeserializeProfileKey(bytes []byte) (*ProfileKey, error) {
|
func DeserializeProfileKey(bytes []byte) (*ProfileKey, error) {
|
||||||
if len(bytes) == 0 {
|
if len(bytes) == 0 {
|
||||||
|
|
@ -100,7 +73,7 @@ func (ak *AccessKey) Xor(other *AccessKey) *AccessKey {
|
||||||
return ak
|
return ak
|
||||||
}
|
}
|
||||||
var result AccessKey
|
var result AccessKey
|
||||||
for i := 0; i < AccessKeyLength; i++ {
|
for i := 0; i < C.SignalACCESS_KEY_LEN; i++ {
|
||||||
result[i] = ak[i] ^ other[i]
|
result[i] = ak[i] ^ other[i]
|
||||||
}
|
}
|
||||||
return &result
|
return &result
|
||||||
|
|
@ -111,12 +84,13 @@ func (ak *AccessKey) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pk *ProfileKey) GetCommitment(u uuid.UUID) (*ProfileKeyCommitment, error) {
|
func (pk *ProfileKey) GetCommitment(u uuid.UUID) (*ProfileKeyCommitment, error) {
|
||||||
var result ProfileKeyCommitment
|
c_result := [C.SignalPROFILE_KEY_COMMITMENT_LEN]C.uchar{}
|
||||||
c_uuid := NewACIServiceID(u).cConstFixedArray()
|
c_profileKey := (*[C.SignalPROFILE_KEY_LEN]C.uchar)(unsafe.Pointer(pk))
|
||||||
|
c_uuid := NewACIServiceID(u).CFixedBytes()
|
||||||
|
|
||||||
signalFfiError := C.signal_profile_key_get_commitment(
|
signalFfiError := C.signal_profile_key_get_commitment(
|
||||||
result.cFixedArray(),
|
&c_result,
|
||||||
pk.cConstFixedArray(),
|
c_profileKey,
|
||||||
c_uuid,
|
c_uuid,
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(pk)
|
runtime.KeepAlive(pk)
|
||||||
|
|
@ -126,16 +100,19 @@ func (pk *ProfileKey) GetCommitment(u uuid.UUID) (*ProfileKeyCommitment, error)
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var result ProfileKeyCommitment
|
||||||
|
copy(result[:], C.GoBytes(unsafe.Pointer(&c_result), C.int(C.SignalPROFILE_KEY_COMMITMENT_LEN)))
|
||||||
return &result, nil
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pk *ProfileKey) GetProfileKeyVersion(u uuid.UUID) (*ProfileKeyVersion, error) {
|
func (pk *ProfileKey) GetProfileKeyVersion(u uuid.UUID) (*ProfileKeyVersion, error) {
|
||||||
var result ProfileKeyVersion
|
c_result := [C.SignalPROFILE_KEY_VERSION_ENCODED_LEN]C.uchar{}
|
||||||
c_uuid := NewACIServiceID(u).cConstFixedArray()
|
c_profileKey := (*[C.SignalPROFILE_KEY_LEN]C.uchar)(unsafe.Pointer(pk))
|
||||||
|
c_uuid := NewACIServiceID(u).CFixedBytes()
|
||||||
|
|
||||||
signalFfiError := C.signal_profile_key_get_profile_key_version(
|
signalFfiError := C.signal_profile_key_get_profile_key_version(
|
||||||
result.cFixedArray(),
|
&c_result,
|
||||||
pk.cConstFixedArray(),
|
c_profileKey,
|
||||||
c_uuid,
|
c_uuid,
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(pk)
|
runtime.KeepAlive(pk)
|
||||||
|
|
@ -145,15 +122,18 @@ func (pk *ProfileKey) GetProfileKeyVersion(u uuid.UUID) (*ProfileKeyVersion, err
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var result ProfileKeyVersion
|
||||||
|
copy(result[:], C.GoBytes(unsafe.Pointer(&c_result), C.int(C.SignalPROFILE_KEY_VERSION_ENCODED_LEN)))
|
||||||
return &result, nil
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pk *ProfileKey) DeriveAccessKey() (*AccessKey, error) {
|
func (pk *ProfileKey) DeriveAccessKey() (*AccessKey, error) {
|
||||||
var result AccessKey
|
c_result := [C.SignalACCESS_KEY_LEN]C.uchar{}
|
||||||
|
c_profileKey := (*[C.SignalPROFILE_KEY_LEN]C.uchar)(unsafe.Pointer(pk))
|
||||||
|
|
||||||
signalFfiError := C.signal_profile_key_derive_access_key(
|
signalFfiError := C.signal_profile_key_derive_access_key(
|
||||||
result.cFixedArray(),
|
&c_result,
|
||||||
pk.cConstFixedArray(),
|
c_profileKey,
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(pk)
|
runtime.KeepAlive(pk)
|
||||||
|
|
||||||
|
|
@ -161,37 +141,31 @@ func (pk *ProfileKey) DeriveAccessKey() (*AccessKey, error) {
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var result AccessKey
|
||||||
|
copy(result[:], C.GoBytes(unsafe.Pointer(&c_result), C.int(C.SignalACCESS_KEY_LEN)))
|
||||||
return &result, nil
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const ExpiringProfileKeyCredentialResponseLength = 497
|
type ProfileKeyCredentialRequestContext [C.SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN]byte
|
||||||
|
type ProfileKeyCredentialRequest [C.SignalPROFILE_KEY_CREDENTIAL_REQUEST_LEN]byte
|
||||||
type ProfileKeyCredentialRequestContext [473]byte
|
|
||||||
type ProfileKeyCredentialRequest = fixedArray329
|
|
||||||
type ProfileKeyCredentialResponse []byte
|
type ProfileKeyCredentialResponse []byte
|
||||||
type ProfileKeyCredentialPresentation []byte
|
type ProfileKeyCredentialPresentation []byte
|
||||||
type ExpiringProfileKeyCredential = fixedArray153
|
type ExpiringProfileKeyCredential [C.SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN]byte
|
||||||
type ExpiringProfileKeyCredentialResponse = fixedArray497
|
type ExpiringProfileKeyCredentialResponse [C.SignalEXPIRING_PROFILE_KEY_CREDENTIAL_RESPONSE_LEN]byte
|
||||||
|
|
||||||
func (p *ProfileKeyCredentialRequestContext) cFixedArray() *C.SignalType_FixedArray473_uint8_t {
|
|
||||||
return (*C.SignalType_FixedArray473_uint8_t)(unsafe.Pointer(p))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *ProfileKeyCredentialRequestContext) cConstFixedArray() cFixedArray473Compat {
|
|
||||||
return cFixedArray473Compat(p.cFixedArray())
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateProfileKeyCredentialRequestContext(serverPublicParams *ServerPublicParams, u uuid.UUID, profileKey ProfileKey) (*ProfileKeyCredentialRequestContext, error) {
|
func CreateProfileKeyCredentialRequestContext(serverPublicParams *ServerPublicParams, u uuid.UUID, profileKey ProfileKey) (*ProfileKeyCredentialRequestContext, error) {
|
||||||
var result ProfileKeyCredentialRequestContext
|
c_result := [C.SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN]C.uchar{}
|
||||||
randBytes := Randomness(random.Bytes(RandomnessLength))
|
randBytes := [32]byte(random.Bytes(32))
|
||||||
c_uuid := NewACIServiceID(u).cConstFixedArray()
|
c_random := (*[32]C.uchar)(unsafe.Pointer(&randBytes[0]))
|
||||||
|
c_profileKey := (*[C.SignalPROFILE_KEY_LEN]C.uchar)(unsafe.Pointer(&profileKey[0]))
|
||||||
|
c_uuid := NewACIServiceID(u).CFixedBytes()
|
||||||
|
|
||||||
signalFfiError := C.signal_server_public_params_create_profile_key_credential_request_context_deterministic(
|
signalFfiError := C.signal_server_public_params_create_profile_key_credential_request_context_deterministic(
|
||||||
result.cFixedArray(),
|
&c_result,
|
||||||
C.SignalConstPointerServerPublicParams{serverPublicParams},
|
C.SignalConstPointerServerPublicParams{serverPublicParams},
|
||||||
randBytes.cConstFixedArray(),
|
c_random,
|
||||||
c_uuid,
|
c_uuid,
|
||||||
profileKey.cConstFixedArray(),
|
c_profileKey,
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(u)
|
runtime.KeepAlive(u)
|
||||||
runtime.KeepAlive(profileKey)
|
runtime.KeepAlive(profileKey)
|
||||||
|
|
@ -199,27 +173,27 @@ func CreateProfileKeyCredentialRequestContext(serverPublicParams *ServerPublicPa
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
|
result := ProfileKeyCredentialRequestContext(C.GoBytes(unsafe.Pointer(&c_result), C.int(C.SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN)))
|
||||||
return &result, nil
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ProfileKeyCredentialRequestContext) ProfileKeyCredentialRequestContextGetRequest() (*ProfileKeyCredentialRequest, error) {
|
func (p *ProfileKeyCredentialRequestContext) ProfileKeyCredentialRequestContextGetRequest() (*ProfileKeyCredentialRequest, error) {
|
||||||
var result ProfileKeyCredentialRequest
|
c_result := [C.SignalPROFILE_KEY_CREDENTIAL_REQUEST_LEN]C.uchar{}
|
||||||
|
c_context := (*[C.SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN]C.uchar)(unsafe.Pointer(p))
|
||||||
|
|
||||||
signalFfiError := C.signal_profile_key_credential_request_context_get_request(
|
signalFfiError := C.signal_profile_key_credential_request_context_get_request(
|
||||||
result.cFixedArray(),
|
&c_result,
|
||||||
p.cConstFixedArray(),
|
c_context,
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(p)
|
runtime.KeepAlive(p)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
|
result := ProfileKeyCredentialRequest(C.GoBytes(unsafe.Pointer(&c_result), C.int(C.SignalPROFILE_KEY_CREDENTIAL_REQUEST_LEN)))
|
||||||
return &result, nil
|
return &result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewExpiringProfileKeyCredentialResponse(b []byte) (*ExpiringProfileKeyCredentialResponse, error) {
|
func NewExpiringProfileKeyCredentialResponse(b []byte) (*ExpiringProfileKeyCredentialResponse, error) {
|
||||||
if len(b) != ExpiringProfileKeyCredentialResponseLength {
|
|
||||||
return nil, fmt.Errorf("invalid expiring profile key credential response length %d (expected %d)", len(b), ExpiringProfileKeyCredentialResponseLength)
|
|
||||||
}
|
|
||||||
borrowedBuffer := BytesToBuffer(b)
|
borrowedBuffer := BytesToBuffer(b)
|
||||||
signalFfiError := C.signal_expiring_profile_key_credential_response_check_valid_contents(borrowedBuffer)
|
signalFfiError := C.signal_expiring_profile_key_credential_response_check_valid_contents(borrowedBuffer)
|
||||||
runtime.KeepAlive(b)
|
runtime.KeepAlive(b)
|
||||||
|
|
@ -231,12 +205,12 @@ func NewExpiringProfileKeyCredentialResponse(b []byte) (*ExpiringProfileKeyCrede
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReceiveExpiringProfileKeyCredential(spp *ServerPublicParams, requestContext *ProfileKeyCredentialRequestContext, response *ExpiringProfileKeyCredentialResponse, currentTimeInSeconds uint64) (*ExpiringProfileKeyCredential, error) {
|
func ReceiveExpiringProfileKeyCredential(spp *ServerPublicParams, requestContext *ProfileKeyCredentialRequestContext, response *ExpiringProfileKeyCredentialResponse, currentTimeInSeconds uint64) (*ExpiringProfileKeyCredential, error) {
|
||||||
var credential ExpiringProfileKeyCredential
|
c_credential := [C.SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN]C.uchar{}
|
||||||
signalFfiError := C.signal_server_public_params_receive_expiring_profile_key_credential(
|
signalFfiError := C.signal_server_public_params_receive_expiring_profile_key_credential(
|
||||||
credential.cFixedArray(),
|
&c_credential,
|
||||||
C.SignalConstPointerServerPublicParams{spp},
|
C.SignalConstPointerServerPublicParams{spp},
|
||||||
requestContext.cConstFixedArray(),
|
(*[C.SignalPROFILE_KEY_CREDENTIAL_REQUEST_CONTEXT_LEN]C.uchar)(unsafe.Pointer(requestContext)),
|
||||||
response.cConstFixedArray(),
|
(*[C.SignalEXPIRING_PROFILE_KEY_CREDENTIAL_RESPONSE_LEN]C.uchar)(unsafe.Pointer(response)),
|
||||||
(C.uint64_t)(currentTimeInSeconds),
|
(C.uint64_t)(currentTimeInSeconds),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(requestContext)
|
runtime.KeepAlive(requestContext)
|
||||||
|
|
@ -245,6 +219,8 @@ func ReceiveExpiringProfileKeyCredential(spp *ServerPublicParams, requestContext
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
|
credential := ExpiringProfileKeyCredential{}
|
||||||
|
copy(credential[:], C.GoBytes(unsafe.Pointer(&c_credential), C.int(C.SignalEXPIRING_PROFILE_KEY_CREDENTIAL_LEN)))
|
||||||
return &credential, nil
|
return &credential, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -255,21 +231,25 @@ func (a ProfileKeyCredentialPresentation) CheckValidContents() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a ProfileKeyCredentialPresentation) UUIDCiphertext() (UUIDCiphertext, error) {
|
func (a ProfileKeyCredentialPresentation) UUIDCiphertext() (UUIDCiphertext, error) {
|
||||||
var out UUIDCiphertext
|
out := [C.SignalUUID_CIPHERTEXT_LEN]C.uchar{}
|
||||||
signalFfiError := C.signal_profile_key_credential_presentation_get_uuid_ciphertext(out.cFixedArray(), BytesToBuffer(a))
|
signalFfiError := C.signal_profile_key_credential_presentation_get_uuid_ciphertext(&out, BytesToBuffer(a))
|
||||||
runtime.KeepAlive(a)
|
runtime.KeepAlive(a)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return UUIDCiphertext{}, wrapError(signalFfiError)
|
return UUIDCiphertext{}, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
return out, nil
|
var result UUIDCiphertext
|
||||||
|
copy(result[:], C.GoBytes(unsafe.Pointer(&out), C.int(C.SignalUUID_CIPHERTEXT_LEN)))
|
||||||
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a ProfileKeyCredentialPresentation) ProfileKeyCiphertext() (ProfileKeyCiphertext, error) {
|
func (a ProfileKeyCredentialPresentation) ProfileKeyCiphertext() (ProfileKeyCiphertext, error) {
|
||||||
var out ProfileKeyCiphertext
|
out := [C.SignalPROFILE_KEY_CIPHERTEXT_LEN]C.uchar{}
|
||||||
signalFfiError := C.signal_profile_key_credential_presentation_get_profile_key_ciphertext(out.cFixedArray(), BytesToBuffer(a))
|
signalFfiError := C.signal_profile_key_credential_presentation_get_profile_key_ciphertext(&out, BytesToBuffer(a))
|
||||||
runtime.KeepAlive(a)
|
runtime.KeepAlive(a)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return ProfileKeyCiphertext{}, wrapError(signalFfiError)
|
return ProfileKeyCiphertext{}, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
return out, nil
|
var result ProfileKeyCiphertext
|
||||||
|
copy(result[:], C.GoBytes(unsafe.Pointer(&out), C.int(C.SignalPROFILE_KEY_CIPHERTEXT_LEN)))
|
||||||
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,17 +44,8 @@ func NewSealedSenderAddress(e164 string, uuid uuid.UUID, deviceID uint32) *Seale
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func SealedSenderEncryptPlaintext(
|
func SealedSenderEncryptPlaintext(ctx context.Context, message []byte, contentHint UnidentifiedSenderMessageContentHint, forAddress *Address, fromSenderCert *SenderCertificate, sessionStore SessionStore, identityStore IdentityKeyStore, groupID *GroupIdentifier) ([]byte, error) {
|
||||||
ctx context.Context,
|
ciphertextMessage, err := Encrypt(ctx, message, forAddress, sessionStore, identityStore)
|
||||||
message []byte,
|
|
||||||
contentHint UnidentifiedSenderMessageContentHint,
|
|
||||||
forAddress, localAddress *Address,
|
|
||||||
fromSenderCert *SenderCertificate,
|
|
||||||
sessionStore SessionStore,
|
|
||||||
identityStore IdentityKeyStore,
|
|
||||||
groupID *GroupIdentifier,
|
|
||||||
) ([]byte, error) {
|
|
||||||
ciphertextMessage, err := Encrypt(ctx, message, forAddress, localAddress, sessionStore, identityStore)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -169,19 +160,6 @@ const (
|
||||||
UnidentifiedSenderMessageContentHintImplicit UnidentifiedSenderMessageContentHint = 2
|
UnidentifiedSenderMessageContentHintImplicit UnidentifiedSenderMessageContentHint = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
func (hint UnidentifiedSenderMessageContentHint) String() string {
|
|
||||||
switch hint {
|
|
||||||
case UnidentifiedSenderMessageContentHintDefault:
|
|
||||||
return "Default"
|
|
||||||
case UnidentifiedSenderMessageContentHintResendable:
|
|
||||||
return "Resendable"
|
|
||||||
case UnidentifiedSenderMessageContentHintImplicit:
|
|
||||||
return "Implicit"
|
|
||||||
default:
|
|
||||||
return fmt.Sprintf("Unknown(%d)", hint)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type UnidentifiedSenderMessageContent struct {
|
type UnidentifiedSenderMessageContent struct {
|
||||||
nc noCopy
|
nc noCopy
|
||||||
ptr *C.SignalUnidentifiedSenderMessageContent
|
ptr *C.SignalUnidentifiedSenderMessageContent
|
||||||
|
|
|
||||||
|
|
@ -44,14 +44,10 @@ func wrapSenderCertificate(ptr *C.SignalSenderCertificate) *SenderCertificate {
|
||||||
// the Swift bindings).
|
// the Swift bindings).
|
||||||
func NewSenderCertificate(sender *SealedSenderAddress, publicKey *PublicKey, expiration time.Time, signerCertificate *ServerCertificate, signerKey *PrivateKey) (*SenderCertificate, error) {
|
func NewSenderCertificate(sender *SealedSenderAddress, publicKey *PublicKey, expiration time.Time, signerCertificate *ServerCertificate, signerKey *PrivateKey) (*SenderCertificate, error) {
|
||||||
var sc C.SignalMutPointerSenderCertificate
|
var sc C.SignalMutPointerSenderCertificate
|
||||||
senderUUIDStr, freeSenderUUIDStr := GoStringToCString(sender.UUID.String())
|
|
||||||
defer freeSenderUUIDStr()
|
|
||||||
senderE164Str, freeSenderE164Str := GoStringToCString(sender.E164)
|
|
||||||
defer freeSenderE164Str()
|
|
||||||
signalFfiError := C.signal_sender_certificate_new(
|
signalFfiError := C.signal_sender_certificate_new(
|
||||||
&sc,
|
&sc,
|
||||||
senderUUIDStr,
|
C.CString(sender.UUID.String()),
|
||||||
senderE164Str,
|
C.CString(sender.E164),
|
||||||
C.uint32_t(sender.DeviceID),
|
C.uint32_t(sender.DeviceID),
|
||||||
publicKey.constPtr(),
|
publicKey.constPtr(),
|
||||||
C.uint64_t(expiration.UnixMilli()),
|
C.uint64_t(expiration.UnixMilli()),
|
||||||
|
|
@ -139,7 +135,7 @@ func (sc *SenderCertificate) GetSignature() ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sc *SenderCertificate) GetSenderUUID() (uuid.UUID, error) {
|
func (sc *SenderCertificate) GetSenderUUID() (uuid.UUID, error) {
|
||||||
var rawUUID C.SignalCStringPtr
|
var rawUUID *C.char
|
||||||
signalFfiError := C.signal_sender_certificate_get_sender_uuid(&rawUUID, sc.constPtr())
|
signalFfiError := C.signal_sender_certificate_get_sender_uuid(&rawUUID, sc.constPtr())
|
||||||
runtime.KeepAlive(sc)
|
runtime.KeepAlive(sc)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
|
|
@ -149,7 +145,7 @@ func (sc *SenderCertificate) GetSenderUUID() (uuid.UUID, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sc *SenderCertificate) GetSenderE164() (string, error) {
|
func (sc *SenderCertificate) GetSenderE164() (string, error) {
|
||||||
var e164 C.SignalCStringPtr
|
var e164 *C.char
|
||||||
signalFfiError := C.signal_sender_certificate_get_sender_e164(&e164, sc.constPtr())
|
signalFfiError := C.signal_sender_certificate_get_sender_e164(&e164, sc.constPtr())
|
||||||
runtime.KeepAlive(sc)
|
runtime.KeepAlive(sc)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
|
|
@ -208,7 +204,6 @@ func (sc *SenderCertificate) Validate(trustRoots []*PublicKey, ts time.Time) (bo
|
||||||
C.uint64_t(ts.UnixMilli()),
|
C.uint64_t(ts.UnixMilli()),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(sc)
|
runtime.KeepAlive(sc)
|
||||||
runtime.KeepAlive(trustRoots)
|
|
||||||
runtime.KeepAlive(constRoots)
|
runtime.KeepAlive(constRoots)
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return false, wrapError(signalFfiError)
|
return false, wrapError(signalFfiError)
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,6 @@ func (sc *SenderKeyDistributionMessage) CancelFinalizer() {
|
||||||
func (sc *SenderKeyDistributionMessage) Serialize() ([]byte, error) {
|
func (sc *SenderKeyDistributionMessage) Serialize() ([]byte, error) {
|
||||||
var serialized C.SignalOwnedBuffer = C.SignalOwnedBuffer{}
|
var serialized C.SignalOwnedBuffer = C.SignalOwnedBuffer{}
|
||||||
signalFfiError := C.signal_sender_key_distribution_message_serialize(&serialized, sc.constPtr())
|
signalFfiError := C.signal_sender_key_distribution_message_serialize(&serialized, sc.constPtr())
|
||||||
runtime.KeepAlive(sc)
|
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return nil, wrapError(signalFfiError)
|
return nil, wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
|
|
@ -117,7 +116,6 @@ func (sc *SenderKeyDistributionMessage) Process(ctx context.Context, sender *Add
|
||||||
callbackCtx.wrapSenderKeyStore(store),
|
callbackCtx.wrapSenderKeyStore(store),
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(sender)
|
runtime.KeepAlive(sender)
|
||||||
runtime.KeepAlive(sc)
|
|
||||||
if signalFfiError != nil {
|
if signalFfiError != nil {
|
||||||
return callbackCtx.wrapError(signalFfiError)
|
return callbackCtx.wrapError(signalFfiError)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,8 @@ func signal_destroy_sender_key_store_callback(storeCtx unsafe.Pointer) {
|
||||||
func (ctx *CallbackContext) wrapSenderKeyStore(store SenderKeyStore) C.SignalConstPointerFfiSenderKeyStoreStruct {
|
func (ctx *CallbackContext) wrapSenderKeyStore(store SenderKeyStore) C.SignalConstPointerFfiSenderKeyStoreStruct {
|
||||||
return C.SignalConstPointerFfiSenderKeyStoreStruct{&C.SignalSenderKeyStore{
|
return C.SignalConstPointerFfiSenderKeyStoreStruct{&C.SignalSenderKeyStore{
|
||||||
ctx: wrapStore(ctx, store),
|
ctx: wrapStore(ctx, store),
|
||||||
load_sender_key: C.SignalFfiSenderKeyStoreLoadSenderKey(C.signal_load_sender_key_callback),
|
load_sender_key: C.SignalFfiBridgeSenderKeyStoreLoadSenderKey(C.signal_load_sender_key_callback),
|
||||||
store_sender_key: C.SignalFfiSenderKeyStoreStoreSenderKey(C.signal_store_sender_key_callback),
|
store_sender_key: C.SignalFfiBridgeSenderKeyStoreStoreSenderKey(C.signal_store_sender_key_callback),
|
||||||
destroy: C.SignalFfiSenderKeyStoreDestroy(C.signal_destroy_sender_key_store_callback),
|
destroy: C.SignalFfiBridgeSenderKeyStoreDestroy(C.signal_destroy_sender_key_store_callback),
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,16 +24,15 @@ import "C"
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServerPublicParams = C.SignalServerPublicParams
|
type ServerPublicParams = C.SignalServerPublicParams
|
||||||
type NotarySignature = fixedArray64
|
type NotarySignature [C.SignalSIGNATURE_LEN]byte
|
||||||
|
|
||||||
const ServerPublicParamsLength = 673
|
|
||||||
|
|
||||||
func DeserializeServerPublicParams(params []byte) (*ServerPublicParams, error) {
|
func DeserializeServerPublicParams(params []byte) (*ServerPublicParams, error) {
|
||||||
if len(params) != ServerPublicParamsLength {
|
if len(params) != C.SignalSERVER_PUBLIC_PARAMS_LEN {
|
||||||
return nil, fmt.Errorf("invalid server public params length: %d (expected %d)", len(params), ServerPublicParamsLength)
|
return nil, fmt.Errorf("invalid server public params length: %d (expected %d)", len(params), int(C.SignalSERVER_PUBLIC_PARAMS_LEN))
|
||||||
}
|
}
|
||||||
var out C.SignalMutPointerServerPublicParams
|
var out C.SignalMutPointerServerPublicParams
|
||||||
signalFfiError := C.signal_server_public_params_deserialize(&out, BytesToBuffer(params[:]))
|
signalFfiError := C.signal_server_public_params_deserialize(&out, BytesToBuffer(params[:]))
|
||||||
|
|
@ -48,10 +47,11 @@ func ServerPublicParamsVerifySignature(
|
||||||
messageBytes []byte,
|
messageBytes []byte,
|
||||||
NotarySignature NotarySignature,
|
NotarySignature NotarySignature,
|
||||||
) error {
|
) error {
|
||||||
|
c_notarySignature := (*[C.SignalSIGNATURE_LEN]C.uint8_t)(unsafe.Pointer(&NotarySignature[0]))
|
||||||
signalFfiError := C.signal_server_public_params_verify_signature(
|
signalFfiError := C.signal_server_public_params_verify_signature(
|
||||||
C.SignalConstPointerServerPublicParams{serverPublicParams},
|
C.SignalConstPointerServerPublicParams{serverPublicParams},
|
||||||
BytesToBuffer(messageBytes),
|
BytesToBuffer(messageBytes),
|
||||||
NotarySignature.cConstFixedArray(),
|
c_notarySignature,
|
||||||
)
|
)
|
||||||
runtime.KeepAlive(messageBytes)
|
runtime.KeepAlive(messageBytes)
|
||||||
return wrapError(signalFfiError)
|
return wrapError(signalFfiError)
|
||||||
|
|
|
||||||
|
|
@ -133,10 +133,7 @@ func (s ServiceID) MarshalZerologObject(e *zerolog.Event) {
|
||||||
e.Stringer("uuid", s.UUID)
|
e.Stringer("uuid", s.UUID)
|
||||||
}
|
}
|
||||||
|
|
||||||
const ServiceIDUUIDLength = 16
|
type ServiceIDFixedBytes [17]byte
|
||||||
const ServiceIDFixedBytesLength = 17
|
|
||||||
|
|
||||||
type ServiceIDFixedBytes = fixedArray17
|
|
||||||
|
|
||||||
func (s ServiceID) FixedBytes() *ServiceIDFixedBytes {
|
func (s ServiceID) FixedBytes() *ServiceIDFixedBytes {
|
||||||
var result ServiceIDFixedBytes
|
var result ServiceIDFixedBytes
|
||||||
|
|
@ -165,18 +162,18 @@ func ServiceIDFromString(val string) (ServiceID, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ServiceIDFromBytes(bytes []byte) (ServiceID, error) {
|
func ServiceIDFromBytes(bytes []byte) (ServiceID, error) {
|
||||||
if len(bytes) == ServiceIDUUIDLength {
|
if len(bytes) == 16 {
|
||||||
return NewACIServiceID(uuid.UUID(bytes)), nil
|
return NewACIServiceID(uuid.UUID(bytes)), nil
|
||||||
} else if len(bytes) == ServiceIDFixedBytesLength {
|
} else if len(bytes) == 17 {
|
||||||
return ServiceID{
|
return ServiceID{
|
||||||
Type: ServiceIDType(bytes[0]),
|
Type: ServiceIDType(bytes[0]),
|
||||||
UUID: uuid.UUID(bytes[1:]),
|
UUID: uuid.UUID(bytes[1:]),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
return EmptyServiceID, fmt.Errorf("invalid ServiceID byte length: %d (expected %d or %d)", len(bytes), ServiceIDUUIDLength, ServiceIDFixedBytesLength)
|
return EmptyServiceID, fmt.Errorf("invalid ServiceID byte length: %d (expected 16 or 17)", len(bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ServiceIDFromCFixedBytes(serviceID *C.SignalType_FixedArray17_uint8_t) ServiceID {
|
func ServiceIDFromCFixedBytes(serviceID *C.SignalServiceIdFixedWidthBinaryBytes) ServiceID {
|
||||||
var id ServiceID
|
var id ServiceID
|
||||||
fixedBytes := (*ServiceIDFixedBytes)(unsafe.Pointer(serviceID))
|
fixedBytes := (*ServiceIDFixedBytes)(unsafe.Pointer(serviceID))
|
||||||
id.Type = ServiceIDType(fixedBytes[0])
|
id.Type = ServiceIDType(fixedBytes[0])
|
||||||
|
|
@ -184,10 +181,6 @@ func ServiceIDFromCFixedBytes(serviceID *C.SignalType_FixedArray17_uint8_t) Serv
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s ServiceID) cFixedArray() *C.SignalType_FixedArray17_uint8_t {
|
func (s ServiceID) CFixedBytes() cPNIType {
|
||||||
return s.FixedBytes().cFixedArray()
|
return cPNIType(unsafe.Pointer(s.FixedBytes()))
|
||||||
}
|
|
||||||
|
|
||||||
func (s ServiceID) cConstFixedArray() cFixedArray17Compat {
|
|
||||||
return cFixedArray17Compat(s.cFixedArray())
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
11
pkg/libsignalgo/serviceid_clang.go
Normal file
11
pkg/libsignalgo/serviceid_clang.go
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
//go:build darwin || android || ios || (windows && arm64)
|
||||||
|
|
||||||
|
package libsignalgo
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include "./libsignal-ffi.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
type cPNIType = *C.SignalServiceIdFixedWidthBinaryBytes
|
||||||
14
pkg/libsignalgo/serviceid_gcc.go
Normal file
14
pkg/libsignalgo/serviceid_gcc.go
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
//go:build !(darwin || android || ios || (windows && arm64))
|
||||||
|
|
||||||
|
package libsignalgo
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include "./libsignal-ffi.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
// Hack for https://github.com/golang/go/issues/7270
|
||||||
|
// The clang version is more correct, but doesn't work with gcc
|
||||||
|
|
||||||
|
type cPNIType = *[17]C.uint8_t
|
||||||
|
|
@ -30,7 +30,7 @@ import (
|
||||||
"go.mau.fi/mautrix-signal/pkg/libsignalgo"
|
"go.mau.fi/mautrix-signal/pkg/libsignalgo"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initializeSessions(t *testing.T, aliceStore, bobStore *InMemorySignalProtocolStore, bobAddress, aliceAddress *libsignalgo.Address) {
|
func initializeSessions(t *testing.T, aliceStore, bobStore *InMemorySignalProtocolStore, bobAddress *libsignalgo.Address) {
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
|
|
||||||
bobPreKey, err := libsignalgo.GeneratePrivateKey()
|
bobPreKey, err := libsignalgo.GeneratePrivateKey()
|
||||||
|
|
@ -86,7 +86,7 @@ func initializeSessions(t *testing.T, aliceStore, bobStore *InMemorySignalProtoc
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Alice processes the bundle
|
// Alice processes the bundle
|
||||||
err = libsignalgo.ProcessPreKeyBundle(ctx, bobBundle, bobAddress, aliceAddress, aliceStore, aliceStore)
|
err = libsignalgo.ProcessPreKeyBundle(ctx, bobBundle, bobAddress, aliceStore, aliceStore)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
record, err := aliceStore.LoadSession(ctx, bobAddress)
|
record, err := aliceStore.LoadSession(ctx, bobAddress)
|
||||||
|
|
@ -132,11 +132,11 @@ func TestSessionCipher(t *testing.T) {
|
||||||
aliceStore := NewInMemorySignalProtocolStore()
|
aliceStore := NewInMemorySignalProtocolStore()
|
||||||
bobStore := NewInMemorySignalProtocolStore()
|
bobStore := NewInMemorySignalProtocolStore()
|
||||||
|
|
||||||
initializeSessions(t, aliceStore, bobStore, bobAddress, aliceAddress)
|
initializeSessions(t, aliceStore, bobStore, bobAddress)
|
||||||
|
|
||||||
alicePlaintext := []byte{8, 6, 7, 5, 3, 0, 9}
|
alicePlaintext := []byte{8, 6, 7, 5, 3, 0, 9}
|
||||||
|
|
||||||
aliceCiphertext, err := libsignalgo.Encrypt(ctx, alicePlaintext, bobAddress, aliceAddress, aliceStore, aliceStore)
|
aliceCiphertext, err := libsignalgo.Encrypt(ctx, alicePlaintext, bobAddress, aliceStore, aliceStore)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
aliceCiphertextMessageType, err := aliceCiphertext.MessageType()
|
aliceCiphertextMessageType, err := aliceCiphertext.MessageType()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
@ -147,13 +147,13 @@ func TestSessionCipher(t *testing.T) {
|
||||||
bobCiphertext, err := libsignalgo.DeserializePreKeyMessage(aliceCiphertextSerialized)
|
bobCiphertext, err := libsignalgo.DeserializePreKeyMessage(aliceCiphertextSerialized)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
bobPlaintext, err := libsignalgo.DecryptPreKey(ctx, bobCiphertext, aliceAddress, bobAddress, bobStore, bobStore, bobStore, bobStore, bobStore)
|
bobPlaintext, err := libsignalgo.DecryptPreKey(ctx, bobCiphertext, aliceAddress, bobStore, bobStore, bobStore, bobStore, bobStore)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, alicePlaintext, bobPlaintext)
|
assert.Equal(t, alicePlaintext, bobPlaintext)
|
||||||
|
|
||||||
bobPlaintext2 := []byte{23}
|
bobPlaintext2 := []byte{23}
|
||||||
|
|
||||||
bobCiphertext2, err := libsignalgo.Encrypt(ctx, bobPlaintext2, aliceAddress, bobAddress, bobStore, bobStore)
|
bobCiphertext2, err := libsignalgo.Encrypt(ctx, bobPlaintext2, aliceAddress, bobStore, bobStore)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
bobCiphertext2MessageType, err := bobCiphertext2.MessageType()
|
bobCiphertext2MessageType, err := bobCiphertext2.MessageType()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
@ -163,7 +163,7 @@ func TestSessionCipher(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
aliceCiphertext2, err := libsignalgo.DeserializeMessage(bobCiphertext2Serialized)
|
aliceCiphertext2, err := libsignalgo.DeserializeMessage(bobCiphertext2Serialized)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
alicePlaintext2, err := libsignalgo.Decrypt(ctx, aliceCiphertext2, bobAddress, aliceAddress, aliceStore, aliceStore)
|
alicePlaintext2, err := libsignalgo.Decrypt(ctx, aliceCiphertext2, bobAddress, aliceStore, aliceStore)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, bobPlaintext2, alicePlaintext2)
|
assert.Equal(t, bobPlaintext2, alicePlaintext2)
|
||||||
}
|
}
|
||||||
|
|
@ -183,11 +183,11 @@ func TestSessionCipherWithBadStore(t *testing.T) {
|
||||||
aliceStore := NewInMemorySignalProtocolStore()
|
aliceStore := NewInMemorySignalProtocolStore()
|
||||||
bobStore := &BadInMemorySignalProtocolStore{NewInMemorySignalProtocolStore()}
|
bobStore := &BadInMemorySignalProtocolStore{NewInMemorySignalProtocolStore()}
|
||||||
|
|
||||||
initializeSessions(t, aliceStore, bobStore.InMemorySignalProtocolStore, bobAddress, aliceAddress)
|
initializeSessions(t, aliceStore, bobStore.InMemorySignalProtocolStore, bobAddress)
|
||||||
|
|
||||||
alicePlaintext := []byte{8, 6, 7, 5, 3, 0, 9}
|
alicePlaintext := []byte{8, 6, 7, 5, 3, 0, 9}
|
||||||
|
|
||||||
aliceCiphertext, err := libsignalgo.Encrypt(ctx, alicePlaintext, bobAddress, aliceAddress, aliceStore, aliceStore)
|
aliceCiphertext, err := libsignalgo.Encrypt(ctx, alicePlaintext, bobAddress, aliceStore, aliceStore)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
aliceCiphertextMessageType, err := aliceCiphertext.MessageType()
|
aliceCiphertextMessageType, err := aliceCiphertext.MessageType()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
@ -198,7 +198,7 @@ func TestSessionCipherWithBadStore(t *testing.T) {
|
||||||
bobCiphertext, err := libsignalgo.DeserializePreKeyMessage(aliceCiphertextSerialized)
|
bobCiphertext, err := libsignalgo.DeserializePreKeyMessage(aliceCiphertextSerialized)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
t.Skip("This test is broken") // TODO fix
|
t.Skip("This test is broken") // TODO fix
|
||||||
_, err = libsignalgo.DecryptPreKey(ctx, bobCiphertext, aliceAddress, bobAddress, bobStore, bobStore, bobStore, bobStore, bobStore)
|
_, err = libsignalgo.DecryptPreKey(ctx, bobCiphertext, aliceAddress, bobStore, bobStore, bobStore, bobStore, bobStore)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
assert.Equal(t, "Test error", err.Error())
|
assert.Equal(t, "Test error", err.Error())
|
||||||
}
|
}
|
||||||
|
|
@ -216,7 +216,7 @@ func TestSealedSenderEncrypt_Repeated(t *testing.T) {
|
||||||
aliceStore := NewInMemorySignalProtocolStore()
|
aliceStore := NewInMemorySignalProtocolStore()
|
||||||
bobStore := NewInMemorySignalProtocolStore()
|
bobStore := NewInMemorySignalProtocolStore()
|
||||||
|
|
||||||
initializeSessions(t, aliceStore, bobStore, bobAddress, aliceAddress)
|
initializeSessions(t, aliceStore, bobStore, bobAddress)
|
||||||
|
|
||||||
trustRoot, err := libsignalgo.GenerateIdentityKeyPair()
|
trustRoot, err := libsignalgo.GenerateIdentityKeyPair()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
@ -241,7 +241,7 @@ func TestSealedSenderEncrypt_Repeated(t *testing.T) {
|
||||||
}()
|
}()
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
message := []byte(fmt.Sprintf("%04d vision", i))
|
message := []byte(fmt.Sprintf("%04d vision", i))
|
||||||
ciphertext, err := libsignalgo.SealedSenderEncryptPlaintext(ctx, message, libsignalgo.UnidentifiedSenderMessageContentHintDefault, bobAddress, aliceAddress, senderCert, aliceStore, aliceStore, nil)
|
ciphertext, err := libsignalgo.SealedSenderEncryptPlaintext(ctx, message, libsignalgo.UnidentifiedSenderMessageContentHintDefault, bobAddress, senderCert, aliceStore, aliceStore, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.NotNil(t, ciphertext)
|
assert.NotNil(t, ciphertext)
|
||||||
}
|
}
|
||||||
|
|
@ -252,18 +252,15 @@ func TestArchiveSession(t *testing.T) {
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
setupLogging()
|
setupLogging()
|
||||||
|
|
||||||
aliceACI := uuid.New()
|
|
||||||
bobACI := uuid.New()
|
bobACI := uuid.New()
|
||||||
|
|
||||||
aliceAddress, err := libsignalgo.NewACIServiceID(aliceACI).Address(1)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
bobAddress, err := libsignalgo.NewACIServiceID(bobACI).Address(1)
|
bobAddress, err := libsignalgo.NewACIServiceID(bobACI).Address(1)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
aliceStore := NewInMemorySignalProtocolStore()
|
aliceStore := NewInMemorySignalProtocolStore()
|
||||||
bobStore := NewInMemorySignalProtocolStore()
|
bobStore := NewInMemorySignalProtocolStore()
|
||||||
|
|
||||||
initializeSessions(t, aliceStore, bobStore, bobAddress, aliceAddress)
|
initializeSessions(t, aliceStore, bobStore, bobAddress)
|
||||||
|
|
||||||
session, err := aliceStore.LoadSession(ctx, bobAddress)
|
session, err := aliceStore.LoadSession(ctx, bobAddress)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
@ -318,7 +315,7 @@ func TestSealedSenderGroupCipher(t *testing.T) {
|
||||||
|
|
||||||
bobStore := NewInMemorySignalProtocolStore()
|
bobStore := NewInMemorySignalProtocolStore()
|
||||||
|
|
||||||
initializeSessions(t, aliceStore, bobStore, bobAddress, aliceAddress)
|
initializeSessions(t, aliceStore, bobStore, bobAddress)
|
||||||
|
|
||||||
trustRoot, err := libsignalgo.GenerateIdentityKeyPair()
|
trustRoot, err := libsignalgo.GenerateIdentityKeyPair()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
|
||||||
|
|
@ -67,8 +67,8 @@ func signal_destroy_session_store_callback(storeCtx unsafe.Pointer) {
|
||||||
func (ctx *CallbackContext) wrapSessionStore(store SessionStore) C.SignalConstPointerFfiSessionStoreStruct {
|
func (ctx *CallbackContext) wrapSessionStore(store SessionStore) C.SignalConstPointerFfiSessionStoreStruct {
|
||||||
return C.SignalConstPointerFfiSessionStoreStruct{&C.SignalSessionStore{
|
return C.SignalConstPointerFfiSessionStoreStruct{&C.SignalSessionStore{
|
||||||
ctx: wrapStore(ctx, store),
|
ctx: wrapStore(ctx, store),
|
||||||
load_session: C.SignalFfiSessionStoreLoadSession(C.signal_load_session_callback),
|
load_session: C.SignalFfiBridgeSessionStoreLoadSession(C.signal_load_session_callback),
|
||||||
store_session: C.SignalFfiSessionStoreStoreSession(C.signal_store_session_callback),
|
store_session: C.SignalFfiBridgeSessionStoreStoreSession(C.signal_store_session_callback),
|
||||||
destroy: C.SignalFfiSessionStoreDestroy(C.signal_destroy_session_store_callback),
|
destroy: C.SignalFfiBridgeSessionStoreDestroy(C.signal_destroy_session_store_callback),
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,8 +54,6 @@ func (FFILogger) Log(level libsignalgo.LogLevel, file string, line uint, message
|
||||||
|
|
||||||
func (FFILogger) Flush() {}
|
func (FFILogger) Flush() {}
|
||||||
|
|
||||||
func (FFILogger) Destroy() {}
|
|
||||||
|
|
||||||
var loggingSetup = false
|
var loggingSetup = false
|
||||||
|
|
||||||
func setupLogging() {
|
func setupLogging() {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
// Generated by update-ffi.sh; DO NOT EDIT.
|
|
||||||
|
|
||||||
package signalversion
|
|
||||||
|
|
||||||
const Version = "v0.102.2"
|
|
||||||
|
|
@ -67,8 +67,8 @@ func signal_destroy_signed_pre_key_store_callback(storeCtx unsafe.Pointer) {
|
||||||
func (ctx *CallbackContext) wrapSignedPreKeyStore(store SignedPreKeyStore) C.SignalConstPointerFfiSignedPreKeyStoreStruct {
|
func (ctx *CallbackContext) wrapSignedPreKeyStore(store SignedPreKeyStore) C.SignalConstPointerFfiSignedPreKeyStoreStruct {
|
||||||
return C.SignalConstPointerFfiSignedPreKeyStoreStruct{&C.SignalSignedPreKeyStore{
|
return C.SignalConstPointerFfiSignedPreKeyStoreStruct{&C.SignalSignedPreKeyStore{
|
||||||
ctx: wrapStore(ctx, store),
|
ctx: wrapStore(ctx, store),
|
||||||
load_signed_pre_key: C.SignalFfiSignedPreKeyStoreLoadSignedPreKey(C.signal_load_signed_pre_key_callback),
|
load_signed_pre_key: C.SignalFfiBridgeSignedPreKeyStoreLoadSignedPreKey(C.signal_load_signed_pre_key_callback),
|
||||||
store_signed_pre_key: C.SignalFfiSignedPreKeyStoreStoreSignedPreKey(C.signal_store_signed_pre_key_callback),
|
store_signed_pre_key: C.SignalFfiBridgeSignedPreKeyStoreStoreSignedPreKey(C.signal_store_signed_pre_key_callback),
|
||||||
destroy: C.SignalFfiSignedPreKeyStoreDestroy(C.signal_destroy_signed_pre_key_store_callback),
|
destroy: C.SignalFfiBridgeSignedPreKeyStoreDestroy(C.signal_destroy_signed_pre_key_store_callback),
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
cd /data
|
cd /data
|
||||||
export RUSTFLAGS="-Ctarget-feature=-crt-static" RUSTC_WRAPPER=""
|
export RUSTFLAGS="-Ctarget-feature=-crt-static" RUSTC_WRAPPER=""
|
||||||
apk add --no-cache git make cmake protobuf-dev musl-dev g++ clang-dev
|
apk add --no-cache git make cmake protobuf-dev musl-dev g++ clang-dev cbindgen
|
||||||
cd libsignal
|
cd libsignal
|
||||||
cargo build -p libsignal-ffi --release
|
cargo build -p libsignal-ffi --release
|
||||||
|
cbindgen --profile release rust/bridge/ffi -o libsignal-ffi.h
|
||||||
cd ..
|
cd ..
|
||||||
mv libsignal/target/release/libsignal_ffi.a .
|
mv libsignal/target/release/libsignal_ffi.a .
|
||||||
cp libsignal/swift/Sources/SignalFfi/signal_ffi.h libsignal-ffi.h
|
mv libsignal/libsignal-ffi.h .
|
||||||
chown 1000:1000 libsignal_ffi.a libsignal-ffi.h
|
chown 1000:1000 libsignal_ffi.a libsignal-ffi.h version.go
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
docker run --rm -itv $(pwd):/data rust:1-alpine /data/update-ffi-docker-inner.sh
|
docker run --rm -itv $(pwd):/data rust:1-alpine /data/update-ffi-docker-inner.sh
|
||||||
|
|
||||||
echo "// Generated by update-ffi.sh; DO NOT EDIT." > signalversion/version.go
|
echo "// Generated by update-ffi.sh; DO NOT EDIT." > version.go
|
||||||
echo >> signalversion/version.go
|
echo >> version.go
|
||||||
echo "package signalversion" >> signalversion/version.go
|
echo "package libsignalgo" >> version.go
|
||||||
echo >> signalversion/version.go
|
echo >> version.go
|
||||||
cd libsignal
|
cd libsignal
|
||||||
echo "const Version = \"$(git describe --tags --always)\"" >> ../signalversion/version.go
|
echo "const Version = \"$(git describe --tags --always)\"" >> ../version.go
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@ if [ ! -d "$LIBSIGNAL_DIRECTORY" ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "// Generated by update-ffi.sh; DO NOT EDIT." > signalversion/version.go
|
echo "// Generated by update-ffi.sh; DO NOT EDIT." > version.go
|
||||||
echo >> signalversion/version.go
|
echo >> version.go
|
||||||
echo "package signalversion" >> signalversion/version.go
|
echo "package libsignalgo" >> version.go
|
||||||
echo >> signalversion/version.go
|
echo >> version.go
|
||||||
|
|
||||||
# Store the current working directory
|
# Store the current working directory
|
||||||
ORIGINAL_DIR="$(pwd)"
|
ORIGINAL_DIR="$(pwd)"
|
||||||
|
|
@ -23,16 +23,19 @@ ORIGINAL_DIR="$(pwd)"
|
||||||
# Navigate to libsignal directory
|
# Navigate to libsignal directory
|
||||||
cd "$LIBSIGNAL_DIRECTORY"
|
cd "$LIBSIGNAL_DIRECTORY"
|
||||||
|
|
||||||
echo "const Version = \"$(git describe --tags --always)\"" >> ../signalversion/version.go
|
echo "const Version = \"$(git describe --tags --always)\"" >> ../version.go
|
||||||
|
|
||||||
# Build libsignal
|
# Build libsignal
|
||||||
cargo build -p libsignal-ffi --release
|
cargo build -p libsignal-ffi --release
|
||||||
|
|
||||||
|
# Regenerate the header file
|
||||||
|
cbindgen --profile release rust/bridge/ffi -o libsignal-ffi.h
|
||||||
|
|
||||||
# Navigate back to the original directory
|
# Navigate back to the original directory
|
||||||
cd "$ORIGINAL_DIR"
|
cd "$ORIGINAL_DIR"
|
||||||
|
|
||||||
# Copy files from the libsignal directory
|
# Copy files from the libsignal directory
|
||||||
cp "${LIBSIGNAL_DIRECTORY}/target/release/libsignal_ffi.a" .
|
cp "${LIBSIGNAL_DIRECTORY}/target/release/libsignal_ffi.a" .
|
||||||
cp "${LIBSIGNAL_DIRECTORY}/swift/Sources/SignalFfi/signal_ffi.h" libsignal-ffi.h
|
cp "${LIBSIGNAL_DIRECTORY}/libsignal-ffi.h" .
|
||||||
|
|
||||||
echo "Files copied successfully."
|
echo "Files copied successfully."
|
||||||
|
|
|
||||||
5
pkg/libsignalgo/version.go
Normal file
5
pkg/libsignalgo/version.go
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
// Generated by update-ffi.sh; DO NOT EDIT.
|
||||||
|
|
||||||
|
package libsignalgo
|
||||||
|
|
||||||
|
const Version = "v0.87.5"
|
||||||
|
|
@ -35,7 +35,7 @@ import (
|
||||||
"go.mau.fi/mautrix-signal/pkg/msgconv/matrixfmt"
|
"go.mau.fi/mautrix-signal/pkg/msgconv/matrixfmt"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalid"
|
"go.mau.fi/mautrix-signal/pkg/signalid"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow"
|
"go.mau.fi/mautrix-signal/pkg/signalmeow"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/signalpb"
|
signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (mc *MessageConverter) ToSignal(
|
func (mc *MessageConverter) ToSignal(
|
||||||
|
|
@ -110,24 +110,21 @@ func (mc *MessageConverter) ToSignal(
|
||||||
return nil, fmt.Errorf("failed to convert sticker: %w", err)
|
return nil, fmt.Errorf("failed to convert sticker: %w", err)
|
||||||
}
|
}
|
||||||
att.Flags = proto.Uint32(uint32(signalpb.AttachmentPointer_BORDERLESS))
|
att.Flags = proto.Uint32(uint32(signalpb.AttachmentPointer_BORDERLESS))
|
||||||
|
var emoji *string
|
||||||
dm.Sticker = ParseStickerMeta(content.Info.BridgedSticker)
|
// TODO check for single grapheme cluster?
|
||||||
if dm.Sticker == nil {
|
if len([]rune(content.Body)) == 1 {
|
||||||
var emoji *string
|
emoji = proto.String(variationselector.Remove(content.Body))
|
||||||
// TODO check for single grapheme cluster?
|
}
|
||||||
if len([]rune(content.Body)) == 1 {
|
dm.Sticker = &signalpb.DataMessage_Sticker{
|
||||||
emoji = proto.String(variationselector.Remove(content.Body))
|
// Signal iOS validates that pack id/key are of the correct length.
|
||||||
}
|
// Android is fine with any non-nil values (like a zero-length byte string).
|
||||||
dm.Sticker = &signalpb.DataMessage_Sticker{
|
PackId: make([]byte, 16),
|
||||||
// Signal iOS validates that pack id/key are of the correct length.
|
PackKey: make([]byte, 32),
|
||||||
// Android is fine with any non-nil values (like a zero-length byte string).
|
StickerId: proto.Uint32(0),
|
||||||
PackId: make([]byte, 16),
|
|
||||||
PackKey: make([]byte, 32),
|
Data: att,
|
||||||
StickerId: proto.Uint32(0),
|
Emoji: emoji,
|
||||||
Emoji: emoji,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
dm.Sticker.Data = att
|
|
||||||
case event.MsgLocation:
|
case event.MsgLocation:
|
||||||
lat, lon, err := parseGeoURI(content.GeoURI)
|
lat, lon, err := parseGeoURI(content.GeoURI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ import (
|
||||||
"go.mau.fi/util/exslices"
|
"go.mau.fi/util/exslices"
|
||||||
"go.mau.fi/util/ptr"
|
"go.mau.fi/util/ptr"
|
||||||
|
|
||||||
|
signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/backuppb"
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/backuppb"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/signalpb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func boolToInt(b bool) int {
|
func boolToInt(b bool) int {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"mime"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
@ -43,7 +42,7 @@ import (
|
||||||
"go.mau.fi/mautrix-signal/pkg/msgconv/signalfmt"
|
"go.mau.fi/mautrix-signal/pkg/msgconv/signalfmt"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalid"
|
"go.mau.fi/mautrix-signal/pkg/signalid"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow"
|
"go.mau.fi/mautrix-signal/pkg/signalmeow"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/signalpb"
|
signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -115,7 +114,7 @@ func (mc *MessageConverter) ToMatrix(
|
||||||
return cm
|
return cm
|
||||||
}
|
}
|
||||||
if dm.PollVote != nil {
|
if dm.PollVote != nil {
|
||||||
cm.Parts = append(cm.Parts, mc.convertPollVoteToMatrix(ctx, sender, dm.PollVote))
|
cm.Parts = append(cm.Parts, mc.convertPollVoteToMatrix(ctx, dm.PollVote))
|
||||||
return cm
|
return cm
|
||||||
}
|
}
|
||||||
if dm.PollCreate != nil {
|
if dm.PollCreate != nil {
|
||||||
|
|
@ -469,16 +468,20 @@ func (mc *MessageConverter) convertStickerToMatrix(ctx context.Context, sticker
|
||||||
converted.Content.Info.Height = 200
|
converted.Content.Info.Height = 200
|
||||||
}
|
}
|
||||||
converted.Content.Body = sticker.GetEmoji()
|
converted.Content.Body = sticker.GetEmoji()
|
||||||
if len(sticker.GetPackId()) == PackIDLength && len(sticker.GetPackKey()) == PackKeyLength && !bytes.Equal(sticker.GetPackId(), zeroPackID) {
|
|
||||||
converted.Content.Info.BridgedSticker = &event.BridgedSticker{
|
|
||||||
Network: StickerSourceID,
|
|
||||||
ID: strconv.FormatUint(uint64(sticker.GetStickerId()), 10),
|
|
||||||
Emoji: sticker.GetEmoji(),
|
|
||||||
PackURL: fmt.Sprintf(PackURLFormat, sticker.GetPackId(), sticker.GetPackKey()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
converted.Type = event.EventSticker
|
converted.Type = event.EventSticker
|
||||||
converted.Content.MsgType = ""
|
converted.Content.MsgType = ""
|
||||||
|
if converted.Extra == nil {
|
||||||
|
converted.Extra = map[string]any{}
|
||||||
|
}
|
||||||
|
// TODO fetch full pack metadata like the old bridge did?
|
||||||
|
converted.Extra["fi.mau.signal.sticker"] = map[string]any{
|
||||||
|
"id": sticker.GetStickerId(),
|
||||||
|
"emoji": sticker.GetEmoji(),
|
||||||
|
"pack": map[string]any{
|
||||||
|
"id": sticker.GetPackId(),
|
||||||
|
"key": sticker.GetPackKey(),
|
||||||
|
},
|
||||||
|
}
|
||||||
return converted
|
return converted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -570,20 +573,15 @@ func (mc *MessageConverter) reuploadAttachment(ctx context.Context, att *signalp
|
||||||
content.Info.Blurhash = att.GetBlurHash()
|
content.Info.Blurhash = att.GetBlurHash()
|
||||||
content.Info.AnoaBlurhash = att.GetBlurHash()
|
content.Info.AnoaBlurhash = att.GetBlurHash()
|
||||||
}
|
}
|
||||||
plainMime, _, _ := mime.ParseMediaType(content.Info.MimeType)
|
switch strings.Split(content.Info.MimeType, "/")[0] {
|
||||||
// Supported mime types from https://github.com/signalapp/Signal-Desktop/blob/main/ts/util/GoogleChrome.std.ts
|
case "image":
|
||||||
switch plainMime {
|
|
||||||
case "image/avif", "image/bmp", "image/gif", "image/jpeg", "image/webp", "image/x-xbitmap",
|
|
||||||
"image/vnd.microsoft.icon", "image/ico", "image/icon", "image/x-icon", "image/png", "image/apng":
|
|
||||||
content.MsgType = event.MsgImage
|
content.MsgType = event.MsgImage
|
||||||
case "video/mp4", "video/ogg", "video/webm":
|
case "video":
|
||||||
content.MsgType = event.MsgVideo
|
content.MsgType = event.MsgVideo
|
||||||
|
case "audio":
|
||||||
|
content.MsgType = event.MsgAudio
|
||||||
default:
|
default:
|
||||||
if strings.HasPrefix(plainMime, "audio/") && !strings.HasSuffix(plainMime, "aiff") {
|
content.MsgType = event.MsgFile
|
||||||
content.MsgType = event.MsgAudio
|
|
||||||
} else {
|
|
||||||
content.MsgType = event.MsgFile
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
var extra map[string]any
|
var extra map[string]any
|
||||||
if att.GetFlags()&uint32(signalpb.AttachmentPointer_GIF) != 0 {
|
if att.GetFlags()&uint32(signalpb.AttachmentPointer_GIF) != 0 {
|
||||||
|
|
@ -749,7 +747,7 @@ var invalidPollVote = &bridgev2.ConvertedMessagePart{
|
||||||
DontBridge: true,
|
DontBridge: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *MessageConverter) convertPollVoteToMatrix(ctx context.Context, senderACI uuid.UUID, vote *signalpb.DataMessage_PollVote) *bridgev2.ConvertedMessagePart {
|
func (mc *MessageConverter) convertPollVoteToMatrix(ctx context.Context, vote *signalpb.DataMessage_PollVote) *bridgev2.ConvertedMessagePart {
|
||||||
if len(vote.GetTargetAuthorAciBinary()) != 16 {
|
if len(vote.GetTargetAuthorAciBinary()) != 16 {
|
||||||
zerolog.Ctx(ctx).Debug().
|
zerolog.Ctx(ctx).Debug().
|
||||||
Str("author_aci_b64", base64.StdEncoding.EncodeToString(vote.GetTargetAuthorAciBinary())).
|
Str("author_aci_b64", base64.StdEncoding.EncodeToString(vote.GetTargetAuthorAciBinary())).
|
||||||
|
|
@ -765,24 +763,7 @@ func (mc *MessageConverter) convertPollVoteToMatrix(ctx context.Context, senderA
|
||||||
zerolog.Ctx(ctx).Warn().Msg("Poll vote target message not found")
|
zerolog.Ctx(ctx).Warn().Msg("Poll vote target message not found")
|
||||||
return invalidPollVote
|
return invalidPollVote
|
||||||
}
|
}
|
||||||
meta := pollMessage.Metadata.(*signalid.MessageMetadata)
|
mxOptionIDs := pollMessage.Metadata.(*signalid.MessageMetadata).MatrixPollOptionIDs
|
||||||
if prevCount, ok := meta.VoteCount[senderACI.String()]; ok && vote.GetVoteCount() <= prevCount {
|
|
||||||
zerolog.Ctx(ctx).Debug().
|
|
||||||
Stringer("sender_aci", senderACI).
|
|
||||||
Uint32("vote_count", vote.GetVoteCount()).
|
|
||||||
Uint32("previous_vote_count", prevCount).
|
|
||||||
Msg("Ignoring poll vote with lower vote count")
|
|
||||||
return invalidPollVote
|
|
||||||
}
|
|
||||||
if meta.VoteCount == nil {
|
|
||||||
meta.VoteCount = make(map[string]uint32)
|
|
||||||
}
|
|
||||||
meta.VoteCount[senderACI.String()] = vote.GetVoteCount()
|
|
||||||
err = mc.Bridge.DB.Message.Update(ctx, pollMessage)
|
|
||||||
if err != nil {
|
|
||||||
zerolog.Ctx(ctx).Warn().Err(err).Msg("Failed to update poll message with new vote count")
|
|
||||||
}
|
|
||||||
mxOptionIDs := meta.MatrixPollOptionIDs
|
|
||||||
optionIDs := make([]string, len(vote.GetOptionIndexes()))
|
optionIDs := make([]string, len(vote.GetOptionIndexes()))
|
||||||
for i, optionIndex := range vote.GetOptionIndexes() {
|
for i, optionIndex := range vote.GetOptionIndexes() {
|
||||||
if int(optionIndex) < len(mxOptionIDs) {
|
if int(optionIndex) < len(mxOptionIDs) {
|
||||||
|
|
|
||||||
|
|
@ -1,199 +0,0 @@
|
||||||
// mautrix-signal - A Matrix-Signal puppeting bridge.
|
|
||||||
// Copyright (C) 2026 Tulir Asokan
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Affero General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Affero General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package msgconv
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"go.mau.fi/util/emojishortcodes"
|
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
"maunium.net/go/mautrix"
|
|
||||||
"maunium.net/go/mautrix/bridgev2"
|
|
||||||
"maunium.net/go/mautrix/bridgev2/database"
|
|
||||||
"maunium.net/go/mautrix/event"
|
|
||||||
"maunium.net/go/mautrix/id"
|
|
||||||
|
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalid"
|
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow"
|
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/signalpb"
|
|
||||||
)
|
|
||||||
|
|
||||||
const StickerSourceID = "signal"
|
|
||||||
const PackURLFormat = "https://signal.art/addstickers/#pack_id=%x&pack_key=%x"
|
|
||||||
|
|
||||||
const PackIDLength = 16
|
|
||||||
const PackKeyLength = 32
|
|
||||||
const PackURLLength = len(PackURLFormat) - len("%x")*2 + PackIDLength*2 + PackKeyLength*2
|
|
||||||
|
|
||||||
var zeroPackID = make([]byte, PackIDLength)
|
|
||||||
|
|
||||||
func ParseStickerMeta(info *event.BridgedSticker) *signalpb.DataMessage_Sticker {
|
|
||||||
if info == nil || info.Network != StickerSourceID || len(info.PackURL) != PackURLLength {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
stickerID, err := strconv.ParseUint(info.ID, 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
packID, packKey, err := parsePackURL(info.PackURL)
|
|
||||||
if err != nil || len(packID) != PackIDLength || len(packKey) != PackKeyLength || bytes.Equal(packID, zeroPackID) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &signalpb.DataMessage_Sticker{
|
|
||||||
PackId: packID,
|
|
||||||
PackKey: packKey,
|
|
||||||
StickerId: proto.Uint32(uint32(stickerID)),
|
|
||||||
Emoji: &info.Emoji,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func parsePackURL(rawURL string) (packID, packKey []byte, err error) {
|
|
||||||
parsed, err := url.Parse(rawURL)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("invalid URL: %w", err)
|
|
||||||
} else if parsed.Host != "signal.art" || !strings.HasPrefix(parsed.Path, "/addstickers") {
|
|
||||||
return nil, nil, fmt.Errorf("invalid host or path in URL")
|
|
||||||
}
|
|
||||||
q, err := url.ParseQuery(parsed.Fragment)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("invalid URL fragment: %w", err)
|
|
||||||
}
|
|
||||||
packID, err = hex.DecodeString(q.Get("pack_id"))
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("invalid pack ID in URL: %w", err)
|
|
||||||
}
|
|
||||||
packKey, err = hex.DecodeString(q.Get("pack_key"))
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("invalid pack key in URL: %w", err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mc *MessageConverter) DownloadImagePack(ctx context.Context, url string) (*bridgev2.ImportedImagePack, error) {
|
|
||||||
packID, packKey, err := parsePackURL(url)
|
|
||||||
if err != nil {
|
|
||||||
return nil, bridgev2.WrapRespErr(err, mautrix.MNotFound)
|
|
||||||
}
|
|
||||||
manifest, err := signalmeow.DownloadStickerPackManifest(ctx, packID, packKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to download sticker pack manifest: %w", err)
|
|
||||||
}
|
|
||||||
topLevelExtra := map[string]any{
|
|
||||||
"fi.mau.signal.stickerpack": map[string]any{
|
|
||||||
"pack_id": hex.EncodeToString(packID),
|
|
||||||
"pack_key": hex.EncodeToString(packKey),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
content := &event.ImagePackEventContent{
|
|
||||||
Images: make(map[string]*event.ImagePackImage, len(manifest.Stickers)),
|
|
||||||
Metadata: event.ImagePackMetadata{
|
|
||||||
DisplayName: manifest.GetTitle(),
|
|
||||||
AvatarURL: "",
|
|
||||||
Usage: []event.ImagePackUsage{event.ImagePackUsageSticker},
|
|
||||||
Attribution: manifest.GetAuthor(),
|
|
||||||
BridgedPack: &event.BridgedStickerPack{
|
|
||||||
Network: StickerSourceID,
|
|
||||||
URL: fmt.Sprintf(PackURLFormat, packID, packKey),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
imagesByID := make(map[uint32]id.ContentURIString, len(manifest.Stickers))
|
|
||||||
uploadImage := func(sticker *signalpb.Pack_Sticker) (id.ContentURIString, error) {
|
|
||||||
stickerID := sticker.GetId()
|
|
||||||
existing, ok := imagesByID[stickerID]
|
|
||||||
if ok {
|
|
||||||
return existing, nil
|
|
||||||
}
|
|
||||||
var mxc id.ContentURIString
|
|
||||||
if mc.DirectMedia {
|
|
||||||
mediaID, err := signalid.DirectMediaSticker{
|
|
||||||
PackID: packID,
|
|
||||||
PackKey: packKey,
|
|
||||||
StickerID: stickerID,
|
|
||||||
}.AsMediaID()
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to create media ID for sticker %d: %w", stickerID, err)
|
|
||||||
}
|
|
||||||
mxc, err = mc.Bridge.Matrix.GenerateContentURI(ctx, mediaID)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to generate content URI for sticker %d: %w", stickerID, err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dbKey := database.Key(fmt.Sprintf("stickercache:%x:%d", packID, stickerID))
|
|
||||||
if cached := mc.Bridge.DB.KV.Get(ctx, dbKey); cached != "" {
|
|
||||||
mxc = id.ContentURIString(cached)
|
|
||||||
imagesByID[stickerID] = mxc
|
|
||||||
return mxc, nil
|
|
||||||
}
|
|
||||||
data, err := signalmeow.DownloadStickerPackItem(ctx, packID, packKey, stickerID)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to download sticker %d: %w", stickerID, err)
|
|
||||||
}
|
|
||||||
mxc, _, err = mc.Bridge.Bot.UploadMedia(ctx, "", data, "", sticker.GetContentType())
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to upload sticker %d: %w", stickerID, err)
|
|
||||||
}
|
|
||||||
mc.Bridge.DB.KV.Set(ctx, dbKey, string(mxc))
|
|
||||||
}
|
|
||||||
imagesByID[stickerID] = mxc
|
|
||||||
return mxc, nil
|
|
||||||
}
|
|
||||||
for _, sticker := range manifest.Stickers {
|
|
||||||
mxc, err := uploadImage(sticker)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
shortcode := emojishortcodes.Get(sticker.GetEmoji())
|
|
||||||
realShortcode := shortcode
|
|
||||||
i := 2
|
|
||||||
for _, alreadyExists := content.Images[realShortcode]; alreadyExists; i++ {
|
|
||||||
realShortcode = fmt.Sprintf("%s_%d", shortcode, i)
|
|
||||||
}
|
|
||||||
content.Images[realShortcode] = &event.ImagePackImage{
|
|
||||||
URL: mxc,
|
|
||||||
Body: sticker.GetEmoji(),
|
|
||||||
Info: &event.FileInfo{
|
|
||||||
MimeType: sticker.GetContentType(),
|
|
||||||
Width: 200,
|
|
||||||
Height: 200,
|
|
||||||
BridgedSticker: &event.BridgedSticker{
|
|
||||||
Network: StickerSourceID,
|
|
||||||
ID: strconv.FormatUint(uint64(sticker.GetId()), 10),
|
|
||||||
Emoji: sticker.GetEmoji(),
|
|
||||||
PackURL: content.Metadata.BridgedPack.URL,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if manifest.Cover != nil {
|
|
||||||
content.Metadata.AvatarURL, err = uploadImage(manifest.Cover)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to upload sticker pack cover: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &bridgev2.ImportedImagePack{
|
|
||||||
Content: content,
|
|
||||||
Extra: topLevelExtra,
|
|
||||||
Shortcode: hex.EncodeToString(packID),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
@ -21,7 +21,7 @@ import (
|
||||||
|
|
||||||
"maunium.net/go/mautrix/event"
|
"maunium.net/go/mautrix/event"
|
||||||
|
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/signalpb"
|
signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Parse(ctx context.Context, parser *HTMLParser, content *event.MessageEventContent) (string, []*signalpb.BodyRange) {
|
func Parse(ctx context.Context, parser *HTMLParser, content *event.MessageEventContent) (string, []*signalpb.BodyRange) {
|
||||||
|
|
|
||||||
|
|
@ -111,13 +111,22 @@ func TestParse_HTML(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "List",
|
name: "List",
|
||||||
in: "<ul><li>woof</li><li><strong>meow</strong></li><li><pre><code>hmm\nmeow</code></pre></li><li><blockquote>meow<br><h1>meow</h1></blockquote></li></ul>",
|
in: "<ul><li>woof</li><li><strong>meow</strong></li><li><pre><code>hmm\nmeow</code></pre></li><li><blockquote>meow<br><h1>meow</h1></blockquote></li></ul>",
|
||||||
out: "* woof\n* meow\n* ```\n hmm\n meow\n ```\n* > meow\n > \n > # meow",
|
out: "* woof\n* meow\n* hmm\n meow\n* > meow\n > \n > # meow",
|
||||||
ent: signalfmt.BodyRangeList{{
|
ent: signalfmt.BodyRangeList{{
|
||||||
Start: 9,
|
Start: 9,
|
||||||
Length: 4,
|
Length: 4,
|
||||||
Value: signalfmt.StyleBold,
|
Value: signalfmt.StyleBold,
|
||||||
}, {
|
}, {
|
||||||
Start: 57,
|
Start: 16,
|
||||||
|
Length: 3,
|
||||||
|
Value: signalfmt.StyleMonospace,
|
||||||
|
}, {
|
||||||
|
// FIXME optimally this would be a single range with the previous one so the indent is also monospace
|
||||||
|
Start: 22,
|
||||||
|
Length: 4,
|
||||||
|
Value: signalfmt.StyleMonospace,
|
||||||
|
}, {
|
||||||
|
Start: 45,
|
||||||
Length: 6,
|
Length: 6,
|
||||||
Value: signalfmt.StyleBold,
|
Value: signalfmt.StyleBold,
|
||||||
}},
|
}},
|
||||||
|
|
@ -125,13 +134,21 @@ func TestParse_HTML(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "OrderedList",
|
name: "OrderedList",
|
||||||
in: "<ol start=9><li>woof</li><li><strong>meow</strong></li><li><pre><code>hmm\nmeow</code></pre></li><li><blockquote>meow<br><h1>meow</h1></blockquote></li></ol>",
|
in: "<ol start=9><li>woof</li><li><strong>meow</strong></li><li><pre><code>hmm\nmeow</code></pre></li><li><blockquote>meow<br><h1>meow</h1></blockquote></li></ol>",
|
||||||
out: "9. woof\n10. meow\n11. ```\n hmm\n meow\n ```\n12. > meow\n > \n > # meow",
|
out: "9. woof\n10. meow\n11. hmm\n meow\n12. > meow\n > \n > # meow",
|
||||||
ent: signalfmt.BodyRangeList{{
|
ent: signalfmt.BodyRangeList{{
|
||||||
Start: 13,
|
Start: 13,
|
||||||
Length: 4,
|
Length: 4,
|
||||||
Value: signalfmt.StyleBold,
|
Value: signalfmt.StyleBold,
|
||||||
}, {
|
}, {
|
||||||
Start: 75,
|
Start: 22,
|
||||||
|
Length: 3,
|
||||||
|
Value: signalfmt.StyleMonospace,
|
||||||
|
}, {
|
||||||
|
Start: 30,
|
||||||
|
Length: 4,
|
||||||
|
Value: signalfmt.StyleMonospace,
|
||||||
|
}, {
|
||||||
|
Start: 59,
|
||||||
Length: 6,
|
Length: 6,
|
||||||
Value: signalfmt.StyleBold,
|
Value: signalfmt.StyleBold,
|
||||||
}},
|
}},
|
||||||
|
|
|
||||||
|
|
@ -404,17 +404,17 @@ func (parser *HTMLParser) tagToString(node *html.Node, ctx Context) *EntityStrin
|
||||||
return NewEntityString("---")
|
return NewEntityString("---")
|
||||||
case "pre":
|
case "pre":
|
||||||
var preStr *EntityString
|
var preStr *EntityString
|
||||||
var language string
|
//var language string
|
||||||
if node.FirstChild != nil && node.FirstChild.Type == html.ElementNode && node.FirstChild.Data == "code" {
|
if node.FirstChild != nil && node.FirstChild.Type == html.ElementNode && node.FirstChild.Data == "code" {
|
||||||
class := parser.getAttribute(node.FirstChild, "class")
|
//class := parser.getAttribute(node.FirstChild, "class")
|
||||||
if strings.HasPrefix(class, "language-") {
|
//if strings.HasPrefix(class, "language-") {
|
||||||
language = class[len("language-"):]
|
// language = class[len("language-"):]
|
||||||
}
|
//}
|
||||||
preStr = parser.nodeToString(node.FirstChild.FirstChild, ctx.WithWhitespace())
|
preStr = parser.nodeToString(node.FirstChild.FirstChild, ctx.WithWhitespace())
|
||||||
} else {
|
} else {
|
||||||
preStr = parser.nodeToString(node.FirstChild, ctx.WithWhitespace())
|
preStr = parser.nodeToString(node.FirstChild, ctx.WithWhitespace())
|
||||||
}
|
}
|
||||||
return NewEntityString(fmt.Sprintf("```%s\n", language)).Append(preStr).AppendString("\n```")
|
return preStr.Format(signalfmt.StyleMonospace)
|
||||||
default:
|
default:
|
||||||
return parser.nodeToTagAwareString(node.FirstChild, ctx)
|
return parser.nodeToTagAwareString(node.FirstChild, ctx)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ import (
|
||||||
"maunium.net/go/mautrix/event"
|
"maunium.net/go/mautrix/event"
|
||||||
"maunium.net/go/mautrix/id"
|
"maunium.net/go/mautrix/id"
|
||||||
|
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/signalpb"
|
signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserInfo struct {
|
type UserInfo struct {
|
||||||
|
|
@ -86,9 +86,6 @@ func Parse(ctx context.Context, message string, ranges []*signalpb.BodyRange, pa
|
||||||
Start: int(*r.Start),
|
Start: int(*r.Start),
|
||||||
Length: int(*r.Length),
|
Length: int(*r.Length),
|
||||||
}.TruncateEnd(maxLength)
|
}.TruncateEnd(maxLength)
|
||||||
if br.Start >= maxLength {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
var mentionACI uuid.UUID
|
var mentionACI uuid.UUID
|
||||||
switch rv := r.GetAssociatedValue().(type) {
|
switch rv := r.GetAssociatedValue().(type) {
|
||||||
case *signalpb.BodyRange_Style_:
|
case *signalpb.BodyRange_Style_:
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import (
|
||||||
"maunium.net/go/mautrix/id"
|
"maunium.net/go/mautrix/id"
|
||||||
|
|
||||||
"go.mau.fi/mautrix-signal/pkg/msgconv/signalfmt"
|
"go.mau.fi/mautrix-signal/pkg/msgconv/signalfmt"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/signalpb"
|
signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf"
|
||||||
)
|
)
|
||||||
|
|
||||||
var realUser = uuid.New()
|
var realUser = uuid.New()
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import (
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/signalpb"
|
signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BodyRangeValue interface {
|
type BodyRangeValue interface {
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import (
|
||||||
|
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
|
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/signalpb"
|
signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BodyRange struct {
|
type BodyRange struct {
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import (
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
"maunium.net/go/mautrix/event"
|
"maunium.net/go/mautrix/event"
|
||||||
|
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/signalpb"
|
signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (mc *MessageConverter) convertURLPreviewsToBeeper(ctx context.Context, preview []*signalpb.Preview, attMap AttachmentMap) []*event.BeeperLinkPreview {
|
func (mc *MessageConverter) convertURLPreviewsToBeeper(ctx context.Context, preview []*signalpb.Preview, attMap AttachmentMap) []*event.BeeperLinkPreview {
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,8 @@ type PortalMetadata struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type MessageMetadata struct {
|
type MessageMetadata struct {
|
||||||
ContainsAttachments bool `json:"contains_attachments,omitempty"`
|
ContainsAttachments bool `json:"contains_attachments,omitempty"`
|
||||||
MatrixPollOptionIDs []string `json:"matrix_poll_option_ids,omitempty"`
|
MatrixPollOptionIDs []string `json:"matrix_poll_option_ids,omitempty"`
|
||||||
VoteCount map[string]uint32 `json:"vote_count,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserLoginMetadata struct {
|
type UserLoginMetadata struct {
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ const (
|
||||||
directMediaTypeGroupAvatar directMediaType = 1
|
directMediaTypeGroupAvatar directMediaType = 1
|
||||||
directMediaTypeProfileAvatar directMediaType = 2
|
directMediaTypeProfileAvatar directMediaType = 2
|
||||||
directMediaTypePlaintextDigestAttachment directMediaType = 3
|
directMediaTypePlaintextDigestAttachment directMediaType = 3
|
||||||
directMediaTypeSticker directMediaType = 4
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type DirectMediaInfo interface {
|
type DirectMediaInfo interface {
|
||||||
|
|
@ -45,7 +44,6 @@ var (
|
||||||
_ DirectMediaInfo = (*DirectMediaAttachment)(nil)
|
_ DirectMediaInfo = (*DirectMediaAttachment)(nil)
|
||||||
_ DirectMediaInfo = (*DirectMediaGroupAvatar)(nil)
|
_ DirectMediaInfo = (*DirectMediaGroupAvatar)(nil)
|
||||||
_ DirectMediaInfo = (*DirectMediaProfileAvatar)(nil)
|
_ DirectMediaInfo = (*DirectMediaProfileAvatar)(nil)
|
||||||
_ DirectMediaInfo = (*DirectMediaSticker)(nil)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type DirectMediaAttachment struct {
|
type DirectMediaAttachment struct {
|
||||||
|
|
@ -129,30 +127,6 @@ func (m DirectMediaProfileAvatar) AsMediaID() (mediaID networkid.MediaID, err er
|
||||||
return networkid.MediaID(buf.Bytes()), nil
|
return networkid.MediaID(buf.Bytes()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type DirectMediaSticker struct {
|
|
||||||
PackID []byte
|
|
||||||
PackKey []byte
|
|
||||||
StickerID uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
const packIDLen = 16
|
|
||||||
const packKeyLen = 32
|
|
||||||
const directMediaStickerLen = 1 + packIDLen + packKeyLen + 4
|
|
||||||
|
|
||||||
func (m DirectMediaSticker) AsMediaID() (mediaID networkid.MediaID, err error) {
|
|
||||||
if len(m.PackID) != packIDLen {
|
|
||||||
return nil, fmt.Errorf("invalid pack ID length: %d", len(m.PackID))
|
|
||||||
} else if len(m.PackKey) != packKeyLen {
|
|
||||||
return nil, fmt.Errorf("invalid pack key length: %d", len(m.PackKey))
|
|
||||||
}
|
|
||||||
mediaID = make(networkid.MediaID, directMediaStickerLen)
|
|
||||||
mediaID[0] = byte(directMediaTypeSticker)
|
|
||||||
copy(mediaID[1:], m.PackID)
|
|
||||||
copy(mediaID[1+packIDLen:], m.PackKey)
|
|
||||||
binary.BigEndian.PutUint32(mediaID[1+packIDLen+packKeyLen:], m.StickerID)
|
|
||||||
return mediaID, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseDirectMediaInfo(mediaID networkid.MediaID) (_ DirectMediaInfo, err error) {
|
func ParseDirectMediaInfo(mediaID networkid.MediaID) (_ DirectMediaInfo, err error) {
|
||||||
mediaIDLen := len(mediaID)
|
mediaIDLen := len(mediaID)
|
||||||
if mediaIDLen == 0 {
|
if mediaIDLen == 0 {
|
||||||
|
|
@ -226,15 +200,6 @@ func ParseDirectMediaInfo(mediaID networkid.MediaID) (_ DirectMediaInfo, err err
|
||||||
info.ProfileAvatarPath = string(profileAvatarPath)
|
info.ProfileAvatarPath = string(profileAvatarPath)
|
||||||
}
|
}
|
||||||
return &info, nil
|
return &info, nil
|
||||||
case directMediaTypeSticker:
|
|
||||||
var info DirectMediaSticker
|
|
||||||
if len(mediaID) != directMediaStickerLen {
|
|
||||||
return info, fmt.Errorf("invalid media ID length for sticker: %d", len(mediaID))
|
|
||||||
}
|
|
||||||
info.PackID = mediaID[1 : 1+packIDLen]
|
|
||||||
info.PackKey = mediaID[1+packIDLen : 1+packIDLen+packKeyLen]
|
|
||||||
info.StickerID = binary.BigEndian.Uint32(mediaID[1+packIDLen+packKeyLen:])
|
|
||||||
return &info, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("invalid direct media type %d", mediaType)
|
return nil, fmt.Errorf("invalid direct media type %d", mediaType)
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,11 @@ import (
|
||||||
|
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"go.mau.fi/util/fallocate"
|
"go.mau.fi/util/fallocate"
|
||||||
"go.mau.fi/util/pkcs7"
|
|
||||||
"go.mau.fi/util/random"
|
"go.mau.fi/util/random"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
|
|
||||||
"go.mau.fi/mautrix-signal/pkg/libsignalgo"
|
"go.mau.fi/mautrix-signal/pkg/libsignalgo"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/signalpb"
|
signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/types"
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/types"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/web"
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/web"
|
||||||
)
|
)
|
||||||
|
|
@ -137,15 +136,6 @@ func DownloadAttachment(
|
||||||
const MACLength = 32
|
const MACLength = 32
|
||||||
const IVLength = 16
|
const IVLength = 16
|
||||||
|
|
||||||
func macAndAESDecrypt(body, key []byte) ([]byte, error) {
|
|
||||||
l := len(body) - MACLength
|
|
||||||
if !verifyMAC(key[MACLength:], body[:l], body[l:]) {
|
|
||||||
return nil, ErrInvalidMACForAttachment
|
|
||||||
}
|
|
||||||
|
|
||||||
return aesDecrypt(key[:MACLength], body[:l])
|
|
||||||
}
|
|
||||||
|
|
||||||
func decryptAttachment(body, key, digest []byte, plaintextDigest bool, size uint32) ([]byte, error) {
|
func decryptAttachment(body, key, digest []byte, plaintextDigest bool, size uint32) ([]byte, error) {
|
||||||
if !plaintextDigest {
|
if !plaintextDigest {
|
||||||
hash := sha256.Sum256(body)
|
hash := sha256.Sum256(body)
|
||||||
|
|
@ -153,7 +143,12 @@ func decryptAttachment(body, key, digest []byte, plaintextDigest bool, size uint
|
||||||
return nil, ErrInvalidDigestForAttachment
|
return nil, ErrInvalidDigestForAttachment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
decrypted, err := macAndAESDecrypt(body, key)
|
l := len(body) - MACLength
|
||||||
|
if !verifyMAC(key[MACLength:], body[:l], body[l:]) {
|
||||||
|
return nil, ErrInvalidMACForAttachment
|
||||||
|
}
|
||||||
|
|
||||||
|
decrypted, err := aesDecrypt(key[:MACLength], body[:l])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -245,14 +240,6 @@ func extend(data []byte, paddedLen int) []byte {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func macAndAESEncrypt(keys, plaintext []byte) ([]byte, error) {
|
|
||||||
encrypted, err := aesEncrypt(keys[:32], plaintext)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return appendMAC(keys[32:], encrypted), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cli *Client) UploadAttachment(ctx context.Context, body []byte) (*signalpb.AttachmentPointer, error) {
|
func (cli *Client) UploadAttachment(ctx context.Context, body []byte) (*signalpb.AttachmentPointer, error) {
|
||||||
log := zerolog.Ctx(ctx).With().Str("func", "upload attachment").Logger()
|
log := zerolog.Ctx(ctx).With().Str("func", "upload attachment").Logger()
|
||||||
keys := random.Bytes(64) // combined AES and MAC keys
|
keys := random.Bytes(64) // combined AES and MAC keys
|
||||||
|
|
@ -268,10 +255,11 @@ func (cli *Client) UploadAttachment(ctx context.Context, body []byte) (*signalpb
|
||||||
}
|
}
|
||||||
body = extend(body, paddedLen)
|
body = extend(body, paddedLen)
|
||||||
|
|
||||||
encryptedWithMAC, err := macAndAESEncrypt(keys, body)
|
encrypted, err := aesEncrypt(keys[:32], body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
encryptedWithMAC := appendMAC(keys[32:], encrypted)
|
||||||
|
|
||||||
// Get upload attributes from Signal server
|
// Get upload attributes from Signal server
|
||||||
attributesPath := "/v4/attachments/form/upload"
|
attributesPath := "/v4/attachments/form/upload"
|
||||||
|
|
@ -479,10 +467,13 @@ func aesDecrypt(key, ciphertext []byte) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
iv := ciphertext[:IVLength]
|
iv := ciphertext[:IVLength]
|
||||||
ciphertext = ciphertext[IVLength:]
|
|
||||||
mode := cipher.NewCBCDecrypter(block, iv)
|
mode := cipher.NewCBCDecrypter(block, iv)
|
||||||
mode.CryptBlocks(ciphertext, ciphertext)
|
mode.CryptBlocks(ciphertext, ciphertext)
|
||||||
return pkcs7.Unpad(ciphertext)
|
pad := ciphertext[len(ciphertext)-1]
|
||||||
|
if pad > aes.BlockSize {
|
||||||
|
return nil, fmt.Errorf("pad value (%d) larger than AES blocksize (%d)", pad, aes.BlockSize)
|
||||||
|
}
|
||||||
|
return ciphertext[aes.BlockSize : len(ciphertext)-int(pad)], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func aesDecryptFile(key []byte, file *os.File, downloadedSize int64) (int64, error) {
|
func aesDecryptFile(key []byte, file *os.File, downloadedSize int64) (int64, error) {
|
||||||
|
|
@ -542,11 +533,14 @@ func aesEncrypt(key, plaintext []byte) ([]byte, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
plaintext = pkcs7.Pad(plaintext, aes.BlockSize)
|
pad := aes.BlockSize - len(plaintext)%aes.BlockSize
|
||||||
|
plaintext = append(plaintext, bytes.Repeat([]byte{byte(pad)}, pad)...)
|
||||||
|
|
||||||
|
ciphertext := make([]byte, len(plaintext))
|
||||||
iv := random.Bytes(16)
|
iv := random.Bytes(16)
|
||||||
|
|
||||||
mode := cipher.NewCBCEncrypter(block, iv)
|
mode := cipher.NewCBCEncrypter(block, iv)
|
||||||
mode.CryptBlocks(plaintext, plaintext)
|
mode.CryptBlocks(ciphertext, plaintext)
|
||||||
|
|
||||||
return append(iv, plaintext...), nil
|
return append(iv, ciphertext...), nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ import (
|
||||||
|
|
||||||
"go.mau.fi/mautrix-signal/pkg/libsignalgo"
|
"go.mau.fi/mautrix-signal/pkg/libsignalgo"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/events"
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/events"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/signalpb"
|
signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/store"
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/store"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/types"
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/types"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/web"
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/web"
|
||||||
|
|
@ -55,7 +55,6 @@ type Client struct {
|
||||||
|
|
||||||
AuthedWS *web.SignalWebsocket
|
AuthedWS *web.SignalWebsocket
|
||||||
UnauthedWS *web.SignalWebsocket
|
UnauthedWS *web.SignalWebsocket
|
||||||
GRPC *web.GRPCClient
|
|
||||||
lastConnectionStatus SignalConnectionStatus
|
lastConnectionStatus SignalConnectionStatus
|
||||||
|
|
||||||
loopCancel context.CancelFunc
|
loopCancel context.CancelFunc
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ import (
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
|
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/signalpb"
|
signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/types"
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,14 +35,12 @@ import (
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
|
|
||||||
"go.mau.fi/mautrix-signal/pkg/libsignalgo"
|
"go.mau.fi/mautrix-signal/pkg/libsignalgo"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/cds2pb"
|
signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/web"
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/web"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProdContactDiscoveryMrenclave should always match ENCLAVE_ID_CDSI_PROD from libsignal
|
|
||||||
// https://github.com/signalapp/libsignal/blob/main/rust/attest/src/constants.rs#L69
|
|
||||||
const ProdContactDiscoveryMrenclave = "15637fa1e54fe655176d3df1a9f94b87c01ed377acaa570682dc5d72c95ef07b"
|
|
||||||
const ProdContactDiscoveryServer = "cdsi.signal.org"
|
const ProdContactDiscoveryServer = "cdsi.signal.org"
|
||||||
|
const ProdContactDiscoveryMrenclave = "ee9503070127120074612b6688e593b67e486b1541449f54d71e387484eb40a3"
|
||||||
const ContactDiscoveryAuthTTL = 23 * time.Hour
|
const ContactDiscoveryAuthTTL = 23 * time.Hour
|
||||||
|
|
||||||
const rateLimitCloseCode = websocket.StatusCode(4008)
|
const rateLimitCloseCode = websocket.StatusCode(4008)
|
||||||
|
|
@ -83,7 +81,7 @@ func (cli *Client) LookupPhone(ctx context.Context, e164s ...uint64) (ContactDis
|
||||||
}
|
}
|
||||||
ctx, cancel := context.WithTimeout(ctx, 20*time.Second)
|
ctx, cancel := context.WithTimeout(ctx, 20*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
resp, token, err := cli.doContactDiscovery(ctx, &cds2pb.ClientRequest{
|
resp, token, err := cli.doContactDiscovery(ctx, &signalpb.CDSClientRequest{
|
||||||
// TODO figure out if tokens are useful
|
// TODO figure out if tokens are useful
|
||||||
// (it's meant for old_e164s)
|
// (it's meant for old_e164s)
|
||||||
//Token: cli.cdToken,
|
//Token: cli.cdToken,
|
||||||
|
|
@ -95,7 +93,7 @@ func (cli *Client) LookupPhone(ctx context.Context, e164s ...uint64) (ContactDis
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cli *Client) doContactDiscovery(ctx context.Context, req *cds2pb.ClientRequest) (ContactDiscoveryResponse, []byte, error) {
|
func (cli *Client) doContactDiscovery(ctx context.Context, req *signalpb.CDSClientRequest) (ContactDiscoveryResponse, []byte, error) {
|
||||||
creds, err := cli.getContactDiscoveryCredentials(ctx)
|
creds, err := cli.getContactDiscoveryCredentials(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("failed to fetch contact discovery auth: %w", err)
|
return nil, nil, fmt.Errorf("failed to fetch contact discovery auth: %w", err)
|
||||||
|
|
@ -187,7 +185,7 @@ func (cdc *ContactDiscoveryClient) Handshake(ctx context.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cdc *ContactDiscoveryClient) SendRequest(ctx context.Context, req *cds2pb.ClientRequest) error {
|
func (cdc *ContactDiscoveryClient) SendRequest(ctx context.Context, req *signalpb.CDSClientRequest) error {
|
||||||
plaintext, err := proto.Marshal(req)
|
plaintext, err := proto.Marshal(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to marshal request: %w", err)
|
return fmt.Errorf("failed to marshal request: %w", err)
|
||||||
|
|
@ -224,15 +222,15 @@ func (cdc *ContactDiscoveryClient) handleResponse(ctx context.Context, msg []byt
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to decrypt message: %w", err)
|
return fmt.Errorf("failed to decrypt message: %w", err)
|
||||||
}
|
}
|
||||||
var cdsClientResp cds2pb.ClientResponse
|
var cdsClientResp signalpb.CDSClientResponse
|
||||||
err = proto.Unmarshal(decrypted, &cdsClientResp)
|
err = proto.Unmarshal(decrypted, &cdsClientResp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to unmarshal message: %w", err)
|
return fmt.Errorf("failed to unmarshal message: %w", err)
|
||||||
}
|
}
|
||||||
if cdsClientResp.Token != nil {
|
if cdsClientResp.Token != nil {
|
||||||
cdc.Token = cdsClientResp.Token
|
cdc.Token = cdsClientResp.Token
|
||||||
err = cdc.SendRequest(ctx, &cds2pb.ClientRequest{
|
err = cdc.SendRequest(ctx, &signalpb.CDSClientRequest{
|
||||||
TokenAck: true,
|
TokenAck: proto.Bool(true),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to send token ack request: %w", err)
|
return fmt.Errorf("failed to send token ack request: %w", err)
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ import (
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
|
|
||||||
"go.mau.fi/mautrix-signal/pkg/libsignalgo"
|
"go.mau.fi/mautrix-signal/pkg/libsignalgo"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/signalpb"
|
signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf"
|
||||||
)
|
)
|
||||||
|
|
||||||
func hmacSHA256(key, input []byte) []byte {
|
func hmacSHA256(key, input []byte) []byte {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import (
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
|
||||||
"go.mau.fi/mautrix-signal/pkg/libsignalgo"
|
"go.mau.fi/mautrix-signal/pkg/libsignalgo"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/signalpb"
|
signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/types"
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ import (
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
|
|
||||||
"go.mau.fi/mautrix-signal/pkg/libsignalgo"
|
"go.mau.fi/mautrix-signal/pkg/libsignalgo"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/signalpb"
|
signalpb "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/types"
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/types"
|
||||||
"go.mau.fi/mautrix-signal/pkg/signalmeow/web"
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/web"
|
||||||
)
|
)
|
||||||
|
|
@ -619,7 +619,7 @@ func (cli *Client) fetchGroupByID(ctx context.Context, gid types.GroupIdentifier
|
||||||
return nil, fmt.Errorf("failed to get group master key: %w", err)
|
return nil, fmt.Errorf("failed to get group master key: %w", err)
|
||||||
}
|
}
|
||||||
if groupMasterKey == "" {
|
if groupMasterKey == "" {
|
||||||
return nil, fmt.Errorf("%w for %s", ErrGroupMasterKeyNotFound, gid)
|
return nil, fmt.Errorf("No group master key found for group identifier %s", gid)
|
||||||
}
|
}
|
||||||
return cli.fetchGroupWithMasterKey(ctx, groupMasterKey)
|
return cli.fetchGroupWithMasterKey(ctx, groupMasterKey)
|
||||||
}
|
}
|
||||||
|
|
@ -641,7 +641,7 @@ func (cli *Client) fetchGroupWithMasterKey(ctx context.Context, groupMasterKey t
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if response.StatusCode != 200 {
|
if response.StatusCode != 200 {
|
||||||
return nil, fmt.Errorf("unexpected response status: %d", response.StatusCode)
|
return nil, fmt.Errorf("fetchGroupByID SendHTTPRequest bad status: %d", response.StatusCode)
|
||||||
}
|
}
|
||||||
return cli.parseGroupResponse(ctx, response, groupMasterKey)
|
return cli.parseGroupResponse(ctx, response, groupMasterKey)
|
||||||
}
|
}
|
||||||
|
|
@ -1513,15 +1513,11 @@ func (cli *Client) patchGroup(ctx context.Context, groupChange *signalpb.GroupCh
|
||||||
return &changeResp, nil
|
return &changeResp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var ErrGroupMasterKeyNotFound = errors.New("group master key not found in store")
|
|
||||||
|
|
||||||
func (cli *Client) UpdateGroup(ctx context.Context, groupChange *GroupChange, gid types.GroupIdentifier) (uint32, error) {
|
func (cli *Client) UpdateGroup(ctx context.Context, groupChange *GroupChange, gid types.GroupIdentifier) (uint32, error) {
|
||||||
log := zerolog.Ctx(ctx).With().Str("action", "UpdateGroup").Logger()
|
log := zerolog.Ctx(ctx).With().Str("action", "UpdateGroup").Logger()
|
||||||
groupMasterKey, err := cli.Store.GroupStore.MasterKeyFromGroupIdentifier(ctx, gid)
|
groupMasterKey, err := cli.Store.GroupStore.MasterKeyFromGroupIdentifier(ctx, gid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("failed to get master key for group: %w", err)
|
return 0, fmt.Errorf("failed to get master key for group: %w", err)
|
||||||
} else if groupMasterKey == "" {
|
|
||||||
return 0, ErrGroupMasterKeyNotFound
|
|
||||||
}
|
}
|
||||||
groupChange.GroupMasterKey = groupMasterKey
|
groupChange.GroupMasterKey = groupMasterKey
|
||||||
masterKeyBytes := masterKeyToBytes(groupMasterKey)
|
masterKeyBytes := masterKeyToBytes(groupMasterKey)
|
||||||
|
|
@ -1756,7 +1752,7 @@ func (cli *Client) GetGroupHistoryPage(ctx context.Context, gid types.GroupIdent
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if groupMasterKey == "" {
|
if groupMasterKey == "" {
|
||||||
return nil, ErrGroupMasterKeyNotFound
|
return nil, fmt.Errorf("No group master key found for group identifier %s", gid)
|
||||||
}
|
}
|
||||||
masterKeyBytes := masterKeyToBytes(groupMasterKey)
|
masterKeyBytes := masterKeyToBytes(groupMasterKey)
|
||||||
groupAuth, err := cli.GetAuthorizationForToday(ctx, masterKeyBytes)
|
groupAuth, err := cli.GetAuthorizationForToday(ctx, masterKeyBytes)
|
||||||
|
|
@ -1780,7 +1776,7 @@ func (cli *Client) GetGroupHistoryPage(ctx context.Context, gid types.GroupIdent
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if response.StatusCode != 200 {
|
if response.StatusCode != 200 {
|
||||||
return nil, fmt.Errorf("unexpected response status: %d", response.StatusCode)
|
return nil, fmt.Errorf("fetchGroupByID SendHTTPRequest bad status: %d", response.StatusCode)
|
||||||
}
|
}
|
||||||
var encryptedGroupChanges signalpb.GroupChanges
|
var encryptedGroupChanges signalpb.GroupChanges
|
||||||
groupChangesBytes, err := io.ReadAll(response.Body)
|
groupChangesBytes, err := io.ReadAll(response.Body)
|
||||||
|
|
|
||||||
|
|
@ -413,10 +413,6 @@ func (cli *Client) FetchAndProcessPreKey(ctx context.Context, theirServiceID lib
|
||||||
if cli.Store.RecipientStore.IsUnregistered(ctx, theirServiceID) {
|
if cli.Store.RecipientStore.IsUnregistered(ctx, theirServiceID) {
|
||||||
return fmt.Errorf("%w (cached)", ErrUnregisteredUser)
|
return fmt.Errorf("%w (cached)", ErrUnregisteredUser)
|
||||||
}
|
}
|
||||||
localAddress, err := cli.Store.ACIServiceID().Address(uint(cli.Store.DeviceID))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to get own address: %w", err)
|
|
||||||
}
|
|
||||||
// Fetch prekey
|
// Fetch prekey
|
||||||
deviceIDPath := "/*"
|
deviceIDPath := "/*"
|
||||||
if specificDeviceID >= 0 {
|
if specificDeviceID >= 0 {
|
||||||
|
|
@ -522,7 +518,6 @@ func (cli *Client) FetchAndProcessPreKey(ctx context.Context, theirServiceID lib
|
||||||
ctx,
|
ctx,
|
||||||
preKeyBundle,
|
preKeyBundle,
|
||||||
address,
|
address,
|
||||||
localAddress,
|
|
||||||
cli.Store.ACISessionStore,
|
cli.Store.ACISessionStore,
|
||||||
cli.Store.ACIIdentityStore,
|
cli.Store.ACIIdentityStore,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -69,8 +69,6 @@ func (l FFILogger) Log(level libsignalgo.LogLevel, file string, line uint, messa
|
||||||
|
|
||||||
func (FFILogger) Flush() {}
|
func (FFILogger) Flush() {}
|
||||||
|
|
||||||
func (FFILogger) Destroy() {}
|
|
||||||
|
|
||||||
// Ensure FFILogger implements the Logger interface
|
// Ensure FFILogger implements the Logger interface
|
||||||
var _ libsignalgo.Logger = FFILogger{}
|
var _ libsignalgo.Logger = FFILogger{}
|
||||||
|
|
||||||
|
|
|
||||||
272
pkg/signalmeow/protobuf/ContactDiscovery.pb.go
generated
Normal file
272
pkg/signalmeow/protobuf/ContactDiscovery.pb.go
generated
Normal file
|
|
@ -0,0 +1,272 @@
|
||||||
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// protoc-gen-go v1.36.11
|
||||||
|
// protoc v6.33.5
|
||||||
|
// source: ContactDiscovery.proto
|
||||||
|
|
||||||
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
package signalpb
|
||||||
|
|
||||||
|
import (
|
||||||
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||||
|
reflect "reflect"
|
||||||
|
sync "sync"
|
||||||
|
unsafe "unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Verify that this generated code is sufficiently up-to-date.
|
||||||
|
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||||
|
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||||
|
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||||
|
)
|
||||||
|
|
||||||
|
type CDSClientRequest struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
// Each ACI/UAK pair is a 32-byte buffer, containing the 16-byte ACI followed
|
||||||
|
// by its 16-byte UAK.
|
||||||
|
AciUakPairs []byte `protobuf:"bytes,1,opt,name=aci_uak_pairs,json=aciUakPairs" json:"aci_uak_pairs,omitempty"`
|
||||||
|
// Each E164 is an 8-byte big-endian number, as 8 bytes.
|
||||||
|
PrevE164S []byte `protobuf:"bytes,2,opt,name=prev_e164s,json=prevE164s" json:"prev_e164s,omitempty"`
|
||||||
|
NewE164S []byte `protobuf:"bytes,3,opt,name=new_e164s,json=newE164s" json:"new_e164s,omitempty"`
|
||||||
|
DiscardE164S []byte `protobuf:"bytes,4,opt,name=discard_e164s,json=discardE164s" json:"discard_e164s,omitempty"`
|
||||||
|
// If true, the client has more pairs or e164s to send. If false or unset,
|
||||||
|
// this is the client's last request, and processing should commence.
|
||||||
|
HasMore *bool `protobuf:"varint,5,opt,name=has_more,json=hasMore" json:"has_more,omitempty"`
|
||||||
|
// If set, a token which allows rate limiting to discount the e164s in
|
||||||
|
// the request's prev_e164s, only counting new_e164s. If not set, then
|
||||||
|
// rate limiting considers both prev_e164s' and new_e164s' size.
|
||||||
|
Token []byte `protobuf:"bytes,6,opt,name=token" json:"token,omitempty"`
|
||||||
|
// After receiving a new token from the server, send back a message just
|
||||||
|
// containing a token_ack.
|
||||||
|
TokenAck *bool `protobuf:"varint,7,opt,name=token_ack,json=tokenAck" json:"token_ack,omitempty"`
|
||||||
|
// Request that, if the server allows, both ACI and PNI be returned even
|
||||||
|
// if the aci_uak_pairs don't match.
|
||||||
|
ReturnAcisWithoutUaks *bool `protobuf:"varint,8,opt,name=return_acis_without_uaks,json=returnAcisWithoutUaks" json:"return_acis_without_uaks,omitempty"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CDSClientRequest) Reset() {
|
||||||
|
*x = CDSClientRequest{}
|
||||||
|
mi := &file_ContactDiscovery_proto_msgTypes[0]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CDSClientRequest) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CDSClientRequest) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *CDSClientRequest) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_ContactDiscovery_proto_msgTypes[0]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use CDSClientRequest.ProtoReflect.Descriptor instead.
|
||||||
|
func (*CDSClientRequest) Descriptor() ([]byte, []int) {
|
||||||
|
return file_ContactDiscovery_proto_rawDescGZIP(), []int{0}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CDSClientRequest) GetAciUakPairs() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.AciUakPairs
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CDSClientRequest) GetPrevE164S() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.PrevE164S
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CDSClientRequest) GetNewE164S() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.NewE164S
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CDSClientRequest) GetDiscardE164S() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.DiscardE164S
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CDSClientRequest) GetHasMore() bool {
|
||||||
|
if x != nil && x.HasMore != nil {
|
||||||
|
return *x.HasMore
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CDSClientRequest) GetToken() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.Token
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CDSClientRequest) GetTokenAck() bool {
|
||||||
|
if x != nil && x.TokenAck != nil {
|
||||||
|
return *x.TokenAck
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CDSClientRequest) GetReturnAcisWithoutUaks() bool {
|
||||||
|
if x != nil && x.ReturnAcisWithoutUaks != nil {
|
||||||
|
return *x.ReturnAcisWithoutUaks
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
type CDSClientResponse struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
// Each triple is an 8-byte e164, a 16-byte PNI, and a 16-byte ACI.
|
||||||
|
// If the e164 was not found, PNI and ACI are all zeros. If the PNI
|
||||||
|
// was found but the ACI was not, the PNI will be non-zero and the ACI
|
||||||
|
// will be all zeros. ACI will be returned if one of the returned
|
||||||
|
// PNIs has an ACI/UAK pair that matches.
|
||||||
|
//
|
||||||
|
// Should the request be successful (IE: a successful status returned),
|
||||||
|
// |e164_pni_aci_triple| will always equal |e164| of the request,
|
||||||
|
// so the entire marshalled size of the response will be (2+32)*|e164|,
|
||||||
|
// where the additional 2 bytes are the id/type/length additions of the
|
||||||
|
// protobuf marshaling added to each byte array. This avoids any data
|
||||||
|
// leakage based on the size of the encrypted output.
|
||||||
|
E164PniAciTriples []byte `protobuf:"bytes,1,opt,name=e164_pni_aci_triples,json=e164PniAciTriples" json:"e164_pni_aci_triples,omitempty"`
|
||||||
|
// A token which allows subsequent calls' rate limiting to discount the
|
||||||
|
// e164s sent up in this request, only counting those in the next
|
||||||
|
// request's new_e164s.
|
||||||
|
Token []byte `protobuf:"bytes,3,opt,name=token" json:"token,omitempty"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CDSClientResponse) Reset() {
|
||||||
|
*x = CDSClientResponse{}
|
||||||
|
mi := &file_ContactDiscovery_proto_msgTypes[1]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CDSClientResponse) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*CDSClientResponse) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *CDSClientResponse) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_ContactDiscovery_proto_msgTypes[1]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use CDSClientResponse.ProtoReflect.Descriptor instead.
|
||||||
|
func (*CDSClientResponse) Descriptor() ([]byte, []int) {
|
||||||
|
return file_ContactDiscovery_proto_rawDescGZIP(), []int{1}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CDSClientResponse) GetE164PniAciTriples() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.E164PniAciTriples
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CDSClientResponse) GetToken() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.Token
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var File_ContactDiscovery_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
|
const file_ContactDiscovery_proto_rawDesc = "" +
|
||||||
|
"\n" +
|
||||||
|
"\x16ContactDiscovery.proto\x12\rsignalservice\"\x9e\x02\n" +
|
||||||
|
"\x10CDSClientRequest\x12\"\n" +
|
||||||
|
"\raci_uak_pairs\x18\x01 \x01(\fR\vaciUakPairs\x12\x1d\n" +
|
||||||
|
"\n" +
|
||||||
|
"prev_e164s\x18\x02 \x01(\fR\tprevE164s\x12\x1b\n" +
|
||||||
|
"\tnew_e164s\x18\x03 \x01(\fR\bnewE164s\x12#\n" +
|
||||||
|
"\rdiscard_e164s\x18\x04 \x01(\fR\fdiscardE164s\x12\x19\n" +
|
||||||
|
"\bhas_more\x18\x05 \x01(\bR\ahasMore\x12\x14\n" +
|
||||||
|
"\x05token\x18\x06 \x01(\fR\x05token\x12\x1b\n" +
|
||||||
|
"\ttoken_ack\x18\a \x01(\bR\btokenAck\x127\n" +
|
||||||
|
"\x18return_acis_without_uaks\x18\b \x01(\bR\x15returnAcisWithoutUaks\"Z\n" +
|
||||||
|
"\x11CDSClientResponse\x12/\n" +
|
||||||
|
"\x14e164_pni_aci_triples\x18\x01 \x01(\fR\x11e164PniAciTriples\x12\x14\n" +
|
||||||
|
"\x05token\x18\x03 \x01(\fR\x05token"
|
||||||
|
|
||||||
|
var (
|
||||||
|
file_ContactDiscovery_proto_rawDescOnce sync.Once
|
||||||
|
file_ContactDiscovery_proto_rawDescData []byte
|
||||||
|
)
|
||||||
|
|
||||||
|
func file_ContactDiscovery_proto_rawDescGZIP() []byte {
|
||||||
|
file_ContactDiscovery_proto_rawDescOnce.Do(func() {
|
||||||
|
file_ContactDiscovery_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_ContactDiscovery_proto_rawDesc), len(file_ContactDiscovery_proto_rawDesc)))
|
||||||
|
})
|
||||||
|
return file_ContactDiscovery_proto_rawDescData
|
||||||
|
}
|
||||||
|
|
||||||
|
var file_ContactDiscovery_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||||
|
var file_ContactDiscovery_proto_goTypes = []any{
|
||||||
|
(*CDSClientRequest)(nil), // 0: signalservice.CDSClientRequest
|
||||||
|
(*CDSClientResponse)(nil), // 1: signalservice.CDSClientResponse
|
||||||
|
}
|
||||||
|
var file_ContactDiscovery_proto_depIdxs = []int32{
|
||||||
|
0, // [0:0] is the sub-list for method output_type
|
||||||
|
0, // [0:0] is the sub-list for method input_type
|
||||||
|
0, // [0:0] is the sub-list for extension type_name
|
||||||
|
0, // [0:0] is the sub-list for extension extendee
|
||||||
|
0, // [0:0] is the sub-list for field type_name
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() { file_ContactDiscovery_proto_init() }
|
||||||
|
func file_ContactDiscovery_proto_init() {
|
||||||
|
if File_ContactDiscovery_proto != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
type x struct{}
|
||||||
|
out := protoimpl.TypeBuilder{
|
||||||
|
File: protoimpl.DescBuilder{
|
||||||
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
|
RawDescriptor: unsafe.Slice(unsafe.StringData(file_ContactDiscovery_proto_rawDesc), len(file_ContactDiscovery_proto_rawDesc)),
|
||||||
|
NumEnums: 0,
|
||||||
|
NumMessages: 2,
|
||||||
|
NumExtensions: 0,
|
||||||
|
NumServices: 0,
|
||||||
|
},
|
||||||
|
GoTypes: file_ContactDiscovery_proto_goTypes,
|
||||||
|
DependencyIndexes: file_ContactDiscovery_proto_depIdxs,
|
||||||
|
MessageInfos: file_ContactDiscovery_proto_msgTypes,
|
||||||
|
}.Build()
|
||||||
|
File_ContactDiscovery_proto = out.File
|
||||||
|
file_ContactDiscovery_proto_goTypes = nil
|
||||||
|
file_ContactDiscovery_proto_depIdxs = nil
|
||||||
|
}
|
||||||
|
|
@ -1,36 +1,37 @@
|
||||||
syntax = "proto3";
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
package org.signal.cdsi;
|
package signalservice;
|
||||||
|
|
||||||
message ClientRequest {
|
message CDSClientRequest {
|
||||||
// Each ACI/UAK pair is a 32-byte buffer, containing the 16-byte ACI followed
|
// Each ACI/UAK pair is a 32-byte buffer, containing the 16-byte ACI followed
|
||||||
// by its 16-byte UAK.
|
// by its 16-byte UAK.
|
||||||
bytes aci_uak_pairs = 1;
|
optional bytes aci_uak_pairs = 1;
|
||||||
|
|
||||||
// Each E164 is an 8-byte big-endian number, as 8 bytes.
|
// Each E164 is an 8-byte big-endian number, as 8 bytes.
|
||||||
bytes prev_e164s = 2;
|
optional bytes prev_e164s = 2;
|
||||||
bytes new_e164s = 3;
|
optional bytes new_e164s = 3;
|
||||||
bytes discard_e164s = 4;
|
optional bytes discard_e164s = 4;
|
||||||
|
|
||||||
// If true, the client has more pairs or e164s to send. If false or unset,
|
// If true, the client has more pairs or e164s to send. If false or unset,
|
||||||
// this is the client's last request, and processing should commence.
|
// this is the client's last request, and processing should commence.
|
||||||
// bool has_more = 5;
|
optional bool has_more = 5;
|
||||||
reserved 5;
|
|
||||||
|
|
||||||
// If set, a token which allows rate limiting to discount the e164s in
|
// If set, a token which allows rate limiting to discount the e164s in
|
||||||
// the request's prev_e164s, only counting new_e164s. If not set, then
|
// the request's prev_e164s, only counting new_e164s. If not set, then
|
||||||
// rate limiting considers both prev_e164s' and new_e164s' size.
|
// rate limiting considers both prev_e164s' and new_e164s' size.
|
||||||
bytes token = 6;
|
optional bytes token = 6;
|
||||||
|
|
||||||
// After receiving a new token from the server, send back a message just
|
// After receiving a new token from the server, send back a message just
|
||||||
// containing a token_ack.
|
// containing a token_ack.
|
||||||
bool token_ack = 7;
|
optional bool token_ack = 7;
|
||||||
|
|
||||||
// [deprecated] bool return_acis_without_uaks = 8
|
// Request that, if the server allows, both ACI and PNI be returned even
|
||||||
reserved 8;
|
// if the aci_uak_pairs don't match.
|
||||||
|
optional bool return_acis_without_uaks = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ClientResponse {
|
message CDSClientResponse {
|
||||||
// Each triple is an 8-byte e164, a 16-byte PNI, and a 16-byte ACI.
|
// Each triple is an 8-byte e164, a 16-byte PNI, and a 16-byte ACI.
|
||||||
// If the e164 was not found, PNI and ACI are all zeros. If the PNI
|
// If the e164 was not found, PNI and ACI are all zeros. If the PNI
|
||||||
// was found but the ACI was not, the PNI will be non-zero and the ACI
|
// was found but the ACI was not, the PNI will be non-zero and the ACI
|
||||||
|
|
@ -43,18 +44,10 @@ message ClientResponse {
|
||||||
// where the additional 2 bytes are the id/type/length additions of the
|
// where the additional 2 bytes are the id/type/length additions of the
|
||||||
// protobuf marshaling added to each byte array. This avoids any data
|
// protobuf marshaling added to each byte array. This avoids any data
|
||||||
// leakage based on the size of the encrypted output.
|
// leakage based on the size of the encrypted output.
|
||||||
bytes e164_pni_aci_triples = 1;
|
optional bytes e164_pni_aci_triples = 1;
|
||||||
|
|
||||||
// int32 retry_after_secs = 2 [deprecated]
|
|
||||||
reserved 2;
|
|
||||||
|
|
||||||
// A token which allows subsequent calls' rate limiting to discount the
|
// A token which allows subsequent calls' rate limiting to discount the
|
||||||
// e164s sent up in this request, only counting those in the next
|
// e164s sent up in this request, only counting those in the next
|
||||||
// request's new_e164s.
|
// request's new_e164s.
|
||||||
bytes token = 3;
|
optional bytes token = 3;
|
||||||
|
|
||||||
// On a successful response to a token_ack request, the number of permits
|
|
||||||
// that were deducted from the user's rate-limit in order to process the
|
|
||||||
// request
|
|
||||||
int32 debug_permits_used = 4;
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
//*
|
|
||||||
// Copyright (C) 2014-2016 Open Whisper Systems
|
|
||||||
//
|
|
||||||
// Licensed according to the LICENSE file in this repository.
|
|
||||||
|
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.11
|
// protoc-gen-go v1.36.11
|
||||||
// protoc v7.34.1
|
// protoc v6.33.5
|
||||||
// source: signalpb/DeviceName.proto
|
// source: DeviceName.proto
|
||||||
|
|
||||||
|
// Copyright 2018 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
package signalpb
|
package signalpb
|
||||||
|
|
||||||
|
|
@ -37,7 +35,7 @@ type DeviceName struct {
|
||||||
|
|
||||||
func (x *DeviceName) Reset() {
|
func (x *DeviceName) Reset() {
|
||||||
*x = DeviceName{}
|
*x = DeviceName{}
|
||||||
mi := &file_signalpb_DeviceName_proto_msgTypes[0]
|
mi := &file_DeviceName_proto_msgTypes[0]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
|
|
@ -49,7 +47,7 @@ func (x *DeviceName) String() string {
|
||||||
func (*DeviceName) ProtoMessage() {}
|
func (*DeviceName) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *DeviceName) ProtoReflect() protoreflect.Message {
|
func (x *DeviceName) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_signalpb_DeviceName_proto_msgTypes[0]
|
mi := &file_DeviceName_proto_msgTypes[0]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
|
@ -62,7 +60,7 @@ func (x *DeviceName) ProtoReflect() protoreflect.Message {
|
||||||
|
|
||||||
// Deprecated: Use DeviceName.ProtoReflect.Descriptor instead.
|
// Deprecated: Use DeviceName.ProtoReflect.Descriptor instead.
|
||||||
func (*DeviceName) Descriptor() ([]byte, []int) {
|
func (*DeviceName) Descriptor() ([]byte, []int) {
|
||||||
return file_signalpb_DeviceName_proto_rawDescGZIP(), []int{0}
|
return file_DeviceName_proto_rawDescGZIP(), []int{0}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *DeviceName) GetEphemeralPublic() []byte {
|
func (x *DeviceName) GetEphemeralPublic() []byte {
|
||||||
|
|
@ -86,37 +84,36 @@ func (x *DeviceName) GetCiphertext() []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var File_signalpb_DeviceName_proto protoreflect.FileDescriptor
|
var File_DeviceName_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
const file_signalpb_DeviceName_proto_rawDesc = "" +
|
const file_DeviceName_proto_rawDesc = "" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"\x19signalpb/DeviceName.proto\x12\rsignalservice\"x\n" +
|
"\x10DeviceName.proto\x12\rsignalservice\"x\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"DeviceName\x12(\n" +
|
"DeviceName\x12(\n" +
|
||||||
"\x0fephemeralPublic\x18\x01 \x01(\fR\x0fephemeralPublic\x12 \n" +
|
"\x0fephemeralPublic\x18\x01 \x01(\fR\x0fephemeralPublic\x12 \n" +
|
||||||
"\vsyntheticIv\x18\x02 \x01(\fR\vsyntheticIv\x12\x1e\n" +
|
"\vsyntheticIv\x18\x02 \x01(\fR\vsyntheticIv\x12\x1e\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"ciphertext\x18\x03 \x01(\fR\n" +
|
"ciphertext\x18\x03 \x01(\fR\n" +
|
||||||
"ciphertextB\x1d\n" +
|
"ciphertext"
|
||||||
"\x1borg.signal.core.util.crypto"
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
file_signalpb_DeviceName_proto_rawDescOnce sync.Once
|
file_DeviceName_proto_rawDescOnce sync.Once
|
||||||
file_signalpb_DeviceName_proto_rawDescData []byte
|
file_DeviceName_proto_rawDescData []byte
|
||||||
)
|
)
|
||||||
|
|
||||||
func file_signalpb_DeviceName_proto_rawDescGZIP() []byte {
|
func file_DeviceName_proto_rawDescGZIP() []byte {
|
||||||
file_signalpb_DeviceName_proto_rawDescOnce.Do(func() {
|
file_DeviceName_proto_rawDescOnce.Do(func() {
|
||||||
file_signalpb_DeviceName_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_signalpb_DeviceName_proto_rawDesc), len(file_signalpb_DeviceName_proto_rawDesc)))
|
file_DeviceName_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_DeviceName_proto_rawDesc), len(file_DeviceName_proto_rawDesc)))
|
||||||
})
|
})
|
||||||
return file_signalpb_DeviceName_proto_rawDescData
|
return file_DeviceName_proto_rawDescData
|
||||||
}
|
}
|
||||||
|
|
||||||
var file_signalpb_DeviceName_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
var file_DeviceName_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||||
var file_signalpb_DeviceName_proto_goTypes = []any{
|
var file_DeviceName_proto_goTypes = []any{
|
||||||
(*DeviceName)(nil), // 0: signalservice.DeviceName
|
(*DeviceName)(nil), // 0: signalservice.DeviceName
|
||||||
}
|
}
|
||||||
var file_signalpb_DeviceName_proto_depIdxs = []int32{
|
var file_DeviceName_proto_depIdxs = []int32{
|
||||||
0, // [0:0] is the sub-list for method output_type
|
0, // [0:0] is the sub-list for method output_type
|
||||||
0, // [0:0] is the sub-list for method input_type
|
0, // [0:0] is the sub-list for method input_type
|
||||||
0, // [0:0] is the sub-list for extension type_name
|
0, // [0:0] is the sub-list for extension type_name
|
||||||
|
|
@ -124,26 +121,26 @@ var file_signalpb_DeviceName_proto_depIdxs = []int32{
|
||||||
0, // [0:0] is the sub-list for field type_name
|
0, // [0:0] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_signalpb_DeviceName_proto_init() }
|
func init() { file_DeviceName_proto_init() }
|
||||||
func file_signalpb_DeviceName_proto_init() {
|
func file_DeviceName_proto_init() {
|
||||||
if File_signalpb_DeviceName_proto != nil {
|
if File_DeviceName_proto != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
type x struct{}
|
type x struct{}
|
||||||
out := protoimpl.TypeBuilder{
|
out := protoimpl.TypeBuilder{
|
||||||
File: protoimpl.DescBuilder{
|
File: protoimpl.DescBuilder{
|
||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_signalpb_DeviceName_proto_rawDesc), len(file_signalpb_DeviceName_proto_rawDesc)),
|
RawDescriptor: unsafe.Slice(unsafe.StringData(file_DeviceName_proto_rawDesc), len(file_DeviceName_proto_rawDesc)),
|
||||||
NumEnums: 0,
|
NumEnums: 0,
|
||||||
NumMessages: 1,
|
NumMessages: 1,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 0,
|
NumServices: 0,
|
||||||
},
|
},
|
||||||
GoTypes: file_signalpb_DeviceName_proto_goTypes,
|
GoTypes: file_DeviceName_proto_goTypes,
|
||||||
DependencyIndexes: file_signalpb_DeviceName_proto_depIdxs,
|
DependencyIndexes: file_DeviceName_proto_depIdxs,
|
||||||
MessageInfos: file_signalpb_DeviceName_proto_msgTypes,
|
MessageInfos: file_DeviceName_proto_msgTypes,
|
||||||
}.Build()
|
}.Build()
|
||||||
File_signalpb_DeviceName_proto = out.File
|
File_DeviceName_proto = out.File
|
||||||
file_signalpb_DeviceName_proto_goTypes = nil
|
file_DeviceName_proto_goTypes = nil
|
||||||
file_signalpb_DeviceName_proto_depIdxs = nil
|
file_DeviceName_proto_depIdxs = nil
|
||||||
}
|
}
|
||||||
10
pkg/signalmeow/protobuf/DeviceName.proto
Normal file
10
pkg/signalmeow/protobuf/DeviceName.proto
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
// Copyright 2018 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
package signalservice;
|
||||||
|
|
||||||
|
message DeviceName {
|
||||||
|
optional bytes ephemeralPublic = 1;
|
||||||
|
optional bytes syntheticIv = 2;
|
||||||
|
optional bytes ciphertext = 3;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -69,7 +69,6 @@ message AccessControl {
|
||||||
AccessRequired attributes = 1;
|
AccessRequired attributes = 1;
|
||||||
AccessRequired members = 2;
|
AccessRequired members = 2;
|
||||||
AccessRequired addFromInviteLink = 3;
|
AccessRequired addFromInviteLink = 3;
|
||||||
AccessRequired memberLabel = 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message Group {
|
message Group {
|
||||||
|
|
@ -88,8 +87,7 @@ message Group {
|
||||||
bytes inviteLinkPassword = 10;
|
bytes inviteLinkPassword = 10;
|
||||||
bool announcements_only = 12;
|
bool announcements_only = 12;
|
||||||
repeated MemberBanned members_banned = 13;
|
repeated MemberBanned members_banned = 13;
|
||||||
bool terminated = 14;
|
// next: 14
|
||||||
// next: 15
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message GroupAttributeBlob {
|
message GroupAttributeBlob {
|
||||||
|
|
@ -227,10 +225,6 @@ message GroupChange {
|
||||||
AccessControl.AccessRequired addFromInviteLinkAccess = 1;
|
AccessControl.AccessRequired addFromInviteLinkAccess = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ModifyMemberLabelAccessControlAction {
|
|
||||||
AccessControl.AccessRequired memberLabelAccess = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
message ModifyInviteLinkPasswordAction {
|
message ModifyInviteLinkPasswordAction {
|
||||||
bytes inviteLinkPassword = 1;
|
bytes inviteLinkPassword = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -239,8 +233,6 @@ message GroupChange {
|
||||||
bool announcements_only = 1;
|
bool announcements_only = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message TerminateGroupAction {}
|
|
||||||
|
|
||||||
bytes sourceUserId = 1;
|
bytes sourceUserId = 1;
|
||||||
// clients should not provide this value; the server will provide it in the response buffer to ensure the signature is binding to a particular group
|
// clients should not provide this value; the server will provide it in the response buffer to ensure the signature is binding to a particular group
|
||||||
// if clients set it during a request the server will respond with 400.
|
// if clients set it during a request the server will respond with 400.
|
||||||
|
|
@ -270,9 +262,7 @@ message GroupChange {
|
||||||
repeated DeleteMemberBannedAction delete_members_banned = 23; // change epoch = 4
|
repeated DeleteMemberBannedAction delete_members_banned = 23; // change epoch = 4
|
||||||
repeated PromoteMemberPendingPniAciProfileKeyAction promote_members_pending_pni_aci_profile_key = 24; // change epoch = 5
|
repeated PromoteMemberPendingPniAciProfileKeyAction promote_members_pending_pni_aci_profile_key = 24; // change epoch = 5
|
||||||
repeated ModifyMemberLabelAction modifyMemberLabels = 26; // change epoch = 6;
|
repeated ModifyMemberLabelAction modifyMemberLabels = 26; // change epoch = 6;
|
||||||
ModifyMemberLabelAccessControlAction modifyMemberLabelAccess = 27; // change epoch = 6
|
// next: 27
|
||||||
TerminateGroupAction terminate_group = 28; // change epoch = 7
|
|
||||||
// next: 29
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes actions = 1;
|
bytes actions = 1;
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.11
|
// protoc-gen-go v1.36.11
|
||||||
// protoc v7.34.1
|
// protoc v6.33.5
|
||||||
// source: signalpb/Provisioning.proto
|
// source: Provisioning.proto
|
||||||
|
|
||||||
package signalpb
|
package signalpb
|
||||||
|
|
||||||
|
|
@ -58,11 +58,11 @@ func (x ProvisioningVersion) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ProvisioningVersion) Descriptor() protoreflect.EnumDescriptor {
|
func (ProvisioningVersion) Descriptor() protoreflect.EnumDescriptor {
|
||||||
return file_signalpb_Provisioning_proto_enumTypes[0].Descriptor()
|
return file_Provisioning_proto_enumTypes[0].Descriptor()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ProvisioningVersion) Type() protoreflect.EnumType {
|
func (ProvisioningVersion) Type() protoreflect.EnumType {
|
||||||
return &file_signalpb_Provisioning_proto_enumTypes[0]
|
return &file_Provisioning_proto_enumTypes[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x ProvisioningVersion) Number() protoreflect.EnumNumber {
|
func (x ProvisioningVersion) Number() protoreflect.EnumNumber {
|
||||||
|
|
@ -81,7 +81,7 @@ func (x *ProvisioningVersion) UnmarshalJSON(b []byte) error {
|
||||||
|
|
||||||
// Deprecated: Use ProvisioningVersion.Descriptor instead.
|
// Deprecated: Use ProvisioningVersion.Descriptor instead.
|
||||||
func (ProvisioningVersion) EnumDescriptor() ([]byte, []int) {
|
func (ProvisioningVersion) EnumDescriptor() ([]byte, []int) {
|
||||||
return file_signalpb_Provisioning_proto_rawDescGZIP(), []int{0}
|
return file_Provisioning_proto_rawDescGZIP(), []int{0}
|
||||||
}
|
}
|
||||||
|
|
||||||
// An opaque address sent by the server when clients first open a provisioning
|
// An opaque address sent by the server when clients first open a provisioning
|
||||||
|
|
@ -98,7 +98,7 @@ type ProvisioningAddress struct {
|
||||||
|
|
||||||
func (x *ProvisioningAddress) Reset() {
|
func (x *ProvisioningAddress) Reset() {
|
||||||
*x = ProvisioningAddress{}
|
*x = ProvisioningAddress{}
|
||||||
mi := &file_signalpb_Provisioning_proto_msgTypes[0]
|
mi := &file_Provisioning_proto_msgTypes[0]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
|
|
@ -110,7 +110,7 @@ func (x *ProvisioningAddress) String() string {
|
||||||
func (*ProvisioningAddress) ProtoMessage() {}
|
func (*ProvisioningAddress) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *ProvisioningAddress) ProtoReflect() protoreflect.Message {
|
func (x *ProvisioningAddress) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_signalpb_Provisioning_proto_msgTypes[0]
|
mi := &file_Provisioning_proto_msgTypes[0]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
|
@ -123,7 +123,7 @@ func (x *ProvisioningAddress) ProtoReflect() protoreflect.Message {
|
||||||
|
|
||||||
// Deprecated: Use ProvisioningAddress.ProtoReflect.Descriptor instead.
|
// Deprecated: Use ProvisioningAddress.ProtoReflect.Descriptor instead.
|
||||||
func (*ProvisioningAddress) Descriptor() ([]byte, []int) {
|
func (*ProvisioningAddress) Descriptor() ([]byte, []int) {
|
||||||
return file_signalpb_Provisioning_proto_rawDescGZIP(), []int{0}
|
return file_Provisioning_proto_rawDescGZIP(), []int{0}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ProvisioningAddress) GetAddress() string {
|
func (x *ProvisioningAddress) GetAddress() string {
|
||||||
|
|
@ -143,7 +143,7 @@ type ProvisionEnvelope struct {
|
||||||
|
|
||||||
func (x *ProvisionEnvelope) Reset() {
|
func (x *ProvisionEnvelope) Reset() {
|
||||||
*x = ProvisionEnvelope{}
|
*x = ProvisionEnvelope{}
|
||||||
mi := &file_signalpb_Provisioning_proto_msgTypes[1]
|
mi := &file_Provisioning_proto_msgTypes[1]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
|
|
@ -155,7 +155,7 @@ func (x *ProvisionEnvelope) String() string {
|
||||||
func (*ProvisionEnvelope) ProtoMessage() {}
|
func (*ProvisionEnvelope) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *ProvisionEnvelope) ProtoReflect() protoreflect.Message {
|
func (x *ProvisionEnvelope) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_signalpb_Provisioning_proto_msgTypes[1]
|
mi := &file_Provisioning_proto_msgTypes[1]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
|
@ -168,7 +168,7 @@ func (x *ProvisionEnvelope) ProtoReflect() protoreflect.Message {
|
||||||
|
|
||||||
// Deprecated: Use ProvisionEnvelope.ProtoReflect.Descriptor instead.
|
// Deprecated: Use ProvisionEnvelope.ProtoReflect.Descriptor instead.
|
||||||
func (*ProvisionEnvelope) Descriptor() ([]byte, []int) {
|
func (*ProvisionEnvelope) Descriptor() ([]byte, []int) {
|
||||||
return file_signalpb_Provisioning_proto_rawDescGZIP(), []int{1}
|
return file_Provisioning_proto_rawDescGZIP(), []int{1}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ProvisionEnvelope) GetPublicKey() []byte {
|
func (x *ProvisionEnvelope) GetPublicKey() []byte {
|
||||||
|
|
@ -199,19 +199,19 @@ type ProvisionMessage struct {
|
||||||
ProfileKey []byte `protobuf:"bytes,6,opt,name=profileKey" json:"profileKey,omitempty"`
|
ProfileKey []byte `protobuf:"bytes,6,opt,name=profileKey" json:"profileKey,omitempty"`
|
||||||
ReadReceipts *bool `protobuf:"varint,7,opt,name=readReceipts" json:"readReceipts,omitempty"`
|
ReadReceipts *bool `protobuf:"varint,7,opt,name=readReceipts" json:"readReceipts,omitempty"`
|
||||||
ProvisioningVersion *uint32 `protobuf:"varint,9,opt,name=provisioningVersion" json:"provisioningVersion,omitempty"`
|
ProvisioningVersion *uint32 `protobuf:"varint,9,opt,name=provisioningVersion" json:"provisioningVersion,omitempty"`
|
||||||
|
MasterKey []byte `protobuf:"bytes,13,opt,name=masterKey" json:"masterKey,omitempty"` // Deprecated, but required by linked devices
|
||||||
EphemeralBackupKey []byte `protobuf:"bytes,14,opt,name=ephemeralBackupKey" json:"ephemeralBackupKey,omitempty"` // 32 bytes
|
EphemeralBackupKey []byte `protobuf:"bytes,14,opt,name=ephemeralBackupKey" json:"ephemeralBackupKey,omitempty"` // 32 bytes
|
||||||
AccountEntropyPool *string `protobuf:"bytes,15,opt,name=accountEntropyPool" json:"accountEntropyPool,omitempty"`
|
AccountEntropyPool *string `protobuf:"bytes,15,opt,name=accountEntropyPool" json:"accountEntropyPool,omitempty"`
|
||||||
MediaRootBackupKey []byte `protobuf:"bytes,16,opt,name=mediaRootBackupKey" json:"mediaRootBackupKey,omitempty"` // 32-bytes
|
MediaRootBackupKey []byte `protobuf:"bytes,16,opt,name=mediaRootBackupKey" json:"mediaRootBackupKey,omitempty"` // 32-bytes
|
||||||
AciBinary []byte `protobuf:"bytes,17,opt,name=aciBinary" json:"aciBinary,omitempty"` // 16-byte UUID
|
AciBinary []byte `protobuf:"bytes,17,opt,name=aciBinary" json:"aciBinary,omitempty"` // 16-byte UUID
|
||||||
PniBinary []byte `protobuf:"bytes,18,opt,name=pniBinary" json:"pniBinary,omitempty"` // 16-byte UUID
|
PniBinary []byte `protobuf:"bytes,18,opt,name=pniBinary" json:"pniBinary,omitempty"` // 16-byte UUID
|
||||||
AuthCredentialSalt []byte `protobuf:"bytes,19,opt,name=authCredentialSalt" json:"authCredentialSalt,omitempty"` // 16-bytes
|
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ProvisionMessage) Reset() {
|
func (x *ProvisionMessage) Reset() {
|
||||||
*x = ProvisionMessage{}
|
*x = ProvisionMessage{}
|
||||||
mi := &file_signalpb_Provisioning_proto_msgTypes[2]
|
mi := &file_Provisioning_proto_msgTypes[2]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
|
|
@ -223,7 +223,7 @@ func (x *ProvisionMessage) String() string {
|
||||||
func (*ProvisionMessage) ProtoMessage() {}
|
func (*ProvisionMessage) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *ProvisionMessage) ProtoReflect() protoreflect.Message {
|
func (x *ProvisionMessage) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_signalpb_Provisioning_proto_msgTypes[2]
|
mi := &file_Provisioning_proto_msgTypes[2]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
|
@ -236,7 +236,7 @@ func (x *ProvisionMessage) ProtoReflect() protoreflect.Message {
|
||||||
|
|
||||||
// Deprecated: Use ProvisionMessage.ProtoReflect.Descriptor instead.
|
// Deprecated: Use ProvisionMessage.ProtoReflect.Descriptor instead.
|
||||||
func (*ProvisionMessage) Descriptor() ([]byte, []int) {
|
func (*ProvisionMessage) Descriptor() ([]byte, []int) {
|
||||||
return file_signalpb_Provisioning_proto_rawDescGZIP(), []int{2}
|
return file_Provisioning_proto_rawDescGZIP(), []int{2}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ProvisionMessage) GetAciIdentityKeyPublic() []byte {
|
func (x *ProvisionMessage) GetAciIdentityKeyPublic() []byte {
|
||||||
|
|
@ -323,6 +323,13 @@ func (x *ProvisionMessage) GetProvisioningVersion() uint32 {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *ProvisionMessage) GetMasterKey() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.MasterKey
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (x *ProvisionMessage) GetEphemeralBackupKey() []byte {
|
func (x *ProvisionMessage) GetEphemeralBackupKey() []byte {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.EphemeralBackupKey
|
return x.EphemeralBackupKey
|
||||||
|
|
@ -358,23 +365,16 @@ func (x *ProvisionMessage) GetPniBinary() []byte {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *ProvisionMessage) GetAuthCredentialSalt() []byte {
|
var File_Provisioning_proto protoreflect.FileDescriptor
|
||||||
if x != nil {
|
|
||||||
return x.AuthCredentialSalt
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var File_signalpb_Provisioning_proto protoreflect.FileDescriptor
|
const file_Provisioning_proto_rawDesc = "" +
|
||||||
|
|
||||||
const file_signalpb_Provisioning_proto_rawDesc = "" +
|
|
||||||
"\n" +
|
"\n" +
|
||||||
"\x1bsignalpb/Provisioning.proto\x12\rsignalservice\"/\n" +
|
"\x12Provisioning.proto\x12\rsignalservice\"/\n" +
|
||||||
"\x13ProvisioningAddress\x12\x18\n" +
|
"\x13ProvisioningAddress\x12\x18\n" +
|
||||||
"\aaddress\x18\x01 \x01(\tR\aaddress\"E\n" +
|
"\aaddress\x18\x01 \x01(\tR\aaddress\"E\n" +
|
||||||
"\x11ProvisionEnvelope\x12\x1c\n" +
|
"\x11ProvisionEnvelope\x12\x1c\n" +
|
||||||
"\tpublicKey\x18\x01 \x01(\fR\tpublicKey\x12\x12\n" +
|
"\tpublicKey\x18\x01 \x01(\fR\tpublicKey\x12\x12\n" +
|
||||||
"\x04body\x18\x02 \x01(\fR\x04body\"\xe4\x05\n" +
|
"\x04body\x18\x02 \x01(\fR\x04body\"\xcc\x05\n" +
|
||||||
"\x10ProvisionMessage\x122\n" +
|
"\x10ProvisionMessage\x122\n" +
|
||||||
"\x14aciIdentityKeyPublic\x18\x01 \x01(\fR\x14aciIdentityKeyPublic\x124\n" +
|
"\x14aciIdentityKeyPublic\x18\x01 \x01(\fR\x14aciIdentityKeyPublic\x124\n" +
|
||||||
"\x15aciIdentityKeyPrivate\x18\x02 \x01(\fR\x15aciIdentityKeyPrivate\x122\n" +
|
"\x15aciIdentityKeyPrivate\x18\x02 \x01(\fR\x15aciIdentityKeyPrivate\x122\n" +
|
||||||
|
|
@ -390,13 +390,13 @@ const file_signalpb_Provisioning_proto_rawDesc = "" +
|
||||||
"profileKey\x18\x06 \x01(\fR\n" +
|
"profileKey\x18\x06 \x01(\fR\n" +
|
||||||
"profileKey\x12\"\n" +
|
"profileKey\x12\"\n" +
|
||||||
"\freadReceipts\x18\a \x01(\bR\freadReceipts\x120\n" +
|
"\freadReceipts\x18\a \x01(\bR\freadReceipts\x120\n" +
|
||||||
"\x13provisioningVersion\x18\t \x01(\rR\x13provisioningVersion\x12.\n" +
|
"\x13provisioningVersion\x18\t \x01(\rR\x13provisioningVersion\x12\x1c\n" +
|
||||||
|
"\tmasterKey\x18\r \x01(\fR\tmasterKey\x12.\n" +
|
||||||
"\x12ephemeralBackupKey\x18\x0e \x01(\fR\x12ephemeralBackupKey\x12.\n" +
|
"\x12ephemeralBackupKey\x18\x0e \x01(\fR\x12ephemeralBackupKey\x12.\n" +
|
||||||
"\x12accountEntropyPool\x18\x0f \x01(\tR\x12accountEntropyPool\x12.\n" +
|
"\x12accountEntropyPool\x18\x0f \x01(\tR\x12accountEntropyPool\x12.\n" +
|
||||||
"\x12mediaRootBackupKey\x18\x10 \x01(\fR\x12mediaRootBackupKey\x12\x1c\n" +
|
"\x12mediaRootBackupKey\x18\x10 \x01(\fR\x12mediaRootBackupKey\x12\x1c\n" +
|
||||||
"\taciBinary\x18\x11 \x01(\fR\taciBinary\x12\x1c\n" +
|
"\taciBinary\x18\x11 \x01(\fR\taciBinary\x12\x1c\n" +
|
||||||
"\tpniBinary\x18\x12 \x01(\fR\tpniBinary\x12.\n" +
|
"\tpniBinary\x18\x12 \x01(\fR\tpniBinary*G\n" +
|
||||||
"\x12authCredentialSalt\x18\x13 \x01(\fR\x12authCredentialSaltJ\x04\b\r\x10\x0e*G\n" +
|
|
||||||
"\x13ProvisioningVersion\x12\v\n" +
|
"\x13ProvisioningVersion\x12\v\n" +
|
||||||
"\aINITIAL\x10\x00\x12\x12\n" +
|
"\aINITIAL\x10\x00\x12\x12\n" +
|
||||||
"\x0eTABLET_SUPPORT\x10\x01\x12\v\n" +
|
"\x0eTABLET_SUPPORT\x10\x01\x12\v\n" +
|
||||||
|
|
@ -404,26 +404,26 @@ const file_signalpb_Provisioning_proto_rawDesc = "" +
|
||||||
".org.whispersystems.signalservice.internal.pushB\x12ProvisioningProtos"
|
".org.whispersystems.signalservice.internal.pushB\x12ProvisioningProtos"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
file_signalpb_Provisioning_proto_rawDescOnce sync.Once
|
file_Provisioning_proto_rawDescOnce sync.Once
|
||||||
file_signalpb_Provisioning_proto_rawDescData []byte
|
file_Provisioning_proto_rawDescData []byte
|
||||||
)
|
)
|
||||||
|
|
||||||
func file_signalpb_Provisioning_proto_rawDescGZIP() []byte {
|
func file_Provisioning_proto_rawDescGZIP() []byte {
|
||||||
file_signalpb_Provisioning_proto_rawDescOnce.Do(func() {
|
file_Provisioning_proto_rawDescOnce.Do(func() {
|
||||||
file_signalpb_Provisioning_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_signalpb_Provisioning_proto_rawDesc), len(file_signalpb_Provisioning_proto_rawDesc)))
|
file_Provisioning_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_Provisioning_proto_rawDesc), len(file_Provisioning_proto_rawDesc)))
|
||||||
})
|
})
|
||||||
return file_signalpb_Provisioning_proto_rawDescData
|
return file_Provisioning_proto_rawDescData
|
||||||
}
|
}
|
||||||
|
|
||||||
var file_signalpb_Provisioning_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
var file_Provisioning_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||||
var file_signalpb_Provisioning_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
var file_Provisioning_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
||||||
var file_signalpb_Provisioning_proto_goTypes = []any{
|
var file_Provisioning_proto_goTypes = []any{
|
||||||
(ProvisioningVersion)(0), // 0: signalservice.ProvisioningVersion
|
(ProvisioningVersion)(0), // 0: signalservice.ProvisioningVersion
|
||||||
(*ProvisioningAddress)(nil), // 1: signalservice.ProvisioningAddress
|
(*ProvisioningAddress)(nil), // 1: signalservice.ProvisioningAddress
|
||||||
(*ProvisionEnvelope)(nil), // 2: signalservice.ProvisionEnvelope
|
(*ProvisionEnvelope)(nil), // 2: signalservice.ProvisionEnvelope
|
||||||
(*ProvisionMessage)(nil), // 3: signalservice.ProvisionMessage
|
(*ProvisionMessage)(nil), // 3: signalservice.ProvisionMessage
|
||||||
}
|
}
|
||||||
var file_signalpb_Provisioning_proto_depIdxs = []int32{
|
var file_Provisioning_proto_depIdxs = []int32{
|
||||||
0, // [0:0] is the sub-list for method output_type
|
0, // [0:0] is the sub-list for method output_type
|
||||||
0, // [0:0] is the sub-list for method input_type
|
0, // [0:0] is the sub-list for method input_type
|
||||||
0, // [0:0] is the sub-list for extension type_name
|
0, // [0:0] is the sub-list for extension type_name
|
||||||
|
|
@ -431,27 +431,27 @@ var file_signalpb_Provisioning_proto_depIdxs = []int32{
|
||||||
0, // [0:0] is the sub-list for field type_name
|
0, // [0:0] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_signalpb_Provisioning_proto_init() }
|
func init() { file_Provisioning_proto_init() }
|
||||||
func file_signalpb_Provisioning_proto_init() {
|
func file_Provisioning_proto_init() {
|
||||||
if File_signalpb_Provisioning_proto != nil {
|
if File_Provisioning_proto != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
type x struct{}
|
type x struct{}
|
||||||
out := protoimpl.TypeBuilder{
|
out := protoimpl.TypeBuilder{
|
||||||
File: protoimpl.DescBuilder{
|
File: protoimpl.DescBuilder{
|
||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_signalpb_Provisioning_proto_rawDesc), len(file_signalpb_Provisioning_proto_rawDesc)),
|
RawDescriptor: unsafe.Slice(unsafe.StringData(file_Provisioning_proto_rawDesc), len(file_Provisioning_proto_rawDesc)),
|
||||||
NumEnums: 1,
|
NumEnums: 1,
|
||||||
NumMessages: 3,
|
NumMessages: 3,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 0,
|
NumServices: 0,
|
||||||
},
|
},
|
||||||
GoTypes: file_signalpb_Provisioning_proto_goTypes,
|
GoTypes: file_Provisioning_proto_goTypes,
|
||||||
DependencyIndexes: file_signalpb_Provisioning_proto_depIdxs,
|
DependencyIndexes: file_Provisioning_proto_depIdxs,
|
||||||
EnumInfos: file_signalpb_Provisioning_proto_enumTypes,
|
EnumInfos: file_Provisioning_proto_enumTypes,
|
||||||
MessageInfos: file_signalpb_Provisioning_proto_msgTypes,
|
MessageInfos: file_Provisioning_proto_msgTypes,
|
||||||
}.Build()
|
}.Build()
|
||||||
File_signalpb_Provisioning_proto = out.File
|
File_Provisioning_proto = out.File
|
||||||
file_signalpb_Provisioning_proto_goTypes = nil
|
file_Provisioning_proto_goTypes = nil
|
||||||
file_signalpb_Provisioning_proto_depIdxs = nil
|
file_Provisioning_proto_depIdxs = nil
|
||||||
}
|
}
|
||||||
|
|
@ -38,14 +38,13 @@ message ProvisionMessage {
|
||||||
optional bytes profileKey = 6;
|
optional bytes profileKey = 6;
|
||||||
optional bool readReceipts = 7;
|
optional bool readReceipts = 7;
|
||||||
optional uint32 provisioningVersion = 9;
|
optional uint32 provisioningVersion = 9;
|
||||||
reserved /*masterKey*/ 13; // Deprecated in favor of accountEntropyPool
|
optional bytes masterKey = 13; // Deprecated, but required by linked devices
|
||||||
optional bytes ephemeralBackupKey = 14; // 32 bytes
|
optional bytes ephemeralBackupKey = 14; // 32 bytes
|
||||||
optional string accountEntropyPool = 15;
|
optional string accountEntropyPool = 15;
|
||||||
optional bytes mediaRootBackupKey = 16; // 32-bytes
|
optional bytes mediaRootBackupKey = 16; // 32-bytes
|
||||||
optional bytes aciBinary = 17; // 16-byte UUID
|
optional bytes aciBinary = 17; // 16-byte UUID
|
||||||
optional bytes pniBinary = 18; // 16-byte UUID
|
optional bytes pniBinary = 18; // 16-byte UUID
|
||||||
optional bytes authCredentialSalt = 19; // 16-bytes
|
// NEXT ID: 19
|
||||||
// NEXT ID: 20
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ProvisioningVersion {
|
enum ProvisioningVersion {
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -13,79 +13,23 @@ option java_outer_classname = "SignalServiceProtos";
|
||||||
message Envelope {
|
message Envelope {
|
||||||
enum Type {
|
enum Type {
|
||||||
UNKNOWN = 0;
|
UNKNOWN = 0;
|
||||||
|
CIPHERTEXT = 1; // content => (version byte | SignalMessage{Content})
|
||||||
/**
|
|
||||||
* A double-ratchet message represents a "normal," "unsealed-sender" message
|
|
||||||
* encrypted using the Double Ratchet within an established Signal session.
|
|
||||||
* Double-ratchet messages include sender information in the plaintext
|
|
||||||
* portion of the `Envelope`.
|
|
||||||
*/
|
|
||||||
DOUBLE_RATCHET = 1; // content => (version byte | SignalMessage{Content})
|
|
||||||
|
|
||||||
reserved 2;
|
reserved 2;
|
||||||
reserved "KEY_EXCHANGE";
|
reserved "KEY_EXCHANGE";
|
||||||
|
PREKEY_BUNDLE = 3; // content => (version byte | PreKeySignalMessage{Content})
|
||||||
/**
|
SERVER_DELIVERY_RECEIPT = 5; // legacyMessage => [] AND content => []
|
||||||
* A prekey message begins a new Signal session. The `content` of a prekey
|
UNIDENTIFIED_SENDER = 6; // legacyMessage => [] AND content => ((version byte | UnidentifiedSenderMessage) OR (version byte | Multi-Recipient Sealed Sender Format))
|
||||||
* message is a superset of a double-ratchet message's `content` and
|
SENDERKEY_MESSAGE = 7; // legacyMessage => [] AND content => (version byte | SenderKeyMessage)
|
||||||
* contains the sender's identity public key and information identifying the
|
PLAINTEXT_CONTENT = 8; // legacyMessage => [] AND content => (marker byte | Content)
|
||||||
* pre-keys used in the message's ciphertext. Like double-ratchet messages,
|
|
||||||
* prekey messages contain sender information in the plaintext portion of
|
|
||||||
* the `Envelope`.
|
|
||||||
*/
|
|
||||||
PREKEY_MESSAGE = 3; // content => (version byte | PreKeySignalMessage{Content})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Server delivery receipts are generated by the server when
|
|
||||||
* "unsealed-sender" messages are delivered to and acknowledged by the
|
|
||||||
* destination device. Server delivery receipts identify the sender in the
|
|
||||||
* plaintext portion of the `Envelope` and have no `content`. Note that
|
|
||||||
* receipts for sealed-sender messages are generated by clients as
|
|
||||||
* `UNIDENTIFIED_SENDER` messages.
|
|
||||||
*
|
|
||||||
* Note that, with server delivery receipts, the "client timestamp" on
|
|
||||||
* the envelope refers to the timestamp of the original message (i.e. the
|
|
||||||
* message the server just delivered) and not to the time of delivery. The
|
|
||||||
* "server timestamp" refers to the time of delivery.
|
|
||||||
*/
|
|
||||||
SERVER_DELIVERY_RECEIPT = 5; // content => []
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An unidentified sender message represents a message with no sender
|
|
||||||
* information in the plaintext portion of the `Envelope`. Unidentified
|
|
||||||
* sender messages always contain an additional `subtype` in their
|
|
||||||
* `content`. They may or may not be part of an existing Signal session
|
|
||||||
* (i.e. an unidentified sender message may have a "prekey message"
|
|
||||||
* subtype or may indicate an encryption error).
|
|
||||||
*/
|
|
||||||
UNIDENTIFIED_SENDER = 6; // content => ((version byte | UnidentifiedSenderMessage) OR (version byte | Multi-Recipient Sealed Sender Format))
|
|
||||||
|
|
||||||
reserved 7;
|
|
||||||
reserved "SENDERKEY_MESSAGE";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A plaintext message is used solely to convey encryption error receipts
|
|
||||||
* and never contains encrypted message content. Encryption error receipts
|
|
||||||
* must be delivered in plaintext because, encryption/decryption of a prior
|
|
||||||
* message failed and there is no reason to believe that
|
|
||||||
* encryption/decryption of subsequent messages with the same key material
|
|
||||||
* would succeed.
|
|
||||||
*
|
|
||||||
* Critically, plaintext messages never have "real" message content
|
|
||||||
* generated by users. Plaintext messages include sender information.
|
|
||||||
*/
|
|
||||||
PLAINTEXT_CONTENT = 8; // content => (marker byte | Content)
|
|
||||||
|
|
||||||
// next: 9
|
|
||||||
}
|
}
|
||||||
|
|
||||||
optional Type type = 1;
|
optional Type type = 1;
|
||||||
reserved 2; // formerly optional string sourceE164 = 2;
|
reserved 2; // formerly optional string sourceE164 = 2;
|
||||||
optional string sourceServiceId = 11;
|
optional string sourceServiceId = 11;
|
||||||
optional uint32 sourceDeviceId = 7;
|
optional uint32 sourceDevice = 7;
|
||||||
optional string destinationServiceId = 13;
|
optional string destinationServiceId = 13;
|
||||||
reserved 3; // formerly optional string relay = 3;
|
reserved 3; // formerly optional string relay = 3;
|
||||||
optional uint64 clientTimestamp = 5;
|
optional uint64 timestamp = 5;
|
||||||
reserved 6; // formerly optional bytes legacyMessage = 6; // Contains an encrypted DataMessage; this field could have been set historically for type 1 or 3 messages; no longer in use
|
reserved 6; // formerly optional bytes legacyMessage = 6; // Contains an encrypted DataMessage; this field could have been set historically for type 1 or 3 messages; no longer in use
|
||||||
optional bytes content = 8; // Contains an encrypted Content
|
optional bytes content = 8; // Contains an encrypted Content
|
||||||
optional string serverGuid = 9;
|
optional string serverGuid = 9;
|
||||||
|
|
@ -104,20 +48,17 @@ message Envelope {
|
||||||
}
|
}
|
||||||
|
|
||||||
message Content {
|
message Content {
|
||||||
oneof content {
|
optional DataMessage dataMessage = 1;
|
||||||
DataMessage dataMessage = 1;
|
optional SyncMessage syncMessage = 2;
|
||||||
SyncMessage syncMessage = 2;
|
optional CallMessage callMessage = 3;
|
||||||
CallMessage callMessage = 3;
|
optional NullMessage nullMessage = 4;
|
||||||
NullMessage nullMessage = 4;
|
optional ReceiptMessage receiptMessage = 5;
|
||||||
ReceiptMessage receiptMessage = 5;
|
optional TypingMessage typingMessage = 6;
|
||||||
TypingMessage typingMessage = 6;
|
|
||||||
bytes /* DecryptionErrorMessage */ decryptionErrorMessage = 8;
|
|
||||||
StoryMessage storyMessage = 9;
|
|
||||||
EditMessage editMessage = 11;
|
|
||||||
}
|
|
||||||
|
|
||||||
optional bytes /* SenderKeyDistributionMessage */ senderKeyDistributionMessage = 7;
|
optional bytes /* SenderKeyDistributionMessage */ senderKeyDistributionMessage = 7;
|
||||||
|
optional bytes /* DecryptionErrorMessage */ decryptionErrorMessage = 8;
|
||||||
|
optional StoryMessage storyMessage = 9;
|
||||||
optional PniSignatureMessage pniSignatureMessage = 10;
|
optional PniSignatureMessage pniSignatureMessage = 10;
|
||||||
|
optional EditMessage editMessage = 11;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CallMessage {
|
message CallMessage {
|
||||||
|
|
@ -187,7 +128,7 @@ message CallMessage {
|
||||||
|
|
||||||
message DataMessage {
|
message DataMessage {
|
||||||
enum Flags {
|
enum Flags {
|
||||||
reserved /*END_SESSION*/ 1;
|
END_SESSION = 1;
|
||||||
EXPIRATION_TIMER_UPDATE = 2;
|
EXPIRATION_TIMER_UPDATE = 2;
|
||||||
PROFILE_KEY_UPDATE = 4;
|
PROFILE_KEY_UPDATE = 4;
|
||||||
FORWARD = 8;
|
FORWARD = 8;
|
||||||
|
|
@ -390,8 +331,8 @@ message DataMessage {
|
||||||
message PollVote {
|
message PollVote {
|
||||||
optional bytes targetAuthorAciBinary = 1;
|
optional bytes targetAuthorAciBinary = 1;
|
||||||
optional uint64 targetSentTimestamp = 2;
|
optional uint64 targetSentTimestamp = 2;
|
||||||
repeated uint32 optionIndexes = 3;
|
repeated uint32 optionIndexes = 3; // must be in the range [0, options.length) from the PollCreate
|
||||||
optional uint32 voteCount = 4;
|
optional uint32 voteCount = 4; // increment this by 1 each time you vote on a given poll
|
||||||
}
|
}
|
||||||
|
|
||||||
message PinMessage {
|
message PinMessage {
|
||||||
|
|
@ -408,11 +349,6 @@ message DataMessage {
|
||||||
optional uint64 targetSentTimestamp = 2;
|
optional uint64 targetSentTimestamp = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AdminDelete {
|
|
||||||
optional bytes targetAuthorAciBinary = 1; // 16-byte UUID
|
|
||||||
optional uint64 targetSentTimestamp = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
optional string body = 1;
|
optional string body = 1;
|
||||||
repeated AttachmentPointer attachments = 2;
|
repeated AttachmentPointer attachments = 2;
|
||||||
reserved /*groupV1*/ 3;
|
reserved /*groupV1*/ 3;
|
||||||
|
|
@ -440,8 +376,7 @@ message DataMessage {
|
||||||
optional PollVote pollVote = 26;
|
optional PollVote pollVote = 26;
|
||||||
optional PinMessage pinMessage = 27;
|
optional PinMessage pinMessage = 27;
|
||||||
optional UnpinMessage unpinMessage = 28;
|
optional UnpinMessage unpinMessage = 28;
|
||||||
optional AdminDelete adminDelete = 29;
|
// NEXT ID: 29
|
||||||
// NEXT ID: 30
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message NullMessage {
|
message NullMessage {
|
||||||
|
|
@ -500,12 +435,6 @@ message TextAttachment {
|
||||||
}
|
}
|
||||||
|
|
||||||
message Gradient {
|
message Gradient {
|
||||||
// Color ordering:
|
|
||||||
// 0 degrees: bottom-to-top
|
|
||||||
// 90 degrees: left-to-right
|
|
||||||
// 180 degrees: top-to-bottom
|
|
||||||
// 270 degrees: right-to-left
|
|
||||||
|
|
||||||
optional uint32 startColor = 1; // deprecated: this field will be removed in a future release.
|
optional uint32 startColor = 1; // deprecated: this field will be removed in a future release.
|
||||||
optional uint32 endColor = 2; // deprecated: this field will be removed in a future release.
|
optional uint32 endColor = 2; // deprecated: this field will be removed in a future release.
|
||||||
optional uint32 angle = 3; // degrees
|
optional uint32 angle = 3; // degrees
|
||||||
|
|
@ -579,29 +508,10 @@ message SyncMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
message Blocked {
|
message Blocked {
|
||||||
repeated string numbers = 1; // deprecated: this field will be removed in a future release.
|
repeated string numbers = 1;
|
||||||
repeated string acis = 3;
|
repeated string acis = 3;
|
||||||
repeated bytes groupIds = 2; // deprecated: this field will be removed in a future release.
|
repeated bytes groupIds = 2;
|
||||||
repeated bytes acisBinary = 4; // deprecated: this field will be removed in a future release.
|
repeated bytes acisBinary = 4; // 16-byte UUID
|
||||||
|
|
||||||
message BlockedE164 {
|
|
||||||
optional string e164 = 1;
|
|
||||||
optional uint64 timestamp = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message BlockedAci {
|
|
||||||
optional bytes aciBinary = 1; // 16-byte UUID
|
|
||||||
optional uint64 timestamp = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
message BlockedGroup {
|
|
||||||
optional bytes groupId = 1;
|
|
||||||
optional uint64 timestamp = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
repeated BlockedE164 blockedE164s = 5;
|
|
||||||
repeated BlockedAci blockedAcis = 6;
|
|
||||||
repeated BlockedGroup blockedGroups = 7;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message Request {
|
message Request {
|
||||||
|
|
@ -637,7 +547,7 @@ message SyncMessage {
|
||||||
optional bool unidentifiedDeliveryIndicators = 2;
|
optional bool unidentifiedDeliveryIndicators = 2;
|
||||||
optional bool typingIndicators = 3;
|
optional bool typingIndicators = 3;
|
||||||
reserved /* linkPreviews */ 4;
|
reserved /* linkPreviews */ 4;
|
||||||
reserved /* provisioningVersion */ 5;
|
optional uint32 provisioningVersion = 5;
|
||||||
optional bool linkPreviews = 6;
|
optional bool linkPreviews = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -672,7 +582,7 @@ message SyncMessage {
|
||||||
|
|
||||||
message Keys {
|
message Keys {
|
||||||
reserved /* storageService */ 1;
|
reserved /* storageService */ 1;
|
||||||
reserved /* master */ 2;
|
optional bytes master = 2; // deprecated: this field will be removed in a future release.
|
||||||
optional string accountEntropyPool = 3;
|
optional string accountEntropyPool = 3;
|
||||||
optional bytes mediaRootBackupKey = 4;
|
optional bytes mediaRootBackupKey = 4;
|
||||||
}
|
}
|
||||||
|
|
@ -772,7 +682,7 @@ message SyncMessage {
|
||||||
optional bytes rootKey = 1;
|
optional bytes rootKey = 1;
|
||||||
optional bytes adminPasskey = 2;
|
optional bytes adminPasskey = 2;
|
||||||
optional Type type = 3; // defaults to UPDATE
|
optional Type type = 3; // defaults to UPDATE
|
||||||
reserved /*epoch*/ 4;
|
optional bytes epoch = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CallLogEvent {
|
message CallLogEvent {
|
||||||
|
|
@ -869,43 +779,31 @@ message SyncMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
message UsernameChange {}
|
optional Sent sent = 1;
|
||||||
|
optional Contacts contacts = 2;
|
||||||
oneof content {
|
|
||||||
Sent sent = 1;
|
|
||||||
Contacts contacts = 2;
|
|
||||||
Request request = 4;
|
|
||||||
Blocked blocked = 6;
|
|
||||||
Verified verified = 7;
|
|
||||||
Configuration configuration = 9;
|
|
||||||
ViewOnceOpen viewOnceOpen = 11;
|
|
||||||
FetchLatest fetchLatest = 12;
|
|
||||||
Keys keys = 13;
|
|
||||||
MessageRequestResponse messageRequestResponse = 14;
|
|
||||||
OutgoingPayment outgoingPayment = 15;
|
|
||||||
PniChangeNumber pniChangeNumber = 18;
|
|
||||||
CallEvent callEvent = 19;
|
|
||||||
CallLinkUpdate callLinkUpdate = 20;
|
|
||||||
CallLogEvent callLogEvent = 21;
|
|
||||||
DeleteForMe deleteForMe = 22;
|
|
||||||
DeviceNameChange deviceNameChange = 23;
|
|
||||||
AttachmentBackfillRequest attachmentBackfillRequest = 24;
|
|
||||||
AttachmentBackfillResponse attachmentBackfillResponse = 25;
|
|
||||||
UsernameChange usernameChange = 26;
|
|
||||||
}
|
|
||||||
|
|
||||||
reserved /*groups*/ 3;
|
reserved /*groups*/ 3;
|
||||||
|
optional Request request = 4;
|
||||||
// Protobufs don't allow `repeated` fields to be inside of `oneof` so while
|
|
||||||
// the fields below are mutually exclusive with the rest of the values above
|
|
||||||
// we have to place them outside of `oneof`.
|
|
||||||
repeated Read read = 5;
|
repeated Read read = 5;
|
||||||
repeated StickerPackOperation stickerPackOperation = 10;
|
optional Blocked blocked = 6;
|
||||||
repeated Viewed viewed = 16;
|
optional Verified verified = 7;
|
||||||
|
optional Configuration configuration = 9;
|
||||||
reserved /*pniIdentity*/ 17;
|
|
||||||
|
|
||||||
optional bytes padding = 8;
|
optional bytes padding = 8;
|
||||||
|
repeated StickerPackOperation stickerPackOperation = 10;
|
||||||
|
optional ViewOnceOpen viewOnceOpen = 11;
|
||||||
|
optional FetchLatest fetchLatest = 12;
|
||||||
|
optional Keys keys = 13;
|
||||||
|
optional MessageRequestResponse messageRequestResponse = 14;
|
||||||
|
optional OutgoingPayment outgoingPayment = 15;
|
||||||
|
repeated Viewed viewed = 16;
|
||||||
|
reserved /*pniIdentity*/ 17;
|
||||||
|
optional PniChangeNumber pniChangeNumber = 18;
|
||||||
|
optional CallEvent callEvent = 19;
|
||||||
|
optional CallLinkUpdate callLinkUpdate = 20;
|
||||||
|
optional CallLogEvent callLogEvent = 21;
|
||||||
|
optional DeleteForMe deleteForMe = 22;
|
||||||
|
optional DeviceNameChange deviceNameChange = 23;
|
||||||
|
optional AttachmentBackfillRequest attachmentBackfillRequest = 24;
|
||||||
|
optional AttachmentBackfillResponse attachmentBackfillResponse = 25;
|
||||||
}
|
}
|
||||||
|
|
||||||
message AttachmentPointer {
|
message AttachmentPointer {
|
||||||
|
|
@ -6,8 +6,8 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.11
|
// protoc-gen-go v1.36.11
|
||||||
// protoc v7.34.1
|
// protoc v6.33.5
|
||||||
// source: signalpb/StickerResources.proto
|
// source: StickerResources.proto
|
||||||
|
|
||||||
package signalpb
|
package signalpb
|
||||||
|
|
||||||
|
|
@ -38,7 +38,7 @@ type Pack struct {
|
||||||
|
|
||||||
func (x *Pack) Reset() {
|
func (x *Pack) Reset() {
|
||||||
*x = Pack{}
|
*x = Pack{}
|
||||||
mi := &file_signalpb_StickerResources_proto_msgTypes[0]
|
mi := &file_StickerResources_proto_msgTypes[0]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
|
|
@ -50,7 +50,7 @@ func (x *Pack) String() string {
|
||||||
func (*Pack) ProtoMessage() {}
|
func (*Pack) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *Pack) ProtoReflect() protoreflect.Message {
|
func (x *Pack) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_signalpb_StickerResources_proto_msgTypes[0]
|
mi := &file_StickerResources_proto_msgTypes[0]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
|
@ -63,7 +63,7 @@ func (x *Pack) ProtoReflect() protoreflect.Message {
|
||||||
|
|
||||||
// Deprecated: Use Pack.ProtoReflect.Descriptor instead.
|
// Deprecated: Use Pack.ProtoReflect.Descriptor instead.
|
||||||
func (*Pack) Descriptor() ([]byte, []int) {
|
func (*Pack) Descriptor() ([]byte, []int) {
|
||||||
return file_signalpb_StickerResources_proto_rawDescGZIP(), []int{0}
|
return file_StickerResources_proto_rawDescGZIP(), []int{0}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *Pack) GetTitle() string {
|
func (x *Pack) GetTitle() string {
|
||||||
|
|
@ -105,7 +105,7 @@ type Pack_Sticker struct {
|
||||||
|
|
||||||
func (x *Pack_Sticker) Reset() {
|
func (x *Pack_Sticker) Reset() {
|
||||||
*x = Pack_Sticker{}
|
*x = Pack_Sticker{}
|
||||||
mi := &file_signalpb_StickerResources_proto_msgTypes[1]
|
mi := &file_StickerResources_proto_msgTypes[1]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
|
|
@ -117,7 +117,7 @@ func (x *Pack_Sticker) String() string {
|
||||||
func (*Pack_Sticker) ProtoMessage() {}
|
func (*Pack_Sticker) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *Pack_Sticker) ProtoReflect() protoreflect.Message {
|
func (x *Pack_Sticker) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_signalpb_StickerResources_proto_msgTypes[1]
|
mi := &file_StickerResources_proto_msgTypes[1]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
|
@ -130,7 +130,7 @@ func (x *Pack_Sticker) ProtoReflect() protoreflect.Message {
|
||||||
|
|
||||||
// Deprecated: Use Pack_Sticker.ProtoReflect.Descriptor instead.
|
// Deprecated: Use Pack_Sticker.ProtoReflect.Descriptor instead.
|
||||||
func (*Pack_Sticker) Descriptor() ([]byte, []int) {
|
func (*Pack_Sticker) Descriptor() ([]byte, []int) {
|
||||||
return file_signalpb_StickerResources_proto_rawDescGZIP(), []int{0, 0}
|
return file_StickerResources_proto_rawDescGZIP(), []int{0, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *Pack_Sticker) GetId() uint32 {
|
func (x *Pack_Sticker) GetId() uint32 {
|
||||||
|
|
@ -154,11 +154,11 @@ func (x *Pack_Sticker) GetContentType() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
var File_signalpb_StickerResources_proto protoreflect.FileDescriptor
|
var File_StickerResources_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
const file_signalpb_StickerResources_proto_rawDesc = "" +
|
const file_StickerResources_proto_rawDesc = "" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"\x1fsignalpb/StickerResources.proto\x12\rsignalservice\"\xf3\x01\n" +
|
"\x16StickerResources.proto\x12\rsignalservice\"\xf3\x01\n" +
|
||||||
"\x04Pack\x12\x14\n" +
|
"\x04Pack\x12\x14\n" +
|
||||||
"\x05title\x18\x01 \x01(\tR\x05title\x12\x16\n" +
|
"\x05title\x18\x01 \x01(\tR\x05title\x12\x16\n" +
|
||||||
"\x06author\x18\x02 \x01(\tR\x06author\x121\n" +
|
"\x06author\x18\x02 \x01(\tR\x06author\x121\n" +
|
||||||
|
|
@ -171,23 +171,23 @@ const file_signalpb_StickerResources_proto_rawDesc = "" +
|
||||||
"1org.whispersystems.signalservice.internal.stickerB\rStickerProtos"
|
"1org.whispersystems.signalservice.internal.stickerB\rStickerProtos"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
file_signalpb_StickerResources_proto_rawDescOnce sync.Once
|
file_StickerResources_proto_rawDescOnce sync.Once
|
||||||
file_signalpb_StickerResources_proto_rawDescData []byte
|
file_StickerResources_proto_rawDescData []byte
|
||||||
)
|
)
|
||||||
|
|
||||||
func file_signalpb_StickerResources_proto_rawDescGZIP() []byte {
|
func file_StickerResources_proto_rawDescGZIP() []byte {
|
||||||
file_signalpb_StickerResources_proto_rawDescOnce.Do(func() {
|
file_StickerResources_proto_rawDescOnce.Do(func() {
|
||||||
file_signalpb_StickerResources_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_signalpb_StickerResources_proto_rawDesc), len(file_signalpb_StickerResources_proto_rawDesc)))
|
file_StickerResources_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_StickerResources_proto_rawDesc), len(file_StickerResources_proto_rawDesc)))
|
||||||
})
|
})
|
||||||
return file_signalpb_StickerResources_proto_rawDescData
|
return file_StickerResources_proto_rawDescData
|
||||||
}
|
}
|
||||||
|
|
||||||
var file_signalpb_StickerResources_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
var file_StickerResources_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||||
var file_signalpb_StickerResources_proto_goTypes = []any{
|
var file_StickerResources_proto_goTypes = []any{
|
||||||
(*Pack)(nil), // 0: signalservice.Pack
|
(*Pack)(nil), // 0: signalservice.Pack
|
||||||
(*Pack_Sticker)(nil), // 1: signalservice.Pack.Sticker
|
(*Pack_Sticker)(nil), // 1: signalservice.Pack.Sticker
|
||||||
}
|
}
|
||||||
var file_signalpb_StickerResources_proto_depIdxs = []int32{
|
var file_StickerResources_proto_depIdxs = []int32{
|
||||||
1, // 0: signalservice.Pack.cover:type_name -> signalservice.Pack.Sticker
|
1, // 0: signalservice.Pack.cover:type_name -> signalservice.Pack.Sticker
|
||||||
1, // 1: signalservice.Pack.stickers:type_name -> signalservice.Pack.Sticker
|
1, // 1: signalservice.Pack.stickers:type_name -> signalservice.Pack.Sticker
|
||||||
2, // [2:2] is the sub-list for method output_type
|
2, // [2:2] is the sub-list for method output_type
|
||||||
|
|
@ -197,26 +197,26 @@ var file_signalpb_StickerResources_proto_depIdxs = []int32{
|
||||||
0, // [0:2] is the sub-list for field type_name
|
0, // [0:2] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_signalpb_StickerResources_proto_init() }
|
func init() { file_StickerResources_proto_init() }
|
||||||
func file_signalpb_StickerResources_proto_init() {
|
func file_StickerResources_proto_init() {
|
||||||
if File_signalpb_StickerResources_proto != nil {
|
if File_StickerResources_proto != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
type x struct{}
|
type x struct{}
|
||||||
out := protoimpl.TypeBuilder{
|
out := protoimpl.TypeBuilder{
|
||||||
File: protoimpl.DescBuilder{
|
File: protoimpl.DescBuilder{
|
||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_signalpb_StickerResources_proto_rawDesc), len(file_signalpb_StickerResources_proto_rawDesc)),
|
RawDescriptor: unsafe.Slice(unsafe.StringData(file_StickerResources_proto_rawDesc), len(file_StickerResources_proto_rawDesc)),
|
||||||
NumEnums: 0,
|
NumEnums: 0,
|
||||||
NumMessages: 2,
|
NumMessages: 2,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 0,
|
NumServices: 0,
|
||||||
},
|
},
|
||||||
GoTypes: file_signalpb_StickerResources_proto_goTypes,
|
GoTypes: file_StickerResources_proto_goTypes,
|
||||||
DependencyIndexes: file_signalpb_StickerResources_proto_depIdxs,
|
DependencyIndexes: file_StickerResources_proto_depIdxs,
|
||||||
MessageInfos: file_signalpb_StickerResources_proto_msgTypes,
|
MessageInfos: file_StickerResources_proto_msgTypes,
|
||||||
}.Build()
|
}.Build()
|
||||||
File_signalpb_StickerResources_proto = out.File
|
File_StickerResources_proto = out.File
|
||||||
file_signalpb_StickerResources_proto_goTypes = nil
|
file_StickerResources_proto_goTypes = nil
|
||||||
file_signalpb_StickerResources_proto_depIdxs = nil
|
file_StickerResources_proto_depIdxs = nil
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/**
|
||||||
* Copyright 2020-2021 Signal Messenger, LLC
|
* Copyright (C) 2019 Open Whisper Systems
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
*
|
||||||
|
* Licensed according to the LICENSE file in this repository.
|
||||||
*/
|
*/
|
||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
|
|
||||||
|
|
@ -49,7 +50,6 @@ message ManifestRecord {
|
||||||
GROUPV2 = 3;
|
GROUPV2 = 3;
|
||||||
ACCOUNT = 4;
|
ACCOUNT = 4;
|
||||||
STORY_DISTRIBUTION_LIST = 5;
|
STORY_DISTRIBUTION_LIST = 5;
|
||||||
STICKER_PACK = 6;
|
|
||||||
CALL_LINK = 7;
|
CALL_LINK = 7;
|
||||||
CHAT_FOLDER = 8;
|
CHAT_FOLDER = 8;
|
||||||
NOTIFICATION_PROFILE = 9;
|
NOTIFICATION_PROFILE = 9;
|
||||||
|
|
@ -73,7 +73,6 @@ message StorageRecord {
|
||||||
GroupV2Record groupV2 = 3;
|
GroupV2Record groupV2 = 3;
|
||||||
AccountRecord account = 4;
|
AccountRecord account = 4;
|
||||||
StoryDistributionListRecord storyDistributionList = 5;
|
StoryDistributionListRecord storyDistributionList = 5;
|
||||||
StickerPackRecord stickerPack = 6;
|
|
||||||
CallLinkRecord callLink = 7;
|
CallLinkRecord callLink = 7;
|
||||||
ChatFolderRecord chatFolder = 8;
|
ChatFolderRecord chatFolder = 8;
|
||||||
NotificationProfile notificationProfile = 9;
|
NotificationProfile notificationProfile = 9;
|
||||||
|
|
@ -143,10 +142,7 @@ message ContactRecord {
|
||||||
optional AvatarColor avatarColor = 24;
|
optional AvatarColor avatarColor = 24;
|
||||||
bytes aciBinary = 25; // 16-byte UUID
|
bytes aciBinary = 25; // 16-byte UUID
|
||||||
bytes pniBinary = 26; // 16-byte UUID
|
bytes pniBinary = 26; // 16-byte UUID
|
||||||
uint64 blockedAtTimestamp = 27; // 0 means the blocked time is unknown
|
// Next ID: 27
|
||||||
OptionalBool notifyForCallsIfMuted = 28; // If unset, use the default settings
|
|
||||||
OptionalBool showUnreadReminders = 29; // If unset, use the default settings
|
|
||||||
// Next ID: 30
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message GroupV1Record {
|
message GroupV1Record {
|
||||||
|
|
@ -171,17 +167,11 @@ message GroupV2Record {
|
||||||
bool archived = 4;
|
bool archived = 4;
|
||||||
bool markedUnread = 5;
|
bool markedUnread = 5;
|
||||||
uint64 mutedUntilTimestamp = 6;
|
uint64 mutedUntilTimestamp = 6;
|
||||||
bool dontNotifyForMentionsIfMuted = 7; // will be deprecated in favor of [notifyForMentionsIfMuted]
|
bool dontNotifyForMentionsIfMuted = 7;
|
||||||
bool hideStory = 8;
|
bool hideStory = 8;
|
||||||
reserved /* storySendEnabled */ 9;
|
reserved /* storySendEnabled */ 9;
|
||||||
StorySendMode storySendMode = 10;
|
StorySendMode storySendMode = 10;
|
||||||
optional AvatarColor avatarColor = 11;
|
optional AvatarColor avatarColor = 11;
|
||||||
bytes verifiedNameHash = 12; // SHA-256 of UTF-8 encoded decrypted group title that was last verified
|
|
||||||
uint64 blockedAtTimestamp = 13; // 0 means the blocked time is unknown
|
|
||||||
OptionalBool notifyForCallsIfMuted = 14; // If unset, use the default settings
|
|
||||||
OptionalBool notifyForMentionsIfMuted = 15; // If unset, use the default settings. If [dontNotifyForMentionsIfMuted] is true, this should be initialized to false.
|
|
||||||
OptionalBool notifyForRepliesIfMuted = 16; // If unset, use the default settings
|
|
||||||
OptionalBool showUnreadReminders = 17; // If unset, use the default settings
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message Payments {
|
message Payments {
|
||||||
|
|
@ -191,12 +181,6 @@ message Payments {
|
||||||
|
|
||||||
message AccountRecord {
|
message AccountRecord {
|
||||||
|
|
||||||
enum UnreadBadgeType {
|
|
||||||
UNKNOWN_BADGE_TYPE = 0; // Interpret as "Unread messages"
|
|
||||||
UNREAD_MESSAGES = 1;
|
|
||||||
UNREAD_CHATS = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum PhoneNumberSharingMode {
|
enum PhoneNumberSharingMode {
|
||||||
UNKNOWN = 0;
|
UNKNOWN = 0;
|
||||||
EVERYBODY = 1;
|
EVERYBODY = 1;
|
||||||
|
|
@ -210,13 +194,10 @@ message AccountRecord {
|
||||||
bytes serviceIdBinary = 3; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI)
|
bytes serviceIdBinary = 3; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI)
|
||||||
}
|
}
|
||||||
|
|
||||||
message ReleaseNotes {}
|
|
||||||
|
|
||||||
oneof identifier {
|
oneof identifier {
|
||||||
Contact contact = 1;
|
Contact contact = 1;
|
||||||
bytes legacyGroupId = 3;
|
bytes legacyGroupId = 3;
|
||||||
bytes groupMasterKey = 4;
|
bytes groupMasterKey = 4;
|
||||||
ReleaseNotes releaseNotes = 5;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -249,6 +230,12 @@ message AccountRecord {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message BackupTierHistory {
|
||||||
|
// See zkgroup for integer particular values. Unset if backups are not enabled.
|
||||||
|
optional uint64 backupTier = 1;
|
||||||
|
optional uint64 endedAtTimestamp = 2;
|
||||||
|
}
|
||||||
|
|
||||||
message NotificationProfileManualOverride {
|
message NotificationProfileManualOverride {
|
||||||
message ManuallyEnabled {
|
message ManuallyEnabled {
|
||||||
bytes id = 1;
|
bytes id = 1;
|
||||||
|
|
@ -301,28 +288,14 @@ message AccountRecord {
|
||||||
reserved /* backupsSubscriberId */ 36;
|
reserved /* backupsSubscriberId */ 36;
|
||||||
reserved /* backupsSubscriberCurrencyCode */ 37;
|
reserved /* backupsSubscriberCurrencyCode */ 37;
|
||||||
reserved /* backupsSubscriptionManuallyCancelled */ 38;
|
reserved /* backupsSubscriptionManuallyCancelled */ 38;
|
||||||
reserved /* hasBackup */ 39;
|
optional bool hasBackup = 39; // Set to true after backups are enabled and one is uploaded.
|
||||||
optional uint64 backupTier = 40; // See zkgroup for integer particular values. Unset if backups are not enabled.
|
optional uint64 backupTier = 40; // See zkgroup for integer particular values. Unset if backups are not enabled.
|
||||||
IAPSubscriberData backupSubscriberData = 41;
|
IAPSubscriberData backupSubscriberData = 41;
|
||||||
optional AvatarColor avatarColor = 42;
|
optional AvatarColor avatarColor = 42;
|
||||||
reserved /* backupTierHistory */ 43;
|
BackupTierHistory backupTierHistory = 43;
|
||||||
NotificationProfileManualOverride notificationProfileManualOverride = 44;
|
NotificationProfileManualOverride notificationProfileManualOverride = 44;
|
||||||
bool notificationProfileSyncDisabled = 45;
|
bool notificationProfileSyncDisabled = 45;
|
||||||
bool automaticKeyVerificationDisabled = 46;
|
bool automaticKeyVerificationDisabled = 46;
|
||||||
bool hasSeenAdminDeleteEducationDialog = 47;
|
|
||||||
optional bool releaseNotesChatArchived = 48;
|
|
||||||
optional uint64 releaseNotesChatMutedUntilTimestamp = 49;
|
|
||||||
optional bool releaseNotesChatBlocked = 50;
|
|
||||||
optional bool releaseNotesChatMarkedUnread = 51;
|
|
||||||
optional uint64 releaseNotesChatBlockedAt = 52; // only set if known (>0)
|
|
||||||
UnreadBadgeType unreadBadgeType = 53; // Only used in desktop/ios
|
|
||||||
OptionalBool includeMutedChatsInBadge = 54; // Only used in desktop/ios. If unset, consider this off. Only used in desktop/ios
|
|
||||||
OptionalBool reactionNotifications = 55; // If unset, consider this on
|
|
||||||
OptionalBool notifyForCallsIfMuted = 56; // If unset, consider this off
|
|
||||||
OptionalBool notifyForMentionsIfMuted = 57; // If unset, consider this on
|
|
||||||
OptionalBool notifyForRepliesIfMuted = 58; // If unset, consider this on
|
|
||||||
OptionalBool showUnreadReminders = 59; // If unset, consider this on
|
|
||||||
OptionalBool notifyWhenContactJoins = 60; // If unset, consider this off
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message StoryDistributionListRecord {
|
message StoryDistributionListRecord {
|
||||||
|
|
@ -335,32 +308,11 @@ message StoryDistributionListRecord {
|
||||||
repeated bytes recipientServiceIdsBinary = 7; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI)
|
repeated bytes recipientServiceIdsBinary = 7; // service ID binary (i.e. 16 byte UUID for ACI, 1 byte prefix + 16 byte UUID for PNI)
|
||||||
}
|
}
|
||||||
|
|
||||||
message StickerPackRecord {
|
|
||||||
bytes packId = 1; // 16 bytes
|
|
||||||
bytes packKey = 2; // 32 bytes, used to derive the AES-256 key
|
|
||||||
// aesKey = HKDF(
|
|
||||||
// input = packKey,
|
|
||||||
// salt = 32 zero bytes,
|
|
||||||
// info = "Sticker Pack"
|
|
||||||
// )
|
|
||||||
uint32 position = 3; // When displayed sticker packs should be first sorted
|
|
||||||
// in ascending order by zero-based `position` and
|
|
||||||
// then by ascending `packId` (lexicographically,
|
|
||||||
// packId can be treated as a hex string).
|
|
||||||
// When installing a sticker pack the client should find
|
|
||||||
// the maximum `position` among currently known stickers
|
|
||||||
// and use `max_position + 1` as the value for the new
|
|
||||||
// `position`.
|
|
||||||
uint64 deletedAtTimestamp = 4; // Timestamp in milliseconds. When present and
|
|
||||||
// non-zero - `packKey` and `position` should
|
|
||||||
// be unset
|
|
||||||
}
|
|
||||||
|
|
||||||
message CallLinkRecord {
|
message CallLinkRecord {
|
||||||
bytes rootKey = 1;
|
bytes rootKey = 1;
|
||||||
bytes adminPasskey = 2;
|
bytes adminPasskey = 2;
|
||||||
uint64 deletedAtTimestampMs = 3;
|
uint64 deletedAtTimestampMs = 3;
|
||||||
reserved 4; // was epoch field, never used
|
optional bytes epoch = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Recipient {
|
message Recipient {
|
||||||
635
pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go
generated
Normal file
635
pkg/signalmeow/protobuf/UnidentifiedDelivery.pb.go
generated
Normal file
|
|
@ -0,0 +1,635 @@
|
||||||
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// protoc-gen-go v1.36.11
|
||||||
|
// protoc v6.33.5
|
||||||
|
// source: UnidentifiedDelivery.proto
|
||||||
|
|
||||||
|
// Copyright 2018 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
package signalpb
|
||||||
|
|
||||||
|
import (
|
||||||
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||||
|
reflect "reflect"
|
||||||
|
sync "sync"
|
||||||
|
unsafe "unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Verify that this generated code is sufficiently up-to-date.
|
||||||
|
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||||
|
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||||
|
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||||
|
)
|
||||||
|
|
||||||
|
type UnidentifiedSenderMessage_Message_Type int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Our parser does not handle reserved in enums: DESKTOP-1569
|
||||||
|
// reserved 1;
|
||||||
|
UnidentifiedSenderMessage_Message_MESSAGE UnidentifiedSenderMessage_Message_Type = 2
|
||||||
|
UnidentifiedSenderMessage_Message_PREKEY_MESSAGE UnidentifiedSenderMessage_Message_Type = 3 // Further cases should line up with Envelope.Type, even though old cases don't.
|
||||||
|
UnidentifiedSenderMessage_Message_SENDERKEY_MESSAGE UnidentifiedSenderMessage_Message_Type = 7
|
||||||
|
UnidentifiedSenderMessage_Message_PLAINTEXT_CONTENT UnidentifiedSenderMessage_Message_Type = 8
|
||||||
|
)
|
||||||
|
|
||||||
|
// Enum value maps for UnidentifiedSenderMessage_Message_Type.
|
||||||
|
var (
|
||||||
|
UnidentifiedSenderMessage_Message_Type_name = map[int32]string{
|
||||||
|
2: "MESSAGE",
|
||||||
|
3: "PREKEY_MESSAGE",
|
||||||
|
7: "SENDERKEY_MESSAGE",
|
||||||
|
8: "PLAINTEXT_CONTENT",
|
||||||
|
}
|
||||||
|
UnidentifiedSenderMessage_Message_Type_value = map[string]int32{
|
||||||
|
"MESSAGE": 2,
|
||||||
|
"PREKEY_MESSAGE": 3,
|
||||||
|
"SENDERKEY_MESSAGE": 7,
|
||||||
|
"PLAINTEXT_CONTENT": 8,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (x UnidentifiedSenderMessage_Message_Type) Enum() *UnidentifiedSenderMessage_Message_Type {
|
||||||
|
p := new(UnidentifiedSenderMessage_Message_Type)
|
||||||
|
*p = x
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x UnidentifiedSenderMessage_Message_Type) String() string {
|
||||||
|
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (UnidentifiedSenderMessage_Message_Type) Descriptor() protoreflect.EnumDescriptor {
|
||||||
|
return file_UnidentifiedDelivery_proto_enumTypes[0].Descriptor()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (UnidentifiedSenderMessage_Message_Type) Type() protoreflect.EnumType {
|
||||||
|
return &file_UnidentifiedDelivery_proto_enumTypes[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x UnidentifiedSenderMessage_Message_Type) Number() protoreflect.EnumNumber {
|
||||||
|
return protoreflect.EnumNumber(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Do not use.
|
||||||
|
func (x *UnidentifiedSenderMessage_Message_Type) UnmarshalJSON(b []byte) error {
|
||||||
|
num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*x = UnidentifiedSenderMessage_Message_Type(num)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use UnidentifiedSenderMessage_Message_Type.Descriptor instead.
|
||||||
|
func (UnidentifiedSenderMessage_Message_Type) EnumDescriptor() ([]byte, []int) {
|
||||||
|
return file_UnidentifiedDelivery_proto_rawDescGZIP(), []int{2, 0, 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
type UnidentifiedSenderMessage_Message_ContentHint int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Show an error immediately; it was important but we can't retry.
|
||||||
|
UnidentifiedSenderMessage_Message_DEFAULT UnidentifiedSenderMessage_Message_ContentHint = 0
|
||||||
|
// Sender will try to resend; delay any error UI if possible
|
||||||
|
UnidentifiedSenderMessage_Message_RESENDABLE UnidentifiedSenderMessage_Message_ContentHint = 1
|
||||||
|
// Don't show any error UI at all; this is something sent implicitly like a typing message or a receipt
|
||||||
|
UnidentifiedSenderMessage_Message_IMPLICIT UnidentifiedSenderMessage_Message_ContentHint = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// Enum value maps for UnidentifiedSenderMessage_Message_ContentHint.
|
||||||
|
var (
|
||||||
|
UnidentifiedSenderMessage_Message_ContentHint_name = map[int32]string{
|
||||||
|
0: "DEFAULT",
|
||||||
|
1: "RESENDABLE",
|
||||||
|
2: "IMPLICIT",
|
||||||
|
}
|
||||||
|
UnidentifiedSenderMessage_Message_ContentHint_value = map[string]int32{
|
||||||
|
"DEFAULT": 0,
|
||||||
|
"RESENDABLE": 1,
|
||||||
|
"IMPLICIT": 2,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (x UnidentifiedSenderMessage_Message_ContentHint) Enum() *UnidentifiedSenderMessage_Message_ContentHint {
|
||||||
|
p := new(UnidentifiedSenderMessage_Message_ContentHint)
|
||||||
|
*p = x
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x UnidentifiedSenderMessage_Message_ContentHint) String() string {
|
||||||
|
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (UnidentifiedSenderMessage_Message_ContentHint) Descriptor() protoreflect.EnumDescriptor {
|
||||||
|
return file_UnidentifiedDelivery_proto_enumTypes[1].Descriptor()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (UnidentifiedSenderMessage_Message_ContentHint) Type() protoreflect.EnumType {
|
||||||
|
return &file_UnidentifiedDelivery_proto_enumTypes[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x UnidentifiedSenderMessage_Message_ContentHint) Number() protoreflect.EnumNumber {
|
||||||
|
return protoreflect.EnumNumber(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Do not use.
|
||||||
|
func (x *UnidentifiedSenderMessage_Message_ContentHint) UnmarshalJSON(b []byte) error {
|
||||||
|
num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*x = UnidentifiedSenderMessage_Message_ContentHint(num)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use UnidentifiedSenderMessage_Message_ContentHint.Descriptor instead.
|
||||||
|
func (UnidentifiedSenderMessage_Message_ContentHint) EnumDescriptor() ([]byte, []int) {
|
||||||
|
return file_UnidentifiedDelivery_proto_rawDescGZIP(), []int{2, 0, 1}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServerCertificate struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
Certificate []byte `protobuf:"bytes,1,opt,name=certificate" json:"certificate,omitempty"`
|
||||||
|
Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ServerCertificate) Reset() {
|
||||||
|
*x = ServerCertificate{}
|
||||||
|
mi := &file_UnidentifiedDelivery_proto_msgTypes[0]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ServerCertificate) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ServerCertificate) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *ServerCertificate) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_UnidentifiedDelivery_proto_msgTypes[0]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use ServerCertificate.ProtoReflect.Descriptor instead.
|
||||||
|
func (*ServerCertificate) Descriptor() ([]byte, []int) {
|
||||||
|
return file_UnidentifiedDelivery_proto_rawDescGZIP(), []int{0}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ServerCertificate) GetCertificate() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.Certificate
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ServerCertificate) GetSignature() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.Signature
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type SenderCertificate struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
Certificate []byte `protobuf:"bytes,1,opt,name=certificate" json:"certificate,omitempty"`
|
||||||
|
Signature []byte `protobuf:"bytes,2,opt,name=signature" json:"signature,omitempty"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SenderCertificate) Reset() {
|
||||||
|
*x = SenderCertificate{}
|
||||||
|
mi := &file_UnidentifiedDelivery_proto_msgTypes[1]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SenderCertificate) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*SenderCertificate) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *SenderCertificate) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_UnidentifiedDelivery_proto_msgTypes[1]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use SenderCertificate.ProtoReflect.Descriptor instead.
|
||||||
|
func (*SenderCertificate) Descriptor() ([]byte, []int) {
|
||||||
|
return file_UnidentifiedDelivery_proto_rawDescGZIP(), []int{1}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SenderCertificate) GetCertificate() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.Certificate
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SenderCertificate) GetSignature() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.Signature
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type UnidentifiedSenderMessage struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
EphemeralPublic []byte `protobuf:"bytes,1,opt,name=ephemeralPublic" json:"ephemeralPublic,omitempty"`
|
||||||
|
EncryptedStatic []byte `protobuf:"bytes,2,opt,name=encryptedStatic" json:"encryptedStatic,omitempty"`
|
||||||
|
EncryptedMessage []byte `protobuf:"bytes,3,opt,name=encryptedMessage" json:"encryptedMessage,omitempty"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *UnidentifiedSenderMessage) Reset() {
|
||||||
|
*x = UnidentifiedSenderMessage{}
|
||||||
|
mi := &file_UnidentifiedDelivery_proto_msgTypes[2]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *UnidentifiedSenderMessage) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*UnidentifiedSenderMessage) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *UnidentifiedSenderMessage) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_UnidentifiedDelivery_proto_msgTypes[2]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use UnidentifiedSenderMessage.ProtoReflect.Descriptor instead.
|
||||||
|
func (*UnidentifiedSenderMessage) Descriptor() ([]byte, []int) {
|
||||||
|
return file_UnidentifiedDelivery_proto_rawDescGZIP(), []int{2}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *UnidentifiedSenderMessage) GetEphemeralPublic() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.EphemeralPublic
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *UnidentifiedSenderMessage) GetEncryptedStatic() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.EncryptedStatic
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *UnidentifiedSenderMessage) GetEncryptedMessage() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.EncryptedMessage
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type ServerCertificate_Certificate struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
Id *uint32 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"`
|
||||||
|
Key []byte `protobuf:"bytes,2,opt,name=key" json:"key,omitempty"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ServerCertificate_Certificate) Reset() {
|
||||||
|
*x = ServerCertificate_Certificate{}
|
||||||
|
mi := &file_UnidentifiedDelivery_proto_msgTypes[3]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ServerCertificate_Certificate) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ServerCertificate_Certificate) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *ServerCertificate_Certificate) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_UnidentifiedDelivery_proto_msgTypes[3]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use ServerCertificate_Certificate.ProtoReflect.Descriptor instead.
|
||||||
|
func (*ServerCertificate_Certificate) Descriptor() ([]byte, []int) {
|
||||||
|
return file_UnidentifiedDelivery_proto_rawDescGZIP(), []int{0, 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ServerCertificate_Certificate) GetId() uint32 {
|
||||||
|
if x != nil && x.Id != nil {
|
||||||
|
return *x.Id
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ServerCertificate_Certificate) GetKey() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.Key
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type SenderCertificate_Certificate struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
SenderE164 *string `protobuf:"bytes,1,opt,name=senderE164" json:"senderE164,omitempty"`
|
||||||
|
SenderUuid *string `protobuf:"bytes,6,opt,name=senderUuid" json:"senderUuid,omitempty"`
|
||||||
|
SenderDevice *uint32 `protobuf:"varint,2,opt,name=senderDevice" json:"senderDevice,omitempty"`
|
||||||
|
Expires *uint64 `protobuf:"fixed64,3,opt,name=expires" json:"expires,omitempty"`
|
||||||
|
IdentityKey []byte `protobuf:"bytes,4,opt,name=identityKey" json:"identityKey,omitempty"`
|
||||||
|
Signer *ServerCertificate `protobuf:"bytes,5,opt,name=signer" json:"signer,omitempty"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SenderCertificate_Certificate) Reset() {
|
||||||
|
*x = SenderCertificate_Certificate{}
|
||||||
|
mi := &file_UnidentifiedDelivery_proto_msgTypes[4]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SenderCertificate_Certificate) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*SenderCertificate_Certificate) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *SenderCertificate_Certificate) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_UnidentifiedDelivery_proto_msgTypes[4]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use SenderCertificate_Certificate.ProtoReflect.Descriptor instead.
|
||||||
|
func (*SenderCertificate_Certificate) Descriptor() ([]byte, []int) {
|
||||||
|
return file_UnidentifiedDelivery_proto_rawDescGZIP(), []int{1, 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SenderCertificate_Certificate) GetSenderE164() string {
|
||||||
|
if x != nil && x.SenderE164 != nil {
|
||||||
|
return *x.SenderE164
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SenderCertificate_Certificate) GetSenderUuid() string {
|
||||||
|
if x != nil && x.SenderUuid != nil {
|
||||||
|
return *x.SenderUuid
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SenderCertificate_Certificate) GetSenderDevice() uint32 {
|
||||||
|
if x != nil && x.SenderDevice != nil {
|
||||||
|
return *x.SenderDevice
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SenderCertificate_Certificate) GetExpires() uint64 {
|
||||||
|
if x != nil && x.Expires != nil {
|
||||||
|
return *x.Expires
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SenderCertificate_Certificate) GetIdentityKey() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.IdentityKey
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SenderCertificate_Certificate) GetSigner() *ServerCertificate {
|
||||||
|
if x != nil {
|
||||||
|
return x.Signer
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type UnidentifiedSenderMessage_Message struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
Type *UnidentifiedSenderMessage_Message_Type `protobuf:"varint,1,opt,name=type,enum=signalservice.UnidentifiedSenderMessage_Message_Type" json:"type,omitempty"`
|
||||||
|
SenderCertificate *SenderCertificate `protobuf:"bytes,2,opt,name=senderCertificate" json:"senderCertificate,omitempty"`
|
||||||
|
Content []byte `protobuf:"bytes,3,opt,name=content" json:"content,omitempty"`
|
||||||
|
ContentHint *UnidentifiedSenderMessage_Message_ContentHint `protobuf:"varint,4,opt,name=contentHint,enum=signalservice.UnidentifiedSenderMessage_Message_ContentHint" json:"contentHint,omitempty"`
|
||||||
|
GroupId []byte `protobuf:"bytes,5,opt,name=groupId" json:"groupId,omitempty"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *UnidentifiedSenderMessage_Message) Reset() {
|
||||||
|
*x = UnidentifiedSenderMessage_Message{}
|
||||||
|
mi := &file_UnidentifiedDelivery_proto_msgTypes[5]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *UnidentifiedSenderMessage_Message) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*UnidentifiedSenderMessage_Message) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *UnidentifiedSenderMessage_Message) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_UnidentifiedDelivery_proto_msgTypes[5]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use UnidentifiedSenderMessage_Message.ProtoReflect.Descriptor instead.
|
||||||
|
func (*UnidentifiedSenderMessage_Message) Descriptor() ([]byte, []int) {
|
||||||
|
return file_UnidentifiedDelivery_proto_rawDescGZIP(), []int{2, 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *UnidentifiedSenderMessage_Message) GetType() UnidentifiedSenderMessage_Message_Type {
|
||||||
|
if x != nil && x.Type != nil {
|
||||||
|
return *x.Type
|
||||||
|
}
|
||||||
|
return UnidentifiedSenderMessage_Message_MESSAGE
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *UnidentifiedSenderMessage_Message) GetSenderCertificate() *SenderCertificate {
|
||||||
|
if x != nil {
|
||||||
|
return x.SenderCertificate
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *UnidentifiedSenderMessage_Message) GetContent() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.Content
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *UnidentifiedSenderMessage_Message) GetContentHint() UnidentifiedSenderMessage_Message_ContentHint {
|
||||||
|
if x != nil && x.ContentHint != nil {
|
||||||
|
return *x.ContentHint
|
||||||
|
}
|
||||||
|
return UnidentifiedSenderMessage_Message_DEFAULT
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *UnidentifiedSenderMessage_Message) GetGroupId() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.GroupId
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var File_UnidentifiedDelivery_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
|
const file_UnidentifiedDelivery_proto_rawDesc = "" +
|
||||||
|
"\n" +
|
||||||
|
"\x1aUnidentifiedDelivery.proto\x12\rsignalservice\"\x84\x01\n" +
|
||||||
|
"\x11ServerCertificate\x12 \n" +
|
||||||
|
"\vcertificate\x18\x01 \x01(\fR\vcertificate\x12\x1c\n" +
|
||||||
|
"\tsignature\x18\x02 \x01(\fR\tsignature\x1a/\n" +
|
||||||
|
"\vCertificate\x12\x0e\n" +
|
||||||
|
"\x02id\x18\x01 \x01(\rR\x02id\x12\x10\n" +
|
||||||
|
"\x03key\x18\x02 \x01(\fR\x03key\"\xbd\x02\n" +
|
||||||
|
"\x11SenderCertificate\x12 \n" +
|
||||||
|
"\vcertificate\x18\x01 \x01(\fR\vcertificate\x12\x1c\n" +
|
||||||
|
"\tsignature\x18\x02 \x01(\fR\tsignature\x1a\xe7\x01\n" +
|
||||||
|
"\vCertificate\x12\x1e\n" +
|
||||||
|
"\n" +
|
||||||
|
"senderE164\x18\x01 \x01(\tR\n" +
|
||||||
|
"senderE164\x12\x1e\n" +
|
||||||
|
"\n" +
|
||||||
|
"senderUuid\x18\x06 \x01(\tR\n" +
|
||||||
|
"senderUuid\x12\"\n" +
|
||||||
|
"\fsenderDevice\x18\x02 \x01(\rR\fsenderDevice\x12\x18\n" +
|
||||||
|
"\aexpires\x18\x03 \x01(\x06R\aexpires\x12 \n" +
|
||||||
|
"\videntityKey\x18\x04 \x01(\fR\videntityKey\x128\n" +
|
||||||
|
"\x06signer\x18\x05 \x01(\v2 .signalservice.ServerCertificateR\x06signer\"\xe7\x04\n" +
|
||||||
|
"\x19UnidentifiedSenderMessage\x12(\n" +
|
||||||
|
"\x0fephemeralPublic\x18\x01 \x01(\fR\x0fephemeralPublic\x12(\n" +
|
||||||
|
"\x0fencryptedStatic\x18\x02 \x01(\fR\x0fencryptedStatic\x12*\n" +
|
||||||
|
"\x10encryptedMessage\x18\x03 \x01(\fR\x10encryptedMessage\x1a\xc9\x03\n" +
|
||||||
|
"\aMessage\x12I\n" +
|
||||||
|
"\x04type\x18\x01 \x01(\x0e25.signalservice.UnidentifiedSenderMessage.Message.TypeR\x04type\x12N\n" +
|
||||||
|
"\x11senderCertificate\x18\x02 \x01(\v2 .signalservice.SenderCertificateR\x11senderCertificate\x12\x18\n" +
|
||||||
|
"\acontent\x18\x03 \x01(\fR\acontent\x12^\n" +
|
||||||
|
"\vcontentHint\x18\x04 \x01(\x0e2<.signalservice.UnidentifiedSenderMessage.Message.ContentHintR\vcontentHint\x12\x18\n" +
|
||||||
|
"\agroupId\x18\x05 \x01(\fR\agroupId\"U\n" +
|
||||||
|
"\x04Type\x12\v\n" +
|
||||||
|
"\aMESSAGE\x10\x02\x12\x12\n" +
|
||||||
|
"\x0ePREKEY_MESSAGE\x10\x03\x12\x15\n" +
|
||||||
|
"\x11SENDERKEY_MESSAGE\x10\a\x12\x15\n" +
|
||||||
|
"\x11PLAINTEXT_CONTENT\x10\b\"8\n" +
|
||||||
|
"\vContentHint\x12\v\n" +
|
||||||
|
"\aDEFAULT\x10\x00\x12\x0e\n" +
|
||||||
|
"\n" +
|
||||||
|
"RESENDABLE\x10\x01\x12\f\n" +
|
||||||
|
"\bIMPLICIT\x10\x02B6\n" +
|
||||||
|
"%org.whispersystems.libsignal.protocolB\rWhisperProtos"
|
||||||
|
|
||||||
|
var (
|
||||||
|
file_UnidentifiedDelivery_proto_rawDescOnce sync.Once
|
||||||
|
file_UnidentifiedDelivery_proto_rawDescData []byte
|
||||||
|
)
|
||||||
|
|
||||||
|
func file_UnidentifiedDelivery_proto_rawDescGZIP() []byte {
|
||||||
|
file_UnidentifiedDelivery_proto_rawDescOnce.Do(func() {
|
||||||
|
file_UnidentifiedDelivery_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_UnidentifiedDelivery_proto_rawDesc), len(file_UnidentifiedDelivery_proto_rawDesc)))
|
||||||
|
})
|
||||||
|
return file_UnidentifiedDelivery_proto_rawDescData
|
||||||
|
}
|
||||||
|
|
||||||
|
var file_UnidentifiedDelivery_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
|
||||||
|
var file_UnidentifiedDelivery_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||||
|
var file_UnidentifiedDelivery_proto_goTypes = []any{
|
||||||
|
(UnidentifiedSenderMessage_Message_Type)(0), // 0: signalservice.UnidentifiedSenderMessage.Message.Type
|
||||||
|
(UnidentifiedSenderMessage_Message_ContentHint)(0), // 1: signalservice.UnidentifiedSenderMessage.Message.ContentHint
|
||||||
|
(*ServerCertificate)(nil), // 2: signalservice.ServerCertificate
|
||||||
|
(*SenderCertificate)(nil), // 3: signalservice.SenderCertificate
|
||||||
|
(*UnidentifiedSenderMessage)(nil), // 4: signalservice.UnidentifiedSenderMessage
|
||||||
|
(*ServerCertificate_Certificate)(nil), // 5: signalservice.ServerCertificate.Certificate
|
||||||
|
(*SenderCertificate_Certificate)(nil), // 6: signalservice.SenderCertificate.Certificate
|
||||||
|
(*UnidentifiedSenderMessage_Message)(nil), // 7: signalservice.UnidentifiedSenderMessage.Message
|
||||||
|
}
|
||||||
|
var file_UnidentifiedDelivery_proto_depIdxs = []int32{
|
||||||
|
2, // 0: signalservice.SenderCertificate.Certificate.signer:type_name -> signalservice.ServerCertificate
|
||||||
|
0, // 1: signalservice.UnidentifiedSenderMessage.Message.type:type_name -> signalservice.UnidentifiedSenderMessage.Message.Type
|
||||||
|
3, // 2: signalservice.UnidentifiedSenderMessage.Message.senderCertificate:type_name -> signalservice.SenderCertificate
|
||||||
|
1, // 3: signalservice.UnidentifiedSenderMessage.Message.contentHint:type_name -> signalservice.UnidentifiedSenderMessage.Message.ContentHint
|
||||||
|
4, // [4:4] is the sub-list for method output_type
|
||||||
|
4, // [4:4] is the sub-list for method input_type
|
||||||
|
4, // [4:4] is the sub-list for extension type_name
|
||||||
|
4, // [4:4] is the sub-list for extension extendee
|
||||||
|
0, // [0:4] is the sub-list for field type_name
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() { file_UnidentifiedDelivery_proto_init() }
|
||||||
|
func file_UnidentifiedDelivery_proto_init() {
|
||||||
|
if File_UnidentifiedDelivery_proto != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
type x struct{}
|
||||||
|
out := protoimpl.TypeBuilder{
|
||||||
|
File: protoimpl.DescBuilder{
|
||||||
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
|
RawDescriptor: unsafe.Slice(unsafe.StringData(file_UnidentifiedDelivery_proto_rawDesc), len(file_UnidentifiedDelivery_proto_rawDesc)),
|
||||||
|
NumEnums: 2,
|
||||||
|
NumMessages: 6,
|
||||||
|
NumExtensions: 0,
|
||||||
|
NumServices: 0,
|
||||||
|
},
|
||||||
|
GoTypes: file_UnidentifiedDelivery_proto_goTypes,
|
||||||
|
DependencyIndexes: file_UnidentifiedDelivery_proto_depIdxs,
|
||||||
|
EnumInfos: file_UnidentifiedDelivery_proto_enumTypes,
|
||||||
|
MessageInfos: file_UnidentifiedDelivery_proto_msgTypes,
|
||||||
|
}.Build()
|
||||||
|
File_UnidentifiedDelivery_proto = out.File
|
||||||
|
file_UnidentifiedDelivery_proto_goTypes = nil
|
||||||
|
file_UnidentifiedDelivery_proto_depIdxs = nil
|
||||||
|
}
|
||||||
70
pkg/signalmeow/protobuf/UnidentifiedDelivery.proto
Normal file
70
pkg/signalmeow/protobuf/UnidentifiedDelivery.proto
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
// Copyright 2018 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
package signalservice;
|
||||||
|
|
||||||
|
option java_package = "org.whispersystems.libsignal.protocol";
|
||||||
|
option java_outer_classname = "WhisperProtos";
|
||||||
|
|
||||||
|
message ServerCertificate {
|
||||||
|
message Certificate {
|
||||||
|
optional uint32 id = 1;
|
||||||
|
optional bytes key = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
optional bytes certificate = 1;
|
||||||
|
optional bytes signature = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SenderCertificate {
|
||||||
|
message Certificate {
|
||||||
|
optional string senderE164 = 1;
|
||||||
|
optional string senderUuid = 6;
|
||||||
|
optional uint32 senderDevice = 2;
|
||||||
|
optional fixed64 expires = 3;
|
||||||
|
optional bytes identityKey = 4;
|
||||||
|
optional ServerCertificate signer = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
optional bytes certificate = 1;
|
||||||
|
optional bytes signature = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UnidentifiedSenderMessage {
|
||||||
|
|
||||||
|
message Message {
|
||||||
|
enum Type {
|
||||||
|
// Our parser does not handle reserved in enums: DESKTOP-1569
|
||||||
|
// reserved 1;
|
||||||
|
MESSAGE = 2;
|
||||||
|
PREKEY_MESSAGE = 3;
|
||||||
|
// Further cases should line up with Envelope.Type, even though old cases don't.
|
||||||
|
|
||||||
|
// reserved 3 to 6;
|
||||||
|
|
||||||
|
SENDERKEY_MESSAGE = 7;
|
||||||
|
PLAINTEXT_CONTENT = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ContentHint {
|
||||||
|
// Show an error immediately; it was important but we can't retry.
|
||||||
|
DEFAULT = 0;
|
||||||
|
|
||||||
|
// Sender will try to resend; delay any error UI if possible
|
||||||
|
RESENDABLE = 1;
|
||||||
|
|
||||||
|
// Don't show any error UI at all; this is something sent implicitly like a typing message or a receipt
|
||||||
|
IMPLICIT = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
optional Type type = 1;
|
||||||
|
optional SenderCertificate senderCertificate = 2;
|
||||||
|
optional bytes content = 3;
|
||||||
|
optional ContentHint contentHint = 4;
|
||||||
|
optional bytes groupId = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
optional bytes ephemeralPublic = 1;
|
||||||
|
optional bytes encryptedStatic = 2;
|
||||||
|
optional bytes encryptedMessage = 3;
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue