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 2.9KB

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