keys.go raw

   1  // Copyright 2012 The Go Authors. All rights reserved.
   2  // Use of this source code is governed by a BSD-style
   3  // license that can be found in the LICENSE file.
   4  
   5  package ssh
   6  
   7  import (
   8  	"bytes"
   9  	"crypto"
  10  	"crypto/aes"
  11  	"crypto/cipher"
  12  	"crypto/dsa"
  13  	"crypto/ecdsa"
  14  	"crypto/ed25519"
  15  	"crypto/elliptic"
  16  	"crypto/md5"
  17  	"crypto/rand"
  18  	"crypto/rsa"
  19  	"crypto/sha256"
  20  	"crypto/x509"
  21  	"encoding/asn1"
  22  	"encoding/base64"
  23  	"encoding/binary"
  24  	"encoding/hex"
  25  	"encoding/pem"
  26  	"errors"
  27  	"fmt"
  28  	"io"
  29  	"math/big"
  30  	"slices"
  31  	"strings"
  32  
  33  	"golang.org/x/crypto/ssh/internal/bcrypt_pbkdf"
  34  )
  35  
  36  // Public key algorithms names. These values can appear in PublicKey.Type,
  37  // ClientConfig.HostKeyAlgorithms, Signature.Format, or as AlgorithmSigner
  38  // arguments.
  39  const (
  40  	KeyAlgoRSA = "ssh-rsa"
  41  	// Deprecated: DSA is only supported at insecure key sizes, and was removed
  42  	// from major implementations.
  43  	KeyAlgoDSA = InsecureKeyAlgoDSA
  44  	// Deprecated: DSA is only supported at insecure key sizes, and was removed
  45  	// from major implementations.
  46  	InsecureKeyAlgoDSA = "ssh-dss"
  47  	KeyAlgoECDSA256    = "ecdsa-sha2-nistp256"
  48  	KeyAlgoSKECDSA256  = "sk-ecdsa-sha2-nistp256@openssh.com"
  49  	KeyAlgoECDSA384    = "ecdsa-sha2-nistp384"
  50  	KeyAlgoECDSA521    = "ecdsa-sha2-nistp521"
  51  	KeyAlgoED25519     = "ssh-ed25519"
  52  	KeyAlgoSKED25519   = "sk-ssh-ed25519@openssh.com"
  53  
  54  	// KeyAlgoRSASHA256 and KeyAlgoRSASHA512 are only public key algorithms, not
  55  	// public key formats, so they can't appear as a PublicKey.Type. The
  56  	// corresponding PublicKey.Type is KeyAlgoRSA. See RFC 8332, Section 2.
  57  	KeyAlgoRSASHA256 = "rsa-sha2-256"
  58  	KeyAlgoRSASHA512 = "rsa-sha2-512"
  59  )
  60  
  61  const (
  62  	// Deprecated: use KeyAlgoRSA.
  63  	SigAlgoRSA = KeyAlgoRSA
  64  	// Deprecated: use KeyAlgoRSASHA256.
  65  	SigAlgoRSASHA2256 = KeyAlgoRSASHA256
  66  	// Deprecated: use KeyAlgoRSASHA512.
  67  	SigAlgoRSASHA2512 = KeyAlgoRSASHA512
  68  )
  69  
  70  // parsePubKey parses a public key of the given algorithm.
  71  // Use ParsePublicKey for keys with prepended algorithm.
  72  func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err error) {
  73  	switch algo {
  74  	case KeyAlgoRSA:
  75  		return parseRSA(in)
  76  	case InsecureKeyAlgoDSA:
  77  		return parseDSA(in)
  78  	case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:
  79  		return parseECDSA(in)
  80  	case KeyAlgoSKECDSA256:
  81  		return parseSKECDSA(in)
  82  	case KeyAlgoED25519:
  83  		return parseED25519(in)
  84  	case KeyAlgoSKED25519:
  85  		return parseSKEd25519(in)
  86  	case CertAlgoRSAv01, InsecureCertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01:
  87  		cert, err := parseCert(in, certKeyAlgoNames[algo])
  88  		if err != nil {
  89  			return nil, nil, err
  90  		}
  91  		return cert, nil, nil
  92  	}
  93  	if keyFormat := keyFormatForAlgorithm(algo); keyFormat != "" {
  94  		return nil, nil, fmt.Errorf("ssh: signature algorithm %q isn't a key format; key is malformed and should be re-encoded with type %q",
  95  			algo, keyFormat)
  96  	}
  97  
  98  	return nil, nil, fmt.Errorf("ssh: unknown key algorithm: %v", algo)
  99  }
 100  
 101  // parseAuthorizedKey parses a public key in OpenSSH authorized_keys format
 102  // (see sshd(8) manual page) once the options and key type fields have been
 103  // removed.
 104  func parseAuthorizedKey(in []byte) (out PublicKey, comment string, err error) {
 105  	in = bytes.TrimSpace(in)
 106  
 107  	i := bytes.IndexAny(in, " \t")
 108  	if i == -1 {
 109  		i = len(in)
 110  	}
 111  	base64Key := in[:i]
 112  
 113  	key := make([]byte, base64.StdEncoding.DecodedLen(len(base64Key)))
 114  	n, err := base64.StdEncoding.Decode(key, base64Key)
 115  	if err != nil {
 116  		return nil, "", err
 117  	}
 118  	key = key[:n]
 119  	out, err = ParsePublicKey(key)
 120  	if err != nil {
 121  		return nil, "", err
 122  	}
 123  	comment = string(bytes.TrimSpace(in[i:]))
 124  	return out, comment, nil
 125  }
 126  
 127  // ParseKnownHosts parses an entry in the format of the known_hosts file.
 128  //
 129  // The known_hosts format is documented in the sshd(8) manual page. This
 130  // function will parse a single entry from in. On successful return, marker
 131  // will contain the optional marker value (i.e. "cert-authority" or "revoked")
 132  // or else be empty, hosts will contain the hosts that this entry matches,
 133  // pubKey will contain the public key and comment will contain any trailing
 134  // comment at the end of the line. See the sshd(8) manual page for the various
 135  // forms that a host string can take.
 136  //
 137  // The unparsed remainder of the input will be returned in rest. This function
 138  // can be called repeatedly to parse multiple entries.
 139  //
 140  // If no entries were found in the input then err will be io.EOF. Otherwise a
 141  // non-nil err value indicates a parse error.
 142  func ParseKnownHosts(in []byte) (marker string, hosts []string, pubKey PublicKey, comment string, rest []byte, err error) {
 143  	for len(in) > 0 {
 144  		end := bytes.IndexByte(in, '\n')
 145  		if end != -1 {
 146  			rest = in[end+1:]
 147  			in = in[:end]
 148  		} else {
 149  			rest = nil
 150  		}
 151  
 152  		end = bytes.IndexByte(in, '\r')
 153  		if end != -1 {
 154  			in = in[:end]
 155  		}
 156  
 157  		in = bytes.TrimSpace(in)
 158  		if len(in) == 0 || in[0] == '#' {
 159  			in = rest
 160  			continue
 161  		}
 162  
 163  		i := bytes.IndexAny(in, " \t")
 164  		if i == -1 {
 165  			in = rest
 166  			continue
 167  		}
 168  
 169  		// Strip out the beginning of the known_host key.
 170  		// This is either an optional marker or a (set of) hostname(s).
 171  		keyFields := bytes.Fields(in)
 172  		if len(keyFields) < 3 || len(keyFields) > 5 {
 173  			return "", nil, nil, "", nil, errors.New("ssh: invalid entry in known_hosts data")
 174  		}
 175  
 176  		// keyFields[0] is either "@cert-authority", "@revoked" or a comma separated
 177  		// list of hosts
 178  		marker := ""
 179  		if keyFields[0][0] == '@' {
 180  			marker = string(keyFields[0][1:])
 181  			keyFields = keyFields[1:]
 182  		}
 183  
 184  		hosts := string(keyFields[0])
 185  		// keyFields[1] contains the key type (e.g. “ssh-rsa”).
 186  		// However, that information is duplicated inside the
 187  		// base64-encoded key and so is ignored here.
 188  
 189  		key := bytes.Join(keyFields[2:], []byte(" "))
 190  		if pubKey, comment, err = parseAuthorizedKey(key); err != nil {
 191  			return "", nil, nil, "", nil, err
 192  		}
 193  
 194  		return marker, strings.Split(hosts, ","), pubKey, comment, rest, nil
 195  	}
 196  
 197  	return "", nil, nil, "", nil, io.EOF
 198  }
 199  
 200  // ParseAuthorizedKey parses a public key from an authorized_keys file used in
 201  // OpenSSH according to the sshd(8) manual page. Invalid lines are ignored.
 202  func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error) {
 203  	var lastErr error
 204  	for len(in) > 0 {
 205  		end := bytes.IndexByte(in, '\n')
 206  		if end != -1 {
 207  			rest = in[end+1:]
 208  			in = in[:end]
 209  		} else {
 210  			rest = nil
 211  		}
 212  
 213  		end = bytes.IndexByte(in, '\r')
 214  		if end != -1 {
 215  			in = in[:end]
 216  		}
 217  
 218  		in = bytes.TrimSpace(in)
 219  		if len(in) == 0 || in[0] == '#' {
 220  			in = rest
 221  			continue
 222  		}
 223  
 224  		i := bytes.IndexAny(in, " \t")
 225  		if i == -1 {
 226  			in = rest
 227  			continue
 228  		}
 229  
 230  		if out, comment, err = parseAuthorizedKey(in[i:]); err == nil {
 231  			return out, comment, options, rest, nil
 232  		} else {
 233  			lastErr = err
 234  		}
 235  
 236  		// No key type recognised. Maybe there's an options field at
 237  		// the beginning.
 238  		var b byte
 239  		inQuote := false
 240  		var candidateOptions []string
 241  		optionStart := 0
 242  		for i, b = range in {
 243  			isEnd := !inQuote && (b == ' ' || b == '\t')
 244  			if (b == ',' && !inQuote) || isEnd {
 245  				if i-optionStart > 0 {
 246  					candidateOptions = append(candidateOptions, string(in[optionStart:i]))
 247  				}
 248  				optionStart = i + 1
 249  			}
 250  			if isEnd {
 251  				break
 252  			}
 253  			if b == '"' && (i == 0 || (i > 0 && in[i-1] != '\\')) {
 254  				inQuote = !inQuote
 255  			}
 256  		}
 257  		for i < len(in) && (in[i] == ' ' || in[i] == '\t') {
 258  			i++
 259  		}
 260  		if i == len(in) {
 261  			// Invalid line: unmatched quote
 262  			in = rest
 263  			continue
 264  		}
 265  
 266  		in = in[i:]
 267  		i = bytes.IndexAny(in, " \t")
 268  		if i == -1 {
 269  			in = rest
 270  			continue
 271  		}
 272  
 273  		if out, comment, err = parseAuthorizedKey(in[i:]); err == nil {
 274  			options = candidateOptions
 275  			return out, comment, options, rest, nil
 276  		} else {
 277  			lastErr = err
 278  		}
 279  
 280  		in = rest
 281  		continue
 282  	}
 283  
 284  	if lastErr != nil {
 285  		return nil, "", nil, nil, fmt.Errorf("ssh: no key found; last parsing error for ignored line: %w", lastErr)
 286  	}
 287  
 288  	return nil, "", nil, nil, errors.New("ssh: no key found")
 289  }
 290  
 291  // ParsePublicKey parses an SSH public key or certificate formatted for use in
 292  // the SSH wire protocol according to RFC 4253, section 6.6.
 293  func ParsePublicKey(in []byte) (out PublicKey, err error) {
 294  	algo, in, ok := parseString(in)
 295  	if !ok {
 296  		return nil, errShortRead
 297  	}
 298  	var rest []byte
 299  	out, rest, err = parsePubKey(in, string(algo))
 300  	if len(rest) > 0 {
 301  		return nil, errors.New("ssh: trailing junk in public key")
 302  	}
 303  
 304  	return out, err
 305  }
 306  
 307  // MarshalAuthorizedKey serializes key for inclusion in an OpenSSH
 308  // authorized_keys file. The return value ends with newline.
 309  func MarshalAuthorizedKey(key PublicKey) []byte {
 310  	b := &bytes.Buffer{}
 311  	b.WriteString(key.Type())
 312  	b.WriteByte(' ')
 313  	e := base64.NewEncoder(base64.StdEncoding, b)
 314  	e.Write(key.Marshal())
 315  	e.Close()
 316  	b.WriteByte('\n')
 317  	return b.Bytes()
 318  }
 319  
 320  // MarshalPrivateKey returns a PEM block with the private key serialized in the
 321  // OpenSSH format.
 322  func MarshalPrivateKey(key crypto.PrivateKey, comment string) (*pem.Block, error) {
 323  	return marshalOpenSSHPrivateKey(key, comment, unencryptedOpenSSHMarshaler)
 324  }
 325  
 326  // MarshalPrivateKeyWithPassphrase returns a PEM block holding the encrypted
 327  // private key serialized in the OpenSSH format.
 328  func MarshalPrivateKeyWithPassphrase(key crypto.PrivateKey, comment string, passphrase []byte) (*pem.Block, error) {
 329  	return marshalOpenSSHPrivateKey(key, comment, passphraseProtectedOpenSSHMarshaler(passphrase))
 330  }
 331  
 332  // PublicKey represents a public key using an unspecified algorithm.
 333  //
 334  // Some PublicKeys provided by this package also implement CryptoPublicKey.
 335  type PublicKey interface {
 336  	// Type returns the key format name, e.g. "ssh-rsa".
 337  	Type() string
 338  
 339  	// Marshal returns the serialized key data in SSH wire format, with the name
 340  	// prefix. To unmarshal the returned data, use the ParsePublicKey function.
 341  	Marshal() []byte
 342  
 343  	// Verify that sig is a signature on the given data using this key. This
 344  	// method will hash the data appropriately first. sig.Format is allowed to
 345  	// be any signature algorithm compatible with the key type, the caller
 346  	// should check if it has more stringent requirements.
 347  	Verify(data []byte, sig *Signature) error
 348  }
 349  
 350  // CryptoPublicKey, if implemented by a PublicKey,
 351  // returns the underlying crypto.PublicKey form of the key.
 352  type CryptoPublicKey interface {
 353  	CryptoPublicKey() crypto.PublicKey
 354  }
 355  
 356  // A Signer can create signatures that verify against a public key.
 357  //
 358  // Some Signers provided by this package also implement MultiAlgorithmSigner.
 359  type Signer interface {
 360  	// PublicKey returns the associated PublicKey.
 361  	PublicKey() PublicKey
 362  
 363  	// Sign returns a signature for the given data. This method will hash the
 364  	// data appropriately first. The signature algorithm is expected to match
 365  	// the key format returned by the PublicKey.Type method (and not to be any
 366  	// alternative algorithm supported by the key format).
 367  	Sign(rand io.Reader, data []byte) (*Signature, error)
 368  }
 369  
 370  // An AlgorithmSigner is a Signer that also supports specifying an algorithm to
 371  // use for signing.
 372  //
 373  // An AlgorithmSigner can't advertise the algorithms it supports, unless it also
 374  // implements MultiAlgorithmSigner, so it should be prepared to be invoked with
 375  // every algorithm supported by the public key format.
 376  type AlgorithmSigner interface {
 377  	Signer
 378  
 379  	// SignWithAlgorithm is like Signer.Sign, but allows specifying a desired
 380  	// signing algorithm. Callers may pass an empty string for the algorithm in
 381  	// which case the AlgorithmSigner will use a default algorithm. This default
 382  	// doesn't currently control any behavior in this package.
 383  	SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error)
 384  }
 385  
 386  // MultiAlgorithmSigner is an AlgorithmSigner that also reports the algorithms
 387  // supported by that signer.
 388  type MultiAlgorithmSigner interface {
 389  	AlgorithmSigner
 390  
 391  	// Algorithms returns the available algorithms in preference order. The list
 392  	// must not be empty, and it must not include certificate types.
 393  	Algorithms() []string
 394  }
 395  
 396  // NewSignerWithAlgorithms returns a signer restricted to the specified
 397  // algorithms. The algorithms must be set in preference order. The list must not
 398  // be empty, and it must not include certificate types. An error is returned if
 399  // the specified algorithms are incompatible with the public key type.
 400  func NewSignerWithAlgorithms(signer AlgorithmSigner, algorithms []string) (MultiAlgorithmSigner, error) {
 401  	if len(algorithms) == 0 {
 402  		return nil, errors.New("ssh: please specify at least one valid signing algorithm")
 403  	}
 404  	var signerAlgos []string
 405  	supportedAlgos := algorithmsForKeyFormat(underlyingAlgo(signer.PublicKey().Type()))
 406  	if s, ok := signer.(*multiAlgorithmSigner); ok {
 407  		signerAlgos = s.Algorithms()
 408  	} else {
 409  		signerAlgos = supportedAlgos
 410  	}
 411  
 412  	for _, algo := range algorithms {
 413  		if !slices.Contains(supportedAlgos, algo) {
 414  			return nil, fmt.Errorf("ssh: algorithm %q is not supported for key type %q",
 415  				algo, signer.PublicKey().Type())
 416  		}
 417  		if !slices.Contains(signerAlgos, algo) {
 418  			return nil, fmt.Errorf("ssh: algorithm %q is restricted for the provided signer", algo)
 419  		}
 420  	}
 421  	return &multiAlgorithmSigner{
 422  		AlgorithmSigner:     signer,
 423  		supportedAlgorithms: algorithms,
 424  	}, nil
 425  }
 426  
 427  type multiAlgorithmSigner struct {
 428  	AlgorithmSigner
 429  	supportedAlgorithms []string
 430  }
 431  
 432  func (s *multiAlgorithmSigner) Algorithms() []string {
 433  	return s.supportedAlgorithms
 434  }
 435  
 436  func (s *multiAlgorithmSigner) isAlgorithmSupported(algorithm string) bool {
 437  	if algorithm == "" {
 438  		algorithm = underlyingAlgo(s.PublicKey().Type())
 439  	}
 440  	for _, algo := range s.supportedAlgorithms {
 441  		if algorithm == algo {
 442  			return true
 443  		}
 444  	}
 445  	return false
 446  }
 447  
 448  func (s *multiAlgorithmSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
 449  	if !s.isAlgorithmSupported(algorithm) {
 450  		return nil, fmt.Errorf("ssh: algorithm %q is not supported: %v", algorithm, s.supportedAlgorithms)
 451  	}
 452  	return s.AlgorithmSigner.SignWithAlgorithm(rand, data, algorithm)
 453  }
 454  
 455  type rsaPublicKey rsa.PublicKey
 456  
 457  func (r *rsaPublicKey) Type() string {
 458  	return "ssh-rsa"
 459  }
 460  
 461  // parseRSA parses an RSA key according to RFC 4253, section 6.6.
 462  func parseRSA(in []byte) (out PublicKey, rest []byte, err error) {
 463  	var w struct {
 464  		E    *big.Int
 465  		N    *big.Int
 466  		Rest []byte `ssh:"rest"`
 467  	}
 468  	if err := Unmarshal(in, &w); err != nil {
 469  		return nil, nil, err
 470  	}
 471  
 472  	if w.E.BitLen() > 24 {
 473  		return nil, nil, errors.New("ssh: exponent too large")
 474  	}
 475  	e := w.E.Int64()
 476  	if e < 3 || e&1 == 0 {
 477  		return nil, nil, errors.New("ssh: incorrect exponent")
 478  	}
 479  
 480  	var key rsa.PublicKey
 481  	key.E = int(e)
 482  	key.N = w.N
 483  	return (*rsaPublicKey)(&key), w.Rest, nil
 484  }
 485  
 486  func (r *rsaPublicKey) Marshal() []byte {
 487  	e := new(big.Int).SetInt64(int64(r.E))
 488  	// RSA publickey struct layout should match the struct used by
 489  	// parseRSACert in the x/crypto/ssh/agent package.
 490  	wirekey := struct {
 491  		Name string
 492  		E    *big.Int
 493  		N    *big.Int
 494  	}{
 495  		KeyAlgoRSA,
 496  		e,
 497  		r.N,
 498  	}
 499  	return Marshal(&wirekey)
 500  }
 501  
 502  func (r *rsaPublicKey) Verify(data []byte, sig *Signature) error {
 503  	supportedAlgos := algorithmsForKeyFormat(r.Type())
 504  	if !slices.Contains(supportedAlgos, sig.Format) {
 505  		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, r.Type())
 506  	}
 507  	hash, err := hashFunc(sig.Format)
 508  	if err != nil {
 509  		return err
 510  	}
 511  	h := hash.New()
 512  	h.Write(data)
 513  	digest := h.Sum(nil)
 514  
 515  	// Signatures in PKCS1v15 must match the key's modulus in
 516  	// length. However with SSH, some signers provide RSA
 517  	// signatures which are missing the MSB 0's of the bignum
 518  	// represented. With ssh-rsa signatures, this is encouraged by
 519  	// the spec (even though e.g. OpenSSH will give the full
 520  	// length unconditionally). With rsa-sha2-* signatures, the
 521  	// verifier is allowed to support these, even though they are
 522  	// out of spec. See RFC 4253 Section 6.6 for ssh-rsa and RFC
 523  	// 8332 Section 3 for rsa-sha2-* details.
 524  	//
 525  	// In practice:
 526  	// * OpenSSH always allows "short" signatures:
 527  	//   https://github.com/openssh/openssh-portable/blob/V_9_8_P1/ssh-rsa.c#L526
 528  	//   but always generates padded signatures:
 529  	//   https://github.com/openssh/openssh-portable/blob/V_9_8_P1/ssh-rsa.c#L439
 530  	//
 531  	// * PuTTY versions 0.81 and earlier will generate short
 532  	//   signatures for all RSA signature variants. Note that
 533  	//   PuTTY is embedded in other software, such as WinSCP and
 534  	//   FileZilla. At the time of writing, a patch has been
 535  	//   applied to PuTTY to generate padded signatures for
 536  	//   rsa-sha2-*, but not yet released:
 537  	//   https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=a5bcf3d384e1bf15a51a6923c3724cbbee022d8e
 538  	//
 539  	// * SSH.NET versions 2024.0.0 and earlier will generate short
 540  	//   signatures for all RSA signature variants, fixed in 2024.1.0:
 541  	//   https://github.com/sshnet/SSH.NET/releases/tag/2024.1.0
 542  	//
 543  	// As a result, we pad these up to the key size by inserting
 544  	// leading 0's.
 545  	//
 546  	// Note that support for short signatures with rsa-sha2-* may
 547  	// be removed in the future due to such signatures not being
 548  	// allowed by the spec.
 549  	blob := sig.Blob
 550  	keySize := (*rsa.PublicKey)(r).Size()
 551  	if len(blob) < keySize {
 552  		padded := make([]byte, keySize)
 553  		copy(padded[keySize-len(blob):], blob)
 554  		blob = padded
 555  	}
 556  	return rsa.VerifyPKCS1v15((*rsa.PublicKey)(r), hash, digest, blob)
 557  }
 558  
 559  func (r *rsaPublicKey) CryptoPublicKey() crypto.PublicKey {
 560  	return (*rsa.PublicKey)(r)
 561  }
 562  
 563  type dsaPublicKey dsa.PublicKey
 564  
 565  func (k *dsaPublicKey) Type() string {
 566  	return "ssh-dss"
 567  }
 568  
 569  func checkDSAParams(param *dsa.Parameters) error {
 570  	// SSH specifies FIPS 186-2, which only provided a single size
 571  	// (1024 bits) DSA key. FIPS 186-3 allows for larger key
 572  	// sizes, which would confuse SSH.
 573  	if l := param.P.BitLen(); l != 1024 {
 574  		return fmt.Errorf("ssh: unsupported DSA key size %d", l)
 575  	}
 576  
 577  	return nil
 578  }
 579  
 580  // parseDSA parses an DSA key according to RFC 4253, section 6.6.
 581  func parseDSA(in []byte) (out PublicKey, rest []byte, err error) {
 582  	var w struct {
 583  		P, Q, G, Y *big.Int
 584  		Rest       []byte `ssh:"rest"`
 585  	}
 586  	if err := Unmarshal(in, &w); err != nil {
 587  		return nil, nil, err
 588  	}
 589  
 590  	param := dsa.Parameters{
 591  		P: w.P,
 592  		Q: w.Q,
 593  		G: w.G,
 594  	}
 595  	if err := checkDSAParams(&param); err != nil {
 596  		return nil, nil, err
 597  	}
 598  
 599  	key := &dsaPublicKey{
 600  		Parameters: param,
 601  		Y:          w.Y,
 602  	}
 603  	return key, w.Rest, nil
 604  }
 605  
 606  func (k *dsaPublicKey) Marshal() []byte {
 607  	// DSA publickey struct layout should match the struct used by
 608  	// parseDSACert in the x/crypto/ssh/agent package.
 609  	w := struct {
 610  		Name       string
 611  		P, Q, G, Y *big.Int
 612  	}{
 613  		k.Type(),
 614  		k.P,
 615  		k.Q,
 616  		k.G,
 617  		k.Y,
 618  	}
 619  
 620  	return Marshal(&w)
 621  }
 622  
 623  func (k *dsaPublicKey) Verify(data []byte, sig *Signature) error {
 624  	if sig.Format != k.Type() {
 625  		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
 626  	}
 627  	hash, err := hashFunc(sig.Format)
 628  	if err != nil {
 629  		return err
 630  	}
 631  	h := hash.New()
 632  	h.Write(data)
 633  	digest := h.Sum(nil)
 634  
 635  	// Per RFC 4253, section 6.6,
 636  	// The value for 'dss_signature_blob' is encoded as a string containing
 637  	// r, followed by s (which are 160-bit integers, without lengths or
 638  	// padding, unsigned, and in network byte order).
 639  	// For DSS purposes, sig.Blob should be exactly 40 bytes in length.
 640  	if len(sig.Blob) != 40 {
 641  		return errors.New("ssh: DSA signature parse error")
 642  	}
 643  	r := new(big.Int).SetBytes(sig.Blob[:20])
 644  	s := new(big.Int).SetBytes(sig.Blob[20:])
 645  	if dsa.Verify((*dsa.PublicKey)(k), digest, r, s) {
 646  		return nil
 647  	}
 648  	return errors.New("ssh: signature did not verify")
 649  }
 650  
 651  func (k *dsaPublicKey) CryptoPublicKey() crypto.PublicKey {
 652  	return (*dsa.PublicKey)(k)
 653  }
 654  
 655  type dsaPrivateKey struct {
 656  	*dsa.PrivateKey
 657  }
 658  
 659  func (k *dsaPrivateKey) PublicKey() PublicKey {
 660  	return (*dsaPublicKey)(&k.PrivateKey.PublicKey)
 661  }
 662  
 663  func (k *dsaPrivateKey) Sign(rand io.Reader, data []byte) (*Signature, error) {
 664  	return k.SignWithAlgorithm(rand, data, k.PublicKey().Type())
 665  }
 666  
 667  func (k *dsaPrivateKey) Algorithms() []string {
 668  	return []string{k.PublicKey().Type()}
 669  }
 670  
 671  func (k *dsaPrivateKey) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
 672  	if algorithm != "" && algorithm != k.PublicKey().Type() {
 673  		return nil, fmt.Errorf("ssh: unsupported signature algorithm %s", algorithm)
 674  	}
 675  
 676  	hash, err := hashFunc(k.PublicKey().Type())
 677  	if err != nil {
 678  		return nil, err
 679  	}
 680  	h := hash.New()
 681  	h.Write(data)
 682  	digest := h.Sum(nil)
 683  	r, s, err := dsa.Sign(rand, k.PrivateKey, digest)
 684  	if err != nil {
 685  		return nil, err
 686  	}
 687  
 688  	sig := make([]byte, 40)
 689  	rb := r.Bytes()
 690  	sb := s.Bytes()
 691  
 692  	copy(sig[20-len(rb):20], rb)
 693  	copy(sig[40-len(sb):], sb)
 694  
 695  	return &Signature{
 696  		Format: k.PublicKey().Type(),
 697  		Blob:   sig,
 698  	}, nil
 699  }
 700  
 701  type ecdsaPublicKey ecdsa.PublicKey
 702  
 703  func (k *ecdsaPublicKey) Type() string {
 704  	return "ecdsa-sha2-" + k.nistID()
 705  }
 706  
 707  func (k *ecdsaPublicKey) nistID() string {
 708  	switch k.Params().BitSize {
 709  	case 256:
 710  		return "nistp256"
 711  	case 384:
 712  		return "nistp384"
 713  	case 521:
 714  		return "nistp521"
 715  	}
 716  	panic("ssh: unsupported ecdsa key size")
 717  }
 718  
 719  type ed25519PublicKey ed25519.PublicKey
 720  
 721  func (k ed25519PublicKey) Type() string {
 722  	return KeyAlgoED25519
 723  }
 724  
 725  func parseED25519(in []byte) (out PublicKey, rest []byte, err error) {
 726  	var w struct {
 727  		KeyBytes []byte
 728  		Rest     []byte `ssh:"rest"`
 729  	}
 730  
 731  	if err := Unmarshal(in, &w); err != nil {
 732  		return nil, nil, err
 733  	}
 734  
 735  	if l := len(w.KeyBytes); l != ed25519.PublicKeySize {
 736  		return nil, nil, fmt.Errorf("invalid size %d for Ed25519 public key", l)
 737  	}
 738  
 739  	return ed25519PublicKey(w.KeyBytes), w.Rest, nil
 740  }
 741  
 742  func (k ed25519PublicKey) Marshal() []byte {
 743  	w := struct {
 744  		Name     string
 745  		KeyBytes []byte
 746  	}{
 747  		KeyAlgoED25519,
 748  		[]byte(k),
 749  	}
 750  	return Marshal(&w)
 751  }
 752  
 753  func (k ed25519PublicKey) Verify(b []byte, sig *Signature) error {
 754  	if sig.Format != k.Type() {
 755  		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
 756  	}
 757  	if l := len(k); l != ed25519.PublicKeySize {
 758  		return fmt.Errorf("ssh: invalid size %d for Ed25519 public key", l)
 759  	}
 760  
 761  	if ok := ed25519.Verify(ed25519.PublicKey(k), b, sig.Blob); !ok {
 762  		return errors.New("ssh: signature did not verify")
 763  	}
 764  
 765  	return nil
 766  }
 767  
 768  func (k ed25519PublicKey) CryptoPublicKey() crypto.PublicKey {
 769  	return ed25519.PublicKey(k)
 770  }
 771  
 772  func supportedEllipticCurve(curve elliptic.Curve) bool {
 773  	return curve == elliptic.P256() || curve == elliptic.P384() || curve == elliptic.P521()
 774  }
 775  
 776  // parseECDSA parses an ECDSA key according to RFC 5656, section 3.1.
 777  func parseECDSA(in []byte) (out PublicKey, rest []byte, err error) {
 778  	var w struct {
 779  		Curve    string
 780  		KeyBytes []byte
 781  		Rest     []byte `ssh:"rest"`
 782  	}
 783  
 784  	if err := Unmarshal(in, &w); err != nil {
 785  		return nil, nil, err
 786  	}
 787  
 788  	key := new(ecdsa.PublicKey)
 789  
 790  	switch w.Curve {
 791  	case "nistp256":
 792  		key.Curve = elliptic.P256()
 793  	case "nistp384":
 794  		key.Curve = elliptic.P384()
 795  	case "nistp521":
 796  		key.Curve = elliptic.P521()
 797  	default:
 798  		return nil, nil, errors.New("ssh: unsupported curve")
 799  	}
 800  
 801  	key.X, key.Y = elliptic.Unmarshal(key.Curve, w.KeyBytes)
 802  	if key.X == nil || key.Y == nil {
 803  		return nil, nil, errors.New("ssh: invalid curve point")
 804  	}
 805  	return (*ecdsaPublicKey)(key), w.Rest, nil
 806  }
 807  
 808  func (k *ecdsaPublicKey) Marshal() []byte {
 809  	// See RFC 5656, section 3.1.
 810  	keyBytes := elliptic.Marshal(k.Curve, k.X, k.Y)
 811  	// ECDSA publickey struct layout should match the struct used by
 812  	// parseECDSACert in the x/crypto/ssh/agent package.
 813  	w := struct {
 814  		Name string
 815  		ID   string
 816  		Key  []byte
 817  	}{
 818  		k.Type(),
 819  		k.nistID(),
 820  		keyBytes,
 821  	}
 822  
 823  	return Marshal(&w)
 824  }
 825  
 826  func (k *ecdsaPublicKey) Verify(data []byte, sig *Signature) error {
 827  	if sig.Format != k.Type() {
 828  		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
 829  	}
 830  	hash, err := hashFunc(sig.Format)
 831  	if err != nil {
 832  		return err
 833  	}
 834  	h := hash.New()
 835  	h.Write(data)
 836  	digest := h.Sum(nil)
 837  
 838  	// Per RFC 5656, section 3.1.2,
 839  	// The ecdsa_signature_blob value has the following specific encoding:
 840  	//    mpint    r
 841  	//    mpint    s
 842  	var ecSig struct {
 843  		R *big.Int
 844  		S *big.Int
 845  	}
 846  
 847  	if err := Unmarshal(sig.Blob, &ecSig); err != nil {
 848  		return err
 849  	}
 850  
 851  	if ecdsa.Verify((*ecdsa.PublicKey)(k), digest, ecSig.R, ecSig.S) {
 852  		return nil
 853  	}
 854  	return errors.New("ssh: signature did not verify")
 855  }
 856  
 857  func (k *ecdsaPublicKey) CryptoPublicKey() crypto.PublicKey {
 858  	return (*ecdsa.PublicKey)(k)
 859  }
 860  
 861  // skFields holds the additional fields present in U2F/FIDO2 signatures.
 862  // See openssh/PROTOCOL.u2f 'SSH U2F Signatures' for details.
 863  type skFields struct {
 864  	// Flags contains U2F/FIDO2 flags such as 'user present'
 865  	Flags byte
 866  	// Counter is a monotonic signature counter which can be
 867  	// used to detect concurrent use of a private key, should
 868  	// it be extracted from hardware.
 869  	Counter uint32
 870  }
 871  
 872  type skECDSAPublicKey struct {
 873  	// application is a URL-like string, typically "ssh:" for SSH.
 874  	// see openssh/PROTOCOL.u2f for details.
 875  	application string
 876  	ecdsa.PublicKey
 877  }
 878  
 879  func (k *skECDSAPublicKey) Type() string {
 880  	return KeyAlgoSKECDSA256
 881  }
 882  
 883  func (k *skECDSAPublicKey) nistID() string {
 884  	return "nistp256"
 885  }
 886  
 887  func parseSKECDSA(in []byte) (out PublicKey, rest []byte, err error) {
 888  	var w struct {
 889  		Curve       string
 890  		KeyBytes    []byte
 891  		Application string
 892  		Rest        []byte `ssh:"rest"`
 893  	}
 894  
 895  	if err := Unmarshal(in, &w); err != nil {
 896  		return nil, nil, err
 897  	}
 898  
 899  	key := new(skECDSAPublicKey)
 900  	key.application = w.Application
 901  
 902  	if w.Curve != "nistp256" {
 903  		return nil, nil, errors.New("ssh: unsupported curve")
 904  	}
 905  	key.Curve = elliptic.P256()
 906  
 907  	key.X, key.Y = elliptic.Unmarshal(key.Curve, w.KeyBytes)
 908  	if key.X == nil || key.Y == nil {
 909  		return nil, nil, errors.New("ssh: invalid curve point")
 910  	}
 911  
 912  	return key, w.Rest, nil
 913  }
 914  
 915  func (k *skECDSAPublicKey) Marshal() []byte {
 916  	// See RFC 5656, section 3.1.
 917  	keyBytes := elliptic.Marshal(k.Curve, k.X, k.Y)
 918  	w := struct {
 919  		Name        string
 920  		ID          string
 921  		Key         []byte
 922  		Application string
 923  	}{
 924  		k.Type(),
 925  		k.nistID(),
 926  		keyBytes,
 927  		k.application,
 928  	}
 929  
 930  	return Marshal(&w)
 931  }
 932  
 933  func (k *skECDSAPublicKey) Verify(data []byte, sig *Signature) error {
 934  	if sig.Format != k.Type() {
 935  		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
 936  	}
 937  	hash, err := hashFunc(sig.Format)
 938  	if err != nil {
 939  		return err
 940  	}
 941  	h := hash.New()
 942  	h.Write([]byte(k.application))
 943  	appDigest := h.Sum(nil)
 944  
 945  	h.Reset()
 946  	h.Write(data)
 947  	dataDigest := h.Sum(nil)
 948  
 949  	var ecSig struct {
 950  		R *big.Int
 951  		S *big.Int
 952  	}
 953  	if err := Unmarshal(sig.Blob, &ecSig); err != nil {
 954  		return err
 955  	}
 956  
 957  	var skf skFields
 958  	if err := Unmarshal(sig.Rest, &skf); err != nil {
 959  		return err
 960  	}
 961  
 962  	blob := struct {
 963  		ApplicationDigest []byte `ssh:"rest"`
 964  		Flags             byte
 965  		Counter           uint32
 966  		MessageDigest     []byte `ssh:"rest"`
 967  	}{
 968  		appDigest,
 969  		skf.Flags,
 970  		skf.Counter,
 971  		dataDigest,
 972  	}
 973  
 974  	original := Marshal(blob)
 975  
 976  	h.Reset()
 977  	h.Write(original)
 978  	digest := h.Sum(nil)
 979  
 980  	if ecdsa.Verify((*ecdsa.PublicKey)(&k.PublicKey), digest, ecSig.R, ecSig.S) {
 981  		return nil
 982  	}
 983  	return errors.New("ssh: signature did not verify")
 984  }
 985  
 986  func (k *skECDSAPublicKey) CryptoPublicKey() crypto.PublicKey {
 987  	return &k.PublicKey
 988  }
 989  
 990  type skEd25519PublicKey struct {
 991  	// application is a URL-like string, typically "ssh:" for SSH.
 992  	// see openssh/PROTOCOL.u2f for details.
 993  	application string
 994  	ed25519.PublicKey
 995  }
 996  
 997  func (k *skEd25519PublicKey) Type() string {
 998  	return KeyAlgoSKED25519
 999  }
1000  
1001  func parseSKEd25519(in []byte) (out PublicKey, rest []byte, err error) {
1002  	var w struct {
1003  		KeyBytes    []byte
1004  		Application string
1005  		Rest        []byte `ssh:"rest"`
1006  	}
1007  
1008  	if err := Unmarshal(in, &w); err != nil {
1009  		return nil, nil, err
1010  	}
1011  
1012  	if l := len(w.KeyBytes); l != ed25519.PublicKeySize {
1013  		return nil, nil, fmt.Errorf("invalid size %d for Ed25519 public key", l)
1014  	}
1015  
1016  	key := new(skEd25519PublicKey)
1017  	key.application = w.Application
1018  	key.PublicKey = ed25519.PublicKey(w.KeyBytes)
1019  
1020  	return key, w.Rest, nil
1021  }
1022  
1023  func (k *skEd25519PublicKey) Marshal() []byte {
1024  	w := struct {
1025  		Name        string
1026  		KeyBytes    []byte
1027  		Application string
1028  	}{
1029  		KeyAlgoSKED25519,
1030  		[]byte(k.PublicKey),
1031  		k.application,
1032  	}
1033  	return Marshal(&w)
1034  }
1035  
1036  func (k *skEd25519PublicKey) Verify(data []byte, sig *Signature) error {
1037  	if sig.Format != k.Type() {
1038  		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
1039  	}
1040  	if l := len(k.PublicKey); l != ed25519.PublicKeySize {
1041  		return fmt.Errorf("invalid size %d for Ed25519 public key", l)
1042  	}
1043  
1044  	hash, err := hashFunc(sig.Format)
1045  	if err != nil {
1046  		return err
1047  	}
1048  	h := hash.New()
1049  	h.Write([]byte(k.application))
1050  	appDigest := h.Sum(nil)
1051  
1052  	h.Reset()
1053  	h.Write(data)
1054  	dataDigest := h.Sum(nil)
1055  
1056  	var edSig struct {
1057  		Signature []byte `ssh:"rest"`
1058  	}
1059  
1060  	if err := Unmarshal(sig.Blob, &edSig); err != nil {
1061  		return err
1062  	}
1063  
1064  	var skf skFields
1065  	if err := Unmarshal(sig.Rest, &skf); err != nil {
1066  		return err
1067  	}
1068  
1069  	blob := struct {
1070  		ApplicationDigest []byte `ssh:"rest"`
1071  		Flags             byte
1072  		Counter           uint32
1073  		MessageDigest     []byte `ssh:"rest"`
1074  	}{
1075  		appDigest,
1076  		skf.Flags,
1077  		skf.Counter,
1078  		dataDigest,
1079  	}
1080  
1081  	original := Marshal(blob)
1082  
1083  	if ok := ed25519.Verify(k.PublicKey, original, edSig.Signature); !ok {
1084  		return errors.New("ssh: signature did not verify")
1085  	}
1086  
1087  	return nil
1088  }
1089  
1090  func (k *skEd25519PublicKey) CryptoPublicKey() crypto.PublicKey {
1091  	return k.PublicKey
1092  }
1093  
1094  // NewSignerFromKey takes an *rsa.PrivateKey, *dsa.PrivateKey,
1095  // *ecdsa.PrivateKey or any other crypto.Signer and returns a
1096  // corresponding Signer instance. ECDSA keys must use P-256, P-384 or
1097  // P-521. DSA keys must use parameter size L1024N160.
1098  func NewSignerFromKey(key interface{}) (Signer, error) {
1099  	switch key := key.(type) {
1100  	case crypto.Signer:
1101  		return NewSignerFromSigner(key)
1102  	case *dsa.PrivateKey:
1103  		return newDSAPrivateKey(key)
1104  	default:
1105  		return nil, fmt.Errorf("ssh: unsupported key type %T", key)
1106  	}
1107  }
1108  
1109  func newDSAPrivateKey(key *dsa.PrivateKey) (Signer, error) {
1110  	if err := checkDSAParams(&key.PublicKey.Parameters); err != nil {
1111  		return nil, err
1112  	}
1113  
1114  	return &dsaPrivateKey{key}, nil
1115  }
1116  
1117  type wrappedSigner struct {
1118  	signer crypto.Signer
1119  	pubKey PublicKey
1120  }
1121  
1122  // NewSignerFromSigner takes any crypto.Signer implementation and
1123  // returns a corresponding Signer interface. This can be used, for
1124  // example, with keys kept in hardware modules.
1125  func NewSignerFromSigner(signer crypto.Signer) (Signer, error) {
1126  	pubKey, err := NewPublicKey(signer.Public())
1127  	if err != nil {
1128  		return nil, err
1129  	}
1130  
1131  	return &wrappedSigner{signer, pubKey}, nil
1132  }
1133  
1134  func (s *wrappedSigner) PublicKey() PublicKey {
1135  	return s.pubKey
1136  }
1137  
1138  func (s *wrappedSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
1139  	return s.SignWithAlgorithm(rand, data, s.pubKey.Type())
1140  }
1141  
1142  func (s *wrappedSigner) Algorithms() []string {
1143  	return algorithmsForKeyFormat(s.pubKey.Type())
1144  }
1145  
1146  func (s *wrappedSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
1147  	if algorithm == "" {
1148  		algorithm = s.pubKey.Type()
1149  	}
1150  
1151  	if !slices.Contains(s.Algorithms(), algorithm) {
1152  		return nil, fmt.Errorf("ssh: unsupported signature algorithm %q for key format %q", algorithm, s.pubKey.Type())
1153  	}
1154  
1155  	hashFunc, err := hashFunc(algorithm)
1156  	if err != nil {
1157  		return nil, err
1158  	}
1159  	var digest []byte
1160  	if hashFunc != 0 {
1161  		h := hashFunc.New()
1162  		h.Write(data)
1163  		digest = h.Sum(nil)
1164  	} else {
1165  		digest = data
1166  	}
1167  
1168  	signature, err := s.signer.Sign(rand, digest, hashFunc)
1169  	if err != nil {
1170  		return nil, err
1171  	}
1172  
1173  	// crypto.Signer.Sign is expected to return an ASN.1-encoded signature
1174  	// for ECDSA and DSA, but that's not the encoding expected by SSH, so
1175  	// re-encode.
1176  	switch s.pubKey.(type) {
1177  	case *ecdsaPublicKey, *dsaPublicKey:
1178  		type asn1Signature struct {
1179  			R, S *big.Int
1180  		}
1181  		asn1Sig := new(asn1Signature)
1182  		_, err := asn1.Unmarshal(signature, asn1Sig)
1183  		if err != nil {
1184  			return nil, err
1185  		}
1186  
1187  		switch s.pubKey.(type) {
1188  		case *ecdsaPublicKey:
1189  			signature = Marshal(asn1Sig)
1190  
1191  		case *dsaPublicKey:
1192  			signature = make([]byte, 40)
1193  			r := asn1Sig.R.Bytes()
1194  			s := asn1Sig.S.Bytes()
1195  			copy(signature[20-len(r):20], r)
1196  			copy(signature[40-len(s):40], s)
1197  		}
1198  	}
1199  
1200  	return &Signature{
1201  		Format: algorithm,
1202  		Blob:   signature,
1203  	}, nil
1204  }
1205  
1206  // NewPublicKey takes an *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey,
1207  // or ed25519.PublicKey returns a corresponding PublicKey instance.
1208  // ECDSA keys must use P-256, P-384 or P-521.
1209  func NewPublicKey(key interface{}) (PublicKey, error) {
1210  	switch key := key.(type) {
1211  	case *rsa.PublicKey:
1212  		return (*rsaPublicKey)(key), nil
1213  	case *ecdsa.PublicKey:
1214  		if !supportedEllipticCurve(key.Curve) {
1215  			return nil, errors.New("ssh: only P-256, P-384 and P-521 EC keys are supported")
1216  		}
1217  		return (*ecdsaPublicKey)(key), nil
1218  	case *dsa.PublicKey:
1219  		return (*dsaPublicKey)(key), nil
1220  	case ed25519.PublicKey:
1221  		if l := len(key); l != ed25519.PublicKeySize {
1222  			return nil, fmt.Errorf("ssh: invalid size %d for Ed25519 public key", l)
1223  		}
1224  		return ed25519PublicKey(key), nil
1225  	default:
1226  		return nil, fmt.Errorf("ssh: unsupported key type %T", key)
1227  	}
1228  }
1229  
1230  // ParsePrivateKey returns a Signer from a PEM encoded private key. It supports
1231  // the same keys as ParseRawPrivateKey. If the private key is encrypted, it
1232  // will return a PassphraseMissingError.
1233  func ParsePrivateKey(pemBytes []byte) (Signer, error) {
1234  	key, err := ParseRawPrivateKey(pemBytes)
1235  	if err != nil {
1236  		return nil, err
1237  	}
1238  
1239  	return NewSignerFromKey(key)
1240  }
1241  
1242  // ParsePrivateKeyWithPassphrase returns a Signer from a PEM encoded private
1243  // key and passphrase. It supports the same keys as
1244  // ParseRawPrivateKeyWithPassphrase.
1245  func ParsePrivateKeyWithPassphrase(pemBytes, passphrase []byte) (Signer, error) {
1246  	key, err := ParseRawPrivateKeyWithPassphrase(pemBytes, passphrase)
1247  	if err != nil {
1248  		return nil, err
1249  	}
1250  
1251  	return NewSignerFromKey(key)
1252  }
1253  
1254  // encryptedBlock tells whether a private key is
1255  // encrypted by examining its Proc-Type header
1256  // for a mention of ENCRYPTED
1257  // according to RFC 1421 Section 4.6.1.1.
1258  func encryptedBlock(block *pem.Block) bool {
1259  	return strings.Contains(block.Headers["Proc-Type"], "ENCRYPTED")
1260  }
1261  
1262  // A PassphraseMissingError indicates that parsing this private key requires a
1263  // passphrase. Use ParsePrivateKeyWithPassphrase.
1264  type PassphraseMissingError struct {
1265  	// PublicKey will be set if the private key format includes an unencrypted
1266  	// public key along with the encrypted private key.
1267  	PublicKey PublicKey
1268  }
1269  
1270  func (*PassphraseMissingError) Error() string {
1271  	return "ssh: this private key is passphrase protected"
1272  }
1273  
1274  // ParseRawPrivateKey returns a private key from a PEM encoded private key. It supports
1275  // RSA, DSA, ECDSA, and Ed25519 private keys in PKCS#1, PKCS#8, OpenSSL, and OpenSSH
1276  // formats. If the private key is encrypted, it will return a PassphraseMissingError.
1277  func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) {
1278  	block, _ := pem.Decode(pemBytes)
1279  	if block == nil {
1280  		return nil, errors.New("ssh: no key found")
1281  	}
1282  
1283  	if encryptedBlock(block) {
1284  		return nil, &PassphraseMissingError{}
1285  	}
1286  
1287  	switch block.Type {
1288  	case "RSA PRIVATE KEY":
1289  		return x509.ParsePKCS1PrivateKey(block.Bytes)
1290  	// RFC5208 - https://tools.ietf.org/html/rfc5208
1291  	case "PRIVATE KEY":
1292  		return x509.ParsePKCS8PrivateKey(block.Bytes)
1293  	case "EC PRIVATE KEY":
1294  		return x509.ParseECPrivateKey(block.Bytes)
1295  	case "DSA PRIVATE KEY":
1296  		return ParseDSAPrivateKey(block.Bytes)
1297  	case "OPENSSH PRIVATE KEY":
1298  		return parseOpenSSHPrivateKey(block.Bytes, unencryptedOpenSSHKey)
1299  	default:
1300  		return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type)
1301  	}
1302  }
1303  
1304  // ParseRawPrivateKeyWithPassphrase returns a private key decrypted with
1305  // passphrase from a PEM encoded private key. If the passphrase is wrong, it
1306  // will return x509.IncorrectPasswordError.
1307  func ParseRawPrivateKeyWithPassphrase(pemBytes, passphrase []byte) (interface{}, error) {
1308  	block, _ := pem.Decode(pemBytes)
1309  	if block == nil {
1310  		return nil, errors.New("ssh: no key found")
1311  	}
1312  
1313  	if block.Type == "OPENSSH PRIVATE KEY" {
1314  		return parseOpenSSHPrivateKey(block.Bytes, passphraseProtectedOpenSSHKey(passphrase))
1315  	}
1316  
1317  	if !encryptedBlock(block) || !x509.IsEncryptedPEMBlock(block) {
1318  		return nil, errors.New("ssh: not an encrypted key")
1319  	}
1320  
1321  	buf, err := x509.DecryptPEMBlock(block, passphrase)
1322  	if err != nil {
1323  		if err == x509.IncorrectPasswordError {
1324  			return nil, err
1325  		}
1326  		return nil, fmt.Errorf("ssh: cannot decode encrypted private keys: %v", err)
1327  	}
1328  
1329  	var result interface{}
1330  
1331  	switch block.Type {
1332  	case "RSA PRIVATE KEY":
1333  		result, err = x509.ParsePKCS1PrivateKey(buf)
1334  	case "EC PRIVATE KEY":
1335  		result, err = x509.ParseECPrivateKey(buf)
1336  	case "DSA PRIVATE KEY":
1337  		result, err = ParseDSAPrivateKey(buf)
1338  	default:
1339  		err = fmt.Errorf("ssh: unsupported key type %q", block.Type)
1340  	}
1341  	// Because of deficiencies in the format, DecryptPEMBlock does not always
1342  	// detect an incorrect password. In these cases decrypted DER bytes is
1343  	// random noise. If the parsing of the key returns an asn1.StructuralError
1344  	// we return x509.IncorrectPasswordError.
1345  	if _, ok := err.(asn1.StructuralError); ok {
1346  		return nil, x509.IncorrectPasswordError
1347  	}
1348  
1349  	return result, err
1350  }
1351  
1352  // ParseDSAPrivateKey returns a DSA private key from its ASN.1 DER encoding, as
1353  // specified by the OpenSSL DSA man page.
1354  func ParseDSAPrivateKey(der []byte) (*dsa.PrivateKey, error) {
1355  	var k struct {
1356  		Version int
1357  		P       *big.Int
1358  		Q       *big.Int
1359  		G       *big.Int
1360  		Pub     *big.Int
1361  		Priv    *big.Int
1362  	}
1363  	rest, err := asn1.Unmarshal(der, &k)
1364  	if err != nil {
1365  		return nil, errors.New("ssh: failed to parse DSA key: " + err.Error())
1366  	}
1367  	if len(rest) > 0 {
1368  		return nil, errors.New("ssh: garbage after DSA key")
1369  	}
1370  
1371  	return &dsa.PrivateKey{
1372  		PublicKey: dsa.PublicKey{
1373  			Parameters: dsa.Parameters{
1374  				P: k.P,
1375  				Q: k.Q,
1376  				G: k.G,
1377  			},
1378  			Y: k.Pub,
1379  		},
1380  		X: k.Priv,
1381  	}, nil
1382  }
1383  
1384  func unencryptedOpenSSHKey(cipherName, kdfName, kdfOpts string, privKeyBlock []byte) ([]byte, error) {
1385  	if kdfName != "none" || cipherName != "none" {
1386  		return nil, &PassphraseMissingError{}
1387  	}
1388  	if kdfOpts != "" {
1389  		return nil, errors.New("ssh: invalid openssh private key")
1390  	}
1391  	return privKeyBlock, nil
1392  }
1393  
1394  func passphraseProtectedOpenSSHKey(passphrase []byte) openSSHDecryptFunc {
1395  	return func(cipherName, kdfName, kdfOpts string, privKeyBlock []byte) ([]byte, error) {
1396  		if kdfName == "none" || cipherName == "none" {
1397  			return nil, errors.New("ssh: key is not password protected")
1398  		}
1399  		if kdfName != "bcrypt" {
1400  			return nil, fmt.Errorf("ssh: unknown KDF %q, only supports %q", kdfName, "bcrypt")
1401  		}
1402  
1403  		var opts struct {
1404  			Salt   string
1405  			Rounds uint32
1406  		}
1407  		if err := Unmarshal([]byte(kdfOpts), &opts); err != nil {
1408  			return nil, err
1409  		}
1410  
1411  		k, err := bcrypt_pbkdf.Key(passphrase, []byte(opts.Salt), int(opts.Rounds), 32+16)
1412  		if err != nil {
1413  			return nil, err
1414  		}
1415  		key, iv := k[:32], k[32:]
1416  
1417  		c, err := aes.NewCipher(key)
1418  		if err != nil {
1419  			return nil, err
1420  		}
1421  		switch cipherName {
1422  		case "aes256-ctr":
1423  			ctr := cipher.NewCTR(c, iv)
1424  			ctr.XORKeyStream(privKeyBlock, privKeyBlock)
1425  		case "aes256-cbc":
1426  			if len(privKeyBlock)%c.BlockSize() != 0 {
1427  				return nil, fmt.Errorf("ssh: invalid encrypted private key length, not a multiple of the block size")
1428  			}
1429  			cbc := cipher.NewCBCDecrypter(c, iv)
1430  			cbc.CryptBlocks(privKeyBlock, privKeyBlock)
1431  		default:
1432  			return nil, fmt.Errorf("ssh: unknown cipher %q, only supports %q or %q", cipherName, "aes256-ctr", "aes256-cbc")
1433  		}
1434  
1435  		return privKeyBlock, nil
1436  	}
1437  }
1438  
1439  func unencryptedOpenSSHMarshaler(privKeyBlock []byte) ([]byte, string, string, string, error) {
1440  	key := generateOpenSSHPadding(privKeyBlock, 8)
1441  	return key, "none", "none", "", nil
1442  }
1443  
1444  func passphraseProtectedOpenSSHMarshaler(passphrase []byte) openSSHEncryptFunc {
1445  	return func(privKeyBlock []byte) ([]byte, string, string, string, error) {
1446  		salt := make([]byte, 16)
1447  		if _, err := rand.Read(salt); err != nil {
1448  			return nil, "", "", "", err
1449  		}
1450  
1451  		opts := struct {
1452  			Salt   []byte
1453  			Rounds uint32
1454  		}{salt, 16}
1455  
1456  		// Derive key to encrypt the private key block.
1457  		k, err := bcrypt_pbkdf.Key(passphrase, salt, int(opts.Rounds), 32+aes.BlockSize)
1458  		if err != nil {
1459  			return nil, "", "", "", err
1460  		}
1461  
1462  		// Add padding matching the block size of AES.
1463  		keyBlock := generateOpenSSHPadding(privKeyBlock, aes.BlockSize)
1464  
1465  		// Encrypt the private key using the derived secret.
1466  
1467  		dst := make([]byte, len(keyBlock))
1468  		key, iv := k[:32], k[32:]
1469  		block, err := aes.NewCipher(key)
1470  		if err != nil {
1471  			return nil, "", "", "", err
1472  		}
1473  
1474  		stream := cipher.NewCTR(block, iv)
1475  		stream.XORKeyStream(dst, keyBlock)
1476  
1477  		return dst, "aes256-ctr", "bcrypt", string(Marshal(opts)), nil
1478  	}
1479  }
1480  
1481  const privateKeyAuthMagic = "openssh-key-v1\x00"
1482  
1483  type openSSHDecryptFunc func(CipherName, KdfName, KdfOpts string, PrivKeyBlock []byte) ([]byte, error)
1484  type openSSHEncryptFunc func(PrivKeyBlock []byte) (ProtectedKeyBlock []byte, cipherName, kdfName, kdfOptions string, err error)
1485  
1486  type openSSHEncryptedPrivateKey struct {
1487  	CipherName   string
1488  	KdfName      string
1489  	KdfOpts      string
1490  	NumKeys      uint32
1491  	PubKey       []byte
1492  	PrivKeyBlock []byte
1493  	Rest         []byte `ssh:"rest"`
1494  }
1495  
1496  type openSSHPrivateKey struct {
1497  	Check1  uint32
1498  	Check2  uint32
1499  	Keytype string
1500  	Rest    []byte `ssh:"rest"`
1501  }
1502  
1503  type openSSHRSAPrivateKey struct {
1504  	N       *big.Int
1505  	E       *big.Int
1506  	D       *big.Int
1507  	Iqmp    *big.Int
1508  	P       *big.Int
1509  	Q       *big.Int
1510  	Comment string
1511  	Pad     []byte `ssh:"rest"`
1512  }
1513  
1514  type openSSHEd25519PrivateKey struct {
1515  	Pub     []byte
1516  	Priv    []byte
1517  	Comment string
1518  	Pad     []byte `ssh:"rest"`
1519  }
1520  
1521  type openSSHECDSAPrivateKey struct {
1522  	Curve   string
1523  	Pub     []byte
1524  	D       *big.Int
1525  	Comment string
1526  	Pad     []byte `ssh:"rest"`
1527  }
1528  
1529  // parseOpenSSHPrivateKey parses an OpenSSH private key, using the decrypt
1530  // function to unwrap the encrypted portion. unencryptedOpenSSHKey can be used
1531  // as the decrypt function to parse an unencrypted private key. See
1532  // https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key.
1533  func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.PrivateKey, error) {
1534  	if len(key) < len(privateKeyAuthMagic) || string(key[:len(privateKeyAuthMagic)]) != privateKeyAuthMagic {
1535  		return nil, errors.New("ssh: invalid openssh private key format")
1536  	}
1537  	remaining := key[len(privateKeyAuthMagic):]
1538  
1539  	var w openSSHEncryptedPrivateKey
1540  	if err := Unmarshal(remaining, &w); err != nil {
1541  		return nil, err
1542  	}
1543  	if w.NumKeys != 1 {
1544  		// We only support single key files, and so does OpenSSH.
1545  		// https://github.com/openssh/openssh-portable/blob/4103a3ec7/sshkey.c#L4171
1546  		return nil, errors.New("ssh: multi-key files are not supported")
1547  	}
1548  
1549  	privKeyBlock, err := decrypt(w.CipherName, w.KdfName, w.KdfOpts, w.PrivKeyBlock)
1550  	if err != nil {
1551  		if err, ok := err.(*PassphraseMissingError); ok {
1552  			pub, errPub := ParsePublicKey(w.PubKey)
1553  			if errPub != nil {
1554  				return nil, fmt.Errorf("ssh: failed to parse embedded public key: %v", errPub)
1555  			}
1556  			err.PublicKey = pub
1557  		}
1558  		return nil, err
1559  	}
1560  
1561  	var pk1 openSSHPrivateKey
1562  	if err := Unmarshal(privKeyBlock, &pk1); err != nil || pk1.Check1 != pk1.Check2 {
1563  		if w.CipherName != "none" {
1564  			return nil, x509.IncorrectPasswordError
1565  		}
1566  		return nil, errors.New("ssh: malformed OpenSSH key")
1567  	}
1568  
1569  	switch pk1.Keytype {
1570  	case KeyAlgoRSA:
1571  		var key openSSHRSAPrivateKey
1572  		if err := Unmarshal(pk1.Rest, &key); err != nil {
1573  			return nil, err
1574  		}
1575  
1576  		if err := checkOpenSSHKeyPadding(key.Pad); err != nil {
1577  			return nil, err
1578  		}
1579  
1580  		pk := &rsa.PrivateKey{
1581  			PublicKey: rsa.PublicKey{
1582  				N: key.N,
1583  				E: int(key.E.Int64()),
1584  			},
1585  			D:      key.D,
1586  			Primes: []*big.Int{key.P, key.Q},
1587  		}
1588  
1589  		if err := pk.Validate(); err != nil {
1590  			return nil, err
1591  		}
1592  
1593  		pk.Precompute()
1594  
1595  		return pk, nil
1596  	case KeyAlgoED25519:
1597  		var key openSSHEd25519PrivateKey
1598  		if err := Unmarshal(pk1.Rest, &key); err != nil {
1599  			return nil, err
1600  		}
1601  
1602  		if len(key.Priv) != ed25519.PrivateKeySize {
1603  			return nil, errors.New("ssh: private key unexpected length")
1604  		}
1605  
1606  		if err := checkOpenSSHKeyPadding(key.Pad); err != nil {
1607  			return nil, err
1608  		}
1609  
1610  		pk := ed25519.PrivateKey(make([]byte, ed25519.PrivateKeySize))
1611  		copy(pk, key.Priv)
1612  		return &pk, nil
1613  	case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:
1614  		var key openSSHECDSAPrivateKey
1615  		if err := Unmarshal(pk1.Rest, &key); err != nil {
1616  			return nil, err
1617  		}
1618  
1619  		if err := checkOpenSSHKeyPadding(key.Pad); err != nil {
1620  			return nil, err
1621  		}
1622  
1623  		var curve elliptic.Curve
1624  		switch key.Curve {
1625  		case "nistp256":
1626  			curve = elliptic.P256()
1627  		case "nistp384":
1628  			curve = elliptic.P384()
1629  		case "nistp521":
1630  			curve = elliptic.P521()
1631  		default:
1632  			return nil, errors.New("ssh: unhandled elliptic curve: " + key.Curve)
1633  		}
1634  
1635  		X, Y := elliptic.Unmarshal(curve, key.Pub)
1636  		if X == nil || Y == nil {
1637  			return nil, errors.New("ssh: failed to unmarshal public key")
1638  		}
1639  
1640  		if key.D.Cmp(curve.Params().N) >= 0 {
1641  			return nil, errors.New("ssh: scalar is out of range")
1642  		}
1643  
1644  		x, y := curve.ScalarBaseMult(key.D.Bytes())
1645  		if x.Cmp(X) != 0 || y.Cmp(Y) != 0 {
1646  			return nil, errors.New("ssh: public key does not match private key")
1647  		}
1648  
1649  		return &ecdsa.PrivateKey{
1650  			PublicKey: ecdsa.PublicKey{
1651  				Curve: curve,
1652  				X:     X,
1653  				Y:     Y,
1654  			},
1655  			D: key.D,
1656  		}, nil
1657  	default:
1658  		return nil, errors.New("ssh: unhandled key type")
1659  	}
1660  }
1661  
1662  func marshalOpenSSHPrivateKey(key crypto.PrivateKey, comment string, encrypt openSSHEncryptFunc) (*pem.Block, error) {
1663  	var w openSSHEncryptedPrivateKey
1664  	var pk1 openSSHPrivateKey
1665  
1666  	// Random check bytes.
1667  	var check uint32
1668  	if err := binary.Read(rand.Reader, binary.BigEndian, &check); err != nil {
1669  		return nil, err
1670  	}
1671  
1672  	pk1.Check1 = check
1673  	pk1.Check2 = check
1674  	w.NumKeys = 1
1675  
1676  	// Use a []byte directly on ed25519 keys.
1677  	if k, ok := key.(*ed25519.PrivateKey); ok {
1678  		key = *k
1679  	}
1680  
1681  	switch k := key.(type) {
1682  	case *rsa.PrivateKey:
1683  		E := new(big.Int).SetInt64(int64(k.PublicKey.E))
1684  		// Marshal public key:
1685  		// E and N are in reversed order in the public and private key.
1686  		pubKey := struct {
1687  			KeyType string
1688  			E       *big.Int
1689  			N       *big.Int
1690  		}{
1691  			KeyAlgoRSA,
1692  			E, k.PublicKey.N,
1693  		}
1694  		w.PubKey = Marshal(pubKey)
1695  
1696  		// Marshal private key.
1697  		key := openSSHRSAPrivateKey{
1698  			N:       k.PublicKey.N,
1699  			E:       E,
1700  			D:       k.D,
1701  			Iqmp:    k.Precomputed.Qinv,
1702  			P:       k.Primes[0],
1703  			Q:       k.Primes[1],
1704  			Comment: comment,
1705  		}
1706  		pk1.Keytype = KeyAlgoRSA
1707  		pk1.Rest = Marshal(key)
1708  	case ed25519.PrivateKey:
1709  		pub := make([]byte, ed25519.PublicKeySize)
1710  		priv := make([]byte, ed25519.PrivateKeySize)
1711  		copy(pub, k[32:])
1712  		copy(priv, k)
1713  
1714  		// Marshal public key.
1715  		pubKey := struct {
1716  			KeyType string
1717  			Pub     []byte
1718  		}{
1719  			KeyAlgoED25519, pub,
1720  		}
1721  		w.PubKey = Marshal(pubKey)
1722  
1723  		// Marshal private key.
1724  		key := openSSHEd25519PrivateKey{
1725  			Pub:     pub,
1726  			Priv:    priv,
1727  			Comment: comment,
1728  		}
1729  		pk1.Keytype = KeyAlgoED25519
1730  		pk1.Rest = Marshal(key)
1731  	case *ecdsa.PrivateKey:
1732  		var curve, keyType string
1733  		switch name := k.Curve.Params().Name; name {
1734  		case "P-256":
1735  			curve = "nistp256"
1736  			keyType = KeyAlgoECDSA256
1737  		case "P-384":
1738  			curve = "nistp384"
1739  			keyType = KeyAlgoECDSA384
1740  		case "P-521":
1741  			curve = "nistp521"
1742  			keyType = KeyAlgoECDSA521
1743  		default:
1744  			return nil, errors.New("ssh: unhandled elliptic curve " + name)
1745  		}
1746  
1747  		pub := elliptic.Marshal(k.Curve, k.PublicKey.X, k.PublicKey.Y)
1748  
1749  		// Marshal public key.
1750  		pubKey := struct {
1751  			KeyType string
1752  			Curve   string
1753  			Pub     []byte
1754  		}{
1755  			keyType, curve, pub,
1756  		}
1757  		w.PubKey = Marshal(pubKey)
1758  
1759  		// Marshal private key.
1760  		key := openSSHECDSAPrivateKey{
1761  			Curve:   curve,
1762  			Pub:     pub,
1763  			D:       k.D,
1764  			Comment: comment,
1765  		}
1766  		pk1.Keytype = keyType
1767  		pk1.Rest = Marshal(key)
1768  	default:
1769  		return nil, fmt.Errorf("ssh: unsupported key type %T", k)
1770  	}
1771  
1772  	var err error
1773  	// Add padding and encrypt the key if necessary.
1774  	w.PrivKeyBlock, w.CipherName, w.KdfName, w.KdfOpts, err = encrypt(Marshal(pk1))
1775  	if err != nil {
1776  		return nil, err
1777  	}
1778  
1779  	b := Marshal(w)
1780  	block := &pem.Block{
1781  		Type:  "OPENSSH PRIVATE KEY",
1782  		Bytes: append([]byte(privateKeyAuthMagic), b...),
1783  	}
1784  	return block, nil
1785  }
1786  
1787  func checkOpenSSHKeyPadding(pad []byte) error {
1788  	for i, b := range pad {
1789  		if int(b) != i+1 {
1790  			return errors.New("ssh: padding not as expected")
1791  		}
1792  	}
1793  	return nil
1794  }
1795  
1796  func generateOpenSSHPadding(block []byte, blockSize int) []byte {
1797  	for i, l := 0, len(block); (l+i)%blockSize != 0; i++ {
1798  		block = append(block, byte(i+1))
1799  	}
1800  	return block
1801  }
1802  
1803  // FingerprintLegacyMD5 returns the user presentation of the key's
1804  // fingerprint as described by RFC 4716 section 4.
1805  func FingerprintLegacyMD5(pubKey PublicKey) string {
1806  	md5sum := md5.Sum(pubKey.Marshal())
1807  	hexarray := make([]string, len(md5sum))
1808  	for i, c := range md5sum {
1809  		hexarray[i] = hex.EncodeToString([]byte{c})
1810  	}
1811  	return strings.Join(hexarray, ":")
1812  }
1813  
1814  // FingerprintSHA256 returns the user presentation of the key's
1815  // fingerprint as unpadded base64 encoded sha256 hash.
1816  // This format was introduced from OpenSSH 6.8.
1817  // https://www.openssh.com/txt/release-6.8
1818  // https://tools.ietf.org/html/rfc4648#section-3.2 (unpadded base64 encoding)
1819  func FingerprintSHA256(pubKey PublicKey) string {
1820  	sha256sum := sha256.Sum256(pubKey.Marshal())
1821  	hash := base64.RawStdEncoding.EncodeToString(sha256sum[:])
1822  	return "SHA256:" + hash
1823  }
1824