...
1
16
17
18 package utils
19
20 import (
21 "crypto/sha256"
22 "encoding/base64"
23 "fmt"
24 "math/rand"
25 "strings"
26 )
27
28 const (
29 MinLength = 32
30 MaxLength = 96
31 )
32
33 type PKCECodeVerifier struct {
34 CodeVerifier string
35 }
36
37 func (v *PKCECodeVerifier) String() string {
38 return v.CodeVerifier
39 }
40
41
42 func (v *PKCECodeVerifier) CodeChallengePlain() string {
43 return v.CodeVerifier
44 }
45
46
47 func (v *PKCECodeVerifier) CodeChallengeS256() string {
48 h := sha256.New()
49 h.Write([]byte(v.CodeVerifier))
50 return encode(h.Sum(nil))
51 }
52
53
54 func GenerateCodeVerifier() (*PKCECodeVerifier, error) {
55 return GenerateCodeVerifierWithLength(MinLength)
56 }
57
58
59 func GenerateCodeVerifierWithLength(length int) (*PKCECodeVerifier, error) {
60 if length < MinLength || length > MaxLength {
61 return nil, fmt.Errorf("invalid length: %v", length)
62 }
63
64 b, err := bytes(length)
65 if err != nil {
66 return nil, err
67 }
68 return &PKCECodeVerifier{
69 CodeVerifier: encode(b),
70 }, nil
71 }
72
73
74 func bytes(n int) ([]byte, error) {
75 b := make([]byte, n)
76 _, err := rand.Read(b)
77 return b, err
78 }
79
80
81 func encode(b []byte) string {
82 encoded := base64.StdEncoding.EncodeToString(b)
83 encoded = strings.Replace(encoded, "+", "-", -1)
84 encoded = strings.Replace(encoded, "/", "_", -1)
85 encoded = strings.Replace(encoded, "=", "", -1)
86 return encoded
87 }
88
View as plain text