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.

62 lines
1.4 KiB

Sign merges, CRUD, Wiki and Repository initialisation with gpg key (#7631) This PR fixes #7598 by providing a configurable way of signing commits across the Gitea instance. Per repository configurability and import/generation of trusted secure keys is not provided by this PR - from a security PoV that's probably impossible to do properly. Similarly web-signing, that is asking the user to sign something, is not implemented - this could be done at a later stage however. ## Features - [x] If commit.gpgsign is set in .gitconfig sign commits and files created through repofiles. (merges should already have been signed.) - [x] Verify commits signed with the default gpg as valid - [x] Signer, Committer and Author can all be different - [x] Allow signer to be arbitrarily different - We still require the key to have an activated email on Gitea. A more complete implementation would be to use a keyserver and mark external-or-unactivated with an "unknown" trust level icon. - [x] Add a signing-key.gpg endpoint to get the default gpg pub key if available - Rather than add a fake web-flow user I've added this as an endpoint on /api/v1/signing-key.gpg - [x] Try to match the default key with a user on gitea - this is done at verification time - [x] Make things configurable? - app.ini configuration done - [x] when checking commits are signed need to check if they're actually verifiable too - [x] Add documentation I have decided that adjusting the docker to create a default gpg key is not the correct thing to do and therefore have not implemented this.
5 years ago
  1. package misc
  2. import (
  3. "fmt"
  4. "net/http"
  5. "code.gitea.io/gitea/models"
  6. "code.gitea.io/gitea/modules/context"
  7. "code.gitea.io/gitea/modules/log"
  8. )
  9. // SigningKey returns the public key of the default signing key if it exists
  10. func SigningKey(ctx *context.Context) {
  11. // swagger:operation GET /signing-key.gpg miscellaneous getSigningKey
  12. // ---
  13. // summary: Get default signing-key.gpg
  14. // produces:
  15. // - text/plain
  16. // responses:
  17. // "200":
  18. // description: "GPG armored public key"
  19. // schema:
  20. // type: string
  21. // swagger:operation GET /repos/{owner}/{repo}/signing-key.gpg repository repoSigningKey
  22. // ---
  23. // summary: Get signing-key.gpg for given repository
  24. // produces:
  25. // - text/plain
  26. // parameters:
  27. // - name: owner
  28. // in: path
  29. // description: owner of the repo
  30. // type: string
  31. // required: true
  32. // - name: repo
  33. // in: path
  34. // description: name of the repo
  35. // type: string
  36. // required: true
  37. // responses:
  38. // "200":
  39. // description: "GPG armored public key"
  40. // schema:
  41. // type: string
  42. path := ""
  43. if ctx.Repo != nil && ctx.Repo.Repository != nil {
  44. path = ctx.Repo.Repository.RepoPath()
  45. }
  46. content, err := models.PublicSigningKey(path)
  47. if err != nil {
  48. ctx.ServerError("gpg export", err)
  49. return
  50. }
  51. _, err = ctx.Write([]byte(content))
  52. if err != nil {
  53. log.Error("Error writing key content %v", err)
  54. ctx.Error(http.StatusInternalServerError, fmt.Sprintf("%v", err))
  55. }
  56. }