updated deps; updated healthchecks.io integration
This commit is contained in:
94
vendor/maunium.net/go/mautrix/crypto/signatures/signatures.go
generated
vendored
Normal file
94
vendor/maunium.net/go/mautrix/crypto/signatures/signatures.go
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
// Copyright (c) 2024 Sumner Evans
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package signatures
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
"github.com/tidwall/sjson"
|
||||
"go.mau.fi/util/exgjson"
|
||||
|
||||
"maunium.net/go/mautrix/crypto/canonicaljson"
|
||||
"maunium.net/go/mautrix/crypto/goolm/crypto"
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrEmptyInput = errors.New("empty input")
|
||||
ErrSignatureNotFound = errors.New("input JSON doesn't contain signature from specified device")
|
||||
)
|
||||
|
||||
// Signatures represents a set of signatures for some data from multiple users
|
||||
// and keys.
|
||||
type Signatures map[id.UserID]map[id.KeyID]string
|
||||
|
||||
// NewSingleSignature creates a new [Signatures] object with a single
|
||||
// signature.
|
||||
func NewSingleSignature(userID id.UserID, algorithm id.KeyAlgorithm, keyID string, signature string) Signatures {
|
||||
return Signatures{
|
||||
userID: {
|
||||
id.NewKeyID(algorithm, keyID): signature,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// VerifySignature verifies an Ed25519 signature.
|
||||
func VerifySignature(message []byte, key id.Ed25519, signature []byte) (ok bool, err error) {
|
||||
if len(message) == 0 || len(key) == 0 || len(signature) == 0 {
|
||||
return false, ErrEmptyInput
|
||||
}
|
||||
keyDecoded, err := base64.RawStdEncoding.DecodeString(key.String())
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
publicKey := crypto.Ed25519PublicKey(keyDecoded)
|
||||
return publicKey.Verify(message, signature), nil
|
||||
}
|
||||
|
||||
// VerifySignatureJSON verifies the signature in the given JSON object "obj"
|
||||
// as described in [Appendix 3] of the Matrix Spec.
|
||||
//
|
||||
// This function is a wrapper over [Utility.VerifySignatureJSON] that creates
|
||||
// and destroys the [Utility] object transparently.
|
||||
//
|
||||
// If the "obj" is not already a [json.RawMessage], it will re-encoded as JSON
|
||||
// for the verification, so "json" tags will be honored.
|
||||
//
|
||||
// [Appendix 3]: https://spec.matrix.org/v1.9/appendices/#signing-json
|
||||
func VerifySignatureJSON(obj any, userID id.UserID, keyName string, key id.Ed25519) (bool, error) {
|
||||
var err error
|
||||
objJSON, ok := obj.(json.RawMessage)
|
||||
if !ok {
|
||||
objJSON, err = json.Marshal(obj)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
sig := gjson.GetBytes(objJSON, exgjson.Path("signatures", string(userID), fmt.Sprintf("ed25519:%s", keyName)))
|
||||
if !sig.Exists() || sig.Type != gjson.String {
|
||||
return false, ErrSignatureNotFound
|
||||
}
|
||||
objJSON, err = sjson.DeleteBytes(objJSON, "unsigned")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
objJSON, err = sjson.DeleteBytes(objJSON, "signatures")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
objJSONString := canonicaljson.CanonicalJSONAssumeValid(objJSON)
|
||||
sigBytes, err := base64.RawStdEncoding.DecodeString(sig.Str)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return VerifySignature(objJSONString, key, sigBytes)
|
||||
}
|
||||
Reference in New Issue
Block a user