Enforce valid key IDs (#1437)

* Enforce valid key IDs

* Don't use key_id from dendrite.yaml as it is in matrix_key.pem
This commit is contained in:
Neil Alexander 2020-09-23 11:07:57 +01:00 committed by GitHub
parent f908f8baab
commit de8b39065e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 13 additions and 5 deletions

View file

@ -38,9 +38,6 @@ global:
# The path to the signing private key file, used to sign requests and events. # The path to the signing private key file, used to sign requests and events.
private_key: matrix_key.pem private_key: matrix_key.pem
# A unique identifier for this private key. Must start with the prefix "ed25519:".
key_id: ed25519:auto
# How long a remote server can cache our server signing key before requesting it # How long a remote server can cache our server signing key before requesting it
# again. Increasing this number will reduce the number of requests made by other # again. Increasing this number will reduce the number of requests made by other
# servers for our key but increases the period that a compromised key will be # servers for our key but increases the period that a compromised key will be

View file

@ -36,6 +36,9 @@ import (
jaegermetrics "github.com/uber/jaeger-lib/metrics" jaegermetrics "github.com/uber/jaeger-lib/metrics"
) )
// keyIDRegexp defines allowable characters in Key IDs.
var keyIDRegexp = regexp.MustCompile("^ed25519:[a-zA-Z0-9_]+$")
// Version is the current version of the config format. // Version is the current version of the config format.
// This will change whenever we make breaking changes to the config format. // This will change whenever we make breaking changes to the config format.
const Version = 1 const Version = 1
@ -459,6 +462,9 @@ func readKeyPEM(path string, data []byte) (gomatrixserverlib.KeyID, ed25519.Priv
if !strings.HasPrefix(keyID, "ed25519:") { if !strings.HasPrefix(keyID, "ed25519:") {
return "", nil, fmt.Errorf("key ID %q doesn't start with \"ed25519:\" in %q", keyID, path) return "", nil, fmt.Errorf("key ID %q doesn't start with \"ed25519:\" in %q", keyID, path)
} }
if !keyIDRegexp.MatchString(keyID) {
return "", nil, fmt.Errorf("key ID %q in %q contains illegal characters (use a-z, A-Z, 0-9 and _ only)", keyID, path)
}
_, privKey, err := ed25519.GenerateKey(bytes.NewReader(keyBlock.Bytes)) _, privKey, err := ed25519.GenerateKey(bytes.NewReader(keyBlock.Bytes))
if err != nil { if err != nil {
return "", nil, err return "", nil, err

View file

@ -20,7 +20,7 @@ type Global struct {
// An arbitrary string used to uniquely identify the PrivateKey. Must start with the // An arbitrary string used to uniquely identify the PrivateKey. Must start with the
// prefix "ed25519:". // prefix "ed25519:".
KeyID gomatrixserverlib.KeyID `yaml:"key_id"` KeyID gomatrixserverlib.KeyID `yaml:"-"`
// How long a remote server can cache our server key for before requesting it again. // How long a remote server can cache our server key for before requesting it again.
// Increasing this number will reduce the number of requests made by remote servers // Increasing this number will reduce the number of requests made by remote servers

View file

@ -25,6 +25,7 @@ import (
"math/big" "math/big"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"time" "time"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
@ -146,10 +147,14 @@ func NewMatrixKey(matrixKeyPath string) (err error) {
err = keyOut.Close() err = keyOut.Close()
})() })()
keyID := base64.RawURLEncoding.EncodeToString(data[:])
keyID = strings.ReplaceAll(keyID, "-", "")
keyID = strings.ReplaceAll(keyID, "_", "")
err = pem.Encode(keyOut, &pem.Block{ err = pem.Encode(keyOut, &pem.Block{
Type: "MATRIX PRIVATE KEY", Type: "MATRIX PRIVATE KEY",
Headers: map[string]string{ Headers: map[string]string{
"Key-ID": "ed25519:" + base64.RawStdEncoding.EncodeToString(data[:3]), "Key-ID": fmt.Sprintf("ed25519:%s", keyID[:6]),
}, },
Bytes: data[3:], Bytes: data[3:],
}) })