diff --git a/hub.go b/hub.go index 15163a42..2b982cab 100644 --- a/hub.go +++ b/hub.go @@ -22,12 +22,16 @@ package signaling import ( + "bytes" "context" + "crypto/ed25519" "crypto/hmac" "crypto/sha256" + "crypto/x509" "encoding/base64" "encoding/hex" "encoding/json" + "encoding/pem" "errors" "fmt" "hash/fnv" @@ -1030,6 +1034,24 @@ func (h *Hub) processHelloV2(client *Client, message *ClientMessage) (*Backend, } case *jwt.SigningMethodEd25519: loadKeyFunc = func(data []byte) (interface{}, error) { + if !bytes.HasPrefix(data, []byte("-----BEGIN ")) { + // Nextcloud sends the Ed25519 key as base64-encoded public key data. + decoded, err := base64.StdEncoding.DecodeString(string(data)) + if err != nil { + return nil, err + } + + key := ed25519.PublicKey(decoded) + data, err = x509.MarshalPKIXPublicKey(key) + if err != nil { + return nil, err + } + + data = pem.EncodeToMemory(&pem.Block{ + Type: "PUBLIC KEY", + Bytes: data, + }) + } return jwt.ParseEdPublicKeyFromPEM(data) } default: diff --git a/hub_test.go b/hub_test.go index fbdb8616..9e56a7ef 100644 --- a/hub_test.go +++ b/hub_test.go @@ -68,6 +68,7 @@ var ( "RSA", "ECDSA", "Ed25519", + "Ed25519_Nextcloud", } ) @@ -715,7 +716,13 @@ func registerBackendHandlerUrl(t *testing.T, router *mux.Router, url string) { Type: pemType, Bytes: public, }) - signaling[ConfigKeyHelloV2TokenKey] = string(public) + if strings.Contains(t.Name(), "Ed25519_Nextcloud") { + // Simulate Nextcloud which returns the Ed25519 key as base64-encoded data. + encoded := base64.StdEncoding.EncodeToString(key.(ed25519.PublicKey)) + signaling[ConfigKeyHelloV2TokenKey] = encoded + } else { + signaling[ConfigKeyHelloV2TokenKey] = string(public) + } } spreedCapa, _ := json.Marshal(map[string]interface{}{ "features": features,