97 lines
3 KiB
Go
97 lines
3 KiB
Go
package webshared
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"strings"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
|
|
"git.mstar.dev/mstar/linstrom/config"
|
|
"git.mstar.dev/mstar/linstrom/shared"
|
|
)
|
|
|
|
// Generate the signed string of the headers, method and target
|
|
// and sign it using the given RSA key. Returns the base64 encoded
|
|
// result
|
|
func CreateSignatureRSA(
|
|
method string,
|
|
target string,
|
|
headers map[string]string,
|
|
privateKeyBytes []byte,
|
|
) (string, []string, error) {
|
|
message, usedHeaders := genPreSignatureString(method, target, headers)
|
|
log.Error().Str("message", message)
|
|
signed, err := shared.Sign(message, privateKeyBytes, true)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
encoded := base64.StdEncoding.EncodeToString(signed)
|
|
log.Debug().
|
|
Str("raw-message", message).
|
|
Bytes("signed", signed).
|
|
Str("encoded", encoded).
|
|
Strs("header-order", usedHeaders).
|
|
Msg("Signing complete")
|
|
return encoded, usedHeaders, nil
|
|
}
|
|
|
|
// Generate the signed string of the headers, method and target
|
|
// and sign it using the given ED25519 key. Returns the base64
|
|
// encoded result
|
|
func CreateSignatureED(
|
|
method string,
|
|
target string,
|
|
headers map[string]string,
|
|
privateKeyBytes []byte,
|
|
) (string, []string, error) {
|
|
message, usedHeaders := genPreSignatureString(method, target, headers)
|
|
signed, err := shared.Sign(message, privateKeyBytes, false)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
return base64.StdEncoding.EncodeToString(signed), usedHeaders, nil
|
|
}
|
|
|
|
func genPreSignatureString(method, target string, headers map[string]string) (string, []string) {
|
|
dataBuilder := strings.Builder{}
|
|
dataBuilder.WriteString("(request-target): ")
|
|
dataBuilder.WriteString(strings.ToLower(method) + " ")
|
|
dataBuilder.WriteString(target + "\n")
|
|
// dataBuilder.WriteString("algorithm: rsa-sha256\n")
|
|
// usedHeaders := []string{"(request-target)", "algorithm"}
|
|
usedHeaders := []string{"(request-target)"}
|
|
for k, v := range headers {
|
|
dataBuilder.WriteString(k + ": " + v + "\n")
|
|
usedHeaders = append(usedHeaders, k)
|
|
}
|
|
tmp := strings.TrimSuffix(dataBuilder.String(), "\n")
|
|
log.Debug().Str("Raw signature string", tmp).Send()
|
|
return tmp, usedHeaders
|
|
}
|
|
|
|
// Generate the content of the "Signature" header based on
|
|
// The user who's key was used, the hashed and base64 encoded
|
|
// signed string, as returned by CreateSignatureED/RSA
|
|
func CreateSignatureHeaderContent(userId string, hash string, headerNames ...string) string {
|
|
builder := strings.Builder{}
|
|
builder.WriteString("keyId=\"")
|
|
builder.WriteString(config.GlobalConfig.General.GetFullPublicUrl())
|
|
builder.WriteString("/api/activitypub/user/")
|
|
builder.WriteString(userId)
|
|
builder.WriteString("\",headers=\"")
|
|
for i, header := range headerNames {
|
|
builder.WriteString(header)
|
|
if i+1 < len(headerNames) {
|
|
builder.WriteRune(' ')
|
|
}
|
|
}
|
|
if config.GlobalConfig.Experimental.UseEd25519Keys {
|
|
builder.WriteString("\",algorithm=\"ed-sha512\",signature=\"")
|
|
} else {
|
|
builder.WriteString("\",algorithm=\"rsa-sha256\",signature=\"")
|
|
}
|
|
builder.WriteString(hash)
|
|
builder.WriteRune('"')
|
|
|
|
return builder.String()
|
|
}
|