diff --git a/impl/create_srpm.go b/impl/create_srpm.go index ebf4ee0..6dd9d9a 100644 --- a/impl/create_srpm.go +++ b/impl/create_srpm.go @@ -4,7 +4,9 @@ package impl import ( + "crypto/sha256" "fmt" + "io" "log" "os" "path/filepath" @@ -74,6 +76,24 @@ func (bldr *srpmBuilder) clean() error { return nil } +// Generate SHA256 hash of the downloaded upstream source +// and match it with the SHA256 hash in eext.yaml +func generateSrcSha256Hash(srcFilePath string) (string, error) { + srcFile, err := os.Open(srcFilePath) + if err != nil { + return "", fmt.Errorf("errored with %s while creating file", + err) + } + defer srcFile.Close() + hashComputer := sha256.New() + if _, err := io.Copy(hashComputer, srcFile); err != nil { + return "", fmt.Errorf("errored with %s while generating hash", + err) + } + sha256Hash := fmt.Sprintf("%x", hashComputer.Sum(nil)) + return sha256Hash, nil +} + // Fetch the upstream sources mentioned in the manifest. // Put them into downloadDir and populate bldr.upstreamSrc func (bldr *srpmBuilder) fetchUpstream() error { @@ -98,6 +118,24 @@ func (bldr *srpmBuilder) fetchUpstream() error { if err != nil { return err } + + if upstreamSrcFromManifest.Signature.SkipCheck && upstreamSrcFromManifest.Signature.SrcSha256Hash != "" { + srcFilePath := filepath.Join(downloadDir, upstreamSrc.sourceFile) + sha256Hash, err := generateSrcSha256Hash(srcFilePath) + if err != nil { + return fmt.Errorf("%sError '%s'", + bldr.errPrefix, err) + } + eextSha256Hash := upstreamSrcFromManifest.Signature.SrcSha256Hash + fmt.Printf("calculated SHA hash is `%s`, hash in eext-yaml file is `%s` \n", sha256Hash, eextSha256Hash) + if sha256Hash != eextSha256Hash { + return fmt.Errorf("%sError:SHA256 hash '%s'is not matching with eext.yaml sha hash '%s' for upstream file '%s', package '%s'", + bldr.errPrefix, sha256Hash, eextSha256Hash, srcFilePath, bldr.pkgSpec.Name) + } else { + fmt.Printf("SHA-256 hash matched successfully, unmodified upstream source found \n") + } + } + bldr.upstreamSrc = append(bldr.upstreamSrc, *upstreamSrc) } diff --git a/impl/create_srpm_from_others_test.go b/impl/create_srpm_from_others_test.go index 92981df..6b471ff 100644 --- a/impl/create_srpm_from_others_test.go +++ b/impl/create_srpm_from_others_test.go @@ -42,3 +42,12 @@ func TestMatchTarballSignature(t *testing.T) { t.Log("Test tarball Signatue Match") testTarballSig(t, "matchTarball") } + +func TestUpstreamSourcesSHA256Hash(t *testing.T) { + pkg := "bandit" + cwd, _ := os.Getwd() + repo := filepath.Join(cwd, "testData/upstream-src-hash") + createSrpmErr := CreateSrpm(repo, pkg, CreateSrpmExtraCmdlineArgs{}) + require.NotEqual(t, nil, createSrpmErr) + t.Log("TestupstreamSourcesSHA256Hash test passed") +} diff --git a/impl/testData/upstream-src-hash/eext.yaml b/impl/testData/upstream-src-hash/eext.yaml new file mode 100644 index 0000000..ea3c1aa --- /dev/null +++ b/impl/testData/upstream-src-hash/eext.yaml @@ -0,0 +1,16 @@ +--- +package: + - name: bandit + upstream-sources: + - source-bundle: + name: srpm + override: + version: 1.7.7-1.fc40 + signature: + skip-check: true + src-sha256-hash: c2b29c064e8c9dcf92fe21b416d2sfgsgsfg94d7850f22d7aca596fd97fc + type: srpm + build: + repo-bundle: + - name: el9 + - name: epel9 \ No newline at end of file diff --git a/manifest/manifest.go b/manifest/manifest.go index 5296447..7739abf 100644 --- a/manifest/manifest.go +++ b/manifest/manifest.go @@ -109,6 +109,7 @@ type DetachedSignature struct { type Signature struct { SkipCheck bool `yaml:"skip-check"` DetachedSignature DetachedSignature `yaml:"detached-sig"` + SrcSha256Hash string `yaml:"src-sha256-hash"` } // SourceBundle spec