@@ -2,10 +2,12 @@ package encryption
22
33import (
44 "crypto/hmac"
5+ "crypto/rand"
56 "crypto/sha256"
67 "encoding/base64"
78 "fmt"
89 "hash"
10+ "math/big"
911 "net/http"
1012 "strconv"
1113 "strings"
@@ -15,6 +17,7 @@ import (
1517const (
1618 CodeChallengeMethodPlain = "plain"
1719 CodeChallengeMethodS256 = "S256"
20+ asciiCharset = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
1821)
1922
2023// SecretBytes attempts to base64 decode the secret, if that fails it treats the secret as binary
@@ -80,6 +83,19 @@ func SignedValue(seed string, key string, value []byte, now time.Time) (string,
8083 return cookieVal, nil
8184}
8285
86+func GenerateRandomASCIIString(length int) (string, error) {
87+ b := make([]byte, length)
88+ charsetLen := new(big.Int).SetInt64(int64(len(asciiCharset)))
89+ for i := range b {
90+ character, err := rand.Int(rand.Reader, charsetLen)
91+ if err != nil {
92+ return "", err
93+ }
94+ b[i] = asciiCharset[character.Int64()]
95+ }
96+ return string(b), nil
97+}
98+
8399func GenerateCodeChallenge(method, codeVerifier string) (string, error) {
84100 switch method {
85101 case CodeChallengeMethodPlain: