certs.go 13 KB

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