mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 01:53:42 +08:00 
			
		
		
		
	vendor: update buildkit to master@d5c1d785b042
Signed-off-by: Justin Chadwell <me@jedevc.com>
This commit is contained in:
		
							
								
								
									
										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