OSDN Git Service

Thanos did someting
[bytom/vapor.git] / vendor / golang.org / x / crypto / ssh / certs.go
diff --git a/vendor/golang.org/x/crypto/ssh/certs.go b/vendor/golang.org/x/crypto/ssh/certs.go
deleted file mode 100644 (file)
index b1f0220..0000000
+++ /dev/null
@@ -1,519 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ssh
-
-import (
-       "bytes"
-       "errors"
-       "fmt"
-       "io"
-       "net"
-       "sort"
-       "time"
-)
-
-// These constants from [PROTOCOL.certkeys] represent the algorithm names
-// for certificate types supported by this package.
-const (
-       CertAlgoRSAv01      = "ssh-rsa-cert-v01@openssh.com"
-       CertAlgoDSAv01      = "ssh-dss-cert-v01@openssh.com"
-       CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com"
-       CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com"
-       CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com"
-       CertAlgoED25519v01  = "ssh-ed25519-cert-v01@openssh.com"
-)
-
-// Certificate types distinguish between host and user
-// certificates. The values can be set in the CertType field of
-// Certificate.
-const (
-       UserCert = 1
-       HostCert = 2
-)
-
-// Signature represents a cryptographic signature.
-type Signature struct {
-       Format string
-       Blob   []byte
-}
-
-// CertTimeInfinity can be used for OpenSSHCertV01.ValidBefore to indicate that
-// a certificate does not expire.
-const CertTimeInfinity = 1<<64 - 1
-
-// An Certificate represents an OpenSSH certificate as defined in
-// [PROTOCOL.certkeys]?rev=1.8.
-type Certificate struct {
-       Nonce           []byte
-       Key             PublicKey
-       Serial          uint64
-       CertType        uint32
-       KeyId           string
-       ValidPrincipals []string
-       ValidAfter      uint64
-       ValidBefore     uint64
-       Permissions
-       Reserved     []byte
-       SignatureKey PublicKey
-       Signature    *Signature
-}
-
-// genericCertData holds the key-independent part of the certificate data.
-// Overall, certificates contain an nonce, public key fields and
-// key-independent fields.
-type genericCertData struct {
-       Serial          uint64
-       CertType        uint32
-       KeyId           string
-       ValidPrincipals []byte
-       ValidAfter      uint64
-       ValidBefore     uint64
-       CriticalOptions []byte
-       Extensions      []byte
-       Reserved        []byte
-       SignatureKey    []byte
-       Signature       []byte
-}
-
-func marshalStringList(namelist []string) []byte {
-       var to []byte
-       for _, name := range namelist {
-               s := struct{ N string }{name}
-               to = append(to, Marshal(&s)...)
-       }
-       return to
-}
-
-type optionsTuple struct {
-       Key   string
-       Value []byte
-}
-
-type optionsTupleValue struct {
-       Value string
-}
-
-// serialize a map of critical options or extensions
-// issue #10569 - per [PROTOCOL.certkeys] and SSH implementation,
-// we need two length prefixes for a non-empty string value
-func marshalTuples(tups map[string]string) []byte {
-       keys := make([]string, 0, len(tups))
-       for key := range tups {
-               keys = append(keys, key)
-       }
-       sort.Strings(keys)
-
-       var ret []byte
-       for _, key := range keys {
-               s := optionsTuple{Key: key}
-               if value := tups[key]; len(value) > 0 {
-                       s.Value = Marshal(&optionsTupleValue{value})
-               }
-               ret = append(ret, Marshal(&s)...)
-       }
-       return ret
-}
-
-// issue #10569 - per [PROTOCOL.certkeys] and SSH implementation,
-// we need two length prefixes for a non-empty option value
-func parseTuples(in []byte) (map[string]string, error) {
-       tups := map[string]string{}
-       var lastKey string
-       var haveLastKey bool
-
-       for len(in) > 0 {
-               var key, val, extra []byte
-               var ok bool
-
-               if key, in, ok = parseString(in); !ok {
-                       return nil, errShortRead
-               }
-               keyStr := string(key)
-               // according to [PROTOCOL.certkeys], the names must be in
-               // lexical order.
-               if haveLastKey && keyStr <= lastKey {
-                       return nil, fmt.Errorf("ssh: certificate options are not in lexical order")
-               }
-               lastKey, haveLastKey = keyStr, true
-               // the next field is a data field, which if non-empty has a string embedded
-               if val, in, ok = parseString(in); !ok {
-                       return nil, errShortRead
-               }
-               if len(val) > 0 {
-                       val, extra, ok = parseString(val)
-                       if !ok {
-                               return nil, errShortRead
-                       }
-                       if len(extra) > 0 {
-                               return nil, fmt.Errorf("ssh: unexpected trailing data after certificate option value")
-                       }
-                       tups[keyStr] = string(val)
-               } else {
-                       tups[keyStr] = ""
-               }
-       }
-       return tups, nil
-}
-
-func parseCert(in []byte, privAlgo string) (*Certificate, error) {
-       nonce, rest, ok := parseString(in)
-       if !ok {
-               return nil, errShortRead
-       }
-
-       key, rest, err := parsePubKey(rest, privAlgo)
-       if err != nil {
-               return nil, err
-       }
-
-       var g genericCertData
-       if err := Unmarshal(rest, &g); err != nil {
-               return nil, err
-       }
-
-       c := &Certificate{
-               Nonce:       nonce,
-               Key:         key,
-               Serial:      g.Serial,
-               CertType:    g.CertType,
-               KeyId:       g.KeyId,
-               ValidAfter:  g.ValidAfter,
-               ValidBefore: g.ValidBefore,
-       }
-
-       for principals := g.ValidPrincipals; len(principals) > 0; {
-               principal, rest, ok := parseString(principals)
-               if !ok {
-                       return nil, errShortRead
-               }
-               c.ValidPrincipals = append(c.ValidPrincipals, string(principal))
-               principals = rest
-       }
-
-       c.CriticalOptions, err = parseTuples(g.CriticalOptions)
-       if err != nil {
-               return nil, err
-       }
-       c.Extensions, err = parseTuples(g.Extensions)
-       if err != nil {
-               return nil, err
-       }
-       c.Reserved = g.Reserved
-       k, err := ParsePublicKey(g.SignatureKey)
-       if err != nil {
-               return nil, err
-       }
-
-       c.SignatureKey = k
-       c.Signature, rest, ok = parseSignatureBody(g.Signature)
-       if !ok || len(rest) > 0 {
-               return nil, errors.New("ssh: signature parse error")
-       }
-
-       return c, nil
-}
-
-type openSSHCertSigner struct {
-       pub    *Certificate
-       signer Signer
-}
-
-// NewCertSigner returns a Signer that signs with the given Certificate, whose
-// private key is held by signer. It returns an error if the public key in cert
-// doesn't match the key used by signer.
-func NewCertSigner(cert *Certificate, signer Signer) (Signer, error) {
-       if bytes.Compare(cert.Key.Marshal(), signer.PublicKey().Marshal()) != 0 {
-               return nil, errors.New("ssh: signer and cert have different public key")
-       }
-
-       return &openSSHCertSigner{cert, signer}, nil
-}
-
-func (s *openSSHCertSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
-       return s.signer.Sign(rand, data)
-}
-
-func (s *openSSHCertSigner) PublicKey() PublicKey {
-       return s.pub
-}
-
-const sourceAddressCriticalOption = "source-address"
-
-// CertChecker does the work of verifying a certificate. Its methods
-// can be plugged into ClientConfig.HostKeyCallback and
-// ServerConfig.PublicKeyCallback. For the CertChecker to work,
-// minimally, the IsAuthority callback should be set.
-type CertChecker struct {
-       // SupportedCriticalOptions lists the CriticalOptions that the
-       // server application layer understands. These are only used
-       // for user certificates.
-       SupportedCriticalOptions []string
-
-       // IsUserAuthority should return true if the key is recognized as an
-       // authority for the given user certificate. This allows for
-       // certificates to be signed by other certificates. This must be set
-       // if this CertChecker will be checking user certificates.
-       IsUserAuthority func(auth PublicKey) bool
-
-       // IsHostAuthority should report whether the key is recognized as
-       // an authority for this host. This allows for certificates to be
-       // signed by other keys, and for those other keys to only be valid
-       // signers for particular hostnames. This must be set if this
-       // CertChecker will be checking host certificates.
-       IsHostAuthority func(auth PublicKey, address string) bool
-
-       // Clock is used for verifying time stamps. If nil, time.Now
-       // is used.
-       Clock func() time.Time
-
-       // UserKeyFallback is called when CertChecker.Authenticate encounters a
-       // public key that is not a certificate. It must implement validation
-       // of user keys or else, if nil, all such keys are rejected.
-       UserKeyFallback func(conn ConnMetadata, key PublicKey) (*Permissions, error)
-
-       // HostKeyFallback is called when CertChecker.CheckHostKey encounters a
-       // public key that is not a certificate. It must implement host key
-       // validation or else, if nil, all such keys are rejected.
-       HostKeyFallback HostKeyCallback
-
-       // IsRevoked is called for each certificate so that revocation checking
-       // can be implemented. It should return true if the given certificate
-       // is revoked and false otherwise. If nil, no certificates are
-       // considered to have been revoked.
-       IsRevoked func(cert *Certificate) bool
-}
-
-// CheckHostKey checks a host key certificate. This method can be
-// plugged into ClientConfig.HostKeyCallback.
-func (c *CertChecker) CheckHostKey(addr string, remote net.Addr, key PublicKey) error {
-       cert, ok := key.(*Certificate)
-       if !ok {
-               if c.HostKeyFallback != nil {
-                       return c.HostKeyFallback(addr, remote, key)
-               }
-               return errors.New("ssh: non-certificate host key")
-       }
-       if cert.CertType != HostCert {
-               return fmt.Errorf("ssh: certificate presented as a host key has type %d", cert.CertType)
-       }
-       if !c.IsHostAuthority(cert.SignatureKey, addr) {
-               return fmt.Errorf("ssh: no authorities for hostname: %v", addr)
-       }
-
-       hostname, _, err := net.SplitHostPort(addr)
-       if err != nil {
-               return err
-       }
-
-       // Pass hostname only as principal for host certificates (consistent with OpenSSH)
-       return c.CheckCert(hostname, cert)
-}
-
-// Authenticate checks a user certificate. Authenticate can be used as
-// a value for ServerConfig.PublicKeyCallback.
-func (c *CertChecker) Authenticate(conn ConnMetadata, pubKey PublicKey) (*Permissions, error) {
-       cert, ok := pubKey.(*Certificate)
-       if !ok {
-               if c.UserKeyFallback != nil {
-                       return c.UserKeyFallback(conn, pubKey)
-               }
-               return nil, errors.New("ssh: normal key pairs not accepted")
-       }
-
-       if cert.CertType != UserCert {
-               return nil, fmt.Errorf("ssh: cert has type %d", cert.CertType)
-       }
-       if !c.IsUserAuthority(cert.SignatureKey) {
-               return nil, fmt.Errorf("ssh: certificate signed by unrecognized authority")
-       }
-
-       if err := c.CheckCert(conn.User(), cert); err != nil {
-               return nil, err
-       }
-
-       return &cert.Permissions, nil
-}
-
-// CheckCert checks CriticalOptions, ValidPrincipals, revocation, timestamp and
-// the signature of the certificate.
-func (c *CertChecker) CheckCert(principal string, cert *Certificate) error {
-       if c.IsRevoked != nil && c.IsRevoked(cert) {
-               return fmt.Errorf("ssh: certicate serial %d revoked", cert.Serial)
-       }
-
-       for opt, _ := range cert.CriticalOptions {
-               // sourceAddressCriticalOption will be enforced by
-               // serverAuthenticate
-               if opt == sourceAddressCriticalOption {
-                       continue
-               }
-
-               found := false
-               for _, supp := range c.SupportedCriticalOptions {
-                       if supp == opt {
-                               found = true
-                               break
-                       }
-               }
-               if !found {
-                       return fmt.Errorf("ssh: unsupported critical option %q in certificate", opt)
-               }
-       }
-
-       if len(cert.ValidPrincipals) > 0 {
-               // By default, certs are valid for all users/hosts.
-               found := false
-               for _, p := range cert.ValidPrincipals {
-                       if p == principal {
-                               found = true
-                               break
-                       }
-               }
-               if !found {
-                       return fmt.Errorf("ssh: principal %q not in the set of valid principals for given certificate: %q", principal, cert.ValidPrincipals)
-               }
-       }
-
-       clock := c.Clock
-       if clock == nil {
-               clock = time.Now
-       }
-
-       unixNow := clock().Unix()
-       if after := int64(cert.ValidAfter); after < 0 || unixNow < int64(cert.ValidAfter) {
-               return fmt.Errorf("ssh: cert is not yet valid")
-       }
-       if before := int64(cert.ValidBefore); cert.ValidBefore != uint64(CertTimeInfinity) && (unixNow >= before || before < 0) {
-               return fmt.Errorf("ssh: cert has expired")
-       }
-       if err := cert.SignatureKey.Verify(cert.bytesForSigning(), cert.Signature); err != nil {
-               return fmt.Errorf("ssh: certificate signature does not verify")
-       }
-
-       return nil
-}
-
-// SignCert sets c.SignatureKey to the authority's public key and stores a
-// Signature, by authority, in the certificate.
-func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
-       c.Nonce = make([]byte, 32)
-       if _, err := io.ReadFull(rand, c.Nonce); err != nil {
-               return err
-       }
-       c.SignatureKey = authority.PublicKey()
-
-       sig, err := authority.Sign(rand, c.bytesForSigning())
-       if err != nil {
-               return err
-       }
-       c.Signature = sig
-       return nil
-}
-
-var certAlgoNames = map[string]string{
-       KeyAlgoRSA:      CertAlgoRSAv01,
-       KeyAlgoDSA:      CertAlgoDSAv01,
-       KeyAlgoECDSA256: CertAlgoECDSA256v01,
-       KeyAlgoECDSA384: CertAlgoECDSA384v01,
-       KeyAlgoECDSA521: CertAlgoECDSA521v01,
-       KeyAlgoED25519:  CertAlgoED25519v01,
-}
-
-// certToPrivAlgo returns the underlying algorithm for a certificate algorithm.
-// Panics if a non-certificate algorithm is passed.
-func certToPrivAlgo(algo string) string {
-       for privAlgo, pubAlgo := range certAlgoNames {
-               if pubAlgo == algo {
-                       return privAlgo
-               }
-       }
-       panic("unknown cert algorithm")
-}
-
-func (cert *Certificate) bytesForSigning() []byte {
-       c2 := *cert
-       c2.Signature = nil
-       out := c2.Marshal()
-       // Drop trailing signature length.
-       return out[:len(out)-4]
-}
-
-// Marshal serializes c into OpenSSH's wire format. It is part of the
-// PublicKey interface.
-func (c *Certificate) Marshal() []byte {
-       generic := genericCertData{
-               Serial:          c.Serial,
-               CertType:        c.CertType,
-               KeyId:           c.KeyId,
-               ValidPrincipals: marshalStringList(c.ValidPrincipals),
-               ValidAfter:      uint64(c.ValidAfter),
-               ValidBefore:     uint64(c.ValidBefore),
-               CriticalOptions: marshalTuples(c.CriticalOptions),
-               Extensions:      marshalTuples(c.Extensions),
-               Reserved:        c.Reserved,
-               SignatureKey:    c.SignatureKey.Marshal(),
-       }
-       if c.Signature != nil {
-               generic.Signature = Marshal(c.Signature)
-       }
-       genericBytes := Marshal(&generic)
-       keyBytes := c.Key.Marshal()
-       _, keyBytes, _ = parseString(keyBytes)
-       prefix := Marshal(&struct {
-               Name  string
-               Nonce []byte
-               Key   []byte `ssh:"rest"`
-       }{c.Type(), c.Nonce, keyBytes})
-
-       result := make([]byte, 0, len(prefix)+len(genericBytes))
-       result = append(result, prefix...)
-       result = append(result, genericBytes...)
-       return result
-}
-
-// Type returns the key name. It is part of the PublicKey interface.
-func (c *Certificate) Type() string {
-       algo, ok := certAlgoNames[c.Key.Type()]
-       if !ok {
-               panic("unknown cert key type " + c.Key.Type())
-       }
-       return algo
-}
-
-// Verify verifies a signature against the certificate's public
-// key. It is part of the PublicKey interface.
-func (c *Certificate) Verify(data []byte, sig *Signature) error {
-       return c.Key.Verify(data, sig)
-}
-
-func parseSignatureBody(in []byte) (out *Signature, rest []byte, ok bool) {
-       format, in, ok := parseString(in)
-       if !ok {
-               return
-       }
-
-       out = &Signature{
-               Format: string(format),
-       }
-
-       if out.Blob, in, ok = parseString(in); !ok {
-               return
-       }
-
-       return out, in, ok
-}
-
-func parseSignature(in []byte) (out *Signature, rest []byte, ok bool) {
-       sigBytes, rest, ok := parseString(in)
-       if !ok {
-               return
-       }
-
-       out, trailing, ok := parseSignatureBody(sigBytes)
-       if !ok || len(trailing) > 0 {
-               return nil, nil, false
-       }
-       return
-}