e0a9bef6ce
This will allow it to be imported by Go code outside of our repository, which was something we have planned for since this code was written. Signed-off-by: Matt Moyer <moyerm@vmware.com>
59 lines
1.6 KiB
Go
59 lines
1.6 KiB
Go
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
// Package nonce implements
|
|
package nonce
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"crypto/subtle"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/coreos/go-oidc"
|
|
"golang.org/x/oauth2"
|
|
)
|
|
|
|
// Generate generates a new random OIDC nonce parameter of an appropriate size.
|
|
func Generate() (Nonce, error) { return generate(rand.Reader) }
|
|
|
|
func generate(rand io.Reader) (Nonce, error) {
|
|
var buf [16]byte
|
|
if _, err := io.ReadFull(rand, buf[:]); err != nil {
|
|
return "", fmt.Errorf("could not generate random nonce: %w", err)
|
|
}
|
|
return Nonce(hex.EncodeToString(buf[:])), nil
|
|
}
|
|
|
|
// Nonce implements some utilities for working with OIDC nonce parameters.
|
|
type Nonce string
|
|
|
|
// String returns the string encoding of this state value.
|
|
func (n *Nonce) String() string {
|
|
return string(*n)
|
|
}
|
|
|
|
// Param returns the OAuth2 auth code parameter for sending the nonce during the authorization request.
|
|
func (n *Nonce) Param() oauth2.AuthCodeOption {
|
|
return oidc.Nonce(string(*n))
|
|
}
|
|
|
|
// Validate the returned ID token). Returns true iff the nonce matches or the returned JWT does not have a nonce.
|
|
func (n *Nonce) Validate(token *oidc.IDToken) error {
|
|
if subtle.ConstantTimeCompare([]byte(token.Nonce), []byte(*n)) != 1 {
|
|
return InvalidNonceError{Expected: *n, Got: Nonce(token.Nonce)}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// InvalidNonceError is returned by Validate when the observed nonce is invalid.
|
|
type InvalidNonceError struct {
|
|
Expected Nonce
|
|
Got Nonce
|
|
}
|
|
|
|
func (e InvalidNonceError) Error() string {
|
|
return fmt.Sprintf("invalid nonce (expected %q, got %q)", e.Expected.String(), e.Got.String())
|
|
}
|