aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Alexander <neilalexander@users.noreply.github.com>2020-05-27 10:19:24 +0100
committerGitHub <noreply@github.com>2020-05-27 10:19:24 +0100
commit7d6461dd3c4429303148a115d72b1b3b0ebaba72 (patch)
tree1dd75984fd4227882cae6314334bd39753ce399d
parent267a4d1823fad787aef16318272710611e19d07e (diff)
Server key component (#1050)
* Server key API (works for monolith but not for polylith yet) * Re-enable caching on server key API component * Groundwork for HTTP APIs for server key API * Hopefully implement HTTP for server key API * Simplify public key request marshalling from map keys * Update gomatrixserverlib * go mod tidy * Common -> internal * remove keyring.go * Update Docker Hub for server key API * YAML is funny about indentation * Wire in new server key API into hybrid monolith mode * Create maps * Route server key API endpoints on internal API mux * Fix server key API URLs * Add fetcher behaviour into server key API implementation * Return error if we failed to fetch some keys * Return results anyway * Move things about a bit * Remove unused code * Fix comments, don't use federation sender URL in polylith mode * Add server_key_api to sample config * Review comments * HTTP API to cache keys that have been requested * Overwrite server_key_api listen in monolith hybrid mode
-rw-r--r--build/docker/hub/config/dendrite-config.yaml2
-rw-r--r--build/docker/hub/docker-compose.polylith.yml13
-rwxr-xr-xbuild/docker/hub/images-build.sh25
-rw-r--r--cmd/dendrite-client-api-server/main.go8
-rw-r--r--cmd/dendrite-demo-libp2p/main.go32
-rw-r--r--cmd/dendrite-demo-libp2p/mdnslistener.go3
-rw-r--r--cmd/dendrite-federation-api-server/main.go9
-rw-r--r--cmd/dendrite-federation-sender-server/main.go9
-rw-r--r--cmd/dendrite-monolith-server/main.go19
-rw-r--r--cmd/dendrite-room-server/main.go6
-rw-r--r--cmd/dendrite-server-key-api-server/main.go32
-rw-r--r--cmd/dendritejs/main.go8
-rw-r--r--dendrite-config.yaml3
-rw-r--r--go.mod2
-rw-r--r--go.sum4
-rw-r--r--internal/basecomponent/base.go40
-rw-r--r--internal/config/config.go12
-rw-r--r--internal/keydb/keyring.go74
-rw-r--r--serverkeyapi/api/api.go113
-rw-r--r--serverkeyapi/api/http.go57
-rw-r--r--serverkeyapi/internal/api.go76
-rw-r--r--serverkeyapi/internal/http.go60
-rw-r--r--serverkeyapi/serverkeyapi.go83
-rw-r--r--serverkeyapi/storage/cache/keydb.go (renamed from internal/keydb/cache/keydb.go)5
-rw-r--r--serverkeyapi/storage/interface.go (renamed from internal/keydb/interface.go)2
-rw-r--r--serverkeyapi/storage/keydb.go (renamed from internal/keydb/keydb.go)6
-rw-r--r--serverkeyapi/storage/keydb_wasm.go (renamed from internal/keydb/keydb_wasm.go)8
-rw-r--r--serverkeyapi/storage/postgres/keydb.go (renamed from internal/keydb/postgres/keydb.go)0
-rw-r--r--serverkeyapi/storage/postgres/server_key_table.go (renamed from internal/keydb/postgres/server_key_table.go)0
-rw-r--r--serverkeyapi/storage/sqlite3/keydb.go (renamed from internal/keydb/sqlite3/keydb.go)0
-rw-r--r--serverkeyapi/storage/sqlite3/server_key_table.go (renamed from internal/keydb/sqlite3/server_key_table.go)0
31 files changed, 542 insertions, 169 deletions
diff --git a/build/docker/hub/config/dendrite-config.yaml b/build/docker/hub/config/dendrite-config.yaml
index 23d6479b..26dc272a 100644
--- a/build/docker/hub/config/dendrite-config.yaml
+++ b/build/docker/hub/config/dendrite-config.yaml
@@ -110,11 +110,13 @@ listen:
room_server: "room_server:7770"
client_api: "client_api:7771"
federation_api: "federation_api:7772"
+ server_key_api: "server_key_api:7778"
sync_api: "sync_api:7773"
media_api: "media_api:7774"
public_rooms_api: "public_rooms_api:7775"
federation_sender: "federation_sender:7776"
edu_server: "edu_server:7777"
+ key_server: "key_server:7779"
# The configuration for tracing the dendrite components.
tracing:
diff --git a/build/docker/hub/docker-compose.polylith.yml b/build/docker/hub/docker-compose.polylith.yml
index d88e5bfb..17860409 100644
--- a/build/docker/hub/docker-compose.polylith.yml
+++ b/build/docker/hub/docker-compose.polylith.yml
@@ -131,7 +131,7 @@ services:
- internal
key_server:
- hostname: key_serverde
+ hostname: key_server
image: matrixdotorg/dendrite:keyserver
command: [
"--config=dendrite.yaml"
@@ -141,6 +141,17 @@ services:
networks:
- internal
+ server_key_api:
+ hostname: server_key_api
+ image: matrixdotorg/dendrite:serverkeyapi
+ command: [
+ "--config=dendrite.yaml"
+ ]
+ volumes:
+ - ./config:/etc/dendrite
+ networks:
+ - internal
+
networks:
internal:
attachable: true
diff --git a/build/docker/hub/images-build.sh b/build/docker/hub/images-build.sh
index 0c6a0eb7..b162a063 100755
--- a/build/docker/hub/images-build.sh
+++ b/build/docker/hub/images-build.sh
@@ -2,16 +2,17 @@
cd $(git rev-parse --show-toplevel)
-docker build -f docker/hub/Dockerfile -t matrixdotorg/dendrite:latest .
+docker build -f build/docker/hub/Dockerfile -t matrixdotorg/dendrite:latest .
-docker build -t matrixdotorg/dendrite:clientapi --build-arg component=dendrite-client-api-server -f docker/hub/Dockerfile.component .
-docker build -t matrixdotorg/dendrite:clientproxy --build-arg component=client-api-proxy -f docker/hub/Dockerfile.component .
-docker build -t matrixdotorg/dendrite:eduserver --build-arg component=dendrite-edu-server -f docker/hub/Dockerfile.component .
-docker build -t matrixdotorg/dendrite:federationapi --build-arg component=dendrite-federation-api-server -f docker/hub/Dockerfile.component .
-docker build -t matrixdotorg/dendrite:federationsender --build-arg component=dendrite-federation-sender-server -f docker/hub/Dockerfile.component .
-docker build -t matrixdotorg/dendrite:federationproxy --build-arg component=federation-api-proxy -f docker/hub/Dockerfile.component .
-docker build -t matrixdotorg/dendrite:keyserver --build-arg component=dendrite-key-server -f docker/hub/Dockerfile.component .
-docker build -t matrixdotorg/dendrite:mediaapi --build-arg component=dendrite-media-api-server -f docker/hub/Dockerfile.component .
-docker build -t matrixdotorg/dendrite:publicroomsapi --build-arg component=dendrite-public-rooms-api-server -f docker/hub/Dockerfile.component .
-docker build -t matrixdotorg/dendrite:roomserver --build-arg component=dendrite-room-server -f docker/hub/Dockerfile.component .
-docker build -t matrixdotorg/dendrite:syncapi --build-arg component=dendrite-sync-api-server -f docker/hub/Dockerfile.component .
+docker build -t matrixdotorg/dendrite:clientapi --build-arg component=dendrite-client-api-server -f build/docker/hub/Dockerfile.component .
+docker build -t matrixdotorg/dendrite:clientproxy --build-arg component=client-api-proxy -f build/docker/hub/Dockerfile.component .
+docker build -t matrixdotorg/dendrite:eduserver --build-arg component=dendrite-edu-server -f build/docker/hub/Dockerfile.component .
+docker build -t matrixdotorg/dendrite:federationapi --build-arg component=dendrite-federation-api-server -f build/docker/hub/Dockerfile.component .
+docker build -t matrixdotorg/dendrite:federationsender --build-arg component=dendrite-federation-sender-server -f build/docker/hub/Dockerfile.component .
+docker build -t matrixdotorg/dendrite:federationproxy --build-arg component=federation-api-proxy -f build/docker/hub/Dockerfile.component .
+docker build -t matrixdotorg/dendrite:keyserver --build-arg component=dendrite-key-server -f build/docker/hub/Dockerfile.component .
+docker build -t matrixdotorg/dendrite:mediaapi --build-arg component=dendrite-media-api-server -f build/docker/hub/Dockerfile.component .
+docker build -t matrixdotorg/dendrite:publicroomsapi --build-arg component=dendrite-public-rooms-api-server -f build/docker/hub/Dockerfile.component .
+docker build -t matrixdotorg/dendrite:roomserver --build-arg component=dendrite-room-server -f build/docker/hub/Dockerfile.component .
+docker build -t matrixdotorg/dendrite:syncapi --build-arg component=dendrite-sync-api-server -f build/docker/hub/Dockerfile.component .
+docker build -t matrixdotorg/dendrite:serverkeyapi --build-arg component=dendrite-server-key-api-server -f build/docker/hub/Dockerfile.component .
diff --git a/cmd/dendrite-client-api-server/main.go b/cmd/dendrite-client-api-server/main.go
index 0815be79..e06adf8f 100644
--- a/cmd/dendrite-client-api-server/main.go
+++ b/cmd/dendrite-client-api-server/main.go
@@ -19,7 +19,6 @@ import (
"github.com/matrix-org/dendrite/eduserver"
"github.com/matrix-org/dendrite/eduserver/cache"
"github.com/matrix-org/dendrite/internal/basecomponent"
- "github.com/matrix-org/dendrite/internal/keydb"
"github.com/matrix-org/dendrite/internal/transactions"
)
@@ -31,9 +30,10 @@ func main() {
accountDB := base.CreateAccountsDB()
deviceDB := base.CreateDeviceDB()
- keyDB := base.CreateKeyDB()
federation := base.CreateFederationClient()
- keyRing := keydb.CreateKeyRing(federation.Client, keyDB, cfg.Matrix.KeyPerspectives)
+
+ serverKeyAPI := base.CreateHTTPServerKeyAPIs()
+ keyRing := serverKeyAPI.KeyRing()
asQuery := base.CreateHTTPAppServiceAPIs()
rsAPI := base.CreateHTTPRoomserverAPIs()
@@ -42,7 +42,7 @@ func main() {
eduInputAPI := eduserver.SetupEDUServerComponent(base, cache.New())
clientapi.SetupClientAPIComponent(
- base, deviceDB, accountDB, federation, &keyRing,
+ base, deviceDB, accountDB, federation, keyRing,
rsAPI, eduInputAPI, asQuery, transactions.New(), fsAPI,
)
diff --git a/cmd/dendrite-demo-libp2p/main.go b/cmd/dendrite-demo-libp2p/main.go
index 3f53cb42..fc56b9bb 100644
--- a/cmd/dendrite-demo-libp2p/main.go
+++ b/cmd/dendrite-demo-libp2p/main.go
@@ -37,11 +37,11 @@ import (
"github.com/matrix-org/dendrite/federationsender"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/config"
- "github.com/matrix-org/dendrite/internal/keydb"
"github.com/matrix-org/dendrite/internal/transactions"
"github.com/matrix-org/dendrite/mediaapi"
"github.com/matrix-org/dendrite/publicroomsapi"
"github.com/matrix-org/dendrite/roomserver"
+ "github.com/matrix-org/dendrite/serverkeyapi"
"github.com/matrix-org/dendrite/syncapi"
"github.com/matrix-org/gomatrixserverlib"
@@ -52,17 +52,8 @@ import (
func createKeyDB(
base *P2PDendrite,
-) keydb.Database {
- db, err := keydb.NewDatabase(
- string(base.Base.Cfg.Database.ServerKey),
- base.Base.Cfg.DbProperties(),
- base.Base.Cfg.Matrix.ServerName,
- base.Base.Cfg.Matrix.PrivateKey.Public().(ed25519.PublicKey),
- base.Base.Cfg.Matrix.KeyID,
- )
- if err != nil {
- logrus.WithError(err).Panicf("failed to connect to keys db")
- }
+ db gomatrixserverlib.KeyDatabase,
+) {
mdns := mDNSListener{
host: base.LibP2P,
keydb: db,
@@ -77,7 +68,6 @@ func createKeyDB(
panic(err)
}
serv.RegisterNotifee(&mdns)
- return db
}
func createFederationClient(
@@ -144,9 +134,15 @@ func main() {
accountDB := base.Base.CreateAccountsDB()
deviceDB := base.Base.CreateDeviceDB()
- keyDB := createKeyDB(base)
federation := createFederationClient(base)
- keyRing := keydb.CreateKeyRing(federation.Client, keyDB, cfg.Matrix.KeyPerspectives)
+
+ serverKeyAPI := serverkeyapi.SetupServerKeyAPIComponent(
+ &base.Base, federation,
+ )
+ keyRing := serverKeyAPI.KeyRing()
+ createKeyDB(
+ base, serverKeyAPI,
+ )
rsAPI := roomserver.SetupRoomServerComponent(
&base.Base, keyRing, federation,
@@ -158,17 +154,17 @@ func main() {
&base.Base, accountDB, deviceDB, federation, rsAPI, transactions.New(),
)
fsAPI := federationsender.SetupFederationSenderComponent(
- &base.Base, federation, rsAPI, &keyRing,
+ &base.Base, federation, rsAPI, keyRing,
)
rsAPI.SetFederationSenderAPI(fsAPI)
clientapi.SetupClientAPIComponent(
&base.Base, deviceDB, accountDB,
- federation, &keyRing, rsAPI,
+ federation, keyRing, rsAPI,
eduInputAPI, asAPI, transactions.New(), fsAPI,
)
eduProducer := producers.NewEDUServerProducer(eduInputAPI)
- federationapi.SetupFederationAPIComponent(&base.Base, accountDB, deviceDB, federation, &keyRing, rsAPI, asAPI, fsAPI, eduProducer)
+ federationapi.SetupFederationAPIComponent(&base.Base, accountDB, deviceDB, federation, keyRing, rsAPI, asAPI, fsAPI, eduProducer)
mediaapi.SetupMediaAPIComponent(&base.Base, deviceDB)
publicRoomsDB, err := storage.NewPublicRoomsServerDatabaseWithPubSub(string(base.Base.Cfg.Database.PublicRoomsAPI), base.LibP2PPubsub)
if err != nil {
diff --git a/cmd/dendrite-demo-libp2p/mdnslistener.go b/cmd/dendrite-demo-libp2p/mdnslistener.go
index c05c94d5..01705cf3 100644
--- a/cmd/dendrite-demo-libp2p/mdnslistener.go
+++ b/cmd/dendrite-demo-libp2p/mdnslistener.go
@@ -21,12 +21,11 @@ import (
"github.com/libp2p/go-libp2p-core/host"
"github.com/libp2p/go-libp2p-core/peer"
- "github.com/matrix-org/dendrite/internal/keydb"
"github.com/matrix-org/gomatrixserverlib"
)
type mDNSListener struct {
- keydb keydb.Database
+ keydb gomatrixserverlib.KeyDatabase
host host.Host
}
diff --git a/cmd/dendrite-federation-api-server/main.go b/cmd/dendrite-federation-api-server/main.go
index be97bc9a..5425d117 100644
--- a/cmd/dendrite-federation-api-server/main.go
+++ b/cmd/dendrite-federation-api-server/main.go
@@ -20,7 +20,6 @@ import (
"github.com/matrix-org/dendrite/eduserver/cache"
"github.com/matrix-org/dendrite/federationapi"
"github.com/matrix-org/dendrite/internal/basecomponent"
- "github.com/matrix-org/dendrite/internal/keydb"
)
func main() {
@@ -30,10 +29,12 @@ func main() {
accountDB := base.CreateAccountsDB()
deviceDB := base.CreateDeviceDB()
- keyDB := base.CreateKeyDB()
federation := base.CreateFederationClient()
+
+ serverKeyAPI := base.CreateHTTPServerKeyAPIs()
+ keyRing := serverKeyAPI.KeyRing()
+
fsAPI := base.CreateHTTPFederationSenderAPIs()
- keyRing := keydb.CreateKeyRing(federation.Client, keyDB, cfg.Matrix.KeyPerspectives)
rsAPI := base.CreateHTTPRoomserverAPIs()
asAPI := base.CreateHTTPAppServiceAPIs()
@@ -42,7 +43,7 @@ func main() {
eduProducer := producers.NewEDUServerProducer(eduInputAPI)
federationapi.SetupFederationAPIComponent(
- base, accountDB, deviceDB, federation, &keyRing,
+ base, accountDB, deviceDB, federation, keyRing,
rsAPI, asAPI, fsAPI, eduProducer,
)
diff --git a/cmd/dendrite-federation-sender-server/main.go b/cmd/dendrite-federation-sender-server/main.go
index b6af8deb..2b1e0ae8 100644
--- a/cmd/dendrite-federation-sender-server/main.go
+++ b/cmd/dendrite-federation-sender-server/main.go
@@ -17,7 +17,6 @@ package main
import (
"github.com/matrix-org/dendrite/federationsender"
"github.com/matrix-org/dendrite/internal/basecomponent"
- "github.com/matrix-org/dendrite/internal/keydb"
)
func main() {
@@ -26,11 +25,13 @@ func main() {
defer base.Close() // nolint: errcheck
federation := base.CreateFederationClient()
- keyDB := base.CreateKeyDB()
- keyRing := keydb.CreateKeyRing(federation.Client, keyDB, cfg.Matrix.KeyPerspectives)
+
+ serverKeyAPI := base.CreateHTTPServerKeyAPIs()
+ keyRing := serverKeyAPI.KeyRing()
+
rsAPI := base.CreateHTTPRoomserverAPIs()
fsAPI := federationsender.SetupFederationSenderComponent(
- base, federation, rsAPI, &keyRing,
+ base, federation, rsAPI, keyRing,
)
rsAPI.SetFederationSenderAPI(fsAPI)
diff --git a/cmd/dendrite-monolith-server/main.go b/cmd/dendrite-monolith-server/main.go
index f9993774..8367cd9d 100644
--- a/cmd/dendrite-monolith-server/main.go
+++ b/cmd/dendrite-monolith-server/main.go
@@ -28,13 +28,13 @@ import (
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/basecomponent"
"github.com/matrix-org/dendrite/internal/config"
- "github.com/matrix-org/dendrite/internal/keydb"
"github.com/matrix-org/dendrite/internal/transactions"
"github.com/matrix-org/dendrite/keyserver"
"github.com/matrix-org/dendrite/mediaapi"
"github.com/matrix-org/dendrite/publicroomsapi"
"github.com/matrix-org/dendrite/publicroomsapi/storage"
"github.com/matrix-org/dendrite/roomserver"
+ "github.com/matrix-org/dendrite/serverkeyapi"
"github.com/matrix-org/dendrite/syncapi"
"github.com/sirupsen/logrus"
@@ -60,6 +60,7 @@ func main() {
cfg.Listen.EDUServer = addr
cfg.Listen.AppServiceAPI = addr
cfg.Listen.FederationSender = addr
+ cfg.Listen.ServerKeyAPI = addr
}
base := basecomponent.NewBaseDendrite(cfg, "Monolith", *enableHTTPAPIs)
@@ -67,9 +68,15 @@ func main() {
accountDB := base.CreateAccountsDB()
deviceDB := base.CreateDeviceDB()
- keyDB := base.CreateKeyDB()
federation := base.CreateFederationClient()
- keyRing := keydb.CreateKeyRing(federation.Client, keyDB, cfg.Matrix.KeyPerspectives)
+
+ serverKeyAPI := serverkeyapi.SetupServerKeyAPIComponent(
+ base, federation,
+ )
+ if base.EnableHTTPAPIs {
+ serverKeyAPI = base.CreateHTTPServerKeyAPIs()
+ }
+ keyRing := serverKeyAPI.KeyRing()
rsComponent := roomserver.SetupRoomServerComponent(
base, keyRing, federation,
@@ -94,7 +101,7 @@ func main() {
}
fsAPI := federationsender.SetupFederationSenderComponent(
- base, federation, rsAPI, &keyRing,
+ base, federation, rsAPI, keyRing,
)
if base.EnableHTTPAPIs {
fsAPI = base.CreateHTTPFederationSenderAPIs()
@@ -103,7 +110,7 @@ func main() {
clientapi.SetupClientAPIComponent(
base, deviceDB, accountDB,
- federation, &keyRing, rsAPI,
+ federation, keyRing, rsAPI,
eduInputAPI, asAPI, transactions.New(), fsAPI,
)
@@ -111,7 +118,7 @@ func main() {
base, deviceDB, accountDB,
)
eduProducer := producers.NewEDUServerProducer(eduInputAPI)
- federationapi.SetupFederationAPIComponent(base, accountDB, deviceDB, federation, &keyRing, rsAPI, asAPI, fsAPI, eduProducer)
+ federationapi.SetupFederationAPIComponent(base, accountDB, deviceDB, federation, keyRing, rsAPI, asAPI, fsAPI, eduProducer)
mediaapi.SetupMediaAPIComponent(base, deviceDB)
publicRoomsDB, err := storage.NewPublicRoomsServerDatabase(string(base.Cfg.Database.PublicRoomsAPI), base.Cfg.DbProperties())
if err != nil {
diff --git a/cmd/dendrite-room-server/main.go b/cmd/dendrite-room-server/main.go
index 31cf4a04..b86b7497 100644
--- a/cmd/dendrite-room-server/main.go
+++ b/cmd/dendrite-room-server/main.go
@@ -16,7 +16,6 @@ package main
import (
"github.com/matrix-org/dendrite/internal/basecomponent"
- "github.com/matrix-org/dendrite/internal/keydb"
"github.com/matrix-org/dendrite/roomserver"
)
@@ -24,9 +23,10 @@ func main() {
cfg := basecomponent.ParseFlags()
base := basecomponent.NewBaseDendrite(cfg, "RoomServerAPI", true)
defer base.Close() // nolint: errcheck
- keyDB := base.CreateKeyDB()
federation := base.CreateFederationClient()
- keyRing := keydb.CreateKeyRing(federation.Client, keyDB, cfg.Matrix.KeyPerspectives)
+
+ serverKeyAPI := base.CreateHTTPServerKeyAPIs()
+ keyRing := serverKeyAPI.KeyRing()
fsAPI := base.CreateHTTPFederationSenderAPIs()
rsAPI := roomserver.SetupRoomServerComponent(base, keyRing, federation)
diff --git a/cmd/dendrite-server-key-api-server/main.go b/cmd/dendrite-server-key-api-server/main.go
new file mode 100644
index 00000000..07573412
--- /dev/null
+++ b/cmd/dendrite-server-key-api-server/main.go
@@ -0,0 +1,32 @@
+// Copyright 2020 The Matrix.org Foundation C.I.C.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package main
+
+import (
+ "github.com/matrix-org/dendrite/internal/basecomponent"
+ "github.com/matrix-org/dendrite/serverkeyapi"
+)
+
+func main() {
+ cfg := basecomponent.ParseFlags()
+ base := basecomponent.NewBaseDendrite(cfg, "ServerKeyAPI", true)
+ defer base.Close() // nolint: errcheck
+
+ federation := base.CreateFederationClient()
+
+ serverkeyapi.SetupServerKeyAPIComponent(base, federation)
+
+ base.SetupAndServeHTTP(string(base.Cfg.Bind.ServerKeyAPI), string(base.Cfg.Listen.ServerKeyAPI))
+}
diff --git a/cmd/dendritejs/main.go b/cmd/dendritejs/main.go
index 73d38149..b8517bf9 100644
--- a/cmd/dendritejs/main.go
+++ b/cmd/dendritejs/main.go
@@ -37,6 +37,7 @@ import (
"github.com/matrix-org/dendrite/publicroomsapi"
"github.com/matrix-org/dendrite/publicroomsapi/storage"
"github.com/matrix-org/dendrite/roomserver"
+ "github.com/matrix-org/dendrite/serverkeyapi"
"github.com/matrix-org/dendrite/syncapi"
go_http_js_libp2p "github.com/matrix-org/go-http-js-libp2p"
"github.com/matrix-org/gomatrixserverlib"
@@ -194,13 +195,16 @@ func main() {
accountDB := base.CreateAccountsDB()
deviceDB := base.CreateDeviceDB()
- keyDB := base.CreateKeyDB()
federation := createFederationClient(cfg, node)
+
+ serverKeyAPI := serverkeyapi.SetupServerKeyAPIComponent(
+ base, federation,
+ )
keyRing := gomatrixserverlib.KeyRing{
KeyFetchers: []gomatrixserverlib.KeyFetcher{
&libp2pKeyFetcher{},
},
- KeyDatabase: keyDB,
+ KeyDatabase: serverKeyAPI,
}
p2pPublicRoomProvider := NewLibP2PPublicRoomsProvider(node)
diff --git a/dendrite-config.yaml b/dendrite-config.yaml
index 2616d74d..1802b8b7 100644
--- a/dendrite-config.yaml
+++ b/dendrite-config.yaml
@@ -137,7 +137,8 @@ listen:
federation_sender: "localhost:7776"
appservice_api: "localhost:7777"
edu_server: "localhost:7778"
- key_server: "localhost:7779"
+ key_server: "localhost:7779"
+ server_key_api: "localhost:7780"
# The configuration for tracing the dendrite components.
tracing:
diff --git a/go.mod b/go.mod
index 151fee27..fe2cff76 100644
--- a/go.mod
+++ b/go.mod
@@ -18,7 +18,7 @@ require (
github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4
github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26
- github.com/matrix-org/gomatrixserverlib v0.0.0-20200511154227-5cc71d36632b
+ github.com/matrix-org/gomatrixserverlib v0.0.0-20200521102632-2a81324a04ae
github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7
github.com/mattn/go-sqlite3 v2.0.2+incompatible
diff --git a/go.sum b/go.sum
index 15822b53..aa0c8dd5 100644
--- a/go.sum
+++ b/go.sum
@@ -358,8 +358,8 @@ github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3 h1:Yb+Wlf
github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3/go.mod h1:e+cg2q7C7yE5QnAXgzo512tgFh1RbQLC0+jozuegKgo=
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26 h1:Hr3zjRsq2bhrnp3Ky1qgx/fzCtCALOoGYylh2tpS9K4=
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0=
-github.com/matrix-org/gomatrixserverlib v0.0.0-20200511154227-5cc71d36632b h1:nAmSc1KvQOumoRTz/LD68KyrB6Q5/6q7CmQ5Bswc2nM=
-github.com/matrix-org/gomatrixserverlib v0.0.0-20200511154227-5cc71d36632b/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
+github.com/matrix-org/gomatrixserverlib v0.0.0-20200521102632-2a81324a04ae h1:kFMh2aU3pMCkVCUeH57rtgm05XImbxKOHFYeUp80RCk=
+github.com/matrix-org/gomatrixserverlib v0.0.0-20200521102632-2a81324a04ae/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f h1:pRz4VTiRCO4zPlEMc3ESdUOcW4PXHH4Kj+YDz1XyE+Y=
github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f/go.mod h1:y0oDTjZDv5SM9a2rp3bl+CU+bvTRINQsdb7YlDql5Go=
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7 h1:ntrLa/8xVzeSs8vHFHK25k0C+NV74sYMJnNSg5NoSRo=
diff --git a/internal/basecomponent/base.go b/internal/basecomponent/base.go
index e86d9102..a4832372 100644
--- a/internal/basecomponent/base.go
+++ b/internal/basecomponent/base.go
@@ -21,12 +21,8 @@ import (
"net/url"
"time"
- "golang.org/x/crypto/ed25519"
-
"github.com/matrix-org/dendrite/internal/caching"
"github.com/matrix-org/dendrite/internal/httpapis"
- "github.com/matrix-org/dendrite/internal/keydb"
- "github.com/matrix-org/dendrite/internal/keydb/cache"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/naffka"
@@ -43,6 +39,7 @@ import (
federationSenderAPI "github.com/matrix-org/dendrite/federationsender/api"
"github.com/matrix-org/dendrite/internal/config"
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
+ serverKeyAPI "github.com/matrix-org/dendrite/serverkeyapi/api"
"github.com/sirupsen/logrus"
_ "net/http/pprof"
@@ -157,6 +154,20 @@ func (b *BaseDendrite) CreateHTTPFederationSenderAPIs() federationSenderAPI.Fede
return f
}
+// CreateHTTPServerKeyAPIs returns ServerKeyInternalAPI for hitting the server key
+// API over HTTP
+func (b *BaseDendrite) CreateHTTPServerKeyAPIs() serverKeyAPI.ServerKeyInternalAPI {
+ f, err := serverKeyAPI.NewServerKeyInternalAPIHTTP(
+ b.Cfg.ServerKeyAPIURL(),
+ b.httpClient,
+ b.ImmutableCache,
+ )
+ if err != nil {
+ logrus.WithError(err).Panic("NewServerKeyInternalAPIHTTP failed", b.httpClient)
+ }
+ return f
+}
+
// CreateDeviceDB creates a new instance of the device database. Should only be
// called once per component.
func (b *BaseDendrite) CreateDeviceDB() devices.Database {
@@ -179,27 +190,6 @@ func (b *BaseDendrite) CreateAccountsDB() accounts.Database {
return db
}
-// CreateKeyDB creates a new instance of the key database. Should only be called
-// once per component.
-func (b *BaseDendrite) CreateKeyDB() keydb.Database {
- db, err := keydb.NewDatabase(
- string(b.Cfg.Database.ServerKey),
- b.Cfg.DbProperties(),
- b.Cfg.Matrix.ServerName,
- b.Cfg.Matrix.PrivateKey.Public().(ed25519.PublicKey),
- b.Cfg.Matrix.KeyID,
- )
- if err != nil {
- logrus.WithError(err).Panicf("failed to connect to keys db")
- }
-
- cachedDB, err := cache.NewKeyDatabase(db, b.ImmutableCache)
- if err != nil {
- logrus.WithError(err).Panicf("failed to create key cache wrapper")
- }
- return cachedDB
-}
-
// CreateFederationClient creates a new federation client. Should only be called
// once per component.
func (b *BaseDendrite) CreateFederationClient() *gomatrixserverlib.FederationClient {
diff --git a/internal/config/config.go b/internal/config/config.go
index e1e96f9d..2a95069a 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -223,6 +223,7 @@ type Dendrite struct {
MediaAPI Address `yaml:"media_api"`
ClientAPI Address `yaml:"client_api"`
FederationAPI Address `yaml:"federation_api"`
+ ServerKeyAPI Address `yaml:"server_key_api"`
AppServiceAPI Address `yaml:"appservice_api"`
SyncAPI Address `yaml:"sync_api"`
RoomServer Address `yaml:"room_server"`
@@ -237,6 +238,7 @@ type Dendrite struct {
MediaAPI Address `yaml:"media_api"`
ClientAPI Address `yaml:"client_api"`
FederationAPI Address `yaml:"federation_api"`
+ ServerKeyAPI Address `yaml:"server_key_api"`
AppServiceAPI Address `yaml:"appservice_api"`
SyncAPI Address `yaml:"sync_api"`
RoomServer Address `yaml:"room_server"`
@@ -620,6 +622,7 @@ func (config *Dendrite) checkListen(configErrs *configErrors) {
checkNotEmpty(configErrs, "listen.sync_api", string(config.Listen.SyncAPI))
checkNotEmpty(configErrs, "listen.room_server", string(config.Listen.RoomServer))
checkNotEmpty(configErrs, "listen.edu_server", string(config.Listen.EDUServer))
+ checkNotEmpty(configErrs, "listen.server_key_api", string(config.Listen.EDUServer))
}
// checkLogging verifies the parameters logging.* are valid.
@@ -751,6 +754,15 @@ func (config *Dendrite) FederationSenderURL() string {
return "http://" + string(config.Listen.FederationSender)
}
+// FederationSenderURL returns an HTTP URL for where the federation sender is listening.
+func (config *Dendrite) ServerKeyAPIURL() string {
+ // Hard code the server key API server to talk HTTP for now.
+ // If we support HTTPS we need to think of a practical way to do certificate validation.
+ // People setting up servers shouldn't need to get a certificate valid for the public
+ // internet for an internal API.
+ return "http://" + string(config.Listen.ServerKeyAPI)
+}
+
// SetupTracing configures the opentracing using the supplied configuration.
func (config *Dendrite) SetupTracing(serviceName string) (closer io.Closer, err error) {
if !config.Tracing.Enabled {
diff --git a/internal/keydb/keyring.go b/internal/keydb/keyring.go
deleted file mode 100644
index d0b1904e..00000000
--- a/internal/keydb/keyring.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2017 New Vector Ltd
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package keydb
-
-import (
- "encoding/base64"
-
- "github.com/matrix-org/dendrite/internal/config"
- "github.com/matrix-org/gomatrixserverlib"
- "github.com/sirupsen/logrus"
- "golang.org/x/crypto/ed25519"
-)
-
-// CreateKeyRing creates and configures a KeyRing object.
-//
-// It creates the necessary key fetchers and collects them into a KeyRing
-// backed by the given KeyDatabase.
-func CreateKeyRing(client gomatrixserverlib.Client,
- keyDB gomatrixserverlib.KeyDatabase,
- cfg config.KeyPerspectives) gomatrixserverlib.KeyRing {
-
- fetchers := gomatrixserverlib.KeyRing{
- KeyFetchers: []gomatrixserverlib.KeyFetcher{
- &gomatrixserverlib.DirectKeyFetcher{
- Client: client,
- },
- },
- KeyDatabase: keyDB,
- }
-
- logrus.Info("Enabled direct key fetcher")
-
- var b64e = base64.StdEncoding.WithPadding(base64.NoPadding)
- for _, ps := range cfg {
- perspective := &gomatrixserverlib.PerspectiveKeyFetcher{
- PerspectiveServerName: ps.ServerName,
- PerspectiveServerKeys: map[gomatrixserverlib.KeyID]ed25519.PublicKey{},
- Client: client,
- }
-
- for _, key := range ps.Keys {
- rawkey, err := b64e.DecodeString(key.PublicKey)
- if err != nil {
- logrus.WithError(err).WithFields(logrus.Fields{
- "server_name": ps.ServerName,
- "public_key": key.PublicKey,
- }).Warn("Couldn't parse perspective key")
- continue
- }
- perspective.PerspectiveServerKeys[key.KeyID] = rawkey
- }
-
- fetchers.KeyFetchers = append(fetchers.KeyFetchers, perspective)
-
- logrus.WithFields(logrus.Fields{
- "server_name": ps.ServerName,
- "num_public_keys": len(ps.Keys),
- }).Info("Enabled perspective key fetcher")
- }
-
- return fetchers
-}
diff --git a/serverkeyapi/api/api.go b/serverkeyapi/api/api.go
new file mode 100644
index 00000000..f108d437
--- /dev/null
+++ b/serverkeyapi/api/api.go
@@ -0,0 +1,113 @@
+package api
+
+import (
+ "context"
+ "errors"
+ "net/http"
+
+ "github.com/matrix-org/dendrite/internal/caching"
+ "github.com/matrix-org/gomatrixserverlib"
+)
+
+type ServerKeyInternalAPI interface {
+ gomatrixserverlib.KeyDatabase
+
+ KeyRing() *gomatrixserverlib.KeyRing
+
+ InputPublicKeys(
+ ctx context.Context,
+ request *InputPublicKeysRequest,
+ response *InputPublicKeysResponse,
+ ) error
+
+ QueryPublicKeys(
+ ctx context.Context,
+ request *QueryPublicKeysRequest,
+ response *QueryPublicKeysResponse,
+ ) error
+}
+
+// NewRoomserverInputAPIHTTP creates a RoomserverInputAPI implemented by talking to a HTTP POST API.
+// If httpClient is nil an error is returned
+func NewServerKeyInternalAPIHTTP(
+ serverKeyAPIURL string,
+ httpClient *http.Client,
+ immutableCache caching.ImmutableCache,
+) (ServerKeyInternalAPI, error) {
+ if httpClient == nil {
+ return nil, errors.New("NewRoomserverInternalAPIHTTP: httpClient is <nil>")
+ }
+ return &httpServerKeyInternalAPI{
+ serverKeyAPIURL: serverKeyAPIURL,
+ httpClient: httpClient,
+ immutableCache: immutableCache,
+ }, nil
+}
+
+type httpServerKeyInternalAPI struct {
+ ServerKeyInternalAPI
+
+ serverKeyAPIURL string
+ httpClient *http.Client
+ immutableCache caching.ImmutableCache
+}
+
+func (s *httpServerKeyInternalAPI) KeyRing() *gomatrixserverlib.KeyRing {
+ // This is a bit of a cheat - we tell gomatrixserverlib that this API is
+ // both the key database and the key fetcher. While this does have the
+ // rather unfortunate effect of preventing gomatrixserverlib from handling
+ // key fetchers directly, we can at least reimplement this behaviour on
+ // the other end of the API.
+ return &gomatrixserverlib.KeyRing{
+ KeyDatabase: s,
+ KeyFetchers: []gomatrixserverlib.KeyFetcher{s},
+ }
+}
+
+func (s *httpServerKeyInternalAPI) FetcherName() string {
+ return "httpServerKeyInternalAPI"
+}
+
+func (s *httpServerKeyInternalAPI) StoreKeys(
+ ctx context.Context,
+ results map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult,
+) error {
+ request := InputPublicKeysRequest{
+ Keys: make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult),
+ }
+ response := InputPublicKeysResponse{}
+ for req, res := range results {
+ request.Keys[req] = res
+ s.immutableCache.StoreServerKey(req, res)
+ }
+ return s.InputPublicKeys(ctx, &request, &response)
+}
+
+func (s *httpServerKeyInternalAPI) FetchKeys(
+ ctx context.Context,
+ requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp,
+) (map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult, error) {
+ result := make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult)
+ request := QueryPublicKeysRequest{
+ Requests: make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp),
+ }
+ response := QueryPublicKeysResponse{
+ Results: make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult),
+ }
+ for req, ts := range requests {
+ if res, ok := s.immutableCache.GetServerKey(req); ok {
+ result[req] = res
+ continue
+ }
+ request.Requests[req] = ts
+ }
+ err := s.QueryPublicKeys(ctx, &request, &response)
+ if err != nil {
+ return nil, err
+ }
+ for req, res := range response.Results {
+ result[req] = res
+ s.immutableCache.StoreServerKey(req, res)
+ }
+ return result, nil
+}
diff --git a/serverkeyapi/api/http.go b/serverkeyapi/api/http.go
new file mode 100644
index 00000000..ab89f7bf
--- /dev/null
+++ b/serverkeyapi/api/http.go
@@ -0,0 +1,57 @@
+package api
+
+import (
+ "context"
+
+ commonHTTP "github.com/matrix-org/dendrite/internal/http"
+ "github.com/matrix-org/gomatrixserverlib"
+
+ "github.com/opentracing/opentracing-go"
+)
+
+const (
+ // ServerKeyInputPublicKeyPath is the HTTP path for the InputPublicKeys API.
+ ServerKeyInputPublicKeyPath = "/serverkeyapi/inputPublicKey"
+
+ // ServerKeyQueryPublicKeyPath is the HTTP path for the QueryPublicKeys API.
+ ServerKeyQueryPublicKeyPath = "/serverkeyapi/queryPublicKey"
+)
+
+type InputPublicKeysRequest struct {
+ Keys map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult `json:"keys"`
+}
+
+type InputPublicKeysResponse struct {
+}
+
+func (h *httpServerKeyInternalAPI) InputPublicKeys(
+ ctx context.Context,
+ request *InputPublicKeysRequest,
+ response *InputPublicKeysResponse,
+) error {
+ span, ctx := opentracing.StartSpanFromContext(ctx, "InputPublicKey")
+ defer span.Finish()
+
+ apiURL := h.serverKeyAPIURL + ServerKeyInputPublicKeyPath
+ return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
+}
+
+type QueryPublicKeysRequest struct {
+ Requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp `json:"requests"`
+}
+
+type QueryPublicKeysResponse struct {
+ Results map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult `json:"results"`
+}
+
+func (h *httpServerKeyInternalAPI) QueryPublicKeys(
+ ctx context.Context,
+ request *QueryPublicKeysRequest,
+ response *QueryPublicKeysResponse,
+) error {
+ span, ctx := opentracing.StartSpanFromContext(ctx, "QueryPublicKey")
+ defer span.Finish()
+
+ apiURL := h.serverKeyAPIURL + ServerKeyQueryPublicKeyPath
+ return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
+}
diff --git a/serverkeyapi/internal/api.go b/serverkeyapi/internal/api.go
new file mode 100644
index 00000000..cbae59d9
--- /dev/null
+++ b/serverkeyapi/internal/api.go
@@ -0,0 +1,76 @@
+package internal
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/matrix-org/dendrite/internal/caching"
+ "github.com/matrix-org/dendrite/serverkeyapi/api"
+ "github.com/matrix-org/gomatrixserverlib"
+)
+
+type ServerKeyAPI struct {
+ api.ServerKeyInternalAPI
+
+ ImmutableCache caching.ImmutableCache
+ OurKeyRing gomatrixserverlib.KeyRing
+ FedClient *gomatrixserverlib.FederationClient
+}
+
+func (s *ServerKeyAPI) KeyRing() *gomatrixserverlib.KeyRing {
+ // Return a real keyring - one that has the real database and real
+ // fetchers.
+ return &s.OurKeyRing
+}
+
+func (s *ServerKeyAPI) StoreKeys(
+ ctx context.Context,
+ results map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult,
+) error {
+ // Store any keys that we were given in our database.
+ return s.OurKeyRing.KeyDatabase.StoreKeys(ctx, results)
+}
+
+func (s *ServerKeyAPI) FetchKeys(
+ ctx context.Context,
+ requests map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp,
+) (map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult, error) {
+ results := map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult{}
+ // First consult our local database and see if we have the requested
+ // keys. These might come from a cache, depending on the database
+ // implementation used.
+ if dbResults, err := s.OurKeyRing.KeyDatabase.FetchKeys(ctx, requests); err == nil {
+ // We successfully got some keys. Add them to the results and
+ // remove them from the request list.
+ for req, res := range dbResults {
+ results[req] = res
+ delete(requests, req)
+ }
+ }
+ // For any key requests that we still have outstanding, next try to
+ // fetch them directly. We'll go through each of the key fetchers to
+ // ask for the remaining keys.
+ for _, fetcher := range s.OurKeyRing.KeyFetchers {
+ if len(requests) == 0 {
+ break
+ }
+ if fetcherResults, err := fetcher.FetchKeys(ctx, requests); err == nil {
+ // We successfully got some keys. Add them to the results and
+ // remove them from the request list.
+ for req, res := range fetcherResults {
+ results[req] = res
+ delete(requests, req)
+ }
+ }
+ }
+ // If we failed to fetch any keys then we should report an error.
+ if len(requests) > 0 {
+ return results, fmt.Errorf("server key API failed to fetch %d keys", len(requests))
+ }
+ // Return the keys.
+ return results, nil
+}
+
+func (s *ServerKeyAPI) FetcherName() string {
+ return s.OurKeyRing.KeyDatabase.FetcherName()
+}
diff --git a/serverkeyapi/internal/http.go b/serverkeyapi/internal/http.go
new file mode 100644
index 00000000..30327571
--- /dev/null
+++ b/serverkeyapi/internal/http.go
@@ -0,0 +1,60 @@
+package internal
+
+import (
+ "encoding/json"
+ "net/http"
+
+ "github.com/gorilla/mux"
+ "github.com/matrix-org/dendrite/internal"
+ "github.com/matrix-org/dendrite/serverkeyapi/api"
+ "github.com/matrix-org/gomatrixserverlib"
+ "github.com/matrix-org/util"
+)
+
+func (s *ServerKeyAPI) SetupHTTP(internalAPIMux *mux.Router) {
+ internalAPIMux.Handle(api.ServerKeyQueryPublicKeyPath,
+ internal.MakeInternalAPI("queryPublicKeys", func(req *http.Request) util.JSONResponse {
+ result := map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult{}
+ request := api.QueryPublicKeysRequest{}
+ response := api.QueryPublicKeysResponse{}
+ if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
+ return util.MessageResponse(http.StatusBadRequest, err.Error())
+ }
+ lookup := make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.Timestamp)
+ for req, timestamp := range request.Requests {
+ if res, ok := s.ImmutableCache.GetServerKey(req); ok {
+ result[req] = res
+ continue
+ }
+ lookup[req] = timestamp
+ }
+ keys, err := s.FetchKeys(req.Context(), lookup)
+ if err != nil {
+ return util.ErrorResponse(err)
+ }
+ for req, res := range keys {
+ result[req] = res
+ }
+ response.Results = result
+ return util.JSONResponse{Code: http.StatusOK, JSON: &response}
+ }),
+ )
+ internalAPIMux.Handle(api.ServerKeyInputPublicKeyPath,
+ internal.MakeInternalAPI("inputPublicKeys", func(req *http.Request) util.JSONResponse {
+ request := api.InputPublicKeysRequest{}
+ response := api.InputPublicKeysResponse{}
+ if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
+ return util.MessageResponse(http.StatusBadRequest, err.Error())
+ }
+ store := make(map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult)
+ for req, res := range request.Keys {
+ store[req] = res
+ s.ImmutableCache.StoreServerKey(req, res)
+ }
+ if err := s.StoreKeys(req.Context(), store); err != nil {
+ return util.ErrorResponse(err)
+ }
+ return util.JSONResponse{Code: http.StatusOK, JSON: &response}
+ }),
+ )
+}
diff --git a/serverkeyapi/serverkeyapi.go b/serverkeyapi/serverkeyapi.go
new file mode 100644
index 00000000..61d807d6
--- /dev/null
+++ b/serverkeyapi/serverkeyapi.go
@@ -0,0 +1,83 @@
+package serverkeyapi
+
+import (
+ "crypto/ed25519"
+ "encoding/base64"
+
+ "github.com/matrix-org/dendrite/internal/basecomponent"
+ "github.com/matrix-org/dendrite/serverkeyapi/api"
+ "github.com/matrix-org/dendrite/serverkeyapi/internal"
+ "github.com/matrix-org/dendrite/serverkeyapi/storage"
+ "github.com/matrix-org/dendrite/serverkeyapi/storage/cache"
+ "github.com/matrix-org/gomatrixserverlib"
+ "github.com/sirupsen/logrus"
+)
+
+func SetupServerKeyAPIComponent(
+ base *basecomponent.BaseDendrite,
+ fedClient *gomatrixserverlib.FederationClient,
+) api.ServerKeyInternalAPI {
+ innerDB, err := storage.NewDatabase(
+ string(base.Cfg.Database.ServerKey),
+ base.Cfg.DbProperties(),
+ base.Cfg.Matrix.ServerName,
+ base.Cfg.Matrix.PrivateKey.Public().(ed25519.PublicKey),
+ base.Cfg.Matrix.KeyID,
+ )
+ if err != nil {
+ logrus.WithError(err).Panicf("failed to connect to server key database")
+ }
+
+ serverKeyDB, err := cache.NewKeyDatabase(innerDB, base.ImmutableCache)
+ if err != nil {
+ logrus.WithError(err).Panicf("failed to set up caching wrapper for server key database")
+ }
+
+ internalAPI := internal.ServerKeyAPI{
+ ImmutableCache: base.ImmutableCache,
+ FedClient: fedClient,
+ OurKeyRing: gomatrixserverlib.KeyRing{
+ KeyFetchers: []gomatrixserverlib.KeyFetcher{
+ &gomatrixserverlib.DirectKeyFetcher{
+ Client: fedClient.Client,
+ },
+ },
+ KeyDatabase: serverKeyDB,
+ },
+ }
+
+ var b64e = base64.StdEncoding.WithPadding(base64.NoPadding)
+ for _, ps := range base.Cfg.Matrix.KeyPerspectives {
+ perspective := &gomatrixserverlib.PerspectiveKeyFetcher{
+ PerspectiveServerName: ps.ServerName,
+ PerspectiveServerKeys: map[gomatrixserverlib.KeyID]ed25519.PublicKey{},
+ Client: fedClient.Client,
+ }
+
+ for _, key := range ps.Keys {
+ rawkey, err := b64e.DecodeString(key.PublicKey)
+ if err != nil {
+ logrus.WithError(err).WithFields(logrus.Fields{
+ "server_name": ps.ServerName,
+ "public_key": key.PublicKey,
+ }).Warn("Couldn't parse perspective key")
+ continue
+ }
+ perspective.PerspectiveServerKeys[key.KeyID] = rawkey
+ }
+
+ internalAPI.OurKeyRing.KeyFetchers = append(
+ internalAPI.OurKeyRing.KeyFetchers,
+ perspective,
+ )
+
+ logrus.WithFields(logrus.Fields{
+ "server_name": ps.ServerName,
+ "num_public_keys": len(ps.Keys),
+ }).Info("Enabled perspective key fetcher")
+ }
+
+ internalAPI.SetupHTTP(base.InternalAPIMux)
+
+ return &internalAPI
+}
diff --git a/internal/keydb/cache/keydb.go b/serverkeyapi/storage/cache/keydb.go
index 87573ed2..a0cdb900 100644
--- a/internal/keydb/cache/keydb.go
+++ b/serverkeyapi/storage/cache/keydb.go
@@ -5,18 +5,17 @@ import (
"errors"
"github.com/matrix-org/dendrite/internal/caching"
- "github.com/matrix-org/dendrite/internal/keydb"
"github.com/matrix-org/gomatrixserverlib"
)
// A Database implements gomatrixserverlib.KeyDatabase and is used to store
// the public keys for other matrix servers.
type KeyDatabase struct {
- inner keydb.Database
+ inner gomatrixserverlib.KeyDatabase
cache caching.ImmutableCache
}
-func NewKeyDatabase(inner keydb.Database, cache caching.ImmutableCache) (*KeyDatabase, error) {
+func NewKeyDatabase(inner gomatrixserverlib.KeyDatabase, cache caching.ImmutableCache) (*KeyDatabase, error) {
if inner == nil {
return nil, errors.New("inner database can't be nil")
}
diff --git a/internal/keydb/interface.go b/serverkeyapi/storage/interface.go
index c9a20fdd..3a67ac55 100644
--- a/internal/keydb/interface.go
+++ b/serverkeyapi/storage/interface.go
@@ -1,4 +1,4 @@
-package keydb
+package storage
import (
"context"
diff --git a/internal/keydb/keydb.go b/serverkeyapi/storage/keydb.go
index ad6d56b8..b9389bd6 100644
--- a/internal/keydb/keydb.go
+++ b/serverkeyapi/storage/keydb.go
@@ -14,7 +14,7 @@
// +build !wasm
-package keydb
+package storage
import (
"net/url"
@@ -22,8 +22,8 @@ import (
"golang.org/x/crypto/ed25519"
"github.com/matrix-org/dendrite/internal"
- "github.com/matrix-org/dendrite/internal/keydb/postgres"
- "github.com/matrix-org/dendrite/internal/keydb/sqlite3"
+ "github.com/matrix-org/dendrite/serverkeyapi/storage/postgres"
+ "github.com/matrix-org/dendrite/serverkeyapi/storage/sqlite3"
"github.com/matrix-org/gomatrixserverlib"
)
diff --git a/internal/keydb/keydb_wasm.go b/serverkeyapi/storage/keydb_wasm.go
index c8032902..3d2ca550 100644
--- a/internal/keydb/keydb_wasm.go
+++ b/serverkeyapi/storage/keydb_wasm.go
@@ -12,7 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package keydb
+// +build wasm
+
+package storage
import (
"fmt"
@@ -21,7 +23,7 @@ import (
"golang.org/x/crypto/ed25519"
"github.com/matrix-org/dendrite/internal"
- "github.com/matrix-org/dendrite/internal/keydb/sqlite3"
+ "github.com/matrix-org/dendrite/serverkeyapi/storage/sqlite3"
"github.com/matrix-org/gomatrixserverlib"
)
@@ -41,7 +43,7 @@ func NewDatabase(
case "postgres":
return nil, fmt.Errorf("Cannot use postgres implementation")
case "file":
- return sqlite3.NewDatabase(uri.Path, serverName, serverKey, serverKeyID)
+ return sqlite3.NewDatabase(dataSourceName, serverName, serverKey, serverKeyID)
default:
return nil, fmt.Errorf("Cannot use postgres implementation")
}
diff --git a/internal/keydb/postgres/keydb.go b/serverkeyapi/storage/postgres/keydb.go
index da3a4d37..da3a4d37 100644
--- a/internal/keydb/postgres/keydb.go
+++ b/serverkeyapi/storage/postgres/keydb.go
diff --git a/internal/keydb/postgres/server_key_table.go b/serverkeyapi/storage/postgres/server_key_table.go
index b3c26a48..b3c26a48 100644
--- a/internal/keydb/postgres/server_key_table.go
+++ b/serverkeyapi/storage/postgres/server_key_table.go
diff --git a/internal/keydb/sqlite3/keydb.go b/serverkeyapi/storage/sqlite3/keydb.go
index d1dc61c9..d1dc61c9 100644
--- a/internal/keydb/sqlite3/keydb.go
+++ b/serverkeyapi/storage/sqlite3/keydb.go
diff --git a/internal/keydb/sqlite3/server_key_table.go b/serverkeyapi/storage/sqlite3/server_key_table.go
index ae24a14d..ae24a14d 100644
--- a/internal/keydb/sqlite3/server_key_table.go
+++ b/serverkeyapi/storage/sqlite3/server_key_table.go