-
Notifications
You must be signed in to change notification settings - Fork 80
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support Synapse's (and technically Dendrite's) multi-key format
- Loading branch information
Showing
13 changed files
with
642 additions
and
129 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package _common | ||
|
||
import ( | ||
"os" | ||
|
||
"github.com/sirupsen/logrus" | ||
"github.com/turt2live/matrix-media-repo/homeserver_interop" | ||
"github.com/turt2live/matrix-media-repo/homeserver_interop/dendrite" | ||
"github.com/turt2live/matrix-media-repo/homeserver_interop/mmr" | ||
"github.com/turt2live/matrix-media-repo/homeserver_interop/synapse" | ||
) | ||
|
||
func EncodeSigningKeys(keys []*homeserver_interop.SigningKey, format string, file string) { | ||
var err error | ||
var b []byte | ||
switch format { | ||
case "synapse": | ||
b, err = synapse.EncodeAllSigningKeys(keys) | ||
case "dendrite": | ||
b, err = dendrite.EncodeAllSigningKeys(keys) | ||
case "mmr": | ||
b, err = mmr.EncodeAllSigningKeys(keys) | ||
default: | ||
logrus.Fatalf("Unknown output format '%s'. Try '%s -help' for information.", format, os.Args[0]) | ||
} | ||
if err != nil { | ||
logrus.Fatal(err) | ||
} | ||
|
||
f, err := os.Create(file) | ||
if err != nil { | ||
logrus.Fatal(err) | ||
} | ||
defer func(f *os.File) { | ||
_ = f.Close() | ||
}(f) | ||
|
||
_, err = f.Write(b) | ||
if err != nil { | ||
logrus.Fatal(err) | ||
} | ||
|
||
logrus.Infof("Done! Signing key written to '%s' in %s format", f.Name(), format) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package main | ||
|
||
import ( | ||
"flag" | ||
"os" | ||
|
||
"github.com/sirupsen/logrus" | ||
"github.com/turt2live/matrix-media-repo/cmd/utilities/_common" | ||
"github.com/turt2live/matrix-media-repo/homeserver_interop" | ||
"github.com/turt2live/matrix-media-repo/homeserver_interop/any_server" | ||
"github.com/turt2live/matrix-media-repo/util" | ||
) | ||
|
||
func main() { | ||
outputFormat := flag.String("format", "mmr", "The output format for the key. May be 'mmr', 'synapse', or 'dendrite'.") | ||
outputFile := flag.String("output", "./signing.key", "The output file for the key. Note that not all software will use multiple keys.") | ||
flag.Parse() | ||
|
||
keys := make(map[string]*homeserver_interop.SigningKey) | ||
keysArray := make([]*homeserver_interop.SigningKey, 0) | ||
for _, file := range flag.Args() { | ||
logrus.Infof("Reading %s", file) | ||
|
||
localKeys, err := decodeKeys(file) | ||
if err != nil { | ||
logrus.Fatal(err) | ||
} | ||
|
||
for _, key := range localKeys { | ||
if val, ok := keys[key.KeyVersion]; ok { | ||
logrus.Fatalf("Duplicate key version '%s' detected. Known='%s', duplicate='%s'", key.KeyVersion, util.EncodeUnpaddedBase64ToString(val.PrivateKey), util.EncodeUnpaddedBase64ToString(key.PrivateKey)) | ||
} | ||
|
||
keys[key.KeyVersion] = key | ||
keysArray = append(keysArray, key) | ||
} | ||
} | ||
|
||
_common.EncodeSigningKeys(keysArray, *outputFormat, *outputFile) | ||
} | ||
|
||
func decodeKeys(fileName string) ([]*homeserver_interop.SigningKey, error) { | ||
f, err := os.Open(fileName) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer f.Close() | ||
|
||
return any_server.DecodeAllSigningKeys(f) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,57 @@ | ||
package any_server | ||
|
||
import ( | ||
"crypto/ed25519" | ||
"errors" | ||
"io" | ||
|
||
"github.com/turt2live/matrix-media-repo/homeserver_interop" | ||
"github.com/turt2live/matrix-media-repo/homeserver_interop/dendrite" | ||
"github.com/turt2live/matrix-media-repo/homeserver_interop/mmr" | ||
"github.com/turt2live/matrix-media-repo/homeserver_interop/synapse" | ||
) | ||
|
||
func DecodeSigningKey(key io.ReadSeeker) (ed25519.PrivateKey, string, error) { | ||
var keyVersion string | ||
var priv ed25519.PrivateKey | ||
func DecodeSigningKey(key io.ReadSeeker) (*homeserver_interop.SigningKey, error) { | ||
keys, err := DecodeAllSigningKeys(key) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return keys[0], nil | ||
} | ||
|
||
func DecodeAllSigningKeys(key io.ReadSeeker) ([]*homeserver_interop.SigningKey, error) { | ||
var keys []*homeserver_interop.SigningKey | ||
var err error | ||
|
||
var errorStack error | ||
|
||
// Try Synapse first, as the most popular | ||
priv, keyVersion, err = synapse.DecodeSigningKey(key) | ||
keys, err = synapse.DecodeAllSigningKeys(key) | ||
if err == nil { | ||
return priv, keyVersion, nil | ||
return keys, nil | ||
} | ||
errorStack = errors.Join(errors.New("synapse: unable to decode"), err, errorStack) | ||
|
||
// Rewind & try Dendrite | ||
if _, err = key.Seek(0, io.SeekStart); err != nil { | ||
return nil, "", err | ||
return nil, err | ||
} | ||
priv, keyVersion, err = dendrite.DecodeSigningKey(key) | ||
keys, err = dendrite.DecodeAllSigningKeys(key) | ||
if err == nil { | ||
return priv, keyVersion, nil | ||
return keys, nil | ||
} | ||
errorStack = errors.Join(errors.New("dendrite: unable to decode"), err, errorStack) | ||
|
||
// Rewind & try MMR | ||
if _, err = key.Seek(0, io.SeekStart); err != nil { | ||
return nil, "", err | ||
return nil, err | ||
} | ||
priv, keyVersion, err = mmr.DecodeSigningKey(key) | ||
keys, err = mmr.DecodeAllSigningKeys(key) | ||
if err == nil { | ||
return priv, keyVersion, nil | ||
return keys, nil | ||
} | ||
errorStack = errors.Join(errors.New("mmr: unable to decode"), err, errorStack) | ||
|
||
// Fail case | ||
return nil, "", errors.Join(errors.New("unable to detect signing key format"), errorStack) | ||
return nil, errors.Join(errors.New("unable to detect signing key format"), errorStack) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package internal | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
|
||
"github.com/turt2live/matrix-media-repo/homeserver_interop" | ||
) | ||
|
||
func EncodeNewlineAppendFormattedSigningKeys(keys []*homeserver_interop.SigningKey, encodeFn func(*homeserver_interop.SigningKey) ([]byte, error)) ([]byte, error) { | ||
buf := &bytes.Buffer{} | ||
for i, key := range keys { | ||
b, err := encodeFn(key) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
n, err := buf.Write(b) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if n != len(b) { | ||
return nil, fmt.Errorf("wrote %d bytes but expected %d bytes", n, len(b)) | ||
} | ||
|
||
if b[len(b)-1] != '\n' && i != (len(keys)-1) { | ||
n, err = buf.Write([]byte{'\n'}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if n != 1 { | ||
return nil, fmt.Errorf("wrote %d bytes but expected %d bytes", n, 1) | ||
} | ||
} | ||
} | ||
return buf.Bytes(), nil | ||
} |
Oops, something went wrong.