update package dependencies (#5463)
Signed-off-by: fsl <1171313930@qq.com> Signed-off-by: fsl <1171313930@qq.com>
This commit is contained in:
3
vendor/golang.org/x/crypto/AUTHORS
generated
vendored
3
vendor/golang.org/x/crypto/AUTHORS
generated
vendored
@@ -1,3 +0,0 @@
|
||||
# This source code refers to The Go Authors for copyright purposes.
|
||||
# The master list of authors is in the main Go distribution,
|
||||
# visible at https://tip.golang.org/AUTHORS.
|
||||
3
vendor/golang.org/x/crypto/CONTRIBUTORS
generated
vendored
3
vendor/golang.org/x/crypto/CONTRIBUTORS
generated
vendored
@@ -1,3 +0,0 @@
|
||||
# This source code was written by the Go contributors.
|
||||
# The master list of contributors is in the main Go distribution,
|
||||
# visible at https://tip.golang.org/CONTRIBUTORS.
|
||||
11
vendor/golang.org/x/crypto/bcrypt/bcrypt.go
generated
vendored
11
vendor/golang.org/x/crypto/bcrypt/bcrypt.go
generated
vendored
@@ -50,7 +50,7 @@ func (ih InvalidHashPrefixError) Error() string {
|
||||
type InvalidCostError int
|
||||
|
||||
func (ic InvalidCostError) Error() string {
|
||||
return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), int(MinCost), int(MaxCost))
|
||||
return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), MinCost, MaxCost)
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -82,11 +82,20 @@ type hashed struct {
|
||||
minor byte
|
||||
}
|
||||
|
||||
// ErrPasswordTooLong is returned when the password passed to
|
||||
// GenerateFromPassword is too long (i.e. > 72 bytes).
|
||||
var ErrPasswordTooLong = errors.New("bcrypt: password length exceeds 72 bytes")
|
||||
|
||||
// GenerateFromPassword returns the bcrypt hash of the password at the given
|
||||
// cost. If the cost given is less than MinCost, the cost will be set to
|
||||
// DefaultCost, instead. Use CompareHashAndPassword, as defined in this package,
|
||||
// to compare the returned hashed password with its cleartext version.
|
||||
// GenerateFromPassword does not accept passwords longer than 72 bytes, which
|
||||
// is the longest password bcrypt will operate on.
|
||||
func GenerateFromPassword(password []byte, cost int) ([]byte, error) {
|
||||
if len(password) > 72 {
|
||||
return nil, ErrPasswordTooLong
|
||||
}
|
||||
p, err := newFromPassword(password, cost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
11
vendor/golang.org/x/crypto/cast5/cast5.go
generated
vendored
11
vendor/golang.org/x/crypto/cast5/cast5.go
generated
vendored
@@ -13,7 +13,10 @@
|
||||
// golang.org/x/crypto/chacha20poly1305).
|
||||
package cast5 // import "golang.org/x/crypto/cast5"
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"errors"
|
||||
"math/bits"
|
||||
)
|
||||
|
||||
const BlockSize = 8
|
||||
const KeySize = 16
|
||||
@@ -241,19 +244,19 @@ func (c *Cipher) keySchedule(in []byte) {
|
||||
// These are the three 'f' functions. See RFC 2144, section 2.2.
|
||||
func f1(d, m uint32, r uint8) uint32 {
|
||||
t := m + d
|
||||
I := (t << r) | (t >> (32 - r))
|
||||
I := bits.RotateLeft32(t, int(r))
|
||||
return ((sBox[0][I>>24] ^ sBox[1][(I>>16)&0xff]) - sBox[2][(I>>8)&0xff]) + sBox[3][I&0xff]
|
||||
}
|
||||
|
||||
func f2(d, m uint32, r uint8) uint32 {
|
||||
t := m ^ d
|
||||
I := (t << r) | (t >> (32 - r))
|
||||
I := bits.RotateLeft32(t, int(r))
|
||||
return ((sBox[0][I>>24] - sBox[1][(I>>16)&0xff]) + sBox[2][(I>>8)&0xff]) ^ sBox[3][I&0xff]
|
||||
}
|
||||
|
||||
func f3(d, m uint32, r uint8) uint32 {
|
||||
t := m - d
|
||||
I := (t << r) | (t >> (32 - r))
|
||||
I := bits.RotateLeft32(t, int(r))
|
||||
return ((sBox[0][I>>24] + sBox[1][(I>>16)&0xff]) ^ sBox[2][(I>>8)&0xff]) - sBox[3][I&0xff]
|
||||
}
|
||||
|
||||
|
||||
4
vendor/golang.org/x/crypto/chacha20/chacha_generic.go
generated
vendored
4
vendor/golang.org/x/crypto/chacha20/chacha_generic.go
generated
vendored
@@ -12,7 +12,7 @@ import (
|
||||
"errors"
|
||||
"math/bits"
|
||||
|
||||
"golang.org/x/crypto/internal/subtle"
|
||||
"golang.org/x/crypto/internal/alias"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -189,7 +189,7 @@ func (s *Cipher) XORKeyStream(dst, src []byte) {
|
||||
panic("chacha20: output smaller than input")
|
||||
}
|
||||
dst = dst[:len(src)]
|
||||
if subtle.InexactOverlap(dst, src) {
|
||||
if alias.InexactOverlap(dst, src) {
|
||||
panic("chacha20: invalid buffer overlap")
|
||||
}
|
||||
|
||||
|
||||
1
vendor/golang.org/x/crypto/chacha20/chacha_s390x.go
generated
vendored
1
vendor/golang.org/x/crypto/chacha20/chacha_s390x.go
generated
vendored
@@ -15,6 +15,7 @@ const bufSize = 256
|
||||
|
||||
// xorKeyStreamVX is an assembly implementation of XORKeyStream. It must only
|
||||
// be called when the vector facility is available. Implementation in asm_s390x.s.
|
||||
//
|
||||
//go:noescape
|
||||
func xorKeyStreamVX(dst, src []byte, key *[8]uint32, nonce *[3]uint32, counter *uint32)
|
||||
|
||||
|
||||
84
vendor/golang.org/x/crypto/cryptobyte/asn1.go
generated
vendored
84
vendor/golang.org/x/crypto/cryptobyte/asn1.go
generated
vendored
@@ -264,36 +264,35 @@ func (s *String) ReadASN1Boolean(out *bool) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
var bigIntType = reflect.TypeOf((*big.Int)(nil)).Elem()
|
||||
|
||||
// ReadASN1Integer decodes an ASN.1 INTEGER into out and advances. If out does
|
||||
// not point to an integer or to a big.Int, it panics. It reports whether the
|
||||
// read was successful.
|
||||
// not point to an integer, to a big.Int, or to a []byte it panics. Only
|
||||
// positive and zero values can be decoded into []byte, and they are returned as
|
||||
// big-endian binary values that share memory with s. Positive values will have
|
||||
// no leading zeroes, and zero will be returned as a single zero byte.
|
||||
// ReadASN1Integer reports whether the read was successful.
|
||||
func (s *String) ReadASN1Integer(out interface{}) bool {
|
||||
if reflect.TypeOf(out).Kind() != reflect.Ptr {
|
||||
panic("out is not a pointer")
|
||||
}
|
||||
switch reflect.ValueOf(out).Elem().Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
switch out := out.(type) {
|
||||
case *int, *int8, *int16, *int32, *int64:
|
||||
var i int64
|
||||
if !s.readASN1Int64(&i) || reflect.ValueOf(out).Elem().OverflowInt(i) {
|
||||
return false
|
||||
}
|
||||
reflect.ValueOf(out).Elem().SetInt(i)
|
||||
return true
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
case *uint, *uint8, *uint16, *uint32, *uint64:
|
||||
var u uint64
|
||||
if !s.readASN1Uint64(&u) || reflect.ValueOf(out).Elem().OverflowUint(u) {
|
||||
return false
|
||||
}
|
||||
reflect.ValueOf(out).Elem().SetUint(u)
|
||||
return true
|
||||
case reflect.Struct:
|
||||
if reflect.TypeOf(out).Elem() == bigIntType {
|
||||
return s.readASN1BigInt(out.(*big.Int))
|
||||
}
|
||||
case *big.Int:
|
||||
return s.readASN1BigInt(out)
|
||||
case *[]byte:
|
||||
return s.readASN1Bytes(out)
|
||||
default:
|
||||
panic("out does not point to an integer type")
|
||||
}
|
||||
panic("out does not point to an integer type")
|
||||
}
|
||||
|
||||
func checkASN1Integer(bytes []byte) bool {
|
||||
@@ -333,6 +332,21 @@ func (s *String) readASN1BigInt(out *big.Int) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *String) readASN1Bytes(out *[]byte) bool {
|
||||
var bytes String
|
||||
if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) {
|
||||
return false
|
||||
}
|
||||
if bytes[0]&0x80 == 0x80 {
|
||||
return false
|
||||
}
|
||||
for len(bytes) > 1 && bytes[0] == 0 {
|
||||
bytes = bytes[1:]
|
||||
}
|
||||
*out = bytes
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *String) readASN1Int64(out *int64) bool {
|
||||
var bytes String
|
||||
if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) || !asn1Signed(out, bytes) {
|
||||
@@ -407,7 +421,12 @@ func (s *String) ReadASN1Enum(out *int) bool {
|
||||
func (s *String) readBase128Int(out *int) bool {
|
||||
ret := 0
|
||||
for i := 0; len(*s) > 0; i++ {
|
||||
if i == 4 {
|
||||
if i == 5 {
|
||||
return false
|
||||
}
|
||||
// Avoid overflowing int on a 32-bit platform.
|
||||
// We don't want different behavior based on the architecture.
|
||||
if ret >= 1<<(31-7) {
|
||||
return false
|
||||
}
|
||||
ret <<= 7
|
||||
@@ -527,7 +546,7 @@ func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
paddingBits := uint8(bytes[0])
|
||||
paddingBits := bytes[0]
|
||||
bytes = bytes[1:]
|
||||
if paddingBits > 7 ||
|
||||
len(bytes) == 0 && paddingBits != 0 ||
|
||||
@@ -549,7 +568,7 @@ func (s *String) ReadASN1BitStringAsBytes(out *[]byte) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
paddingBits := uint8(bytes[0])
|
||||
paddingBits := bytes[0]
|
||||
if paddingBits != 0 {
|
||||
return false
|
||||
}
|
||||
@@ -649,34 +668,27 @@ func (s *String) SkipOptionalASN1(tag asn1.Tag) bool {
|
||||
return s.ReadASN1(&unused, tag)
|
||||
}
|
||||
|
||||
// ReadOptionalASN1Integer attempts to read an optional ASN.1 INTEGER
|
||||
// explicitly tagged with tag into out and advances. If no element with a
|
||||
// matching tag is present, it writes defaultValue into out instead. If out
|
||||
// does not point to an integer or to a big.Int, it panics. It reports
|
||||
// whether the read was successful.
|
||||
// ReadOptionalASN1Integer attempts to read an optional ASN.1 INTEGER explicitly
|
||||
// tagged with tag into out and advances. If no element with a matching tag is
|
||||
// present, it writes defaultValue into out instead. Otherwise, it behaves like
|
||||
// ReadASN1Integer.
|
||||
func (s *String) ReadOptionalASN1Integer(out interface{}, tag asn1.Tag, defaultValue interface{}) bool {
|
||||
if reflect.TypeOf(out).Kind() != reflect.Ptr {
|
||||
panic("out is not a pointer")
|
||||
}
|
||||
var present bool
|
||||
var i String
|
||||
if !s.ReadOptionalASN1(&i, &present, tag) {
|
||||
return false
|
||||
}
|
||||
if !present {
|
||||
switch reflect.ValueOf(out).Elem().Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
switch out.(type) {
|
||||
case *int, *int8, *int16, *int32, *int64,
|
||||
*uint, *uint8, *uint16, *uint32, *uint64, *[]byte:
|
||||
reflect.ValueOf(out).Elem().Set(reflect.ValueOf(defaultValue))
|
||||
case reflect.Struct:
|
||||
if reflect.TypeOf(out).Elem() != bigIntType {
|
||||
panic("invalid integer type")
|
||||
}
|
||||
if reflect.TypeOf(defaultValue).Kind() != reflect.Ptr ||
|
||||
reflect.TypeOf(defaultValue).Elem() != bigIntType {
|
||||
case *big.Int:
|
||||
if defaultValue, ok := defaultValue.(*big.Int); ok {
|
||||
out.(*big.Int).Set(defaultValue)
|
||||
} else {
|
||||
panic("out points to big.Int, but defaultValue does not")
|
||||
}
|
||||
out.(*big.Int).Set(defaultValue.(*big.Int))
|
||||
default:
|
||||
panic("invalid integer type")
|
||||
}
|
||||
|
||||
19
vendor/golang.org/x/crypto/cryptobyte/builder.go
generated
vendored
19
vendor/golang.org/x/crypto/cryptobyte/builder.go
generated
vendored
@@ -95,6 +95,11 @@ func (b *Builder) AddUint32(v uint32) {
|
||||
b.add(byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
|
||||
}
|
||||
|
||||
// AddUint64 appends a big-endian, 64-bit value to the byte string.
|
||||
func (b *Builder) AddUint64(v uint64) {
|
||||
b.add(byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
|
||||
}
|
||||
|
||||
// AddBytes appends a sequence of bytes to the byte string.
|
||||
func (b *Builder) AddBytes(v []byte) {
|
||||
b.add(v...)
|
||||
@@ -106,13 +111,13 @@ func (b *Builder) AddBytes(v []byte) {
|
||||
// supplied to them. The child builder passed to the continuation can be used
|
||||
// to build the content of the length-prefixed sequence. For example:
|
||||
//
|
||||
// parent := cryptobyte.NewBuilder()
|
||||
// parent.AddUint8LengthPrefixed(func (child *Builder) {
|
||||
// child.AddUint8(42)
|
||||
// child.AddUint8LengthPrefixed(func (grandchild *Builder) {
|
||||
// grandchild.AddUint8(5)
|
||||
// })
|
||||
// })
|
||||
// parent := cryptobyte.NewBuilder()
|
||||
// parent.AddUint8LengthPrefixed(func (child *Builder) {
|
||||
// child.AddUint8(42)
|
||||
// child.AddUint8LengthPrefixed(func (grandchild *Builder) {
|
||||
// grandchild.AddUint8(5)
|
||||
// })
|
||||
// })
|
||||
//
|
||||
// It is an error to write more bytes to the child than allowed by the reserved
|
||||
// length prefix. After the continuation returns, the child must be considered
|
||||
|
||||
11
vendor/golang.org/x/crypto/cryptobyte/string.go
generated
vendored
11
vendor/golang.org/x/crypto/cryptobyte/string.go
generated
vendored
@@ -81,6 +81,17 @@ func (s *String) ReadUint32(out *uint32) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// ReadUint64 decodes a big-endian, 64-bit value into out and advances over it.
|
||||
// It reports whether the read was successful.
|
||||
func (s *String) ReadUint64(out *uint64) bool {
|
||||
v := s.read(8)
|
||||
if v == nil {
|
||||
return false
|
||||
}
|
||||
*out = uint64(v[0])<<56 | uint64(v[1])<<48 | uint64(v[2])<<40 | uint64(v[3])<<32 | uint64(v[4])<<24 | uint64(v[5])<<16 | uint64(v[6])<<8 | uint64(v[7])
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *String) readUnsigned(out *uint32, length int) bool {
|
||||
v := s.read(length)
|
||||
if v == nil {
|
||||
|
||||
9
vendor/golang.org/x/crypto/curve25519/curve25519.go
generated
vendored
9
vendor/golang.org/x/crypto/curve25519/curve25519.go
generated
vendored
@@ -9,7 +9,8 @@ package curve25519 // import "golang.org/x/crypto/curve25519"
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"fmt"
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/crypto/curve25519/internal/field"
|
||||
)
|
||||
@@ -124,10 +125,10 @@ func X25519(scalar, point []byte) ([]byte, error) {
|
||||
func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
|
||||
var in [32]byte
|
||||
if l := len(scalar); l != 32 {
|
||||
return nil, fmt.Errorf("bad scalar length: %d, expected %d", l, 32)
|
||||
return nil, errors.New("bad scalar length: " + strconv.Itoa(l) + ", expected 32")
|
||||
}
|
||||
if l := len(point); l != 32 {
|
||||
return nil, fmt.Errorf("bad point length: %d, expected %d", l, 32)
|
||||
return nil, errors.New("bad point length: " + strconv.Itoa(l) + ", expected 32")
|
||||
}
|
||||
copy(in[:], scalar)
|
||||
if &point[0] == &Basepoint[0] {
|
||||
@@ -138,7 +139,7 @@ func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
|
||||
copy(base[:], point)
|
||||
ScalarMult(dst, &in, &base)
|
||||
if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 {
|
||||
return nil, fmt.Errorf("bad input point: low order point")
|
||||
return nil, errors.New("bad input point: low order point")
|
||||
}
|
||||
}
|
||||
return dst[:], nil
|
||||
|
||||
3
vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go
generated
vendored
3
vendor/golang.org/x/crypto/curve25519/internal/field/fe_amd64.go
generated
vendored
@@ -1,13 +1,16 @@
|
||||
// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
|
||||
|
||||
//go:build amd64 && gc && !purego
|
||||
// +build amd64,gc,!purego
|
||||
|
||||
package field
|
||||
|
||||
// feMul sets out = a * b. It works like feMulGeneric.
|
||||
//
|
||||
//go:noescape
|
||||
func feMul(out *Element, a *Element, b *Element)
|
||||
|
||||
// feSquare sets out = a * a. It works like feSquareGeneric.
|
||||
//
|
||||
//go:noescape
|
||||
func feSquare(out *Element, a *Element)
|
||||
|
||||
188
vendor/golang.org/x/crypto/ed25519/ed25519.go
generated
vendored
188
vendor/golang.org/x/crypto/ed25519/ed25519.go
generated
vendored
@@ -1,13 +1,7 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// 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.
|
||||
|
||||
// In Go 1.13, the ed25519 package was promoted to the standard library as
|
||||
// crypto/ed25519, and this package became a wrapper for the standard library one.
|
||||
//
|
||||
//go:build !go1.13
|
||||
// +build !go1.13
|
||||
|
||||
// Package ed25519 implements the Ed25519 signature algorithm. See
|
||||
// https://ed25519.cr.yp.to/.
|
||||
//
|
||||
@@ -16,21 +10,15 @@
|
||||
// representation includes a public key suffix to make multiple signing
|
||||
// operations with the same key more efficient. This package refers to the RFC
|
||||
// 8032 private key as the “seed”.
|
||||
//
|
||||
// Beginning with Go 1.13, the functionality of this package was moved to the
|
||||
// standard library as crypto/ed25519. This package only acts as a compatibility
|
||||
// wrapper.
|
||||
package ed25519
|
||||
|
||||
// This code is a port of the public domain, “ref10” implementation of ed25519
|
||||
// from SUPERCOP.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
cryptorand "crypto/rand"
|
||||
"crypto/sha512"
|
||||
"errors"
|
||||
"crypto/ed25519"
|
||||
"io"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/crypto/ed25519/internal/edwards25519"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -45,57 +33,21 @@ const (
|
||||
)
|
||||
|
||||
// PublicKey is the type of Ed25519 public keys.
|
||||
type PublicKey []byte
|
||||
//
|
||||
// This type is an alias for crypto/ed25519's PublicKey type.
|
||||
// See the crypto/ed25519 package for the methods on this type.
|
||||
type PublicKey = ed25519.PublicKey
|
||||
|
||||
// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer.
|
||||
type PrivateKey []byte
|
||||
|
||||
// Public returns the PublicKey corresponding to priv.
|
||||
func (priv PrivateKey) Public() crypto.PublicKey {
|
||||
publicKey := make([]byte, PublicKeySize)
|
||||
copy(publicKey, priv[32:])
|
||||
return PublicKey(publicKey)
|
||||
}
|
||||
|
||||
// Seed returns the private key seed corresponding to priv. It is provided for
|
||||
// interoperability with RFC 8032. RFC 8032's private keys correspond to seeds
|
||||
// in this package.
|
||||
func (priv PrivateKey) Seed() []byte {
|
||||
seed := make([]byte, SeedSize)
|
||||
copy(seed, priv[:32])
|
||||
return seed
|
||||
}
|
||||
|
||||
// Sign signs the given message with priv.
|
||||
// Ed25519 performs two passes over messages to be signed and therefore cannot
|
||||
// handle pre-hashed messages. Thus opts.HashFunc() must return zero to
|
||||
// indicate the message hasn't been hashed. This can be achieved by passing
|
||||
// crypto.Hash(0) as the value for opts.
|
||||
func (priv PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts) (signature []byte, err error) {
|
||||
if opts.HashFunc() != crypto.Hash(0) {
|
||||
return nil, errors.New("ed25519: cannot sign hashed message")
|
||||
}
|
||||
|
||||
return Sign(priv, message), nil
|
||||
}
|
||||
//
|
||||
// This type is an alias for crypto/ed25519's PrivateKey type.
|
||||
// See the crypto/ed25519 package for the methods on this type.
|
||||
type PrivateKey = ed25519.PrivateKey
|
||||
|
||||
// GenerateKey generates a public/private key pair using entropy from rand.
|
||||
// If rand is nil, crypto/rand.Reader will be used.
|
||||
func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
|
||||
if rand == nil {
|
||||
rand = cryptorand.Reader
|
||||
}
|
||||
|
||||
seed := make([]byte, SeedSize)
|
||||
if _, err := io.ReadFull(rand, seed); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
privateKey := NewKeyFromSeed(seed)
|
||||
publicKey := make([]byte, PublicKeySize)
|
||||
copy(publicKey, privateKey[32:])
|
||||
|
||||
return publicKey, privateKey, nil
|
||||
return ed25519.GenerateKey(rand)
|
||||
}
|
||||
|
||||
// NewKeyFromSeed calculates a private key from a seed. It will panic if
|
||||
@@ -103,121 +55,17 @@ func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
|
||||
// with RFC 8032. RFC 8032's private keys correspond to seeds in this
|
||||
// package.
|
||||
func NewKeyFromSeed(seed []byte) PrivateKey {
|
||||
if l := len(seed); l != SeedSize {
|
||||
panic("ed25519: bad seed length: " + strconv.Itoa(l))
|
||||
}
|
||||
|
||||
digest := sha512.Sum512(seed)
|
||||
digest[0] &= 248
|
||||
digest[31] &= 127
|
||||
digest[31] |= 64
|
||||
|
||||
var A edwards25519.ExtendedGroupElement
|
||||
var hBytes [32]byte
|
||||
copy(hBytes[:], digest[:])
|
||||
edwards25519.GeScalarMultBase(&A, &hBytes)
|
||||
var publicKeyBytes [32]byte
|
||||
A.ToBytes(&publicKeyBytes)
|
||||
|
||||
privateKey := make([]byte, PrivateKeySize)
|
||||
copy(privateKey, seed)
|
||||
copy(privateKey[32:], publicKeyBytes[:])
|
||||
|
||||
return privateKey
|
||||
return ed25519.NewKeyFromSeed(seed)
|
||||
}
|
||||
|
||||
// Sign signs the message with privateKey and returns a signature. It will
|
||||
// panic if len(privateKey) is not PrivateKeySize.
|
||||
func Sign(privateKey PrivateKey, message []byte) []byte {
|
||||
if l := len(privateKey); l != PrivateKeySize {
|
||||
panic("ed25519: bad private key length: " + strconv.Itoa(l))
|
||||
}
|
||||
|
||||
h := sha512.New()
|
||||
h.Write(privateKey[:32])
|
||||
|
||||
var digest1, messageDigest, hramDigest [64]byte
|
||||
var expandedSecretKey [32]byte
|
||||
h.Sum(digest1[:0])
|
||||
copy(expandedSecretKey[:], digest1[:])
|
||||
expandedSecretKey[0] &= 248
|
||||
expandedSecretKey[31] &= 63
|
||||
expandedSecretKey[31] |= 64
|
||||
|
||||
h.Reset()
|
||||
h.Write(digest1[32:])
|
||||
h.Write(message)
|
||||
h.Sum(messageDigest[:0])
|
||||
|
||||
var messageDigestReduced [32]byte
|
||||
edwards25519.ScReduce(&messageDigestReduced, &messageDigest)
|
||||
var R edwards25519.ExtendedGroupElement
|
||||
edwards25519.GeScalarMultBase(&R, &messageDigestReduced)
|
||||
|
||||
var encodedR [32]byte
|
||||
R.ToBytes(&encodedR)
|
||||
|
||||
h.Reset()
|
||||
h.Write(encodedR[:])
|
||||
h.Write(privateKey[32:])
|
||||
h.Write(message)
|
||||
h.Sum(hramDigest[:0])
|
||||
var hramDigestReduced [32]byte
|
||||
edwards25519.ScReduce(&hramDigestReduced, &hramDigest)
|
||||
|
||||
var s [32]byte
|
||||
edwards25519.ScMulAdd(&s, &hramDigestReduced, &expandedSecretKey, &messageDigestReduced)
|
||||
|
||||
signature := make([]byte, SignatureSize)
|
||||
copy(signature[:], encodedR[:])
|
||||
copy(signature[32:], s[:])
|
||||
|
||||
return signature
|
||||
return ed25519.Sign(privateKey, message)
|
||||
}
|
||||
|
||||
// Verify reports whether sig is a valid signature of message by publicKey. It
|
||||
// will panic if len(publicKey) is not PublicKeySize.
|
||||
func Verify(publicKey PublicKey, message, sig []byte) bool {
|
||||
if l := len(publicKey); l != PublicKeySize {
|
||||
panic("ed25519: bad public key length: " + strconv.Itoa(l))
|
||||
}
|
||||
|
||||
if len(sig) != SignatureSize || sig[63]&224 != 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
var A edwards25519.ExtendedGroupElement
|
||||
var publicKeyBytes [32]byte
|
||||
copy(publicKeyBytes[:], publicKey)
|
||||
if !A.FromBytes(&publicKeyBytes) {
|
||||
return false
|
||||
}
|
||||
edwards25519.FeNeg(&A.X, &A.X)
|
||||
edwards25519.FeNeg(&A.T, &A.T)
|
||||
|
||||
h := sha512.New()
|
||||
h.Write(sig[:32])
|
||||
h.Write(publicKey[:])
|
||||
h.Write(message)
|
||||
var digest [64]byte
|
||||
h.Sum(digest[:0])
|
||||
|
||||
var hReduced [32]byte
|
||||
edwards25519.ScReduce(&hReduced, &digest)
|
||||
|
||||
var R edwards25519.ProjectiveGroupElement
|
||||
var s [32]byte
|
||||
copy(s[:], sig[32:])
|
||||
|
||||
// https://tools.ietf.org/html/rfc8032#section-5.1.7 requires that s be in
|
||||
// the range [0, order) in order to prevent signature malleability.
|
||||
if !edwards25519.ScMinimal(&s) {
|
||||
return false
|
||||
}
|
||||
|
||||
edwards25519.GeDoubleScalarMultVartime(&R, &hReduced, &A, &s)
|
||||
|
||||
var checkR [32]byte
|
||||
R.ToBytes(&checkR)
|
||||
return bytes.Equal(sig[:32], checkR[:])
|
||||
return ed25519.Verify(publicKey, message, sig)
|
||||
}
|
||||
|
||||
74
vendor/golang.org/x/crypto/ed25519/ed25519_go113.go
generated
vendored
74
vendor/golang.org/x/crypto/ed25519/ed25519_go113.go
generated
vendored
@@ -1,74 +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.
|
||||
|
||||
//go:build go1.13
|
||||
// +build go1.13
|
||||
|
||||
// Package ed25519 implements the Ed25519 signature algorithm. See
|
||||
// https://ed25519.cr.yp.to/.
|
||||
//
|
||||
// These functions are also compatible with the “Ed25519” function defined in
|
||||
// RFC 8032. However, unlike RFC 8032's formulation, this package's private key
|
||||
// representation includes a public key suffix to make multiple signing
|
||||
// operations with the same key more efficient. This package refers to the RFC
|
||||
// 8032 private key as the “seed”.
|
||||
//
|
||||
// Beginning with Go 1.13, the functionality of this package was moved to the
|
||||
// standard library as crypto/ed25519. This package only acts as a compatibility
|
||||
// wrapper.
|
||||
package ed25519
|
||||
|
||||
import (
|
||||
"crypto/ed25519"
|
||||
"io"
|
||||
)
|
||||
|
||||
const (
|
||||
// PublicKeySize is the size, in bytes, of public keys as used in this package.
|
||||
PublicKeySize = 32
|
||||
// PrivateKeySize is the size, in bytes, of private keys as used in this package.
|
||||
PrivateKeySize = 64
|
||||
// SignatureSize is the size, in bytes, of signatures generated and verified by this package.
|
||||
SignatureSize = 64
|
||||
// SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032.
|
||||
SeedSize = 32
|
||||
)
|
||||
|
||||
// PublicKey is the type of Ed25519 public keys.
|
||||
//
|
||||
// This type is an alias for crypto/ed25519's PublicKey type.
|
||||
// See the crypto/ed25519 package for the methods on this type.
|
||||
type PublicKey = ed25519.PublicKey
|
||||
|
||||
// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer.
|
||||
//
|
||||
// This type is an alias for crypto/ed25519's PrivateKey type.
|
||||
// See the crypto/ed25519 package for the methods on this type.
|
||||
type PrivateKey = ed25519.PrivateKey
|
||||
|
||||
// GenerateKey generates a public/private key pair using entropy from rand.
|
||||
// If rand is nil, crypto/rand.Reader will be used.
|
||||
func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
|
||||
return ed25519.GenerateKey(rand)
|
||||
}
|
||||
|
||||
// NewKeyFromSeed calculates a private key from a seed. It will panic if
|
||||
// len(seed) is not SeedSize. This function is provided for interoperability
|
||||
// with RFC 8032. RFC 8032's private keys correspond to seeds in this
|
||||
// package.
|
||||
func NewKeyFromSeed(seed []byte) PrivateKey {
|
||||
return ed25519.NewKeyFromSeed(seed)
|
||||
}
|
||||
|
||||
// Sign signs the message with privateKey and returns a signature. It will
|
||||
// panic if len(privateKey) is not PrivateKeySize.
|
||||
func Sign(privateKey PrivateKey, message []byte) []byte {
|
||||
return ed25519.Sign(privateKey, message)
|
||||
}
|
||||
|
||||
// Verify reports whether sig is a valid signature of message by publicKey. It
|
||||
// will panic if len(publicKey) is not PublicKeySize.
|
||||
func Verify(publicKey PublicKey, message, sig []byte) bool {
|
||||
return ed25519.Verify(publicKey, message, sig)
|
||||
}
|
||||
1422
vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go
generated
vendored
1422
vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go
generated
vendored
File diff suppressed because it is too large
Load Diff
1793
vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go
generated
vendored
1793
vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go
generated
vendored
File diff suppressed because it is too large
Load Diff
@@ -5,9 +5,8 @@
|
||||
//go:build !purego
|
||||
// +build !purego
|
||||
|
||||
// Package subtle implements functions that are often useful in cryptographic
|
||||
// code but require careful thought to use correctly.
|
||||
package subtle // import "golang.org/x/crypto/internal/subtle"
|
||||
// Package alias implements memory aliasing tests.
|
||||
package alias
|
||||
|
||||
import "unsafe"
|
||||
|
||||
@@ -5,9 +5,8 @@
|
||||
//go:build purego
|
||||
// +build purego
|
||||
|
||||
// Package subtle implements functions that are often useful in cryptographic
|
||||
// code but require careful thought to use correctly.
|
||||
package subtle // import "golang.org/x/crypto/internal/subtle"
|
||||
// Package alias implements memory aliasing tests.
|
||||
package alias
|
||||
|
||||
// This is the Google App Engine standard variant based on reflect
|
||||
// because the unsafe package and cgo are disallowed.
|
||||
@@ -15,7 +15,7 @@
|
||||
// used with a fixed key in order to generate one-time keys from an nonce.
|
||||
// However, in this package AES isn't used and the one-time key is specified
|
||||
// directly.
|
||||
package poly1305 // import "golang.org/x/crypto/poly1305"
|
||||
package poly1305
|
||||
|
||||
import "crypto/subtle"
|
||||
|
||||
@@ -136,7 +136,7 @@ func shiftRightBy2(a uint128) uint128 {
|
||||
// updateGeneric absorbs msg into the state.h accumulator. For each chunk m of
|
||||
// 128 bits of message, it computes
|
||||
//
|
||||
// h₊ = (h + m) * r mod 2¹³⁰ - 5
|
||||
// h₊ = (h + m) * r mod 2¹³⁰ - 5
|
||||
//
|
||||
// If the msg length is not a multiple of TagSize, it assumes the last
|
||||
// incomplete chunk is the final one.
|
||||
@@ -278,8 +278,7 @@ const (
|
||||
|
||||
// finalize completes the modular reduction of h and computes
|
||||
//
|
||||
// out = h + s mod 2¹²⁸
|
||||
//
|
||||
// out = h + s mod 2¹²⁸
|
||||
func finalize(out *[TagSize]byte, h *[3]uint64, s *[2]uint64) {
|
||||
h0, h1, h2 := h[0], h[1], h[2]
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
// updateVX is an assembly implementation of Poly1305 that uses vector
|
||||
// instructions. It must only be called if the vector facility (vx) is
|
||||
// available.
|
||||
//
|
||||
//go:noescape
|
||||
func updateVX(state *macState, msg []byte)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
// value. These limbs are, for the most part, zero extended and
|
||||
// placed into 64-bit vector register elements. Each vector
|
||||
// register is 128-bits wide and so holds 2 of these elements.
|
||||
// Using 26-bit limbs allows us plenty of headroom to accomodate
|
||||
// Using 26-bit limbs allows us plenty of headroom to accommodate
|
||||
// accumulations before and after multiplication without
|
||||
// overflowing either 32-bits (before multiplication) or 64-bits
|
||||
// (after multiplication).
|
||||
8
vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go
generated
vendored
8
vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go
generated
vendored
@@ -35,8 +35,8 @@ This package is interoperable with NaCl: https://nacl.cr.yp.to/secretbox.html.
|
||||
package secretbox // import "golang.org/x/crypto/nacl/secretbox"
|
||||
|
||||
import (
|
||||
"golang.org/x/crypto/internal/subtle"
|
||||
"golang.org/x/crypto/poly1305"
|
||||
"golang.org/x/crypto/internal/alias"
|
||||
"golang.org/x/crypto/internal/poly1305"
|
||||
"golang.org/x/crypto/salsa20/salsa"
|
||||
)
|
||||
|
||||
@@ -88,7 +88,7 @@ func Seal(out, message []byte, nonce *[24]byte, key *[32]byte) []byte {
|
||||
copy(poly1305Key[:], firstBlock[:])
|
||||
|
||||
ret, out := sliceForAppend(out, len(message)+poly1305.TagSize)
|
||||
if subtle.AnyOverlap(out, message) {
|
||||
if alias.AnyOverlap(out, message) {
|
||||
panic("nacl: invalid buffer overlap")
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ func Open(out, box []byte, nonce *[24]byte, key *[32]byte) ([]byte, bool) {
|
||||
}
|
||||
|
||||
ret, out := sliceForAppend(out, len(box)-Overhead)
|
||||
if subtle.AnyOverlap(out, box) {
|
||||
if alias.AnyOverlap(out, box) {
|
||||
panic("nacl: invalid buffer overlap")
|
||||
}
|
||||
|
||||
|
||||
20
vendor/golang.org/x/crypto/openpgp/armor/armor.go
generated
vendored
20
vendor/golang.org/x/crypto/openpgp/armor/armor.go
generated
vendored
@@ -4,6 +4,12 @@
|
||||
|
||||
// Package armor implements OpenPGP ASCII Armor, see RFC 4880. OpenPGP Armor is
|
||||
// very similar to PEM except that it has an additional CRC checksum.
|
||||
//
|
||||
// Deprecated: this package is unmaintained except for security fixes. New
|
||||
// applications should consider a more focused, modern alternative to OpenPGP
|
||||
// for their specific task. If you are required to interoperate with OpenPGP
|
||||
// systems and need a maintained package, consider a community fork.
|
||||
// See https://golang.org/issue/44226.
|
||||
package armor // import "golang.org/x/crypto/openpgp/armor"
|
||||
|
||||
import (
|
||||
@@ -17,12 +23,14 @@ import (
|
||||
// A Block represents an OpenPGP armored structure.
|
||||
//
|
||||
// The encoded form is:
|
||||
// -----BEGIN Type-----
|
||||
// Headers
|
||||
//
|
||||
// base64-encoded Bytes
|
||||
// '=' base64 encoded checksum
|
||||
// -----END Type-----
|
||||
// -----BEGIN Type-----
|
||||
// Headers
|
||||
//
|
||||
// base64-encoded Bytes
|
||||
// '=' base64 encoded checksum
|
||||
// -----END Type-----
|
||||
//
|
||||
// where Headers is a possibly empty sequence of Key: Value lines.
|
||||
//
|
||||
// Since the armored data can be very large, this package presents a streaming
|
||||
@@ -148,7 +156,7 @@ func (r *openpgpReader) Read(p []byte) (n int, err error) {
|
||||
n, err = r.b64Reader.Read(p)
|
||||
r.currentCRC = crc24(r.currentCRC, p[:n])
|
||||
|
||||
if err == io.EOF && r.lReader.crcSet && r.lReader.crc != uint32(r.currentCRC&crc24Mask) {
|
||||
if err == io.EOF && r.lReader.crcSet && r.lReader.crc != r.currentCRC&crc24Mask {
|
||||
return 0, ArmorCorrupt
|
||||
}
|
||||
|
||||
|
||||
3
vendor/golang.org/x/crypto/openpgp/armor/encode.go
generated
vendored
3
vendor/golang.org/x/crypto/openpgp/armor/encode.go
generated
vendored
@@ -96,7 +96,8 @@ func (l *lineBreaker) Close() (err error) {
|
||||
// trailer.
|
||||
//
|
||||
// It's built into a stack of io.Writers:
|
||||
// encoding -> base64 encoder -> lineBreaker -> out
|
||||
//
|
||||
// encoding -> base64 encoder -> lineBreaker -> out
|
||||
type encoding struct {
|
||||
out io.Writer
|
||||
breaker *lineBreaker
|
||||
|
||||
6
vendor/golang.org/x/crypto/openpgp/clearsign/clearsign.go
generated
vendored
6
vendor/golang.org/x/crypto/openpgp/clearsign/clearsign.go
generated
vendored
@@ -7,6 +7,12 @@
|
||||
//
|
||||
// Clearsigned messages are cryptographically signed, but the contents of the
|
||||
// message are kept in plaintext so that it can be read without special tools.
|
||||
//
|
||||
// Deprecated: this package is unmaintained except for security fixes. New
|
||||
// applications should consider a more focused, modern alternative to OpenPGP
|
||||
// for their specific task. If you are required to interoperate with OpenPGP
|
||||
// systems and need a maintained package, consider a community fork.
|
||||
// See https://golang.org/issue/44226.
|
||||
package clearsign // import "golang.org/x/crypto/openpgp/clearsign"
|
||||
|
||||
import (
|
||||
|
||||
10
vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go
generated
vendored
10
vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go
generated
vendored
@@ -10,6 +10,12 @@
|
||||
// This form of ElGamal embeds PKCS#1 v1.5 padding, which may make it
|
||||
// unsuitable for other protocols. RSA should be used in preference in any
|
||||
// case.
|
||||
//
|
||||
// Deprecated: this package was only provided to support ElGamal encryption in
|
||||
// OpenPGP. The golang.org/x/crypto/openpgp package is now deprecated (see
|
||||
// https://golang.org/issue/44226), and ElGamal in the OpenPGP ecosystem has
|
||||
// compatibility and security issues (see https://eprint.iacr.org/2021/923).
|
||||
// Moreover, this package doesn't protect against side-channel attacks.
|
||||
package elgamal // import "golang.org/x/crypto/openpgp/elgamal"
|
||||
|
||||
import (
|
||||
@@ -71,8 +77,8 @@ func Encrypt(random io.Reader, pub *PublicKey, msg []byte) (c1, c2 *big.Int, err
|
||||
// returns the plaintext of the message. An error can result only if the
|
||||
// ciphertext is invalid. Users should keep in mind that this is a padding
|
||||
// oracle and thus, if exposed to an adaptive chosen ciphertext attack, can
|
||||
// be used to break the cryptosystem. See ``Chosen Ciphertext Attacks
|
||||
// Against Protocols Based on the RSA Encryption Standard PKCS #1'', Daniel
|
||||
// be used to break the cryptosystem. See “Chosen Ciphertext Attacks
|
||||
// Against Protocols Based on the RSA Encryption Standard PKCS #1”, Daniel
|
||||
// Bleichenbacher, Advances in Cryptology (Crypto '98),
|
||||
func Decrypt(priv *PrivateKey, c1, c2 *big.Int) (msg []byte, err error) {
|
||||
s := new(big.Int).Exp(c1, priv.X, priv.P)
|
||||
|
||||
6
vendor/golang.org/x/crypto/openpgp/errors/errors.go
generated
vendored
6
vendor/golang.org/x/crypto/openpgp/errors/errors.go
generated
vendored
@@ -3,6 +3,12 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package errors contains common error types for the OpenPGP packages.
|
||||
//
|
||||
// Deprecated: this package is unmaintained except for security fixes. New
|
||||
// applications should consider a more focused, modern alternative to OpenPGP
|
||||
// for their specific task. If you are required to interoperate with OpenPGP
|
||||
// systems and need a maintained package, consider a community fork.
|
||||
// See https://golang.org/issue/44226.
|
||||
package errors // import "golang.org/x/crypto/openpgp/errors"
|
||||
|
||||
import (
|
||||
|
||||
3
vendor/golang.org/x/crypto/openpgp/packet/opaque.go
generated
vendored
3
vendor/golang.org/x/crypto/openpgp/packet/opaque.go
generated
vendored
@@ -7,7 +7,6 @@ package packet
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"golang.org/x/crypto/openpgp/errors"
|
||||
)
|
||||
@@ -26,7 +25,7 @@ type OpaquePacket struct {
|
||||
}
|
||||
|
||||
func (op *OpaquePacket) parse(r io.Reader) (err error) {
|
||||
op.Contents, err = ioutil.ReadAll(r)
|
||||
op.Contents, err = io.ReadAll(r)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
6
vendor/golang.org/x/crypto/openpgp/packet/packet.go
generated
vendored
6
vendor/golang.org/x/crypto/openpgp/packet/packet.go
generated
vendored
@@ -4,6 +4,12 @@
|
||||
|
||||
// Package packet implements parsing and serialization of OpenPGP packets, as
|
||||
// specified in RFC 4880.
|
||||
//
|
||||
// Deprecated: this package is unmaintained except for security fixes. New
|
||||
// applications should consider a more focused, modern alternative to OpenPGP
|
||||
// for their specific task. If you are required to interoperate with OpenPGP
|
||||
// systems and need a maintained package, consider a community fork.
|
||||
// See https://golang.org/issue/44226.
|
||||
package packet // import "golang.org/x/crypto/openpgp/packet"
|
||||
|
||||
import (
|
||||
|
||||
3
vendor/golang.org/x/crypto/openpgp/packet/private_key.go
generated
vendored
3
vendor/golang.org/x/crypto/openpgp/packet/private_key.go
generated
vendored
@@ -13,7 +13,6 @@ import (
|
||||
"crypto/rsa"
|
||||
"crypto/sha1"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"strconv"
|
||||
"time"
|
||||
@@ -133,7 +132,7 @@ func (pk *PrivateKey) parse(r io.Reader) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
pk.encryptedData, err = ioutil.ReadAll(r)
|
||||
pk.encryptedData, err = io.ReadAll(r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
2
vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go
generated
vendored
2
vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go
generated
vendored
@@ -236,7 +236,7 @@ func (w *seMDCWriter) Close() (err error) {
|
||||
return w.w.Close()
|
||||
}
|
||||
|
||||
// noOpCloser is like an ioutil.NopCloser, but for an io.Writer.
|
||||
// noOpCloser is like an io.NopCloser, but for an io.Writer.
|
||||
type noOpCloser struct {
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
3
vendor/golang.org/x/crypto/openpgp/packet/userattribute.go
generated
vendored
3
vendor/golang.org/x/crypto/openpgp/packet/userattribute.go
generated
vendored
@@ -9,7 +9,6 @@ import (
|
||||
"image"
|
||||
"image/jpeg"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
const UserAttrImageSubpacket = 1
|
||||
@@ -56,7 +55,7 @@ func NewUserAttribute(contents ...*OpaqueSubpacket) *UserAttribute {
|
||||
|
||||
func (uat *UserAttribute) parse(r io.Reader) (err error) {
|
||||
// RFC 4880, section 5.13
|
||||
b, err := ioutil.ReadAll(r)
|
||||
b, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
3
vendor/golang.org/x/crypto/openpgp/packet/userid.go
generated
vendored
3
vendor/golang.org/x/crypto/openpgp/packet/userid.go
generated
vendored
@@ -6,7 +6,6 @@ package packet
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -66,7 +65,7 @@ func NewUserId(name, comment, email string) *UserId {
|
||||
|
||||
func (uid *UserId) parse(r io.Reader) (err error) {
|
||||
// RFC 4880, section 5.11
|
||||
b, err := ioutil.ReadAll(r)
|
||||
b, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
6
vendor/golang.org/x/crypto/openpgp/read.go
generated
vendored
6
vendor/golang.org/x/crypto/openpgp/read.go
generated
vendored
@@ -3,6 +3,12 @@
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package openpgp implements high level operations on OpenPGP messages.
|
||||
//
|
||||
// Deprecated: this package is unmaintained except for security fixes. New
|
||||
// applications should consider a more focused, modern alternative to OpenPGP
|
||||
// for their specific task. If you are required to interoperate with OpenPGP
|
||||
// systems and need a maintained package, consider a community fork.
|
||||
// See https://golang.org/issue/44226.
|
||||
package openpgp // import "golang.org/x/crypto/openpgp"
|
||||
|
||||
import (
|
||||
|
||||
8
vendor/golang.org/x/crypto/openpgp/s2k/s2k.go
generated
vendored
8
vendor/golang.org/x/crypto/openpgp/s2k/s2k.go
generated
vendored
@@ -4,6 +4,12 @@
|
||||
|
||||
// Package s2k implements the various OpenPGP string-to-key transforms as
|
||||
// specified in RFC 4800 section 3.7.1.
|
||||
//
|
||||
// Deprecated: this package is unmaintained except for security fixes. New
|
||||
// applications should consider a more focused, modern alternative to OpenPGP
|
||||
// for their specific task. If you are required to interoperate with OpenPGP
|
||||
// systems and need a maintained package, consider a community fork.
|
||||
// See https://golang.org/issue/44226.
|
||||
package s2k // import "golang.org/x/crypto/openpgp/s2k"
|
||||
|
||||
import (
|
||||
@@ -262,7 +268,7 @@ func HashIdToString(id byte) (name string, ok bool) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
// HashIdToHash returns an OpenPGP hash id which corresponds the given Hash.
|
||||
// HashToHashId returns an OpenPGP hash id which corresponds the given Hash.
|
||||
func HashToHashId(h crypto.Hash) (id byte, ok bool) {
|
||||
for _, m := range hashToHashIdMapping {
|
||||
if m.hash == h {
|
||||
|
||||
2
vendor/golang.org/x/crypto/openpgp/write.go
generated
vendored
2
vendor/golang.org/x/crypto/openpgp/write.go
generated
vendored
@@ -402,7 +402,7 @@ func (s signatureWriter) Close() error {
|
||||
return s.encryptedData.Close()
|
||||
}
|
||||
|
||||
// noOpCloser is like an ioutil.NopCloser, but for an io.Writer.
|
||||
// noOpCloser is like an io.NopCloser, but for an io.Writer.
|
||||
// TODO: we have two of these in OpenPGP packages alone. This probably needs
|
||||
// to be promoted somewhere more common.
|
||||
type noOpCloser struct {
|
||||
|
||||
2
vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
generated
vendored
2
vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
generated
vendored
@@ -32,7 +32,7 @@ import (
|
||||
// can get a derived key for e.g. AES-256 (which needs a 32-byte key) by
|
||||
// doing:
|
||||
//
|
||||
// dk := pbkdf2.Key([]byte("some password"), salt, 4096, 32, sha1.New)
|
||||
// dk := pbkdf2.Key([]byte("some password"), salt, 4096, 32, sha1.New)
|
||||
//
|
||||
// Remember to get a good random salt. At least 8 bytes is recommended by the
|
||||
// RFC.
|
||||
|
||||
66
vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go
generated
vendored
66
vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go
generated
vendored
@@ -5,6 +5,8 @@
|
||||
// Package salsa provides low-level access to functions in the Salsa family.
|
||||
package salsa // import "golang.org/x/crypto/salsa20/salsa"
|
||||
|
||||
import "math/bits"
|
||||
|
||||
// Sigma is the Salsa20 constant for 256-bit keys.
|
||||
var Sigma = [16]byte{'e', 'x', 'p', 'a', 'n', 'd', ' ', '3', '2', '-', 'b', 'y', 't', 'e', ' ', 'k'}
|
||||
|
||||
@@ -31,76 +33,76 @@ func HSalsa20(out *[32]byte, in *[16]byte, k *[32]byte, c *[16]byte) {
|
||||
|
||||
for i := 0; i < 20; i += 2 {
|
||||
u := x0 + x12
|
||||
x4 ^= u<<7 | u>>(32-7)
|
||||
x4 ^= bits.RotateLeft32(u, 7)
|
||||
u = x4 + x0
|
||||
x8 ^= u<<9 | u>>(32-9)
|
||||
x8 ^= bits.RotateLeft32(u, 9)
|
||||
u = x8 + x4
|
||||
x12 ^= u<<13 | u>>(32-13)
|
||||
x12 ^= bits.RotateLeft32(u, 13)
|
||||
u = x12 + x8
|
||||
x0 ^= u<<18 | u>>(32-18)
|
||||
x0 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x5 + x1
|
||||
x9 ^= u<<7 | u>>(32-7)
|
||||
x9 ^= bits.RotateLeft32(u, 7)
|
||||
u = x9 + x5
|
||||
x13 ^= u<<9 | u>>(32-9)
|
||||
x13 ^= bits.RotateLeft32(u, 9)
|
||||
u = x13 + x9
|
||||
x1 ^= u<<13 | u>>(32-13)
|
||||
x1 ^= bits.RotateLeft32(u, 13)
|
||||
u = x1 + x13
|
||||
x5 ^= u<<18 | u>>(32-18)
|
||||
x5 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x10 + x6
|
||||
x14 ^= u<<7 | u>>(32-7)
|
||||
x14 ^= bits.RotateLeft32(u, 7)
|
||||
u = x14 + x10
|
||||
x2 ^= u<<9 | u>>(32-9)
|
||||
x2 ^= bits.RotateLeft32(u, 9)
|
||||
u = x2 + x14
|
||||
x6 ^= u<<13 | u>>(32-13)
|
||||
x6 ^= bits.RotateLeft32(u, 13)
|
||||
u = x6 + x2
|
||||
x10 ^= u<<18 | u>>(32-18)
|
||||
x10 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x15 + x11
|
||||
x3 ^= u<<7 | u>>(32-7)
|
||||
x3 ^= bits.RotateLeft32(u, 7)
|
||||
u = x3 + x15
|
||||
x7 ^= u<<9 | u>>(32-9)
|
||||
x7 ^= bits.RotateLeft32(u, 9)
|
||||
u = x7 + x3
|
||||
x11 ^= u<<13 | u>>(32-13)
|
||||
x11 ^= bits.RotateLeft32(u, 13)
|
||||
u = x11 + x7
|
||||
x15 ^= u<<18 | u>>(32-18)
|
||||
x15 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x0 + x3
|
||||
x1 ^= u<<7 | u>>(32-7)
|
||||
x1 ^= bits.RotateLeft32(u, 7)
|
||||
u = x1 + x0
|
||||
x2 ^= u<<9 | u>>(32-9)
|
||||
x2 ^= bits.RotateLeft32(u, 9)
|
||||
u = x2 + x1
|
||||
x3 ^= u<<13 | u>>(32-13)
|
||||
x3 ^= bits.RotateLeft32(u, 13)
|
||||
u = x3 + x2
|
||||
x0 ^= u<<18 | u>>(32-18)
|
||||
x0 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x5 + x4
|
||||
x6 ^= u<<7 | u>>(32-7)
|
||||
x6 ^= bits.RotateLeft32(u, 7)
|
||||
u = x6 + x5
|
||||
x7 ^= u<<9 | u>>(32-9)
|
||||
x7 ^= bits.RotateLeft32(u, 9)
|
||||
u = x7 + x6
|
||||
x4 ^= u<<13 | u>>(32-13)
|
||||
x4 ^= bits.RotateLeft32(u, 13)
|
||||
u = x4 + x7
|
||||
x5 ^= u<<18 | u>>(32-18)
|
||||
x5 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x10 + x9
|
||||
x11 ^= u<<7 | u>>(32-7)
|
||||
x11 ^= bits.RotateLeft32(u, 7)
|
||||
u = x11 + x10
|
||||
x8 ^= u<<9 | u>>(32-9)
|
||||
x8 ^= bits.RotateLeft32(u, 9)
|
||||
u = x8 + x11
|
||||
x9 ^= u<<13 | u>>(32-13)
|
||||
x9 ^= bits.RotateLeft32(u, 13)
|
||||
u = x9 + x8
|
||||
x10 ^= u<<18 | u>>(32-18)
|
||||
x10 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x15 + x14
|
||||
x12 ^= u<<7 | u>>(32-7)
|
||||
x12 ^= bits.RotateLeft32(u, 7)
|
||||
u = x12 + x15
|
||||
x13 ^= u<<9 | u>>(32-9)
|
||||
x13 ^= bits.RotateLeft32(u, 9)
|
||||
u = x13 + x12
|
||||
x14 ^= u<<13 | u>>(32-13)
|
||||
x14 ^= bits.RotateLeft32(u, 13)
|
||||
u = x14 + x13
|
||||
x15 ^= u<<18 | u>>(32-18)
|
||||
x15 ^= bits.RotateLeft32(u, 18)
|
||||
}
|
||||
out[0] = byte(x0)
|
||||
out[1] = byte(x0 >> 8)
|
||||
|
||||
66
vendor/golang.org/x/crypto/salsa20/salsa/salsa208.go
generated
vendored
66
vendor/golang.org/x/crypto/salsa20/salsa/salsa208.go
generated
vendored
@@ -4,6 +4,8 @@
|
||||
|
||||
package salsa
|
||||
|
||||
import "math/bits"
|
||||
|
||||
// Core208 applies the Salsa20/8 core function to the 64-byte array in and puts
|
||||
// the result into the 64-byte array out. The input and output may be the same array.
|
||||
func Core208(out *[64]byte, in *[64]byte) {
|
||||
@@ -29,76 +31,76 @@ func Core208(out *[64]byte, in *[64]byte) {
|
||||
|
||||
for i := 0; i < 8; i += 2 {
|
||||
u := x0 + x12
|
||||
x4 ^= u<<7 | u>>(32-7)
|
||||
x4 ^= bits.RotateLeft32(u, 7)
|
||||
u = x4 + x0
|
||||
x8 ^= u<<9 | u>>(32-9)
|
||||
x8 ^= bits.RotateLeft32(u, 9)
|
||||
u = x8 + x4
|
||||
x12 ^= u<<13 | u>>(32-13)
|
||||
x12 ^= bits.RotateLeft32(u, 13)
|
||||
u = x12 + x8
|
||||
x0 ^= u<<18 | u>>(32-18)
|
||||
x0 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x5 + x1
|
||||
x9 ^= u<<7 | u>>(32-7)
|
||||
x9 ^= bits.RotateLeft32(u, 7)
|
||||
u = x9 + x5
|
||||
x13 ^= u<<9 | u>>(32-9)
|
||||
x13 ^= bits.RotateLeft32(u, 9)
|
||||
u = x13 + x9
|
||||
x1 ^= u<<13 | u>>(32-13)
|
||||
x1 ^= bits.RotateLeft32(u, 13)
|
||||
u = x1 + x13
|
||||
x5 ^= u<<18 | u>>(32-18)
|
||||
x5 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x10 + x6
|
||||
x14 ^= u<<7 | u>>(32-7)
|
||||
x14 ^= bits.RotateLeft32(u, 7)
|
||||
u = x14 + x10
|
||||
x2 ^= u<<9 | u>>(32-9)
|
||||
x2 ^= bits.RotateLeft32(u, 9)
|
||||
u = x2 + x14
|
||||
x6 ^= u<<13 | u>>(32-13)
|
||||
x6 ^= bits.RotateLeft32(u, 13)
|
||||
u = x6 + x2
|
||||
x10 ^= u<<18 | u>>(32-18)
|
||||
x10 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x15 + x11
|
||||
x3 ^= u<<7 | u>>(32-7)
|
||||
x3 ^= bits.RotateLeft32(u, 7)
|
||||
u = x3 + x15
|
||||
x7 ^= u<<9 | u>>(32-9)
|
||||
x7 ^= bits.RotateLeft32(u, 9)
|
||||
u = x7 + x3
|
||||
x11 ^= u<<13 | u>>(32-13)
|
||||
x11 ^= bits.RotateLeft32(u, 13)
|
||||
u = x11 + x7
|
||||
x15 ^= u<<18 | u>>(32-18)
|
||||
x15 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x0 + x3
|
||||
x1 ^= u<<7 | u>>(32-7)
|
||||
x1 ^= bits.RotateLeft32(u, 7)
|
||||
u = x1 + x0
|
||||
x2 ^= u<<9 | u>>(32-9)
|
||||
x2 ^= bits.RotateLeft32(u, 9)
|
||||
u = x2 + x1
|
||||
x3 ^= u<<13 | u>>(32-13)
|
||||
x3 ^= bits.RotateLeft32(u, 13)
|
||||
u = x3 + x2
|
||||
x0 ^= u<<18 | u>>(32-18)
|
||||
x0 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x5 + x4
|
||||
x6 ^= u<<7 | u>>(32-7)
|
||||
x6 ^= bits.RotateLeft32(u, 7)
|
||||
u = x6 + x5
|
||||
x7 ^= u<<9 | u>>(32-9)
|
||||
x7 ^= bits.RotateLeft32(u, 9)
|
||||
u = x7 + x6
|
||||
x4 ^= u<<13 | u>>(32-13)
|
||||
x4 ^= bits.RotateLeft32(u, 13)
|
||||
u = x4 + x7
|
||||
x5 ^= u<<18 | u>>(32-18)
|
||||
x5 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x10 + x9
|
||||
x11 ^= u<<7 | u>>(32-7)
|
||||
x11 ^= bits.RotateLeft32(u, 7)
|
||||
u = x11 + x10
|
||||
x8 ^= u<<9 | u>>(32-9)
|
||||
x8 ^= bits.RotateLeft32(u, 9)
|
||||
u = x8 + x11
|
||||
x9 ^= u<<13 | u>>(32-13)
|
||||
x9 ^= bits.RotateLeft32(u, 13)
|
||||
u = x9 + x8
|
||||
x10 ^= u<<18 | u>>(32-18)
|
||||
x10 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x15 + x14
|
||||
x12 ^= u<<7 | u>>(32-7)
|
||||
x12 ^= bits.RotateLeft32(u, 7)
|
||||
u = x12 + x15
|
||||
x13 ^= u<<9 | u>>(32-9)
|
||||
x13 ^= bits.RotateLeft32(u, 9)
|
||||
u = x13 + x12
|
||||
x14 ^= u<<13 | u>>(32-13)
|
||||
x14 ^= bits.RotateLeft32(u, 13)
|
||||
u = x14 + x13
|
||||
x15 ^= u<<18 | u>>(32-18)
|
||||
x15 ^= bits.RotateLeft32(u, 18)
|
||||
}
|
||||
x0 += j0
|
||||
x1 += j1
|
||||
|
||||
66
vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go
generated
vendored
66
vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go
generated
vendored
@@ -4,6 +4,8 @@
|
||||
|
||||
package salsa
|
||||
|
||||
import "math/bits"
|
||||
|
||||
const rounds = 20
|
||||
|
||||
// core applies the Salsa20 core function to 16-byte input in, 32-byte key k,
|
||||
@@ -31,76 +33,76 @@ func core(out *[64]byte, in *[16]byte, k *[32]byte, c *[16]byte) {
|
||||
|
||||
for i := 0; i < rounds; i += 2 {
|
||||
u := x0 + x12
|
||||
x4 ^= u<<7 | u>>(32-7)
|
||||
x4 ^= bits.RotateLeft32(u, 7)
|
||||
u = x4 + x0
|
||||
x8 ^= u<<9 | u>>(32-9)
|
||||
x8 ^= bits.RotateLeft32(u, 9)
|
||||
u = x8 + x4
|
||||
x12 ^= u<<13 | u>>(32-13)
|
||||
x12 ^= bits.RotateLeft32(u, 13)
|
||||
u = x12 + x8
|
||||
x0 ^= u<<18 | u>>(32-18)
|
||||
x0 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x5 + x1
|
||||
x9 ^= u<<7 | u>>(32-7)
|
||||
x9 ^= bits.RotateLeft32(u, 7)
|
||||
u = x9 + x5
|
||||
x13 ^= u<<9 | u>>(32-9)
|
||||
x13 ^= bits.RotateLeft32(u, 9)
|
||||
u = x13 + x9
|
||||
x1 ^= u<<13 | u>>(32-13)
|
||||
x1 ^= bits.RotateLeft32(u, 13)
|
||||
u = x1 + x13
|
||||
x5 ^= u<<18 | u>>(32-18)
|
||||
x5 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x10 + x6
|
||||
x14 ^= u<<7 | u>>(32-7)
|
||||
x14 ^= bits.RotateLeft32(u, 7)
|
||||
u = x14 + x10
|
||||
x2 ^= u<<9 | u>>(32-9)
|
||||
x2 ^= bits.RotateLeft32(u, 9)
|
||||
u = x2 + x14
|
||||
x6 ^= u<<13 | u>>(32-13)
|
||||
x6 ^= bits.RotateLeft32(u, 13)
|
||||
u = x6 + x2
|
||||
x10 ^= u<<18 | u>>(32-18)
|
||||
x10 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x15 + x11
|
||||
x3 ^= u<<7 | u>>(32-7)
|
||||
x3 ^= bits.RotateLeft32(u, 7)
|
||||
u = x3 + x15
|
||||
x7 ^= u<<9 | u>>(32-9)
|
||||
x7 ^= bits.RotateLeft32(u, 9)
|
||||
u = x7 + x3
|
||||
x11 ^= u<<13 | u>>(32-13)
|
||||
x11 ^= bits.RotateLeft32(u, 13)
|
||||
u = x11 + x7
|
||||
x15 ^= u<<18 | u>>(32-18)
|
||||
x15 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x0 + x3
|
||||
x1 ^= u<<7 | u>>(32-7)
|
||||
x1 ^= bits.RotateLeft32(u, 7)
|
||||
u = x1 + x0
|
||||
x2 ^= u<<9 | u>>(32-9)
|
||||
x2 ^= bits.RotateLeft32(u, 9)
|
||||
u = x2 + x1
|
||||
x3 ^= u<<13 | u>>(32-13)
|
||||
x3 ^= bits.RotateLeft32(u, 13)
|
||||
u = x3 + x2
|
||||
x0 ^= u<<18 | u>>(32-18)
|
||||
x0 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x5 + x4
|
||||
x6 ^= u<<7 | u>>(32-7)
|
||||
x6 ^= bits.RotateLeft32(u, 7)
|
||||
u = x6 + x5
|
||||
x7 ^= u<<9 | u>>(32-9)
|
||||
x7 ^= bits.RotateLeft32(u, 9)
|
||||
u = x7 + x6
|
||||
x4 ^= u<<13 | u>>(32-13)
|
||||
x4 ^= bits.RotateLeft32(u, 13)
|
||||
u = x4 + x7
|
||||
x5 ^= u<<18 | u>>(32-18)
|
||||
x5 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x10 + x9
|
||||
x11 ^= u<<7 | u>>(32-7)
|
||||
x11 ^= bits.RotateLeft32(u, 7)
|
||||
u = x11 + x10
|
||||
x8 ^= u<<9 | u>>(32-9)
|
||||
x8 ^= bits.RotateLeft32(u, 9)
|
||||
u = x8 + x11
|
||||
x9 ^= u<<13 | u>>(32-13)
|
||||
x9 ^= bits.RotateLeft32(u, 13)
|
||||
u = x9 + x8
|
||||
x10 ^= u<<18 | u>>(32-18)
|
||||
x10 ^= bits.RotateLeft32(u, 18)
|
||||
|
||||
u = x15 + x14
|
||||
x12 ^= u<<7 | u>>(32-7)
|
||||
x12 ^= bits.RotateLeft32(u, 7)
|
||||
u = x12 + x15
|
||||
x13 ^= u<<9 | u>>(32-9)
|
||||
x13 ^= bits.RotateLeft32(u, 9)
|
||||
u = x13 + x12
|
||||
x14 ^= u<<13 | u>>(32-13)
|
||||
x14 ^= bits.RotateLeft32(u, 13)
|
||||
u = x14 + x13
|
||||
x15 ^= u<<18 | u>>(32-18)
|
||||
x15 ^= bits.RotateLeft32(u, 18)
|
||||
}
|
||||
x0 += j0
|
||||
x1 += j1
|
||||
|
||||
2
vendor/golang.org/x/crypto/scrypt/scrypt.go
generated
vendored
2
vendor/golang.org/x/crypto/scrypt/scrypt.go
generated
vendored
@@ -186,7 +186,7 @@ func smix(b []byte, r, N int, v, xy []uint32) {
|
||||
// For example, you can get a derived key for e.g. AES-256 (which needs a
|
||||
// 32-byte key) by doing:
|
||||
//
|
||||
// dk, err := scrypt.Key([]byte("some password"), salt, 32768, 8, 1, 32)
|
||||
// dk, err := scrypt.Key([]byte("some password"), salt, 32768, 8, 1, 32)
|
||||
//
|
||||
// The recommended parameters for interactive logins as of 2017 are N=32768, r=8
|
||||
// and p=1. The parameters N, r, and p should be increased as memory latency and
|
||||
|
||||
64
vendor/golang.org/x/crypto/ssh/agent/client.go
generated
vendored
64
vendor/golang.org/x/crypto/ssh/agent/client.go
generated
vendored
@@ -8,7 +8,8 @@
|
||||
// ssh-agent process using the sample server.
|
||||
//
|
||||
// References:
|
||||
// [PROTOCOL.agent]: https://tools.ietf.org/html/draft-miller-ssh-agent-00
|
||||
//
|
||||
// [PROTOCOL.agent]: https://tools.ietf.org/html/draft-miller-ssh-agent-00
|
||||
package agent // import "golang.org/x/crypto/ssh/agent"
|
||||
|
||||
import (
|
||||
@@ -25,7 +26,6 @@ import (
|
||||
"math/big"
|
||||
"sync"
|
||||
|
||||
"crypto"
|
||||
"golang.org/x/crypto/ed25519"
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
@@ -93,7 +93,7 @@ type ExtendedAgent interface {
|
||||
type ConstraintExtension struct {
|
||||
// ExtensionName consist of a UTF-8 string suffixed by the
|
||||
// implementation domain following the naming scheme defined
|
||||
// in Section 4.2 of [RFC4251], e.g. "foo@example.com".
|
||||
// in Section 4.2 of RFC 4251, e.g. "foo@example.com".
|
||||
ExtensionName string
|
||||
// ExtensionDetails contains the actual content of the extended
|
||||
// constraint.
|
||||
@@ -226,7 +226,9 @@ var ErrExtensionUnsupported = errors.New("agent: extension unsupported")
|
||||
|
||||
type extensionAgentMsg struct {
|
||||
ExtensionType string `sshtype:"27"`
|
||||
Contents []byte
|
||||
// NOTE: this matches OpenSSH's PROTOCOL.agent, not the IETF draft [PROTOCOL.agent],
|
||||
// so that it matches what OpenSSH actually implements in the wild.
|
||||
Contents []byte `ssh:"rest"`
|
||||
}
|
||||
|
||||
// Key represents a protocol 2 public key as defined in
|
||||
@@ -729,7 +731,7 @@ func (c *client) insertCert(s interface{}, cert *ssh.Certificate, comment string
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if bytes.Compare(cert.Key.Marshal(), signer.PublicKey().Marshal()) != 0 {
|
||||
if !bytes.Equal(cert.Key.Marshal(), signer.PublicKey().Marshal()) {
|
||||
return errors.New("agent: signer and cert have different public key")
|
||||
}
|
||||
|
||||
@@ -771,19 +773,53 @@ func (s *agentKeyringSigner) Sign(rand io.Reader, data []byte) (*ssh.Signature,
|
||||
return s.agent.Sign(s.pub, data)
|
||||
}
|
||||
|
||||
func (s *agentKeyringSigner) SignWithOpts(rand io.Reader, data []byte, opts crypto.SignerOpts) (*ssh.Signature, error) {
|
||||
var flags SignatureFlags
|
||||
if opts != nil {
|
||||
switch opts.HashFunc() {
|
||||
case crypto.SHA256:
|
||||
flags = SignatureFlagRsaSha256
|
||||
case crypto.SHA512:
|
||||
flags = SignatureFlagRsaSha512
|
||||
}
|
||||
func (s *agentKeyringSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*ssh.Signature, error) {
|
||||
if algorithm == "" || algorithm == underlyingAlgo(s.pub.Type()) {
|
||||
return s.Sign(rand, data)
|
||||
}
|
||||
|
||||
var flags SignatureFlags
|
||||
switch algorithm {
|
||||
case ssh.KeyAlgoRSASHA256:
|
||||
flags = SignatureFlagRsaSha256
|
||||
case ssh.KeyAlgoRSASHA512:
|
||||
flags = SignatureFlagRsaSha512
|
||||
default:
|
||||
return nil, fmt.Errorf("agent: unsupported algorithm %q", algorithm)
|
||||
}
|
||||
|
||||
return s.agent.SignWithFlags(s.pub, data, flags)
|
||||
}
|
||||
|
||||
var _ ssh.AlgorithmSigner = &agentKeyringSigner{}
|
||||
|
||||
// certKeyAlgoNames is a mapping from known certificate algorithm names to the
|
||||
// corresponding public key signature algorithm.
|
||||
//
|
||||
// This map must be kept in sync with the one in certs.go.
|
||||
var certKeyAlgoNames = map[string]string{
|
||||
ssh.CertAlgoRSAv01: ssh.KeyAlgoRSA,
|
||||
ssh.CertAlgoRSASHA256v01: ssh.KeyAlgoRSASHA256,
|
||||
ssh.CertAlgoRSASHA512v01: ssh.KeyAlgoRSASHA512,
|
||||
ssh.CertAlgoDSAv01: ssh.KeyAlgoDSA,
|
||||
ssh.CertAlgoECDSA256v01: ssh.KeyAlgoECDSA256,
|
||||
ssh.CertAlgoECDSA384v01: ssh.KeyAlgoECDSA384,
|
||||
ssh.CertAlgoECDSA521v01: ssh.KeyAlgoECDSA521,
|
||||
ssh.CertAlgoSKECDSA256v01: ssh.KeyAlgoSKECDSA256,
|
||||
ssh.CertAlgoED25519v01: ssh.KeyAlgoED25519,
|
||||
ssh.CertAlgoSKED25519v01: ssh.KeyAlgoSKED25519,
|
||||
}
|
||||
|
||||
// underlyingAlgo returns the signature algorithm associated with algo (which is
|
||||
// an advertised or negotiated public key or host key algorithm). These are
|
||||
// usually the same, except for certificate algorithms.
|
||||
func underlyingAlgo(algo string) string {
|
||||
if a, ok := certKeyAlgoNames[algo]; ok {
|
||||
return a
|
||||
}
|
||||
return algo
|
||||
}
|
||||
|
||||
// Calls an extension method. It is up to the agent implementation as to whether or not
|
||||
// any particular extension is supported and may always return an error. Because the
|
||||
// type of the response is up to the implementation, this returns the bytes of the
|
||||
|
||||
6
vendor/golang.org/x/crypto/ssh/agent/keyring.go
generated
vendored
6
vendor/golang.org/x/crypto/ssh/agent/keyring.go
generated
vendored
@@ -113,7 +113,7 @@ func (r *keyring) Unlock(passphrase []byte) error {
|
||||
|
||||
// expireKeysLocked removes expired keys from the keyring. If a key was added
|
||||
// with a lifetimesecs contraint and seconds >= lifetimesecs seconds have
|
||||
// ellapsed, it is removed. The caller *must* be holding the keyring mutex.
|
||||
// elapsed, it is removed. The caller *must* be holding the keyring mutex.
|
||||
func (r *keyring) expireKeysLocked() {
|
||||
for _, k := range r.keys {
|
||||
if k.expire != nil && time.Now().After(*k.expire) {
|
||||
@@ -205,9 +205,9 @@ func (r *keyring) SignWithFlags(key ssh.PublicKey, data []byte, flags SignatureF
|
||||
var algorithm string
|
||||
switch flags {
|
||||
case SignatureFlagRsaSha256:
|
||||
algorithm = ssh.SigAlgoRSASHA2256
|
||||
algorithm = ssh.KeyAlgoRSASHA256
|
||||
case SignatureFlagRsaSha512:
|
||||
algorithm = ssh.SigAlgoRSASHA2512
|
||||
algorithm = ssh.KeyAlgoRSASHA512
|
||||
default:
|
||||
return nil, fmt.Errorf("agent: unsupported signature flags: %d", flags)
|
||||
}
|
||||
|
||||
89
vendor/golang.org/x/crypto/ssh/certs.go
generated
vendored
89
vendor/golang.org/x/crypto/ssh/certs.go
generated
vendored
@@ -14,8 +14,10 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// These constants from [PROTOCOL.certkeys] represent the algorithm names
|
||||
// for certificate types supported by this package.
|
||||
// Certificate algorithm names from [PROTOCOL.certkeys]. These values can appear
|
||||
// in Certificate.Type, PublicKey.Type, and ClientConfig.HostKeyAlgorithms.
|
||||
// Unlike key algorithm names, these are not passed to AlgorithmSigner and don't
|
||||
// appear in the Signature.Format field.
|
||||
const (
|
||||
CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com"
|
||||
CertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com"
|
||||
@@ -25,6 +27,21 @@ const (
|
||||
CertAlgoSKECDSA256v01 = "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com"
|
||||
CertAlgoED25519v01 = "ssh-ed25519-cert-v01@openssh.com"
|
||||
CertAlgoSKED25519v01 = "sk-ssh-ed25519-cert-v01@openssh.com"
|
||||
|
||||
// CertAlgoRSASHA256v01 and CertAlgoRSASHA512v01 can't appear as a
|
||||
// Certificate.Type (or PublicKey.Type), but only in
|
||||
// ClientConfig.HostKeyAlgorithms.
|
||||
CertAlgoRSASHA256v01 = "rsa-sha2-256-cert-v01@openssh.com"
|
||||
CertAlgoRSASHA512v01 = "rsa-sha2-512-cert-v01@openssh.com"
|
||||
)
|
||||
|
||||
const (
|
||||
// Deprecated: use CertAlgoRSAv01.
|
||||
CertSigAlgoRSAv01 = CertAlgoRSAv01
|
||||
// Deprecated: use CertAlgoRSASHA256v01.
|
||||
CertSigAlgoRSASHA2256v01 = CertAlgoRSASHA256v01
|
||||
// Deprecated: use CertAlgoRSASHA512v01.
|
||||
CertSigAlgoRSASHA2512v01 = CertAlgoRSASHA512v01
|
||||
)
|
||||
|
||||
// Certificate types distinguish between host and user
|
||||
@@ -234,7 +251,7 @@ type algorithmOpenSSHCertSigner struct {
|
||||
// private key is held by signer. It returns an error if the public key in cert
|
||||
// doesn't match the key used by signer.
|
||||
func NewCertSigner(cert *Certificate, signer Signer) (Signer, error) {
|
||||
if bytes.Compare(cert.Key.Marshal(), signer.PublicKey().Marshal()) != 0 {
|
||||
if !bytes.Equal(cert.Key.Marshal(), signer.PublicKey().Marshal()) {
|
||||
return nil, errors.New("ssh: signer and cert have different public key")
|
||||
}
|
||||
|
||||
@@ -423,6 +440,16 @@ func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
|
||||
}
|
||||
c.SignatureKey = authority.PublicKey()
|
||||
|
||||
// Default to KeyAlgoRSASHA512 for ssh-rsa signers.
|
||||
if v, ok := authority.(AlgorithmSigner); ok && v.PublicKey().Type() == KeyAlgoRSA {
|
||||
sig, err := v.SignWithAlgorithm(rand, c.bytesForSigning(), KeyAlgoRSASHA512)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Signature = sig
|
||||
return nil
|
||||
}
|
||||
|
||||
sig, err := authority.Sign(rand, c.bytesForSigning())
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -431,26 +458,42 @@ func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var certAlgoNames = map[string]string{
|
||||
KeyAlgoRSA: CertAlgoRSAv01,
|
||||
KeyAlgoDSA: CertAlgoDSAv01,
|
||||
KeyAlgoECDSA256: CertAlgoECDSA256v01,
|
||||
KeyAlgoECDSA384: CertAlgoECDSA384v01,
|
||||
KeyAlgoECDSA521: CertAlgoECDSA521v01,
|
||||
KeyAlgoSKECDSA256: CertAlgoSKECDSA256v01,
|
||||
KeyAlgoED25519: CertAlgoED25519v01,
|
||||
KeyAlgoSKED25519: CertAlgoSKED25519v01,
|
||||
// certKeyAlgoNames is a mapping from known certificate algorithm names to the
|
||||
// corresponding public key signature algorithm.
|
||||
//
|
||||
// This map must be kept in sync with the one in agent/client.go.
|
||||
var certKeyAlgoNames = map[string]string{
|
||||
CertAlgoRSAv01: KeyAlgoRSA,
|
||||
CertAlgoRSASHA256v01: KeyAlgoRSASHA256,
|
||||
CertAlgoRSASHA512v01: KeyAlgoRSASHA512,
|
||||
CertAlgoDSAv01: KeyAlgoDSA,
|
||||
CertAlgoECDSA256v01: KeyAlgoECDSA256,
|
||||
CertAlgoECDSA384v01: KeyAlgoECDSA384,
|
||||
CertAlgoECDSA521v01: KeyAlgoECDSA521,
|
||||
CertAlgoSKECDSA256v01: KeyAlgoSKECDSA256,
|
||||
CertAlgoED25519v01: KeyAlgoED25519,
|
||||
CertAlgoSKED25519v01: KeyAlgoSKED25519,
|
||||
}
|
||||
|
||||
// certToPrivAlgo returns the underlying algorithm for a certificate algorithm.
|
||||
// Panics if a non-certificate algorithm is passed.
|
||||
func certToPrivAlgo(algo string) string {
|
||||
for privAlgo, pubAlgo := range certAlgoNames {
|
||||
if pubAlgo == algo {
|
||||
return privAlgo
|
||||
// underlyingAlgo returns the signature algorithm associated with algo (which is
|
||||
// an advertised or negotiated public key or host key algorithm). These are
|
||||
// usually the same, except for certificate algorithms.
|
||||
func underlyingAlgo(algo string) string {
|
||||
if a, ok := certKeyAlgoNames[algo]; ok {
|
||||
return a
|
||||
}
|
||||
return algo
|
||||
}
|
||||
|
||||
// certificateAlgo returns the certificate algorithms that uses the provided
|
||||
// underlying signature algorithm.
|
||||
func certificateAlgo(algo string) (certAlgo string, ok bool) {
|
||||
for certName, algoName := range certKeyAlgoNames {
|
||||
if algoName == algo {
|
||||
return certName, true
|
||||
}
|
||||
}
|
||||
panic("unknown cert algorithm")
|
||||
return "", false
|
||||
}
|
||||
|
||||
func (cert *Certificate) bytesForSigning() []byte {
|
||||
@@ -494,13 +537,13 @@ func (c *Certificate) Marshal() []byte {
|
||||
return result
|
||||
}
|
||||
|
||||
// Type returns the key name. It is part of the PublicKey interface.
|
||||
// Type returns the certificate algorithm name. It is part of the PublicKey interface.
|
||||
func (c *Certificate) Type() string {
|
||||
algo, ok := certAlgoNames[c.Key.Type()]
|
||||
certName, ok := certificateAlgo(c.Key.Type())
|
||||
if !ok {
|
||||
panic("unknown cert key type " + c.Key.Type())
|
||||
panic("unknown certificate type for key type " + c.Key.Type())
|
||||
}
|
||||
return algo
|
||||
return certName
|
||||
}
|
||||
|
||||
// Verify verifies a signature against the certificate's public
|
||||
|
||||
23
vendor/golang.org/x/crypto/ssh/cipher.go
generated
vendored
23
vendor/golang.org/x/crypto/ssh/cipher.go
generated
vendored
@@ -15,10 +15,9 @@ import (
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"golang.org/x/crypto/chacha20"
|
||||
"golang.org/x/crypto/poly1305"
|
||||
"golang.org/x/crypto/internal/poly1305"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -97,13 +96,13 @@ func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream,
|
||||
// are not supported and will not be negotiated, even if explicitly requested in
|
||||
// ClientConfig.Crypto.Ciphers.
|
||||
var cipherModes = map[string]*cipherMode{
|
||||
// Ciphers from RFC4344, which introduced many CTR-based ciphers. Algorithms
|
||||
// Ciphers from RFC 4344, which introduced many CTR-based ciphers. Algorithms
|
||||
// are defined in the order specified in the RFC.
|
||||
"aes128-ctr": {16, aes.BlockSize, streamCipherMode(0, newAESCTR)},
|
||||
"aes192-ctr": {24, aes.BlockSize, streamCipherMode(0, newAESCTR)},
|
||||
"aes256-ctr": {32, aes.BlockSize, streamCipherMode(0, newAESCTR)},
|
||||
|
||||
// Ciphers from RFC4345, which introduces security-improved arcfour ciphers.
|
||||
// Ciphers from RFC 4345, which introduces security-improved arcfour ciphers.
|
||||
// They are defined in the order specified in the RFC.
|
||||
"arcfour128": {16, 0, streamCipherMode(1536, newRC4)},
|
||||
"arcfour256": {32, 0, streamCipherMode(1536, newRC4)},
|
||||
@@ -111,7 +110,7 @@ var cipherModes = map[string]*cipherMode{
|
||||
// Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol.
|
||||
// Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and
|
||||
// RC4) has problems with weak keys, and should be used with caution."
|
||||
// RFC4345 introduces improved versions of Arcfour.
|
||||
// RFC 4345 introduces improved versions of Arcfour.
|
||||
"arcfour": {16, 0, streamCipherMode(0, newRC4)},
|
||||
|
||||
// AEAD ciphers
|
||||
@@ -394,6 +393,10 @@ func (c *gcmCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error)
|
||||
}
|
||||
c.incIV()
|
||||
|
||||
if len(plain) == 0 {
|
||||
return nil, errors.New("ssh: empty packet")
|
||||
}
|
||||
|
||||
padding := plain[0]
|
||||
if padding < 4 {
|
||||
// padding is a byte, so it automatically satisfies
|
||||
@@ -493,7 +496,7 @@ func (c *cbcCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error)
|
||||
// data, to make distinguishing between
|
||||
// failing MAC and failing length check more
|
||||
// difficult.
|
||||
io.CopyN(ioutil.Discard, r, int64(c.oracleCamouflage))
|
||||
io.CopyN(io.Discard, r, int64(c.oracleCamouflage))
|
||||
}
|
||||
}
|
||||
return p, err
|
||||
@@ -636,9 +639,9 @@ const chacha20Poly1305ID = "chacha20-poly1305@openssh.com"
|
||||
// chacha20Poly1305Cipher implements the chacha20-poly1305@openssh.com
|
||||
// AEAD, which is described here:
|
||||
//
|
||||
// https://tools.ietf.org/html/draft-josefsson-ssh-chacha20-poly1305-openssh-00
|
||||
// https://tools.ietf.org/html/draft-josefsson-ssh-chacha20-poly1305-openssh-00
|
||||
//
|
||||
// the methods here also implement padding, which RFC4253 Section 6
|
||||
// the methods here also implement padding, which RFC 4253 Section 6
|
||||
// also requires of stream ciphers.
|
||||
type chacha20Poly1305Cipher struct {
|
||||
lengthKey [32]byte
|
||||
@@ -710,6 +713,10 @@ func (c *chacha20Poly1305Cipher) readCipherPacket(seqNum uint32, r io.Reader) ([
|
||||
plain := c.buf[4:contentEnd]
|
||||
s.XORKeyStream(plain, plain)
|
||||
|
||||
if len(plain) == 0 {
|
||||
return nil, errors.New("ssh: empty packet")
|
||||
}
|
||||
|
||||
padding := plain[0]
|
||||
if padding < 4 {
|
||||
// padding is a byte, so it automatically satisfies
|
||||
|
||||
18
vendor/golang.org/x/crypto/ssh/client.go
generated
vendored
18
vendor/golang.org/x/crypto/ssh/client.go
generated
vendored
@@ -113,14 +113,18 @@ func (c *connection) clientHandshake(dialAddress string, config *ClientConfig) e
|
||||
return c.clientAuthenticate(config)
|
||||
}
|
||||
|
||||
// verifyHostKeySignature verifies the host key obtained in the key
|
||||
// exchange.
|
||||
func verifyHostKeySignature(hostKey PublicKey, result *kexResult) error {
|
||||
// verifyHostKeySignature verifies the host key obtained in the key exchange.
|
||||
// algo is the negotiated algorithm, and may be a certificate type.
|
||||
func verifyHostKeySignature(hostKey PublicKey, algo string, result *kexResult) error {
|
||||
sig, rest, ok := parseSignatureBody(result.Signature)
|
||||
if len(rest) > 0 || !ok {
|
||||
return errors.New("ssh: signature parse error")
|
||||
}
|
||||
|
||||
if a := underlyingAlgo(algo); sig.Format != a {
|
||||
return fmt.Errorf("ssh: invalid signature algorithm %q, expected %q", sig.Format, a)
|
||||
}
|
||||
|
||||
return hostKey.Verify(result.H, sig)
|
||||
}
|
||||
|
||||
@@ -224,11 +228,11 @@ type ClientConfig struct {
|
||||
// be used for the connection. If empty, a reasonable default is used.
|
||||
ClientVersion string
|
||||
|
||||
// HostKeyAlgorithms lists the key types that the client will
|
||||
// accept from the server as host key, in order of
|
||||
// HostKeyAlgorithms lists the public key algorithms that the client will
|
||||
// accept from the server for host key authentication, in order of
|
||||
// preference. If empty, a reasonable default is used. Any
|
||||
// string returned from PublicKey.Type method may be used, or
|
||||
// any of the CertAlgoXxxx and KeyAlgoXxxx constants.
|
||||
// string returned from a PublicKey.Type method may be used, or
|
||||
// any of the CertAlgo and KeyAlgo constants.
|
||||
HostKeyAlgorithms []string
|
||||
|
||||
// Timeout is the maximum amount of time for the TCP connection to establish.
|
||||
|
||||
132
vendor/golang.org/x/crypto/ssh/client_auth.go
generated
vendored
132
vendor/golang.org/x/crypto/ssh/client_auth.go
generated
vendored
@@ -9,6 +9,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type authResult int
|
||||
@@ -29,6 +30,33 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// The server may choose to send a SSH_MSG_EXT_INFO at this point (if we
|
||||
// advertised willingness to receive one, which we always do) or not. See
|
||||
// RFC 8308, Section 2.4.
|
||||
extensions := make(map[string][]byte)
|
||||
if len(packet) > 0 && packet[0] == msgExtInfo {
|
||||
var extInfo extInfoMsg
|
||||
if err := Unmarshal(packet, &extInfo); err != nil {
|
||||
return err
|
||||
}
|
||||
payload := extInfo.Payload
|
||||
for i := uint32(0); i < extInfo.NumExtensions; i++ {
|
||||
name, rest, ok := parseString(payload)
|
||||
if !ok {
|
||||
return parseError(msgExtInfo)
|
||||
}
|
||||
value, rest, ok := parseString(rest)
|
||||
if !ok {
|
||||
return parseError(msgExtInfo)
|
||||
}
|
||||
extensions[string(name)] = value
|
||||
payload = rest
|
||||
}
|
||||
packet, err = c.transport.readPacket()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
var serviceAccept serviceAcceptMsg
|
||||
if err := Unmarshal(packet, &serviceAccept); err != nil {
|
||||
return err
|
||||
@@ -41,7 +69,7 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error {
|
||||
|
||||
sessionID := c.transport.getSessionID()
|
||||
for auth := AuthMethod(new(noneAuth)); auth != nil; {
|
||||
ok, methods, err := auth.auth(sessionID, config.User, c.transport, config.Rand)
|
||||
ok, methods, err := auth.auth(sessionID, config.User, c.transport, config.Rand, extensions)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -93,7 +121,7 @@ type AuthMethod interface {
|
||||
// If authentication is not successful, a []string of alternative
|
||||
// method names is returned. If the slice is nil, it will be ignored
|
||||
// and the previous set of possible methods will be reused.
|
||||
auth(session []byte, user string, p packetConn, rand io.Reader) (authResult, []string, error)
|
||||
auth(session []byte, user string, p packetConn, rand io.Reader, extensions map[string][]byte) (authResult, []string, error)
|
||||
|
||||
// method returns the RFC 4252 method name.
|
||||
method() string
|
||||
@@ -102,7 +130,7 @@ type AuthMethod interface {
|
||||
// "none" authentication, RFC 4252 section 5.2.
|
||||
type noneAuth int
|
||||
|
||||
func (n *noneAuth) auth(session []byte, user string, c packetConn, rand io.Reader) (authResult, []string, error) {
|
||||
func (n *noneAuth) auth(session []byte, user string, c packetConn, rand io.Reader, _ map[string][]byte) (authResult, []string, error) {
|
||||
if err := c.writePacket(Marshal(&userAuthRequestMsg{
|
||||
User: user,
|
||||
Service: serviceSSH,
|
||||
@@ -122,7 +150,7 @@ func (n *noneAuth) method() string {
|
||||
// a function call, e.g. by prompting the user.
|
||||
type passwordCallback func() (password string, err error)
|
||||
|
||||
func (cb passwordCallback) auth(session []byte, user string, c packetConn, rand io.Reader) (authResult, []string, error) {
|
||||
func (cb passwordCallback) auth(session []byte, user string, c packetConn, rand io.Reader, _ map[string][]byte) (authResult, []string, error) {
|
||||
type passwordAuthMsg struct {
|
||||
User string `sshtype:"50"`
|
||||
Service string
|
||||
@@ -189,7 +217,46 @@ func (cb publicKeyCallback) method() string {
|
||||
return "publickey"
|
||||
}
|
||||
|
||||
func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand io.Reader) (authResult, []string, error) {
|
||||
func pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (as AlgorithmSigner, algo string) {
|
||||
keyFormat := signer.PublicKey().Type()
|
||||
|
||||
// Like in sendKexInit, if the public key implements AlgorithmSigner we
|
||||
// assume it supports all algorithms, otherwise only the key format one.
|
||||
as, ok := signer.(AlgorithmSigner)
|
||||
if !ok {
|
||||
return algorithmSignerWrapper{signer}, keyFormat
|
||||
}
|
||||
|
||||
extPayload, ok := extensions["server-sig-algs"]
|
||||
if !ok {
|
||||
// If there is no "server-sig-algs" extension, fall back to the key
|
||||
// format algorithm.
|
||||
return as, keyFormat
|
||||
}
|
||||
|
||||
// The server-sig-algs extension only carries underlying signature
|
||||
// algorithm, but we are trying to select a protocol-level public key
|
||||
// algorithm, which might be a certificate type. Extend the list of server
|
||||
// supported algorithms to include the corresponding certificate algorithms.
|
||||
serverAlgos := strings.Split(string(extPayload), ",")
|
||||
for _, algo := range serverAlgos {
|
||||
if certAlgo, ok := certificateAlgo(algo); ok {
|
||||
serverAlgos = append(serverAlgos, certAlgo)
|
||||
}
|
||||
}
|
||||
|
||||
keyAlgos := algorithmsForKeyFormat(keyFormat)
|
||||
algo, err := findCommon("public key signature algorithm", keyAlgos, serverAlgos)
|
||||
if err != nil {
|
||||
// If there is no overlap, try the key anyway with the key format
|
||||
// algorithm, to support servers that fail to list all supported
|
||||
// algorithms.
|
||||
return as, keyFormat
|
||||
}
|
||||
return as, algo
|
||||
}
|
||||
|
||||
func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand io.Reader, extensions map[string][]byte) (authResult, []string, error) {
|
||||
// Authentication is performed by sending an enquiry to test if a key is
|
||||
// acceptable to the remote. If the key is acceptable, the client will
|
||||
// attempt to authenticate with the valid key. If not the client will repeat
|
||||
@@ -201,7 +268,10 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
|
||||
}
|
||||
var methods []string
|
||||
for _, signer := range signers {
|
||||
ok, err := validateKey(signer.PublicKey(), user, c)
|
||||
pub := signer.PublicKey()
|
||||
as, algo := pickSignatureAlgorithm(signer, extensions)
|
||||
|
||||
ok, err := validateKey(pub, algo, user, c)
|
||||
if err != nil {
|
||||
return authFailure, nil, err
|
||||
}
|
||||
@@ -209,13 +279,13 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
|
||||
continue
|
||||
}
|
||||
|
||||
pub := signer.PublicKey()
|
||||
pubKey := pub.Marshal()
|
||||
sign, err := signer.Sign(rand, buildDataSignedForAuth(session, userAuthRequestMsg{
|
||||
data := buildDataSignedForAuth(session, userAuthRequestMsg{
|
||||
User: user,
|
||||
Service: serviceSSH,
|
||||
Method: cb.method(),
|
||||
}, []byte(pub.Type()), pubKey))
|
||||
}, algo, pubKey)
|
||||
sign, err := as.SignWithAlgorithm(rand, data, underlyingAlgo(algo))
|
||||
if err != nil {
|
||||
return authFailure, nil, err
|
||||
}
|
||||
@@ -229,7 +299,7 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
|
||||
Service: serviceSSH,
|
||||
Method: cb.method(),
|
||||
HasSig: true,
|
||||
Algoname: pub.Type(),
|
||||
Algoname: algo,
|
||||
PubKey: pubKey,
|
||||
Sig: sig,
|
||||
}
|
||||
@@ -266,26 +336,25 @@ func containsMethod(methods []string, method string) bool {
|
||||
}
|
||||
|
||||
// validateKey validates the key provided is acceptable to the server.
|
||||
func validateKey(key PublicKey, user string, c packetConn) (bool, error) {
|
||||
func validateKey(key PublicKey, algo string, user string, c packetConn) (bool, error) {
|
||||
pubKey := key.Marshal()
|
||||
msg := publickeyAuthMsg{
|
||||
User: user,
|
||||
Service: serviceSSH,
|
||||
Method: "publickey",
|
||||
HasSig: false,
|
||||
Algoname: key.Type(),
|
||||
Algoname: algo,
|
||||
PubKey: pubKey,
|
||||
}
|
||||
if err := c.writePacket(Marshal(&msg)); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return confirmKeyAck(key, c)
|
||||
return confirmKeyAck(key, algo, c)
|
||||
}
|
||||
|
||||
func confirmKeyAck(key PublicKey, c packetConn) (bool, error) {
|
||||
func confirmKeyAck(key PublicKey, algo string, c packetConn) (bool, error) {
|
||||
pubKey := key.Marshal()
|
||||
algoname := key.Type()
|
||||
|
||||
for {
|
||||
packet, err := c.readPacket()
|
||||
@@ -302,14 +371,14 @@ func confirmKeyAck(key PublicKey, c packetConn) (bool, error) {
|
||||
if err := Unmarshal(packet, &msg); err != nil {
|
||||
return false, err
|
||||
}
|
||||
if msg.Algo != algoname || !bytes.Equal(msg.PubKey, pubKey) {
|
||||
if msg.Algo != algo || !bytes.Equal(msg.PubKey, pubKey) {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
case msgUserAuthFailure:
|
||||
return false, nil
|
||||
default:
|
||||
return false, unexpectedMessageError(msgUserAuthSuccess, packet[0])
|
||||
return false, unexpectedMessageError(msgUserAuthPubKeyOk, packet[0])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -330,6 +399,7 @@ func PublicKeysCallback(getSigners func() (signers []Signer, err error)) AuthMet
|
||||
// along with a list of remaining authentication methods to try next and
|
||||
// an error if an unexpected response was received.
|
||||
func handleAuthResponse(c packetConn) (authResult, []string, error) {
|
||||
gotMsgExtInfo := false
|
||||
for {
|
||||
packet, err := c.readPacket()
|
||||
if err != nil {
|
||||
@@ -341,6 +411,12 @@ func handleAuthResponse(c packetConn) (authResult, []string, error) {
|
||||
if err := handleBannerResponse(c, packet); err != nil {
|
||||
return authFailure, nil, err
|
||||
}
|
||||
case msgExtInfo:
|
||||
// Ignore post-authentication RFC 8308 extensions, once.
|
||||
if gotMsgExtInfo {
|
||||
return authFailure, nil, unexpectedMessageError(msgUserAuthSuccess, packet[0])
|
||||
}
|
||||
gotMsgExtInfo = true
|
||||
case msgUserAuthFailure:
|
||||
var msg userAuthFailureMsg
|
||||
if err := Unmarshal(packet, &msg); err != nil {
|
||||
@@ -380,10 +456,10 @@ func handleBannerResponse(c packetConn, packet []byte) error {
|
||||
// disabling echoing (e.g. for passwords), and return all the answers.
|
||||
// Challenge may be called multiple times in a single session. After
|
||||
// successful authentication, the server may send a challenge with no
|
||||
// questions, for which the user and instruction messages should be
|
||||
// questions, for which the name and instruction messages should be
|
||||
// printed. RFC 4256 section 3.3 details how the UI should behave for
|
||||
// both CLI and GUI environments.
|
||||
type KeyboardInteractiveChallenge func(user, instruction string, questions []string, echos []bool) (answers []string, err error)
|
||||
type KeyboardInteractiveChallenge func(name, instruction string, questions []string, echos []bool) (answers []string, err error)
|
||||
|
||||
// KeyboardInteractive returns an AuthMethod using a prompt/response
|
||||
// sequence controlled by the server.
|
||||
@@ -395,7 +471,7 @@ func (cb KeyboardInteractiveChallenge) method() string {
|
||||
return "keyboard-interactive"
|
||||
}
|
||||
|
||||
func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packetConn, rand io.Reader) (authResult, []string, error) {
|
||||
func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packetConn, rand io.Reader, _ map[string][]byte) (authResult, []string, error) {
|
||||
type initiateMsg struct {
|
||||
User string `sshtype:"50"`
|
||||
Service string
|
||||
@@ -412,6 +488,7 @@ func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packe
|
||||
return authFailure, nil, err
|
||||
}
|
||||
|
||||
gotMsgExtInfo := false
|
||||
for {
|
||||
packet, err := c.readPacket()
|
||||
if err != nil {
|
||||
@@ -425,6 +502,13 @@ func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packe
|
||||
return authFailure, nil, err
|
||||
}
|
||||
continue
|
||||
case msgExtInfo:
|
||||
// Ignore post-authentication RFC 8308 extensions, once.
|
||||
if gotMsgExtInfo {
|
||||
return authFailure, nil, unexpectedMessageError(msgUserAuthInfoRequest, packet[0])
|
||||
}
|
||||
gotMsgExtInfo = true
|
||||
continue
|
||||
case msgUserAuthInfoRequest:
|
||||
// OK
|
||||
case msgUserAuthFailure:
|
||||
@@ -465,7 +549,7 @@ func (cb KeyboardInteractiveChallenge) auth(session []byte, user string, c packe
|
||||
return authFailure, nil, errors.New("ssh: extra data following keyboard-interactive pairs")
|
||||
}
|
||||
|
||||
answers, err := cb(msg.User, msg.Instruction, prompts, echos)
|
||||
answers, err := cb(msg.Name, msg.Instruction, prompts, echos)
|
||||
if err != nil {
|
||||
return authFailure, nil, err
|
||||
}
|
||||
@@ -497,9 +581,9 @@ type retryableAuthMethod struct {
|
||||
maxTries int
|
||||
}
|
||||
|
||||
func (r *retryableAuthMethod) auth(session []byte, user string, c packetConn, rand io.Reader) (ok authResult, methods []string, err error) {
|
||||
func (r *retryableAuthMethod) auth(session []byte, user string, c packetConn, rand io.Reader, extensions map[string][]byte) (ok authResult, methods []string, err error) {
|
||||
for i := 0; r.maxTries <= 0 || i < r.maxTries; i++ {
|
||||
ok, methods, err = r.authMethod.auth(session, user, c, rand)
|
||||
ok, methods, err = r.authMethod.auth(session, user, c, rand, extensions)
|
||||
if ok != authFailure || err != nil { // either success, partial success or error terminate
|
||||
return ok, methods, err
|
||||
}
|
||||
@@ -542,7 +626,7 @@ type gssAPIWithMICCallback struct {
|
||||
target string
|
||||
}
|
||||
|
||||
func (g *gssAPIWithMICCallback) auth(session []byte, user string, c packetConn, rand io.Reader) (authResult, []string, error) {
|
||||
func (g *gssAPIWithMICCallback) auth(session []byte, user string, c packetConn, rand io.Reader, _ map[string][]byte) (authResult, []string, error) {
|
||||
m := &userAuthRequestMsg{
|
||||
User: user,
|
||||
Service: serviceSSH,
|
||||
|
||||
95
vendor/golang.org/x/crypto/ssh/common.go
generated
vendored
95
vendor/golang.org/x/crypto/ssh/common.go
generated
vendored
@@ -10,6 +10,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
_ "crypto/sha1"
|
||||
@@ -44,11 +45,11 @@ var preferredCiphers = []string{
|
||||
// supportedKexAlgos specifies the supported key-exchange algorithms in
|
||||
// preference order.
|
||||
var supportedKexAlgos = []string{
|
||||
kexAlgoCurve25519SHA256,
|
||||
kexAlgoCurve25519SHA256, kexAlgoCurve25519SHA256LibSSH,
|
||||
// P384 and P521 are not constant-time yet, but since we don't
|
||||
// reuse ephemeral keys, using them for ECDH should be OK.
|
||||
kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521,
|
||||
kexAlgoDH14SHA1, kexAlgoDH1SHA1,
|
||||
kexAlgoDH14SHA256, kexAlgoDH14SHA1, kexAlgoDH1SHA1,
|
||||
}
|
||||
|
||||
// serverForbiddenKexAlgos contains key exchange algorithms, that are forbidden
|
||||
@@ -61,18 +62,20 @@ var serverForbiddenKexAlgos = map[string]struct{}{
|
||||
// preferredKexAlgos specifies the default preference for key-exchange algorithms
|
||||
// in preference order.
|
||||
var preferredKexAlgos = []string{
|
||||
kexAlgoCurve25519SHA256,
|
||||
kexAlgoCurve25519SHA256, kexAlgoCurve25519SHA256LibSSH,
|
||||
kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521,
|
||||
kexAlgoDH14SHA1,
|
||||
kexAlgoDH14SHA256, kexAlgoDH14SHA1,
|
||||
}
|
||||
|
||||
// supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. methods
|
||||
// of authenticating servers) in preference order.
|
||||
var supportedHostKeyAlgos = []string{
|
||||
CertAlgoRSASHA512v01, CertAlgoRSASHA256v01,
|
||||
CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01,
|
||||
CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01,
|
||||
|
||||
KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521,
|
||||
KeyAlgoRSASHA512, KeyAlgoRSASHA256,
|
||||
KeyAlgoRSA, KeyAlgoDSA,
|
||||
|
||||
KeyAlgoED25519,
|
||||
@@ -87,21 +90,49 @@ var supportedMACs = []string{
|
||||
|
||||
var supportedCompressions = []string{compressionNone}
|
||||
|
||||
// hashFuncs keeps the mapping of supported algorithms to their respective
|
||||
// hashes needed for signature verification.
|
||||
// hashFuncs keeps the mapping of supported signature algorithms to their
|
||||
// respective hashes needed for signing and verification.
|
||||
var hashFuncs = map[string]crypto.Hash{
|
||||
KeyAlgoRSA: crypto.SHA1,
|
||||
KeyAlgoDSA: crypto.SHA1,
|
||||
KeyAlgoECDSA256: crypto.SHA256,
|
||||
KeyAlgoECDSA384: crypto.SHA384,
|
||||
KeyAlgoECDSA521: crypto.SHA512,
|
||||
CertAlgoRSAv01: crypto.SHA1,
|
||||
CertAlgoDSAv01: crypto.SHA1,
|
||||
CertAlgoECDSA256v01: crypto.SHA256,
|
||||
CertAlgoECDSA384v01: crypto.SHA384,
|
||||
CertAlgoECDSA521v01: crypto.SHA512,
|
||||
KeyAlgoRSA: crypto.SHA1,
|
||||
KeyAlgoRSASHA256: crypto.SHA256,
|
||||
KeyAlgoRSASHA512: crypto.SHA512,
|
||||
KeyAlgoDSA: crypto.SHA1,
|
||||
KeyAlgoECDSA256: crypto.SHA256,
|
||||
KeyAlgoECDSA384: crypto.SHA384,
|
||||
KeyAlgoECDSA521: crypto.SHA512,
|
||||
// KeyAlgoED25519 doesn't pre-hash.
|
||||
KeyAlgoSKECDSA256: crypto.SHA256,
|
||||
KeyAlgoSKED25519: crypto.SHA256,
|
||||
}
|
||||
|
||||
// algorithmsForKeyFormat returns the supported signature algorithms for a given
|
||||
// public key format (PublicKey.Type), in order of preference. See RFC 8332,
|
||||
// Section 2. See also the note in sendKexInit on backwards compatibility.
|
||||
func algorithmsForKeyFormat(keyFormat string) []string {
|
||||
switch keyFormat {
|
||||
case KeyAlgoRSA:
|
||||
return []string{KeyAlgoRSASHA256, KeyAlgoRSASHA512, KeyAlgoRSA}
|
||||
case CertAlgoRSAv01:
|
||||
return []string{CertAlgoRSASHA256v01, CertAlgoRSASHA512v01, CertAlgoRSAv01}
|
||||
default:
|
||||
return []string{keyFormat}
|
||||
}
|
||||
}
|
||||
|
||||
// supportedPubKeyAuthAlgos specifies the supported client public key
|
||||
// authentication algorithms. Note that this doesn't include certificate types
|
||||
// since those use the underlying algorithm. This list is sent to the client if
|
||||
// it supports the server-sig-algs extension. Order is irrelevant.
|
||||
var supportedPubKeyAuthAlgos = []string{
|
||||
KeyAlgoED25519,
|
||||
KeyAlgoSKED25519, KeyAlgoSKECDSA256,
|
||||
KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521,
|
||||
KeyAlgoRSASHA256, KeyAlgoRSASHA512, KeyAlgoRSA,
|
||||
KeyAlgoDSA,
|
||||
}
|
||||
|
||||
var supportedPubKeyAuthAlgosList = strings.Join(supportedPubKeyAuthAlgos, ",")
|
||||
|
||||
// unexpectedMessageError results when the SSH message that we received didn't
|
||||
// match what we wanted.
|
||||
func unexpectedMessageError(expected, got uint8) error {
|
||||
@@ -133,7 +164,7 @@ type directionAlgorithms struct {
|
||||
|
||||
// rekeyBytes returns a rekeying intervals in bytes.
|
||||
func (a *directionAlgorithms) rekeyBytes() int64 {
|
||||
// According to RFC4344 block ciphers should rekey after
|
||||
// According to RFC 4344 block ciphers should rekey after
|
||||
// 2^(BLOCKSIZE/4) blocks. For all AES flavors BLOCKSIZE is
|
||||
// 128.
|
||||
switch a.Cipher {
|
||||
@@ -142,10 +173,15 @@ func (a *directionAlgorithms) rekeyBytes() int64 {
|
||||
|
||||
}
|
||||
|
||||
// For others, stick with RFC4253 recommendation to rekey after 1 Gb of data.
|
||||
// For others, stick with RFC 4253 recommendation to rekey after 1 Gb of data.
|
||||
return 1 << 30
|
||||
}
|
||||
|
||||
var aeadCiphers = map[string]bool{
|
||||
gcmCipherID: true,
|
||||
chacha20Poly1305ID: true,
|
||||
}
|
||||
|
||||
type algorithms struct {
|
||||
kex string
|
||||
hostKey string
|
||||
@@ -181,14 +217,18 @@ func findAgreedAlgorithms(isClient bool, clientKexInit, serverKexInit *kexInitMs
|
||||
return
|
||||
}
|
||||
|
||||
ctos.MAC, err = findCommon("client to server MAC", clientKexInit.MACsClientServer, serverKexInit.MACsClientServer)
|
||||
if err != nil {
|
||||
return
|
||||
if !aeadCiphers[ctos.Cipher] {
|
||||
ctos.MAC, err = findCommon("client to server MAC", clientKexInit.MACsClientServer, serverKexInit.MACsClientServer)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
stoc.MAC, err = findCommon("server to client MAC", clientKexInit.MACsServerClient, serverKexInit.MACsServerClient)
|
||||
if err != nil {
|
||||
return
|
||||
if !aeadCiphers[stoc.Cipher] {
|
||||
stoc.MAC, err = findCommon("server to client MAC", clientKexInit.MACsServerClient, serverKexInit.MACsServerClient)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ctos.Compression, err = findCommon("client to server compression", clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer)
|
||||
@@ -272,8 +312,9 @@ func (c *Config) SetDefaults() {
|
||||
}
|
||||
|
||||
// buildDataSignedForAuth returns the data that is signed in order to prove
|
||||
// possession of a private key. See RFC 4252, section 7.
|
||||
func buildDataSignedForAuth(sessionID []byte, req userAuthRequestMsg, algo, pubKey []byte) []byte {
|
||||
// possession of a private key. See RFC 4252, section 7. algo is the advertised
|
||||
// algorithm, and may be a certificate type.
|
||||
func buildDataSignedForAuth(sessionID []byte, req userAuthRequestMsg, algo string, pubKey []byte) []byte {
|
||||
data := struct {
|
||||
Session []byte
|
||||
Type byte
|
||||
@@ -281,7 +322,7 @@ func buildDataSignedForAuth(sessionID []byte, req userAuthRequestMsg, algo, pubK
|
||||
Service string
|
||||
Method string
|
||||
Sign bool
|
||||
Algo []byte
|
||||
Algo string
|
||||
PubKey []byte
|
||||
}{
|
||||
sessionID,
|
||||
|
||||
2
vendor/golang.org/x/crypto/ssh/connection.go
generated
vendored
2
vendor/golang.org/x/crypto/ssh/connection.go
generated
vendored
@@ -52,7 +52,7 @@ type Conn interface {
|
||||
|
||||
// SendRequest sends a global request, and returns the
|
||||
// reply. If wantReply is true, it returns the response status
|
||||
// and payload. See also RFC4254, section 4.
|
||||
// and payload. See also RFC 4254, section 4.
|
||||
SendRequest(name string, wantReply bool, payload []byte) (bool, []byte, error)
|
||||
|
||||
// OpenChannel tries to open an channel. If the request is
|
||||
|
||||
5
vendor/golang.org/x/crypto/ssh/doc.go
generated
vendored
5
vendor/golang.org/x/crypto/ssh/doc.go
generated
vendored
@@ -12,8 +12,9 @@ the multiplexed nature of SSH is exposed to users that wish to support
|
||||
others.
|
||||
|
||||
References:
|
||||
[PROTOCOL.certkeys]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=HEAD
|
||||
[SSH-PARAMETERS]: http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1
|
||||
|
||||
[PROTOCOL.certkeys]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=HEAD
|
||||
[SSH-PARAMETERS]: http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1
|
||||
|
||||
This package does not fall under the stability promise of the Go language itself,
|
||||
so its API may be changed when pressing needs arise.
|
||||
|
||||
154
vendor/golang.org/x/crypto/ssh/handshake.go
generated
vendored
154
vendor/golang.org/x/crypto/ssh/handshake.go
generated
vendored
@@ -58,11 +58,13 @@ type handshakeTransport struct {
|
||||
incoming chan []byte
|
||||
readError error
|
||||
|
||||
mu sync.Mutex
|
||||
writeError error
|
||||
sentInitPacket []byte
|
||||
sentInitMsg *kexInitMsg
|
||||
pendingPackets [][]byte // Used when a key exchange is in progress.
|
||||
mu sync.Mutex
|
||||
writeError error
|
||||
sentInitPacket []byte
|
||||
sentInitMsg *kexInitMsg
|
||||
pendingPackets [][]byte // Used when a key exchange is in progress.
|
||||
writePacketsLeft uint32
|
||||
writeBytesLeft int64
|
||||
|
||||
// If the read loop wants to schedule a kex, it pings this
|
||||
// channel, and the write loop will send out a kex
|
||||
@@ -71,7 +73,8 @@ type handshakeTransport struct {
|
||||
|
||||
// If the other side requests or confirms a kex, its kexInit
|
||||
// packet is sent here for the write loop to find it.
|
||||
startKex chan *pendingKex
|
||||
startKex chan *pendingKex
|
||||
kexLoopDone chan struct{} // closed (with writeError non-nil) when kexLoop exits
|
||||
|
||||
// data for host key checking
|
||||
hostKeyCallback HostKeyCallback
|
||||
@@ -86,12 +89,10 @@ type handshakeTransport struct {
|
||||
// Algorithms agreed in the last key exchange.
|
||||
algorithms *algorithms
|
||||
|
||||
// Counters exclusively owned by readLoop.
|
||||
readPacketsLeft uint32
|
||||
readBytesLeft int64
|
||||
|
||||
writePacketsLeft uint32
|
||||
writeBytesLeft int64
|
||||
|
||||
// The session ID or nil if first kex did not complete yet.
|
||||
sessionID []byte
|
||||
}
|
||||
@@ -108,7 +109,8 @@ func newHandshakeTransport(conn keyingTransport, config *Config, clientVersion,
|
||||
clientVersion: clientVersion,
|
||||
incoming: make(chan []byte, chanSize),
|
||||
requestKex: make(chan struct{}, 1),
|
||||
startKex: make(chan *pendingKex, 1),
|
||||
startKex: make(chan *pendingKex),
|
||||
kexLoopDone: make(chan struct{}),
|
||||
|
||||
config: config,
|
||||
}
|
||||
@@ -340,16 +342,17 @@ write:
|
||||
t.mu.Unlock()
|
||||
}
|
||||
|
||||
// drain startKex channel. We don't service t.requestKex
|
||||
// because nobody does blocking sends there.
|
||||
go func() {
|
||||
for init := range t.startKex {
|
||||
init.done <- t.writeError
|
||||
}
|
||||
}()
|
||||
|
||||
// Unblock reader.
|
||||
t.conn.Close()
|
||||
|
||||
// drain startKex channel. We don't service t.requestKex
|
||||
// because nobody does blocking sends there.
|
||||
for request := range t.startKex {
|
||||
request.done <- t.getWriteError()
|
||||
}
|
||||
|
||||
// Mark that the loop is done so that Close can return.
|
||||
close(t.kexLoopDone)
|
||||
}
|
||||
|
||||
// The protocol uses uint32 for packet counters, so we can't let them
|
||||
@@ -455,14 +458,38 @@ func (t *handshakeTransport) sendKexInit() error {
|
||||
}
|
||||
io.ReadFull(rand.Reader, msg.Cookie[:])
|
||||
|
||||
if len(t.hostKeys) > 0 {
|
||||
isServer := len(t.hostKeys) > 0
|
||||
if isServer {
|
||||
for _, k := range t.hostKeys {
|
||||
msg.ServerHostKeyAlgos = append(
|
||||
msg.ServerHostKeyAlgos, k.PublicKey().Type())
|
||||
// If k is an AlgorithmSigner, presume it supports all signature algorithms
|
||||
// associated with the key format. (Ideally AlgorithmSigner would have a
|
||||
// method to advertise supported algorithms, but it doesn't. This means that
|
||||
// adding support for a new algorithm is a breaking change, as we will
|
||||
// immediately negotiate it even if existing implementations don't support
|
||||
// it. If that ever happens, we'll have to figure something out.)
|
||||
// If k is not an AlgorithmSigner, we can only assume it only supports the
|
||||
// algorithms that matches the key format. (This means that Sign can't pick
|
||||
// a different default.)
|
||||
keyFormat := k.PublicKey().Type()
|
||||
if _, ok := k.(AlgorithmSigner); ok {
|
||||
msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algorithmsForKeyFormat(keyFormat)...)
|
||||
} else {
|
||||
msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, keyFormat)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
msg.ServerHostKeyAlgos = t.hostKeyAlgorithms
|
||||
|
||||
// As a client we opt in to receiving SSH_MSG_EXT_INFO so we know what
|
||||
// algorithms the server supports for public key authentication. See RFC
|
||||
// 8308, Section 2.1.
|
||||
if firstKeyExchange := t.sessionID == nil; firstKeyExchange {
|
||||
msg.KexAlgos = make([]string, 0, len(t.config.KeyExchanges)+1)
|
||||
msg.KexAlgos = append(msg.KexAlgos, t.config.KeyExchanges...)
|
||||
msg.KexAlgos = append(msg.KexAlgos, "ext-info-c")
|
||||
}
|
||||
}
|
||||
|
||||
packet := Marshal(msg)
|
||||
|
||||
// writePacket destroys the contents, so save a copy.
|
||||
@@ -521,7 +548,16 @@ func (t *handshakeTransport) writePacket(p []byte) error {
|
||||
}
|
||||
|
||||
func (t *handshakeTransport) Close() error {
|
||||
return t.conn.Close()
|
||||
// Close the connection. This should cause the readLoop goroutine to wake up
|
||||
// and close t.startKex, which will shut down kexLoop if running.
|
||||
err := t.conn.Close()
|
||||
|
||||
// Wait for the kexLoop goroutine to complete.
|
||||
// At that point we know that the readLoop goroutine is complete too,
|
||||
// because kexLoop itself waits for readLoop to close the startKex channel.
|
||||
<-t.kexLoopDone
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
|
||||
@@ -582,16 +618,17 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
|
||||
|
||||
var result *kexResult
|
||||
if len(t.hostKeys) > 0 {
|
||||
result, err = t.server(kex, t.algorithms, &magics)
|
||||
result, err = t.server(kex, &magics)
|
||||
} else {
|
||||
result, err = t.client(kex, t.algorithms, &magics)
|
||||
result, err = t.client(kex, &magics)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if t.sessionID == nil {
|
||||
firstKeyExchange := t.sessionID == nil
|
||||
if firstKeyExchange {
|
||||
t.sessionID = result.H
|
||||
}
|
||||
result.SessionID = t.sessionID
|
||||
@@ -602,6 +639,24 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
|
||||
if err = t.conn.writePacket([]byte{msgNewKeys}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// On the server side, after the first SSH_MSG_NEWKEYS, send a SSH_MSG_EXT_INFO
|
||||
// message with the server-sig-algs extension if the client supports it. See
|
||||
// RFC 8308, Sections 2.4 and 3.1.
|
||||
if !isClient && firstKeyExchange && contains(clientInit.KexAlgos, "ext-info-c") {
|
||||
extInfo := &extInfoMsg{
|
||||
NumExtensions: 1,
|
||||
Payload: make([]byte, 0, 4+15+4+len(supportedPubKeyAuthAlgosList)),
|
||||
}
|
||||
extInfo.Payload = appendInt(extInfo.Payload, len("server-sig-algs"))
|
||||
extInfo.Payload = append(extInfo.Payload, "server-sig-algs"...)
|
||||
extInfo.Payload = appendInt(extInfo.Payload, len(supportedPubKeyAuthAlgosList))
|
||||
extInfo.Payload = append(extInfo.Payload, supportedPubKeyAuthAlgosList...)
|
||||
if err := t.conn.writePacket(Marshal(extInfo)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if packet, err := t.conn.readPacket(); err != nil {
|
||||
return err
|
||||
} else if packet[0] != msgNewKeys {
|
||||
@@ -611,19 +666,52 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *handshakeTransport) server(kex kexAlgorithm, algs *algorithms, magics *handshakeMagics) (*kexResult, error) {
|
||||
var hostKey Signer
|
||||
for _, k := range t.hostKeys {
|
||||
if algs.hostKey == k.PublicKey().Type() {
|
||||
hostKey = k
|
||||
// algorithmSignerWrapper is an AlgorithmSigner that only supports the default
|
||||
// key format algorithm.
|
||||
//
|
||||
// This is technically a violation of the AlgorithmSigner interface, but it
|
||||
// should be unreachable given where we use this. Anyway, at least it returns an
|
||||
// error instead of panicing or producing an incorrect signature.
|
||||
type algorithmSignerWrapper struct {
|
||||
Signer
|
||||
}
|
||||
|
||||
func (a algorithmSignerWrapper) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
|
||||
if algorithm != underlyingAlgo(a.PublicKey().Type()) {
|
||||
return nil, errors.New("ssh: internal error: algorithmSignerWrapper invoked with non-default algorithm")
|
||||
}
|
||||
return a.Sign(rand, data)
|
||||
}
|
||||
|
||||
func pickHostKey(hostKeys []Signer, algo string) AlgorithmSigner {
|
||||
for _, k := range hostKeys {
|
||||
if algo == k.PublicKey().Type() {
|
||||
return algorithmSignerWrapper{k}
|
||||
}
|
||||
k, ok := k.(AlgorithmSigner)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
for _, a := range algorithmsForKeyFormat(k.PublicKey().Type()) {
|
||||
if algo == a {
|
||||
return k
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey)
|
||||
func (t *handshakeTransport) server(kex kexAlgorithm, magics *handshakeMagics) (*kexResult, error) {
|
||||
hostKey := pickHostKey(t.hostKeys, t.algorithms.hostKey)
|
||||
if hostKey == nil {
|
||||
return nil, errors.New("ssh: internal error: negotiated unsupported signature type")
|
||||
}
|
||||
|
||||
r, err := kex.Server(t.conn, t.config.Rand, magics, hostKey, t.algorithms.hostKey)
|
||||
return r, err
|
||||
}
|
||||
|
||||
func (t *handshakeTransport) client(kex kexAlgorithm, algs *algorithms, magics *handshakeMagics) (*kexResult, error) {
|
||||
func (t *handshakeTransport) client(kex kexAlgorithm, magics *handshakeMagics) (*kexResult, error) {
|
||||
result, err := kex.Client(t.conn, t.config.Rand, magics)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -634,7 +722,7 @@ func (t *handshakeTransport) client(kex kexAlgorithm, algs *algorithms, magics *
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := verifyHostKeySignature(hostKey, result); err != nil {
|
||||
if err := verifyHostKeySignature(hostKey, t.algorithms.hostKey, result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
186
vendor/golang.org/x/crypto/ssh/kex.go
generated
vendored
186
vendor/golang.org/x/crypto/ssh/kex.go
generated
vendored
@@ -20,12 +20,14 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
kexAlgoDH1SHA1 = "diffie-hellman-group1-sha1"
|
||||
kexAlgoDH14SHA1 = "diffie-hellman-group14-sha1"
|
||||
kexAlgoECDH256 = "ecdh-sha2-nistp256"
|
||||
kexAlgoECDH384 = "ecdh-sha2-nistp384"
|
||||
kexAlgoECDH521 = "ecdh-sha2-nistp521"
|
||||
kexAlgoCurve25519SHA256 = "curve25519-sha256@libssh.org"
|
||||
kexAlgoDH1SHA1 = "diffie-hellman-group1-sha1"
|
||||
kexAlgoDH14SHA1 = "diffie-hellman-group14-sha1"
|
||||
kexAlgoDH14SHA256 = "diffie-hellman-group14-sha256"
|
||||
kexAlgoECDH256 = "ecdh-sha2-nistp256"
|
||||
kexAlgoECDH384 = "ecdh-sha2-nistp384"
|
||||
kexAlgoECDH521 = "ecdh-sha2-nistp521"
|
||||
kexAlgoCurve25519SHA256LibSSH = "curve25519-sha256@libssh.org"
|
||||
kexAlgoCurve25519SHA256 = "curve25519-sha256"
|
||||
|
||||
// For the following kex only the client half contains a production
|
||||
// ready implementation. The server half only consists of a minimal
|
||||
@@ -75,8 +77,9 @@ func (m *handshakeMagics) write(w io.Writer) {
|
||||
// kexAlgorithm abstracts different key exchange algorithms.
|
||||
type kexAlgorithm interface {
|
||||
// Server runs server-side key agreement, signing the result
|
||||
// with a hostkey.
|
||||
Server(p packetConn, rand io.Reader, magics *handshakeMagics, s Signer) (*kexResult, error)
|
||||
// with a hostkey. algo is the negotiated algorithm, and may
|
||||
// be a certificate type.
|
||||
Server(p packetConn, rand io.Reader, magics *handshakeMagics, s AlgorithmSigner, algo string) (*kexResult, error)
|
||||
|
||||
// Client runs the client-side key agreement. Caller is
|
||||
// responsible for verifying the host key signature.
|
||||
@@ -86,6 +89,7 @@ type kexAlgorithm interface {
|
||||
// dhGroup is a multiplicative group suitable for implementing Diffie-Hellman key agreement.
|
||||
type dhGroup struct {
|
||||
g, p, pMinus1 *big.Int
|
||||
hashFunc crypto.Hash
|
||||
}
|
||||
|
||||
func (group *dhGroup) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int, error) {
|
||||
@@ -96,8 +100,6 @@ func (group *dhGroup) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int,
|
||||
}
|
||||
|
||||
func (group *dhGroup) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) {
|
||||
hashFunc := crypto.SHA1
|
||||
|
||||
var x *big.Int
|
||||
for {
|
||||
var err error
|
||||
@@ -132,7 +134,7 @@ func (group *dhGroup) Client(c packetConn, randSource io.Reader, magics *handsha
|
||||
return nil, err
|
||||
}
|
||||
|
||||
h := hashFunc.New()
|
||||
h := group.hashFunc.New()
|
||||
magics.write(h)
|
||||
writeString(h, kexDHReply.HostKey)
|
||||
writeInt(h, X)
|
||||
@@ -146,12 +148,11 @@ func (group *dhGroup) Client(c packetConn, randSource io.Reader, magics *handsha
|
||||
K: K,
|
||||
HostKey: kexDHReply.HostKey,
|
||||
Signature: kexDHReply.Signature,
|
||||
Hash: crypto.SHA1,
|
||||
Hash: group.hashFunc,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
|
||||
hashFunc := crypto.SHA1
|
||||
func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) {
|
||||
packet, err := c.readPacket()
|
||||
if err != nil {
|
||||
return
|
||||
@@ -179,7 +180,7 @@ func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handsha
|
||||
|
||||
hostKeyBytes := priv.PublicKey().Marshal()
|
||||
|
||||
h := hashFunc.New()
|
||||
h := group.hashFunc.New()
|
||||
magics.write(h)
|
||||
writeString(h, hostKeyBytes)
|
||||
writeInt(h, kexDHInit.X)
|
||||
@@ -193,7 +194,7 @@ func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handsha
|
||||
|
||||
// H is already a hash, but the hostkey signing will apply its
|
||||
// own key-specific hash algorithm.
|
||||
sig, err := signAndMarshal(priv, randSource, H)
|
||||
sig, err := signAndMarshal(priv, randSource, H, algo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -211,7 +212,7 @@ func (group *dhGroup) Server(c packetConn, randSource io.Reader, magics *handsha
|
||||
K: K,
|
||||
HostKey: hostKeyBytes,
|
||||
Signature: sig,
|
||||
Hash: crypto.SHA1,
|
||||
Hash: group.hashFunc,
|
||||
}, err
|
||||
}
|
||||
|
||||
@@ -314,7 +315,7 @@ func validateECPublicKey(curve elliptic.Curve, x, y *big.Int) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (kex *ecdh) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
|
||||
func (kex *ecdh) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) {
|
||||
packet, err := c.readPacket()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -359,7 +360,7 @@ func (kex *ecdh) Server(c packetConn, rand io.Reader, magics *handshakeMagics, p
|
||||
|
||||
// H is already a hash, but the hostkey signing will apply its
|
||||
// own key-specific hash algorithm.
|
||||
sig, err := signAndMarshal(priv, rand, H)
|
||||
sig, err := signAndMarshal(priv, rand, H, algo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -384,39 +385,62 @@ func (kex *ecdh) Server(c packetConn, rand io.Reader, magics *handshakeMagics, p
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ecHash returns the hash to match the given elliptic curve, see RFC
|
||||
// 5656, section 6.2.1
|
||||
func ecHash(curve elliptic.Curve) crypto.Hash {
|
||||
bitSize := curve.Params().BitSize
|
||||
switch {
|
||||
case bitSize <= 256:
|
||||
return crypto.SHA256
|
||||
case bitSize <= 384:
|
||||
return crypto.SHA384
|
||||
}
|
||||
return crypto.SHA512
|
||||
}
|
||||
|
||||
var kexAlgoMap = map[string]kexAlgorithm{}
|
||||
|
||||
func init() {
|
||||
// This is the group called diffie-hellman-group1-sha1 in RFC
|
||||
// 4253 and Oakley Group 2 in RFC 2409.
|
||||
// This is the group called diffie-hellman-group1-sha1 in
|
||||
// RFC 4253 and Oakley Group 2 in RFC 2409.
|
||||
p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF", 16)
|
||||
kexAlgoMap[kexAlgoDH1SHA1] = &dhGroup{
|
||||
g: new(big.Int).SetInt64(2),
|
||||
p: p,
|
||||
pMinus1: new(big.Int).Sub(p, bigOne),
|
||||
hashFunc: crypto.SHA1,
|
||||
}
|
||||
|
||||
// This are the groups called diffie-hellman-group14-sha1 and
|
||||
// diffie-hellman-group14-sha256 in RFC 4253 and RFC 8268,
|
||||
// and Oakley Group 14 in RFC 3526.
|
||||
p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16)
|
||||
group14 := &dhGroup{
|
||||
g: new(big.Int).SetInt64(2),
|
||||
p: p,
|
||||
pMinus1: new(big.Int).Sub(p, bigOne),
|
||||
}
|
||||
|
||||
// This is the group called diffie-hellman-group14-sha1 in RFC
|
||||
// 4253 and Oakley Group 14 in RFC 3526.
|
||||
p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16)
|
||||
|
||||
kexAlgoMap[kexAlgoDH14SHA1] = &dhGroup{
|
||||
g: new(big.Int).SetInt64(2),
|
||||
p: p,
|
||||
pMinus1: new(big.Int).Sub(p, bigOne),
|
||||
g: group14.g, p: group14.p, pMinus1: group14.pMinus1,
|
||||
hashFunc: crypto.SHA1,
|
||||
}
|
||||
kexAlgoMap[kexAlgoDH14SHA256] = &dhGroup{
|
||||
g: group14.g, p: group14.p, pMinus1: group14.pMinus1,
|
||||
hashFunc: crypto.SHA256,
|
||||
}
|
||||
|
||||
kexAlgoMap[kexAlgoECDH521] = &ecdh{elliptic.P521()}
|
||||
kexAlgoMap[kexAlgoECDH384] = &ecdh{elliptic.P384()}
|
||||
kexAlgoMap[kexAlgoECDH256] = &ecdh{elliptic.P256()}
|
||||
kexAlgoMap[kexAlgoCurve25519SHA256] = &curve25519sha256{}
|
||||
kexAlgoMap[kexAlgoCurve25519SHA256LibSSH] = &curve25519sha256{}
|
||||
kexAlgoMap[kexAlgoDHGEXSHA1] = &dhGEXSHA{hashFunc: crypto.SHA1}
|
||||
kexAlgoMap[kexAlgoDHGEXSHA256] = &dhGEXSHA{hashFunc: crypto.SHA256}
|
||||
}
|
||||
|
||||
// curve25519sha256 implements the curve25519-sha256@libssh.org key
|
||||
// agreement protocol, as described in
|
||||
// https://git.libssh.org/projects/libssh.git/tree/doc/curve25519-sha256@libssh.org.txt
|
||||
// curve25519sha256 implements the curve25519-sha256 (formerly known as
|
||||
// curve25519-sha256@libssh.org) key exchange method, as described in RFC 8731.
|
||||
type curve25519sha256 struct{}
|
||||
|
||||
type curve25519KeyPair struct {
|
||||
@@ -486,7 +510,7 @@ func (kex *curve25519sha256) Client(c packetConn, rand io.Reader, magics *handsh
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
|
||||
func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) {
|
||||
packet, err := c.readPacket()
|
||||
if err != nil {
|
||||
return
|
||||
@@ -527,7 +551,7 @@ func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handsh
|
||||
|
||||
H := h.Sum(nil)
|
||||
|
||||
sig, err := signAndMarshal(priv, rand, H)
|
||||
sig, err := signAndMarshal(priv, rand, H, algo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -553,7 +577,6 @@ func (kex *curve25519sha256) Server(c packetConn, rand io.Reader, magics *handsh
|
||||
// diffie-hellman-group-exchange-sha256 key agreement protocols,
|
||||
// as described in RFC 4419
|
||||
type dhGEXSHA struct {
|
||||
g, p *big.Int
|
||||
hashFunc crypto.Hash
|
||||
}
|
||||
|
||||
@@ -563,14 +586,7 @@ const (
|
||||
dhGroupExchangeMaximumBits = 8192
|
||||
)
|
||||
|
||||
func (gex *dhGEXSHA) diffieHellman(theirPublic, myPrivate *big.Int) (*big.Int, error) {
|
||||
if theirPublic.Sign() <= 0 || theirPublic.Cmp(gex.p) >= 0 {
|
||||
return nil, fmt.Errorf("ssh: DH parameter out of bounds")
|
||||
}
|
||||
return new(big.Int).Exp(theirPublic, myPrivate, gex.p), nil
|
||||
}
|
||||
|
||||
func (gex dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) {
|
||||
func (gex *dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshakeMagics) (*kexResult, error) {
|
||||
// Send GexRequest
|
||||
kexDHGexRequest := kexDHGexRequestMsg{
|
||||
MinBits: dhGroupExchangeMinimumBits,
|
||||
@@ -587,35 +603,29 @@ func (gex dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshake
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var kexDHGexGroup kexDHGexGroupMsg
|
||||
if err = Unmarshal(packet, &kexDHGexGroup); err != nil {
|
||||
var msg kexDHGexGroupMsg
|
||||
if err = Unmarshal(packet, &msg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// reject if p's bit length < dhGroupExchangeMinimumBits or > dhGroupExchangeMaximumBits
|
||||
if kexDHGexGroup.P.BitLen() < dhGroupExchangeMinimumBits || kexDHGexGroup.P.BitLen() > dhGroupExchangeMaximumBits {
|
||||
return nil, fmt.Errorf("ssh: server-generated gex p is out of range (%d bits)", kexDHGexGroup.P.BitLen())
|
||||
if msg.P.BitLen() < dhGroupExchangeMinimumBits || msg.P.BitLen() > dhGroupExchangeMaximumBits {
|
||||
return nil, fmt.Errorf("ssh: server-generated gex p is out of range (%d bits)", msg.P.BitLen())
|
||||
}
|
||||
|
||||
gex.p = kexDHGexGroup.P
|
||||
gex.g = kexDHGexGroup.G
|
||||
|
||||
// Check if g is safe by verifing that g > 1 and g < p - 1
|
||||
one := big.NewInt(1)
|
||||
var pMinusOne = &big.Int{}
|
||||
pMinusOne.Sub(gex.p, one)
|
||||
if gex.g.Cmp(one) != 1 && gex.g.Cmp(pMinusOne) != -1 {
|
||||
// Check if g is safe by verifying that 1 < g < p-1
|
||||
pMinusOne := new(big.Int).Sub(msg.P, bigOne)
|
||||
if msg.G.Cmp(bigOne) <= 0 || msg.G.Cmp(pMinusOne) >= 0 {
|
||||
return nil, fmt.Errorf("ssh: server provided gex g is not safe")
|
||||
}
|
||||
|
||||
// Send GexInit
|
||||
var pHalf = &big.Int{}
|
||||
pHalf.Rsh(gex.p, 1)
|
||||
pHalf := new(big.Int).Rsh(msg.P, 1)
|
||||
x, err := rand.Int(randSource, pHalf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
X := new(big.Int).Exp(gex.g, x, gex.p)
|
||||
X := new(big.Int).Exp(msg.G, x, msg.P)
|
||||
kexDHGexInit := kexDHGexInitMsg{
|
||||
X: X,
|
||||
}
|
||||
@@ -634,13 +644,13 @@ func (gex dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshake
|
||||
return nil, err
|
||||
}
|
||||
|
||||
kInt, err := gex.diffieHellman(kexDHGexReply.Y, x)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if kexDHGexReply.Y.Cmp(bigOne) <= 0 || kexDHGexReply.Y.Cmp(pMinusOne) >= 0 {
|
||||
return nil, errors.New("ssh: DH parameter out of bounds")
|
||||
}
|
||||
kInt := new(big.Int).Exp(kexDHGexReply.Y, x, msg.P)
|
||||
|
||||
// Check if k is safe by verifing that k > 1 and k < p - 1
|
||||
if kInt.Cmp(one) != 1 && kInt.Cmp(pMinusOne) != -1 {
|
||||
// Check if k is safe by verifying that k > 1 and k < p - 1
|
||||
if kInt.Cmp(bigOne) <= 0 || kInt.Cmp(pMinusOne) >= 0 {
|
||||
return nil, fmt.Errorf("ssh: derived k is not safe")
|
||||
}
|
||||
|
||||
@@ -650,8 +660,8 @@ func (gex dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshake
|
||||
binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMinimumBits))
|
||||
binary.Write(h, binary.BigEndian, uint32(dhGroupExchangePreferredBits))
|
||||
binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMaximumBits))
|
||||
writeInt(h, gex.p)
|
||||
writeInt(h, gex.g)
|
||||
writeInt(h, msg.P)
|
||||
writeInt(h, msg.G)
|
||||
writeInt(h, X)
|
||||
writeInt(h, kexDHGexReply.Y)
|
||||
K := make([]byte, intLength(kInt))
|
||||
@@ -670,7 +680,7 @@ func (gex dhGEXSHA) Client(c packetConn, randSource io.Reader, magics *handshake
|
||||
// Server half implementation of the Diffie Hellman Key Exchange with SHA1 and SHA256.
|
||||
//
|
||||
// This is a minimal implementation to satisfy the automated tests.
|
||||
func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
|
||||
func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshakeMagics, priv AlgorithmSigner, algo string) (result *kexResult, err error) {
|
||||
// Receive GexRequest
|
||||
packet, err := c.readPacket()
|
||||
if err != nil {
|
||||
@@ -681,35 +691,17 @@ func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshake
|
||||
return
|
||||
}
|
||||
|
||||
// smoosh the user's preferred size into our own limits
|
||||
if kexDHGexRequest.PreferedBits > dhGroupExchangeMaximumBits {
|
||||
kexDHGexRequest.PreferedBits = dhGroupExchangeMaximumBits
|
||||
}
|
||||
if kexDHGexRequest.PreferedBits < dhGroupExchangeMinimumBits {
|
||||
kexDHGexRequest.PreferedBits = dhGroupExchangeMinimumBits
|
||||
}
|
||||
// fix min/max if they're inconsistent. technically, we could just pout
|
||||
// and hang up, but there's no harm in giving them the benefit of the
|
||||
// doubt and just picking a bitsize for them.
|
||||
if kexDHGexRequest.MinBits > kexDHGexRequest.PreferedBits {
|
||||
kexDHGexRequest.MinBits = kexDHGexRequest.PreferedBits
|
||||
}
|
||||
if kexDHGexRequest.MaxBits < kexDHGexRequest.PreferedBits {
|
||||
kexDHGexRequest.MaxBits = kexDHGexRequest.PreferedBits
|
||||
}
|
||||
|
||||
// Send GexGroup
|
||||
// This is the group called diffie-hellman-group14-sha1 in RFC
|
||||
// 4253 and Oakley Group 14 in RFC 3526.
|
||||
p, _ := new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF", 16)
|
||||
gex.p = p
|
||||
gex.g = big.NewInt(2)
|
||||
g := big.NewInt(2)
|
||||
|
||||
kexDHGexGroup := kexDHGexGroupMsg{
|
||||
P: gex.p,
|
||||
G: gex.g,
|
||||
msg := &kexDHGexGroupMsg{
|
||||
P: p,
|
||||
G: g,
|
||||
}
|
||||
if err := c.writePacket(Marshal(&kexDHGexGroup)); err != nil {
|
||||
if err := c.writePacket(Marshal(msg)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -723,19 +715,19 @@ func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshake
|
||||
return
|
||||
}
|
||||
|
||||
var pHalf = &big.Int{}
|
||||
pHalf.Rsh(gex.p, 1)
|
||||
pHalf := new(big.Int).Rsh(p, 1)
|
||||
|
||||
y, err := rand.Int(randSource, pHalf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
Y := new(big.Int).Exp(g, y, p)
|
||||
|
||||
Y := new(big.Int).Exp(gex.g, y, gex.p)
|
||||
kInt, err := gex.diffieHellman(kexDHGexInit.X, y)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
pMinusOne := new(big.Int).Sub(p, bigOne)
|
||||
if kexDHGexInit.X.Cmp(bigOne) <= 0 || kexDHGexInit.X.Cmp(pMinusOne) >= 0 {
|
||||
return nil, errors.New("ssh: DH parameter out of bounds")
|
||||
}
|
||||
kInt := new(big.Int).Exp(kexDHGexInit.X, y, p)
|
||||
|
||||
hostKeyBytes := priv.PublicKey().Marshal()
|
||||
|
||||
@@ -745,8 +737,8 @@ func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshake
|
||||
binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMinimumBits))
|
||||
binary.Write(h, binary.BigEndian, uint32(dhGroupExchangePreferredBits))
|
||||
binary.Write(h, binary.BigEndian, uint32(dhGroupExchangeMaximumBits))
|
||||
writeInt(h, gex.p)
|
||||
writeInt(h, gex.g)
|
||||
writeInt(h, p)
|
||||
writeInt(h, g)
|
||||
writeInt(h, kexDHGexInit.X)
|
||||
writeInt(h, Y)
|
||||
|
||||
@@ -758,7 +750,7 @@ func (gex dhGEXSHA) Server(c packetConn, randSource io.Reader, magics *handshake
|
||||
|
||||
// H is already a hash, but the hostkey signing will apply its
|
||||
// own key-specific hash algorithm.
|
||||
sig, err := signAndMarshal(priv, randSource, H)
|
||||
sig, err := signAndMarshal(priv, randSource, H, algo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
151
vendor/golang.org/x/crypto/ssh/keys.go
generated
vendored
151
vendor/golang.org/x/crypto/ssh/keys.go
generated
vendored
@@ -30,8 +30,9 @@ import (
|
||||
"golang.org/x/crypto/ssh/internal/bcrypt_pbkdf"
|
||||
)
|
||||
|
||||
// These constants represent the algorithm names for key types supported by this
|
||||
// package.
|
||||
// Public key algorithms names. These values can appear in PublicKey.Type,
|
||||
// ClientConfig.HostKeyAlgorithms, Signature.Format, or as AlgorithmSigner
|
||||
// arguments.
|
||||
const (
|
||||
KeyAlgoRSA = "ssh-rsa"
|
||||
KeyAlgoDSA = "ssh-dss"
|
||||
@@ -41,16 +42,21 @@ const (
|
||||
KeyAlgoECDSA521 = "ecdsa-sha2-nistp521"
|
||||
KeyAlgoED25519 = "ssh-ed25519"
|
||||
KeyAlgoSKED25519 = "sk-ssh-ed25519@openssh.com"
|
||||
|
||||
// KeyAlgoRSASHA256 and KeyAlgoRSASHA512 are only public key algorithms, not
|
||||
// public key formats, so they can't appear as a PublicKey.Type. The
|
||||
// corresponding PublicKey.Type is KeyAlgoRSA. See RFC 8332, Section 2.
|
||||
KeyAlgoRSASHA256 = "rsa-sha2-256"
|
||||
KeyAlgoRSASHA512 = "rsa-sha2-512"
|
||||
)
|
||||
|
||||
// These constants represent non-default signature algorithms that are supported
|
||||
// as algorithm parameters to AlgorithmSigner.SignWithAlgorithm methods. See
|
||||
// [PROTOCOL.agent] section 4.5.1 and
|
||||
// https://tools.ietf.org/html/draft-ietf-curdle-rsa-sha2-10
|
||||
const (
|
||||
SigAlgoRSA = "ssh-rsa"
|
||||
SigAlgoRSASHA2256 = "rsa-sha2-256"
|
||||
SigAlgoRSASHA2512 = "rsa-sha2-512"
|
||||
// Deprecated: use KeyAlgoRSA.
|
||||
SigAlgoRSA = KeyAlgoRSA
|
||||
// Deprecated: use KeyAlgoRSASHA256.
|
||||
SigAlgoRSASHA2256 = KeyAlgoRSASHA256
|
||||
// Deprecated: use KeyAlgoRSASHA512.
|
||||
SigAlgoRSASHA2512 = KeyAlgoRSASHA512
|
||||
)
|
||||
|
||||
// parsePubKey parses a public key of the given algorithm.
|
||||
@@ -70,7 +76,7 @@ func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err err
|
||||
case KeyAlgoSKED25519:
|
||||
return parseSKEd25519(in)
|
||||
case CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01:
|
||||
cert, err := parseCert(in, certToPrivAlgo(algo))
|
||||
cert, err := parseCert(in, certKeyAlgoNames[algo])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -178,7 +184,7 @@ func ParseKnownHosts(in []byte) (marker string, hosts []string, pubKey PublicKey
|
||||
return "", nil, nil, "", nil, io.EOF
|
||||
}
|
||||
|
||||
// ParseAuthorizedKeys parses a public key from an authorized_keys
|
||||
// ParseAuthorizedKey parses a public key from an authorized_keys
|
||||
// file used in OpenSSH according to the sshd(8) manual page.
|
||||
func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error) {
|
||||
for len(in) > 0 {
|
||||
@@ -289,18 +295,21 @@ func MarshalAuthorizedKey(key PublicKey) []byte {
|
||||
return b.Bytes()
|
||||
}
|
||||
|
||||
// PublicKey is an abstraction of different types of public keys.
|
||||
// PublicKey represents a public key using an unspecified algorithm.
|
||||
//
|
||||
// Some PublicKeys provided by this package also implement CryptoPublicKey.
|
||||
type PublicKey interface {
|
||||
// Type returns the key's type, e.g. "ssh-rsa".
|
||||
// Type returns the key format name, e.g. "ssh-rsa".
|
||||
Type() string
|
||||
|
||||
// Marshal returns the serialized key data in SSH wire format,
|
||||
// with the name prefix. To unmarshal the returned data, use
|
||||
// the ParsePublicKey function.
|
||||
// Marshal returns the serialized key data in SSH wire format, with the name
|
||||
// prefix. To unmarshal the returned data, use the ParsePublicKey function.
|
||||
Marshal() []byte
|
||||
|
||||
// Verify that sig is a signature on the given data using this
|
||||
// key. This function will hash the data appropriately first.
|
||||
// Verify that sig is a signature on the given data using this key. This
|
||||
// method will hash the data appropriately first. sig.Format is allowed to
|
||||
// be any signature algorithm compatible with the key type, the caller
|
||||
// should check if it has more stringent requirements.
|
||||
Verify(data []byte, sig *Signature) error
|
||||
}
|
||||
|
||||
@@ -311,25 +320,32 @@ type CryptoPublicKey interface {
|
||||
}
|
||||
|
||||
// A Signer can create signatures that verify against a public key.
|
||||
//
|
||||
// Some Signers provided by this package also implement AlgorithmSigner.
|
||||
type Signer interface {
|
||||
// PublicKey returns an associated PublicKey instance.
|
||||
// PublicKey returns the associated PublicKey.
|
||||
PublicKey() PublicKey
|
||||
|
||||
// Sign returns raw signature for the given data. This method
|
||||
// will apply the hash specified for the keytype to the data.
|
||||
// Sign returns a signature for the given data. This method will hash the
|
||||
// data appropriately first. The signature algorithm is expected to match
|
||||
// the key format returned by the PublicKey.Type method (and not to be any
|
||||
// alternative algorithm supported by the key format).
|
||||
Sign(rand io.Reader, data []byte) (*Signature, error)
|
||||
}
|
||||
|
||||
// A AlgorithmSigner is a Signer that also supports specifying a specific
|
||||
// algorithm to use for signing.
|
||||
// An AlgorithmSigner is a Signer that also supports specifying an algorithm to
|
||||
// use for signing.
|
||||
//
|
||||
// An AlgorithmSigner can't advertise the algorithms it supports, so it should
|
||||
// be prepared to be invoked with every algorithm supported by the public key
|
||||
// format.
|
||||
type AlgorithmSigner interface {
|
||||
Signer
|
||||
|
||||
// SignWithAlgorithm is like Signer.Sign, but allows specification of a
|
||||
// non-default signing algorithm. See the SigAlgo* constants in this
|
||||
// package for signature algorithms supported by this package. Callers may
|
||||
// pass an empty string for the algorithm in which case the AlgorithmSigner
|
||||
// will use its default algorithm.
|
||||
// SignWithAlgorithm is like Signer.Sign, but allows specifying a desired
|
||||
// signing algorithm. Callers may pass an empty string for the algorithm in
|
||||
// which case the AlgorithmSigner will use a default algorithm. This default
|
||||
// doesn't currently control any behavior in this package.
|
||||
SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error)
|
||||
}
|
||||
|
||||
@@ -381,17 +397,11 @@ func (r *rsaPublicKey) Marshal() []byte {
|
||||
}
|
||||
|
||||
func (r *rsaPublicKey) Verify(data []byte, sig *Signature) error {
|
||||
var hash crypto.Hash
|
||||
switch sig.Format {
|
||||
case SigAlgoRSA:
|
||||
hash = crypto.SHA1
|
||||
case SigAlgoRSASHA2256:
|
||||
hash = crypto.SHA256
|
||||
case SigAlgoRSASHA2512:
|
||||
hash = crypto.SHA512
|
||||
default:
|
||||
supportedAlgos := algorithmsForKeyFormat(r.Type())
|
||||
if !contains(supportedAlgos, sig.Format) {
|
||||
return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, r.Type())
|
||||
}
|
||||
hash := hashFuncs[sig.Format]
|
||||
h := hash.New()
|
||||
h.Write(data)
|
||||
digest := h.Sum(nil)
|
||||
@@ -466,7 +476,7 @@ func (k *dsaPublicKey) Verify(data []byte, sig *Signature) error {
|
||||
if sig.Format != k.Type() {
|
||||
return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
|
||||
}
|
||||
h := crypto.SHA1.New()
|
||||
h := hashFuncs[sig.Format].New()
|
||||
h.Write(data)
|
||||
digest := h.Sum(nil)
|
||||
|
||||
@@ -499,7 +509,7 @@ func (k *dsaPrivateKey) PublicKey() PublicKey {
|
||||
}
|
||||
|
||||
func (k *dsaPrivateKey) Sign(rand io.Reader, data []byte) (*Signature, error) {
|
||||
return k.SignWithAlgorithm(rand, data, "")
|
||||
return k.SignWithAlgorithm(rand, data, k.PublicKey().Type())
|
||||
}
|
||||
|
||||
func (k *dsaPrivateKey) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
|
||||
@@ -507,7 +517,7 @@ func (k *dsaPrivateKey) SignWithAlgorithm(rand io.Reader, data []byte, algorithm
|
||||
return nil, fmt.Errorf("ssh: unsupported signature algorithm %s", algorithm)
|
||||
}
|
||||
|
||||
h := crypto.SHA1.New()
|
||||
h := hashFuncs[k.PublicKey().Type()].New()
|
||||
h.Write(data)
|
||||
digest := h.Sum(nil)
|
||||
r, s, err := dsa.Sign(rand, k.PrivateKey, digest)
|
||||
@@ -603,19 +613,6 @@ func supportedEllipticCurve(curve elliptic.Curve) bool {
|
||||
return curve == elliptic.P256() || curve == elliptic.P384() || curve == elliptic.P521()
|
||||
}
|
||||
|
||||
// ecHash returns the hash to match the given elliptic curve, see RFC
|
||||
// 5656, section 6.2.1
|
||||
func ecHash(curve elliptic.Curve) crypto.Hash {
|
||||
bitSize := curve.Params().BitSize
|
||||
switch {
|
||||
case bitSize <= 256:
|
||||
return crypto.SHA256
|
||||
case bitSize <= 384:
|
||||
return crypto.SHA384
|
||||
}
|
||||
return crypto.SHA512
|
||||
}
|
||||
|
||||
// parseECDSA parses an ECDSA key according to RFC 5656, section 3.1.
|
||||
func parseECDSA(in []byte) (out PublicKey, rest []byte, err error) {
|
||||
var w struct {
|
||||
@@ -671,7 +668,7 @@ func (k *ecdsaPublicKey) Verify(data []byte, sig *Signature) error {
|
||||
return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
|
||||
}
|
||||
|
||||
h := ecHash(k.Curve).New()
|
||||
h := hashFuncs[sig.Format].New()
|
||||
h.Write(data)
|
||||
digest := h.Sum(nil)
|
||||
|
||||
@@ -775,7 +772,7 @@ func (k *skECDSAPublicKey) Verify(data []byte, sig *Signature) error {
|
||||
return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
|
||||
}
|
||||
|
||||
h := ecHash(k.Curve).New()
|
||||
h := hashFuncs[sig.Format].New()
|
||||
h.Write([]byte(k.application))
|
||||
appDigest := h.Sum(nil)
|
||||
|
||||
@@ -874,7 +871,7 @@ func (k *skEd25519PublicKey) Verify(data []byte, sig *Signature) error {
|
||||
return fmt.Errorf("invalid size %d for Ed25519 public key", l)
|
||||
}
|
||||
|
||||
h := sha256.New()
|
||||
h := hashFuncs[sig.Format].New()
|
||||
h.Write([]byte(k.application))
|
||||
appDigest := h.Sum(nil)
|
||||
|
||||
@@ -961,44 +958,20 @@ func (s *wrappedSigner) PublicKey() PublicKey {
|
||||
}
|
||||
|
||||
func (s *wrappedSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
|
||||
return s.SignWithAlgorithm(rand, data, "")
|
||||
return s.SignWithAlgorithm(rand, data, s.pubKey.Type())
|
||||
}
|
||||
|
||||
func (s *wrappedSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
|
||||
var hashFunc crypto.Hash
|
||||
|
||||
if _, ok := s.pubKey.(*rsaPublicKey); ok {
|
||||
// RSA keys support a few hash functions determined by the requested signature algorithm
|
||||
switch algorithm {
|
||||
case "", SigAlgoRSA:
|
||||
algorithm = SigAlgoRSA
|
||||
hashFunc = crypto.SHA1
|
||||
case SigAlgoRSASHA2256:
|
||||
hashFunc = crypto.SHA256
|
||||
case SigAlgoRSASHA2512:
|
||||
hashFunc = crypto.SHA512
|
||||
default:
|
||||
return nil, fmt.Errorf("ssh: unsupported signature algorithm %s", algorithm)
|
||||
}
|
||||
} else {
|
||||
// The only supported algorithm for all other key types is the same as the type of the key
|
||||
if algorithm == "" {
|
||||
algorithm = s.pubKey.Type()
|
||||
} else if algorithm != s.pubKey.Type() {
|
||||
return nil, fmt.Errorf("ssh: unsupported signature algorithm %s", algorithm)
|
||||
}
|
||||
|
||||
switch key := s.pubKey.(type) {
|
||||
case *dsaPublicKey:
|
||||
hashFunc = crypto.SHA1
|
||||
case *ecdsaPublicKey:
|
||||
hashFunc = ecHash(key.Curve)
|
||||
case ed25519PublicKey:
|
||||
default:
|
||||
return nil, fmt.Errorf("ssh: unsupported key type %T", key)
|
||||
}
|
||||
if algorithm == "" {
|
||||
algorithm = s.pubKey.Type()
|
||||
}
|
||||
|
||||
supportedAlgos := algorithmsForKeyFormat(s.pubKey.Type())
|
||||
if !contains(supportedAlgos, algorithm) {
|
||||
return nil, fmt.Errorf("ssh: unsupported signature algorithm %q for key format %q", algorithm, s.pubKey.Type())
|
||||
}
|
||||
|
||||
hashFunc := hashFuncs[algorithm]
|
||||
var digest []byte
|
||||
if hashFunc != 0 {
|
||||
h := hashFunc.New()
|
||||
|
||||
23
vendor/golang.org/x/crypto/ssh/messages.go
generated
vendored
23
vendor/golang.org/x/crypto/ssh/messages.go
generated
vendored
@@ -68,7 +68,7 @@ type kexInitMsg struct {
|
||||
|
||||
// See RFC 4253, section 8.
|
||||
|
||||
// Diffie-Helman
|
||||
// Diffie-Hellman
|
||||
const msgKexDHInit = 30
|
||||
|
||||
type kexDHInitMsg struct {
|
||||
@@ -141,6 +141,14 @@ type serviceAcceptMsg struct {
|
||||
Service string `sshtype:"6"`
|
||||
}
|
||||
|
||||
// See RFC 8308, section 2.3
|
||||
const msgExtInfo = 7
|
||||
|
||||
type extInfoMsg struct {
|
||||
NumExtensions uint32 `sshtype:"7"`
|
||||
Payload []byte `ssh:"rest"`
|
||||
}
|
||||
|
||||
// See RFC 4252, section 5.
|
||||
const msgUserAuthRequest = 50
|
||||
|
||||
@@ -180,11 +188,11 @@ const msgUserAuthInfoRequest = 60
|
||||
const msgUserAuthInfoResponse = 61
|
||||
|
||||
type userAuthInfoRequestMsg struct {
|
||||
User string `sshtype:"60"`
|
||||
Instruction string
|
||||
DeprecatedLanguage string
|
||||
NumPrompts uint32
|
||||
Prompts []byte `ssh:"rest"`
|
||||
Name string `sshtype:"60"`
|
||||
Instruction string
|
||||
Language string
|
||||
NumPrompts uint32
|
||||
Prompts []byte `ssh:"rest"`
|
||||
}
|
||||
|
||||
// See RFC 4254, section 5.1.
|
||||
@@ -782,6 +790,8 @@ func decode(packet []byte) (interface{}, error) {
|
||||
msg = new(serviceRequestMsg)
|
||||
case msgServiceAccept:
|
||||
msg = new(serviceAcceptMsg)
|
||||
case msgExtInfo:
|
||||
msg = new(extInfoMsg)
|
||||
case msgKexInit:
|
||||
msg = new(kexInitMsg)
|
||||
case msgKexDHInit:
|
||||
@@ -843,6 +853,7 @@ var packetTypeNames = map[byte]string{
|
||||
msgDisconnect: "disconnectMsg",
|
||||
msgServiceRequest: "serviceRequestMsg",
|
||||
msgServiceAccept: "serviceAcceptMsg",
|
||||
msgExtInfo: "extInfoMsg",
|
||||
msgKexInit: "kexInitMsg",
|
||||
msgKexDHInit: "kexDHInitMsg",
|
||||
msgKexDHReply: "kexDHReplyMsg",
|
||||
|
||||
71
vendor/golang.org/x/crypto/ssh/server.go
generated
vendored
71
vendor/golang.org/x/crypto/ssh/server.go
generated
vendored
@@ -68,8 +68,16 @@ type ServerConfig struct {
|
||||
|
||||
// NoClientAuth is true if clients are allowed to connect without
|
||||
// authenticating.
|
||||
// To determine NoClientAuth at runtime, set NoClientAuth to true
|
||||
// and the optional NoClientAuthCallback to a non-nil value.
|
||||
NoClientAuth bool
|
||||
|
||||
// NoClientAuthCallback, if non-nil, is called when a user
|
||||
// attempts to authenticate with auth method "none".
|
||||
// NoClientAuth must also be set to true for this be used, or
|
||||
// this func is unused.
|
||||
NoClientAuthCallback func(ConnMetadata) (*Permissions, error)
|
||||
|
||||
// MaxAuthTries specifies the maximum number of authentication attempts
|
||||
// permitted per connection. If set to a negative number, the number of
|
||||
// attempts are unlimited. If set to zero, the number of attempts are limited
|
||||
@@ -120,7 +128,7 @@ type ServerConfig struct {
|
||||
}
|
||||
|
||||
// AddHostKey adds a private key as a host key. If an existing host
|
||||
// key exists with the same algorithm, it is overwritten. Each server
|
||||
// key exists with the same public key format, it is replaced. Each server
|
||||
// config must have at least one host key.
|
||||
func (s *ServerConfig) AddHostKey(key Signer) {
|
||||
for i, k := range s.hostKeys {
|
||||
@@ -212,9 +220,10 @@ func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewCha
|
||||
}
|
||||
|
||||
// signAndMarshal signs the data with the appropriate algorithm,
|
||||
// and serializes the result in SSH wire format.
|
||||
func signAndMarshal(k Signer, rand io.Reader, data []byte) ([]byte, error) {
|
||||
sig, err := k.Sign(rand, data)
|
||||
// and serializes the result in SSH wire format. algo is the negotiate
|
||||
// algorithm and may be a certificate type.
|
||||
func signAndMarshal(k AlgorithmSigner, rand io.Reader, data []byte, algo string) ([]byte, error) {
|
||||
sig, err := k.SignWithAlgorithm(rand, data, underlyingAlgo(algo))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -282,15 +291,6 @@ func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error)
|
||||
return perms, err
|
||||
}
|
||||
|
||||
func isAcceptableAlgo(algo string) bool {
|
||||
switch algo {
|
||||
case KeyAlgoRSA, KeyAlgoDSA, KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521, KeyAlgoSKECDSA256, KeyAlgoED25519, KeyAlgoSKED25519,
|
||||
CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func checkSourceAddress(addr net.Addr, sourceAddrs string) error {
|
||||
if addr == nil {
|
||||
return errors.New("ssh: no address known for client, but source-address match required")
|
||||
@@ -454,7 +454,11 @@ userAuthLoop:
|
||||
switch userAuthReq.Method {
|
||||
case "none":
|
||||
if config.NoClientAuth {
|
||||
authErr = nil
|
||||
if config.NoClientAuthCallback != nil {
|
||||
perms, authErr = config.NoClientAuthCallback(s)
|
||||
} else {
|
||||
authErr = nil
|
||||
}
|
||||
}
|
||||
|
||||
// allow initial attempt of 'none' without penalty
|
||||
@@ -501,7 +505,7 @@ userAuthLoop:
|
||||
return nil, parseError(msgUserAuthRequest)
|
||||
}
|
||||
algo := string(algoBytes)
|
||||
if !isAcceptableAlgo(algo) {
|
||||
if !contains(supportedPubKeyAuthAlgos, underlyingAlgo(algo)) {
|
||||
authErr = fmt.Errorf("ssh: algorithm %q not accepted", algo)
|
||||
break
|
||||
}
|
||||
@@ -553,16 +557,22 @@ userAuthLoop:
|
||||
if !ok || len(payload) > 0 {
|
||||
return nil, parseError(msgUserAuthRequest)
|
||||
}
|
||||
|
||||
// Ensure the public key algo and signature algo
|
||||
// are supported. Compare the private key
|
||||
// algorithm name that corresponds to algo with
|
||||
// sig.Format. This is usually the same, but
|
||||
// for certs, the names differ.
|
||||
if !isAcceptableAlgo(sig.Format) {
|
||||
if !contains(supportedPubKeyAuthAlgos, sig.Format) {
|
||||
authErr = fmt.Errorf("ssh: algorithm %q not accepted", sig.Format)
|
||||
break
|
||||
}
|
||||
signedData := buildDataSignedForAuth(sessionID, userAuthReq, algoBytes, pubKeyData)
|
||||
if underlyingAlgo(algo) != sig.Format {
|
||||
authErr = fmt.Errorf("ssh: signature %q not compatible with selected algorithm %q", sig.Format, algo)
|
||||
break
|
||||
}
|
||||
|
||||
signedData := buildDataSignedForAuth(sessionID, userAuthReq, algo, pubKeyData)
|
||||
|
||||
if err := pubKey.Verify(signedData, sig); err != nil {
|
||||
return nil, err
|
||||
@@ -633,6 +643,30 @@ userAuthLoop:
|
||||
}
|
||||
|
||||
authFailures++
|
||||
if config.MaxAuthTries > 0 && authFailures >= config.MaxAuthTries {
|
||||
// If we have hit the max attempts, don't bother sending the
|
||||
// final SSH_MSG_USERAUTH_FAILURE message, since there are
|
||||
// no more authentication methods which can be attempted,
|
||||
// and this message may cause the client to re-attempt
|
||||
// authentication while we send the disconnect message.
|
||||
// Continue, and trigger the disconnect at the start of
|
||||
// the loop.
|
||||
//
|
||||
// The SSH specification is somewhat confusing about this,
|
||||
// RFC 4252 Section 5.1 requires each authentication failure
|
||||
// be responded to with a respective SSH_MSG_USERAUTH_FAILURE
|
||||
// message, but Section 4 says the server should disconnect
|
||||
// after some number of attempts, but it isn't explicit which
|
||||
// message should take precedence (i.e. should there be a failure
|
||||
// message than a disconnect message, or if we are going to
|
||||
// disconnect, should we only send that message.)
|
||||
//
|
||||
// Either way, OpenSSH disconnects immediately after the last
|
||||
// failed authnetication attempt, and given they are typically
|
||||
// considered the golden implementation it seems reasonable
|
||||
// to match that behavior.
|
||||
continue
|
||||
}
|
||||
|
||||
var failureMsg userAuthFailureMsg
|
||||
if config.PasswordCallback != nil {
|
||||
@@ -670,7 +704,7 @@ type sshClientKeyboardInteractive struct {
|
||||
*connection
|
||||
}
|
||||
|
||||
func (c *sshClientKeyboardInteractive) Challenge(user, instruction string, questions []string, echos []bool) (answers []string, err error) {
|
||||
func (c *sshClientKeyboardInteractive) Challenge(name, instruction string, questions []string, echos []bool) (answers []string, err error) {
|
||||
if len(questions) != len(echos) {
|
||||
return nil, errors.New("ssh: echos and questions must have equal length")
|
||||
}
|
||||
@@ -682,6 +716,7 @@ func (c *sshClientKeyboardInteractive) Challenge(user, instruction string, quest
|
||||
}
|
||||
|
||||
if err := c.transport.writePacket(Marshal(&userAuthInfoRequestMsg{
|
||||
Name: name,
|
||||
Instruction: instruction,
|
||||
NumPrompts: uint32(len(questions)),
|
||||
Prompts: prompts,
|
||||
|
||||
8
vendor/golang.org/x/crypto/ssh/session.go
generated
vendored
8
vendor/golang.org/x/crypto/ssh/session.go
generated
vendored
@@ -13,7 +13,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"sync"
|
||||
)
|
||||
|
||||
@@ -85,6 +84,7 @@ const (
|
||||
IXANY = 39
|
||||
IXOFF = 40
|
||||
IMAXBEL = 41
|
||||
IUTF8 = 42 // RFC 8160
|
||||
ISIG = 50
|
||||
ICANON = 51
|
||||
XCASE = 52
|
||||
@@ -123,7 +123,7 @@ type Session struct {
|
||||
// output and error.
|
||||
//
|
||||
// If either is nil, Run connects the corresponding file
|
||||
// descriptor to an instance of ioutil.Discard. There is a
|
||||
// descriptor to an instance of io.Discard. There is a
|
||||
// fixed amount of buffering that is shared for the two streams.
|
||||
// If either blocks it may eventually cause the remote
|
||||
// command to block.
|
||||
@@ -505,7 +505,7 @@ func (s *Session) stdout() {
|
||||
return
|
||||
}
|
||||
if s.Stdout == nil {
|
||||
s.Stdout = ioutil.Discard
|
||||
s.Stdout = io.Discard
|
||||
}
|
||||
s.copyFuncs = append(s.copyFuncs, func() error {
|
||||
_, err := io.Copy(s.Stdout, s.ch)
|
||||
@@ -518,7 +518,7 @@ func (s *Session) stderr() {
|
||||
return
|
||||
}
|
||||
if s.Stderr == nil {
|
||||
s.Stderr = ioutil.Discard
|
||||
s.Stderr = io.Discard
|
||||
}
|
||||
s.copyFuncs = append(s.copyFuncs, func() error {
|
||||
_, err := io.Copy(s.Stderr, s.ch.Stderr())
|
||||
|
||||
10
vendor/golang.org/x/crypto/ssh/transport.go
generated
vendored
10
vendor/golang.org/x/crypto/ssh/transport.go
generated
vendored
@@ -238,15 +238,19 @@ var (
|
||||
// (to setup server->client keys) or clientKeys (for client->server keys).
|
||||
func newPacketCipher(d direction, algs directionAlgorithms, kex *kexResult) (packetCipher, error) {
|
||||
cipherMode := cipherModes[algs.Cipher]
|
||||
macMode := macModes[algs.MAC]
|
||||
|
||||
iv := make([]byte, cipherMode.ivSize)
|
||||
key := make([]byte, cipherMode.keySize)
|
||||
macKey := make([]byte, macMode.keySize)
|
||||
|
||||
generateKeyMaterial(iv, d.ivTag, kex)
|
||||
generateKeyMaterial(key, d.keyTag, kex)
|
||||
generateKeyMaterial(macKey, d.macKeyTag, kex)
|
||||
|
||||
var macKey []byte
|
||||
if !aeadCiphers[algs.Cipher] {
|
||||
macMode := macModes[algs.MAC]
|
||||
macKey = make([]byte, macMode.keySize)
|
||||
generateKeyMaterial(macKey, d.macKeyTag, kex)
|
||||
}
|
||||
|
||||
return cipherModes[algs.Cipher].create(key, iv, macKey, algs)
|
||||
}
|
||||
|
||||
3
vendor/golang.org/x/net/AUTHORS
generated
vendored
3
vendor/golang.org/x/net/AUTHORS
generated
vendored
@@ -1,3 +0,0 @@
|
||||
# This source code refers to The Go Authors for copyright purposes.
|
||||
# The master list of authors is in the main Go distribution,
|
||||
# visible at http://tip.golang.org/AUTHORS.
|
||||
3
vendor/golang.org/x/net/CONTRIBUTORS
generated
vendored
3
vendor/golang.org/x/net/CONTRIBUTORS
generated
vendored
@@ -1,3 +0,0 @@
|
||||
# This source code was written by the Go contributors.
|
||||
# The master list of contributors is in the main Go distribution,
|
||||
# visible at http://tip.golang.org/CONTRIBUTORS.
|
||||
6
vendor/golang.org/x/net/context/context.go
generated
vendored
6
vendor/golang.org/x/net/context/context.go
generated
vendored
@@ -21,9 +21,9 @@
|
||||
// explicitly to each function that needs it. The Context should be the first
|
||||
// parameter, typically named ctx:
|
||||
//
|
||||
// func DoSomething(ctx context.Context, arg Arg) error {
|
||||
// // ... use ctx ...
|
||||
// }
|
||||
// func DoSomething(ctx context.Context, arg Arg) error {
|
||||
// // ... use ctx ...
|
||||
// }
|
||||
//
|
||||
// Do not pass a nil Context, even if a function permits it. Pass context.TODO
|
||||
// if you are unsure about which Context to use.
|
||||
|
||||
14
vendor/golang.org/x/net/context/go17.go
generated
vendored
14
vendor/golang.org/x/net/context/go17.go
generated
vendored
@@ -32,7 +32,7 @@ var DeadlineExceeded = context.DeadlineExceeded
|
||||
// call cancel as soon as the operations running in this Context complete.
|
||||
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
|
||||
ctx, f := context.WithCancel(parent)
|
||||
return ctx, CancelFunc(f)
|
||||
return ctx, f
|
||||
}
|
||||
|
||||
// WithDeadline returns a copy of the parent context with the deadline adjusted
|
||||
@@ -46,7 +46,7 @@ func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
|
||||
// call cancel as soon as the operations running in this Context complete.
|
||||
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
|
||||
ctx, f := context.WithDeadline(parent, deadline)
|
||||
return ctx, CancelFunc(f)
|
||||
return ctx, f
|
||||
}
|
||||
|
||||
// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
|
||||
@@ -54,11 +54,11 @@ func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) {
|
||||
// Canceling this context releases resources associated with it, so code should
|
||||
// call cancel as soon as the operations running in this Context complete:
|
||||
//
|
||||
// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
|
||||
// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
||||
// defer cancel() // releases resources if slowOperation completes before timeout elapses
|
||||
// return slowOperation(ctx)
|
||||
// }
|
||||
// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
|
||||
// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
||||
// defer cancel() // releases resources if slowOperation completes before timeout elapses
|
||||
// return slowOperation(ctx)
|
||||
// }
|
||||
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
|
||||
return WithDeadline(parent, time.Now().Add(timeout))
|
||||
}
|
||||
|
||||
10
vendor/golang.org/x/net/context/pre_go17.go
generated
vendored
10
vendor/golang.org/x/net/context/pre_go17.go
generated
vendored
@@ -264,11 +264,11 @@ func (c *timerCtx) cancel(removeFromParent bool, err error) {
|
||||
// Canceling this context releases resources associated with it, so code should
|
||||
// call cancel as soon as the operations running in this Context complete:
|
||||
//
|
||||
// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
|
||||
// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
||||
// defer cancel() // releases resources if slowOperation completes before timeout elapses
|
||||
// return slowOperation(ctx)
|
||||
// }
|
||||
// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
|
||||
// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
||||
// defer cancel() // releases resources if slowOperation completes before timeout elapses
|
||||
// return slowOperation(ctx)
|
||||
// }
|
||||
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
|
||||
return WithDeadline(parent, time.Now().Add(timeout))
|
||||
}
|
||||
|
||||
2
vendor/golang.org/x/net/html/parse.go
generated
vendored
2
vendor/golang.org/x/net/html/parse.go
generated
vendored
@@ -734,7 +734,7 @@ func inHeadIM(p *parser) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// 12.2.6.4.5.
|
||||
// Section 12.2.6.4.5.
|
||||
func inHeadNoscriptIM(p *parser) bool {
|
||||
switch p.tok.Type {
|
||||
case DoctypeToken:
|
||||
|
||||
4
vendor/golang.org/x/net/html/render.go
generated
vendored
4
vendor/golang.org/x/net/html/render.go
generated
vendored
@@ -85,7 +85,7 @@ func render1(w writer, n *Node) error {
|
||||
if _, err := w.WriteString("<!--"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.WriteString(n.Data); err != nil {
|
||||
if err := escape(w, n.Data); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.WriteString("-->"); err != nil {
|
||||
@@ -96,7 +96,7 @@ func render1(w writer, n *Node) error {
|
||||
if _, err := w.WriteString("<!DOCTYPE "); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.WriteString(n.Data); err != nil {
|
||||
if err := escape(w, n.Data); err != nil {
|
||||
return err
|
||||
}
|
||||
if n.Attr != nil {
|
||||
|
||||
12
vendor/golang.org/x/net/html/token.go
generated
vendored
12
vendor/golang.org/x/net/html/token.go
generated
vendored
@@ -110,9 +110,9 @@ func (t Token) String() string {
|
||||
case SelfClosingTagToken:
|
||||
return "<" + t.tagString() + "/>"
|
||||
case CommentToken:
|
||||
return "<!--" + t.Data + "-->"
|
||||
return "<!--" + EscapeString(t.Data) + "-->"
|
||||
case DoctypeToken:
|
||||
return "<!DOCTYPE " + t.Data + ">"
|
||||
return "<!DOCTYPE " + EscapeString(t.Data) + ">"
|
||||
}
|
||||
return "Invalid(" + strconv.Itoa(int(t.Type)) + ")"
|
||||
}
|
||||
@@ -605,7 +605,10 @@ func (z *Tokenizer) readComment() {
|
||||
z.data.end = z.data.start
|
||||
}
|
||||
}()
|
||||
for dashCount := 2; ; {
|
||||
|
||||
var dashCount int
|
||||
beginning := true
|
||||
for {
|
||||
c := z.readByte()
|
||||
if z.err != nil {
|
||||
// Ignore up to two dashes at EOF.
|
||||
@@ -620,7 +623,7 @@ func (z *Tokenizer) readComment() {
|
||||
dashCount++
|
||||
continue
|
||||
case '>':
|
||||
if dashCount >= 2 {
|
||||
if dashCount >= 2 || beginning {
|
||||
z.data.end = z.raw.end - len("-->")
|
||||
return
|
||||
}
|
||||
@@ -638,6 +641,7 @@ func (z *Tokenizer) readComment() {
|
||||
}
|
||||
}
|
||||
dashCount = 0
|
||||
beginning = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
54
vendor/golang.org/x/net/http/httpguts/httplex.go
generated
vendored
54
vendor/golang.org/x/net/http/httpguts/httplex.go
generated
vendored
@@ -173,13 +173,15 @@ func tokenEqual(t1, t2 string) bool {
|
||||
|
||||
// isLWS reports whether b is linear white space, according
|
||||
// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
|
||||
// LWS = [CRLF] 1*( SP | HT )
|
||||
//
|
||||
// LWS = [CRLF] 1*( SP | HT )
|
||||
func isLWS(b byte) bool { return b == ' ' || b == '\t' }
|
||||
|
||||
// isCTL reports whether b is a control byte, according
|
||||
// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2
|
||||
// CTL = <any US-ASCII control character
|
||||
// (octets 0 - 31) and DEL (127)>
|
||||
//
|
||||
// CTL = <any US-ASCII control character
|
||||
// (octets 0 - 31) and DEL (127)>
|
||||
func isCTL(b byte) bool {
|
||||
const del = 0x7f // a CTL
|
||||
return b < ' ' || b == del
|
||||
@@ -189,12 +191,13 @@ func isCTL(b byte) bool {
|
||||
// HTTP/2 imposes the additional restriction that uppercase ASCII
|
||||
// letters are not allowed.
|
||||
//
|
||||
// RFC 7230 says:
|
||||
// header-field = field-name ":" OWS field-value OWS
|
||||
// field-name = token
|
||||
// token = 1*tchar
|
||||
// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
|
||||
// "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
|
||||
// RFC 7230 says:
|
||||
//
|
||||
// header-field = field-name ":" OWS field-value OWS
|
||||
// field-name = token
|
||||
// token = 1*tchar
|
||||
// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
|
||||
// "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
|
||||
func ValidHeaderFieldName(v string) bool {
|
||||
if len(v) == 0 {
|
||||
return false
|
||||
@@ -267,27 +270,28 @@ var validHostByte = [256]bool{
|
||||
// ValidHeaderFieldValue reports whether v is a valid "field-value" according to
|
||||
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 :
|
||||
//
|
||||
// message-header = field-name ":" [ field-value ]
|
||||
// field-value = *( field-content | LWS )
|
||||
// field-content = <the OCTETs making up the field-value
|
||||
// and consisting of either *TEXT or combinations
|
||||
// of token, separators, and quoted-string>
|
||||
// message-header = field-name ":" [ field-value ]
|
||||
// field-value = *( field-content | LWS )
|
||||
// field-content = <the OCTETs making up the field-value
|
||||
// and consisting of either *TEXT or combinations
|
||||
// of token, separators, and quoted-string>
|
||||
//
|
||||
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2 :
|
||||
//
|
||||
// TEXT = <any OCTET except CTLs,
|
||||
// but including LWS>
|
||||
// LWS = [CRLF] 1*( SP | HT )
|
||||
// CTL = <any US-ASCII control character
|
||||
// (octets 0 - 31) and DEL (127)>
|
||||
// TEXT = <any OCTET except CTLs,
|
||||
// but including LWS>
|
||||
// LWS = [CRLF] 1*( SP | HT )
|
||||
// CTL = <any US-ASCII control character
|
||||
// (octets 0 - 31) and DEL (127)>
|
||||
//
|
||||
// RFC 7230 says:
|
||||
// field-value = *( field-content / obs-fold )
|
||||
// obj-fold = N/A to http2, and deprecated
|
||||
// field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
|
||||
// field-vchar = VCHAR / obs-text
|
||||
// obs-text = %x80-FF
|
||||
// VCHAR = "any visible [USASCII] character"
|
||||
//
|
||||
// field-value = *( field-content / obs-fold )
|
||||
// obj-fold = N/A to http2, and deprecated
|
||||
// field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
|
||||
// field-vchar = VCHAR / obs-text
|
||||
// obs-text = %x80-FF
|
||||
// VCHAR = "any visible [USASCII] character"
|
||||
//
|
||||
// http2 further says: "Similarly, HTTP/2 allows header field values
|
||||
// that are not valid. While most of the values that can be encoded
|
||||
|
||||
20
vendor/golang.org/x/net/http2/README
generated
vendored
20
vendor/golang.org/x/net/http2/README
generated
vendored
@@ -1,20 +0,0 @@
|
||||
This is a work-in-progress HTTP/2 implementation for Go.
|
||||
|
||||
It will eventually live in the Go standard library and won't require
|
||||
any changes to your code to use. It will just be automatic.
|
||||
|
||||
Status:
|
||||
|
||||
* The server support is pretty good. A few things are missing
|
||||
but are being worked on.
|
||||
* The client work has just started but shares a lot of code
|
||||
is coming along much quicker.
|
||||
|
||||
Docs are at https://godoc.org/golang.org/x/net/http2
|
||||
|
||||
Demo test server at https://http2.golang.org/
|
||||
|
||||
Help & bug reports welcome!
|
||||
|
||||
Contributing: https://golang.org/doc/contribute.html
|
||||
Bugs: https://golang.org/issue/new?title=x/net/http2:+
|
||||
4
vendor/golang.org/x/net/http2/ascii.go
generated
vendored
4
vendor/golang.org/x/net/http2/ascii.go
generated
vendored
@@ -6,6 +6,10 @@ package http2
|
||||
|
||||
import "strings"
|
||||
|
||||
// The HTTP protocols are defined in terms of ASCII, not Unicode. This file
|
||||
// contains helper functions which may use Unicode-aware functions which would
|
||||
// otherwise be unsafe and could introduce vulnerabilities if used improperly.
|
||||
|
||||
// asciiEqualFold is strings.EqualFold, ASCII only. It reports whether s and t
|
||||
// are equal, ASCII-case-insensitively.
|
||||
func asciiEqualFold(s, t string) bool {
|
||||
|
||||
50
vendor/golang.org/x/net/http2/client_conn_pool.go
generated
vendored
50
vendor/golang.org/x/net/http2/client_conn_pool.go
generated
vendored
@@ -16,6 +16,12 @@ import (
|
||||
|
||||
// ClientConnPool manages a pool of HTTP/2 client connections.
|
||||
type ClientConnPool interface {
|
||||
// GetClientConn returns a specific HTTP/2 connection (usually
|
||||
// a TLS-TCP connection) to an HTTP/2 server. On success, the
|
||||
// returned ClientConn accounts for the upcoming RoundTrip
|
||||
// call, so the caller should not omit it. If the caller needs
|
||||
// to, ClientConn.RoundTrip can be called with a bogus
|
||||
// new(http.Request) to release the stream reservation.
|
||||
GetClientConn(req *http.Request, addr string) (*ClientConn, error)
|
||||
MarkDead(*ClientConn)
|
||||
}
|
||||
@@ -42,7 +48,7 @@ type clientConnPool struct {
|
||||
conns map[string][]*ClientConn // key is host:port
|
||||
dialing map[string]*dialCall // currently in-flight dials
|
||||
keys map[*ClientConn][]string
|
||||
addConnCalls map[string]*addConnCall // in-flight addConnIfNeede calls
|
||||
addConnCalls map[string]*addConnCall // in-flight addConnIfNeeded calls
|
||||
}
|
||||
|
||||
func (p *clientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) {
|
||||
@@ -54,28 +60,8 @@ const (
|
||||
noDialOnMiss = false
|
||||
)
|
||||
|
||||
// shouldTraceGetConn reports whether getClientConn should call any
|
||||
// ClientTrace.GetConn hook associated with the http.Request.
|
||||
//
|
||||
// This complexity is needed to avoid double calls of the GetConn hook
|
||||
// during the back-and-forth between net/http and x/net/http2 (when the
|
||||
// net/http.Transport is upgraded to also speak http2), as well as support
|
||||
// the case where x/net/http2 is being used directly.
|
||||
func (p *clientConnPool) shouldTraceGetConn(st clientConnIdleState) bool {
|
||||
// If our Transport wasn't made via ConfigureTransport, always
|
||||
// trace the GetConn hook if provided, because that means the
|
||||
// http2 package is being used directly and it's the one
|
||||
// dialing, as opposed to net/http.
|
||||
if _, ok := p.t.ConnPool.(noDialClientConnPool); !ok {
|
||||
return true
|
||||
}
|
||||
// Otherwise, only use the GetConn hook if this connection has
|
||||
// been used previously for other requests. For fresh
|
||||
// connections, the net/http package does the dialing.
|
||||
return !st.freshConn
|
||||
}
|
||||
|
||||
func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMiss bool) (*ClientConn, error) {
|
||||
// TODO(dneil): Dial a new connection when t.DisableKeepAlives is set?
|
||||
if isConnectionCloseRequest(req) && dialOnMiss {
|
||||
// It gets its own connection.
|
||||
traceGetConn(req, addr)
|
||||
@@ -89,10 +75,14 @@ func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMis
|
||||
for {
|
||||
p.mu.Lock()
|
||||
for _, cc := range p.conns[addr] {
|
||||
if st := cc.idleState(); st.canTakeNewRequest {
|
||||
if p.shouldTraceGetConn(st) {
|
||||
if cc.ReserveNewRequest() {
|
||||
// When a connection is presented to us by the net/http package,
|
||||
// the GetConn hook has already been called.
|
||||
// Don't call it a second time here.
|
||||
if !cc.getConnCalled {
|
||||
traceGetConn(req, addr)
|
||||
}
|
||||
cc.getConnCalled = false
|
||||
p.mu.Unlock()
|
||||
return cc, nil
|
||||
}
|
||||
@@ -108,7 +98,13 @@ func (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMis
|
||||
if shouldRetryDial(call, req) {
|
||||
continue
|
||||
}
|
||||
return call.res, call.err
|
||||
cc, err := call.res, call.err
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if cc.ReserveNewRequest() {
|
||||
return cc, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,7 +139,6 @@ func (p *clientConnPool) getStartDialLocked(ctx context.Context, addr string) *d
|
||||
func (c *dialCall) dial(ctx context.Context, addr string) {
|
||||
const singleUse = false // shared conn
|
||||
c.res, c.err = c.p.t.dialClientConn(ctx, addr, singleUse)
|
||||
close(c.done)
|
||||
|
||||
c.p.mu.Lock()
|
||||
delete(c.p.dialing, addr)
|
||||
@@ -151,6 +146,8 @@ func (c *dialCall) dial(ctx context.Context, addr string) {
|
||||
c.p.addConnLocked(addr, c.res)
|
||||
}
|
||||
c.p.mu.Unlock()
|
||||
|
||||
close(c.done)
|
||||
}
|
||||
|
||||
// addConnIfNeeded makes a NewClientConn out of c if a connection for key doesn't
|
||||
@@ -205,6 +202,7 @@ func (c *addConnCall) run(t *Transport, key string, tc *tls.Conn) {
|
||||
if err != nil {
|
||||
c.err = err
|
||||
} else {
|
||||
cc.getConnCalled = true // already called by the net/http package
|
||||
p.addConnLocked(key, cc)
|
||||
}
|
||||
delete(p.addConnCalls, key)
|
||||
|
||||
14
vendor/golang.org/x/net/http2/errors.go
generated
vendored
14
vendor/golang.org/x/net/http2/errors.go
generated
vendored
@@ -53,6 +53,13 @@ func (e ErrCode) String() string {
|
||||
return fmt.Sprintf("unknown error code 0x%x", uint32(e))
|
||||
}
|
||||
|
||||
func (e ErrCode) stringToken() string {
|
||||
if s, ok := errCodeName[e]; ok {
|
||||
return s
|
||||
}
|
||||
return fmt.Sprintf("ERR_UNKNOWN_%d", uint32(e))
|
||||
}
|
||||
|
||||
// ConnectionError is an error that results in the termination of the
|
||||
// entire connection.
|
||||
type ConnectionError ErrCode
|
||||
@@ -67,6 +74,11 @@ type StreamError struct {
|
||||
Cause error // optional additional detail
|
||||
}
|
||||
|
||||
// errFromPeer is a sentinel error value for StreamError.Cause to
|
||||
// indicate that the StreamError was sent from the peer over the wire
|
||||
// and wasn't locally generated in the Transport.
|
||||
var errFromPeer = errors.New("received from peer")
|
||||
|
||||
func streamError(id uint32, code ErrCode) StreamError {
|
||||
return StreamError{StreamID: id, Code: code}
|
||||
}
|
||||
@@ -124,7 +136,7 @@ func (e headerFieldNameError) Error() string {
|
||||
type headerFieldValueError string
|
||||
|
||||
func (e headerFieldValueError) Error() string {
|
||||
return fmt.Sprintf("invalid header field value %q", string(e))
|
||||
return fmt.Sprintf("invalid header field value for %q", string(e))
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
88
vendor/golang.org/x/net/http2/flow.go
generated
vendored
88
vendor/golang.org/x/net/http2/flow.go
generated
vendored
@@ -6,23 +6,91 @@
|
||||
|
||||
package http2
|
||||
|
||||
// flow is the flow control window's size.
|
||||
type flow struct {
|
||||
// inflowMinRefresh is the minimum number of bytes we'll send for a
|
||||
// flow control window update.
|
||||
const inflowMinRefresh = 4 << 10
|
||||
|
||||
// inflow accounts for an inbound flow control window.
|
||||
// It tracks both the latest window sent to the peer (used for enforcement)
|
||||
// and the accumulated unsent window.
|
||||
type inflow struct {
|
||||
avail int32
|
||||
unsent int32
|
||||
}
|
||||
|
||||
// set sets the initial window.
|
||||
func (f *inflow) init(n int32) {
|
||||
f.avail = n
|
||||
}
|
||||
|
||||
// add adds n bytes to the window, with a maximum window size of max,
|
||||
// indicating that the peer can now send us more data.
|
||||
// For example, the user read from a {Request,Response} body and consumed
|
||||
// some of the buffered data, so the peer can now send more.
|
||||
// It returns the number of bytes to send in a WINDOW_UPDATE frame to the peer.
|
||||
// Window updates are accumulated and sent when the unsent capacity
|
||||
// is at least inflowMinRefresh or will at least double the peer's available window.
|
||||
func (f *inflow) add(n int) (connAdd int32) {
|
||||
if n < 0 {
|
||||
panic("negative update")
|
||||
}
|
||||
unsent := int64(f.unsent) + int64(n)
|
||||
// "A sender MUST NOT allow a flow-control window to exceed 2^31-1 octets."
|
||||
// RFC 7540 Section 6.9.1.
|
||||
const maxWindow = 1<<31 - 1
|
||||
if unsent+int64(f.avail) > maxWindow {
|
||||
panic("flow control update exceeds maximum window size")
|
||||
}
|
||||
f.unsent = int32(unsent)
|
||||
if f.unsent < inflowMinRefresh && f.unsent < f.avail {
|
||||
// If there aren't at least inflowMinRefresh bytes of window to send,
|
||||
// and this update won't at least double the window, buffer the update for later.
|
||||
return 0
|
||||
}
|
||||
f.avail += f.unsent
|
||||
f.unsent = 0
|
||||
return int32(unsent)
|
||||
}
|
||||
|
||||
// take attempts to take n bytes from the peer's flow control window.
|
||||
// It reports whether the window has available capacity.
|
||||
func (f *inflow) take(n uint32) bool {
|
||||
if n > uint32(f.avail) {
|
||||
return false
|
||||
}
|
||||
f.avail -= int32(n)
|
||||
return true
|
||||
}
|
||||
|
||||
// takeInflows attempts to take n bytes from two inflows,
|
||||
// typically connection-level and stream-level flows.
|
||||
// It reports whether both windows have available capacity.
|
||||
func takeInflows(f1, f2 *inflow, n uint32) bool {
|
||||
if n > uint32(f1.avail) || n > uint32(f2.avail) {
|
||||
return false
|
||||
}
|
||||
f1.avail -= int32(n)
|
||||
f2.avail -= int32(n)
|
||||
return true
|
||||
}
|
||||
|
||||
// outflow is the outbound flow control window's size.
|
||||
type outflow struct {
|
||||
_ incomparable
|
||||
|
||||
// n is the number of DATA bytes we're allowed to send.
|
||||
// A flow is kept both on a conn and a per-stream.
|
||||
// An outflow is kept both on a conn and a per-stream.
|
||||
n int32
|
||||
|
||||
// conn points to the shared connection-level flow that is
|
||||
// shared by all streams on that conn. It is nil for the flow
|
||||
// conn points to the shared connection-level outflow that is
|
||||
// shared by all streams on that conn. It is nil for the outflow
|
||||
// that's on the conn directly.
|
||||
conn *flow
|
||||
conn *outflow
|
||||
}
|
||||
|
||||
func (f *flow) setConnFlow(cf *flow) { f.conn = cf }
|
||||
func (f *outflow) setConnFlow(cf *outflow) { f.conn = cf }
|
||||
|
||||
func (f *flow) available() int32 {
|
||||
func (f *outflow) available() int32 {
|
||||
n := f.n
|
||||
if f.conn != nil && f.conn.n < n {
|
||||
n = f.conn.n
|
||||
@@ -30,7 +98,7 @@ func (f *flow) available() int32 {
|
||||
return n
|
||||
}
|
||||
|
||||
func (f *flow) take(n int32) {
|
||||
func (f *outflow) take(n int32) {
|
||||
if n > f.available() {
|
||||
panic("internal error: took too much")
|
||||
}
|
||||
@@ -42,7 +110,7 @@ func (f *flow) take(n int32) {
|
||||
|
||||
// add adds n bytes (positive or negative) to the flow control window.
|
||||
// It returns false if the sum would exceed 2^31-1.
|
||||
func (f *flow) add(n int32) bool {
|
||||
func (f *outflow) add(n int32) bool {
|
||||
sum := f.n + n
|
||||
if (sum > n) == (f.n > 0) {
|
||||
f.n = sum
|
||||
|
||||
87
vendor/golang.org/x/net/http2/frame.go
generated
vendored
87
vendor/golang.org/x/net/http2/frame.go
generated
vendored
@@ -23,7 +23,7 @@ const frameHeaderLen = 9
|
||||
var padZeros = make([]byte, 255) // zeros for padding
|
||||
|
||||
// A FrameType is a registered frame type as defined in
|
||||
// http://http2.github.io/http2-spec/#rfc.section.11.2
|
||||
// https://httpwg.org/specs/rfc7540.html#rfc.section.11.2
|
||||
type FrameType uint8
|
||||
|
||||
const (
|
||||
@@ -122,7 +122,7 @@ var flagName = map[FrameType]map[Flags]string{
|
||||
// a frameParser parses a frame given its FrameHeader and payload
|
||||
// bytes. The length of payload will always equal fh.Length (which
|
||||
// might be 0).
|
||||
type frameParser func(fc *frameCache, fh FrameHeader, payload []byte) (Frame, error)
|
||||
type frameParser func(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error)
|
||||
|
||||
var frameParsers = map[FrameType]frameParser{
|
||||
FrameData: parseDataFrame,
|
||||
@@ -146,7 +146,7 @@ func typeFrameParser(t FrameType) frameParser {
|
||||
|
||||
// A FrameHeader is the 9 byte header of all HTTP/2 frames.
|
||||
//
|
||||
// See http://http2.github.io/http2-spec/#FrameHeader
|
||||
// See https://httpwg.org/specs/rfc7540.html#FrameHeader
|
||||
type FrameHeader struct {
|
||||
valid bool // caller can access []byte fields in the Frame
|
||||
|
||||
@@ -267,6 +267,11 @@ type Framer struct {
|
||||
lastFrame Frame
|
||||
errDetail error
|
||||
|
||||
// countError is a non-nil func that's called on a frame parse
|
||||
// error with some unique error path token. It's initialized
|
||||
// from Transport.CountError or Server.CountError.
|
||||
countError func(errToken string)
|
||||
|
||||
// lastHeaderStream is non-zero if the last frame was an
|
||||
// unfinished HEADERS/CONTINUATION.
|
||||
lastHeaderStream uint32
|
||||
@@ -426,6 +431,7 @@ func NewFramer(w io.Writer, r io.Reader) *Framer {
|
||||
fr := &Framer{
|
||||
w: w,
|
||||
r: r,
|
||||
countError: func(string) {},
|
||||
logReads: logFrameReads,
|
||||
logWrites: logFrameWrites,
|
||||
debugReadLoggerf: log.Printf,
|
||||
@@ -500,7 +506,7 @@ func (fr *Framer) ReadFrame() (Frame, error) {
|
||||
if _, err := io.ReadFull(fr.r, payload); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f, err := typeFrameParser(fh.Type)(fr.frameCache, fh, payload)
|
||||
f, err := typeFrameParser(fh.Type)(fr.frameCache, fh, fr.countError, payload)
|
||||
if err != nil {
|
||||
if ce, ok := err.(connError); ok {
|
||||
return nil, fr.connError(ce.Code, ce.Reason)
|
||||
@@ -569,7 +575,7 @@ func (fr *Framer) checkFrameOrder(f Frame) error {
|
||||
|
||||
// A DataFrame conveys arbitrary, variable-length sequences of octets
|
||||
// associated with a stream.
|
||||
// See http://http2.github.io/http2-spec/#rfc.section.6.1
|
||||
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.1
|
||||
type DataFrame struct {
|
||||
FrameHeader
|
||||
data []byte
|
||||
@@ -588,13 +594,14 @@ func (f *DataFrame) Data() []byte {
|
||||
return f.data
|
||||
}
|
||||
|
||||
func parseDataFrame(fc *frameCache, fh FrameHeader, payload []byte) (Frame, error) {
|
||||
func parseDataFrame(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {
|
||||
if fh.StreamID == 0 {
|
||||
// DATA frames MUST be associated with a stream. If a
|
||||
// DATA frame is received whose stream identifier
|
||||
// field is 0x0, the recipient MUST respond with a
|
||||
// connection error (Section 5.4.1) of type
|
||||
// PROTOCOL_ERROR.
|
||||
countError("frame_data_stream_0")
|
||||
return nil, connError{ErrCodeProtocol, "DATA frame with stream ID 0"}
|
||||
}
|
||||
f := fc.getDataFrame()
|
||||
@@ -605,6 +612,7 @@ func parseDataFrame(fc *frameCache, fh FrameHeader, payload []byte) (Frame, erro
|
||||
var err error
|
||||
payload, padSize, err = readByte(payload)
|
||||
if err != nil {
|
||||
countError("frame_data_pad_byte_short")
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -613,6 +621,7 @@ func parseDataFrame(fc *frameCache, fh FrameHeader, payload []byte) (Frame, erro
|
||||
// length of the frame payload, the recipient MUST
|
||||
// treat this as a connection error.
|
||||
// Filed: https://github.com/http2/http2-spec/issues/610
|
||||
countError("frame_data_pad_too_big")
|
||||
return nil, connError{ErrCodeProtocol, "pad size larger than data payload"}
|
||||
}
|
||||
f.data = payload[:len(payload)-int(padSize)]
|
||||
@@ -689,13 +698,13 @@ func (f *Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []by
|
||||
// endpoints communicate, such as preferences and constraints on peer
|
||||
// behavior.
|
||||
//
|
||||
// See http://http2.github.io/http2-spec/#SETTINGS
|
||||
// See https://httpwg.org/specs/rfc7540.html#SETTINGS
|
||||
type SettingsFrame struct {
|
||||
FrameHeader
|
||||
p []byte
|
||||
}
|
||||
|
||||
func parseSettingsFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
|
||||
func parseSettingsFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
|
||||
if fh.Flags.Has(FlagSettingsAck) && fh.Length > 0 {
|
||||
// When this (ACK 0x1) bit is set, the payload of the
|
||||
// SETTINGS frame MUST be empty. Receipt of a
|
||||
@@ -703,6 +712,7 @@ func parseSettingsFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error)
|
||||
// field value other than 0 MUST be treated as a
|
||||
// connection error (Section 5.4.1) of type
|
||||
// FRAME_SIZE_ERROR.
|
||||
countError("frame_settings_ack_with_length")
|
||||
return nil, ConnectionError(ErrCodeFrameSize)
|
||||
}
|
||||
if fh.StreamID != 0 {
|
||||
@@ -713,14 +723,17 @@ func parseSettingsFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error)
|
||||
// field is anything other than 0x0, the endpoint MUST
|
||||
// respond with a connection error (Section 5.4.1) of
|
||||
// type PROTOCOL_ERROR.
|
||||
countError("frame_settings_has_stream")
|
||||
return nil, ConnectionError(ErrCodeProtocol)
|
||||
}
|
||||
if len(p)%6 != 0 {
|
||||
countError("frame_settings_mod_6")
|
||||
// Expecting even number of 6 byte settings.
|
||||
return nil, ConnectionError(ErrCodeFrameSize)
|
||||
}
|
||||
f := &SettingsFrame{FrameHeader: fh, p: p}
|
||||
if v, ok := f.Value(SettingInitialWindowSize); ok && v > (1<<31)-1 {
|
||||
countError("frame_settings_window_size_too_big")
|
||||
// Values above the maximum flow control window size of 2^31 - 1 MUST
|
||||
// be treated as a connection error (Section 5.4.1) of type
|
||||
// FLOW_CONTROL_ERROR.
|
||||
@@ -824,7 +837,7 @@ func (f *Framer) WriteSettingsAck() error {
|
||||
// A PingFrame is a mechanism for measuring a minimal round trip time
|
||||
// from the sender, as well as determining whether an idle connection
|
||||
// is still functional.
|
||||
// See http://http2.github.io/http2-spec/#rfc.section.6.7
|
||||
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.7
|
||||
type PingFrame struct {
|
||||
FrameHeader
|
||||
Data [8]byte
|
||||
@@ -832,11 +845,13 @@ type PingFrame struct {
|
||||
|
||||
func (f *PingFrame) IsAck() bool { return f.Flags.Has(FlagPingAck) }
|
||||
|
||||
func parsePingFrame(_ *frameCache, fh FrameHeader, payload []byte) (Frame, error) {
|
||||
func parsePingFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {
|
||||
if len(payload) != 8 {
|
||||
countError("frame_ping_length")
|
||||
return nil, ConnectionError(ErrCodeFrameSize)
|
||||
}
|
||||
if fh.StreamID != 0 {
|
||||
countError("frame_ping_has_stream")
|
||||
return nil, ConnectionError(ErrCodeProtocol)
|
||||
}
|
||||
f := &PingFrame{FrameHeader: fh}
|
||||
@@ -855,7 +870,7 @@ func (f *Framer) WritePing(ack bool, data [8]byte) error {
|
||||
}
|
||||
|
||||
// A GoAwayFrame informs the remote peer to stop creating streams on this connection.
|
||||
// See http://http2.github.io/http2-spec/#rfc.section.6.8
|
||||
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.8
|
||||
type GoAwayFrame struct {
|
||||
FrameHeader
|
||||
LastStreamID uint32
|
||||
@@ -872,11 +887,13 @@ func (f *GoAwayFrame) DebugData() []byte {
|
||||
return f.debugData
|
||||
}
|
||||
|
||||
func parseGoAwayFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
|
||||
func parseGoAwayFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
|
||||
if fh.StreamID != 0 {
|
||||
countError("frame_goaway_has_stream")
|
||||
return nil, ConnectionError(ErrCodeProtocol)
|
||||
}
|
||||
if len(p) < 8 {
|
||||
countError("frame_goaway_short")
|
||||
return nil, ConnectionError(ErrCodeFrameSize)
|
||||
}
|
||||
return &GoAwayFrame{
|
||||
@@ -912,19 +929,20 @@ func (f *UnknownFrame) Payload() []byte {
|
||||
return f.p
|
||||
}
|
||||
|
||||
func parseUnknownFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
|
||||
func parseUnknownFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
|
||||
return &UnknownFrame{fh, p}, nil
|
||||
}
|
||||
|
||||
// A WindowUpdateFrame is used to implement flow control.
|
||||
// See http://http2.github.io/http2-spec/#rfc.section.6.9
|
||||
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.9
|
||||
type WindowUpdateFrame struct {
|
||||
FrameHeader
|
||||
Increment uint32 // never read with high bit set
|
||||
}
|
||||
|
||||
func parseWindowUpdateFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
|
||||
func parseWindowUpdateFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
|
||||
if len(p) != 4 {
|
||||
countError("frame_windowupdate_bad_len")
|
||||
return nil, ConnectionError(ErrCodeFrameSize)
|
||||
}
|
||||
inc := binary.BigEndian.Uint32(p[:4]) & 0x7fffffff // mask off high reserved bit
|
||||
@@ -936,8 +954,10 @@ func parseWindowUpdateFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, err
|
||||
// control window MUST be treated as a connection
|
||||
// error (Section 5.4.1).
|
||||
if fh.StreamID == 0 {
|
||||
countError("frame_windowupdate_zero_inc_conn")
|
||||
return nil, ConnectionError(ErrCodeProtocol)
|
||||
}
|
||||
countError("frame_windowupdate_zero_inc_stream")
|
||||
return nil, streamError(fh.StreamID, ErrCodeProtocol)
|
||||
}
|
||||
return &WindowUpdateFrame{
|
||||
@@ -988,7 +1008,7 @@ func (f *HeadersFrame) HasPriority() bool {
|
||||
return f.FrameHeader.Flags.Has(FlagHeadersPriority)
|
||||
}
|
||||
|
||||
func parseHeadersFrame(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err error) {
|
||||
func parseHeadersFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (_ Frame, err error) {
|
||||
hf := &HeadersFrame{
|
||||
FrameHeader: fh,
|
||||
}
|
||||
@@ -997,11 +1017,13 @@ func parseHeadersFrame(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err er
|
||||
// is received whose stream identifier field is 0x0, the recipient MUST
|
||||
// respond with a connection error (Section 5.4.1) of type
|
||||
// PROTOCOL_ERROR.
|
||||
countError("frame_headers_zero_stream")
|
||||
return nil, connError{ErrCodeProtocol, "HEADERS frame with stream ID 0"}
|
||||
}
|
||||
var padLength uint8
|
||||
if fh.Flags.Has(FlagHeadersPadded) {
|
||||
if p, padLength, err = readByte(p); err != nil {
|
||||
countError("frame_headers_pad_short")
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -1009,16 +1031,19 @@ func parseHeadersFrame(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err er
|
||||
var v uint32
|
||||
p, v, err = readUint32(p)
|
||||
if err != nil {
|
||||
countError("frame_headers_prio_short")
|
||||
return nil, err
|
||||
}
|
||||
hf.Priority.StreamDep = v & 0x7fffffff
|
||||
hf.Priority.Exclusive = (v != hf.Priority.StreamDep) // high bit was set
|
||||
p, hf.Priority.Weight, err = readByte(p)
|
||||
if err != nil {
|
||||
countError("frame_headers_prio_weight_short")
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if len(p)-int(padLength) <= 0 {
|
||||
if len(p)-int(padLength) < 0 {
|
||||
countError("frame_headers_pad_too_big")
|
||||
return nil, streamError(fh.StreamID, ErrCodeProtocol)
|
||||
}
|
||||
hf.headerFragBuf = p[:len(p)-int(padLength)]
|
||||
@@ -1098,7 +1123,7 @@ func (f *Framer) WriteHeaders(p HeadersFrameParam) error {
|
||||
}
|
||||
|
||||
// A PriorityFrame specifies the sender-advised priority of a stream.
|
||||
// See http://http2.github.io/http2-spec/#rfc.section.6.3
|
||||
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.3
|
||||
type PriorityFrame struct {
|
||||
FrameHeader
|
||||
PriorityParam
|
||||
@@ -1125,11 +1150,13 @@ func (p PriorityParam) IsZero() bool {
|
||||
return p == PriorityParam{}
|
||||
}
|
||||
|
||||
func parsePriorityFrame(_ *frameCache, fh FrameHeader, payload []byte) (Frame, error) {
|
||||
func parsePriorityFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {
|
||||
if fh.StreamID == 0 {
|
||||
countError("frame_priority_zero_stream")
|
||||
return nil, connError{ErrCodeProtocol, "PRIORITY frame with stream ID 0"}
|
||||
}
|
||||
if len(payload) != 5 {
|
||||
countError("frame_priority_bad_length")
|
||||
return nil, connError{ErrCodeFrameSize, fmt.Sprintf("PRIORITY frame payload size was %d; want 5", len(payload))}
|
||||
}
|
||||
v := binary.BigEndian.Uint32(payload[:4])
|
||||
@@ -1166,17 +1193,19 @@ func (f *Framer) WritePriority(streamID uint32, p PriorityParam) error {
|
||||
}
|
||||
|
||||
// A RSTStreamFrame allows for abnormal termination of a stream.
|
||||
// See http://http2.github.io/http2-spec/#rfc.section.6.4
|
||||
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.4
|
||||
type RSTStreamFrame struct {
|
||||
FrameHeader
|
||||
ErrCode ErrCode
|
||||
}
|
||||
|
||||
func parseRSTStreamFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
|
||||
func parseRSTStreamFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
|
||||
if len(p) != 4 {
|
||||
countError("frame_rststream_bad_len")
|
||||
return nil, ConnectionError(ErrCodeFrameSize)
|
||||
}
|
||||
if fh.StreamID == 0 {
|
||||
countError("frame_rststream_zero_stream")
|
||||
return nil, ConnectionError(ErrCodeProtocol)
|
||||
}
|
||||
return &RSTStreamFrame{fh, ErrCode(binary.BigEndian.Uint32(p[:4]))}, nil
|
||||
@@ -1196,14 +1225,15 @@ func (f *Framer) WriteRSTStream(streamID uint32, code ErrCode) error {
|
||||
}
|
||||
|
||||
// A ContinuationFrame is used to continue a sequence of header block fragments.
|
||||
// See http://http2.github.io/http2-spec/#rfc.section.6.10
|
||||
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.10
|
||||
type ContinuationFrame struct {
|
||||
FrameHeader
|
||||
headerFragBuf []byte
|
||||
}
|
||||
|
||||
func parseContinuationFrame(_ *frameCache, fh FrameHeader, p []byte) (Frame, error) {
|
||||
func parseContinuationFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {
|
||||
if fh.StreamID == 0 {
|
||||
countError("frame_continuation_zero_stream")
|
||||
return nil, connError{ErrCodeProtocol, "CONTINUATION frame with stream ID 0"}
|
||||
}
|
||||
return &ContinuationFrame{fh, p}, nil
|
||||
@@ -1236,7 +1266,7 @@ func (f *Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlock
|
||||
}
|
||||
|
||||
// A PushPromiseFrame is used to initiate a server stream.
|
||||
// See http://http2.github.io/http2-spec/#rfc.section.6.6
|
||||
// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.6
|
||||
type PushPromiseFrame struct {
|
||||
FrameHeader
|
||||
PromiseID uint32
|
||||
@@ -1252,7 +1282,7 @@ func (f *PushPromiseFrame) HeadersEnded() bool {
|
||||
return f.FrameHeader.Flags.Has(FlagPushPromiseEndHeaders)
|
||||
}
|
||||
|
||||
func parsePushPromise(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err error) {
|
||||
func parsePushPromise(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (_ Frame, err error) {
|
||||
pp := &PushPromiseFrame{
|
||||
FrameHeader: fh,
|
||||
}
|
||||
@@ -1263,6 +1293,7 @@ func parsePushPromise(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err err
|
||||
// with. If the stream identifier field specifies the value
|
||||
// 0x0, a recipient MUST respond with a connection error
|
||||
// (Section 5.4.1) of type PROTOCOL_ERROR.
|
||||
countError("frame_pushpromise_zero_stream")
|
||||
return nil, ConnectionError(ErrCodeProtocol)
|
||||
}
|
||||
// The PUSH_PROMISE frame includes optional padding.
|
||||
@@ -1270,18 +1301,21 @@ func parsePushPromise(_ *frameCache, fh FrameHeader, p []byte) (_ Frame, err err
|
||||
var padLength uint8
|
||||
if fh.Flags.Has(FlagPushPromisePadded) {
|
||||
if p, padLength, err = readByte(p); err != nil {
|
||||
countError("frame_pushpromise_pad_short")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
p, pp.PromiseID, err = readUint32(p)
|
||||
if err != nil {
|
||||
countError("frame_pushpromise_promiseid_short")
|
||||
return
|
||||
}
|
||||
pp.PromiseID = pp.PromiseID & (1<<31 - 1)
|
||||
|
||||
if int(padLength) > len(p) {
|
||||
// like the DATA frame, error out if padding is longer than the body.
|
||||
countError("frame_pushpromise_pad_too_big")
|
||||
return nil, ConnectionError(ErrCodeProtocol)
|
||||
}
|
||||
pp.headerFragBuf = p[:len(p)-int(padLength)]
|
||||
@@ -1498,7 +1532,8 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
|
||||
fr.debugReadLoggerf("http2: decoded hpack field %+v", hf)
|
||||
}
|
||||
if !httpguts.ValidHeaderFieldValue(hf.Value) {
|
||||
invalid = headerFieldValueError(hf.Value)
|
||||
// Don't include the value in the error, because it may be sensitive.
|
||||
invalid = headerFieldValueError(hf.Name)
|
||||
}
|
||||
isPseudo := strings.HasPrefix(hf.Name, ":")
|
||||
if isPseudo {
|
||||
|
||||
17
vendor/golang.org/x/net/http2/go118.go
generated
vendored
Normal file
17
vendor/golang.org/x/net/http2/go118.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
package http2
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
)
|
||||
|
||||
func tlsUnderlyingConn(tc *tls.Conn) net.Conn {
|
||||
return tc.NetConn()
|
||||
}
|
||||
18
vendor/golang.org/x/net/http2/headermap.go
generated
vendored
18
vendor/golang.org/x/net/http2/headermap.go
generated
vendored
@@ -27,7 +27,14 @@ func buildCommonHeaderMaps() {
|
||||
"accept-language",
|
||||
"accept-ranges",
|
||||
"age",
|
||||
"access-control-allow-credentials",
|
||||
"access-control-allow-headers",
|
||||
"access-control-allow-methods",
|
||||
"access-control-allow-origin",
|
||||
"access-control-expose-headers",
|
||||
"access-control-max-age",
|
||||
"access-control-request-headers",
|
||||
"access-control-request-method",
|
||||
"allow",
|
||||
"authorization",
|
||||
"cache-control",
|
||||
@@ -53,6 +60,7 @@ func buildCommonHeaderMaps() {
|
||||
"link",
|
||||
"location",
|
||||
"max-forwards",
|
||||
"origin",
|
||||
"proxy-authenticate",
|
||||
"proxy-authorization",
|
||||
"range",
|
||||
@@ -68,6 +76,8 @@ func buildCommonHeaderMaps() {
|
||||
"vary",
|
||||
"via",
|
||||
"www-authenticate",
|
||||
"x-forwarded-for",
|
||||
"x-forwarded-proto",
|
||||
}
|
||||
commonLowerHeader = make(map[string]string, len(common))
|
||||
commonCanonHeader = make(map[string]string, len(common))
|
||||
@@ -85,3 +95,11 @@ func lowerHeader(v string) (lower string, ascii bool) {
|
||||
}
|
||||
return asciiToLower(v)
|
||||
}
|
||||
|
||||
func canonicalHeader(v string) string {
|
||||
buildCommonHeaderMapsOnce()
|
||||
if s, ok := commonCanonHeader[v]; ok {
|
||||
return s
|
||||
}
|
||||
return http.CanonicalHeaderKey(v)
|
||||
}
|
||||
|
||||
7
vendor/golang.org/x/net/http2/hpack/encode.go
generated
vendored
7
vendor/golang.org/x/net/http2/hpack/encode.go
generated
vendored
@@ -116,6 +116,11 @@ func (e *Encoder) SetMaxDynamicTableSize(v uint32) {
|
||||
e.dynTab.setMaxSize(v)
|
||||
}
|
||||
|
||||
// MaxDynamicTableSize returns the current dynamic header table size.
|
||||
func (e *Encoder) MaxDynamicTableSize() (v uint32) {
|
||||
return e.dynTab.maxSize
|
||||
}
|
||||
|
||||
// SetMaxDynamicTableSizeLimit changes the maximum value that can be
|
||||
// specified in SetMaxDynamicTableSize to v. By default, it is set to
|
||||
// 4096, which is the same size of the default dynamic header table
|
||||
@@ -191,7 +196,7 @@ func appendTableSize(dst []byte, v uint32) []byte {
|
||||
// bit prefix, to dst and returns the extended buffer.
|
||||
//
|
||||
// See
|
||||
// http://http2.github.io/http2-spec/compression.html#integer.representation
|
||||
// https://httpwg.org/specs/rfc7541.html#integer.representation
|
||||
func appendVarInt(dst []byte, n byte, i uint64) []byte {
|
||||
k := uint64((1 << n) - 1)
|
||||
if i < k {
|
||||
|
||||
16
vendor/golang.org/x/net/http2/hpack/hpack.go
generated
vendored
16
vendor/golang.org/x/net/http2/hpack/hpack.go
generated
vendored
@@ -59,7 +59,7 @@ func (hf HeaderField) String() string {
|
||||
|
||||
// Size returns the size of an entry per RFC 7541 section 4.1.
|
||||
func (hf HeaderField) Size() uint32 {
|
||||
// http://http2.github.io/http2-spec/compression.html#rfc.section.4.1
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.4.1
|
||||
// "The size of the dynamic table is the sum of the size of
|
||||
// its entries. The size of an entry is the sum of its name's
|
||||
// length in octets (as defined in Section 5.2), its value's
|
||||
@@ -158,7 +158,7 @@ func (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) {
|
||||
}
|
||||
|
||||
type dynamicTable struct {
|
||||
// http://http2.github.io/http2-spec/compression.html#rfc.section.2.3.2
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.2.3.2
|
||||
table headerFieldTable
|
||||
size uint32 // in bytes
|
||||
maxSize uint32 // current maxSize
|
||||
@@ -307,27 +307,27 @@ func (d *Decoder) parseHeaderFieldRepr() error {
|
||||
case b&128 != 0:
|
||||
// Indexed representation.
|
||||
// High bit set?
|
||||
// http://http2.github.io/http2-spec/compression.html#rfc.section.6.1
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.6.1
|
||||
return d.parseFieldIndexed()
|
||||
case b&192 == 64:
|
||||
// 6.2.1 Literal Header Field with Incremental Indexing
|
||||
// 0b10xxxxxx: top two bits are 10
|
||||
// http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.1
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.1
|
||||
return d.parseFieldLiteral(6, indexedTrue)
|
||||
case b&240 == 0:
|
||||
// 6.2.2 Literal Header Field without Indexing
|
||||
// 0b0000xxxx: top four bits are 0000
|
||||
// http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.2
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.2
|
||||
return d.parseFieldLiteral(4, indexedFalse)
|
||||
case b&240 == 16:
|
||||
// 6.2.3 Literal Header Field never Indexed
|
||||
// 0b0001xxxx: top four bits are 0001
|
||||
// http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.3
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.3
|
||||
return d.parseFieldLiteral(4, indexedNever)
|
||||
case b&224 == 32:
|
||||
// 6.3 Dynamic Table Size Update
|
||||
// Top three bits are '001'.
|
||||
// http://http2.github.io/http2-spec/compression.html#rfc.section.6.3
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.6.3
|
||||
return d.parseDynamicTableSizeUpdate()
|
||||
}
|
||||
|
||||
@@ -420,7 +420,7 @@ var errVarintOverflow = DecodingError{errors.New("varint integer overflow")}
|
||||
|
||||
// readVarInt reads an unsigned variable length integer off the
|
||||
// beginning of p. n is the parameter as described in
|
||||
// http://http2.github.io/http2-spec/compression.html#rfc.section.5.1.
|
||||
// https://httpwg.org/specs/rfc7541.html#rfc.section.5.1.
|
||||
//
|
||||
// n must always be between 1 and 8.
|
||||
//
|
||||
|
||||
125
vendor/golang.org/x/net/http2/hpack/huffman.go
generated
vendored
125
vendor/golang.org/x/net/http2/hpack/huffman.go
generated
vendored
@@ -140,50 +140,79 @@ func buildRootHuffmanNode() {
|
||||
panic("unexpected size")
|
||||
}
|
||||
lazyRootHuffmanNode = newInternalNode()
|
||||
for i, code := range huffmanCodes {
|
||||
addDecoderNode(byte(i), code, huffmanCodeLen[i])
|
||||
}
|
||||
}
|
||||
// allocate a leaf node for each of the 256 symbols
|
||||
leaves := new([256]node)
|
||||
|
||||
func addDecoderNode(sym byte, code uint32, codeLen uint8) {
|
||||
cur := lazyRootHuffmanNode
|
||||
for codeLen > 8 {
|
||||
codeLen -= 8
|
||||
i := uint8(code >> codeLen)
|
||||
if cur.children[i] == nil {
|
||||
cur.children[i] = newInternalNode()
|
||||
for sym, code := range huffmanCodes {
|
||||
codeLen := huffmanCodeLen[sym]
|
||||
|
||||
cur := lazyRootHuffmanNode
|
||||
for codeLen > 8 {
|
||||
codeLen -= 8
|
||||
i := uint8(code >> codeLen)
|
||||
if cur.children[i] == nil {
|
||||
cur.children[i] = newInternalNode()
|
||||
}
|
||||
cur = cur.children[i]
|
||||
}
|
||||
shift := 8 - codeLen
|
||||
start, end := int(uint8(code<<shift)), int(1<<shift)
|
||||
|
||||
leaves[sym].sym = byte(sym)
|
||||
leaves[sym].codeLen = codeLen
|
||||
for i := start; i < start+end; i++ {
|
||||
cur.children[i] = &leaves[sym]
|
||||
}
|
||||
cur = cur.children[i]
|
||||
}
|
||||
shift := 8 - codeLen
|
||||
start, end := int(uint8(code<<shift)), int(1<<shift)
|
||||
for i := start; i < start+end; i++ {
|
||||
cur.children[i] = &node{sym: sym, codeLen: codeLen}
|
||||
}
|
||||
}
|
||||
|
||||
// AppendHuffmanString appends s, as encoded in Huffman codes, to dst
|
||||
// and returns the extended buffer.
|
||||
func AppendHuffmanString(dst []byte, s string) []byte {
|
||||
rembits := uint8(8)
|
||||
|
||||
// This relies on the maximum huffman code length being 30 (See tables.go huffmanCodeLen array)
|
||||
// So if a uint64 buffer has less than 32 valid bits can always accommodate another huffmanCode.
|
||||
var (
|
||||
x uint64 // buffer
|
||||
n uint // number valid of bits present in x
|
||||
)
|
||||
for i := 0; i < len(s); i++ {
|
||||
if rembits == 8 {
|
||||
dst = append(dst, 0)
|
||||
c := s[i]
|
||||
n += uint(huffmanCodeLen[c])
|
||||
x <<= huffmanCodeLen[c] % 64
|
||||
x |= uint64(huffmanCodes[c])
|
||||
if n >= 32 {
|
||||
n %= 32 // Normally would be -= 32 but %= 32 informs compiler 0 <= n <= 31 for upcoming shift
|
||||
y := uint32(x >> n) // Compiler doesn't combine memory writes if y isn't uint32
|
||||
dst = append(dst, byte(y>>24), byte(y>>16), byte(y>>8), byte(y))
|
||||
}
|
||||
dst, rembits = appendByteToHuffmanCode(dst, rembits, s[i])
|
||||
}
|
||||
|
||||
if rembits < 8 {
|
||||
// special EOS symbol
|
||||
code := uint32(0x3fffffff)
|
||||
nbits := uint8(30)
|
||||
|
||||
t := uint8(code >> (nbits - rembits))
|
||||
dst[len(dst)-1] |= t
|
||||
// Add padding bits if necessary
|
||||
if over := n % 8; over > 0 {
|
||||
const (
|
||||
eosCode = 0x3fffffff
|
||||
eosNBits = 30
|
||||
eosPadByte = eosCode >> (eosNBits - 8)
|
||||
)
|
||||
pad := 8 - over
|
||||
x = (x << pad) | (eosPadByte >> over)
|
||||
n += pad // 8 now divides into n exactly
|
||||
}
|
||||
|
||||
return dst
|
||||
// n in (0, 8, 16, 24, 32)
|
||||
switch n / 8 {
|
||||
case 0:
|
||||
return dst
|
||||
case 1:
|
||||
return append(dst, byte(x))
|
||||
case 2:
|
||||
y := uint16(x)
|
||||
return append(dst, byte(y>>8), byte(y))
|
||||
case 3:
|
||||
y := uint16(x >> 8)
|
||||
return append(dst, byte(y>>8), byte(y), byte(x))
|
||||
}
|
||||
// case 4:
|
||||
y := uint32(x)
|
||||
return append(dst, byte(y>>24), byte(y>>16), byte(y>>8), byte(y))
|
||||
}
|
||||
|
||||
// HuffmanEncodeLength returns the number of bytes required to encode
|
||||
@@ -195,35 +224,3 @@ func HuffmanEncodeLength(s string) uint64 {
|
||||
}
|
||||
return (n + 7) / 8
|
||||
}
|
||||
|
||||
// appendByteToHuffmanCode appends Huffman code for c to dst and
|
||||
// returns the extended buffer and the remaining bits in the last
|
||||
// element. The appending is not byte aligned and the remaining bits
|
||||
// in the last element of dst is given in rembits.
|
||||
func appendByteToHuffmanCode(dst []byte, rembits uint8, c byte) ([]byte, uint8) {
|
||||
code := huffmanCodes[c]
|
||||
nbits := huffmanCodeLen[c]
|
||||
|
||||
for {
|
||||
if rembits > nbits {
|
||||
t := uint8(code << (rembits - nbits))
|
||||
dst[len(dst)-1] |= t
|
||||
rembits -= nbits
|
||||
break
|
||||
}
|
||||
|
||||
t := uint8(code >> (nbits - rembits))
|
||||
dst[len(dst)-1] |= t
|
||||
|
||||
nbits -= rembits
|
||||
rembits = 8
|
||||
|
||||
if nbits == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
dst = append(dst, 0)
|
||||
}
|
||||
|
||||
return dst, rembits
|
||||
}
|
||||
|
||||
188
vendor/golang.org/x/net/http2/hpack/static_table.go
generated
vendored
Normal file
188
vendor/golang.org/x/net/http2/hpack/static_table.go
generated
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
// go generate gen.go
|
||||
// Code generated by the command above; DO NOT EDIT.
|
||||
|
||||
package hpack
|
||||
|
||||
var staticTable = &headerFieldTable{
|
||||
evictCount: 0,
|
||||
byName: map[string]uint64{
|
||||
":authority": 1,
|
||||
":method": 3,
|
||||
":path": 5,
|
||||
":scheme": 7,
|
||||
":status": 14,
|
||||
"accept-charset": 15,
|
||||
"accept-encoding": 16,
|
||||
"accept-language": 17,
|
||||
"accept-ranges": 18,
|
||||
"accept": 19,
|
||||
"access-control-allow-origin": 20,
|
||||
"age": 21,
|
||||
"allow": 22,
|
||||
"authorization": 23,
|
||||
"cache-control": 24,
|
||||
"content-disposition": 25,
|
||||
"content-encoding": 26,
|
||||
"content-language": 27,
|
||||
"content-length": 28,
|
||||
"content-location": 29,
|
||||
"content-range": 30,
|
||||
"content-type": 31,
|
||||
"cookie": 32,
|
||||
"date": 33,
|
||||
"etag": 34,
|
||||
"expect": 35,
|
||||
"expires": 36,
|
||||
"from": 37,
|
||||
"host": 38,
|
||||
"if-match": 39,
|
||||
"if-modified-since": 40,
|
||||
"if-none-match": 41,
|
||||
"if-range": 42,
|
||||
"if-unmodified-since": 43,
|
||||
"last-modified": 44,
|
||||
"link": 45,
|
||||
"location": 46,
|
||||
"max-forwards": 47,
|
||||
"proxy-authenticate": 48,
|
||||
"proxy-authorization": 49,
|
||||
"range": 50,
|
||||
"referer": 51,
|
||||
"refresh": 52,
|
||||
"retry-after": 53,
|
||||
"server": 54,
|
||||
"set-cookie": 55,
|
||||
"strict-transport-security": 56,
|
||||
"transfer-encoding": 57,
|
||||
"user-agent": 58,
|
||||
"vary": 59,
|
||||
"via": 60,
|
||||
"www-authenticate": 61,
|
||||
},
|
||||
byNameValue: map[pairNameValue]uint64{
|
||||
{name: ":authority", value: ""}: 1,
|
||||
{name: ":method", value: "GET"}: 2,
|
||||
{name: ":method", value: "POST"}: 3,
|
||||
{name: ":path", value: "/"}: 4,
|
||||
{name: ":path", value: "/index.html"}: 5,
|
||||
{name: ":scheme", value: "http"}: 6,
|
||||
{name: ":scheme", value: "https"}: 7,
|
||||
{name: ":status", value: "200"}: 8,
|
||||
{name: ":status", value: "204"}: 9,
|
||||
{name: ":status", value: "206"}: 10,
|
||||
{name: ":status", value: "304"}: 11,
|
||||
{name: ":status", value: "400"}: 12,
|
||||
{name: ":status", value: "404"}: 13,
|
||||
{name: ":status", value: "500"}: 14,
|
||||
{name: "accept-charset", value: ""}: 15,
|
||||
{name: "accept-encoding", value: "gzip, deflate"}: 16,
|
||||
{name: "accept-language", value: ""}: 17,
|
||||
{name: "accept-ranges", value: ""}: 18,
|
||||
{name: "accept", value: ""}: 19,
|
||||
{name: "access-control-allow-origin", value: ""}: 20,
|
||||
{name: "age", value: ""}: 21,
|
||||
{name: "allow", value: ""}: 22,
|
||||
{name: "authorization", value: ""}: 23,
|
||||
{name: "cache-control", value: ""}: 24,
|
||||
{name: "content-disposition", value: ""}: 25,
|
||||
{name: "content-encoding", value: ""}: 26,
|
||||
{name: "content-language", value: ""}: 27,
|
||||
{name: "content-length", value: ""}: 28,
|
||||
{name: "content-location", value: ""}: 29,
|
||||
{name: "content-range", value: ""}: 30,
|
||||
{name: "content-type", value: ""}: 31,
|
||||
{name: "cookie", value: ""}: 32,
|
||||
{name: "date", value: ""}: 33,
|
||||
{name: "etag", value: ""}: 34,
|
||||
{name: "expect", value: ""}: 35,
|
||||
{name: "expires", value: ""}: 36,
|
||||
{name: "from", value: ""}: 37,
|
||||
{name: "host", value: ""}: 38,
|
||||
{name: "if-match", value: ""}: 39,
|
||||
{name: "if-modified-since", value: ""}: 40,
|
||||
{name: "if-none-match", value: ""}: 41,
|
||||
{name: "if-range", value: ""}: 42,
|
||||
{name: "if-unmodified-since", value: ""}: 43,
|
||||
{name: "last-modified", value: ""}: 44,
|
||||
{name: "link", value: ""}: 45,
|
||||
{name: "location", value: ""}: 46,
|
||||
{name: "max-forwards", value: ""}: 47,
|
||||
{name: "proxy-authenticate", value: ""}: 48,
|
||||
{name: "proxy-authorization", value: ""}: 49,
|
||||
{name: "range", value: ""}: 50,
|
||||
{name: "referer", value: ""}: 51,
|
||||
{name: "refresh", value: ""}: 52,
|
||||
{name: "retry-after", value: ""}: 53,
|
||||
{name: "server", value: ""}: 54,
|
||||
{name: "set-cookie", value: ""}: 55,
|
||||
{name: "strict-transport-security", value: ""}: 56,
|
||||
{name: "transfer-encoding", value: ""}: 57,
|
||||
{name: "user-agent", value: ""}: 58,
|
||||
{name: "vary", value: ""}: 59,
|
||||
{name: "via", value: ""}: 60,
|
||||
{name: "www-authenticate", value: ""}: 61,
|
||||
},
|
||||
ents: []HeaderField{
|
||||
{Name: ":authority", Value: "", Sensitive: false},
|
||||
{Name: ":method", Value: "GET", Sensitive: false},
|
||||
{Name: ":method", Value: "POST", Sensitive: false},
|
||||
{Name: ":path", Value: "/", Sensitive: false},
|
||||
{Name: ":path", Value: "/index.html", Sensitive: false},
|
||||
{Name: ":scheme", Value: "http", Sensitive: false},
|
||||
{Name: ":scheme", Value: "https", Sensitive: false},
|
||||
{Name: ":status", Value: "200", Sensitive: false},
|
||||
{Name: ":status", Value: "204", Sensitive: false},
|
||||
{Name: ":status", Value: "206", Sensitive: false},
|
||||
{Name: ":status", Value: "304", Sensitive: false},
|
||||
{Name: ":status", Value: "400", Sensitive: false},
|
||||
{Name: ":status", Value: "404", Sensitive: false},
|
||||
{Name: ":status", Value: "500", Sensitive: false},
|
||||
{Name: "accept-charset", Value: "", Sensitive: false},
|
||||
{Name: "accept-encoding", Value: "gzip, deflate", Sensitive: false},
|
||||
{Name: "accept-language", Value: "", Sensitive: false},
|
||||
{Name: "accept-ranges", Value: "", Sensitive: false},
|
||||
{Name: "accept", Value: "", Sensitive: false},
|
||||
{Name: "access-control-allow-origin", Value: "", Sensitive: false},
|
||||
{Name: "age", Value: "", Sensitive: false},
|
||||
{Name: "allow", Value: "", Sensitive: false},
|
||||
{Name: "authorization", Value: "", Sensitive: false},
|
||||
{Name: "cache-control", Value: "", Sensitive: false},
|
||||
{Name: "content-disposition", Value: "", Sensitive: false},
|
||||
{Name: "content-encoding", Value: "", Sensitive: false},
|
||||
{Name: "content-language", Value: "", Sensitive: false},
|
||||
{Name: "content-length", Value: "", Sensitive: false},
|
||||
{Name: "content-location", Value: "", Sensitive: false},
|
||||
{Name: "content-range", Value: "", Sensitive: false},
|
||||
{Name: "content-type", Value: "", Sensitive: false},
|
||||
{Name: "cookie", Value: "", Sensitive: false},
|
||||
{Name: "date", Value: "", Sensitive: false},
|
||||
{Name: "etag", Value: "", Sensitive: false},
|
||||
{Name: "expect", Value: "", Sensitive: false},
|
||||
{Name: "expires", Value: "", Sensitive: false},
|
||||
{Name: "from", Value: "", Sensitive: false},
|
||||
{Name: "host", Value: "", Sensitive: false},
|
||||
{Name: "if-match", Value: "", Sensitive: false},
|
||||
{Name: "if-modified-since", Value: "", Sensitive: false},
|
||||
{Name: "if-none-match", Value: "", Sensitive: false},
|
||||
{Name: "if-range", Value: "", Sensitive: false},
|
||||
{Name: "if-unmodified-since", Value: "", Sensitive: false},
|
||||
{Name: "last-modified", Value: "", Sensitive: false},
|
||||
{Name: "link", Value: "", Sensitive: false},
|
||||
{Name: "location", Value: "", Sensitive: false},
|
||||
{Name: "max-forwards", Value: "", Sensitive: false},
|
||||
{Name: "proxy-authenticate", Value: "", Sensitive: false},
|
||||
{Name: "proxy-authorization", Value: "", Sensitive: false},
|
||||
{Name: "range", Value: "", Sensitive: false},
|
||||
{Name: "referer", Value: "", Sensitive: false},
|
||||
{Name: "refresh", Value: "", Sensitive: false},
|
||||
{Name: "retry-after", Value: "", Sensitive: false},
|
||||
{Name: "server", Value: "", Sensitive: false},
|
||||
{Name: "set-cookie", Value: "", Sensitive: false},
|
||||
{Name: "strict-transport-security", Value: "", Sensitive: false},
|
||||
{Name: "transfer-encoding", Value: "", Sensitive: false},
|
||||
{Name: "user-agent", Value: "", Sensitive: false},
|
||||
{Name: "vary", Value: "", Sensitive: false},
|
||||
{Name: "via", Value: "", Sensitive: false},
|
||||
{Name: "www-authenticate", Value: "", Sensitive: false},
|
||||
},
|
||||
}
|
||||
78
vendor/golang.org/x/net/http2/hpack/tables.go
generated
vendored
78
vendor/golang.org/x/net/http2/hpack/tables.go
generated
vendored
@@ -96,8 +96,7 @@ func (t *headerFieldTable) evictOldest(n int) {
|
||||
// meaning t.ents is reversed for dynamic tables. Hence, when t is a dynamic
|
||||
// table, the return value i actually refers to the entry t.ents[t.len()-i].
|
||||
//
|
||||
// All tables are assumed to be a dynamic tables except for the global
|
||||
// staticTable pointer.
|
||||
// All tables are assumed to be a dynamic tables except for the global staticTable.
|
||||
//
|
||||
// See Section 2.3.3.
|
||||
func (t *headerFieldTable) search(f HeaderField) (i uint64, nameValueMatch bool) {
|
||||
@@ -125,81 +124,6 @@ func (t *headerFieldTable) idToIndex(id uint64) uint64 {
|
||||
return k + 1
|
||||
}
|
||||
|
||||
// http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-B
|
||||
var staticTable = newStaticTable()
|
||||
var staticTableEntries = [...]HeaderField{
|
||||
{Name: ":authority"},
|
||||
{Name: ":method", Value: "GET"},
|
||||
{Name: ":method", Value: "POST"},
|
||||
{Name: ":path", Value: "/"},
|
||||
{Name: ":path", Value: "/index.html"},
|
||||
{Name: ":scheme", Value: "http"},
|
||||
{Name: ":scheme", Value: "https"},
|
||||
{Name: ":status", Value: "200"},
|
||||
{Name: ":status", Value: "204"},
|
||||
{Name: ":status", Value: "206"},
|
||||
{Name: ":status", Value: "304"},
|
||||
{Name: ":status", Value: "400"},
|
||||
{Name: ":status", Value: "404"},
|
||||
{Name: ":status", Value: "500"},
|
||||
{Name: "accept-charset"},
|
||||
{Name: "accept-encoding", Value: "gzip, deflate"},
|
||||
{Name: "accept-language"},
|
||||
{Name: "accept-ranges"},
|
||||
{Name: "accept"},
|
||||
{Name: "access-control-allow-origin"},
|
||||
{Name: "age"},
|
||||
{Name: "allow"},
|
||||
{Name: "authorization"},
|
||||
{Name: "cache-control"},
|
||||
{Name: "content-disposition"},
|
||||
{Name: "content-encoding"},
|
||||
{Name: "content-language"},
|
||||
{Name: "content-length"},
|
||||
{Name: "content-location"},
|
||||
{Name: "content-range"},
|
||||
{Name: "content-type"},
|
||||
{Name: "cookie"},
|
||||
{Name: "date"},
|
||||
{Name: "etag"},
|
||||
{Name: "expect"},
|
||||
{Name: "expires"},
|
||||
{Name: "from"},
|
||||
{Name: "host"},
|
||||
{Name: "if-match"},
|
||||
{Name: "if-modified-since"},
|
||||
{Name: "if-none-match"},
|
||||
{Name: "if-range"},
|
||||
{Name: "if-unmodified-since"},
|
||||
{Name: "last-modified"},
|
||||
{Name: "link"},
|
||||
{Name: "location"},
|
||||
{Name: "max-forwards"},
|
||||
{Name: "proxy-authenticate"},
|
||||
{Name: "proxy-authorization"},
|
||||
{Name: "range"},
|
||||
{Name: "referer"},
|
||||
{Name: "refresh"},
|
||||
{Name: "retry-after"},
|
||||
{Name: "server"},
|
||||
{Name: "set-cookie"},
|
||||
{Name: "strict-transport-security"},
|
||||
{Name: "transfer-encoding"},
|
||||
{Name: "user-agent"},
|
||||
{Name: "vary"},
|
||||
{Name: "via"},
|
||||
{Name: "www-authenticate"},
|
||||
}
|
||||
|
||||
func newStaticTable() *headerFieldTable {
|
||||
t := &headerFieldTable{}
|
||||
t.init()
|
||||
for _, e := range staticTableEntries[:] {
|
||||
t.addEntry(e)
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
var huffmanCodes = [256]uint32{
|
||||
0x1ff8,
|
||||
0x7fffd8,
|
||||
|
||||
22
vendor/golang.org/x/net/http2/http2.go
generated
vendored
22
vendor/golang.org/x/net/http2/http2.go
generated
vendored
@@ -13,7 +13,6 @@
|
||||
// See https://http2.github.io/ for more information on HTTP/2.
|
||||
//
|
||||
// See https://http2.golang.org/ for a test server running this code.
|
||||
//
|
||||
package http2 // import "golang.org/x/net/http2"
|
||||
|
||||
import (
|
||||
@@ -56,14 +55,14 @@ const (
|
||||
ClientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
|
||||
|
||||
// SETTINGS_MAX_FRAME_SIZE default
|
||||
// http://http2.github.io/http2-spec/#rfc.section.6.5.2
|
||||
// https://httpwg.org/specs/rfc7540.html#rfc.section.6.5.2
|
||||
initialMaxFrameSize = 16384
|
||||
|
||||
// NextProtoTLS is the NPN/ALPN protocol negotiated during
|
||||
// HTTP/2's TLS setup.
|
||||
NextProtoTLS = "h2"
|
||||
|
||||
// http://http2.github.io/http2-spec/#SettingValues
|
||||
// https://httpwg.org/specs/rfc7540.html#SettingValues
|
||||
initialHeaderTableSize = 4096
|
||||
|
||||
initialWindowSize = 65535 // 6.9.2 Initial Flow Control Window Size
|
||||
@@ -112,7 +111,7 @@ func (st streamState) String() string {
|
||||
// Setting is a setting parameter: which setting it is, and its value.
|
||||
type Setting struct {
|
||||
// ID is which setting is being set.
|
||||
// See http://http2.github.io/http2-spec/#SettingValues
|
||||
// See https://httpwg.org/specs/rfc7540.html#SettingFormat
|
||||
ID SettingID
|
||||
|
||||
// Val is the value.
|
||||
@@ -144,7 +143,7 @@ func (s Setting) Valid() error {
|
||||
}
|
||||
|
||||
// A SettingID is an HTTP/2 setting as defined in
|
||||
// http://http2.github.io/http2-spec/#iana-settings
|
||||
// https://httpwg.org/specs/rfc7540.html#iana-settings
|
||||
type SettingID uint16
|
||||
|
||||
const (
|
||||
@@ -176,10 +175,11 @@ func (s SettingID) String() string {
|
||||
// name (key). See httpguts.ValidHeaderName for the base rules.
|
||||
//
|
||||
// Further, http2 says:
|
||||
// "Just as in HTTP/1.x, header field names are strings of ASCII
|
||||
// characters that are compared in a case-insensitive
|
||||
// fashion. However, header field names MUST be converted to
|
||||
// lowercase prior to their encoding in HTTP/2. "
|
||||
//
|
||||
// "Just as in HTTP/1.x, header field names are strings of ASCII
|
||||
// characters that are compared in a case-insensitive
|
||||
// fashion. However, header field names MUST be converted to
|
||||
// lowercase prior to their encoding in HTTP/2. "
|
||||
func validWireHeaderFieldName(v string) bool {
|
||||
if len(v) == 0 {
|
||||
return false
|
||||
@@ -365,8 +365,8 @@ func (s *sorter) SortStrings(ss []string) {
|
||||
// validPseudoPath reports whether v is a valid :path pseudo-header
|
||||
// value. It must be either:
|
||||
//
|
||||
// *) a non-empty string starting with '/'
|
||||
// *) the string '*', for OPTIONS requests.
|
||||
// - a non-empty string starting with '/'
|
||||
// - the string '*', for OPTIONS requests.
|
||||
//
|
||||
// For now this is only used a quick check for deciding when to clean
|
||||
// up Opaque URLs before sending requests from the Transport.
|
||||
|
||||
17
vendor/golang.org/x/net/http2/not_go118.go
generated
vendored
Normal file
17
vendor/golang.org/x/net/http2/not_go118.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
//go:build !go1.18
|
||||
// +build !go1.18
|
||||
|
||||
package http2
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
)
|
||||
|
||||
func tlsUnderlyingConn(tc *tls.Conn) net.Conn {
|
||||
return nil
|
||||
}
|
||||
11
vendor/golang.org/x/net/http2/pipe.go
generated
vendored
11
vendor/golang.org/x/net/http2/pipe.go
generated
vendored
@@ -30,6 +30,17 @@ type pipeBuffer interface {
|
||||
io.Reader
|
||||
}
|
||||
|
||||
// setBuffer initializes the pipe buffer.
|
||||
// It has no effect if the pipe is already closed.
|
||||
func (p *pipe) setBuffer(b pipeBuffer) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
if p.err != nil || p.breakErr != nil {
|
||||
return
|
||||
}
|
||||
p.b = b
|
||||
}
|
||||
|
||||
func (p *pipe) Len() int {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
|
||||
564
vendor/golang.org/x/net/http2/server.go
generated
vendored
564
vendor/golang.org/x/net/http2/server.go
generated
vendored
File diff suppressed because it is too large
Load Diff
1890
vendor/golang.org/x/net/http2/transport.go
generated
vendored
1890
vendor/golang.org/x/net/http2/transport.go
generated
vendored
File diff suppressed because it is too large
Load Diff
4
vendor/golang.org/x/net/http2/writesched.go
generated
vendored
4
vendor/golang.org/x/net/http2/writesched.go
generated
vendored
@@ -32,7 +32,8 @@ type WriteScheduler interface {
|
||||
|
||||
// Pop dequeues the next frame to write. Returns false if no frames can
|
||||
// be written. Frames with a given wr.StreamID() are Pop'd in the same
|
||||
// order they are Push'd. No frames should be discarded except by CloseStream.
|
||||
// order they are Push'd, except RST_STREAM frames. No frames should be
|
||||
// discarded except by CloseStream.
|
||||
Pop() (wr FrameWriteRequest, ok bool)
|
||||
}
|
||||
|
||||
@@ -52,6 +53,7 @@ type FrameWriteRequest struct {
|
||||
|
||||
// stream is the stream on which this frame will be written.
|
||||
// nil for non-stream frames like PING and SETTINGS.
|
||||
// nil for RST_STREAM streams, which use the StreamError.StreamID field instead.
|
||||
stream *stream
|
||||
|
||||
// done, if non-nil, must be a buffered channel with space for
|
||||
|
||||
9
vendor/golang.org/x/net/http2/writesched_priority.go
generated
vendored
9
vendor/golang.org/x/net/http2/writesched_priority.go
generated
vendored
@@ -383,16 +383,15 @@ func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority Priorit
|
||||
|
||||
func (ws *priorityWriteScheduler) Push(wr FrameWriteRequest) {
|
||||
var n *priorityNode
|
||||
if id := wr.StreamID(); id == 0 {
|
||||
if wr.isControl() {
|
||||
n = &ws.root
|
||||
} else {
|
||||
id := wr.StreamID()
|
||||
n = ws.nodes[id]
|
||||
if n == nil {
|
||||
// id is an idle or closed stream. wr should not be a HEADERS or
|
||||
// DATA frame. However, wr can be a RST_STREAM. In this case, we
|
||||
// push wr onto the root, rather than creating a new priorityNode,
|
||||
// since RST_STREAM is tiny and the stream's priority is unknown
|
||||
// anyway. See issue #17919.
|
||||
// DATA frame. In other case, we push wr onto the root, rather
|
||||
// than creating a new priorityNode.
|
||||
if wr.DataSize() > 0 {
|
||||
panic("add DATA on non-open stream")
|
||||
}
|
||||
|
||||
6
vendor/golang.org/x/net/http2/writesched_random.go
generated
vendored
6
vendor/golang.org/x/net/http2/writesched_random.go
generated
vendored
@@ -45,11 +45,11 @@ func (ws *randomWriteScheduler) AdjustStream(streamID uint32, priority PriorityP
|
||||
}
|
||||
|
||||
func (ws *randomWriteScheduler) Push(wr FrameWriteRequest) {
|
||||
id := wr.StreamID()
|
||||
if id == 0 {
|
||||
if wr.isControl() {
|
||||
ws.zero.push(wr)
|
||||
return
|
||||
}
|
||||
id := wr.StreamID()
|
||||
q, ok := ws.sq[id]
|
||||
if !ok {
|
||||
q = ws.queuePool.get()
|
||||
@@ -59,7 +59,7 @@ func (ws *randomWriteScheduler) Push(wr FrameWriteRequest) {
|
||||
}
|
||||
|
||||
func (ws *randomWriteScheduler) Pop() (FrameWriteRequest, bool) {
|
||||
// Control frames first.
|
||||
// Control and RST_STREAM frames first.
|
||||
if !ws.zero.empty() {
|
||||
return ws.zero.shift(), true
|
||||
}
|
||||
|
||||
14
vendor/golang.org/x/net/idna/go118.go
generated
vendored
Normal file
14
vendor/golang.org/x/net/idna/go118.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// Copyright 2021 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.
|
||||
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
package idna
|
||||
|
||||
// Transitional processing is disabled by default in Go 1.18.
|
||||
// https://golang.org/issue/47510
|
||||
const transitionalLookup = false
|
||||
6
vendor/golang.org/x/net/idna/idna10.0.0.go
generated
vendored
6
vendor/golang.org/x/net/idna/idna10.0.0.go
generated
vendored
@@ -59,10 +59,10 @@ type Option func(*options)
|
||||
// Transitional sets a Profile to use the Transitional mapping as defined in UTS
|
||||
// #46. This will cause, for example, "ß" to be mapped to "ss". Using the
|
||||
// transitional mapping provides a compromise between IDNA2003 and IDNA2008
|
||||
// compatibility. It is used by most browsers when resolving domain names. This
|
||||
// compatibility. It is used by some browsers when resolving domain names. This
|
||||
// option is only meaningful if combined with MapForLookup.
|
||||
func Transitional(transitional bool) Option {
|
||||
return func(o *options) { o.transitional = true }
|
||||
return func(o *options) { o.transitional = transitional }
|
||||
}
|
||||
|
||||
// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
|
||||
@@ -284,7 +284,7 @@ var (
|
||||
|
||||
punycode = &Profile{}
|
||||
lookup = &Profile{options{
|
||||
transitional: true,
|
||||
transitional: transitionalLookup,
|
||||
useSTD3Rules: true,
|
||||
checkHyphens: true,
|
||||
checkJoiners: true,
|
||||
|
||||
4
vendor/golang.org/x/net/idna/idna9.0.0.go
generated
vendored
4
vendor/golang.org/x/net/idna/idna9.0.0.go
generated
vendored
@@ -58,10 +58,10 @@ type Option func(*options)
|
||||
// Transitional sets a Profile to use the Transitional mapping as defined in UTS
|
||||
// #46. This will cause, for example, "ß" to be mapped to "ss". Using the
|
||||
// transitional mapping provides a compromise between IDNA2003 and IDNA2008
|
||||
// compatibility. It is used by most browsers when resolving domain names. This
|
||||
// compatibility. It is used by some browsers when resolving domain names. This
|
||||
// option is only meaningful if combined with MapForLookup.
|
||||
func Transitional(transitional bool) Option {
|
||||
return func(o *options) { o.transitional = true }
|
||||
return func(o *options) { o.transitional = transitional }
|
||||
}
|
||||
|
||||
// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
|
||||
|
||||
12
vendor/golang.org/x/net/idna/pre_go118.go
generated
vendored
Normal file
12
vendor/golang.org/x/net/idna/pre_go118.go
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// Copyright 2021 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.
|
||||
|
||||
//go:build !go1.18
|
||||
// +build !go1.18
|
||||
|
||||
package idna
|
||||
|
||||
const transitionalLookup = true
|
||||
36
vendor/golang.org/x/net/idna/punycode.go
generated
vendored
36
vendor/golang.org/x/net/idna/punycode.go
generated
vendored
@@ -49,6 +49,7 @@ func decode(encoded string) (string, error) {
|
||||
}
|
||||
}
|
||||
i, n, bias := int32(0), initialN, initialBias
|
||||
overflow := false
|
||||
for pos < len(encoded) {
|
||||
oldI, w := i, int32(1)
|
||||
for k := base; ; k += base {
|
||||
@@ -60,29 +61,32 @@ func decode(encoded string) (string, error) {
|
||||
return "", punyError(encoded)
|
||||
}
|
||||
pos++
|
||||
i += digit * w
|
||||
if i < 0 {
|
||||
i, overflow = madd(i, digit, w)
|
||||
if overflow {
|
||||
return "", punyError(encoded)
|
||||
}
|
||||
t := k - bias
|
||||
if t < tmin {
|
||||
if k <= bias {
|
||||
t = tmin
|
||||
} else if t > tmax {
|
||||
} else if k >= bias+tmax {
|
||||
t = tmax
|
||||
}
|
||||
if digit < t {
|
||||
break
|
||||
}
|
||||
w *= base - t
|
||||
if w >= math.MaxInt32/base {
|
||||
w, overflow = madd(0, w, base-t)
|
||||
if overflow {
|
||||
return "", punyError(encoded)
|
||||
}
|
||||
}
|
||||
if len(output) >= 1024 {
|
||||
return "", punyError(encoded)
|
||||
}
|
||||
x := int32(len(output) + 1)
|
||||
bias = adapt(i-oldI, x, oldI == 0)
|
||||
n += i / x
|
||||
i %= x
|
||||
if n > utf8.MaxRune || len(output) >= 1024 {
|
||||
if n < 0 || n > utf8.MaxRune {
|
||||
return "", punyError(encoded)
|
||||
}
|
||||
output = append(output, 0)
|
||||
@@ -115,6 +119,7 @@ func encode(prefix, s string) (string, error) {
|
||||
if b > 0 {
|
||||
output = append(output, '-')
|
||||
}
|
||||
overflow := false
|
||||
for remaining != 0 {
|
||||
m := int32(0x7fffffff)
|
||||
for _, r := range s {
|
||||
@@ -122,8 +127,8 @@ func encode(prefix, s string) (string, error) {
|
||||
m = r
|
||||
}
|
||||
}
|
||||
delta += (m - n) * (h + 1)
|
||||
if delta < 0 {
|
||||
delta, overflow = madd(delta, m-n, h+1)
|
||||
if overflow {
|
||||
return "", punyError(s)
|
||||
}
|
||||
n = m
|
||||
@@ -141,9 +146,9 @@ func encode(prefix, s string) (string, error) {
|
||||
q := delta
|
||||
for k := base; ; k += base {
|
||||
t := k - bias
|
||||
if t < tmin {
|
||||
if k <= bias {
|
||||
t = tmin
|
||||
} else if t > tmax {
|
||||
} else if k >= bias+tmax {
|
||||
t = tmax
|
||||
}
|
||||
if q < t {
|
||||
@@ -164,6 +169,15 @@ func encode(prefix, s string) (string, error) {
|
||||
return string(output), nil
|
||||
}
|
||||
|
||||
// madd computes a + (b * c), detecting overflow.
|
||||
func madd(a, b, c int32) (next int32, overflow bool) {
|
||||
p := int64(b) * int64(c)
|
||||
if p > math.MaxInt32-int64(a) {
|
||||
return 0, true
|
||||
}
|
||||
return a + int32(p), false
|
||||
}
|
||||
|
||||
func decodeDigit(x byte) (digit int32, ok bool) {
|
||||
switch {
|
||||
case '0' <= x && x <= '9':
|
||||
|
||||
34
vendor/golang.org/x/net/idna/trieval.go
generated
vendored
34
vendor/golang.org/x/net/idna/trieval.go
generated
vendored
@@ -17,23 +17,23 @@ package idna
|
||||
//
|
||||
// The per-rune values have the following format:
|
||||
//
|
||||
// if mapped {
|
||||
// if inlinedXOR {
|
||||
// 15..13 inline XOR marker
|
||||
// 12..11 unused
|
||||
// 10..3 inline XOR mask
|
||||
// } else {
|
||||
// 15..3 index into xor or mapping table
|
||||
// }
|
||||
// } else {
|
||||
// 15..14 unused
|
||||
// 13 mayNeedNorm
|
||||
// 12..11 attributes
|
||||
// 10..8 joining type
|
||||
// 7..3 category type
|
||||
// }
|
||||
// 2 use xor pattern
|
||||
// 1..0 mapped category
|
||||
// if mapped {
|
||||
// if inlinedXOR {
|
||||
// 15..13 inline XOR marker
|
||||
// 12..11 unused
|
||||
// 10..3 inline XOR mask
|
||||
// } else {
|
||||
// 15..3 index into xor or mapping table
|
||||
// }
|
||||
// } else {
|
||||
// 15..14 unused
|
||||
// 13 mayNeedNorm
|
||||
// 12..11 attributes
|
||||
// 10..8 joining type
|
||||
// 7..3 category type
|
||||
// }
|
||||
// 2 use xor pattern
|
||||
// 1..0 mapped category
|
||||
//
|
||||
// See the definitions below for a more detailed description of the various
|
||||
// bits.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user