verifier.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package verifier
  2. import (
  3. "archive/zip"
  4. "bytes"
  5. "crypto/sha256"
  6. "encoding/base64"
  7. "strconv"
  8. "github.com/langgenius/dify-plugin-daemon/internal/core/license/public_key"
  9. "github.com/langgenius/dify-plugin-daemon/internal/utils/encryption"
  10. "github.com/langgenius/dify-plugin-daemon/internal/utils/parser"
  11. )
  12. // VerifyPlugin is a function that verifies the signature of a plugin
  13. // It takes a plugin as a stream of bytes and verifies the signature
  14. func VerifyPlugin(archive []byte) error {
  15. // load public key
  16. public_key, err := encryption.LoadPublicKey(public_key.PUBLIC_KEY)
  17. if err != nil {
  18. return err
  19. }
  20. // construct zip
  21. zip_reader, err := zip.NewReader(bytes.NewReader(archive), int64(len(archive)))
  22. if err != nil {
  23. return err
  24. }
  25. data := new(bytes.Buffer)
  26. // read one by one
  27. for _, file := range zip_reader.File {
  28. // read file bytes
  29. file_reader, err := file.Open()
  30. if err != nil {
  31. return err
  32. }
  33. defer file_reader.Close()
  34. temp_data := new(bytes.Buffer)
  35. _, err = temp_data.ReadFrom(file_reader)
  36. if err != nil {
  37. return err
  38. }
  39. hash := sha256.New()
  40. hash.Write(temp_data.Bytes())
  41. hashed := hash.Sum(nil)
  42. // write the hash into data
  43. data.Write(hashed)
  44. }
  45. // get the signature
  46. signature := zip_reader.Comment
  47. type signatureData struct {
  48. Signature string `json:"signature"`
  49. Time int64 `json:"time"`
  50. }
  51. signature_data, err := parser.UnmarshalJson[signatureData](signature)
  52. if err != nil {
  53. return err
  54. }
  55. plugin_sig := signature_data.Signature
  56. plugin_time := signature_data.Time
  57. // convert time to bytes
  58. time_string := strconv.FormatInt(plugin_time, 10)
  59. // write the time into data
  60. data.Write([]byte(time_string))
  61. sig_bytes, err := base64.StdEncoding.DecodeString(plugin_sig)
  62. if err != nil {
  63. return err
  64. }
  65. // verify signature
  66. err = encryption.VerifySign(public_key, data.Bytes(), sig_bytes)
  67. return err
  68. }