verifier.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package decoder
  2. import (
  3. "bytes"
  4. "crypto/rsa"
  5. "crypto/sha256"
  6. "encoding/base64"
  7. "os"
  8. "path"
  9. "strconv"
  10. "strings"
  11. "github.com/langgenius/dify-plugin-daemon/internal/core/license/public_key"
  12. "github.com/langgenius/dify-plugin-daemon/internal/utils/encryption"
  13. )
  14. // VerifyPlugin is a function that verifies the signature of a plugin
  15. // It takes a plugin decoder and verifies the signature with a bundled public key
  16. func VerifyPlugin(decoder PluginDecoder) error {
  17. var publicKeys []*rsa.PublicKey
  18. // load official public key
  19. officialPublicKey, err := encryption.LoadPublicKey(public_key.PUBLIC_KEY)
  20. if err != nil {
  21. return err
  22. }
  23. publicKeys = append(publicKeys, officialPublicKey)
  24. // verify the plugin
  25. return VerifyPluginWithPublicKeys(decoder, publicKeys)
  26. }
  27. // VerifyPluginWithPublicKeyPaths is a function that verifies the signature of a plugin
  28. // It takes a plugin decoder and a list of public key paths to verify the signature
  29. func VerifyPluginWithPublicKeyPaths(decoder PluginDecoder, publicKeyPaths []string) error {
  30. var publicKeys []*rsa.PublicKey
  31. // load official public key
  32. officialPublicKey, err := encryption.LoadPublicKey(public_key.PUBLIC_KEY)
  33. if err != nil {
  34. return err
  35. }
  36. publicKeys = append(publicKeys, officialPublicKey)
  37. // load keys provided in the arguments
  38. for _, publicKeyPath := range publicKeyPaths {
  39. // open file by trimming the spaces in path
  40. keyBytes, err := os.ReadFile(strings.TrimSpace(publicKeyPath))
  41. if err != nil {
  42. return err
  43. }
  44. publicKey, err := encryption.LoadPublicKey(keyBytes)
  45. if err != nil {
  46. return err
  47. }
  48. publicKeys = append(publicKeys, publicKey)
  49. }
  50. return VerifyPluginWithPublicKeys(decoder, publicKeys)
  51. }
  52. // VerifyPluginWithPublicKeys is a function that verifies the signature of a plugin
  53. // It takes a plugin decoder and a list of public keys to verify the signature
  54. func VerifyPluginWithPublicKeys(decoder PluginDecoder, publicKeys []*rsa.PublicKey) error {
  55. data := new(bytes.Buffer)
  56. // read one by one
  57. err := decoder.Walk(func(filename, dir string) error {
  58. // read file bytes
  59. file, err := decoder.ReadFile(path.Join(dir, filename))
  60. if err != nil {
  61. return err
  62. }
  63. hash := sha256.New()
  64. hash.Write(file)
  65. // write the hash into data
  66. data.Write(hash.Sum(nil))
  67. return nil
  68. })
  69. if err != nil {
  70. return err
  71. }
  72. // get the signature
  73. signature, err := decoder.Signature()
  74. if err != nil {
  75. return err
  76. }
  77. // get the time
  78. createdAt, err := decoder.CreateTime()
  79. if err != nil {
  80. return err
  81. }
  82. // write the time into data
  83. data.Write([]byte(strconv.FormatInt(createdAt, 10)))
  84. sigBytes, err := base64.StdEncoding.DecodeString(signature)
  85. if err != nil {
  86. return err
  87. }
  88. // verify signature
  89. var lastErr error
  90. for _, publicKey := range publicKeys {
  91. lastErr = encryption.VerifySign(publicKey, data.Bytes(), sigBytes)
  92. if lastErr == nil {
  93. return nil
  94. }
  95. }
  96. return lastErr
  97. }