mirror of
https://github.com/containers/skopeo.git
synced 2025-09-17 23:39:13 +00:00
Update module github.com/containers/image/v5 to v5.36.0
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This commit is contained in:
27
vendor/golang.org/x/mod/LICENSE
generated
vendored
27
vendor/golang.org/x/mod/LICENSE
generated
vendored
@@ -1,27 +0,0 @@
|
||||
Copyright 2009 The Go Authors.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google LLC nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
22
vendor/golang.org/x/mod/PATENTS
generated
vendored
22
vendor/golang.org/x/mod/PATENTS
generated
vendored
@@ -1,22 +0,0 @@
|
||||
Additional IP Rights Grant (Patents)
|
||||
|
||||
"This implementation" means the copyrightable works distributed by
|
||||
Google as part of the Go project.
|
||||
|
||||
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||
patent license to make, have made, use, offer to sell, sell, import,
|
||||
transfer and otherwise run, modify and propagate the contents of this
|
||||
implementation of Go, where such license applies only to those patent
|
||||
claims, both currently owned or controlled by Google and acquired in
|
||||
the future, licensable by Google that are necessarily infringed by this
|
||||
implementation of Go. This grant does not include claims that would be
|
||||
infringed only as a consequence of further modification of this
|
||||
implementation. If you or your agent or exclusive licensee institute or
|
||||
order or agree to the institution of patent litigation against any
|
||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that this implementation of Go or any code incorporated within this
|
||||
implementation of Go constitutes direct or contributory patent
|
||||
infringement, or inducement of patent infringement, then any patent
|
||||
rights granted to you under this License for this implementation of Go
|
||||
shall terminate as of the date such litigation is filed.
|
678
vendor/golang.org/x/mod/sumdb/note/note.go
generated
vendored
678
vendor/golang.org/x/mod/sumdb/note/note.go
generated
vendored
@@ -1,678 +0,0 @@
|
||||
// Copyright 2019 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 note defines the notes signed by the Go module database server.
|
||||
//
|
||||
// A note is text signed by one or more server keys.
|
||||
// The text should be ignored unless the note is signed by
|
||||
// a trusted server key and the signature has been verified
|
||||
// using the server's public key.
|
||||
//
|
||||
// A server's public key is identified by a name, typically the "host[/path]"
|
||||
// giving the base URL of the server's transparency log.
|
||||
// The syntactic restrictions on a name are that it be non-empty,
|
||||
// well-formed UTF-8 containing neither Unicode spaces nor plus (U+002B).
|
||||
//
|
||||
// A Go module database server signs texts using public key cryptography.
|
||||
// A given server may have multiple public keys, each
|
||||
// identified by a 32-bit hash of the public key.
|
||||
//
|
||||
// # Verifying Notes
|
||||
//
|
||||
// A [Verifier] allows verification of signatures by one server public key.
|
||||
// It can report the name of the server and the uint32 hash of the key,
|
||||
// and it can verify a purported signature by that key.
|
||||
//
|
||||
// The standard implementation of a Verifier is constructed
|
||||
// by [NewVerifier] starting from a verifier key, which is a
|
||||
// plain text string of the form "<name>+<hash>+<keydata>".
|
||||
//
|
||||
// A [Verifiers] allows looking up a Verifier by the combination
|
||||
// of server name and key hash.
|
||||
//
|
||||
// The standard implementation of a Verifiers is constructed
|
||||
// by VerifierList from a list of known verifiers.
|
||||
//
|
||||
// A [Note] represents a text with one or more signatures.
|
||||
// An implementation can reject a note with too many signatures
|
||||
// (for example, more than 100 signatures).
|
||||
//
|
||||
// A [Signature] represents a signature on a note, verified or not.
|
||||
//
|
||||
// The [Open] function takes as input a signed message
|
||||
// and a set of known verifiers. It decodes and verifies
|
||||
// the message signatures and returns a [Note] structure
|
||||
// containing the message text and (verified or unverified) signatures.
|
||||
//
|
||||
// # Signing Notes
|
||||
//
|
||||
// A [Signer] allows signing a text with a given key.
|
||||
// It can report the name of the server and the hash of the key
|
||||
// and can sign a raw text using that key.
|
||||
//
|
||||
// The standard implementation of a Signer is constructed
|
||||
// by [NewSigner] starting from an encoded signer key, which is a
|
||||
// plain text string of the form "PRIVATE+KEY+<name>+<hash>+<keydata>".
|
||||
// Anyone with an encoded signer key can sign messages using that key,
|
||||
// so it must be kept secret. The encoding begins with the literal text
|
||||
// "PRIVATE+KEY" to avoid confusion with the public server key.
|
||||
//
|
||||
// The [Sign] function takes as input a Note and a list of Signers
|
||||
// and returns an encoded, signed message.
|
||||
//
|
||||
// # Signed Note Format
|
||||
//
|
||||
// A signed note consists of a text ending in newline (U+000A),
|
||||
// followed by a blank line (only a newline),
|
||||
// followed by one or more signature lines of this form:
|
||||
// em dash (U+2014), space (U+0020),
|
||||
// server name, space, base64-encoded signature, newline.
|
||||
//
|
||||
// Signed notes must be valid UTF-8 and must not contain any
|
||||
// ASCII control characters (those below U+0020) other than newline.
|
||||
//
|
||||
// A signature is a base64 encoding of 4+n bytes.
|
||||
//
|
||||
// The first four bytes in the signature are the uint32 key hash
|
||||
// stored in big-endian order.
|
||||
//
|
||||
// The remaining n bytes are the result of using the specified key
|
||||
// to sign the note text (including the final newline but not the
|
||||
// separating blank line).
|
||||
//
|
||||
// # Generating Keys
|
||||
//
|
||||
// There is only one key type, Ed25519 with algorithm identifier 1.
|
||||
// New key types may be introduced in the future as needed,
|
||||
// although doing so will require deploying the new algorithms to all clients
|
||||
// before starting to depend on them for signatures.
|
||||
//
|
||||
// The [GenerateKey] function generates and returns a new signer
|
||||
// and corresponding verifier.
|
||||
//
|
||||
// # Example
|
||||
//
|
||||
// Here is a well-formed signed note:
|
||||
//
|
||||
// If you think cryptography is the answer to your problem,
|
||||
// then you don't know what your problem is.
|
||||
//
|
||||
// — PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=
|
||||
//
|
||||
// It can be constructed and displayed using:
|
||||
//
|
||||
// skey := "PRIVATE+KEY+PeterNeumann+c74f20a3+AYEKFALVFGyNhPJEMzD1QIDr+Y7hfZx09iUvxdXHKDFz"
|
||||
// text := "If you think cryptography is the answer to your problem,\n" +
|
||||
// "then you don't know what your problem is.\n"
|
||||
//
|
||||
// signer, err := note.NewSigner(skey)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
//
|
||||
// msg, err := note.Sign(¬e.Note{Text: text}, signer)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
// os.Stdout.Write(msg)
|
||||
//
|
||||
// The note's text is two lines, including the final newline,
|
||||
// and the text is purportedly signed by a server named
|
||||
// "PeterNeumann". (Although server names are canonically
|
||||
// base URLs, the only syntactic requirement is that they
|
||||
// not contain spaces or newlines).
|
||||
//
|
||||
// If [Open] is given access to a [Verifiers] including the
|
||||
// [Verifier] for this key, then it will succeed at verifying
|
||||
// the encoded message and returning the parsed [Note]:
|
||||
//
|
||||
// vkey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW"
|
||||
// msg := []byte("If you think cryptography is the answer to your problem,\n" +
|
||||
// "then you don't know what your problem is.\n" +
|
||||
// "\n" +
|
||||
// "— PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=\n")
|
||||
//
|
||||
// verifier, err := note.NewVerifier(vkey)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
// verifiers := note.VerifierList(verifier)
|
||||
//
|
||||
// n, err := note.Open([]byte(msg), verifiers)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
// fmt.Printf("%s (%08x):\n%s", n.Sigs[0].Name, n.Sigs[0].Hash, n.Text)
|
||||
//
|
||||
// You can add your own signature to this message by re-signing the note:
|
||||
//
|
||||
// skey, vkey, err := note.GenerateKey(rand.Reader, "EnochRoot")
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
// _ = vkey // give to verifiers
|
||||
//
|
||||
// me, err := note.NewSigner(skey)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
//
|
||||
// msg, err := note.Sign(n, me)
|
||||
// if err != nil {
|
||||
// log.Fatal(err)
|
||||
// }
|
||||
// os.Stdout.Write(msg)
|
||||
//
|
||||
// This will print a doubly-signed message, like:
|
||||
//
|
||||
// If you think cryptography is the answer to your problem,
|
||||
// then you don't know what your problem is.
|
||||
//
|
||||
// — PeterNeumann x08go/ZJkuBS9UG/SffcvIAQxVBtiFupLLr8pAcElZInNIuGUgYN1FFYC2pZSNXgKvqfqdngotpRZb6KE6RyyBwJnAM=
|
||||
// — EnochRoot rwz+eBzmZa0SO3NbfRGzPCpDckykFXSdeX+MNtCOXm2/5n2tiOHp+vAF1aGrQ5ovTG01oOTGwnWLox33WWd1RvMc+QQ=
|
||||
package note
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ed25519"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// A Verifier verifies messages signed with a specific key.
|
||||
type Verifier interface {
|
||||
// Name returns the server name associated with the key.
|
||||
Name() string
|
||||
|
||||
// KeyHash returns the key hash.
|
||||
KeyHash() uint32
|
||||
|
||||
// Verify reports whether sig is a valid signature of msg.
|
||||
Verify(msg, sig []byte) bool
|
||||
}
|
||||
|
||||
// A Signer signs messages using a specific key.
|
||||
type Signer interface {
|
||||
// Name returns the server name associated with the key.
|
||||
Name() string
|
||||
|
||||
// KeyHash returns the key hash.
|
||||
KeyHash() uint32
|
||||
|
||||
// Sign returns a signature for the given message.
|
||||
Sign(msg []byte) ([]byte, error)
|
||||
}
|
||||
|
||||
// keyHash computes the key hash for the given server name and encoded public key.
|
||||
func keyHash(name string, key []byte) uint32 {
|
||||
h := sha256.New()
|
||||
h.Write([]byte(name))
|
||||
h.Write([]byte("\n"))
|
||||
h.Write(key)
|
||||
sum := h.Sum(nil)
|
||||
return binary.BigEndian.Uint32(sum)
|
||||
}
|
||||
|
||||
var (
|
||||
errVerifierID = errors.New("malformed verifier id")
|
||||
errVerifierAlg = errors.New("unknown verifier algorithm")
|
||||
errVerifierHash = errors.New("invalid verifier hash")
|
||||
)
|
||||
|
||||
const (
|
||||
algEd25519 = 1
|
||||
)
|
||||
|
||||
// isValidName reports whether name is valid.
|
||||
// It must be non-empty and not have any Unicode spaces or pluses.
|
||||
func isValidName(name string) bool {
|
||||
return name != "" && utf8.ValidString(name) && strings.IndexFunc(name, unicode.IsSpace) < 0 && !strings.Contains(name, "+")
|
||||
}
|
||||
|
||||
// NewVerifier construct a new [Verifier] from an encoded verifier key.
|
||||
func NewVerifier(vkey string) (Verifier, error) {
|
||||
name, vkey := chop(vkey, "+")
|
||||
hash16, key64 := chop(vkey, "+")
|
||||
hash, err1 := strconv.ParseUint(hash16, 16, 32)
|
||||
key, err2 := base64.StdEncoding.DecodeString(key64)
|
||||
if len(hash16) != 8 || err1 != nil || err2 != nil || !isValidName(name) || len(key) == 0 {
|
||||
return nil, errVerifierID
|
||||
}
|
||||
if uint32(hash) != keyHash(name, key) {
|
||||
return nil, errVerifierHash
|
||||
}
|
||||
|
||||
v := &verifier{
|
||||
name: name,
|
||||
hash: uint32(hash),
|
||||
}
|
||||
|
||||
alg, key := key[0], key[1:]
|
||||
switch alg {
|
||||
default:
|
||||
return nil, errVerifierAlg
|
||||
|
||||
case algEd25519:
|
||||
if len(key) != 32 {
|
||||
return nil, errVerifierID
|
||||
}
|
||||
v.verify = func(msg, sig []byte) bool {
|
||||
return ed25519.Verify(key, msg, sig)
|
||||
}
|
||||
}
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// chop chops s at the first instance of sep, if any,
|
||||
// and returns the text before and after sep.
|
||||
// If sep is not present, chop returns before is s and after is empty.
|
||||
func chop(s, sep string) (before, after string) {
|
||||
i := strings.Index(s, sep)
|
||||
if i < 0 {
|
||||
return s, ""
|
||||
}
|
||||
return s[:i], s[i+len(sep):]
|
||||
}
|
||||
|
||||
// verifier is a trivial Verifier implementation.
|
||||
type verifier struct {
|
||||
name string
|
||||
hash uint32
|
||||
verify func([]byte, []byte) bool
|
||||
}
|
||||
|
||||
func (v *verifier) Name() string { return v.name }
|
||||
func (v *verifier) KeyHash() uint32 { return v.hash }
|
||||
func (v *verifier) Verify(msg, sig []byte) bool { return v.verify(msg, sig) }
|
||||
|
||||
// NewSigner constructs a new [Signer] from an encoded signer key.
|
||||
func NewSigner(skey string) (Signer, error) {
|
||||
priv1, skey := chop(skey, "+")
|
||||
priv2, skey := chop(skey, "+")
|
||||
name, skey := chop(skey, "+")
|
||||
hash16, key64 := chop(skey, "+")
|
||||
hash, err1 := strconv.ParseUint(hash16, 16, 32)
|
||||
key, err2 := base64.StdEncoding.DecodeString(key64)
|
||||
if priv1 != "PRIVATE" || priv2 != "KEY" || len(hash16) != 8 || err1 != nil || err2 != nil || !isValidName(name) || len(key) == 0 {
|
||||
return nil, errSignerID
|
||||
}
|
||||
|
||||
// Note: hash is the hash of the public key and we have the private key.
|
||||
// Must verify hash after deriving public key.
|
||||
|
||||
s := &signer{
|
||||
name: name,
|
||||
hash: uint32(hash),
|
||||
}
|
||||
|
||||
var pubkey []byte
|
||||
|
||||
alg, key := key[0], key[1:]
|
||||
switch alg {
|
||||
default:
|
||||
return nil, errSignerAlg
|
||||
|
||||
case algEd25519:
|
||||
if len(key) != 32 {
|
||||
return nil, errSignerID
|
||||
}
|
||||
key = ed25519.NewKeyFromSeed(key)
|
||||
pubkey = append([]byte{algEd25519}, key[32:]...)
|
||||
s.sign = func(msg []byte) ([]byte, error) {
|
||||
return ed25519.Sign(key, msg), nil
|
||||
}
|
||||
}
|
||||
|
||||
if uint32(hash) != keyHash(name, pubkey) {
|
||||
return nil, errSignerHash
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
var (
|
||||
errSignerID = errors.New("malformed verifier id")
|
||||
errSignerAlg = errors.New("unknown verifier algorithm")
|
||||
errSignerHash = errors.New("invalid verifier hash")
|
||||
)
|
||||
|
||||
// signer is a trivial Signer implementation.
|
||||
type signer struct {
|
||||
name string
|
||||
hash uint32
|
||||
sign func([]byte) ([]byte, error)
|
||||
}
|
||||
|
||||
func (s *signer) Name() string { return s.name }
|
||||
func (s *signer) KeyHash() uint32 { return s.hash }
|
||||
func (s *signer) Sign(msg []byte) ([]byte, error) { return s.sign(msg) }
|
||||
|
||||
// GenerateKey generates a signer and verifier key pair for a named server.
|
||||
// The signer key skey is private and must be kept secret.
|
||||
func GenerateKey(rand io.Reader, name string) (skey, vkey string, err error) {
|
||||
pub, priv, err := ed25519.GenerateKey(rand)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
pubkey := append([]byte{algEd25519}, pub...)
|
||||
privkey := append([]byte{algEd25519}, priv.Seed()...)
|
||||
h := keyHash(name, pubkey)
|
||||
|
||||
skey = fmt.Sprintf("PRIVATE+KEY+%s+%08x+%s", name, h, base64.StdEncoding.EncodeToString(privkey))
|
||||
vkey = fmt.Sprintf("%s+%08x+%s", name, h, base64.StdEncoding.EncodeToString(pubkey))
|
||||
return skey, vkey, nil
|
||||
}
|
||||
|
||||
// NewEd25519VerifierKey returns an encoded verifier key using the given name
|
||||
// and Ed25519 public key.
|
||||
func NewEd25519VerifierKey(name string, key ed25519.PublicKey) (string, error) {
|
||||
if len(key) != ed25519.PublicKeySize {
|
||||
return "", fmt.Errorf("invalid public key size %d, expected %d", len(key), ed25519.PublicKeySize)
|
||||
}
|
||||
|
||||
pubkey := append([]byte{algEd25519}, key...)
|
||||
hash := keyHash(name, pubkey)
|
||||
|
||||
b64Key := base64.StdEncoding.EncodeToString(pubkey)
|
||||
return fmt.Sprintf("%s+%08x+%s", name, hash, b64Key), nil
|
||||
}
|
||||
|
||||
// A Verifiers is a collection of known verifier keys.
|
||||
type Verifiers interface {
|
||||
// Verifier returns the Verifier associated with the key
|
||||
// identified by the name and hash.
|
||||
// If the name, hash pair is unknown, Verifier should return
|
||||
// an UnknownVerifierError.
|
||||
Verifier(name string, hash uint32) (Verifier, error)
|
||||
}
|
||||
|
||||
// An UnknownVerifierError indicates that the given key is not known.
|
||||
// The Open function records signatures without associated verifiers as
|
||||
// unverified signatures.
|
||||
type UnknownVerifierError struct {
|
||||
Name string
|
||||
KeyHash uint32
|
||||
}
|
||||
|
||||
func (e *UnknownVerifierError) Error() string {
|
||||
return fmt.Sprintf("unknown key %s+%08x", e.Name, e.KeyHash)
|
||||
}
|
||||
|
||||
// An ambiguousVerifierError indicates that the given name and hash
|
||||
// match multiple keys passed to [VerifierList].
|
||||
// (If this happens, some malicious actor has taken control of the
|
||||
// verifier list, at which point we may as well give up entirely,
|
||||
// but we diagnose the problem instead.)
|
||||
type ambiguousVerifierError struct {
|
||||
name string
|
||||
hash uint32
|
||||
}
|
||||
|
||||
func (e *ambiguousVerifierError) Error() string {
|
||||
return fmt.Sprintf("ambiguous key %s+%08x", e.name, e.hash)
|
||||
}
|
||||
|
||||
// VerifierList returns a [Verifiers] implementation that uses the given list of verifiers.
|
||||
func VerifierList(list ...Verifier) Verifiers {
|
||||
m := make(verifierMap)
|
||||
for _, v := range list {
|
||||
k := nameHash{v.Name(), v.KeyHash()}
|
||||
m[k] = append(m[k], v)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
type nameHash struct {
|
||||
name string
|
||||
hash uint32
|
||||
}
|
||||
|
||||
type verifierMap map[nameHash][]Verifier
|
||||
|
||||
func (m verifierMap) Verifier(name string, hash uint32) (Verifier, error) {
|
||||
v, ok := m[nameHash{name, hash}]
|
||||
if !ok {
|
||||
return nil, &UnknownVerifierError{name, hash}
|
||||
}
|
||||
if len(v) > 1 {
|
||||
return nil, &ambiguousVerifierError{name, hash}
|
||||
}
|
||||
return v[0], nil
|
||||
}
|
||||
|
||||
// A Note is a text and signatures.
|
||||
type Note struct {
|
||||
Text string // text of note
|
||||
Sigs []Signature // verified signatures
|
||||
UnverifiedSigs []Signature // unverified signatures
|
||||
}
|
||||
|
||||
// A Signature is a single signature found in a note.
|
||||
type Signature struct {
|
||||
// Name and Hash give the name and key hash
|
||||
// for the key that generated the signature.
|
||||
Name string
|
||||
Hash uint32
|
||||
|
||||
// Base64 records the base64-encoded signature bytes.
|
||||
Base64 string
|
||||
}
|
||||
|
||||
// An UnverifiedNoteError indicates that the note
|
||||
// successfully parsed but had no verifiable signatures.
|
||||
type UnverifiedNoteError struct {
|
||||
Note *Note
|
||||
}
|
||||
|
||||
func (e *UnverifiedNoteError) Error() string {
|
||||
return "note has no verifiable signatures"
|
||||
}
|
||||
|
||||
// An InvalidSignatureError indicates that the given key was known
|
||||
// and the associated Verifier rejected the signature.
|
||||
type InvalidSignatureError struct {
|
||||
Name string
|
||||
Hash uint32
|
||||
}
|
||||
|
||||
func (e *InvalidSignatureError) Error() string {
|
||||
return fmt.Sprintf("invalid signature for key %s+%08x", e.Name, e.Hash)
|
||||
}
|
||||
|
||||
var (
|
||||
errMalformedNote = errors.New("malformed note")
|
||||
errInvalidSigner = errors.New("invalid signer")
|
||||
errMismatchedVerifier = errors.New("verifier name or hash doesn't match signature")
|
||||
|
||||
sigSplit = []byte("\n\n")
|
||||
sigPrefix = []byte("— ")
|
||||
)
|
||||
|
||||
// Open opens and parses the message msg, checking signatures from the known verifiers.
|
||||
//
|
||||
// For each signature in the message, Open calls known.Verifier to find a verifier.
|
||||
// If known.Verifier returns a verifier and the verifier accepts the signature,
|
||||
// Open records the signature in the returned note's Sigs field.
|
||||
// If known.Verifier returns a verifier but the verifier rejects the signature,
|
||||
// Open returns an InvalidSignatureError.
|
||||
// If known.Verifier returns an UnknownVerifierError,
|
||||
// Open records the signature in the returned note's UnverifiedSigs field.
|
||||
// If known.Verifier returns any other error, Open returns that error.
|
||||
//
|
||||
// If no known verifier has signed an otherwise valid note,
|
||||
// Open returns an [UnverifiedNoteError].
|
||||
// In this case, the unverified note can be fetched from inside the error.
|
||||
func Open(msg []byte, known Verifiers) (*Note, error) {
|
||||
if known == nil {
|
||||
// Treat nil Verifiers as empty list, to produce useful error instead of crash.
|
||||
known = VerifierList()
|
||||
}
|
||||
|
||||
// Must have valid UTF-8 with no non-newline ASCII control characters.
|
||||
for i := 0; i < len(msg); {
|
||||
r, size := utf8.DecodeRune(msg[i:])
|
||||
if r < 0x20 && r != '\n' || r == utf8.RuneError && size == 1 {
|
||||
return nil, errMalformedNote
|
||||
}
|
||||
i += size
|
||||
}
|
||||
|
||||
// Must end with signature block preceded by blank line.
|
||||
split := bytes.LastIndex(msg, sigSplit)
|
||||
if split < 0 {
|
||||
return nil, errMalformedNote
|
||||
}
|
||||
text, sigs := msg[:split+1], msg[split+2:]
|
||||
if len(sigs) == 0 || sigs[len(sigs)-1] != '\n' {
|
||||
return nil, errMalformedNote
|
||||
}
|
||||
|
||||
n := &Note{
|
||||
Text: string(text),
|
||||
}
|
||||
|
||||
// Parse and verify signatures.
|
||||
// Ignore duplicate signatures.
|
||||
seen := make(map[nameHash]bool)
|
||||
seenUnverified := make(map[string]bool)
|
||||
numSig := 0
|
||||
for len(sigs) > 0 {
|
||||
// Pull out next signature line.
|
||||
// We know sigs[len(sigs)-1] == '\n', so IndexByte always finds one.
|
||||
i := bytes.IndexByte(sigs, '\n')
|
||||
line := sigs[:i]
|
||||
sigs = sigs[i+1:]
|
||||
|
||||
if !bytes.HasPrefix(line, sigPrefix) {
|
||||
return nil, errMalformedNote
|
||||
}
|
||||
line = line[len(sigPrefix):]
|
||||
name, b64 := chop(string(line), " ")
|
||||
sig, err := base64.StdEncoding.DecodeString(b64)
|
||||
if err != nil || !isValidName(name) || b64 == "" || len(sig) < 5 {
|
||||
return nil, errMalformedNote
|
||||
}
|
||||
hash := binary.BigEndian.Uint32(sig[0:4])
|
||||
sig = sig[4:]
|
||||
|
||||
if numSig++; numSig > 100 {
|
||||
// Avoid spending forever parsing a note with many signatures.
|
||||
return nil, errMalformedNote
|
||||
}
|
||||
|
||||
v, err := known.Verifier(name, hash)
|
||||
if _, ok := err.(*UnknownVerifierError); ok {
|
||||
// Drop repeated identical unverified signatures.
|
||||
if seenUnverified[string(line)] {
|
||||
continue
|
||||
}
|
||||
seenUnverified[string(line)] = true
|
||||
n.UnverifiedSigs = append(n.UnverifiedSigs, Signature{Name: name, Hash: hash, Base64: b64})
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check that known.Verifier returned the right verifier.
|
||||
if v.Name() != name || v.KeyHash() != hash {
|
||||
return nil, errMismatchedVerifier
|
||||
}
|
||||
|
||||
// Drop repeated signatures by a single verifier.
|
||||
if seen[nameHash{name, hash}] {
|
||||
continue
|
||||
}
|
||||
seen[nameHash{name, hash}] = true
|
||||
|
||||
ok := v.Verify(text, sig)
|
||||
if !ok {
|
||||
return nil, &InvalidSignatureError{name, hash}
|
||||
}
|
||||
|
||||
n.Sigs = append(n.Sigs, Signature{Name: name, Hash: hash, Base64: b64})
|
||||
}
|
||||
|
||||
// Parsed and verified all the signatures.
|
||||
if len(n.Sigs) == 0 {
|
||||
return nil, &UnverifiedNoteError{n}
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// Sign signs the note with the given signers and returns the encoded message.
|
||||
// The new signatures from signers are listed in the encoded message after
|
||||
// the existing signatures already present in n.Sigs.
|
||||
// If any signer uses the same key as an existing signature,
|
||||
// the existing signature is elided from the output.
|
||||
func Sign(n *Note, signers ...Signer) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
if !strings.HasSuffix(n.Text, "\n") {
|
||||
return nil, errMalformedNote
|
||||
}
|
||||
buf.WriteString(n.Text)
|
||||
|
||||
// Prepare signatures.
|
||||
var sigs bytes.Buffer
|
||||
have := make(map[nameHash]bool)
|
||||
for _, s := range signers {
|
||||
name := s.Name()
|
||||
hash := s.KeyHash()
|
||||
have[nameHash{name, hash}] = true
|
||||
if !isValidName(name) {
|
||||
return nil, errInvalidSigner
|
||||
}
|
||||
|
||||
sig, err := s.Sign(buf.Bytes()) // buf holds n.Text
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var hbuf [4]byte
|
||||
binary.BigEndian.PutUint32(hbuf[:], hash)
|
||||
b64 := base64.StdEncoding.EncodeToString(append(hbuf[:], sig...))
|
||||
sigs.WriteString("— ")
|
||||
sigs.WriteString(name)
|
||||
sigs.WriteString(" ")
|
||||
sigs.WriteString(b64)
|
||||
sigs.WriteString("\n")
|
||||
}
|
||||
|
||||
buf.WriteString("\n")
|
||||
|
||||
// Emit existing signatures not replaced by new ones.
|
||||
for _, list := range [][]Signature{n.Sigs, n.UnverifiedSigs} {
|
||||
for _, sig := range list {
|
||||
name, hash := sig.Name, sig.Hash
|
||||
if !isValidName(name) {
|
||||
return nil, errMalformedNote
|
||||
}
|
||||
if have[nameHash{name, hash}] {
|
||||
continue
|
||||
}
|
||||
// Double-check hash against base64.
|
||||
raw, err := base64.StdEncoding.DecodeString(sig.Base64)
|
||||
if err != nil || len(raw) < 4 || binary.BigEndian.Uint32(raw) != hash {
|
||||
return nil, errMalformedNote
|
||||
}
|
||||
buf.WriteString("— ")
|
||||
buf.WriteString(sig.Name)
|
||||
buf.WriteString(" ")
|
||||
buf.WriteString(sig.Base64)
|
||||
buf.WriteString("\n")
|
||||
}
|
||||
}
|
||||
buf.Write(sigs.Bytes())
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
16
vendor/golang.org/x/net/http2/frame.go
generated
vendored
16
vendor/golang.org/x/net/http2/frame.go
generated
vendored
@@ -39,7 +39,7 @@ const (
|
||||
FrameContinuation FrameType = 0x9
|
||||
)
|
||||
|
||||
var frameName = map[FrameType]string{
|
||||
var frameNames = [...]string{
|
||||
FrameData: "DATA",
|
||||
FrameHeaders: "HEADERS",
|
||||
FramePriority: "PRIORITY",
|
||||
@@ -53,10 +53,10 @@ var frameName = map[FrameType]string{
|
||||
}
|
||||
|
||||
func (t FrameType) String() string {
|
||||
if s, ok := frameName[t]; ok {
|
||||
return s
|
||||
if int(t) < len(frameNames) {
|
||||
return frameNames[t]
|
||||
}
|
||||
return fmt.Sprintf("UNKNOWN_FRAME_TYPE_%d", uint8(t))
|
||||
return fmt.Sprintf("UNKNOWN_FRAME_TYPE_%d", t)
|
||||
}
|
||||
|
||||
// Flags is a bitmask of HTTP/2 flags.
|
||||
@@ -124,7 +124,7 @@ var flagName = map[FrameType]map[Flags]string{
|
||||
// might be 0).
|
||||
type frameParser func(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error)
|
||||
|
||||
var frameParsers = map[FrameType]frameParser{
|
||||
var frameParsers = [...]frameParser{
|
||||
FrameData: parseDataFrame,
|
||||
FrameHeaders: parseHeadersFrame,
|
||||
FramePriority: parsePriorityFrame,
|
||||
@@ -138,8 +138,8 @@ var frameParsers = map[FrameType]frameParser{
|
||||
}
|
||||
|
||||
func typeFrameParser(t FrameType) frameParser {
|
||||
if f := frameParsers[t]; f != nil {
|
||||
return f
|
||||
if int(t) < len(frameParsers) {
|
||||
return frameParsers[t]
|
||||
}
|
||||
return parseUnknownFrame
|
||||
}
|
||||
@@ -509,7 +509,7 @@ func (fr *Framer) ReadFrame() (Frame, error) {
|
||||
}
|
||||
if fh.Length > fr.maxReadSize {
|
||||
if fh == invalidHTTP1LookingFrameHeader() {
|
||||
return nil, fmt.Errorf("http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header", err)
|
||||
return nil, fmt.Errorf("http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header", ErrFrameTooLarge)
|
||||
}
|
||||
return nil, ErrFrameTooLarge
|
||||
}
|
||||
|
2
vendor/golang.org/x/net/trace/events.go
generated
vendored
2
vendor/golang.org/x/net/trace/events.go
generated
vendored
@@ -508,7 +508,7 @@ const eventsHTML = `
|
||||
<tr class="first">
|
||||
<td class="when">{{$el.When}}</td>
|
||||
<td class="elapsed">{{$el.ElapsedTime}}</td>
|
||||
<td>{{$el.Title}}
|
||||
<td>{{$el.Title}}</td>
|
||||
</tr>
|
||||
{{if $.Expanded}}
|
||||
<tr>
|
||||
|
2
vendor/golang.org/x/oauth2/internal/doc.go
generated
vendored
2
vendor/golang.org/x/oauth2/internal/doc.go
generated
vendored
@@ -2,5 +2,5 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package internal contains support packages for oauth2 package.
|
||||
// Package internal contains support packages for [golang.org/x/oauth2].
|
||||
package internal
|
||||
|
2
vendor/golang.org/x/oauth2/internal/oauth2.go
generated
vendored
2
vendor/golang.org/x/oauth2/internal/oauth2.go
generated
vendored
@@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
// ParseKey converts the binary contents of a private key file
|
||||
// to an *rsa.PrivateKey. It detects whether the private key is in a
|
||||
// to an [*rsa.PrivateKey]. It detects whether the private key is in a
|
||||
// PEM container or not. If so, it extracts the private key
|
||||
// from PEM container before conversion. It only supports PEM
|
||||
// containers with no passphrase.
|
||||
|
50
vendor/golang.org/x/oauth2/internal/token.go
generated
vendored
50
vendor/golang.org/x/oauth2/internal/token.go
generated
vendored
@@ -10,7 +10,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"mime"
|
||||
"net/http"
|
||||
@@ -26,9 +25,9 @@ import (
|
||||
// the requests to access protected resources on the OAuth 2.0
|
||||
// provider's backend.
|
||||
//
|
||||
// This type is a mirror of oauth2.Token and exists to break
|
||||
// This type is a mirror of [golang.org/x/oauth2.Token] and exists to break
|
||||
// an otherwise-circular dependency. Other internal packages
|
||||
// should convert this Token into an oauth2.Token before use.
|
||||
// should convert this Token into an [golang.org/x/oauth2.Token] before use.
|
||||
type Token struct {
|
||||
// AccessToken is the token that authorizes and authenticates
|
||||
// the requests.
|
||||
@@ -50,9 +49,16 @@ type Token struct {
|
||||
// mechanisms for that TokenSource will not be used.
|
||||
Expiry time.Time
|
||||
|
||||
// ExpiresIn is the OAuth2 wire format "expires_in" field,
|
||||
// which specifies how many seconds later the token expires,
|
||||
// relative to an unknown time base approximately around "now".
|
||||
// It is the application's responsibility to populate
|
||||
// `Expiry` from `ExpiresIn` when required.
|
||||
ExpiresIn int64 `json:"expires_in,omitempty"`
|
||||
|
||||
// Raw optionally contains extra metadata from the server
|
||||
// when updating a token.
|
||||
Raw interface{}
|
||||
Raw any
|
||||
}
|
||||
|
||||
// tokenJSON is the struct representing the HTTP response from OAuth2
|
||||
@@ -99,14 +105,6 @@ func (e *expirationTime) UnmarshalJSON(b []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterBrokenAuthHeaderProvider previously did something. It is now a no-op.
|
||||
//
|
||||
// Deprecated: this function no longer does anything. Caller code that
|
||||
// wants to avoid potential extra HTTP requests made during
|
||||
// auto-probing of the provider's auth style should set
|
||||
// Endpoint.AuthStyle.
|
||||
func RegisterBrokenAuthHeaderProvider(tokenURL string) {}
|
||||
|
||||
// AuthStyle is a copy of the golang.org/x/oauth2 package's AuthStyle type.
|
||||
type AuthStyle int
|
||||
|
||||
@@ -143,6 +141,11 @@ func (lc *LazyAuthStyleCache) Get() *AuthStyleCache {
|
||||
return c
|
||||
}
|
||||
|
||||
type authStyleCacheKey struct {
|
||||
url string
|
||||
clientID string
|
||||
}
|
||||
|
||||
// AuthStyleCache is the set of tokenURLs we've successfully used via
|
||||
// RetrieveToken and which style auth we ended up using.
|
||||
// It's called a cache, but it doesn't (yet?) shrink. It's expected that
|
||||
@@ -150,26 +153,26 @@ func (lc *LazyAuthStyleCache) Get() *AuthStyleCache {
|
||||
// small.
|
||||
type AuthStyleCache struct {
|
||||
mu sync.Mutex
|
||||
m map[string]AuthStyle // keyed by tokenURL
|
||||
m map[authStyleCacheKey]AuthStyle
|
||||
}
|
||||
|
||||
// lookupAuthStyle reports which auth style we last used with tokenURL
|
||||
// when calling RetrieveToken and whether we have ever done so.
|
||||
func (c *AuthStyleCache) lookupAuthStyle(tokenURL string) (style AuthStyle, ok bool) {
|
||||
func (c *AuthStyleCache) lookupAuthStyle(tokenURL, clientID string) (style AuthStyle, ok bool) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
style, ok = c.m[tokenURL]
|
||||
style, ok = c.m[authStyleCacheKey{tokenURL, clientID}]
|
||||
return
|
||||
}
|
||||
|
||||
// setAuthStyle adds an entry to authStyleCache, documented above.
|
||||
func (c *AuthStyleCache) setAuthStyle(tokenURL string, v AuthStyle) {
|
||||
func (c *AuthStyleCache) setAuthStyle(tokenURL, clientID string, v AuthStyle) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if c.m == nil {
|
||||
c.m = make(map[string]AuthStyle)
|
||||
c.m = make(map[authStyleCacheKey]AuthStyle)
|
||||
}
|
||||
c.m[tokenURL] = v
|
||||
c.m[authStyleCacheKey{tokenURL, clientID}] = v
|
||||
}
|
||||
|
||||
// newTokenRequest returns a new *http.Request to retrieve a new token
|
||||
@@ -210,9 +213,9 @@ func cloneURLValues(v url.Values) url.Values {
|
||||
}
|
||||
|
||||
func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string, v url.Values, authStyle AuthStyle, styleCache *AuthStyleCache) (*Token, error) {
|
||||
needsAuthStyleProbe := authStyle == 0
|
||||
needsAuthStyleProbe := authStyle == AuthStyleUnknown
|
||||
if needsAuthStyleProbe {
|
||||
if style, ok := styleCache.lookupAuthStyle(tokenURL); ok {
|
||||
if style, ok := styleCache.lookupAuthStyle(tokenURL, clientID); ok {
|
||||
authStyle = style
|
||||
needsAuthStyleProbe = false
|
||||
} else {
|
||||
@@ -242,7 +245,7 @@ func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string,
|
||||
token, err = doTokenRoundTrip(ctx, req)
|
||||
}
|
||||
if needsAuthStyleProbe && err == nil {
|
||||
styleCache.setAuthStyle(tokenURL, authStyle)
|
||||
styleCache.setAuthStyle(tokenURL, clientID, authStyle)
|
||||
}
|
||||
// Don't overwrite `RefreshToken` with an empty value
|
||||
// if this was a token refreshing request.
|
||||
@@ -257,7 +260,7 @@ func doTokenRoundTrip(ctx context.Context, req *http.Request) (*Token, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1<<20))
|
||||
body, err := io.ReadAll(io.LimitReader(r.Body, 1<<20))
|
||||
r.Body.Close()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
|
||||
@@ -312,7 +315,8 @@ func doTokenRoundTrip(ctx context.Context, req *http.Request) (*Token, error) {
|
||||
TokenType: tj.TokenType,
|
||||
RefreshToken: tj.RefreshToken,
|
||||
Expiry: tj.expiry(),
|
||||
Raw: make(map[string]interface{}),
|
||||
ExpiresIn: int64(tj.ExpiresIn),
|
||||
Raw: make(map[string]any),
|
||||
}
|
||||
json.Unmarshal(body, &token.Raw) // no error checks for optional fields
|
||||
}
|
||||
|
4
vendor/golang.org/x/oauth2/internal/transport.go
generated
vendored
4
vendor/golang.org/x/oauth2/internal/transport.go
generated
vendored
@@ -9,8 +9,8 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// HTTPClient is the context key to use with golang.org/x/net/context's
|
||||
// WithValue function to associate an *http.Client value with a context.
|
||||
// HTTPClient is the context key to use with [context.WithValue]
|
||||
// to associate an [*http.Client] value with a context.
|
||||
var HTTPClient ContextKey
|
||||
|
||||
// ContextKey is just an empty struct. It exists so HTTPClient can be
|
||||
|
55
vendor/golang.org/x/oauth2/oauth2.go
generated
vendored
55
vendor/golang.org/x/oauth2/oauth2.go
generated
vendored
@@ -22,9 +22,9 @@ import (
|
||||
)
|
||||
|
||||
// NoContext is the default context you should supply if not using
|
||||
// your own context.Context (see https://golang.org/x/net/context).
|
||||
// your own [context.Context].
|
||||
//
|
||||
// Deprecated: Use context.Background() or context.TODO() instead.
|
||||
// Deprecated: Use [context.Background] or [context.TODO] instead.
|
||||
var NoContext = context.TODO()
|
||||
|
||||
// RegisterBrokenAuthHeaderProvider previously did something. It is now a no-op.
|
||||
@@ -37,8 +37,8 @@ func RegisterBrokenAuthHeaderProvider(tokenURL string) {}
|
||||
|
||||
// Config describes a typical 3-legged OAuth2 flow, with both the
|
||||
// client application information and the server's endpoint URLs.
|
||||
// For the client credentials 2-legged OAuth2 flow, see the clientcredentials
|
||||
// package (https://golang.org/x/oauth2/clientcredentials).
|
||||
// For the client credentials 2-legged OAuth2 flow, see the
|
||||
// [golang.org/x/oauth2/clientcredentials] package.
|
||||
type Config struct {
|
||||
// ClientID is the application's ID.
|
||||
ClientID string
|
||||
@@ -46,7 +46,7 @@ type Config struct {
|
||||
// ClientSecret is the application's secret.
|
||||
ClientSecret string
|
||||
|
||||
// Endpoint contains the resource server's token endpoint
|
||||
// Endpoint contains the authorization server's token endpoint
|
||||
// URLs. These are constants specific to each server and are
|
||||
// often available via site-specific packages, such as
|
||||
// google.Endpoint or github.Endpoint.
|
||||
@@ -135,7 +135,7 @@ type setParam struct{ k, v string }
|
||||
|
||||
func (p setParam) setValue(m url.Values) { m.Set(p.k, p.v) }
|
||||
|
||||
// SetAuthURLParam builds an AuthCodeOption which passes key/value parameters
|
||||
// SetAuthURLParam builds an [AuthCodeOption] which passes key/value parameters
|
||||
// to a provider's authorization endpoint.
|
||||
func SetAuthURLParam(key, value string) AuthCodeOption {
|
||||
return setParam{key, value}
|
||||
@@ -148,8 +148,8 @@ func SetAuthURLParam(key, value string) AuthCodeOption {
|
||||
// request and callback. The authorization server includes this value when
|
||||
// redirecting the user agent back to the client.
|
||||
//
|
||||
// Opts may include AccessTypeOnline or AccessTypeOffline, as well
|
||||
// as ApprovalForce.
|
||||
// Opts may include [AccessTypeOnline] or [AccessTypeOffline], as well
|
||||
// as [ApprovalForce].
|
||||
//
|
||||
// To protect against CSRF attacks, opts should include a PKCE challenge
|
||||
// (S256ChallengeOption). Not all servers support PKCE. An alternative is to
|
||||
@@ -194,7 +194,7 @@ func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string {
|
||||
// and when other authorization grant types are not available."
|
||||
// See https://tools.ietf.org/html/rfc6749#section-4.3 for more info.
|
||||
//
|
||||
// The provided context optionally controls which HTTP client is used. See the HTTPClient variable.
|
||||
// The provided context optionally controls which HTTP client is used. See the [HTTPClient] variable.
|
||||
func (c *Config) PasswordCredentialsToken(ctx context.Context, username, password string) (*Token, error) {
|
||||
v := url.Values{
|
||||
"grant_type": {"password"},
|
||||
@@ -212,10 +212,10 @@ func (c *Config) PasswordCredentialsToken(ctx context.Context, username, passwor
|
||||
// It is used after a resource provider redirects the user back
|
||||
// to the Redirect URI (the URL obtained from AuthCodeURL).
|
||||
//
|
||||
// The provided context optionally controls which HTTP client is used. See the HTTPClient variable.
|
||||
// The provided context optionally controls which HTTP client is used. See the [HTTPClient] variable.
|
||||
//
|
||||
// The code will be in the *http.Request.FormValue("code"). Before
|
||||
// calling Exchange, be sure to validate FormValue("state") if you are
|
||||
// The code will be in the [http.Request.FormValue]("code"). Before
|
||||
// calling Exchange, be sure to validate [http.Request.FormValue]("state") if you are
|
||||
// using it to protect against CSRF attacks.
|
||||
//
|
||||
// If using PKCE to protect against CSRF attacks, opts should include a
|
||||
@@ -242,10 +242,10 @@ func (c *Config) Client(ctx context.Context, t *Token) *http.Client {
|
||||
return NewClient(ctx, c.TokenSource(ctx, t))
|
||||
}
|
||||
|
||||
// TokenSource returns a TokenSource that returns t until t expires,
|
||||
// TokenSource returns a [TokenSource] that returns t until t expires,
|
||||
// automatically refreshing it as necessary using the provided context.
|
||||
//
|
||||
// Most users will use Config.Client instead.
|
||||
// Most users will use [Config.Client] instead.
|
||||
func (c *Config) TokenSource(ctx context.Context, t *Token) TokenSource {
|
||||
tkr := &tokenRefresher{
|
||||
ctx: ctx,
|
||||
@@ -260,7 +260,7 @@ func (c *Config) TokenSource(ctx context.Context, t *Token) TokenSource {
|
||||
}
|
||||
}
|
||||
|
||||
// tokenRefresher is a TokenSource that makes "grant_type"=="refresh_token"
|
||||
// tokenRefresher is a TokenSource that makes "grant_type=refresh_token"
|
||||
// HTTP requests to renew a token using a RefreshToken.
|
||||
type tokenRefresher struct {
|
||||
ctx context.Context // used to get HTTP requests
|
||||
@@ -305,8 +305,7 @@ type reuseTokenSource struct {
|
||||
}
|
||||
|
||||
// Token returns the current token if it's still valid, else will
|
||||
// refresh the current token (using r.Context for HTTP client
|
||||
// information) and return the new one.
|
||||
// refresh the current token and return the new one.
|
||||
func (s *reuseTokenSource) Token() (*Token, error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
@@ -322,7 +321,7 @@ func (s *reuseTokenSource) Token() (*Token, error) {
|
||||
return t, nil
|
||||
}
|
||||
|
||||
// StaticTokenSource returns a TokenSource that always returns the same token.
|
||||
// StaticTokenSource returns a [TokenSource] that always returns the same token.
|
||||
// Because the provided token t is never refreshed, StaticTokenSource is only
|
||||
// useful for tokens that never expire.
|
||||
func StaticTokenSource(t *Token) TokenSource {
|
||||
@@ -338,16 +337,16 @@ func (s staticTokenSource) Token() (*Token, error) {
|
||||
return s.t, nil
|
||||
}
|
||||
|
||||
// HTTPClient is the context key to use with golang.org/x/net/context's
|
||||
// WithValue function to associate an *http.Client value with a context.
|
||||
// HTTPClient is the context key to use with [context.WithValue]
|
||||
// to associate a [*http.Client] value with a context.
|
||||
var HTTPClient internal.ContextKey
|
||||
|
||||
// NewClient creates an *http.Client from a Context and TokenSource.
|
||||
// NewClient creates an [*http.Client] from a [context.Context] and [TokenSource].
|
||||
// The returned client is not valid beyond the lifetime of the context.
|
||||
//
|
||||
// Note that if a custom *http.Client is provided via the Context it
|
||||
// Note that if a custom [*http.Client] is provided via the [context.Context] it
|
||||
// is used only for token acquisition and is not used to configure the
|
||||
// *http.Client returned from NewClient.
|
||||
// [*http.Client] returned from NewClient.
|
||||
//
|
||||
// As a special case, if src is nil, a non-OAuth2 client is returned
|
||||
// using the provided context. This exists to support related OAuth2
|
||||
@@ -368,7 +367,7 @@ func NewClient(ctx context.Context, src TokenSource) *http.Client {
|
||||
}
|
||||
}
|
||||
|
||||
// ReuseTokenSource returns a TokenSource which repeatedly returns the
|
||||
// ReuseTokenSource returns a [TokenSource] which repeatedly returns the
|
||||
// same token as long as it's valid, starting with t.
|
||||
// When its cached token is invalid, a new token is obtained from src.
|
||||
//
|
||||
@@ -376,10 +375,10 @@ func NewClient(ctx context.Context, src TokenSource) *http.Client {
|
||||
// (such as a file on disk) between runs of a program, rather than
|
||||
// obtaining new tokens unnecessarily.
|
||||
//
|
||||
// The initial token t may be nil, in which case the TokenSource is
|
||||
// The initial token t may be nil, in which case the [TokenSource] is
|
||||
// wrapped in a caching version if it isn't one already. This also
|
||||
// means it's always safe to wrap ReuseTokenSource around any other
|
||||
// TokenSource without adverse effects.
|
||||
// [TokenSource] without adverse effects.
|
||||
func ReuseTokenSource(t *Token, src TokenSource) TokenSource {
|
||||
// Don't wrap a reuseTokenSource in itself. That would work,
|
||||
// but cause an unnecessary number of mutex operations.
|
||||
@@ -397,8 +396,8 @@ func ReuseTokenSource(t *Token, src TokenSource) TokenSource {
|
||||
}
|
||||
}
|
||||
|
||||
// ReuseTokenSourceWithExpiry returns a TokenSource that acts in the same manner as the
|
||||
// TokenSource returned by ReuseTokenSource, except the expiry buffer is
|
||||
// ReuseTokenSourceWithExpiry returns a [TokenSource] that acts in the same manner as the
|
||||
// [TokenSource] returned by [ReuseTokenSource], except the expiry buffer is
|
||||
// configurable. The expiration time of a token is calculated as
|
||||
// t.Expiry.Add(-earlyExpiry).
|
||||
func ReuseTokenSourceWithExpiry(t *Token, src TokenSource, earlyExpiry time.Duration) TokenSource {
|
||||
|
15
vendor/golang.org/x/oauth2/pkce.go
generated
vendored
15
vendor/golang.org/x/oauth2/pkce.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
// 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 (
|
||||
@@ -20,9 +21,9 @@ const (
|
||||
// This follows recommendations in RFC 7636.
|
||||
//
|
||||
// A fresh verifier should be generated for each authorization.
|
||||
// S256ChallengeOption(verifier) should then be passed to Config.AuthCodeURL
|
||||
// (or Config.DeviceAuth) and VerifierOption(verifier) to Config.Exchange
|
||||
// (or Config.DeviceAccessToken).
|
||||
// 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
|
||||
@@ -36,22 +37,22 @@ func GenerateVerifier() string {
|
||||
return base64.RawURLEncoding.EncodeToString(data)
|
||||
}
|
||||
|
||||
// VerifierOption returns a PKCE code verifier AuthCodeOption. It should be
|
||||
// passed to Config.Exchange or Config.DeviceAccessToken only.
|
||||
// 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.
|
||||
// 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
|
||||
// method S256. It should be passed to [Config.AuthCodeURL] or [Config.DeviceAuth]
|
||||
// only.
|
||||
func S256ChallengeOption(verifier string) AuthCodeOption {
|
||||
return challengeOption{
|
||||
|
15
vendor/golang.org/x/oauth2/token.go
generated
vendored
15
vendor/golang.org/x/oauth2/token.go
generated
vendored
@@ -44,7 +44,7 @@ type Token struct {
|
||||
|
||||
// Expiry is the optional expiration time of the access token.
|
||||
//
|
||||
// If zero, TokenSource implementations will reuse the same
|
||||
// If zero, [TokenSource] implementations will reuse the same
|
||||
// token forever and RefreshToken or equivalent
|
||||
// mechanisms for that TokenSource will not be used.
|
||||
Expiry time.Time `json:"expiry,omitempty"`
|
||||
@@ -58,7 +58,7 @@ type Token struct {
|
||||
|
||||
// raw optionally contains extra metadata from the server
|
||||
// when updating a token.
|
||||
raw interface{}
|
||||
raw any
|
||||
|
||||
// expiryDelta is used to calculate when a token is considered
|
||||
// expired, by subtracting from Expiry. If zero, defaultExpiryDelta
|
||||
@@ -86,16 +86,16 @@ func (t *Token) Type() string {
|
||||
// SetAuthHeader sets the Authorization header to r using the access
|
||||
// token in t.
|
||||
//
|
||||
// This method is unnecessary when using Transport or an HTTP Client
|
||||
// This method is unnecessary when using [Transport] or an HTTP Client
|
||||
// returned by this package.
|
||||
func (t *Token) SetAuthHeader(r *http.Request) {
|
||||
r.Header.Set("Authorization", t.Type()+" "+t.AccessToken)
|
||||
}
|
||||
|
||||
// WithExtra returns a new Token that's a clone of t, but using the
|
||||
// WithExtra returns a new [Token] that's a clone of t, but using the
|
||||
// provided raw extra map. This is only intended for use by packages
|
||||
// implementing derivative OAuth2 flows.
|
||||
func (t *Token) WithExtra(extra interface{}) *Token {
|
||||
func (t *Token) WithExtra(extra any) *Token {
|
||||
t2 := new(Token)
|
||||
*t2 = *t
|
||||
t2.raw = extra
|
||||
@@ -105,8 +105,8 @@ func (t *Token) WithExtra(extra interface{}) *Token {
|
||||
// Extra returns an extra field.
|
||||
// Extra fields are key-value pairs returned by the server as a
|
||||
// part of the token retrieval response.
|
||||
func (t *Token) Extra(key string) interface{} {
|
||||
if raw, ok := t.raw.(map[string]interface{}); ok {
|
||||
func (t *Token) Extra(key string) any {
|
||||
if raw, ok := t.raw.(map[string]any); ok {
|
||||
return raw[key]
|
||||
}
|
||||
|
||||
@@ -163,6 +163,7 @@ func tokenFromInternal(t *internal.Token) *Token {
|
||||
TokenType: t.TokenType,
|
||||
RefreshToken: t.RefreshToken,
|
||||
Expiry: t.Expiry,
|
||||
ExpiresIn: t.ExpiresIn,
|
||||
raw: t.Raw,
|
||||
}
|
||||
}
|
||||
|
24
vendor/golang.org/x/oauth2/transport.go
generated
vendored
24
vendor/golang.org/x/oauth2/transport.go
generated
vendored
@@ -11,12 +11,12 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Transport is an http.RoundTripper that makes OAuth 2.0 HTTP requests,
|
||||
// wrapping a base RoundTripper and adding an Authorization header
|
||||
// with a token from the supplied Sources.
|
||||
// Transport is an [http.RoundTripper] that makes OAuth 2.0 HTTP requests,
|
||||
// wrapping a base [http.RoundTripper] and adding an Authorization header
|
||||
// with a token from the supplied [TokenSource].
|
||||
//
|
||||
// Transport is a low-level mechanism. Most code will use the
|
||||
// higher-level Config.Client method instead.
|
||||
// higher-level [Config.Client] method instead.
|
||||
type Transport struct {
|
||||
// Source supplies the token to add to outgoing requests'
|
||||
// Authorization headers.
|
||||
@@ -47,7 +47,7 @@ func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req2 := cloneRequest(req) // per RoundTripper contract
|
||||
req2 := req.Clone(req.Context())
|
||||
token.SetAuthHeader(req2)
|
||||
|
||||
// req.Body is assumed to be closed by the base RoundTripper.
|
||||
@@ -73,17 +73,3 @@ func (t *Transport) base() http.RoundTripper {
|
||||
}
|
||||
return http.DefaultTransport
|
||||
}
|
||||
|
||||
// cloneRequest returns a clone of the provided *http.Request.
|
||||
// The clone is a shallow copy of the struct and its Header map.
|
||||
func cloneRequest(r *http.Request) *http.Request {
|
||||
// shallow copy of the struct
|
||||
r2 := new(http.Request)
|
||||
*r2 = *r
|
||||
// deep copy of the Header
|
||||
r2.Header = make(http.Header, len(r.Header))
|
||||
for k, s := range r.Header {
|
||||
r2.Header[k] = append([]string(nil), s...)
|
||||
}
|
||||
return r2
|
||||
}
|
||||
|
20
vendor/golang.org/x/sync/errgroup/errgroup.go
generated
vendored
20
vendor/golang.org/x/sync/errgroup/errgroup.go
generated
vendored
@@ -61,12 +61,14 @@ func (g *Group) Wait() error {
|
||||
}
|
||||
|
||||
// Go calls the given function in a new goroutine.
|
||||
//
|
||||
// The first call to Go must happen before a Wait.
|
||||
// It blocks until the new goroutine can be added without the number of
|
||||
// active goroutines in the group exceeding the configured limit.
|
||||
// goroutines in the group exceeding the configured limit.
|
||||
//
|
||||
// The first call to return a non-nil error cancels the group's context, if the
|
||||
// group was created by calling WithContext. The error will be returned by Wait.
|
||||
// The first goroutine in the group that returns a non-nil error will
|
||||
// cancel the associated Context, if any. The error will be returned
|
||||
// by Wait.
|
||||
func (g *Group) Go(f func() error) {
|
||||
if g.sem != nil {
|
||||
g.sem <- token{}
|
||||
@@ -76,6 +78,18 @@ func (g *Group) Go(f func() error) {
|
||||
go func() {
|
||||
defer g.done()
|
||||
|
||||
// It is tempting to propagate panics from f()
|
||||
// up to the goroutine that calls Wait, but
|
||||
// it creates more problems than it solves:
|
||||
// - it delays panics arbitrarily,
|
||||
// making bugs harder to detect;
|
||||
// - it turns f's panic stack into a mere value,
|
||||
// hiding it from crash-monitoring tools;
|
||||
// - it risks deadlocks that hide the panic entirely,
|
||||
// if f's panic leaves the program in a state
|
||||
// that prevents the Wait call from being reached.
|
||||
// See #53757, #74275, #74304, #74306.
|
||||
|
||||
if err := f(); err != nil {
|
||||
g.errOnce.Do(func() {
|
||||
g.err = err
|
||||
|
Reference in New Issue
Block a user