Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getNEVRA refactor and cleanup #32

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
cleanup: Factor out PGP parsing from the main parsing loop
The main package loop is busy, especially the massive switch statement,
is busy and difficult to read.  This commit pulls the PGP parsing code out
into a separate helper.

Signed-off-by: Jeff Mahoney <[email protected]>
  • Loading branch information
jeffmahoney committed Dec 4, 2022
commit e033aa7d92ad18847b686096951bfef83866b238
216 changes: 114 additions & 102 deletions pkg/package.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type FileInfo struct {
func getNEVRA(indexEntries []indexEntry) (*PackageInfo, error) {
pkgInfo := &PackageInfo{}
for _, ie := range indexEntries {
var err error
switch ie.Info.Tag {
case RPMTAG_DIRINDEXES:
if ie.Info.Type != RPM_INT32_TYPE {
Expand Down Expand Up @@ -208,123 +209,134 @@ func getNEVRA(indexEntries []indexEntry) (*PackageInfo, error) {
// since this is an international string, getting the first null terminated string
pkgInfo.Summary = string(bytes.Split(ie.Data, []byte{0})[0])
case RPMTAG_PGP:
type pgpSig struct {
_ [3]byte
Date int32
KeyID [8]byte
PubKeyAlgo uint8
HashAlgo uint8
pkgInfo.PGP, err = parsePGPSignature(ie)
if err != nil {
return nil, err
}
}
}

type textSig struct {
_ [2]byte
PubKeyAlgo uint8
HashAlgo uint8
_ [4]byte
Date int32
_ [4]byte
KeyID [8]byte
}
return pkgInfo, nil
}

type pgp4Sig struct {
_ [2]byte
PubKeyAlgo uint8
HashAlgo uint8
_ [17]byte
KeyID [8]byte
_ [2]byte
Date int32
}
const (
sizeOfInt32 = 4
sizeOfUInt16 = 2
)

pubKeyLookup := map[uint8]string{
0x01: "RSA",
}
hashLookup := map[uint8]string{
0x02: "SHA1",
0x08: "SHA256",
}
func parsePGPSignature(ie indexEntry) (string, error) {
type pgpSig struct {
_ [3]byte
Date int32
KeyID [8]byte
PubKeyAlgo uint8
HashAlgo uint8
}

if ie.Info.Type != RPM_BIN_TYPE {
return nil, xerrors.New("invalid PGP signature")
}
type textSig struct {
_ [2]byte
PubKeyAlgo uint8
HashAlgo uint8
_ [4]byte
Date int32
_ [4]byte
KeyID [8]byte
}

type pgp4Sig struct {
_ [2]byte
PubKeyAlgo uint8
HashAlgo uint8
_ [17]byte
KeyID [8]byte
_ [2]byte
Date int32
}

var tag, signatureType, version uint8
r := bytes.NewReader(ie.Data)
err := binary.Read(r, binary.BigEndian, &tag)
pubKeyLookup := map[uint8]string{
0x01: "RSA",
}
hashLookup := map[uint8]string{
0x02: "SHA1",
0x08: "SHA256",
}

if ie.Info.Type != RPM_BIN_TYPE {
return "", xerrors.New("invalid PGP signature")
}

var tag, signatureType, version uint8
r := bytes.NewReader(ie.Data)
err := binary.Read(r, binary.BigEndian, &tag)
if err != nil {
return "", err
}
err = binary.Read(r, binary.BigEndian, &signatureType)
if err != nil {
return "", err
}
err = binary.Read(r, binary.BigEndian, &version)
if err != nil {
return "", err
}

var pubKeyAlgo, hashAlgo, pkgDate string
var keyId [8]byte

switch signatureType {
case 0x01:
switch version {
case 0x1c:
sig := textSig{}
err = binary.Read(r, binary.BigEndian, &sig)
if err != nil {
return nil, err
}
err = binary.Read(r, binary.BigEndian, &signatureType)
return "", xerrors.Errorf("invalid PGP signature on decode: %w", err)
}
pubKeyAlgo = pubKeyLookup[sig.PubKeyAlgo]
hashAlgo = hashLookup[sig.HashAlgo]
pkgDate = time.Unix(int64(sig.Date), 0).UTC().Format("Mon Jan _2 15:04:05 2006")
keyId = sig.KeyID
default:
sig := pgpSig{}
err = binary.Read(r, binary.BigEndian, &sig)
if err != nil {
return nil, err
return "", xerrors.Errorf("invalid PGP signature on decode: %w", err)
}
err = binary.Read(r, binary.BigEndian, &version)
pubKeyAlgo = pubKeyLookup[sig.PubKeyAlgo]
hashAlgo = hashLookup[sig.HashAlgo]
pkgDate = time.Unix(int64(sig.Date), 0).UTC().Format("Mon Jan _2 15:04:05 2006")
keyId = sig.KeyID
}
case 0x02:
switch version {
case 0x33:
sig := pgp4Sig{}
err = binary.Read(r, binary.BigEndian, &sig)
if err != nil {
return nil, err
}

var pubKeyAlgo, hashAlgo, pkgDate string
var keyId [8]byte

switch signatureType {
case 0x01:
switch version {
case 0x1c:
sig := textSig{}
err = binary.Read(r, binary.BigEndian, &sig)
if err != nil {
return nil, xerrors.Errorf("invalid PGP signature on decode: %w", err)
}
pubKeyAlgo = pubKeyLookup[sig.PubKeyAlgo]
hashAlgo = hashLookup[sig.HashAlgo]
pkgDate = time.Unix(int64(sig.Date), 0).UTC().Format("Mon Jan _2 15:04:05 2006")
keyId = sig.KeyID
default:
sig := pgpSig{}
err = binary.Read(r, binary.BigEndian, &sig)
if err != nil {
return nil, xerrors.Errorf("invalid PGP signature on decode: %w", err)
}
pubKeyAlgo = pubKeyLookup[sig.PubKeyAlgo]
hashAlgo = hashLookup[sig.HashAlgo]
pkgDate = time.Unix(int64(sig.Date), 0).UTC().Format("Mon Jan _2 15:04:05 2006")
keyId = sig.KeyID
}
case 0x02:
switch version {
case 0x33:
sig := pgp4Sig{}
err = binary.Read(r, binary.BigEndian, &sig)
if err != nil {
return nil, xerrors.Errorf("invalid PGP signature on decode: %w", err)
}
pubKeyAlgo = pubKeyLookup[sig.PubKeyAlgo]
hashAlgo = hashLookup[sig.HashAlgo]
pkgDate = time.Unix(int64(sig.Date), 0).UTC().Format("Mon Jan _2 15:04:05 2006")
keyId = sig.KeyID
default:
sig := pgpSig{}
err = binary.Read(r, binary.BigEndian, &sig)
if err != nil {
return nil, xerrors.Errorf("invalid PGP signature on decode: %w", err)
}
pubKeyAlgo = pubKeyLookup[sig.PubKeyAlgo]
hashAlgo = hashLookup[sig.HashAlgo]
pkgDate = time.Unix(int64(sig.Date), 0).UTC().Format("Mon Jan _2 15:04:05 2006")
keyId = sig.KeyID
}
return "", xerrors.Errorf("invalid PGP signature on decode: %w", err)
}
pubKeyAlgo = pubKeyLookup[sig.PubKeyAlgo]
hashAlgo = hashLookup[sig.HashAlgo]
pkgDate = time.Unix(int64(sig.Date), 0).UTC().Format("Mon Jan _2 15:04:05 2006")
keyId = sig.KeyID
default:
sig := pgpSig{}
err = binary.Read(r, binary.BigEndian, &sig)
if err != nil {
return "", xerrors.Errorf("invalid PGP signature on decode: %w", err)
}
pkgInfo.PGP = fmt.Sprintf("%s/%s, %s, Key ID %x", pubKeyAlgo, hashAlgo, pkgDate, keyId)
pubKeyAlgo = pubKeyLookup[sig.PubKeyAlgo]
hashAlgo = hashLookup[sig.HashAlgo]
pkgDate = time.Unix(int64(sig.Date), 0).UTC().Format("Mon Jan _2 15:04:05 2006")
keyId = sig.KeyID
}
}

return pkgInfo, nil
}
result := fmt.Sprintf("%s/%s, %s, Key ID %x",
pubKeyAlgo, hashAlgo, pkgDate, keyId)

const (
sizeOfInt32 = 4
sizeOfUInt16 = 2
)
return result, nil
}

func parseInt32Array(data []byte, arraySize int) ([]int32, error) {
length := arraySize / sizeOfInt32
Expand Down