Skip to content

Commit

Permalink
SHA-256 hash support for unverified upstream sources
Browse files Browse the repository at this point in the history
Unverified upstream sources (those with `skip-check: true`)
are inherently risky as they lack a verification method. Any
changes to these sources could go undetected. To address
this, we now calculate and store the SHA-256 hash of
unverified sources. This hash is added to the `eext.yaml`
file under the `src-sha256-hash` field. During the
`create-srpm` command, the hash in `eext.yaml` will be
compared with the hash of the downloaded sources.
  • Loading branch information
manishk-arista committed Dec 13, 2024
1 parent 2f083e0 commit fb5e905
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 0 deletions.
38 changes: 38 additions & 0 deletions impl/create_srpm.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
package impl

import (
"crypto/sha256"
"fmt"
"io"
"log"
"os"
"path/filepath"
Expand Down Expand Up @@ -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 {
Expand All @@ -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)
}

Expand Down
9 changes: 9 additions & 0 deletions impl/create_srpm_from_others_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
16 changes: 16 additions & 0 deletions impl/testData/upstream-src-hash/eext.yaml
Original file line number Diff line number Diff line change
@@ -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

Check failure on line 11 in impl/testData/upstream-src-hash/eext.yaml

View workflow job for this annotation

GitHub Actions / Lint

11:81 [line-length] line too long (87 > 80 characters)
type: srpm
build:
repo-bundle:
- name: el9
- name: epel9

Check failure on line 16 in impl/testData/upstream-src-hash/eext.yaml

View workflow job for this annotation

GitHub Actions / Lint

16:22 [new-line-at-end-of-file] no new line character at the end of file
1 change: 1 addition & 0 deletions manifest/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit fb5e905

Please sign in to comment.