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.

gpg_key_verify.go 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package asymkey
  5. import (
  6. "strconv"
  7. "time"
  8. "code.gitea.io/gitea/models/db"
  9. user_model "code.gitea.io/gitea/models/user"
  10. "code.gitea.io/gitea/modules/base"
  11. "code.gitea.io/gitea/modules/log"
  12. )
  13. // __________________ ________ ____ __.
  14. // / _____/\______ \/ _____/ | |/ _|____ ___.__.
  15. // / \ ___ | ___/ \ ___ | <_/ __ < | |
  16. // \ \_\ \| | \ \_\ \ | | \ ___/\___ |
  17. // \______ /|____| \______ / |____|__ \___ > ____|
  18. // \/ \/ \/ \/\/
  19. // ____ ____ .__ _____
  20. // \ \ / /___________|__|/ ____\__.__.
  21. // \ Y // __ \_ __ \ \ __< | |
  22. // \ /\ ___/| | \/ || | \___ |
  23. // \___/ \___ >__| |__||__| / ____|
  24. // \/ \/
  25. // This file provides functions relating verifying gpg keys
  26. // VerifyGPGKey marks a GPG key as verified
  27. func VerifyGPGKey(ownerID int64, keyID, token, signature string) (string, error) {
  28. ctx, committer, err := db.TxContext()
  29. if err != nil {
  30. return "", err
  31. }
  32. defer committer.Close()
  33. key := new(GPGKey)
  34. has, err := db.GetEngine(ctx).Where("owner_id = ? AND key_id = ?", ownerID, keyID).Get(key)
  35. if err != nil {
  36. return "", err
  37. } else if !has {
  38. return "", ErrGPGKeyNotExist{}
  39. }
  40. sig, err := extractSignature(signature)
  41. if err != nil {
  42. return "", ErrGPGInvalidTokenSignature{
  43. ID: key.KeyID,
  44. Wrapped: err,
  45. }
  46. }
  47. signer, err := hashAndVerifyWithSubKeys(sig, token, key)
  48. if err != nil {
  49. return "", ErrGPGInvalidTokenSignature{
  50. ID: key.KeyID,
  51. Wrapped: err,
  52. }
  53. }
  54. if signer == nil {
  55. signer, err = hashAndVerifyWithSubKeys(sig, token+"\n", key)
  56. if err != nil {
  57. return "", ErrGPGInvalidTokenSignature{
  58. ID: key.KeyID,
  59. Wrapped: err,
  60. }
  61. }
  62. }
  63. if signer == nil {
  64. signer, err = hashAndVerifyWithSubKeys(sig, token+"\n\n", key)
  65. if err != nil {
  66. return "", ErrGPGInvalidTokenSignature{
  67. ID: key.KeyID,
  68. Wrapped: err,
  69. }
  70. }
  71. }
  72. if signer == nil {
  73. log.Error("Unable to validate token signature. Error: %v", err)
  74. return "", ErrGPGInvalidTokenSignature{
  75. ID: key.KeyID,
  76. }
  77. }
  78. if signer.PrimaryKeyID != key.KeyID && signer.KeyID != key.KeyID {
  79. return "", ErrGPGKeyNotExist{}
  80. }
  81. key.Verified = true
  82. if _, err := db.GetEngine(ctx).ID(key.ID).SetExpr("verified", true).Update(new(GPGKey)); err != nil {
  83. return "", err
  84. }
  85. if err := committer.Commit(); err != nil {
  86. return "", err
  87. }
  88. return key.KeyID, nil
  89. }
  90. // VerificationToken returns token for the user that will be valid in minutes (time)
  91. func VerificationToken(user *user_model.User, minutes int) string {
  92. return base.EncodeSha256(
  93. time.Now().Truncate(1*time.Minute).Add(time.Duration(minutes)*time.Minute).Format(time.RFC1123Z) + ":" +
  94. user.CreatedUnix.FormatLong() + ":" +
  95. user.Name + ":" +
  96. user.Email + ":" +
  97. strconv.FormatInt(user.ID, 10))
  98. }