certs.go 12 KB

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