46 lines
1.4 KiB
Go
46 lines
1.4 KiB
Go
|
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
||
|
// SPDX-License-Identifier: Apache-2.0
|
||
|
|
||
|
package pkce
|
||
|
|
||
|
import (
|
||
|
"crypto/rand"
|
||
|
"crypto/sha256"
|
||
|
"encoding/base64"
|
||
|
"encoding/hex"
|
||
|
"io"
|
||
|
|
||
|
"github.com/pkg/errors"
|
||
|
"golang.org/x/oauth2"
|
||
|
)
|
||
|
|
||
|
// Generate generates a new random PKCE code.
|
||
|
func Generate() (Code, error) { return generate(rand.Reader) }
|
||
|
|
||
|
func generate(rand io.Reader) (Code, error) {
|
||
|
var buf [32]byte
|
||
|
if _, err := io.ReadFull(rand, buf[:]); err != nil {
|
||
|
return "", errors.WithMessage(err, "could not generate PKCE code")
|
||
|
}
|
||
|
return Code(hex.EncodeToString(buf[:])), nil
|
||
|
}
|
||
|
|
||
|
// Code implements the basic options required for RFC 7636: Proof Key for Code Exchange (PKCE).
|
||
|
type Code string
|
||
|
|
||
|
// Challenge returns the OAuth2 auth code parameter for sending the PKCE code challenge.
|
||
|
func (p *Code) Challenge() oauth2.AuthCodeOption {
|
||
|
b := sha256.Sum256([]byte(*p))
|
||
|
return oauth2.SetAuthURLParam("code_challenge", base64.RawURLEncoding.EncodeToString(b[:]))
|
||
|
}
|
||
|
|
||
|
// Method returns the OAuth2 auth code parameter for sending the PKCE code challenge method.
|
||
|
func (p *Code) Method() oauth2.AuthCodeOption {
|
||
|
return oauth2.SetAuthURLParam("code_challenge_method", "S256")
|
||
|
}
|
||
|
|
||
|
// Verifier returns the OAuth2 auth code parameter for sending the PKCE code verifier.
|
||
|
func (p *Code) Verifier() oauth2.AuthCodeOption {
|
||
|
return oauth2.SetAuthURLParam("code_verifier", string(*p))
|
||
|
}
|