mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-02-05 04:15:03 +00:00
a773768718
Bumps [github.com/SherClockHolmes/webpush-go](https://github.com/SherClockHolmes/webpush-go) from 1.3.0 to 1.4.0. - [Release notes](https://github.com/SherClockHolmes/webpush-go/releases) - [Commits](https://github.com/SherClockHolmes/webpush-go/compare/v1.3.0...v1.4.0) --- updated-dependencies: - dependency-name: github.com/SherClockHolmes/webpush-go dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
119 lines
2.6 KiB
Go
119 lines
2.6 KiB
Go
package webpush
|
|
|
|
import (
|
|
"crypto/ecdsa"
|
|
"crypto/elliptic"
|
|
"crypto/rand"
|
|
"encoding/base64"
|
|
"math/big"
|
|
"net/url"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/golang-jwt/jwt/v5"
|
|
)
|
|
|
|
// GenerateVAPIDKeys will create a private and public VAPID key pair
|
|
func GenerateVAPIDKeys() (privateKey, publicKey string, err error) {
|
|
// Get the private key from the P256 curve
|
|
curve := elliptic.P256()
|
|
|
|
private, x, y, err := elliptic.GenerateKey(curve, rand.Reader)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
public := elliptic.Marshal(curve, x, y)
|
|
|
|
// Convert to base64
|
|
publicKey = base64.RawURLEncoding.EncodeToString(public)
|
|
privateKey = base64.RawURLEncoding.EncodeToString(private)
|
|
|
|
return
|
|
}
|
|
|
|
// Generates the ECDSA public and private keys for the JWT encryption
|
|
func generateVAPIDHeaderKeys(privateKey []byte) *ecdsa.PrivateKey {
|
|
// Public key
|
|
curve := elliptic.P256()
|
|
px, py := curve.ScalarMult(
|
|
curve.Params().Gx,
|
|
curve.Params().Gy,
|
|
privateKey,
|
|
)
|
|
|
|
pubKey := ecdsa.PublicKey{
|
|
Curve: curve,
|
|
X: px,
|
|
Y: py,
|
|
}
|
|
|
|
// Private key
|
|
d := &big.Int{}
|
|
d.SetBytes(privateKey)
|
|
|
|
return &ecdsa.PrivateKey{
|
|
PublicKey: pubKey,
|
|
D: d,
|
|
}
|
|
}
|
|
|
|
// getVAPIDAuthorizationHeader
|
|
func getVAPIDAuthorizationHeader(
|
|
endpoint,
|
|
subscriber,
|
|
vapidPublicKey,
|
|
vapidPrivateKey string,
|
|
expiration time.Time,
|
|
) (string, error) {
|
|
// Create the JWT token
|
|
subURL, err := url.Parse(endpoint)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// Unless subscriber is an HTTPS URL, assume an e-mail address
|
|
if !strings.HasPrefix(subscriber, "https:") {
|
|
subscriber = "mailto:" + subscriber
|
|
}
|
|
|
|
token := jwt.NewWithClaims(jwt.SigningMethodES256, jwt.MapClaims{
|
|
"aud": subURL.Scheme + "://" + subURL.Host,
|
|
"exp": time.Now().Add(time.Hour * 12).Unix(),
|
|
"sub": subscriber,
|
|
})
|
|
|
|
// Decode the VAPID private key
|
|
decodedVapidPrivateKey, err := decodeVapidKey(vapidPrivateKey)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
privKey := generateVAPIDHeaderKeys(decodedVapidPrivateKey)
|
|
|
|
// Sign token with private key
|
|
jwtString, err := token.SignedString(privKey)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// Decode the VAPID public key
|
|
pubKey, err := decodeVapidKey(vapidPublicKey)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return "vapid t=" + jwtString + ", k=" + base64.RawURLEncoding.EncodeToString(pubKey), nil
|
|
}
|
|
|
|
// Need to decode the vapid private key in multiple base64 formats
|
|
// Solution from: https://github.com/SherClockHolmes/webpush-go/issues/29
|
|
func decodeVapidKey(key string) ([]byte, error) {
|
|
bytes, err := base64.URLEncoding.DecodeString(key)
|
|
if err == nil {
|
|
return bytes, nil
|
|
}
|
|
|
|
return base64.RawURLEncoding.DecodeString(key)
|
|
}
|