certs.go 17 KB

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