gitea源码

gpg_key_add.go 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package asymkey
  4. import (
  5. "context"
  6. "strings"
  7. "code.gitea.io/gitea/models/db"
  8. "code.gitea.io/gitea/modules/log"
  9. "github.com/ProtonMail/go-crypto/openpgp"
  10. )
  11. // __________________ ________ ____ __.
  12. // / _____/\______ \/ _____/ | |/ _|____ ___.__.
  13. // / \ ___ | ___/ \ ___ | <_/ __ < | |
  14. // \ \_\ \| | \ \_\ \ | | \ ___/\___ |
  15. // \______ /|____| \______ / |____|__ \___ > ____|
  16. // \/ \/ \/ \/\/
  17. // _____ .___ .___
  18. // / _ \ __| _/__| _/
  19. // / /_\ \ / __ |/ __ |
  20. // / | \/ /_/ / /_/ |
  21. // \____|__ /\____ \____ |
  22. // \/ \/ \/
  23. // This file contains functions relating to adding GPG Keys
  24. // addGPGKey add key, import and subkeys to database
  25. func addGPGKey(ctx context.Context, key *GPGKey, content string) (err error) {
  26. // Add GPGKeyImport
  27. if err = db.Insert(ctx, &GPGKeyImport{
  28. KeyID: key.KeyID,
  29. Content: content,
  30. }); err != nil {
  31. return err
  32. }
  33. // Save GPG primary key.
  34. if err = db.Insert(ctx, key); err != nil {
  35. return err
  36. }
  37. // Save GPG subs key.
  38. for _, subkey := range key.SubsKey {
  39. if err := addGPGSubKey(ctx, subkey); err != nil {
  40. return err
  41. }
  42. }
  43. return nil
  44. }
  45. // addGPGSubKey add subkeys to database
  46. func addGPGSubKey(ctx context.Context, key *GPGKey) (err error) {
  47. // Save GPG primary key.
  48. if err = db.Insert(ctx, key); err != nil {
  49. return err
  50. }
  51. // Save GPG subs key.
  52. for _, subkey := range key.SubsKey {
  53. if err := addGPGSubKey(ctx, subkey); err != nil {
  54. return err
  55. }
  56. }
  57. return nil
  58. }
  59. // AddGPGKey adds new public key to database.
  60. func AddGPGKey(ctx context.Context, ownerID int64, content, token, signature string) ([]*GPGKey, error) {
  61. ekeys, err := CheckArmoredGPGKeyString(content)
  62. if err != nil {
  63. return nil, err
  64. }
  65. return db.WithTx2(ctx, func(ctx context.Context) ([]*GPGKey, error) {
  66. keys := make([]*GPGKey, 0, len(ekeys))
  67. verified := false
  68. // Handle provided signature
  69. if signature != "" {
  70. signer, err := openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token), strings.NewReader(signature), nil)
  71. if err != nil {
  72. signer, err = openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token+"\n"), strings.NewReader(signature), nil)
  73. }
  74. if err != nil {
  75. signer, err = openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token+"\r\n"), strings.NewReader(signature), nil)
  76. }
  77. if err != nil {
  78. log.Debug("AddGPGKey CheckArmoredDetachedSignature failed: %v", err)
  79. return nil, ErrGPGInvalidTokenSignature{
  80. ID: ekeys[0].PrimaryKey.KeyIdString(),
  81. Wrapped: err,
  82. }
  83. }
  84. ekeys = []*openpgp.Entity{signer}
  85. verified = true
  86. }
  87. if len(ekeys) > 1 {
  88. id2key := map[string]*openpgp.Entity{}
  89. newEKeys := make([]*openpgp.Entity, 0, len(ekeys))
  90. for _, ekey := range ekeys {
  91. id := ekey.PrimaryKey.KeyIdString()
  92. if original, has := id2key[id]; has {
  93. // Coalesce this with the other one
  94. for _, subkey := range ekey.Subkeys {
  95. if subkey.PublicKey == nil {
  96. continue
  97. }
  98. found := false
  99. for _, originalSubkey := range original.Subkeys {
  100. if originalSubkey.PublicKey == nil {
  101. continue
  102. }
  103. if originalSubkey.PublicKey.KeyId == subkey.PublicKey.KeyId {
  104. found = true
  105. break
  106. }
  107. }
  108. if !found {
  109. original.Subkeys = append(original.Subkeys, subkey)
  110. }
  111. }
  112. for name, identity := range ekey.Identities {
  113. if _, has := original.Identities[name]; has {
  114. continue
  115. }
  116. original.Identities[name] = identity
  117. }
  118. continue
  119. }
  120. id2key[id] = ekey
  121. newEKeys = append(newEKeys, ekey)
  122. }
  123. ekeys = newEKeys
  124. }
  125. for _, ekey := range ekeys {
  126. // Key ID cannot be duplicated.
  127. has, err := db.GetEngine(ctx).Where("key_id=?", ekey.PrimaryKey.KeyIdString()).
  128. Get(new(GPGKey))
  129. if err != nil {
  130. return nil, err
  131. } else if has {
  132. return nil, ErrGPGKeyIDAlreadyUsed{ekey.PrimaryKey.KeyIdString()}
  133. }
  134. key, err := parseGPGKey(ctx, ownerID, ekey, verified)
  135. if err != nil {
  136. return nil, err
  137. }
  138. if err = addGPGKey(ctx, key, content); err != nil {
  139. return nil, err
  140. }
  141. keys = append(keys, key)
  142. }
  143. return keys, nil
  144. })
  145. }