mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-07-09 21:17:09 +08:00
vendor: update buildkit to master@d5c1d785b042
Signed-off-by: Justin Chadwell <me@jedevc.com>
This commit is contained in:
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
|
||||
|
4
vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
generated
vendored
4
vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
generated
vendored
@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.11 && gc && !purego
|
||||
// +build go1.11,gc,!purego
|
||||
//go:build gc && !purego
|
||||
// +build gc,!purego
|
||||
|
||||
package chacha20
|
||||
|
||||
|
4
vendor/golang.org/x/crypto/chacha20/chacha_arm64.s
generated
vendored
4
vendor/golang.org/x/crypto/chacha20/chacha_arm64.s
generated
vendored
@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build go1.11 && gc && !purego
|
||||
// +build go1.11,gc,!purego
|
||||
//go:build gc && !purego
|
||||
// +build gc,!purego
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
|
4
vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
generated
vendored
4
vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
generated
vendored
@ -2,8 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (!arm64 && !s390x && !ppc64le) || (arm64 && !go1.11) || !gc || purego
|
||||
// +build !arm64,!s390x,!ppc64le arm64,!go1.11 !gc purego
|
||||
//go:build (!arm64 && !s390x && !ppc64le) || !gc || purego
|
||||
// +build !arm64,!s390x,!ppc64le !gc purego
|
||||
|
||||
package chacha20
|
||||
|
||||
|
99
vendor/golang.org/x/crypto/curve25519/curve25519.go
generated
vendored
99
vendor/golang.org/x/crypto/curve25519/curve25519.go
generated
vendored
@ -5,71 +5,18 @@
|
||||
// Package curve25519 provides an implementation of the X25519 function, which
|
||||
// performs scalar multiplication on the elliptic curve known as Curve25519.
|
||||
// See RFC 7748.
|
||||
//
|
||||
// Starting in Go 1.20, this package is a wrapper for the X25519 implementation
|
||||
// in the crypto/ecdh package.
|
||||
package curve25519 // import "golang.org/x/crypto/curve25519"
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/crypto/curve25519/internal/field"
|
||||
)
|
||||
|
||||
// ScalarMult sets dst to the product scalar * point.
|
||||
//
|
||||
// Deprecated: when provided a low-order point, ScalarMult will set dst to all
|
||||
// zeroes, irrespective of the scalar. Instead, use the X25519 function, which
|
||||
// will return an error.
|
||||
func ScalarMult(dst, scalar, point *[32]byte) {
|
||||
var e [32]byte
|
||||
|
||||
copy(e[:], scalar[:])
|
||||
e[0] &= 248
|
||||
e[31] &= 127
|
||||
e[31] |= 64
|
||||
|
||||
var x1, x2, z2, x3, z3, tmp0, tmp1 field.Element
|
||||
x1.SetBytes(point[:])
|
||||
x2.One()
|
||||
x3.Set(&x1)
|
||||
z3.One()
|
||||
|
||||
swap := 0
|
||||
for pos := 254; pos >= 0; pos-- {
|
||||
b := e[pos/8] >> uint(pos&7)
|
||||
b &= 1
|
||||
swap ^= int(b)
|
||||
x2.Swap(&x3, swap)
|
||||
z2.Swap(&z3, swap)
|
||||
swap = int(b)
|
||||
|
||||
tmp0.Subtract(&x3, &z3)
|
||||
tmp1.Subtract(&x2, &z2)
|
||||
x2.Add(&x2, &z2)
|
||||
z2.Add(&x3, &z3)
|
||||
z3.Multiply(&tmp0, &x2)
|
||||
z2.Multiply(&z2, &tmp1)
|
||||
tmp0.Square(&tmp1)
|
||||
tmp1.Square(&x2)
|
||||
x3.Add(&z3, &z2)
|
||||
z2.Subtract(&z3, &z2)
|
||||
x2.Multiply(&tmp1, &tmp0)
|
||||
tmp1.Subtract(&tmp1, &tmp0)
|
||||
z2.Square(&z2)
|
||||
|
||||
z3.Mult32(&tmp1, 121666)
|
||||
x3.Square(&x3)
|
||||
tmp0.Add(&tmp0, &z3)
|
||||
z3.Multiply(&x1, &z2)
|
||||
z2.Multiply(&tmp1, &tmp0)
|
||||
}
|
||||
|
||||
x2.Swap(&x3, swap)
|
||||
z2.Swap(&z3, swap)
|
||||
|
||||
z2.Invert(&z2)
|
||||
x2.Multiply(&x2, &z2)
|
||||
copy(dst[:], x2.Bytes())
|
||||
scalarMult(dst, scalar, point)
|
||||
}
|
||||
|
||||
// ScalarBaseMult sets dst to the product scalar * base where base is the
|
||||
@ -78,7 +25,7 @@ func ScalarMult(dst, scalar, point *[32]byte) {
|
||||
// It is recommended to use the X25519 function with Basepoint instead, as
|
||||
// copying into fixed size arrays can lead to unexpected bugs.
|
||||
func ScalarBaseMult(dst, scalar *[32]byte) {
|
||||
ScalarMult(dst, scalar, &basePoint)
|
||||
scalarBaseMult(dst, scalar)
|
||||
}
|
||||
|
||||
const (
|
||||
@ -91,21 +38,10 @@ const (
|
||||
// Basepoint is the canonical Curve25519 generator.
|
||||
var Basepoint []byte
|
||||
|
||||
var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
var basePoint = [32]byte{9}
|
||||
|
||||
func init() { Basepoint = basePoint[:] }
|
||||
|
||||
func checkBasepoint() {
|
||||
if subtle.ConstantTimeCompare(Basepoint, []byte{
|
||||
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
}) != 1 {
|
||||
panic("curve25519: global Basepoint value was modified")
|
||||
}
|
||||
}
|
||||
|
||||
// X25519 returns the result of the scalar multiplication (scalar * point),
|
||||
// according to RFC 7748, Section 5. scalar, point and the return value are
|
||||
// slices of 32 bytes.
|
||||
@ -121,26 +57,3 @@ func X25519(scalar, point []byte) ([]byte, error) {
|
||||
var dst [32]byte
|
||||
return x25519(&dst, scalar, point)
|
||||
}
|
||||
|
||||
func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
|
||||
var in [32]byte
|
||||
if l := len(scalar); l != 32 {
|
||||
return nil, errors.New("bad scalar length: " + strconv.Itoa(l) + ", expected 32")
|
||||
}
|
||||
if l := len(point); l != 32 {
|
||||
return nil, errors.New("bad point length: " + strconv.Itoa(l) + ", expected 32")
|
||||
}
|
||||
copy(in[:], scalar)
|
||||
if &point[0] == &Basepoint[0] {
|
||||
checkBasepoint()
|
||||
ScalarBaseMult(dst, &in)
|
||||
} else {
|
||||
var base, zero [32]byte
|
||||
copy(base[:], point)
|
||||
ScalarMult(dst, &in, &base)
|
||||
if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 {
|
||||
return nil, errors.New("bad input point: low order point")
|
||||
}
|
||||
}
|
||||
return dst[:], nil
|
||||
}
|
||||
|
105
vendor/golang.org/x/crypto/curve25519/curve25519_compat.go
generated
vendored
Normal file
105
vendor/golang.org/x/crypto/curve25519/curve25519_compat.go
generated
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
// 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.20
|
||||
|
||||
package curve25519
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/crypto/curve25519/internal/field"
|
||||
)
|
||||
|
||||
func scalarMult(dst, scalar, point *[32]byte) {
|
||||
var e [32]byte
|
||||
|
||||
copy(e[:], scalar[:])
|
||||
e[0] &= 248
|
||||
e[31] &= 127
|
||||
e[31] |= 64
|
||||
|
||||
var x1, x2, z2, x3, z3, tmp0, tmp1 field.Element
|
||||
x1.SetBytes(point[:])
|
||||
x2.One()
|
||||
x3.Set(&x1)
|
||||
z3.One()
|
||||
|
||||
swap := 0
|
||||
for pos := 254; pos >= 0; pos-- {
|
||||
b := e[pos/8] >> uint(pos&7)
|
||||
b &= 1
|
||||
swap ^= int(b)
|
||||
x2.Swap(&x3, swap)
|
||||
z2.Swap(&z3, swap)
|
||||
swap = int(b)
|
||||
|
||||
tmp0.Subtract(&x3, &z3)
|
||||
tmp1.Subtract(&x2, &z2)
|
||||
x2.Add(&x2, &z2)
|
||||
z2.Add(&x3, &z3)
|
||||
z3.Multiply(&tmp0, &x2)
|
||||
z2.Multiply(&z2, &tmp1)
|
||||
tmp0.Square(&tmp1)
|
||||
tmp1.Square(&x2)
|
||||
x3.Add(&z3, &z2)
|
||||
z2.Subtract(&z3, &z2)
|
||||
x2.Multiply(&tmp1, &tmp0)
|
||||
tmp1.Subtract(&tmp1, &tmp0)
|
||||
z2.Square(&z2)
|
||||
|
||||
z3.Mult32(&tmp1, 121666)
|
||||
x3.Square(&x3)
|
||||
tmp0.Add(&tmp0, &z3)
|
||||
z3.Multiply(&x1, &z2)
|
||||
z2.Multiply(&tmp1, &tmp0)
|
||||
}
|
||||
|
||||
x2.Swap(&x3, swap)
|
||||
z2.Swap(&z3, swap)
|
||||
|
||||
z2.Invert(&z2)
|
||||
x2.Multiply(&x2, &z2)
|
||||
copy(dst[:], x2.Bytes())
|
||||
}
|
||||
|
||||
func scalarBaseMult(dst, scalar *[32]byte) {
|
||||
checkBasepoint()
|
||||
scalarMult(dst, scalar, &basePoint)
|
||||
}
|
||||
|
||||
func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
|
||||
var in [32]byte
|
||||
if l := len(scalar); l != 32 {
|
||||
return nil, errors.New("bad scalar length: " + strconv.Itoa(l) + ", expected 32")
|
||||
}
|
||||
if l := len(point); l != 32 {
|
||||
return nil, errors.New("bad point length: " + strconv.Itoa(l) + ", expected 32")
|
||||
}
|
||||
copy(in[:], scalar)
|
||||
if &point[0] == &Basepoint[0] {
|
||||
scalarBaseMult(dst, &in)
|
||||
} else {
|
||||
var base, zero [32]byte
|
||||
copy(base[:], point)
|
||||
scalarMult(dst, &in, &base)
|
||||
if subtle.ConstantTimeCompare(dst[:], zero[:]) == 1 {
|
||||
return nil, errors.New("bad input point: low order point")
|
||||
}
|
||||
}
|
||||
return dst[:], nil
|
||||
}
|
||||
|
||||
func checkBasepoint() {
|
||||
if subtle.ConstantTimeCompare(Basepoint, []byte{
|
||||
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
}) != 1 {
|
||||
panic("curve25519: global Basepoint value was modified")
|
||||
}
|
||||
}
|
46
vendor/golang.org/x/crypto/curve25519/curve25519_go120.go
generated
vendored
Normal file
46
vendor/golang.org/x/crypto/curve25519/curve25519_go120.go
generated
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright 2022 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.20
|
||||
|
||||
package curve25519
|
||||
|
||||
import "crypto/ecdh"
|
||||
|
||||
func x25519(dst *[32]byte, scalar, point []byte) ([]byte, error) {
|
||||
curve := ecdh.X25519()
|
||||
pub, err := curve.NewPublicKey(point)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
priv, err := curve.NewPrivateKey(scalar)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out, err := priv.ECDH(pub)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
copy(dst[:], out)
|
||||
return dst[:], nil
|
||||
}
|
||||
|
||||
func scalarMult(dst, scalar, point *[32]byte) {
|
||||
if _, err := x25519(dst, scalar[:], point[:]); err != nil {
|
||||
// The only error condition for x25519 when the inputs are 32 bytes long
|
||||
// is if the output would have been the all-zero value.
|
||||
for i := range dst {
|
||||
dst[i] = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func scalarBaseMult(dst, scalar *[32]byte) {
|
||||
curve := ecdh.X25519()
|
||||
priv, err := curve.NewPrivateKey(scalar[:])
|
||||
if err != nil {
|
||||
panic("curve25519: internal error: scalarBaseMult was not 32 bytes")
|
||||
}
|
||||
copy(dst[:], priv.PublicKey().Bytes())
|
||||
}
|
2
vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go
generated
vendored
2
vendor/golang.org/x/crypto/curve25519/internal/field/fe_generic.go
generated
vendored
@ -245,7 +245,7 @@ func feSquareGeneric(v, a *Element) {
|
||||
v.carryPropagate()
|
||||
}
|
||||
|
||||
// carryPropagate brings the limbs below 52 bits by applying the reduction
|
||||
// carryPropagateGeneric brings the limbs below 52 bits by applying the reduction
|
||||
// identity (a * 2²⁵⁵ + b = a * 19 + b) to the l4 carry. TODO inline
|
||||
func (v *Element) carryPropagateGeneric() *Element {
|
||||
c0 := v.l0 >> 51
|
||||
|
2
vendor/golang.org/x/crypto/nacl/sign/sign.go
generated
vendored
2
vendor/golang.org/x/crypto/nacl/sign/sign.go
generated
vendored
@ -21,9 +21,9 @@
|
||||
package sign
|
||||
|
||||
import (
|
||||
"crypto/ed25519"
|
||||
"io"
|
||||
|
||||
"golang.org/x/crypto/ed25519"
|
||||
"golang.org/x/crypto/internal/alias"
|
||||
)
|
||||
|
||||
|
2
vendor/golang.org/x/crypto/ssh/agent/client.go
generated
vendored
2
vendor/golang.org/x/crypto/ssh/agent/client.go
generated
vendored
@ -16,6 +16,7 @@ import (
|
||||
"bytes"
|
||||
"crypto/dsa"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/elliptic"
|
||||
"crypto/rsa"
|
||||
"encoding/base64"
|
||||
@ -26,7 +27,6 @@ import (
|
||||
"math/big"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/crypto/ed25519"
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
|
4
vendor/golang.org/x/crypto/ssh/agent/server.go
generated
vendored
4
vendor/golang.org/x/crypto/ssh/agent/server.go
generated
vendored
@ -7,6 +7,7 @@ package agent
|
||||
import (
|
||||
"crypto/dsa"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/elliptic"
|
||||
"crypto/rsa"
|
||||
"encoding/binary"
|
||||
@ -16,11 +17,10 @@ import (
|
||||
"log"
|
||||
"math/big"
|
||||
|
||||
"golang.org/x/crypto/ed25519"
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
// Server wraps an Agent and uses it to implement the agent side of
|
||||
// server wraps an Agent and uses it to implement the agent side of
|
||||
// the SSH-agent, wire protocol.
|
||||
type server struct {
|
||||
agent Agent
|
||||
|
38
vendor/golang.org/x/crypto/ssh/certs.go
generated
vendored
38
vendor/golang.org/x/crypto/ssh/certs.go
generated
vendored
@ -16,8 +16,9 @@ import (
|
||||
|
||||
// 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.
|
||||
// Unlike key algorithm names, these are not passed to AlgorithmSigner nor
|
||||
// returned by MultiAlgorithmSigner and don't appear in the Signature.Format
|
||||
// field.
|
||||
const (
|
||||
CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com"
|
||||
CertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com"
|
||||
@ -255,10 +256,17 @@ func NewCertSigner(cert *Certificate, signer Signer) (Signer, error) {
|
||||
return nil, errors.New("ssh: signer and cert have different public key")
|
||||
}
|
||||
|
||||
if algorithmSigner, ok := signer.(AlgorithmSigner); ok {
|
||||
switch s := signer.(type) {
|
||||
case MultiAlgorithmSigner:
|
||||
return &multiAlgorithmSigner{
|
||||
AlgorithmSigner: &algorithmOpenSSHCertSigner{
|
||||
&openSSHCertSigner{cert, signer}, s},
|
||||
supportedAlgorithms: s.Algorithms(),
|
||||
}, nil
|
||||
case AlgorithmSigner:
|
||||
return &algorithmOpenSSHCertSigner{
|
||||
&openSSHCertSigner{cert, signer}, algorithmSigner}, nil
|
||||
} else {
|
||||
&openSSHCertSigner{cert, signer}, s}, nil
|
||||
default:
|
||||
return &openSSHCertSigner{cert, signer}, nil
|
||||
}
|
||||
}
|
||||
@ -432,7 +440,9 @@ func (c *CertChecker) CheckCert(principal string, cert *Certificate) error {
|
||||
}
|
||||
|
||||
// SignCert signs the certificate with an authority, setting the Nonce,
|
||||
// SignatureKey, and Signature fields.
|
||||
// SignatureKey, and Signature fields. If the authority implements the
|
||||
// MultiAlgorithmSigner interface the first algorithm in the list is used. This
|
||||
// is useful if you want to sign with a specific algorithm.
|
||||
func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
|
||||
c.Nonce = make([]byte, 32)
|
||||
if _, err := io.ReadFull(rand, c.Nonce); err != nil {
|
||||
@ -440,8 +450,20 @@ 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 {
|
||||
if v, ok := authority.(MultiAlgorithmSigner); ok {
|
||||
if len(v.Algorithms()) == 0 {
|
||||
return errors.New("the provided authority has no signature algorithm")
|
||||
}
|
||||
// Use the first algorithm in the list.
|
||||
sig, err := v.SignWithAlgorithm(rand, c.bytesForSigning(), v.Algorithms()[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Signature = sig
|
||||
return nil
|
||||
} else if v, ok := authority.(AlgorithmSigner); ok && v.PublicKey().Type() == KeyAlgoRSA {
|
||||
// Default to KeyAlgoRSASHA512 for ssh-rsa signers.
|
||||
// TODO: consider using KeyAlgoRSASHA256 as default.
|
||||
sig, err := v.SignWithAlgorithm(rand, c.bytesForSigning(), KeyAlgoRSASHA512)
|
||||
if err != nil {
|
||||
return err
|
||||
|
3
vendor/golang.org/x/crypto/ssh/cipher.go
generated
vendored
3
vendor/golang.org/x/crypto/ssh/cipher.go
generated
vendored
@ -114,7 +114,8 @@ var cipherModes = map[string]*cipherMode{
|
||||
"arcfour": {16, 0, streamCipherMode(0, newRC4)},
|
||||
|
||||
// AEAD ciphers
|
||||
gcmCipherID: {16, 12, newGCMCipher},
|
||||
gcm128CipherID: {16, 12, newGCMCipher},
|
||||
gcm256CipherID: {32, 12, newGCMCipher},
|
||||
chacha20Poly1305ID: {64, 0, newChaCha20Cipher},
|
||||
|
||||
// CBC mode is insecure and so is not included in the default config.
|
||||
|
96
vendor/golang.org/x/crypto/ssh/client_auth.go
generated
vendored
96
vendor/golang.org/x/crypto/ssh/client_auth.go
generated
vendored
@ -71,7 +71,9 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error {
|
||||
for auth := AuthMethod(new(noneAuth)); auth != nil; {
|
||||
ok, methods, err := auth.auth(sessionID, config.User, c.transport, config.Rand, extensions)
|
||||
if err != nil {
|
||||
return err
|
||||
// We return the error later if there is no other method left to
|
||||
// try.
|
||||
ok = authFailure
|
||||
}
|
||||
if ok == authSuccess {
|
||||
// success
|
||||
@ -101,6 +103,12 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if auth == nil && err != nil {
|
||||
// We have an error and there are no other authentication methods to
|
||||
// try, so we return it.
|
||||
return err
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("ssh: unable to authenticate, attempted methods %v, no supported methods remain", tried)
|
||||
}
|
||||
@ -217,21 +225,45 @@ func (cb publicKeyCallback) method() string {
|
||||
return "publickey"
|
||||
}
|
||||
|
||||
func pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (as AlgorithmSigner, algo string) {
|
||||
func pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (MultiAlgorithmSigner, string, error) {
|
||||
var as MultiAlgorithmSigner
|
||||
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
|
||||
// If the signer implements MultiAlgorithmSigner we use the algorithms it
|
||||
// support, if it implements AlgorithmSigner we assume it supports all
|
||||
// algorithms, otherwise only the key format one.
|
||||
switch s := signer.(type) {
|
||||
case MultiAlgorithmSigner:
|
||||
as = s
|
||||
case AlgorithmSigner:
|
||||
as = &multiAlgorithmSigner{
|
||||
AlgorithmSigner: s,
|
||||
supportedAlgorithms: algorithmsForKeyFormat(underlyingAlgo(keyFormat)),
|
||||
}
|
||||
default:
|
||||
as = &multiAlgorithmSigner{
|
||||
AlgorithmSigner: algorithmSignerWrapper{signer},
|
||||
supportedAlgorithms: []string{underlyingAlgo(keyFormat)},
|
||||
}
|
||||
}
|
||||
|
||||
getFallbackAlgo := func() (string, error) {
|
||||
// Fallback to use if there is no "server-sig-algs" extension or a
|
||||
// common algorithm cannot be found. We use the public key format if the
|
||||
// MultiAlgorithmSigner supports it, otherwise we return an error.
|
||||
if !contains(as.Algorithms(), underlyingAlgo(keyFormat)) {
|
||||
return "", fmt.Errorf("ssh: no common public key signature algorithm, server only supports %q for key type %q, signer only supports %v",
|
||||
underlyingAlgo(keyFormat), keyFormat, as.Algorithms())
|
||||
}
|
||||
return keyFormat, nil
|
||||
}
|
||||
|
||||
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
|
||||
// If there is no "server-sig-algs" extension use the fallback
|
||||
// algorithm.
|
||||
algo, err := getFallbackAlgo()
|
||||
return as, algo, err
|
||||
}
|
||||
|
||||
// The server-sig-algs extension only carries underlying signature
|
||||
@ -245,15 +277,22 @@ func pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (as Alg
|
||||
}
|
||||
}
|
||||
|
||||
keyAlgos := algorithmsForKeyFormat(keyFormat)
|
||||
// Filter algorithms based on those supported by MultiAlgorithmSigner.
|
||||
var keyAlgos []string
|
||||
for _, algo := range algorithmsForKeyFormat(keyFormat) {
|
||||
if contains(as.Algorithms(), underlyingAlgo(algo)) {
|
||||
keyAlgos = append(keyAlgos, algo)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
// If there is no overlap, return the fallback algorithm to support
|
||||
// servers that fail to list all supported algorithms.
|
||||
algo, err := getFallbackAlgo()
|
||||
return as, algo, err
|
||||
}
|
||||
return as, algo
|
||||
return as, algo, nil
|
||||
}
|
||||
|
||||
func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand io.Reader, extensions map[string][]byte) (authResult, []string, error) {
|
||||
@ -267,10 +306,17 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
|
||||
return authFailure, nil, err
|
||||
}
|
||||
var methods []string
|
||||
var errSigAlgo error
|
||||
for _, signer := range signers {
|
||||
pub := signer.PublicKey()
|
||||
as, algo := pickSignatureAlgorithm(signer, extensions)
|
||||
|
||||
as, algo, err := pickSignatureAlgorithm(signer, extensions)
|
||||
if err != nil && errSigAlgo == nil {
|
||||
// If we cannot negotiate a signature algorithm store the first
|
||||
// error so we can return it to provide a more meaningful message if
|
||||
// no other signers work.
|
||||
errSigAlgo = err
|
||||
continue
|
||||
}
|
||||
ok, err := validateKey(pub, algo, user, c)
|
||||
if err != nil {
|
||||
return authFailure, nil, err
|
||||
@ -317,22 +363,12 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
|
||||
// contain the "publickey" method, do not attempt to authenticate with any
|
||||
// other keys. According to RFC 4252 Section 7, the latter can occur when
|
||||
// additional authentication methods are required.
|
||||
if success == authSuccess || !containsMethod(methods, cb.method()) {
|
||||
if success == authSuccess || !contains(methods, cb.method()) {
|
||||
return success, methods, err
|
||||
}
|
||||
}
|
||||
|
||||
return authFailure, methods, nil
|
||||
}
|
||||
|
||||
func containsMethod(methods []string, method string) bool {
|
||||
for _, m := range methods {
|
||||
if m == method {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
return authFailure, methods, errSigAlgo
|
||||
}
|
||||
|
||||
// validateKey validates the key provided is acceptable to the server.
|
||||
|
75
vendor/golang.org/x/crypto/ssh/common.go
generated
vendored
75
vendor/golang.org/x/crypto/ssh/common.go
generated
vendored
@ -10,6 +10,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
_ "crypto/sha1"
|
||||
@ -27,7 +28,7 @@ const (
|
||||
// supportedCiphers lists ciphers we support but might not recommend.
|
||||
var supportedCiphers = []string{
|
||||
"aes128-ctr", "aes192-ctr", "aes256-ctr",
|
||||
"aes128-gcm@openssh.com",
|
||||
"aes128-gcm@openssh.com", gcm256CipherID,
|
||||
chacha20Poly1305ID,
|
||||
"arcfour256", "arcfour128", "arcfour",
|
||||
aes128cbcID,
|
||||
@ -36,7 +37,7 @@ var supportedCiphers = []string{
|
||||
|
||||
// preferredCiphers specifies the default preference for ciphers.
|
||||
var preferredCiphers = []string{
|
||||
"aes128-gcm@openssh.com",
|
||||
"aes128-gcm@openssh.com", gcm256CipherID,
|
||||
chacha20Poly1305ID,
|
||||
"aes128-ctr", "aes192-ctr", "aes256-ctr",
|
||||
}
|
||||
@ -48,7 +49,8 @@ var supportedKexAlgos = []string{
|
||||
// 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,
|
||||
kexAlgoDH14SHA256, kexAlgoDH14SHA1, kexAlgoDH1SHA1,
|
||||
kexAlgoDH14SHA256, kexAlgoDH16SHA512, kexAlgoDH14SHA1,
|
||||
kexAlgoDH1SHA1,
|
||||
}
|
||||
|
||||
// serverForbiddenKexAlgos contains key exchange algorithms, that are forbidden
|
||||
@ -58,8 +60,9 @@ var serverForbiddenKexAlgos = map[string]struct{}{
|
||||
kexAlgoDHGEXSHA256: {}, // server half implementation is only minimal to satisfy the automated tests
|
||||
}
|
||||
|
||||
// preferredKexAlgos specifies the default preference for key-exchange algorithms
|
||||
// in preference order.
|
||||
// preferredKexAlgos specifies the default preference for key-exchange
|
||||
// algorithms in preference order. The diffie-hellman-group16-sha512 algorithm
|
||||
// is disabled by default because it is a bit slower than the others.
|
||||
var preferredKexAlgos = []string{
|
||||
kexAlgoCurve25519SHA256, kexAlgoCurve25519SHA256LibSSH,
|
||||
kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521,
|
||||
@ -69,12 +72,12 @@ var preferredKexAlgos = []string{
|
||||
// supportedHostKeyAlgos specifies the supported host-key algorithms (i.e. methods
|
||||
// of authenticating servers) in preference order.
|
||||
var supportedHostKeyAlgos = []string{
|
||||
CertAlgoRSASHA512v01, CertAlgoRSASHA256v01,
|
||||
CertAlgoRSASHA256v01, CertAlgoRSASHA512v01,
|
||||
CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01,
|
||||
CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoED25519v01,
|
||||
|
||||
KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521,
|
||||
KeyAlgoRSASHA512, KeyAlgoRSASHA256,
|
||||
KeyAlgoRSASHA256, KeyAlgoRSASHA512,
|
||||
KeyAlgoRSA, KeyAlgoDSA,
|
||||
|
||||
KeyAlgoED25519,
|
||||
@ -84,7 +87,7 @@ var supportedHostKeyAlgos = []string{
|
||||
// This is based on RFC 4253, section 6.4, but with hmac-md5 variants removed
|
||||
// because they have reached the end of their useful life.
|
||||
var supportedMACs = []string{
|
||||
"hmac-sha2-256-etm@openssh.com", "hmac-sha2-256", "hmac-sha1", "hmac-sha1-96",
|
||||
"hmac-sha2-256-etm@openssh.com", "hmac-sha2-512-etm@openssh.com", "hmac-sha2-256", "hmac-sha2-512", "hmac-sha1", "hmac-sha1-96",
|
||||
}
|
||||
|
||||
var supportedCompressions = []string{compressionNone}
|
||||
@ -118,6 +121,27 @@ func algorithmsForKeyFormat(keyFormat string) []string {
|
||||
}
|
||||
}
|
||||
|
||||
// isRSA returns whether algo is a supported RSA algorithm, including certificate
|
||||
// algorithms.
|
||||
func isRSA(algo string) bool {
|
||||
algos := algorithmsForKeyFormat(KeyAlgoRSA)
|
||||
return contains(algos, underlyingAlgo(algo))
|
||||
}
|
||||
|
||||
// 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 {
|
||||
@ -153,7 +177,7 @@ func (a *directionAlgorithms) rekeyBytes() int64 {
|
||||
// 2^(BLOCKSIZE/4) blocks. For all AES flavors BLOCKSIZE is
|
||||
// 128.
|
||||
switch a.Cipher {
|
||||
case "aes128-ctr", "aes192-ctr", "aes256-ctr", gcmCipherID, aes128cbcID:
|
||||
case "aes128-ctr", "aes192-ctr", "aes256-ctr", gcm128CipherID, gcm256CipherID, aes128cbcID:
|
||||
return 16 * (1 << 32)
|
||||
|
||||
}
|
||||
@ -163,7 +187,8 @@ func (a *directionAlgorithms) rekeyBytes() int64 {
|
||||
}
|
||||
|
||||
var aeadCiphers = map[string]bool{
|
||||
gcmCipherID: true,
|
||||
gcm128CipherID: true,
|
||||
gcm256CipherID: true,
|
||||
chacha20Poly1305ID: true,
|
||||
}
|
||||
|
||||
@ -246,16 +271,16 @@ type Config struct {
|
||||
// unspecified, a size suitable for the chosen cipher is used.
|
||||
RekeyThreshold uint64
|
||||
|
||||
// The allowed key exchanges algorithms. If unspecified then a
|
||||
// default set of algorithms is used.
|
||||
// The allowed key exchanges algorithms. If unspecified then a default set
|
||||
// of algorithms is used. Unsupported values are silently ignored.
|
||||
KeyExchanges []string
|
||||
|
||||
// The allowed cipher algorithms. If unspecified then a sensible
|
||||
// default is used.
|
||||
// The allowed cipher algorithms. If unspecified then a sensible default is
|
||||
// used. Unsupported values are silently ignored.
|
||||
Ciphers []string
|
||||
|
||||
// The allowed MAC algorithms. If unspecified then a sensible default
|
||||
// is used.
|
||||
// The allowed MAC algorithms. If unspecified then a sensible default is
|
||||
// used. Unsupported values are silently ignored.
|
||||
MACs []string
|
||||
}
|
||||
|
||||
@ -272,7 +297,7 @@ func (c *Config) SetDefaults() {
|
||||
var ciphers []string
|
||||
for _, c := range c.Ciphers {
|
||||
if cipherModes[c] != nil {
|
||||
// reject the cipher if we have no cipherModes definition
|
||||
// Ignore the cipher if we have no cipherModes definition.
|
||||
ciphers = append(ciphers, c)
|
||||
}
|
||||
}
|
||||
@ -281,10 +306,26 @@ func (c *Config) SetDefaults() {
|
||||
if c.KeyExchanges == nil {
|
||||
c.KeyExchanges = preferredKexAlgos
|
||||
}
|
||||
var kexs []string
|
||||
for _, k := range c.KeyExchanges {
|
||||
if kexAlgoMap[k] != nil {
|
||||
// Ignore the KEX if we have no kexAlgoMap definition.
|
||||
kexs = append(kexs, k)
|
||||
}
|
||||
}
|
||||
c.KeyExchanges = kexs
|
||||
|
||||
if c.MACs == nil {
|
||||
c.MACs = supportedMACs
|
||||
}
|
||||
var macs []string
|
||||
for _, m := range c.MACs {
|
||||
if macModes[m] != nil {
|
||||
// Ignore the MAC if we have no macModes definition.
|
||||
macs = append(macs, m)
|
||||
}
|
||||
}
|
||||
c.MACs = macs
|
||||
|
||||
if c.RekeyThreshold == 0 {
|
||||
// cipher specific default
|
||||
|
2
vendor/golang.org/x/crypto/ssh/connection.go
generated
vendored
2
vendor/golang.org/x/crypto/ssh/connection.go
generated
vendored
@ -97,7 +97,7 @@ func (c *connection) Close() error {
|
||||
return c.sshConn.conn.Close()
|
||||
}
|
||||
|
||||
// sshconn provides net.Conn metadata, but disallows direct reads and
|
||||
// sshConn provides net.Conn metadata, but disallows direct reads and
|
||||
// writes.
|
||||
type sshConn struct {
|
||||
conn net.Conn
|
||||
|
1
vendor/golang.org/x/crypto/ssh/doc.go
generated
vendored
1
vendor/golang.org/x/crypto/ssh/doc.go
generated
vendored
@ -13,6 +13,7 @@ others.
|
||||
|
||||
References:
|
||||
|
||||
[PROTOCOL]: https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL?rev=HEAD
|
||||
[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
|
||||
|
||||
|
109
vendor/golang.org/x/crypto/ssh/handshake.go
generated
vendored
109
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
|
||||
@ -458,19 +461,24 @@ func (t *handshakeTransport) sendKexInit() error {
|
||||
isServer := len(t.hostKeys) > 0
|
||||
if isServer {
|
||||
for _, k := range t.hostKeys {
|
||||
// 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.)
|
||||
// If k is a MultiAlgorithmSigner, we restrict the signature
|
||||
// algorithms. If k is a AlgorithmSigner, presume it supports all
|
||||
// signature algorithms associated with the key format. 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 {
|
||||
|
||||
switch s := k.(type) {
|
||||
case MultiAlgorithmSigner:
|
||||
for _, algo := range algorithmsForKeyFormat(keyFormat) {
|
||||
if contains(s.Algorithms(), underlyingAlgo(algo)) {
|
||||
msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algo)
|
||||
}
|
||||
}
|
||||
case AlgorithmSigner:
|
||||
msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algorithmsForKeyFormat(keyFormat)...)
|
||||
} else {
|
||||
default:
|
||||
msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, keyFormat)
|
||||
}
|
||||
}
|
||||
@ -545,7 +553,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 {
|
||||
@ -615,7 +632,8 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if t.sessionID == nil {
|
||||
firstKeyExchange := t.sessionID == nil
|
||||
if firstKeyExchange {
|
||||
t.sessionID = result.H
|
||||
}
|
||||
result.SessionID = t.sessionID
|
||||
@ -626,6 +644,28 @@ 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, and [PROTOCOL], Section 1.9.
|
||||
if !isClient && firstKeyExchange && contains(clientInit.KexAlgos, "ext-info-c") {
|
||||
extInfo := &extInfoMsg{
|
||||
NumExtensions: 2,
|
||||
Payload: make([]byte, 0, 4+15+4+len(supportedPubKeyAuthAlgosList)+4+16+4+1),
|
||||
}
|
||||
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...)
|
||||
extInfo.Payload = appendInt(extInfo.Payload, len("ping@openssh.com"))
|
||||
extInfo.Payload = append(extInfo.Payload, "ping@openssh.com"...)
|
||||
extInfo.Payload = appendInt(extInfo.Payload, 1)
|
||||
extInfo.Payload = append(extInfo.Payload, "0"...)
|
||||
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 {
|
||||
@ -654,9 +694,16 @@ func (a algorithmSignerWrapper) SignWithAlgorithm(rand io.Reader, data []byte, a
|
||||
|
||||
func pickHostKey(hostKeys []Signer, algo string) AlgorithmSigner {
|
||||
for _, k := range hostKeys {
|
||||
if s, ok := k.(MultiAlgorithmSigner); ok {
|
||||
if !contains(s.Algorithms(), underlyingAlgo(algo)) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if algo == k.PublicKey().Type() {
|
||||
return algorithmSignerWrapper{k}
|
||||
}
|
||||
|
||||
k, ok := k.(AlgorithmSigner)
|
||||
if !ok {
|
||||
continue
|
||||
|
12
vendor/golang.org/x/crypto/ssh/kex.go
generated
vendored
12
vendor/golang.org/x/crypto/ssh/kex.go
generated
vendored
@ -23,6 +23,7 @@ const (
|
||||
kexAlgoDH1SHA1 = "diffie-hellman-group1-sha1"
|
||||
kexAlgoDH14SHA1 = "diffie-hellman-group14-sha1"
|
||||
kexAlgoDH14SHA256 = "diffie-hellman-group14-sha256"
|
||||
kexAlgoDH16SHA512 = "diffie-hellman-group16-sha512"
|
||||
kexAlgoECDH256 = "ecdh-sha2-nistp256"
|
||||
kexAlgoECDH384 = "ecdh-sha2-nistp384"
|
||||
kexAlgoECDH521 = "ecdh-sha2-nistp521"
|
||||
@ -430,6 +431,17 @@ func init() {
|
||||
hashFunc: crypto.SHA256,
|
||||
}
|
||||
|
||||
// This is the group called diffie-hellman-group16-sha512 in RFC
|
||||
// 8268 and Oakley Group 16 in RFC 3526.
|
||||
p, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF", 16)
|
||||
|
||||
kexAlgoMap[kexAlgoDH16SHA512] = &dhGroup{
|
||||
g: new(big.Int).SetInt64(2),
|
||||
p: p,
|
||||
pMinus1: new(big.Int).Sub(p, bigOne),
|
||||
hashFunc: crypto.SHA512,
|
||||
}
|
||||
|
||||
kexAlgoMap[kexAlgoECDH521] = &ecdh{elliptic.P521()}
|
||||
kexAlgoMap[kexAlgoECDH384] = &ecdh{elliptic.P384()}
|
||||
kexAlgoMap[kexAlgoECDH256] = &ecdh{elliptic.P256()}
|
||||
|
382
vendor/golang.org/x/crypto/ssh/keys.go
generated
vendored
382
vendor/golang.org/x/crypto/ssh/keys.go
generated
vendored
@ -11,13 +11,16 @@ import (
|
||||
"crypto/cipher"
|
||||
"crypto/dsa"
|
||||
"crypto/ecdsa"
|
||||
"crypto/ed25519"
|
||||
"crypto/elliptic"
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"encoding/asn1"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
@ -26,7 +29,6 @@ import (
|
||||
"math/big"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/crypto/ed25519"
|
||||
"golang.org/x/crypto/ssh/internal/bcrypt_pbkdf"
|
||||
)
|
||||
|
||||
@ -295,6 +297,18 @@ func MarshalAuthorizedKey(key PublicKey) []byte {
|
||||
return b.Bytes()
|
||||
}
|
||||
|
||||
// MarshalPrivateKey returns a PEM block with the private key serialized in the
|
||||
// OpenSSH format.
|
||||
func MarshalPrivateKey(key crypto.PrivateKey, comment string) (*pem.Block, error) {
|
||||
return marshalOpenSSHPrivateKey(key, comment, unencryptedOpenSSHMarshaler)
|
||||
}
|
||||
|
||||
// MarshalPrivateKeyWithPassphrase returns a PEM block holding the encrypted
|
||||
// private key serialized in the OpenSSH format.
|
||||
func MarshalPrivateKeyWithPassphrase(key crypto.PrivateKey, comment string, passphrase []byte) (*pem.Block, error) {
|
||||
return marshalOpenSSHPrivateKey(key, comment, passphraseProtectedOpenSSHMarshaler(passphrase))
|
||||
}
|
||||
|
||||
// PublicKey represents a public key using an unspecified algorithm.
|
||||
//
|
||||
// Some PublicKeys provided by this package also implement CryptoPublicKey.
|
||||
@ -321,7 +335,7 @@ type CryptoPublicKey interface {
|
||||
|
||||
// A Signer can create signatures that verify against a public key.
|
||||
//
|
||||
// Some Signers provided by this package also implement AlgorithmSigner.
|
||||
// Some Signers provided by this package also implement MultiAlgorithmSigner.
|
||||
type Signer interface {
|
||||
// PublicKey returns the associated PublicKey.
|
||||
PublicKey() PublicKey
|
||||
@ -336,9 +350,9 @@ type Signer interface {
|
||||
// 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.
|
||||
// An AlgorithmSigner can't advertise the algorithms it supports, unless it also
|
||||
// implements MultiAlgorithmSigner, so it should be prepared to be invoked with
|
||||
// every algorithm supported by the public key format.
|
||||
type AlgorithmSigner interface {
|
||||
Signer
|
||||
|
||||
@ -349,6 +363,75 @@ type AlgorithmSigner interface {
|
||||
SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error)
|
||||
}
|
||||
|
||||
// MultiAlgorithmSigner is an AlgorithmSigner that also reports the algorithms
|
||||
// supported by that signer.
|
||||
type MultiAlgorithmSigner interface {
|
||||
AlgorithmSigner
|
||||
|
||||
// Algorithms returns the available algorithms in preference order. The list
|
||||
// must not be empty, and it must not include certificate types.
|
||||
Algorithms() []string
|
||||
}
|
||||
|
||||
// NewSignerWithAlgorithms returns a signer restricted to the specified
|
||||
// algorithms. The algorithms must be set in preference order. The list must not
|
||||
// be empty, and it must not include certificate types. An error is returned if
|
||||
// the specified algorithms are incompatible with the public key type.
|
||||
func NewSignerWithAlgorithms(signer AlgorithmSigner, algorithms []string) (MultiAlgorithmSigner, error) {
|
||||
if len(algorithms) == 0 {
|
||||
return nil, errors.New("ssh: please specify at least one valid signing algorithm")
|
||||
}
|
||||
var signerAlgos []string
|
||||
supportedAlgos := algorithmsForKeyFormat(underlyingAlgo(signer.PublicKey().Type()))
|
||||
if s, ok := signer.(*multiAlgorithmSigner); ok {
|
||||
signerAlgos = s.Algorithms()
|
||||
} else {
|
||||
signerAlgos = supportedAlgos
|
||||
}
|
||||
|
||||
for _, algo := range algorithms {
|
||||
if !contains(supportedAlgos, algo) {
|
||||
return nil, fmt.Errorf("ssh: algorithm %q is not supported for key type %q",
|
||||
algo, signer.PublicKey().Type())
|
||||
}
|
||||
if !contains(signerAlgos, algo) {
|
||||
return nil, fmt.Errorf("ssh: algorithm %q is restricted for the provided signer", algo)
|
||||
}
|
||||
}
|
||||
return &multiAlgorithmSigner{
|
||||
AlgorithmSigner: signer,
|
||||
supportedAlgorithms: algorithms,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type multiAlgorithmSigner struct {
|
||||
AlgorithmSigner
|
||||
supportedAlgorithms []string
|
||||
}
|
||||
|
||||
func (s *multiAlgorithmSigner) Algorithms() []string {
|
||||
return s.supportedAlgorithms
|
||||
}
|
||||
|
||||
func (s *multiAlgorithmSigner) isAlgorithmSupported(algorithm string) bool {
|
||||
if algorithm == "" {
|
||||
algorithm = underlyingAlgo(s.PublicKey().Type())
|
||||
}
|
||||
for _, algo := range s.supportedAlgorithms {
|
||||
if algorithm == algo {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *multiAlgorithmSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
|
||||
if !s.isAlgorithmSupported(algorithm) {
|
||||
return nil, fmt.Errorf("ssh: algorithm %q is not supported: %v", algorithm, s.supportedAlgorithms)
|
||||
}
|
||||
return s.AlgorithmSigner.SignWithAlgorithm(rand, data, algorithm)
|
||||
}
|
||||
|
||||
type rsaPublicKey rsa.PublicKey
|
||||
|
||||
func (r *rsaPublicKey) Type() string {
|
||||
@ -512,6 +595,10 @@ func (k *dsaPrivateKey) Sign(rand io.Reader, data []byte) (*Signature, error) {
|
||||
return k.SignWithAlgorithm(rand, data, k.PublicKey().Type())
|
||||
}
|
||||
|
||||
func (k *dsaPrivateKey) Algorithms() []string {
|
||||
return []string{k.PublicKey().Type()}
|
||||
}
|
||||
|
||||
func (k *dsaPrivateKey) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
|
||||
if algorithm != "" && algorithm != k.PublicKey().Type() {
|
||||
return nil, fmt.Errorf("ssh: unsupported signature algorithm %s", algorithm)
|
||||
@ -961,13 +1048,16 @@ func (s *wrappedSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
|
||||
return s.SignWithAlgorithm(rand, data, s.pubKey.Type())
|
||||
}
|
||||
|
||||
func (s *wrappedSigner) Algorithms() []string {
|
||||
return algorithmsForKeyFormat(s.pubKey.Type())
|
||||
}
|
||||
|
||||
func (s *wrappedSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
|
||||
if algorithm == "" {
|
||||
algorithm = s.pubKey.Type()
|
||||
}
|
||||
|
||||
supportedAlgos := algorithmsForKeyFormat(s.pubKey.Type())
|
||||
if !contains(supportedAlgos, algorithm) {
|
||||
if !contains(s.Algorithms(), algorithm) {
|
||||
return nil, fmt.Errorf("ssh: unsupported signature algorithm %q for key format %q", algorithm, s.pubKey.Type())
|
||||
}
|
||||
|
||||
@ -1087,9 +1177,9 @@ func (*PassphraseMissingError) Error() string {
|
||||
return "ssh: this private key is passphrase protected"
|
||||
}
|
||||
|
||||
// ParseRawPrivateKey returns a private key from a PEM encoded private key. It
|
||||
// supports RSA (PKCS#1), PKCS#8, DSA (OpenSSL), and ECDSA private keys. If the
|
||||
// private key is encrypted, it will return a PassphraseMissingError.
|
||||
// ParseRawPrivateKey returns a private key from a PEM encoded private key. It supports
|
||||
// RSA, DSA, ECDSA, and Ed25519 private keys in PKCS#1, PKCS#8, OpenSSL, and OpenSSH
|
||||
// formats. If the private key is encrypted, it will return a PassphraseMissingError.
|
||||
func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) {
|
||||
block, _ := pem.Decode(pemBytes)
|
||||
if block == nil {
|
||||
@ -1241,28 +1331,106 @@ func passphraseProtectedOpenSSHKey(passphrase []byte) openSSHDecryptFunc {
|
||||
}
|
||||
}
|
||||
|
||||
func unencryptedOpenSSHMarshaler(privKeyBlock []byte) ([]byte, string, string, string, error) {
|
||||
key := generateOpenSSHPadding(privKeyBlock, 8)
|
||||
return key, "none", "none", "", nil
|
||||
}
|
||||
|
||||
func passphraseProtectedOpenSSHMarshaler(passphrase []byte) openSSHEncryptFunc {
|
||||
return func(privKeyBlock []byte) ([]byte, string, string, string, error) {
|
||||
salt := make([]byte, 16)
|
||||
if _, err := rand.Read(salt); err != nil {
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
|
||||
opts := struct {
|
||||
Salt []byte
|
||||
Rounds uint32
|
||||
}{salt, 16}
|
||||
|
||||
// Derive key to encrypt the private key block.
|
||||
k, err := bcrypt_pbkdf.Key(passphrase, salt, int(opts.Rounds), 32+aes.BlockSize)
|
||||
if err != nil {
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
|
||||
// Add padding matching the block size of AES.
|
||||
keyBlock := generateOpenSSHPadding(privKeyBlock, aes.BlockSize)
|
||||
|
||||
// Encrypt the private key using the derived secret.
|
||||
|
||||
dst := make([]byte, len(keyBlock))
|
||||
key, iv := k[:32], k[32:]
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, "", "", "", err
|
||||
}
|
||||
|
||||
stream := cipher.NewCTR(block, iv)
|
||||
stream.XORKeyStream(dst, keyBlock)
|
||||
|
||||
return dst, "aes256-ctr", "bcrypt", string(Marshal(opts)), nil
|
||||
}
|
||||
}
|
||||
|
||||
const privateKeyAuthMagic = "openssh-key-v1\x00"
|
||||
|
||||
type openSSHDecryptFunc func(CipherName, KdfName, KdfOpts string, PrivKeyBlock []byte) ([]byte, error)
|
||||
type openSSHEncryptFunc func(PrivKeyBlock []byte) (ProtectedKeyBlock []byte, cipherName, kdfName, kdfOptions string, err error)
|
||||
|
||||
type openSSHEncryptedPrivateKey struct {
|
||||
CipherName string
|
||||
KdfName string
|
||||
KdfOpts string
|
||||
NumKeys uint32
|
||||
PubKey []byte
|
||||
PrivKeyBlock []byte
|
||||
}
|
||||
|
||||
type openSSHPrivateKey struct {
|
||||
Check1 uint32
|
||||
Check2 uint32
|
||||
Keytype string
|
||||
Rest []byte `ssh:"rest"`
|
||||
}
|
||||
|
||||
type openSSHRSAPrivateKey struct {
|
||||
N *big.Int
|
||||
E *big.Int
|
||||
D *big.Int
|
||||
Iqmp *big.Int
|
||||
P *big.Int
|
||||
Q *big.Int
|
||||
Comment string
|
||||
Pad []byte `ssh:"rest"`
|
||||
}
|
||||
|
||||
type openSSHEd25519PrivateKey struct {
|
||||
Pub []byte
|
||||
Priv []byte
|
||||
Comment string
|
||||
Pad []byte `ssh:"rest"`
|
||||
}
|
||||
|
||||
type openSSHECDSAPrivateKey struct {
|
||||
Curve string
|
||||
Pub []byte
|
||||
D *big.Int
|
||||
Comment string
|
||||
Pad []byte `ssh:"rest"`
|
||||
}
|
||||
|
||||
// parseOpenSSHPrivateKey parses an OpenSSH private key, using the decrypt
|
||||
// function to unwrap the encrypted portion. unencryptedOpenSSHKey can be used
|
||||
// as the decrypt function to parse an unencrypted private key. See
|
||||
// https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key.
|
||||
func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.PrivateKey, error) {
|
||||
const magic = "openssh-key-v1\x00"
|
||||
if len(key) < len(magic) || string(key[:len(magic)]) != magic {
|
||||
if len(key) < len(privateKeyAuthMagic) || string(key[:len(privateKeyAuthMagic)]) != privateKeyAuthMagic {
|
||||
return nil, errors.New("ssh: invalid openssh private key format")
|
||||
}
|
||||
remaining := key[len(magic):]
|
||||
|
||||
var w struct {
|
||||
CipherName string
|
||||
KdfName string
|
||||
KdfOpts string
|
||||
NumKeys uint32
|
||||
PubKey []byte
|
||||
PrivKeyBlock []byte
|
||||
}
|
||||
remaining := key[len(privateKeyAuthMagic):]
|
||||
|
||||
var w openSSHEncryptedPrivateKey
|
||||
if err := Unmarshal(remaining, &w); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1284,13 +1452,7 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pk1 := struct {
|
||||
Check1 uint32
|
||||
Check2 uint32
|
||||
Keytype string
|
||||
Rest []byte `ssh:"rest"`
|
||||
}{}
|
||||
|
||||
var pk1 openSSHPrivateKey
|
||||
if err := Unmarshal(privKeyBlock, &pk1); err != nil || pk1.Check1 != pk1.Check2 {
|
||||
if w.CipherName != "none" {
|
||||
return nil, x509.IncorrectPasswordError
|
||||
@ -1300,18 +1462,7 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv
|
||||
|
||||
switch pk1.Keytype {
|
||||
case KeyAlgoRSA:
|
||||
// https://github.com/openssh/openssh-portable/blob/master/sshkey.c#L2760-L2773
|
||||
key := struct {
|
||||
N *big.Int
|
||||
E *big.Int
|
||||
D *big.Int
|
||||
Iqmp *big.Int
|
||||
P *big.Int
|
||||
Q *big.Int
|
||||
Comment string
|
||||
Pad []byte `ssh:"rest"`
|
||||
}{}
|
||||
|
||||
var key openSSHRSAPrivateKey
|
||||
if err := Unmarshal(pk1.Rest, &key); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1337,13 +1488,7 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv
|
||||
|
||||
return pk, nil
|
||||
case KeyAlgoED25519:
|
||||
key := struct {
|
||||
Pub []byte
|
||||
Priv []byte
|
||||
Comment string
|
||||
Pad []byte `ssh:"rest"`
|
||||
}{}
|
||||
|
||||
var key openSSHEd25519PrivateKey
|
||||
if err := Unmarshal(pk1.Rest, &key); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1360,14 +1505,7 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv
|
||||
copy(pk, key.Priv)
|
||||
return &pk, nil
|
||||
case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:
|
||||
key := struct {
|
||||
Curve string
|
||||
Pub []byte
|
||||
D *big.Int
|
||||
Comment string
|
||||
Pad []byte `ssh:"rest"`
|
||||
}{}
|
||||
|
||||
var key openSSHECDSAPrivateKey
|
||||
if err := Unmarshal(pk1.Rest, &key); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1415,6 +1553,131 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv
|
||||
}
|
||||
}
|
||||
|
||||
func marshalOpenSSHPrivateKey(key crypto.PrivateKey, comment string, encrypt openSSHEncryptFunc) (*pem.Block, error) {
|
||||
var w openSSHEncryptedPrivateKey
|
||||
var pk1 openSSHPrivateKey
|
||||
|
||||
// Random check bytes.
|
||||
var check uint32
|
||||
if err := binary.Read(rand.Reader, binary.BigEndian, &check); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pk1.Check1 = check
|
||||
pk1.Check2 = check
|
||||
w.NumKeys = 1
|
||||
|
||||
// Use a []byte directly on ed25519 keys.
|
||||
if k, ok := key.(*ed25519.PrivateKey); ok {
|
||||
key = *k
|
||||
}
|
||||
|
||||
switch k := key.(type) {
|
||||
case *rsa.PrivateKey:
|
||||
E := new(big.Int).SetInt64(int64(k.PublicKey.E))
|
||||
// Marshal public key:
|
||||
// E and N are in reversed order in the public and private key.
|
||||
pubKey := struct {
|
||||
KeyType string
|
||||
E *big.Int
|
||||
N *big.Int
|
||||
}{
|
||||
KeyAlgoRSA,
|
||||
E, k.PublicKey.N,
|
||||
}
|
||||
w.PubKey = Marshal(pubKey)
|
||||
|
||||
// Marshal private key.
|
||||
key := openSSHRSAPrivateKey{
|
||||
N: k.PublicKey.N,
|
||||
E: E,
|
||||
D: k.D,
|
||||
Iqmp: k.Precomputed.Qinv,
|
||||
P: k.Primes[0],
|
||||
Q: k.Primes[1],
|
||||
Comment: comment,
|
||||
}
|
||||
pk1.Keytype = KeyAlgoRSA
|
||||
pk1.Rest = Marshal(key)
|
||||
case ed25519.PrivateKey:
|
||||
pub := make([]byte, ed25519.PublicKeySize)
|
||||
priv := make([]byte, ed25519.PrivateKeySize)
|
||||
copy(pub, k[32:])
|
||||
copy(priv, k)
|
||||
|
||||
// Marshal public key.
|
||||
pubKey := struct {
|
||||
KeyType string
|
||||
Pub []byte
|
||||
}{
|
||||
KeyAlgoED25519, pub,
|
||||
}
|
||||
w.PubKey = Marshal(pubKey)
|
||||
|
||||
// Marshal private key.
|
||||
key := openSSHEd25519PrivateKey{
|
||||
Pub: pub,
|
||||
Priv: priv,
|
||||
Comment: comment,
|
||||
}
|
||||
pk1.Keytype = KeyAlgoED25519
|
||||
pk1.Rest = Marshal(key)
|
||||
case *ecdsa.PrivateKey:
|
||||
var curve, keyType string
|
||||
switch name := k.Curve.Params().Name; name {
|
||||
case "P-256":
|
||||
curve = "nistp256"
|
||||
keyType = KeyAlgoECDSA256
|
||||
case "P-384":
|
||||
curve = "nistp384"
|
||||
keyType = KeyAlgoECDSA384
|
||||
case "P-521":
|
||||
curve = "nistp521"
|
||||
keyType = KeyAlgoECDSA521
|
||||
default:
|
||||
return nil, errors.New("ssh: unhandled elliptic curve " + name)
|
||||
}
|
||||
|
||||
pub := elliptic.Marshal(k.Curve, k.PublicKey.X, k.PublicKey.Y)
|
||||
|
||||
// Marshal public key.
|
||||
pubKey := struct {
|
||||
KeyType string
|
||||
Curve string
|
||||
Pub []byte
|
||||
}{
|
||||
keyType, curve, pub,
|
||||
}
|
||||
w.PubKey = Marshal(pubKey)
|
||||
|
||||
// Marshal private key.
|
||||
key := openSSHECDSAPrivateKey{
|
||||
Curve: curve,
|
||||
Pub: pub,
|
||||
D: k.D,
|
||||
Comment: comment,
|
||||
}
|
||||
pk1.Keytype = keyType
|
||||
pk1.Rest = Marshal(key)
|
||||
default:
|
||||
return nil, fmt.Errorf("ssh: unsupported key type %T", k)
|
||||
}
|
||||
|
||||
var err error
|
||||
// Add padding and encrypt the key if necessary.
|
||||
w.PrivKeyBlock, w.CipherName, w.KdfName, w.KdfOpts, err = encrypt(Marshal(pk1))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b := Marshal(w)
|
||||
block := &pem.Block{
|
||||
Type: "OPENSSH PRIVATE KEY",
|
||||
Bytes: append([]byte(privateKeyAuthMagic), b...),
|
||||
}
|
||||
return block, nil
|
||||
}
|
||||
|
||||
func checkOpenSSHKeyPadding(pad []byte) error {
|
||||
for i, b := range pad {
|
||||
if int(b) != i+1 {
|
||||
@ -1424,6 +1687,13 @@ func checkOpenSSHKeyPadding(pad []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func generateOpenSSHPadding(block []byte, blockSize int) []byte {
|
||||
for i, l := 0, len(block); (l+i)%blockSize != 0; i++ {
|
||||
block = append(block, byte(i+1))
|
||||
}
|
||||
return block
|
||||
}
|
||||
|
||||
// FingerprintLegacyMD5 returns the user presentation of the key's
|
||||
// fingerprint as described by RFC 4716 section 4.
|
||||
func FingerprintLegacyMD5(pubKey PublicKey) string {
|
||||
|
7
vendor/golang.org/x/crypto/ssh/mac.go
generated
vendored
7
vendor/golang.org/x/crypto/ssh/mac.go
generated
vendored
@ -10,6 +10,7 @@ import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"hash"
|
||||
)
|
||||
|
||||
@ -46,9 +47,15 @@ func (t truncatingMAC) Size() int {
|
||||
func (t truncatingMAC) BlockSize() int { return t.hmac.BlockSize() }
|
||||
|
||||
var macModes = map[string]*macMode{
|
||||
"hmac-sha2-512-etm@openssh.com": {64, true, func(key []byte) hash.Hash {
|
||||
return hmac.New(sha512.New, key)
|
||||
}},
|
||||
"hmac-sha2-256-etm@openssh.com": {32, true, func(key []byte) hash.Hash {
|
||||
return hmac.New(sha256.New, key)
|
||||
}},
|
||||
"hmac-sha2-512": {64, false, func(key []byte) hash.Hash {
|
||||
return hmac.New(sha512.New, key)
|
||||
}},
|
||||
"hmac-sha2-256": {32, false, func(key []byte) hash.Hash {
|
||||
return hmac.New(sha256.New, key)
|
||||
}},
|
||||
|
14
vendor/golang.org/x/crypto/ssh/messages.go
generated
vendored
14
vendor/golang.org/x/crypto/ssh/messages.go
generated
vendored
@ -349,6 +349,20 @@ type userAuthGSSAPIError struct {
|
||||
LanguageTag string
|
||||
}
|
||||
|
||||
// Transport layer OpenSSH extension. See [PROTOCOL], section 1.9
|
||||
const msgPing = 192
|
||||
|
||||
type pingMsg struct {
|
||||
Data string `sshtype:"192"`
|
||||
}
|
||||
|
||||
// Transport layer OpenSSH extension. See [PROTOCOL], section 1.9
|
||||
const msgPong = 193
|
||||
|
||||
type pongMsg struct {
|
||||
Data string `sshtype:"193"`
|
||||
}
|
||||
|
||||
// typeTags returns the possible type bytes for the given reflect.Type, which
|
||||
// should be a struct. The possible values are separated by a '|' character.
|
||||
func typeTags(structType reflect.Type) (tags []byte) {
|
||||
|
6
vendor/golang.org/x/crypto/ssh/mux.go
generated
vendored
6
vendor/golang.org/x/crypto/ssh/mux.go
generated
vendored
@ -231,6 +231,12 @@ func (m *mux) onePacket() error {
|
||||
return m.handleChannelOpen(packet)
|
||||
case msgGlobalRequest, msgRequestSuccess, msgRequestFailure:
|
||||
return m.handleGlobalPacket(packet)
|
||||
case msgPing:
|
||||
var msg pingMsg
|
||||
if err := Unmarshal(packet, &msg); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal ping@openssh.com message: %w", err)
|
||||
}
|
||||
return m.sendMessage(pongMsg(msg))
|
||||
}
|
||||
|
||||
// assume a channel packet.
|
||||
|
45
vendor/golang.org/x/crypto/ssh/server.go
generated
vendored
45
vendor/golang.org/x/crypto/ssh/server.go
generated
vendored
@ -291,15 +291,6 @@ func (s *connection) serverHandshake(config *ServerConfig) (*Permissions, error)
|
||||
return perms, err
|
||||
}
|
||||
|
||||
func isAcceptableAlgo(algo string) bool {
|
||||
switch algo {
|
||||
case KeyAlgoRSA, KeyAlgoRSASHA256, KeyAlgoRSASHA512, 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")
|
||||
@ -379,6 +370,25 @@ func gssExchangeToken(gssapiConfig *GSSAPIWithMICConfig, firstToken []byte, s *c
|
||||
return authErr, perms, nil
|
||||
}
|
||||
|
||||
// isAlgoCompatible checks if the signature format is compatible with the
|
||||
// selected algorithm taking into account edge cases that occur with old
|
||||
// clients.
|
||||
func isAlgoCompatible(algo, sigFormat string) bool {
|
||||
// Compatibility for old clients.
|
||||
//
|
||||
// For certificate authentication with OpenSSH 7.2-7.7 signature format can
|
||||
// be rsa-sha2-256 or rsa-sha2-512 for the algorithm
|
||||
// ssh-rsa-cert-v01@openssh.com.
|
||||
//
|
||||
// With gpg-agent < 2.2.6 the algorithm can be rsa-sha2-256 or rsa-sha2-512
|
||||
// for signature format ssh-rsa.
|
||||
if isRSA(algo) && isRSA(sigFormat) {
|
||||
return true
|
||||
}
|
||||
// Standard case: the underlying algorithm must match the signature format.
|
||||
return underlyingAlgo(algo) == sigFormat
|
||||
}
|
||||
|
||||
// ServerAuthError represents server authentication errors and is
|
||||
// sometimes returned by NewServerConn. It appends any authentication
|
||||
// errors that may occur, and is returned if all of the authentication
|
||||
@ -514,7 +524,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
|
||||
}
|
||||
@ -566,17 +576,26 @@ userAuthLoop:
|
||||
if !ok || len(payload) > 0 {
|
||||
return nil, parseError(msgUserAuthRequest)
|
||||
}
|
||||
|
||||
// Ensure the declared public key algo is compatible with the
|
||||
// decoded one. This check will ensure we don't accept e.g.
|
||||
// ssh-rsa-cert-v01@openssh.com algorithm with ssh-rsa public
|
||||
// key type. The algorithm and public key type must be
|
||||
// consistent: both must be certificate algorithms, or neither.
|
||||
if !contains(algorithmsForKeyFormat(pubKey.Type()), algo) {
|
||||
authErr = fmt.Errorf("ssh: public key type %q not compatible with selected algorithm %q",
|
||||
pubKey.Type(), algo)
|
||||
break
|
||||
}
|
||||
// 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
|
||||
}
|
||||
if underlyingAlgo(algo) != sig.Format {
|
||||
if !isAlgoCompatible(algo, sig.Format) {
|
||||
authErr = fmt.Errorf("ssh: signature %q not compatible with selected algorithm %q", sig.Format, algo)
|
||||
break
|
||||
}
|
||||
|
3
vendor/golang.org/x/crypto/ssh/transport.go
generated
vendored
3
vendor/golang.org/x/crypto/ssh/transport.go
generated
vendored
@ -17,7 +17,8 @@ import (
|
||||
const debugTransport = false
|
||||
|
||||
const (
|
||||
gcmCipherID = "aes128-gcm@openssh.com"
|
||||
gcm128CipherID = "aes128-gcm@openssh.com"
|
||||
gcm256CipherID = "aes256-gcm@openssh.com"
|
||||
aes128cbcID = "aes128-cbc"
|
||||
tripledescbcID = "3des-cbc"
|
||||
)
|
||||
|
Reference in New Issue
Block a user