github.com/psiphon-Labs/psiphon-tunnel-core@v2.0.28+incompatible/psiphon/common/crypto/ssh/keys.go (about)

     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/elliptic"
    15  	"crypto/md5"
    16  	"crypto/rsa"
    17  	"crypto/sha256"
    18  	"crypto/x509"
    19  	"encoding/asn1"
    20  	"encoding/base64"
    21  	"encoding/hex"
    22  	"encoding/pem"
    23  	"errors"
    24  	"fmt"
    25  	"io"
    26  	"math/big"
    27  	"strings"
    28  
    29  	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/crypto/ssh/internal/bcrypt_pbkdf"
    30  	"golang.org/x/crypto/ed25519"
    31  )
    32  
    33  // These constants represent the algorithm names for key types supported by this
    34  // package.
    35  const (
    36  	KeyAlgoRSA        = "ssh-rsa"
    37  	KeyAlgoDSA        = "ssh-dss"
    38  	KeyAlgoECDSA256   = "ecdsa-sha2-nistp256"
    39  	KeyAlgoSKECDSA256 = "sk-ecdsa-sha2-nistp256@openssh.com"
    40  	KeyAlgoECDSA384   = "ecdsa-sha2-nistp384"
    41  	KeyAlgoECDSA521   = "ecdsa-sha2-nistp521"
    42  	KeyAlgoED25519    = "ssh-ed25519"
    43  	KeyAlgoSKED25519  = "sk-ssh-ed25519@openssh.com"
    44  )
    45  
    46  // These constants represent non-default signature algorithms that are supported
    47  // as algorithm parameters to AlgorithmSigner.SignWithAlgorithm methods. See
    48  // [PROTOCOL.agent] section 4.5.1 and
    49  // https://tools.ietf.org/html/draft-ietf-curdle-rsa-sha2-10
    50  const (
    51  	SigAlgoRSA        = "ssh-rsa"
    52  	SigAlgoRSASHA2256 = "rsa-sha2-256"
    53  	SigAlgoRSASHA2512 = "rsa-sha2-512"
    54  )
    55  
    56  // parsePubKey parses a public key of the given algorithm.
    57  // Use ParsePublicKey for keys with prepended algorithm.
    58  func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err error) {
    59  	switch algo {
    60  	case KeyAlgoRSA:
    61  		return parseRSA(in)
    62  	case KeyAlgoDSA:
    63  		return parseDSA(in)
    64  	case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:
    65  		return parseECDSA(in)
    66  	case KeyAlgoSKECDSA256:
    67  		return parseSKECDSA(in)
    68  	case KeyAlgoED25519:
    69  		return parseED25519(in)
    70  	case KeyAlgoSKED25519:
    71  		return parseSKEd25519(in)
    72  	case CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA384v01, CertAlgoECDSA521v01, CertAlgoSKECDSA256v01, CertAlgoED25519v01, CertAlgoSKED25519v01:
    73  		cert, err := parseCert(in, certToPrivAlgo(algo))
    74  		if err != nil {
    75  			return nil, nil, err
    76  		}
    77  		return cert, nil, nil
    78  	}
    79  	return nil, nil, fmt.Errorf("ssh: unknown key algorithm: %v", algo)
    80  }
    81  
    82  // parseAuthorizedKey parses a public key in OpenSSH authorized_keys format
    83  // (see sshd(8) manual page) once the options and key type fields have been
    84  // removed.
    85  func parseAuthorizedKey(in []byte) (out PublicKey, comment string, err error) {
    86  	in = bytes.TrimSpace(in)
    87  
    88  	i := bytes.IndexAny(in, " \t")
    89  	if i == -1 {
    90  		i = len(in)
    91  	}
    92  	base64Key := in[:i]
    93  
    94  	key := make([]byte, base64.StdEncoding.DecodedLen(len(base64Key)))
    95  	n, err := base64.StdEncoding.Decode(key, base64Key)
    96  	if err != nil {
    97  		return nil, "", err
    98  	}
    99  	key = key[:n]
   100  	out, err = ParsePublicKey(key)
   101  	if err != nil {
   102  		return nil, "", err
   103  	}
   104  	comment = string(bytes.TrimSpace(in[i:]))
   105  	return out, comment, nil
   106  }
   107  
   108  // ParseKnownHosts parses an entry in the format of the known_hosts file.
   109  //
   110  // The known_hosts format is documented in the sshd(8) manual page. This
   111  // function will parse a single entry from in. On successful return, marker
   112  // will contain the optional marker value (i.e. "cert-authority" or "revoked")
   113  // or else be empty, hosts will contain the hosts that this entry matches,
   114  // pubKey will contain the public key and comment will contain any trailing
   115  // comment at the end of the line. See the sshd(8) manual page for the various
   116  // forms that a host string can take.
   117  //
   118  // The unparsed remainder of the input will be returned in rest. This function
   119  // can be called repeatedly to parse multiple entries.
   120  //
   121  // If no entries were found in the input then err will be io.EOF. Otherwise a
   122  // non-nil err value indicates a parse error.
   123  func ParseKnownHosts(in []byte) (marker string, hosts []string, pubKey PublicKey, comment string, rest []byte, err error) {
   124  	for len(in) > 0 {
   125  		end := bytes.IndexByte(in, '\n')
   126  		if end != -1 {
   127  			rest = in[end+1:]
   128  			in = in[:end]
   129  		} else {
   130  			rest = nil
   131  		}
   132  
   133  		end = bytes.IndexByte(in, '\r')
   134  		if end != -1 {
   135  			in = in[:end]
   136  		}
   137  
   138  		in = bytes.TrimSpace(in)
   139  		if len(in) == 0 || in[0] == '#' {
   140  			in = rest
   141  			continue
   142  		}
   143  
   144  		i := bytes.IndexAny(in, " \t")
   145  		if i == -1 {
   146  			in = rest
   147  			continue
   148  		}
   149  
   150  		// Strip out the beginning of the known_host key.
   151  		// This is either an optional marker or a (set of) hostname(s).
   152  		keyFields := bytes.Fields(in)
   153  		if len(keyFields) < 3 || len(keyFields) > 5 {
   154  			return "", nil, nil, "", nil, errors.New("ssh: invalid entry in known_hosts data")
   155  		}
   156  
   157  		// keyFields[0] is either "@cert-authority", "@revoked" or a comma separated
   158  		// list of hosts
   159  		marker := ""
   160  		if keyFields[0][0] == '@' {
   161  			marker = string(keyFields[0][1:])
   162  			keyFields = keyFields[1:]
   163  		}
   164  
   165  		hosts := string(keyFields[0])
   166  		// keyFields[1] contains the key type (e.g. “ssh-rsa”).
   167  		// However, that information is duplicated inside the
   168  		// base64-encoded key and so is ignored here.
   169  
   170  		key := bytes.Join(keyFields[2:], []byte(" "))
   171  		if pubKey, comment, err = parseAuthorizedKey(key); err != nil {
   172  			return "", nil, nil, "", nil, err
   173  		}
   174  
   175  		return marker, strings.Split(hosts, ","), pubKey, comment, rest, nil
   176  	}
   177  
   178  	return "", nil, nil, "", nil, io.EOF
   179  }
   180  
   181  // ParseAuthorizedKeys parses a public key from an authorized_keys
   182  // file used in OpenSSH according to the sshd(8) manual page.
   183  func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error) {
   184  	for len(in) > 0 {
   185  		end := bytes.IndexByte(in, '\n')
   186  		if end != -1 {
   187  			rest = in[end+1:]
   188  			in = in[:end]
   189  		} else {
   190  			rest = nil
   191  		}
   192  
   193  		end = bytes.IndexByte(in, '\r')
   194  		if end != -1 {
   195  			in = in[:end]
   196  		}
   197  
   198  		in = bytes.TrimSpace(in)
   199  		if len(in) == 0 || in[0] == '#' {
   200  			in = rest
   201  			continue
   202  		}
   203  
   204  		i := bytes.IndexAny(in, " \t")
   205  		if i == -1 {
   206  			in = rest
   207  			continue
   208  		}
   209  
   210  		if out, comment, err = parseAuthorizedKey(in[i:]); err == nil {
   211  			return out, comment, options, rest, nil
   212  		}
   213  
   214  		// No key type recognised. Maybe there's an options field at
   215  		// the beginning.
   216  		var b byte
   217  		inQuote := false
   218  		var candidateOptions []string
   219  		optionStart := 0
   220  		for i, b = range in {
   221  			isEnd := !inQuote && (b == ' ' || b == '\t')
   222  			if (b == ',' && !inQuote) || isEnd {
   223  				if i-optionStart > 0 {
   224  					candidateOptions = append(candidateOptions, string(in[optionStart:i]))
   225  				}
   226  				optionStart = i + 1
   227  			}
   228  			if isEnd {
   229  				break
   230  			}
   231  			if b == '"' && (i == 0 || (i > 0 && in[i-1] != '\\')) {
   232  				inQuote = !inQuote
   233  			}
   234  		}
   235  		for i < len(in) && (in[i] == ' ' || in[i] == '\t') {
   236  			i++
   237  		}
   238  		if i == len(in) {
   239  			// Invalid line: unmatched quote
   240  			in = rest
   241  			continue
   242  		}
   243  
   244  		in = in[i:]
   245  		i = bytes.IndexAny(in, " \t")
   246  		if i == -1 {
   247  			in = rest
   248  			continue
   249  		}
   250  
   251  		if out, comment, err = parseAuthorizedKey(in[i:]); err == nil {
   252  			options = candidateOptions
   253  			return out, comment, options, rest, nil
   254  		}
   255  
   256  		in = rest
   257  		continue
   258  	}
   259  
   260  	return nil, "", nil, nil, errors.New("ssh: no key found")
   261  }
   262  
   263  // ParsePublicKey parses an SSH public key formatted for use in
   264  // the SSH wire protocol according to RFC 4253, section 6.6.
   265  func ParsePublicKey(in []byte) (out PublicKey, err error) {
   266  	algo, in, ok := parseString(in)
   267  	if !ok {
   268  		return nil, errShortRead
   269  	}
   270  	var rest []byte
   271  	out, rest, err = parsePubKey(in, string(algo))
   272  	if len(rest) > 0 {
   273  		return nil, errors.New("ssh: trailing junk in public key")
   274  	}
   275  
   276  	return out, err
   277  }
   278  
   279  // MarshalAuthorizedKey serializes key for inclusion in an OpenSSH
   280  // authorized_keys file. The return value ends with newline.
   281  func MarshalAuthorizedKey(key PublicKey) []byte {
   282  	b := &bytes.Buffer{}
   283  	b.WriteString(key.Type())
   284  	b.WriteByte(' ')
   285  	e := base64.NewEncoder(base64.StdEncoding, b)
   286  	e.Write(key.Marshal())
   287  	e.Close()
   288  	b.WriteByte('\n')
   289  	return b.Bytes()
   290  }
   291  
   292  // PublicKey is an abstraction of different types of public keys.
   293  type PublicKey interface {
   294  	// Type returns the key's type, e.g. "ssh-rsa".
   295  	Type() string
   296  
   297  	// Marshal returns the serialized key data in SSH wire format,
   298  	// with the name prefix. To unmarshal the returned data, use
   299  	// the ParsePublicKey function.
   300  	Marshal() []byte
   301  
   302  	// Verify that sig is a signature on the given data using this
   303  	// key. This function will hash the data appropriately first.
   304  	Verify(data []byte, sig *Signature) error
   305  }
   306  
   307  // CryptoPublicKey, if implemented by a PublicKey,
   308  // returns the underlying crypto.PublicKey form of the key.
   309  type CryptoPublicKey interface {
   310  	CryptoPublicKey() crypto.PublicKey
   311  }
   312  
   313  // A Signer can create signatures that verify against a public key.
   314  type Signer interface {
   315  	// PublicKey returns an associated PublicKey instance.
   316  	PublicKey() PublicKey
   317  
   318  	// Sign returns raw signature for the given data. This method
   319  	// will apply the hash specified for the keytype to the data.
   320  	Sign(rand io.Reader, data []byte) (*Signature, error)
   321  }
   322  
   323  // A AlgorithmSigner is a Signer that also supports specifying a specific
   324  // algorithm to use for signing.
   325  type AlgorithmSigner interface {
   326  	Signer
   327  
   328  	// SignWithAlgorithm is like Signer.Sign, but allows specification of a
   329  	// non-default signing algorithm. See the SigAlgo* constants in this
   330  	// package for signature algorithms supported by this package. Callers may
   331  	// pass an empty string for the algorithm in which case the AlgorithmSigner
   332  	// will use its default algorithm.
   333  	SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error)
   334  }
   335  
   336  type rsaPublicKey rsa.PublicKey
   337  
   338  func (r *rsaPublicKey) Type() string {
   339  	return "ssh-rsa"
   340  }
   341  
   342  // parseRSA parses an RSA key according to RFC 4253, section 6.6.
   343  func parseRSA(in []byte) (out PublicKey, rest []byte, err error) {
   344  	var w struct {
   345  		E    *big.Int
   346  		N    *big.Int
   347  		Rest []byte `ssh:"rest"`
   348  	}
   349  	if err := Unmarshal(in, &w); err != nil {
   350  		return nil, nil, err
   351  	}
   352  
   353  	if w.E.BitLen() > 24 {
   354  		return nil, nil, errors.New("ssh: exponent too large")
   355  	}
   356  	e := w.E.Int64()
   357  	if e < 3 || e&1 == 0 {
   358  		return nil, nil, errors.New("ssh: incorrect exponent")
   359  	}
   360  
   361  	var key rsa.PublicKey
   362  	key.E = int(e)
   363  	key.N = w.N
   364  	return (*rsaPublicKey)(&key), w.Rest, nil
   365  }
   366  
   367  func (r *rsaPublicKey) Marshal() []byte {
   368  	e := new(big.Int).SetInt64(int64(r.E))
   369  	// RSA publickey struct layout should match the struct used by
   370  	// parseRSACert in the x/crypto/ssh/agent package.
   371  	wirekey := struct {
   372  		Name string
   373  		E    *big.Int
   374  		N    *big.Int
   375  	}{
   376  		KeyAlgoRSA,
   377  		e,
   378  		r.N,
   379  	}
   380  	return Marshal(&wirekey)
   381  }
   382  
   383  func (r *rsaPublicKey) Verify(data []byte, sig *Signature) error {
   384  	var hash crypto.Hash
   385  	switch sig.Format {
   386  	case SigAlgoRSA:
   387  		hash = crypto.SHA1
   388  	case SigAlgoRSASHA2256:
   389  		hash = crypto.SHA256
   390  	case SigAlgoRSASHA2512:
   391  		hash = crypto.SHA512
   392  	default:
   393  		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, r.Type())
   394  	}
   395  	h := hash.New()
   396  	h.Write(data)
   397  	digest := h.Sum(nil)
   398  	return rsa.VerifyPKCS1v15((*rsa.PublicKey)(r), hash, digest, sig.Blob)
   399  }
   400  
   401  func (r *rsaPublicKey) CryptoPublicKey() crypto.PublicKey {
   402  	return (*rsa.PublicKey)(r)
   403  }
   404  
   405  type dsaPublicKey dsa.PublicKey
   406  
   407  func (k *dsaPublicKey) Type() string {
   408  	return "ssh-dss"
   409  }
   410  
   411  func checkDSAParams(param *dsa.Parameters) error {
   412  	// SSH specifies FIPS 186-2, which only provided a single size
   413  	// (1024 bits) DSA key. FIPS 186-3 allows for larger key
   414  	// sizes, which would confuse SSH.
   415  	if l := param.P.BitLen(); l != 1024 {
   416  		return fmt.Errorf("ssh: unsupported DSA key size %d", l)
   417  	}
   418  
   419  	return nil
   420  }
   421  
   422  // parseDSA parses an DSA key according to RFC 4253, section 6.6.
   423  func parseDSA(in []byte) (out PublicKey, rest []byte, err error) {
   424  	var w struct {
   425  		P, Q, G, Y *big.Int
   426  		Rest       []byte `ssh:"rest"`
   427  	}
   428  	if err := Unmarshal(in, &w); err != nil {
   429  		return nil, nil, err
   430  	}
   431  
   432  	param := dsa.Parameters{
   433  		P: w.P,
   434  		Q: w.Q,
   435  		G: w.G,
   436  	}
   437  	if err := checkDSAParams(&param); err != nil {
   438  		return nil, nil, err
   439  	}
   440  
   441  	key := &dsaPublicKey{
   442  		Parameters: param,
   443  		Y:          w.Y,
   444  	}
   445  	return key, w.Rest, nil
   446  }
   447  
   448  func (k *dsaPublicKey) Marshal() []byte {
   449  	// DSA publickey struct layout should match the struct used by
   450  	// parseDSACert in the x/crypto/ssh/agent package.
   451  	w := struct {
   452  		Name       string
   453  		P, Q, G, Y *big.Int
   454  	}{
   455  		k.Type(),
   456  		k.P,
   457  		k.Q,
   458  		k.G,
   459  		k.Y,
   460  	}
   461  
   462  	return Marshal(&w)
   463  }
   464  
   465  func (k *dsaPublicKey) Verify(data []byte, sig *Signature) error {
   466  	if sig.Format != k.Type() {
   467  		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
   468  	}
   469  	h := crypto.SHA1.New()
   470  	h.Write(data)
   471  	digest := h.Sum(nil)
   472  
   473  	// Per RFC 4253, section 6.6,
   474  	// The value for 'dss_signature_blob' is encoded as a string containing
   475  	// r, followed by s (which are 160-bit integers, without lengths or
   476  	// padding, unsigned, and in network byte order).
   477  	// For DSS purposes, sig.Blob should be exactly 40 bytes in length.
   478  	if len(sig.Blob) != 40 {
   479  		return errors.New("ssh: DSA signature parse error")
   480  	}
   481  	r := new(big.Int).SetBytes(sig.Blob[:20])
   482  	s := new(big.Int).SetBytes(sig.Blob[20:])
   483  	if dsa.Verify((*dsa.PublicKey)(k), digest, r, s) {
   484  		return nil
   485  	}
   486  	return errors.New("ssh: signature did not verify")
   487  }
   488  
   489  func (k *dsaPublicKey) CryptoPublicKey() crypto.PublicKey {
   490  	return (*dsa.PublicKey)(k)
   491  }
   492  
   493  type dsaPrivateKey struct {
   494  	*dsa.PrivateKey
   495  }
   496  
   497  func (k *dsaPrivateKey) PublicKey() PublicKey {
   498  	return (*dsaPublicKey)(&k.PrivateKey.PublicKey)
   499  }
   500  
   501  func (k *dsaPrivateKey) Sign(rand io.Reader, data []byte) (*Signature, error) {
   502  	return k.SignWithAlgorithm(rand, data, "")
   503  }
   504  
   505  func (k *dsaPrivateKey) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
   506  	if algorithm != "" && algorithm != k.PublicKey().Type() {
   507  		return nil, fmt.Errorf("ssh: unsupported signature algorithm %s", algorithm)
   508  	}
   509  
   510  	h := crypto.SHA1.New()
   511  	h.Write(data)
   512  	digest := h.Sum(nil)
   513  	r, s, err := dsa.Sign(rand, k.PrivateKey, digest)
   514  	if err != nil {
   515  		return nil, err
   516  	}
   517  
   518  	sig := make([]byte, 40)
   519  	rb := r.Bytes()
   520  	sb := s.Bytes()
   521  
   522  	copy(sig[20-len(rb):20], rb)
   523  	copy(sig[40-len(sb):], sb)
   524  
   525  	return &Signature{
   526  		Format: k.PublicKey().Type(),
   527  		Blob:   sig,
   528  	}, nil
   529  }
   530  
   531  type ecdsaPublicKey ecdsa.PublicKey
   532  
   533  func (k *ecdsaPublicKey) Type() string {
   534  	return "ecdsa-sha2-" + k.nistID()
   535  }
   536  
   537  func (k *ecdsaPublicKey) nistID() string {
   538  	switch k.Params().BitSize {
   539  	case 256:
   540  		return "nistp256"
   541  	case 384:
   542  		return "nistp384"
   543  	case 521:
   544  		return "nistp521"
   545  	}
   546  	panic("ssh: unsupported ecdsa key size")
   547  }
   548  
   549  type ed25519PublicKey ed25519.PublicKey
   550  
   551  func (k ed25519PublicKey) Type() string {
   552  	return KeyAlgoED25519
   553  }
   554  
   555  func parseED25519(in []byte) (out PublicKey, rest []byte, err error) {
   556  	var w struct {
   557  		KeyBytes []byte
   558  		Rest     []byte `ssh:"rest"`
   559  	}
   560  
   561  	if err := Unmarshal(in, &w); err != nil {
   562  		return nil, nil, err
   563  	}
   564  
   565  	if l := len(w.KeyBytes); l != ed25519.PublicKeySize {
   566  		return nil, nil, fmt.Errorf("invalid size %d for Ed25519 public key", l)
   567  	}
   568  
   569  	return ed25519PublicKey(w.KeyBytes), w.Rest, nil
   570  }
   571  
   572  func (k ed25519PublicKey) Marshal() []byte {
   573  	w := struct {
   574  		Name     string
   575  		KeyBytes []byte
   576  	}{
   577  		KeyAlgoED25519,
   578  		[]byte(k),
   579  	}
   580  	return Marshal(&w)
   581  }
   582  
   583  func (k ed25519PublicKey) Verify(b []byte, sig *Signature) error {
   584  	if sig.Format != k.Type() {
   585  		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
   586  	}
   587  	if l := len(k); l != ed25519.PublicKeySize {
   588  		return fmt.Errorf("ssh: invalid size %d for Ed25519 public key", l)
   589  	}
   590  
   591  	if ok := ed25519.Verify(ed25519.PublicKey(k), b, sig.Blob); !ok {
   592  		return errors.New("ssh: signature did not verify")
   593  	}
   594  
   595  	return nil
   596  }
   597  
   598  func (k ed25519PublicKey) CryptoPublicKey() crypto.PublicKey {
   599  	return ed25519.PublicKey(k)
   600  }
   601  
   602  func supportedEllipticCurve(curve elliptic.Curve) bool {
   603  	return curve == elliptic.P256() || curve == elliptic.P384() || curve == elliptic.P521()
   604  }
   605  
   606  // ecHash returns the hash to match the given elliptic curve, see RFC
   607  // 5656, section 6.2.1
   608  func ecHash(curve elliptic.Curve) crypto.Hash {
   609  	bitSize := curve.Params().BitSize
   610  	switch {
   611  	case bitSize <= 256:
   612  		return crypto.SHA256
   613  	case bitSize <= 384:
   614  		return crypto.SHA384
   615  	}
   616  	return crypto.SHA512
   617  }
   618  
   619  // parseECDSA parses an ECDSA key according to RFC 5656, section 3.1.
   620  func parseECDSA(in []byte) (out PublicKey, rest []byte, err error) {
   621  	var w struct {
   622  		Curve    string
   623  		KeyBytes []byte
   624  		Rest     []byte `ssh:"rest"`
   625  	}
   626  
   627  	if err := Unmarshal(in, &w); err != nil {
   628  		return nil, nil, err
   629  	}
   630  
   631  	key := new(ecdsa.PublicKey)
   632  
   633  	switch w.Curve {
   634  	case "nistp256":
   635  		key.Curve = elliptic.P256()
   636  	case "nistp384":
   637  		key.Curve = elliptic.P384()
   638  	case "nistp521":
   639  		key.Curve = elliptic.P521()
   640  	default:
   641  		return nil, nil, errors.New("ssh: unsupported curve")
   642  	}
   643  
   644  	key.X, key.Y = elliptic.Unmarshal(key.Curve, w.KeyBytes)
   645  	if key.X == nil || key.Y == nil {
   646  		return nil, nil, errors.New("ssh: invalid curve point")
   647  	}
   648  	return (*ecdsaPublicKey)(key), w.Rest, nil
   649  }
   650  
   651  func (k *ecdsaPublicKey) Marshal() []byte {
   652  	// See RFC 5656, section 3.1.
   653  	keyBytes := elliptic.Marshal(k.Curve, k.X, k.Y)
   654  	// ECDSA publickey struct layout should match the struct used by
   655  	// parseECDSACert in the x/crypto/ssh/agent package.
   656  	w := struct {
   657  		Name string
   658  		ID   string
   659  		Key  []byte
   660  	}{
   661  		k.Type(),
   662  		k.nistID(),
   663  		keyBytes,
   664  	}
   665  
   666  	return Marshal(&w)
   667  }
   668  
   669  func (k *ecdsaPublicKey) Verify(data []byte, sig *Signature) error {
   670  	if sig.Format != k.Type() {
   671  		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
   672  	}
   673  
   674  	h := ecHash(k.Curve).New()
   675  	h.Write(data)
   676  	digest := h.Sum(nil)
   677  
   678  	// Per RFC 5656, section 3.1.2,
   679  	// The ecdsa_signature_blob value has the following specific encoding:
   680  	//    mpint    r
   681  	//    mpint    s
   682  	var ecSig struct {
   683  		R *big.Int
   684  		S *big.Int
   685  	}
   686  
   687  	if err := Unmarshal(sig.Blob, &ecSig); err != nil {
   688  		return err
   689  	}
   690  
   691  	if ecdsa.Verify((*ecdsa.PublicKey)(k), digest, ecSig.R, ecSig.S) {
   692  		return nil
   693  	}
   694  	return errors.New("ssh: signature did not verify")
   695  }
   696  
   697  func (k *ecdsaPublicKey) CryptoPublicKey() crypto.PublicKey {
   698  	return (*ecdsa.PublicKey)(k)
   699  }
   700  
   701  // skFields holds the additional fields present in U2F/FIDO2 signatures.
   702  // See openssh/PROTOCOL.u2f 'SSH U2F Signatures' for details.
   703  type skFields struct {
   704  	// Flags contains U2F/FIDO2 flags such as 'user present'
   705  	Flags byte
   706  	// Counter is a monotonic signature counter which can be
   707  	// used to detect concurrent use of a private key, should
   708  	// it be extracted from hardware.
   709  	Counter uint32
   710  }
   711  
   712  type skECDSAPublicKey struct {
   713  	// application is a URL-like string, typically "ssh:" for SSH.
   714  	// see openssh/PROTOCOL.u2f for details.
   715  	application string
   716  	ecdsa.PublicKey
   717  }
   718  
   719  func (k *skECDSAPublicKey) Type() string {
   720  	return KeyAlgoSKECDSA256
   721  }
   722  
   723  func (k *skECDSAPublicKey) nistID() string {
   724  	return "nistp256"
   725  }
   726  
   727  func parseSKECDSA(in []byte) (out PublicKey, rest []byte, err error) {
   728  	var w struct {
   729  		Curve       string
   730  		KeyBytes    []byte
   731  		Application string
   732  		Rest        []byte `ssh:"rest"`
   733  	}
   734  
   735  	if err := Unmarshal(in, &w); err != nil {
   736  		return nil, nil, err
   737  	}
   738  
   739  	key := new(skECDSAPublicKey)
   740  	key.application = w.Application
   741  
   742  	if w.Curve != "nistp256" {
   743  		return nil, nil, errors.New("ssh: unsupported curve")
   744  	}
   745  	key.Curve = elliptic.P256()
   746  
   747  	key.X, key.Y = elliptic.Unmarshal(key.Curve, w.KeyBytes)
   748  	if key.X == nil || key.Y == nil {
   749  		return nil, nil, errors.New("ssh: invalid curve point")
   750  	}
   751  
   752  	return key, w.Rest, nil
   753  }
   754  
   755  func (k *skECDSAPublicKey) Marshal() []byte {
   756  	// See RFC 5656, section 3.1.
   757  	keyBytes := elliptic.Marshal(k.Curve, k.X, k.Y)
   758  	w := struct {
   759  		Name        string
   760  		ID          string
   761  		Key         []byte
   762  		Application string
   763  	}{
   764  		k.Type(),
   765  		k.nistID(),
   766  		keyBytes,
   767  		k.application,
   768  	}
   769  
   770  	return Marshal(&w)
   771  }
   772  
   773  func (k *skECDSAPublicKey) Verify(data []byte, sig *Signature) error {
   774  	if sig.Format != k.Type() {
   775  		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
   776  	}
   777  
   778  	h := ecHash(k.Curve).New()
   779  	h.Write([]byte(k.application))
   780  	appDigest := h.Sum(nil)
   781  
   782  	h.Reset()
   783  	h.Write(data)
   784  	dataDigest := h.Sum(nil)
   785  
   786  	var ecSig struct {
   787  		R *big.Int
   788  		S *big.Int
   789  	}
   790  	if err := Unmarshal(sig.Blob, &ecSig); err != nil {
   791  		return err
   792  	}
   793  
   794  	var skf skFields
   795  	if err := Unmarshal(sig.Rest, &skf); err != nil {
   796  		return err
   797  	}
   798  
   799  	blob := struct {
   800  		ApplicationDigest []byte `ssh:"rest"`
   801  		Flags             byte
   802  		Counter           uint32
   803  		MessageDigest     []byte `ssh:"rest"`
   804  	}{
   805  		appDigest,
   806  		skf.Flags,
   807  		skf.Counter,
   808  		dataDigest,
   809  	}
   810  
   811  	original := Marshal(blob)
   812  
   813  	h.Reset()
   814  	h.Write(original)
   815  	digest := h.Sum(nil)
   816  
   817  	if ecdsa.Verify((*ecdsa.PublicKey)(&k.PublicKey), digest, ecSig.R, ecSig.S) {
   818  		return nil
   819  	}
   820  	return errors.New("ssh: signature did not verify")
   821  }
   822  
   823  type skEd25519PublicKey struct {
   824  	// application is a URL-like string, typically "ssh:" for SSH.
   825  	// see openssh/PROTOCOL.u2f for details.
   826  	application string
   827  	ed25519.PublicKey
   828  }
   829  
   830  func (k *skEd25519PublicKey) Type() string {
   831  	return KeyAlgoSKED25519
   832  }
   833  
   834  func parseSKEd25519(in []byte) (out PublicKey, rest []byte, err error) {
   835  	var w struct {
   836  		KeyBytes    []byte
   837  		Application string
   838  		Rest        []byte `ssh:"rest"`
   839  	}
   840  
   841  	if err := Unmarshal(in, &w); err != nil {
   842  		return nil, nil, err
   843  	}
   844  
   845  	if l := len(w.KeyBytes); l != ed25519.PublicKeySize {
   846  		return nil, nil, fmt.Errorf("invalid size %d for Ed25519 public key", l)
   847  	}
   848  
   849  	key := new(skEd25519PublicKey)
   850  	key.application = w.Application
   851  	key.PublicKey = ed25519.PublicKey(w.KeyBytes)
   852  
   853  	return key, w.Rest, nil
   854  }
   855  
   856  func (k *skEd25519PublicKey) Marshal() []byte {
   857  	w := struct {
   858  		Name        string
   859  		KeyBytes    []byte
   860  		Application string
   861  	}{
   862  		KeyAlgoSKED25519,
   863  		[]byte(k.PublicKey),
   864  		k.application,
   865  	}
   866  	return Marshal(&w)
   867  }
   868  
   869  func (k *skEd25519PublicKey) Verify(data []byte, sig *Signature) error {
   870  	if sig.Format != k.Type() {
   871  		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
   872  	}
   873  	if l := len(k.PublicKey); l != ed25519.PublicKeySize {
   874  		return fmt.Errorf("invalid size %d for Ed25519 public key", l)
   875  	}
   876  
   877  	h := sha256.New()
   878  	h.Write([]byte(k.application))
   879  	appDigest := h.Sum(nil)
   880  
   881  	h.Reset()
   882  	h.Write(data)
   883  	dataDigest := h.Sum(nil)
   884  
   885  	var edSig struct {
   886  		Signature []byte `ssh:"rest"`
   887  	}
   888  
   889  	if err := Unmarshal(sig.Blob, &edSig); err != nil {
   890  		return err
   891  	}
   892  
   893  	var skf skFields
   894  	if err := Unmarshal(sig.Rest, &skf); err != nil {
   895  		return err
   896  	}
   897  
   898  	blob := struct {
   899  		ApplicationDigest []byte `ssh:"rest"`
   900  		Flags             byte
   901  		Counter           uint32
   902  		MessageDigest     []byte `ssh:"rest"`
   903  	}{
   904  		appDigest,
   905  		skf.Flags,
   906  		skf.Counter,
   907  		dataDigest,
   908  	}
   909  
   910  	original := Marshal(blob)
   911  
   912  	if ok := ed25519.Verify(k.PublicKey, original, edSig.Signature); !ok {
   913  		return errors.New("ssh: signature did not verify")
   914  	}
   915  
   916  	return nil
   917  }
   918  
   919  // NewSignerFromKey takes an *rsa.PrivateKey, *dsa.PrivateKey,
   920  // *ecdsa.PrivateKey or any other crypto.Signer and returns a
   921  // corresponding Signer instance. ECDSA keys must use P-256, P-384 or
   922  // P-521. DSA keys must use parameter size L1024N160.
   923  func NewSignerFromKey(key interface{}) (Signer, error) {
   924  	switch key := key.(type) {
   925  	case crypto.Signer:
   926  		return NewSignerFromSigner(key)
   927  	case *dsa.PrivateKey:
   928  		return newDSAPrivateKey(key)
   929  	default:
   930  		return nil, fmt.Errorf("ssh: unsupported key type %T", key)
   931  	}
   932  }
   933  
   934  func newDSAPrivateKey(key *dsa.PrivateKey) (Signer, error) {
   935  	if err := checkDSAParams(&key.PublicKey.Parameters); err != nil {
   936  		return nil, err
   937  	}
   938  
   939  	return &dsaPrivateKey{key}, nil
   940  }
   941  
   942  type rsaSigner struct {
   943  	AlgorithmSigner
   944  	defaultAlgorithm string
   945  }
   946  
   947  func (s *rsaSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
   948  	return s.AlgorithmSigner.SignWithAlgorithm(rand, data, s.defaultAlgorithm)
   949  }
   950  
   951  type wrappedSigner struct {
   952  	signer crypto.Signer
   953  	pubKey PublicKey
   954  }
   955  
   956  // NewSignerFromSigner takes any crypto.Signer implementation and
   957  // returns a corresponding Signer interface. This can be used, for
   958  // example, with keys kept in hardware modules.
   959  func NewSignerFromSigner(signer crypto.Signer) (Signer, error) {
   960  	pubKey, err := NewPublicKey(signer.Public())
   961  	if err != nil {
   962  		return nil, err
   963  	}
   964  
   965  	return &wrappedSigner{signer, pubKey}, nil
   966  }
   967  
   968  func (s *wrappedSigner) PublicKey() PublicKey {
   969  	return s.pubKey
   970  }
   971  
   972  func (s *wrappedSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
   973  	return s.SignWithAlgorithm(rand, data, "")
   974  }
   975  
   976  func (s *wrappedSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) {
   977  	var hashFunc crypto.Hash
   978  
   979  	if _, ok := s.pubKey.(*rsaPublicKey); ok {
   980  		// RSA keys support a few hash functions determined by the requested signature algorithm
   981  		switch algorithm {
   982  		case "", SigAlgoRSA:
   983  			algorithm = SigAlgoRSA
   984  			hashFunc = crypto.SHA1
   985  		case SigAlgoRSASHA2256:
   986  			hashFunc = crypto.SHA256
   987  		case SigAlgoRSASHA2512:
   988  			hashFunc = crypto.SHA512
   989  		default:
   990  			return nil, fmt.Errorf("ssh: unsupported signature algorithm %s", algorithm)
   991  		}
   992  	} else {
   993  		// The only supported algorithm for all other key types is the same as the type of the key
   994  		if algorithm == "" {
   995  			algorithm = s.pubKey.Type()
   996  		} else if algorithm != s.pubKey.Type() {
   997  			return nil, fmt.Errorf("ssh: unsupported signature algorithm %s", algorithm)
   998  		}
   999  
  1000  		switch key := s.pubKey.(type) {
  1001  		case *dsaPublicKey:
  1002  			hashFunc = crypto.SHA1
  1003  		case *ecdsaPublicKey:
  1004  			hashFunc = ecHash(key.Curve)
  1005  		case ed25519PublicKey:
  1006  		default:
  1007  			return nil, fmt.Errorf("ssh: unsupported key type %T", key)
  1008  		}
  1009  	}
  1010  
  1011  	var digest []byte
  1012  	if hashFunc != 0 {
  1013  		h := hashFunc.New()
  1014  		h.Write(data)
  1015  		digest = h.Sum(nil)
  1016  	} else {
  1017  		digest = data
  1018  	}
  1019  
  1020  	signature, err := s.signer.Sign(rand, digest, hashFunc)
  1021  	if err != nil {
  1022  		return nil, err
  1023  	}
  1024  
  1025  	// crypto.Signer.Sign is expected to return an ASN.1-encoded signature
  1026  	// for ECDSA and DSA, but that's not the encoding expected by SSH, so
  1027  	// re-encode.
  1028  	switch s.pubKey.(type) {
  1029  	case *ecdsaPublicKey, *dsaPublicKey:
  1030  		type asn1Signature struct {
  1031  			R, S *big.Int
  1032  		}
  1033  		asn1Sig := new(asn1Signature)
  1034  		_, err := asn1.Unmarshal(signature, asn1Sig)
  1035  		if err != nil {
  1036  			return nil, err
  1037  		}
  1038  
  1039  		switch s.pubKey.(type) {
  1040  		case *ecdsaPublicKey:
  1041  			signature = Marshal(asn1Sig)
  1042  
  1043  		case *dsaPublicKey:
  1044  			signature = make([]byte, 40)
  1045  			r := asn1Sig.R.Bytes()
  1046  			s := asn1Sig.S.Bytes()
  1047  			copy(signature[20-len(r):20], r)
  1048  			copy(signature[40-len(s):40], s)
  1049  		}
  1050  	}
  1051  
  1052  	return &Signature{
  1053  		Format: algorithm,
  1054  		Blob:   signature,
  1055  	}, nil
  1056  }
  1057  
  1058  // NewPublicKey takes an *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey,
  1059  // or ed25519.PublicKey returns a corresponding PublicKey instance.
  1060  // ECDSA keys must use P-256, P-384 or P-521.
  1061  func NewPublicKey(key interface{}) (PublicKey, error) {
  1062  	switch key := key.(type) {
  1063  	case *rsa.PublicKey:
  1064  		return (*rsaPublicKey)(key), nil
  1065  	case *ecdsa.PublicKey:
  1066  		if !supportedEllipticCurve(key.Curve) {
  1067  			return nil, errors.New("ssh: only P-256, P-384 and P-521 EC keys are supported")
  1068  		}
  1069  		return (*ecdsaPublicKey)(key), nil
  1070  	case *dsa.PublicKey:
  1071  		return (*dsaPublicKey)(key), nil
  1072  	case ed25519.PublicKey:
  1073  		if l := len(key); l != ed25519.PublicKeySize {
  1074  			return nil, fmt.Errorf("ssh: invalid size %d for Ed25519 public key", l)
  1075  		}
  1076  		return ed25519PublicKey(key), nil
  1077  	default:
  1078  		return nil, fmt.Errorf("ssh: unsupported key type %T", key)
  1079  	}
  1080  }
  1081  
  1082  // ParsePrivateKey returns a Signer from a PEM encoded private key. It supports
  1083  // the same keys as ParseRawPrivateKey. If the private key is encrypted, it
  1084  // will return a PassphraseMissingError.
  1085  func ParsePrivateKey(pemBytes []byte) (Signer, error) {
  1086  	key, err := ParseRawPrivateKey(pemBytes)
  1087  	if err != nil {
  1088  		return nil, err
  1089  	}
  1090  
  1091  	return NewSignerFromKey(key)
  1092  }
  1093  
  1094  // ParsePrivateKeyWithPassphrase returns a Signer from a PEM encoded private
  1095  // key and passphrase. It supports the same keys as
  1096  // ParseRawPrivateKeyWithPassphrase.
  1097  func ParsePrivateKeyWithPassphrase(pemBytes, passphrase []byte) (Signer, error) {
  1098  	key, err := ParseRawPrivateKeyWithPassphrase(pemBytes, passphrase)
  1099  	if err != nil {
  1100  		return nil, err
  1101  	}
  1102  
  1103  	return NewSignerFromKey(key)
  1104  }
  1105  
  1106  // encryptedBlock tells whether a private key is
  1107  // encrypted by examining its Proc-Type header
  1108  // for a mention of ENCRYPTED
  1109  // according to RFC 1421 Section 4.6.1.1.
  1110  func encryptedBlock(block *pem.Block) bool {
  1111  	return strings.Contains(block.Headers["Proc-Type"], "ENCRYPTED")
  1112  }
  1113  
  1114  // A PassphraseMissingError indicates that parsing this private key requires a
  1115  // passphrase. Use ParsePrivateKeyWithPassphrase.
  1116  type PassphraseMissingError struct {
  1117  	// PublicKey will be set if the private key format includes an unencrypted
  1118  	// public key along with the encrypted private key.
  1119  	PublicKey PublicKey
  1120  }
  1121  
  1122  func (*PassphraseMissingError) Error() string {
  1123  	return "ssh: this private key is passphrase protected"
  1124  }
  1125  
  1126  // ParseRawPrivateKey returns a private key from a PEM encoded private key. It
  1127  // supports RSA (PKCS#1), PKCS#8, DSA (OpenSSL), and ECDSA private keys. If the
  1128  // private key is encrypted, it will return a PassphraseMissingError.
  1129  func ParseRawPrivateKey(pemBytes []byte) (interface{}, error) {
  1130  	block, _ := pem.Decode(pemBytes)
  1131  	if block == nil {
  1132  		return nil, errors.New("ssh: no key found")
  1133  	}
  1134  
  1135  	if encryptedBlock(block) {
  1136  		return nil, &PassphraseMissingError{}
  1137  	}
  1138  
  1139  	switch block.Type {
  1140  	case "RSA PRIVATE KEY":
  1141  		return x509.ParsePKCS1PrivateKey(block.Bytes)
  1142  	// RFC5208 - https://tools.ietf.org/html/rfc5208
  1143  	case "PRIVATE KEY":
  1144  		return x509.ParsePKCS8PrivateKey(block.Bytes)
  1145  	case "EC PRIVATE KEY":
  1146  		return x509.ParseECPrivateKey(block.Bytes)
  1147  	case "DSA PRIVATE KEY":
  1148  		return ParseDSAPrivateKey(block.Bytes)
  1149  	case "OPENSSH PRIVATE KEY":
  1150  		return parseOpenSSHPrivateKey(block.Bytes, unencryptedOpenSSHKey)
  1151  	default:
  1152  		return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type)
  1153  	}
  1154  }
  1155  
  1156  // ParseRawPrivateKeyWithPassphrase returns a private key decrypted with
  1157  // passphrase from a PEM encoded private key. If the passphrase is wrong, it
  1158  // will return x509.IncorrectPasswordError.
  1159  func ParseRawPrivateKeyWithPassphrase(pemBytes, passphrase []byte) (interface{}, error) {
  1160  	block, _ := pem.Decode(pemBytes)
  1161  	if block == nil {
  1162  		return nil, errors.New("ssh: no key found")
  1163  	}
  1164  
  1165  	if block.Type == "OPENSSH PRIVATE KEY" {
  1166  		return parseOpenSSHPrivateKey(block.Bytes, passphraseProtectedOpenSSHKey(passphrase))
  1167  	}
  1168  
  1169  	if !encryptedBlock(block) || !x509.IsEncryptedPEMBlock(block) {
  1170  		return nil, errors.New("ssh: not an encrypted key")
  1171  	}
  1172  
  1173  	buf, err := x509.DecryptPEMBlock(block, passphrase)
  1174  	if err != nil {
  1175  		if err == x509.IncorrectPasswordError {
  1176  			return nil, err
  1177  		}
  1178  		return nil, fmt.Errorf("ssh: cannot decode encrypted private keys: %v", err)
  1179  	}
  1180  
  1181  	switch block.Type {
  1182  	case "RSA PRIVATE KEY":
  1183  		return x509.ParsePKCS1PrivateKey(buf)
  1184  	case "EC PRIVATE KEY":
  1185  		return x509.ParseECPrivateKey(buf)
  1186  	case "DSA PRIVATE KEY":
  1187  		return ParseDSAPrivateKey(buf)
  1188  	default:
  1189  		return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type)
  1190  	}
  1191  }
  1192  
  1193  // ParseDSAPrivateKey returns a DSA private key from its ASN.1 DER encoding, as
  1194  // specified by the OpenSSL DSA man page.
  1195  func ParseDSAPrivateKey(der []byte) (*dsa.PrivateKey, error) {
  1196  	var k struct {
  1197  		Version int
  1198  		P       *big.Int
  1199  		Q       *big.Int
  1200  		G       *big.Int
  1201  		Pub     *big.Int
  1202  		Priv    *big.Int
  1203  	}
  1204  	rest, err := asn1.Unmarshal(der, &k)
  1205  	if err != nil {
  1206  		return nil, errors.New("ssh: failed to parse DSA key: " + err.Error())
  1207  	}
  1208  	if len(rest) > 0 {
  1209  		return nil, errors.New("ssh: garbage after DSA key")
  1210  	}
  1211  
  1212  	return &dsa.PrivateKey{
  1213  		PublicKey: dsa.PublicKey{
  1214  			Parameters: dsa.Parameters{
  1215  				P: k.P,
  1216  				Q: k.Q,
  1217  				G: k.G,
  1218  			},
  1219  			Y: k.Pub,
  1220  		},
  1221  		X: k.Priv,
  1222  	}, nil
  1223  }
  1224  
  1225  func unencryptedOpenSSHKey(cipherName, kdfName, kdfOpts string, privKeyBlock []byte) ([]byte, error) {
  1226  	if kdfName != "none" || cipherName != "none" {
  1227  		return nil, &PassphraseMissingError{}
  1228  	}
  1229  	if kdfOpts != "" {
  1230  		return nil, errors.New("ssh: invalid openssh private key")
  1231  	}
  1232  	return privKeyBlock, nil
  1233  }
  1234  
  1235  func passphraseProtectedOpenSSHKey(passphrase []byte) openSSHDecryptFunc {
  1236  	return func(cipherName, kdfName, kdfOpts string, privKeyBlock []byte) ([]byte, error) {
  1237  		if kdfName == "none" || cipherName == "none" {
  1238  			return nil, errors.New("ssh: key is not password protected")
  1239  		}
  1240  		if kdfName != "bcrypt" {
  1241  			return nil, fmt.Errorf("ssh: unknown KDF %q, only supports %q", kdfName, "bcrypt")
  1242  		}
  1243  
  1244  		var opts struct {
  1245  			Salt   string
  1246  			Rounds uint32
  1247  		}
  1248  		if err := Unmarshal([]byte(kdfOpts), &opts); err != nil {
  1249  			return nil, err
  1250  		}
  1251  
  1252  		k, err := bcrypt_pbkdf.Key(passphrase, []byte(opts.Salt), int(opts.Rounds), 32+16)
  1253  		if err != nil {
  1254  			return nil, err
  1255  		}
  1256  		key, iv := k[:32], k[32:]
  1257  
  1258  		c, err := aes.NewCipher(key)
  1259  		if err != nil {
  1260  			return nil, err
  1261  		}
  1262  		switch cipherName {
  1263  		case "aes256-ctr":
  1264  			ctr := cipher.NewCTR(c, iv)
  1265  			ctr.XORKeyStream(privKeyBlock, privKeyBlock)
  1266  		case "aes256-cbc":
  1267  			if len(privKeyBlock)%c.BlockSize() != 0 {
  1268  				return nil, fmt.Errorf("ssh: invalid encrypted private key length, not a multiple of the block size")
  1269  			}
  1270  			cbc := cipher.NewCBCDecrypter(c, iv)
  1271  			cbc.CryptBlocks(privKeyBlock, privKeyBlock)
  1272  		default:
  1273  			return nil, fmt.Errorf("ssh: unknown cipher %q, only supports %q or %q", cipherName, "aes256-ctr", "aes256-cbc")
  1274  		}
  1275  
  1276  		return privKeyBlock, nil
  1277  	}
  1278  }
  1279  
  1280  type openSSHDecryptFunc func(CipherName, KdfName, KdfOpts string, PrivKeyBlock []byte) ([]byte, error)
  1281  
  1282  // parseOpenSSHPrivateKey parses an OpenSSH private key, using the decrypt
  1283  // function to unwrap the encrypted portion. unencryptedOpenSSHKey can be used
  1284  // as the decrypt function to parse an unencrypted private key. See
  1285  // https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key.
  1286  func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.PrivateKey, error) {
  1287  	const magic = "openssh-key-v1\x00"
  1288  	if len(key) < len(magic) || string(key[:len(magic)]) != magic {
  1289  		return nil, errors.New("ssh: invalid openssh private key format")
  1290  	}
  1291  	remaining := key[len(magic):]
  1292  
  1293  	var w struct {
  1294  		CipherName   string
  1295  		KdfName      string
  1296  		KdfOpts      string
  1297  		NumKeys      uint32
  1298  		PubKey       []byte
  1299  		PrivKeyBlock []byte
  1300  	}
  1301  
  1302  	if err := Unmarshal(remaining, &w); err != nil {
  1303  		return nil, err
  1304  	}
  1305  	if w.NumKeys != 1 {
  1306  		// We only support single key files, and so does OpenSSH.
  1307  		// https://github.com/openssh/openssh-portable/blob/4103a3ec7/sshkey.c#L4171
  1308  		return nil, errors.New("ssh: multi-key files are not supported")
  1309  	}
  1310  
  1311  	privKeyBlock, err := decrypt(w.CipherName, w.KdfName, w.KdfOpts, w.PrivKeyBlock)
  1312  	if err != nil {
  1313  		if err, ok := err.(*PassphraseMissingError); ok {
  1314  			pub, errPub := ParsePublicKey(w.PubKey)
  1315  			if errPub != nil {
  1316  				return nil, fmt.Errorf("ssh: failed to parse embedded public key: %v", errPub)
  1317  			}
  1318  			err.PublicKey = pub
  1319  		}
  1320  		return nil, err
  1321  	}
  1322  
  1323  	pk1 := struct {
  1324  		Check1  uint32
  1325  		Check2  uint32
  1326  		Keytype string
  1327  		Rest    []byte `ssh:"rest"`
  1328  	}{}
  1329  
  1330  	if err := Unmarshal(privKeyBlock, &pk1); err != nil || pk1.Check1 != pk1.Check2 {
  1331  		if w.CipherName != "none" {
  1332  			return nil, x509.IncorrectPasswordError
  1333  		}
  1334  		return nil, errors.New("ssh: malformed OpenSSH key")
  1335  	}
  1336  
  1337  	switch pk1.Keytype {
  1338  	case KeyAlgoRSA:
  1339  		// https://github.com/openssh/openssh-portable/blob/master/sshkey.c#L2760-L2773
  1340  		key := struct {
  1341  			N       *big.Int
  1342  			E       *big.Int
  1343  			D       *big.Int
  1344  			Iqmp    *big.Int
  1345  			P       *big.Int
  1346  			Q       *big.Int
  1347  			Comment string
  1348  			Pad     []byte `ssh:"rest"`
  1349  		}{}
  1350  
  1351  		if err := Unmarshal(pk1.Rest, &key); err != nil {
  1352  			return nil, err
  1353  		}
  1354  
  1355  		if err := checkOpenSSHKeyPadding(key.Pad); err != nil {
  1356  			return nil, err
  1357  		}
  1358  
  1359  		pk := &rsa.PrivateKey{
  1360  			PublicKey: rsa.PublicKey{
  1361  				N: key.N,
  1362  				E: int(key.E.Int64()),
  1363  			},
  1364  			D:      key.D,
  1365  			Primes: []*big.Int{key.P, key.Q},
  1366  		}
  1367  
  1368  		if err := pk.Validate(); err != nil {
  1369  			return nil, err
  1370  		}
  1371  
  1372  		pk.Precompute()
  1373  
  1374  		return pk, nil
  1375  	case KeyAlgoED25519:
  1376  		key := struct {
  1377  			Pub     []byte
  1378  			Priv    []byte
  1379  			Comment string
  1380  			Pad     []byte `ssh:"rest"`
  1381  		}{}
  1382  
  1383  		if err := Unmarshal(pk1.Rest, &key); err != nil {
  1384  			return nil, err
  1385  		}
  1386  
  1387  		if len(key.Priv) != ed25519.PrivateKeySize {
  1388  			return nil, errors.New("ssh: private key unexpected length")
  1389  		}
  1390  
  1391  		if err := checkOpenSSHKeyPadding(key.Pad); err != nil {
  1392  			return nil, err
  1393  		}
  1394  
  1395  		pk := ed25519.PrivateKey(make([]byte, ed25519.PrivateKeySize))
  1396  		copy(pk, key.Priv)
  1397  		return &pk, nil
  1398  	case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521:
  1399  		key := struct {
  1400  			Curve   string
  1401  			Pub     []byte
  1402  			D       *big.Int
  1403  			Comment string
  1404  			Pad     []byte `ssh:"rest"`
  1405  		}{}
  1406  
  1407  		if err := Unmarshal(pk1.Rest, &key); err != nil {
  1408  			return nil, err
  1409  		}
  1410  
  1411  		if err := checkOpenSSHKeyPadding(key.Pad); err != nil {
  1412  			return nil, err
  1413  		}
  1414  
  1415  		var curve elliptic.Curve
  1416  		switch key.Curve {
  1417  		case "nistp256":
  1418  			curve = elliptic.P256()
  1419  		case "nistp384":
  1420  			curve = elliptic.P384()
  1421  		case "nistp521":
  1422  			curve = elliptic.P521()
  1423  		default:
  1424  			return nil, errors.New("ssh: unhandled elliptic curve: " + key.Curve)
  1425  		}
  1426  
  1427  		X, Y := elliptic.Unmarshal(curve, key.Pub)
  1428  		if X == nil || Y == nil {
  1429  			return nil, errors.New("ssh: failed to unmarshal public key")
  1430  		}
  1431  
  1432  		if key.D.Cmp(curve.Params().N) >= 0 {
  1433  			return nil, errors.New("ssh: scalar is out of range")
  1434  		}
  1435  
  1436  		x, y := curve.ScalarBaseMult(key.D.Bytes())
  1437  		if x.Cmp(X) != 0 || y.Cmp(Y) != 0 {
  1438  			return nil, errors.New("ssh: public key does not match private key")
  1439  		}
  1440  
  1441  		return &ecdsa.PrivateKey{
  1442  			PublicKey: ecdsa.PublicKey{
  1443  				Curve: curve,
  1444  				X:     X,
  1445  				Y:     Y,
  1446  			},
  1447  			D: key.D,
  1448  		}, nil
  1449  	default:
  1450  		return nil, errors.New("ssh: unhandled key type")
  1451  	}
  1452  }
  1453  
  1454  func checkOpenSSHKeyPadding(pad []byte) error {
  1455  	for i, b := range pad {
  1456  		if int(b) != i+1 {
  1457  			return errors.New("ssh: padding not as expected")
  1458  		}
  1459  	}
  1460  	return nil
  1461  }
  1462  
  1463  // FingerprintLegacyMD5 returns the user presentation of the key's
  1464  // fingerprint as described by RFC 4716 section 4.
  1465  func FingerprintLegacyMD5(pubKey PublicKey) string {
  1466  	md5sum := md5.Sum(pubKey.Marshal())
  1467  	hexarray := make([]string, len(md5sum))
  1468  	for i, c := range md5sum {
  1469  		hexarray[i] = hex.EncodeToString([]byte{c})
  1470  	}
  1471  	return strings.Join(hexarray, ":")
  1472  }
  1473  
  1474  // FingerprintSHA256 returns the user presentation of the key's
  1475  // fingerprint as unpadded base64 encoded sha256 hash.
  1476  // This format was introduced from OpenSSH 6.8.
  1477  // https://www.openssh.com/txt/release-6.8
  1478  // https://tools.ietf.org/html/rfc4648#section-3.2 (unpadded base64 encoding)
  1479  func FingerprintSHA256(pubKey PublicKey) string {
  1480  	sha256sum := sha256.Sum256(pubKey.Marshal())
  1481  	hash := base64.RawStdEncoding.EncodeToString(sha256sum[:])
  1482  	return "SHA256:" + hash
  1483  }