certs.go 18 KB

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