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.

certs.go 15KB

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