certs.go 16 KB

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