fix apkdb checksum representation (#1247)

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
Alex Goodman 2022-10-05 16:29:05 -04:00 committed by GitHub
parent 7d2fe9d95e
commit 48f0a4680f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 90 additions and 42 deletions

View File

@ -134,10 +134,7 @@ func parseApkDBEntry(reader io.Reader) (*pkg.ApkMetadata, error) {
log.Warnf("checksum field with no parent record: %q", value)
continue
}
fileRecord.Digest = &file.Digest{
Algorithm: "sha1",
Value: value,
}
fileRecord.Digest = processChecksum(value)
case "I", "S":
// coerce to integer
iVal, err := strconv.Atoi(value)
@ -161,3 +158,23 @@ func parseApkDBEntry(reader io.Reader) (*pkg.ApkMetadata, error) {
return &entry, nil
}
func processChecksum(value string) *file.Digest {
// from: https://wiki.alpinelinux.org/wiki/Apk_spec
// The package checksum field is the SHA1 hash of the second gzip stream (control stream) in the package. The
// binary hash digest is base64 encoded. This is prefixed with Q1 to differentiate it from the MD5 hashes
// used in older index formats. It is not possible to compute this checksum with standard command line tools
// but the apk-tools can compute it in their index operation.
// based on https://github.com/alpinelinux/apk-tools/blob/dd1908f2fc20b4cfe2c15c55fafaa5fadfb599dc/src/blob.c#L379-L393
// it seems that the old md5 checksum value was only the hex representation (not base64)
algorithm := "md5"
if strings.HasPrefix(value, "Q1") {
algorithm = "'Q1'+base64(sha1)"
}
return &file.Digest{
Algorithm: algorithm,
Value: value,
}
}

View File

@ -6,6 +6,7 @@ import (
"testing"
"github.com/go-test/deep"
"github.com/stretchr/testify/assert"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/pkg"
@ -41,7 +42,7 @@ func TestExtraFileAttributes(t *testing.T) {
OwnerGID: "0",
Permissions: "755",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1M0C9qfC/+kdRiOodeihG2GMRtkE=",
},
},
@ -110,7 +111,7 @@ func TestSinglePackageDetails(t *testing.T) {
OwnerGID: "0",
Permissions: "755",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1Kja2+POZKxEkUOZqwSjC6kmaED4=",
},
},
@ -126,7 +127,7 @@ func TestSinglePackageDetails(t *testing.T) {
OwnerGID: "0",
Permissions: "755",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1CVmFbdY+Hv6/jAHl1gec2Kbx1EY=",
},
},
@ -136,7 +137,7 @@ func TestSinglePackageDetails(t *testing.T) {
OwnerGID: "0",
Permissions: "755",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1yFAhGggmL7ERgbIA7KQxyTzf3ks=",
},
},
@ -146,7 +147,7 @@ func TestSinglePackageDetails(t *testing.T) {
OwnerGID: "0",
Permissions: "755",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1dAdYK8M/INibRQF5B3Rw7cmNDDA=",
},
},
@ -156,7 +157,7 @@ func TestSinglePackageDetails(t *testing.T) {
OwnerGID: "0",
Permissions: "755",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1eR2Dz/WylabgbWMTkd2+hGmEya4=",
},
},
@ -195,49 +196,49 @@ func TestSinglePackageDetails(t *testing.T) {
{
Path: "/etc/fstab",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q11Q7hNe8QpDS531guqCdrXBzoA/o=",
},
},
{
Path: "/etc/group",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1oJ16xWudgKOrXIEquEDzlF2Lsm4=",
},
},
{
Path: "/etc/hostname",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q16nVwYVXP/tChvUPdukVD2ifXOmc=",
},
},
{
Path: "/etc/hosts",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1BD6zJKZTRWyqGnPi4tSfd3krsMU=",
},
},
{
Path: "/etc/inittab",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1TsthbhW7QzWRe1E/NKwTOuD4pHc=",
},
},
{
Path: "/etc/modules",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1toogjUipHGcMgECgPJX64SwUT1M=",
},
},
{
Path: "/etc/motd",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1XmduVVNURHQ27TvYp1Lr5TMtFcA=",
},
},
@ -247,35 +248,35 @@ func TestSinglePackageDetails(t *testing.T) {
OwnerGID: "0",
Permissions: "777",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1kiljhXXH1LlQroHsEJIkPZg2eiw=",
},
},
{
Path: "/etc/passwd",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1TchuuLUfur0izvfZQZxgN/LJhB8=",
},
},
{
Path: "/etc/profile",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1KpFb8kl5LvwXWlY3e58FNsjrI34=",
},
},
{
Path: "/etc/protocols",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q13FqXUnvuOpMDrH/6rehxuYAEE34=",
},
},
{
Path: "/etc/services",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1C6HJNgQvLWqt5VY+n7MZJ1rsDuY=",
},
},
@ -285,21 +286,21 @@ func TestSinglePackageDetails(t *testing.T) {
OwnerGID: "42",
Permissions: "640",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1ltrPIAW2zHeDiajsex2Bdmq3uqA=",
},
},
{
Path: "/etc/shells",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1ojm2YdpCJ6B/apGDaZ/Sdb2xJkA=",
},
},
{
Path: "/etc/sysctl.conf",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q14upz3tfnNxZkIEsUhWn7Xoiw96g=",
},
},
@ -318,7 +319,7 @@ func TestSinglePackageDetails(t *testing.T) {
OwnerGID: "0",
Permissions: "600",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1vfk1apUWI4yLJGhhNRd0kJixfvY=",
},
},
@ -331,28 +332,28 @@ func TestSinglePackageDetails(t *testing.T) {
{
Path: "/etc/modprobe.d/aliases.conf",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1WUbh6TBYNVK7e4Y+uUvLs/7viqk=",
},
},
{
Path: "/etc/modprobe.d/blacklist.conf",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1xxYGU6S6TLQvb7ervPrWWwAWqMg=",
},
},
{
Path: "/etc/modprobe.d/i386.conf",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1pnay/njn6ol9cCssL7KiZZ8etlc=",
},
},
{
Path: "/etc/modprobe.d/kms.conf",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1ynbLn3GYDpvajba/ldp1niayeog=",
},
},
@ -401,14 +402,14 @@ func TestSinglePackageDetails(t *testing.T) {
{
Path: "/etc/profile.d/color_prompt",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q10wL23GuSCVfumMRgakabUI6EsSk=",
},
},
{
Path: "/etc/profile.d/locale",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1R4bIEpnKxxOSrlnZy9AoawqZ5DU=",
},
},
@ -436,7 +437,7 @@ func TestSinglePackageDetails(t *testing.T) {
{
Path: "/lib/sysctl.d/00-alpine.conf",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1HpElzW1xEgmKfERtTy7oommnq6c=",
},
},
@ -479,7 +480,7 @@ func TestSinglePackageDetails(t *testing.T) {
OwnerGID: "0",
Permissions: "755",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1YeuSmC7iDbEWrusPzA/zUQF6YSg=",
},
},
@ -537,7 +538,7 @@ func TestSinglePackageDetails(t *testing.T) {
OwnerGID: "0",
Permissions: "777",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q11/SNZz/8cK2dSKK+cJpVrZIuF4Q=",
},
},
@ -586,7 +587,7 @@ func TestSinglePackageDetails(t *testing.T) {
OwnerGID: "0",
Permissions: "777",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1dzbdazYZA2nTzSIG3YyNw7d4Juc=",
},
},
@ -599,7 +600,7 @@ func TestSinglePackageDetails(t *testing.T) {
OwnerGID: "0",
Permissions: "777",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1OFZt+ZMp7j0Gny0rqSKuWJyqYmA=",
},
},
@ -704,7 +705,7 @@ func TestMultiplePackages(t *testing.T) {
OwnerGID: "0",
Permissions: "755",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1Kja2+POZKxEkUOZqwSjC6kmaED4=",
},
},
@ -720,7 +721,7 @@ func TestMultiplePackages(t *testing.T) {
OwnerGID: "0",
Permissions: "755",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1CVmFbdY+Hv6/jAHl1gec2Kbx1EY=",
},
},
@ -730,7 +731,7 @@ func TestMultiplePackages(t *testing.T) {
OwnerGID: "0",
Permissions: "755",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1yFAhGggmL7ERgbIA7KQxyTzf3ks=",
},
},
@ -740,7 +741,7 @@ func TestMultiplePackages(t *testing.T) {
OwnerGID: "0",
Permissions: "755",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1dAdYK8M/INibRQF5B3Rw7cmNDDA=",
},
},
@ -750,7 +751,7 @@ func TestMultiplePackages(t *testing.T) {
OwnerGID: "0",
Permissions: "755",
Digest: &file.Digest{
Algorithm: "sha1",
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1eR2Dz/WylabgbWMTkd2+hGmEya4=",
},
},
@ -795,3 +796,33 @@ func TestMultiplePackages(t *testing.T) {
})
}
}
func Test_processChecksum(t *testing.T) {
tests := []struct {
name string
value string
want file.Digest
}{
{
name: "md5",
value: "38870ede8700535d7382ff66a46fcc2f",
want: file.Digest{
Algorithm: "md5",
Value: "38870ede8700535d7382ff66a46fcc2f",
},
},
{
name: "sha1",
value: "Q1Kja2+POZKxEkUOZqwSjC6kmaED4=",
want: file.Digest{
Algorithm: "'Q1'+base64(sha1)",
Value: "Q1Kja2+POZKxEkUOZqwSjC6kmaED4=",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, &tt.want, processChecksum(tt.value))
})
}
}