You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

522 lines
14 KiB

  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. package ssh
  5. import (
  6. "bytes"
  7. "errors"
  8. "fmt"
  9. "io"
  10. "net"
  11. "sort"
  12. "time"
  13. )
  14. // These constants from [PROTOCOL.certkeys] represent the algorithm names
  15. // for certificate types supported by this package.
  16. const (
  17. CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com"
  18. CertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com"
  19. CertAlgoECDSA256v01 = "ecdsa-sha2-nistp256-cert-v01@openssh.com"
  20. CertAlgoECDSA384v01 = "ecdsa-sha2-nistp384-cert-v01@openssh.com"
  21. CertAlgoECDSA521v01 = "ecdsa-sha2-nistp521-cert-v01@openssh.com"
  22. CertAlgoED25519v01 = "ssh-ed25519-cert-v01@openssh.com"
  23. )
  24. // Certificate types distinguish between host and user
  25. // certificates. The values can be set in the CertType field of
  26. // Certificate.
  27. const (
  28. UserCert = 1
  29. HostCert = 2
  30. )
  31. // Signature represents a cryptographic signature.
  32. type Signature struct {
  33. Format string
  34. Blob []byte
  35. }
  36. // CertTimeInfinity can be used for OpenSSHCertV01.ValidBefore to indicate that
  37. // a certificate does not expire.
  38. const CertTimeInfinity = 1<<64 - 1
  39. // An Certificate represents an OpenSSH certificate as defined in
  40. // [PROTOCOL.certkeys]?rev=1.8. The Certificate type implements the
  41. // PublicKey interface, so it can be unmarshaled using
  42. // ParsePublicKey.
  43. type Certificate struct {
  44. Nonce []byte
  45. Key PublicKey
  46. Serial uint64
  47. CertType uint32
  48. KeyId string
  49. ValidPrincipals []string
  50. ValidAfter uint64
  51. ValidBefore uint64
  52. Permissions
  53. Reserved []byte
  54. SignatureKey PublicKey
  55. Signature *Signature
  56. }
  57. // genericCertData holds the key-independent part of the certificate data.
  58. // Overall, certificates contain an nonce, public key fields and
  59. // key-independent fields.
  60. type genericCertData struct {
  61. Serial uint64
  62. CertType uint32
  63. KeyId string
  64. ValidPrincipals []byte
  65. ValidAfter uint64
  66. ValidBefore uint64
  67. CriticalOptions []byte
  68. Extensions []byte
  69. Reserved []byte
  70. SignatureKey []byte
  71. Signature []byte
  72. }
  73. func marshalStringList(namelist []string) []byte {
  74. var to []byte
  75. for _, name := range namelist {
  76. s := struct{ N string }{name}
  77. to = append(to, Marshal(&s)...)
  78. }
  79. return to
  80. }
  81. type optionsTuple struct {
  82. Key string
  83. Value []byte
  84. }
  85. type optionsTupleValue struct {
  86. Value string
  87. }
  88. // serialize a map of critical options or extensions
  89. // issue #10569 - per [PROTOCOL.certkeys] and SSH implementation,
  90. // we need two length prefixes for a non-empty string value
  91. func marshalTuples(tups map[string]string) []byte {
  92. keys := make([]string, 0, len(tups))
  93. for key := range tups {
  94. keys = append(keys, key)
  95. }
  96. sort.Strings(keys)
  97. var ret []byte
  98. for _, key := range keys {
  99. s := optionsTuple{Key: key}
  100. if value := tups[key]; len(value) > 0 {
  101. s.Value = Marshal(&optionsTupleValue{value})
  102. }
  103. ret = append(ret, Marshal(&s)...)
  104. }
  105. return ret
  106. }
  107. // issue #10569 - per [PROTOCOL.certkeys] and SSH implementation,
  108. // we need two length prefixes for a non-empty option value
  109. func parseTuples(in []byte) (map[string]string, error) {
  110. tups := map[string]string{}
  111. var lastKey string
  112. var haveLastKey bool
  113. for len(in) > 0 {
  114. var key, val, extra []byte
  115. var ok bool
  116. if key, in, ok = parseString(in); !ok {
  117. return nil, errShortRead
  118. }
  119. keyStr := string(key)
  120. // according to [PROTOCOL.certkeys], the names must be in
  121. // lexical order.
  122. if haveLastKey && keyStr <= lastKey {
  123. return nil, fmt.Errorf("ssh: certificate options are not in lexical order")
  124. }
  125. lastKey, haveLastKey = keyStr, true
  126. // the next field is a data field, which if non-empty has a string embedded
  127. if val, in, ok = parseString(in); !ok {
  128. return nil, errShortRead
  129. }
  130. if len(val) > 0 {
  131. val, extra, ok = parseString(val)
  132. if !ok {
  133. return nil, errShortRead
  134. }
  135. if len(extra) > 0 {
  136. return nil, fmt.Errorf("ssh: unexpected trailing data after certificate option value")
  137. }
  138. tups[keyStr] = string(val)
  139. } else {
  140. tups[keyStr] = ""
  141. }
  142. }
  143. return tups, nil
  144. }
  145. func parseCert(in []byte, privAlgo string) (*Certificate, error) {
  146. nonce, rest, ok := parseString(in)
  147. if !ok {
  148. return nil, errShortRead
  149. }
  150. key, rest, err := parsePubKey(rest, privAlgo)
  151. if err != nil {
  152. return nil, err
  153. }
  154. var g genericCertData
  155. if err := Unmarshal(rest, &g); err != nil {
  156. return nil, err
  157. }
  158. c := &Certificate{
  159. Nonce: nonce,
  160. Key: key,
  161. Serial: g.Serial,
  162. CertType: g.CertType,
  163. KeyId: g.KeyId,
  164. ValidAfter: g.ValidAfter,
  165. ValidBefore: g.ValidBefore,
  166. }
  167. for principals := g.ValidPrincipals; len(principals) > 0; {
  168. principal, rest, ok := parseString(principals)
  169. if !ok {
  170. return nil, errShortRead
  171. }
  172. c.ValidPrincipals = append(c.ValidPrincipals, string(principal))
  173. principals = rest
  174. }
  175. c.CriticalOptions, err = parseTuples(g.CriticalOptions)
  176. if err != nil {
  177. return nil, err
  178. }
  179. c.Extensions, err = parseTuples(g.Extensions)
  180. if err != nil {
  181. return nil, err
  182. }
  183. c.Reserved = g.Reserved
  184. k, err := ParsePublicKey(g.SignatureKey)
  185. if err != nil {
  186. return nil, err
  187. }
  188. c.SignatureKey = k
  189. c.Signature, rest, ok = parseSignatureBody(g.Signature)
  190. if !ok || len(rest) > 0 {
  191. return nil, errors.New("ssh: signature parse error")
  192. }
  193. return c, nil
  194. }
  195. type openSSHCertSigner struct {
  196. pub *Certificate
  197. signer Signer
  198. }
  199. // NewCertSigner returns a Signer that signs with the given Certificate, whose
  200. // private key is held by signer. It returns an error if the public key in cert
  201. // doesn't match the key used by signer.
  202. func NewCertSigner(cert *Certificate, signer Signer) (Signer, error) {
  203. if bytes.Compare(cert.Key.Marshal(), signer.PublicKey().Marshal()) != 0 {
  204. return nil, errors.New("ssh: signer and cert have different public key")
  205. }
  206. return &openSSHCertSigner{cert, signer}, nil
  207. }
  208. func (s *openSSHCertSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
  209. return s.signer.Sign(rand, data)
  210. }
  211. func (s *openSSHCertSigner) PublicKey() PublicKey {
  212. return s.pub
  213. }
  214. const sourceAddressCriticalOption = "source-address"
  215. // CertChecker does the work of verifying a certificate. Its methods
  216. // can be plugged into ClientConfig.HostKeyCallback and
  217. // ServerConfig.PublicKeyCallback. For the CertChecker to work,
  218. // minimally, the IsAuthority callback should be set.
  219. type CertChecker struct {
  220. // SupportedCriticalOptions lists the CriticalOptions that the
  221. // server application layer understands. These are only used
  222. // for user certificates.
  223. SupportedCriticalOptions []string
  224. // IsUserAuthority should return true if the key is recognized as an
  225. // authority for the given user certificate. This allows for
  226. // certificates to be signed by other certificates. This must be set
  227. // if this CertChecker will be checking user certificates.
  228. IsUserAuthority func(auth PublicKey) bool
  229. // IsHostAuthority should report whether the key is recognized as
  230. // an authority for this host. This allows for certificates to be
  231. // signed by other keys, and for those other keys to only be valid
  232. // signers for particular hostnames. This must be set if this
  233. // CertChecker will be checking host certificates.
  234. IsHostAuthority func(auth PublicKey, address string) bool
  235. // Clock is used for verifying time stamps. If nil, time.Now
  236. // is used.
  237. Clock func() time.Time
  238. // UserKeyFallback is called when CertChecker.Authenticate encounters a
  239. // public key that is not a certificate. It must implement validation
  240. // of user keys or else, if nil, all such keys are rejected.
  241. UserKeyFallback func(conn ConnMetadata, key PublicKey) (*Permissions, error)
  242. // HostKeyFallback is called when CertChecker.CheckHostKey encounters a
  243. // public key that is not a certificate. It must implement host key
  244. // validation or else, if nil, all such keys are rejected.
  245. HostKeyFallback HostKeyCallback
  246. // IsRevoked is called for each certificate so that revocation checking
  247. // can be implemented. It should return true if the given certificate
  248. // is revoked and false otherwise. If nil, no certificates are
  249. // considered to have been revoked.
  250. IsRevoked func(cert *Certificate) bool
  251. }
  252. // CheckHostKey checks a host key certificate. This method can be
  253. // plugged into ClientConfig.HostKeyCallback.
  254. func (c *CertChecker) CheckHostKey(addr string, remote net.Addr, key PublicKey) error {
  255. cert, ok := key.(*Certificate)
  256. if !ok {
  257. if c.HostKeyFallback != nil {
  258. return c.HostKeyFallback(addr, remote, key)
  259. }
  260. return errors.New("ssh: non-certificate host key")
  261. }
  262. if cert.CertType != HostCert {
  263. return fmt.Errorf("ssh: certificate presented as a host key has type %d", cert.CertType)
  264. }
  265. if !c.IsHostAuthority(cert.SignatureKey, addr) {
  266. return fmt.Errorf("ssh: no authorities for hostname: %v", addr)
  267. }
  268. hostname, _, err := net.SplitHostPort(addr)
  269. if err != nil {
  270. return err
  271. }
  272. // Pass hostname only as principal for host certificates (consistent with OpenSSH)
  273. return c.CheckCert(hostname, cert)
  274. }
  275. // Authenticate checks a user certificate. Authenticate can be used as
  276. // a value for ServerConfig.PublicKeyCallback.
  277. func (c *CertChecker) Authenticate(conn ConnMetadata, pubKey PublicKey) (*Permissions, error) {
  278. cert, ok := pubKey.(*Certificate)
  279. if !ok {
  280. if c.UserKeyFallback != nil {
  281. return c.UserKeyFallback(conn, pubKey)
  282. }
  283. return nil, errors.New("ssh: normal key pairs not accepted")
  284. }
  285. if cert.CertType != UserCert {
  286. return nil, fmt.Errorf("ssh: cert has type %d", cert.CertType)
  287. }
  288. if !c.IsUserAuthority(cert.SignatureKey) {
  289. return nil, fmt.Errorf("ssh: certificate signed by unrecognized authority")
  290. }
  291. if err := c.CheckCert(conn.User(), cert); err != nil {
  292. return nil, err
  293. }
  294. return &cert.Permissions, nil
  295. }
  296. // CheckCert checks CriticalOptions, ValidPrincipals, revocation, timestamp and
  297. // the signature of the certificate.
  298. func (c *CertChecker) CheckCert(principal string, cert *Certificate) error {
  299. if c.IsRevoked != nil && c.IsRevoked(cert) {
  300. return fmt.Errorf("ssh: certificate serial %d revoked", cert.Serial)
  301. }
  302. for opt := range cert.CriticalOptions {
  303. // sourceAddressCriticalOption will be enforced by
  304. // serverAuthenticate
  305. if opt == sourceAddressCriticalOption {
  306. continue
  307. }
  308. found := false
  309. for _, supp := range c.SupportedCriticalOptions {
  310. if supp == opt {
  311. found = true
  312. break
  313. }
  314. }
  315. if !found {
  316. return fmt.Errorf("ssh: unsupported critical option %q in certificate", opt)
  317. }
  318. }
  319. if len(cert.ValidPrincipals) > 0 {
  320. // By default, certs are valid for all users/hosts.
  321. found := false
  322. for _, p := range cert.ValidPrincipals {
  323. if p == principal {
  324. found = true
  325. break
  326. }
  327. }
  328. if !found {
  329. return fmt.Errorf("ssh: principal %q not in the set of valid principals for given certificate: %q", principal, cert.ValidPrincipals)
  330. }
  331. }
  332. clock := c.Clock
  333. if clock == nil {
  334. clock = time.Now
  335. }
  336. unixNow := clock().Unix()
  337. if after := int64(cert.ValidAfter); after < 0 || unixNow < int64(cert.ValidAfter) {
  338. return fmt.Errorf("ssh: cert is not yet valid")
  339. }
  340. if before := int64(cert.ValidBefore); cert.ValidBefore != uint64(CertTimeInfinity) && (unixNow >= before || before < 0) {
  341. return fmt.Errorf("ssh: cert has expired")
  342. }
  343. if err := cert.SignatureKey.Verify(cert.bytesForSigning(), cert.Signature); err != nil {
  344. return fmt.Errorf("ssh: certificate signature does not verify")
  345. }
  346. return nil
  347. }
  348. // SignCert sets c.SignatureKey to the authority's public key and stores a
  349. // Signature, by authority, in the certificate.
  350. func (c *Certificate) SignCert(rand io.Reader, authority Signer) error {
  351. c.Nonce = make([]byte, 32)
  352. if _, err := io.ReadFull(rand, c.Nonce); err != nil {
  353. return err
  354. }
  355. c.SignatureKey = authority.PublicKey()
  356. sig, err := authority.Sign(rand, c.bytesForSigning())
  357. if err != nil {
  358. return err
  359. }
  360. c.Signature = sig
  361. return nil
  362. }
  363. var certAlgoNames = map[string]string{
  364. KeyAlgoRSA: CertAlgoRSAv01,
  365. KeyAlgoDSA: CertAlgoDSAv01,
  366. KeyAlgoECDSA256: CertAlgoECDSA256v01,
  367. KeyAlgoECDSA384: CertAlgoECDSA384v01,
  368. KeyAlgoECDSA521: CertAlgoECDSA521v01,
  369. KeyAlgoED25519: CertAlgoED25519v01,
  370. }
  371. // certToPrivAlgo returns the underlying algorithm for a certificate algorithm.
  372. // Panics if a non-certificate algorithm is passed.
  373. func certToPrivAlgo(algo string) string {
  374. for privAlgo, pubAlgo := range certAlgoNames {
  375. if pubAlgo == algo {
  376. return privAlgo
  377. }
  378. }
  379. panic("unknown cert algorithm")
  380. }
  381. func (cert *Certificate) bytesForSigning() []byte {
  382. c2 := *cert
  383. c2.Signature = nil
  384. out := c2.Marshal()
  385. // Drop trailing signature length.
  386. return out[:len(out)-4]
  387. }
  388. // Marshal serializes c into OpenSSH's wire format. It is part of the
  389. // PublicKey interface.
  390. func (c *Certificate) Marshal() []byte {
  391. generic := genericCertData{
  392. Serial: c.Serial,
  393. CertType: c.CertType,
  394. KeyId: c.KeyId,
  395. ValidPrincipals: marshalStringList(c.ValidPrincipals),
  396. ValidAfter: uint64(c.ValidAfter),
  397. ValidBefore: uint64(c.ValidBefore),
  398. CriticalOptions: marshalTuples(c.CriticalOptions),
  399. Extensions: marshalTuples(c.Extensions),
  400. Reserved: c.Reserved,
  401. SignatureKey: c.SignatureKey.Marshal(),
  402. }
  403. if c.Signature != nil {
  404. generic.Signature = Marshal(c.Signature)
  405. }
  406. genericBytes := Marshal(&generic)
  407. keyBytes := c.Key.Marshal()
  408. _, keyBytes, _ = parseString(keyBytes)
  409. prefix := Marshal(&struct {
  410. Name string
  411. Nonce []byte
  412. Key []byte `ssh:"rest"`
  413. }{c.Type(), c.Nonce, keyBytes})
  414. result := make([]byte, 0, len(prefix)+len(genericBytes))
  415. result = append(result, prefix...)
  416. result = append(result, genericBytes...)
  417. return result
  418. }
  419. // Type returns the key name. It is part of the PublicKey interface.
  420. func (c *Certificate) Type() string {
  421. algo, ok := certAlgoNames[c.Key.Type()]
  422. if !ok {
  423. panic("unknown cert key type " + c.Key.Type())
  424. }
  425. return algo
  426. }
  427. // Verify verifies a signature against the certificate's public
  428. // key. It is part of the PublicKey interface.
  429. func (c *Certificate) Verify(data []byte, sig *Signature) error {
  430. return c.Key.Verify(data, sig)
  431. }
  432. func parseSignatureBody(in []byte) (out *Signature, rest []byte, ok bool) {
  433. format, in, ok := parseString(in)
  434. if !ok {
  435. return
  436. }
  437. out = &Signature{
  438. Format: string(format),
  439. }
  440. if out.Blob, in, ok = parseString(in); !ok {
  441. return
  442. }
  443. return out, in, ok
  444. }
  445. func parseSignature(in []byte) (out *Signature, rest []byte, ok bool) {
  446. sigBytes, rest, ok := parseString(in)
  447. if !ok {
  448. return
  449. }
  450. out, trailing, ok := parseSignatureBody(sigBytes)
  451. if !ok || len(trailing) > 0 {
  452. return nil, nil, false
  453. }
  454. return
  455. }