mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-10-28 23:52:25 -05:00
- update gruf/go-stroage v0.2.0 -> v0.2.1 - update KimMachineGun/automemlimit v0.7.1 -> v0.7.2 - update miekg/dns v1.1.65 -> v1.1.66 - update ncruces/go-sqlite3 v0.25.1 -> v0.25.2 - update spf13/cast v1.7.1 -> v1.8.0 - update tdewolff/minify/v2 v2.23.1 -> v2.23.5 - update x/crypto v0.37.0 -> v0.38.0 - update x/image v0.26.0 -> v0.27.0 - update x/net v0.39.0 -> v0.40.0 - update x/oauth2 v0.29.0 -> v0.30.0 - update x/sys v0.32.0 -> v0.33.0 - update x/text v0.24.0 -> v0.25.0 Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4162 Co-authored-by: kim <grufwub@gmail.com> Co-committed-by: kim <grufwub@gmail.com>
69 lines
2.3 KiB
Go
69 lines
2.3 KiB
Go
// Copyright 2023 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package oauth2
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"crypto/sha256"
|
|
"encoding/base64"
|
|
"net/url"
|
|
)
|
|
|
|
const (
|
|
codeChallengeKey = "code_challenge"
|
|
codeChallengeMethodKey = "code_challenge_method"
|
|
codeVerifierKey = "code_verifier"
|
|
)
|
|
|
|
// GenerateVerifier generates a PKCE code verifier with 32 octets of randomness.
|
|
// This follows recommendations in RFC 7636.
|
|
//
|
|
// A fresh verifier should be generated for each authorization.
|
|
// The resulting verifier should be passed to [Config.AuthCodeURL] or [Config.DeviceAuth]
|
|
// with [S256ChallengeOption], and to [Config.Exchange] or [Config.DeviceAccessToken]
|
|
// with [VerifierOption].
|
|
func GenerateVerifier() string {
|
|
// "RECOMMENDED that the output of a suitable random number generator be
|
|
// used to create a 32-octet sequence. The octet sequence is then
|
|
// base64url-encoded to produce a 43-octet URL-safe string to use as the
|
|
// code verifier."
|
|
// https://datatracker.ietf.org/doc/html/rfc7636#section-4.1
|
|
data := make([]byte, 32)
|
|
if _, err := rand.Read(data); err != nil {
|
|
panic(err)
|
|
}
|
|
return base64.RawURLEncoding.EncodeToString(data)
|
|
}
|
|
|
|
// VerifierOption returns a PKCE code verifier [AuthCodeOption]. It should only be
|
|
// passed to [Config.Exchange] or [Config.DeviceAccessToken].
|
|
func VerifierOption(verifier string) AuthCodeOption {
|
|
return setParam{k: codeVerifierKey, v: verifier}
|
|
}
|
|
|
|
// S256ChallengeFromVerifier returns a PKCE code challenge derived from verifier with method S256.
|
|
//
|
|
// Prefer to use [S256ChallengeOption] where possible.
|
|
func S256ChallengeFromVerifier(verifier string) string {
|
|
sha := sha256.Sum256([]byte(verifier))
|
|
return base64.RawURLEncoding.EncodeToString(sha[:])
|
|
}
|
|
|
|
// S256ChallengeOption derives a PKCE code challenge derived from verifier with
|
|
// method S256. It should be passed to [Config.AuthCodeURL] or [Config.DeviceAuth]
|
|
// only.
|
|
func S256ChallengeOption(verifier string) AuthCodeOption {
|
|
return challengeOption{
|
|
challenge_method: "S256",
|
|
challenge: S256ChallengeFromVerifier(verifier),
|
|
}
|
|
}
|
|
|
|
type challengeOption struct{ challenge_method, challenge string }
|
|
|
|
func (p challengeOption) setValue(m url.Values) {
|
|
m.Set(codeChallengeMethodKey, p.challenge_method)
|
|
m.Set(codeChallengeKey, p.challenge)
|
|
}
|