Skip to content

Commit

Permalink
Tarball Signature check
Browse files Browse the repository at this point in the history
Some tarballs have extra compression on top after making the signature,
which eventually leads to failing of signature check.
So new changes are made which take care of decompressing the tarball
to correct level where the tarball can be verified by its signature.
Checks also has been added to look for valid tarball signature pair,
so that processing can be terminated earlier if invalid pair found.
Test cases are added for followling scenarios:
1. Right decompression of tarball to match its signature
2. Mismatch check in tarbal and its signautre naming i.e., either wrong
   sig file is provided or naming convention is not followed

Fixes: BUG1000391
  • Loading branch information
manishk-arista committed Sep 6, 2024
1 parent 7374f58 commit e7a4f64
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ RUN dnf install -y epel-release-9* git-2.* jq-1.* \
rpmdevtools-9.* sudo-1.* && \
dnf install -y mock-5.* automake-1.16.* && \
dnf install -y wget-1.21.* && \
dnf install -y vim-enhanced-2:8.2.* emacs-27.* && dnf clean all
dnf install -y vim-enhanced-2:8.2.* emacs-27.* p7zip-16.* && dnf clean all
RUN useradd -s /bin/bash mockbuild -p "$(openssl passwd -1 mockbuild)"
CMD ["bash"]

Expand Down
2 changes: 1 addition & 1 deletion barney.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ images:
units:
- floor: .%internal/alma-9.1-bootstrap
sources: []
build: install-rpms autoconf automake coreutils git rpm rpmdevtools rpm-build make mock python3-devel quilt
build: install-rpms autoconf automake coreutils git rpm rpmdevtools rpm-build make mock python3-devel quilt p7zip

go-binaries:
description: |
Expand Down
35 changes: 35 additions & 0 deletions cmd/create_srpm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,41 @@ func testCreateSrpm(t *testing.T,
}
}

func testTarballSig(t *testing.T, folder string) {
curPath, _ := os.Getwd()
workingDir := filepath.Join(curPath, "testData/tarballSig", folder)
tarballPath := map[string]string{
"checkTarball": filepath.Join(workingDir, "linux.10.4.1.tar.gz"),
"matchTarball": filepath.Join(workingDir, "libpcap-1.10.4.tar.gz.xz.gz"),
}
tarballSigPath := filepath.Join(workingDir, "libpcap-1.10.4.tar.gz.sig")

switch folder {
case "checkTarball":
ok, _ := util.CheckValidSignature(tarballPath[folder], tarballSigPath)
require.Equal(t, false, ok)
case "matchTarball":
intermediateTarballs, err := util.MatchtarballSignCmprsn(
tarballPath[folder],
tarballSigPath,
workingDir,
"TestmatchTarballSignature : ",
)
util.RemoveFiles(intermediateTarballs, "TestMatchTarballSignature :")
require.Equal(t, nil, err)
}
}

func TestCheckTarballSignature(t *testing.T) {
t.Log("Test tarball Signatue Check")
testTarballSig(t, "checkTarball")
}

func TestMatchTarballSignature(t *testing.T) {
t.Log("Test tarball Signatue Match")
testTarballSig(t, "matchTarball")
}

func TestCreateSrpmFromSrpm(t *testing.T) {
t.Log("Test createSrpm from SRPM")
testCreateSrpm(t,
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
19 changes: 17 additions & 2 deletions impl/create_srpm.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,18 +218,33 @@ func (bldr *srpmBuilder) verifyUpstream() error {
}
} else {
downloadDir := getDownloadDir(bldr.pkgSpec.Name)
for _, upstreamSrc := range bldr.upstreamSrc {

for index, upstreamSrc := range bldr.upstreamSrc {
upstreamSourceFilePath := filepath.Join(downloadDir, upstreamSrc.sourceFile)

if !upstreamSrc.skipSigCheck {
upstreamSigFilePath := filepath.Join(downloadDir, upstreamSrc.sigFile)
intermediateTarballs, err := util.MatchtarballSignCmprsn(
upstreamSourceFilePath, upstreamSigFilePath,
downloadDir, bldr.errPrefix)
if err != nil {
return err
}
finalTarballPath := intermediateTarballs[len(intermediateTarballs)-1]
if err := util.VerifyTarballSignature(
upstreamSourceFilePath,
finalTarballPath,
upstreamSigFilePath,
upstreamSrc.pubKeyPath,
bldr.errPrefix); err != nil {
return err
}
// if err := util.RemoveFiles(
// intermediateTarballs,
// bldr.errPrefix); err != nil {
// return err
// }
bldr.upstreamSrc[index].sourceFile = strings.TrimPrefix(
finalTarballPath, downloadDir)
}
}
}
Expand Down
65 changes: 65 additions & 0 deletions util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,76 @@ func VerifyRpmSignature(rpmPath string, errPrefix ErrPrefix) error {
return nil
}

// RemoveFiles deletes the files paths in passed slice
func RemoveFiles(filePaths []string, errPrefix ErrPrefix) error {
for _, path := range filePaths {
if err := RunSystemCmd("rm", path); err != nil {
return fmt.Errorf("%sError '%s' while removing %s",
errPrefix, err, path)
}
}
return nil
}

func getNewPath(tarballPath string) string {
lastDotIndex := strings.LastIndex(tarballPath, ".")
return tarballPath[:lastDotIndex]
}

// CheckValidSignature verifies that tarball anf signature
// correspond to same package
func CheckValidSignature(tarballPath, tarballSigPath string) (
bool, int) {
lastDotIndex := strings.LastIndex(tarballSigPath, ".")
if lastDotIndex == -1 || !strings.HasPrefix(
tarballPath, tarballSigPath[:lastDotIndex]) {
return false, 0
}
requiredDecompressions := strings.Count(tarballPath[lastDotIndex:], ".")
return true, requiredDecompressions
}

// UncompressTarball decompresses the compression one layer at a time
// to match the tarball with its valid signature
func UncompressTarball(tarballPath string, downloadDir string) error {
if err := RunSystemCmd(
"7za", "x",
"-y", tarballPath,
"-o"+downloadDir); err != nil {
return err
}
return nil
}

// MatchtarballSignCmprsn evaluvates and finds correct compressed/uncompressed tarball
// that matches with the sign file.
func MatchtarballSignCmprsn(tarballPath string, tarballSigPath string,
downloadDir string, errPrefix ErrPrefix) ([]string, error) {
intermediateTarballPaths := []string{}
if ok, requiredDecompressions := CheckValidSignature(
tarballPath, tarballSigPath); ok {
for requiredDecompressions > 0 {
if err := UncompressTarball(tarballPath, downloadDir); err != nil {
return []string{}, fmt.Errorf("%sError '%s' while decompressing trarball",
errPrefix, err)
}
tarballPath = getNewPath(tarballPath)
intermediateTarballPaths = append(intermediateTarballPaths, tarballPath)
requiredDecompressions--
}
} else {
return intermediateTarballPaths, fmt.Errorf("%sError while matching tarball and signature",
errPrefix)
}
return intermediateTarballPaths, nil
}

// VerifyTarballSignature verifies that the detached signature of the tarball
// is valid.
func VerifyTarballSignature(
tarballPath string, tarballSigPath string, pubKeyPath string,
errPrefix ErrPrefix) error {
// check for matching tarball compression for tarball signature file
tmpDir, mkdtErr := os.MkdirTemp("", "eext-keyring")
if mkdtErr != nil {
return fmt.Errorf("%sError '%s'creating temp dir for keyring",
Expand Down

0 comments on commit e7a4f64

Please sign in to comment.