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

Add signature support for the RPM module #27069

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
9fdaf1c
support gpg sign for rpm
ExplodingDragon Sep 14, 2023
d2cf61a
Delete routers/api/packages/rpm/rpm.go.orig
ExplodingDragon Sep 14, 2023
3aff155
Merge branch 'go-gitea:main' into feature-support-rpm-gpgsign
ExplodingDragon Oct 9, 2023
6726a26
Merge branch 'main' into feature-support-rpm-gpgsign
ExplodingDragon Oct 15, 2023
3b940d6
Merge branch 'main' into feature-support-rpm-gpgsign
ExplodingDragon Jan 12, 2024
9b7585c
Merge branch 'main' into feature-support-rpm-gpgsign
ExplodingDragon Mar 19, 2024
9215fa6
Merge branch 'main' into feature-support-rpm-gpgsign
ExplodingDragon May 13, 2024
45fc0ce
Merge branch 'main' into feature-support-rpm-gpgsign
ExplodingDragon May 15, 2024
4b7ac81
upgrade go-rpmutils to v0.4.0
ExplodingDragon May 15, 2024
6ee4a63
Merge branch 'main' into feature-support-rpm-gpgsign
ExplodingDragon May 20, 2024
e695115
Merge branch 'go-gitea:main' into feature-support-rpm-gpgsign
ExplodingDragon May 21, 2024
ca21f30
add test
ExplodingDragon May 21, 2024
181cac8
add test
ExplodingDragon May 21, 2024
613045b
clean style
ExplodingDragon May 21, 2024
7c0b523
Merge branch 'main' into feature-support-rpm-gpgsign
ExplodingDragon May 24, 2024
2c17a43
Merge branch 'main' into feature-support-rpm-gpgsign
ExplodingDragon Jun 14, 2024
a45daa0
Merge branch 'feature-support-rpm-gpgsign' of https://github.com/Expl…
ExplodingDragon Jun 14, 2024
bd72a8f
Merge branch 'main' into feature-support-rpm-gpgsign
ExplodingDragon Jun 14, 2024
a48fd6f
Merge branch 'main' into feature-support-rpm-gpgsign
ExplodingDragon Aug 1, 2024
7ebc829
fix typo
ExplodingDragon Aug 1, 2024
8278cd3
Merge branch 'main' into feature-support-rpm-gpgsign
ExplodingDragon Aug 2, 2024
954e8ff
Merge branch 'main' into feature-support-rpm-gpgsign
ExplodingDragon Aug 3, 2024
4ff9396
clean style
ExplodingDragon Aug 3, 2024
b7337d4
Merge remote-tracking branch 'origin/feature-support-rpm-gpgsign' int…
ExplodingDragon Aug 3, 2024
d2d961a
Merge branch 'main' into feature-support-rpm-gpgsign
ExplodingDragon Aug 6, 2024
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
3 changes: 2 additions & 1 deletion custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2555,7 +2555,8 @@ LEVEL = Info
;LIMIT_SIZE_SWIFT = -1
;; Maximum size of a Vagrant upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
;LIMIT_SIZE_VAGRANT = -1

;; Enable RPM re-signing by default. (It will overwrite the old signature ,using v4 format, not compatible with CentOS 6 or older)
;DEFAULT_RPM_SIGN_ENABLED = false
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; default storage for attachments, lfs and avatars
Expand Down
3 changes: 3 additions & 0 deletions modules/setting/packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ var (
LimitSizeRubyGems int64
LimitSizeSwift int64
LimitSizeVagrant int64

DefaultRPMSignEnabled bool
}{
Enabled: true,
LimitTotalOwnerCount: -1,
Expand Down Expand Up @@ -97,6 +99,7 @@ func loadPackagesFrom(rootCfg ConfigProvider) (err error) {
Packages.LimitSizeRubyGems = mustBytes(sec, "LIMIT_SIZE_RUBYGEMS")
Packages.LimitSizeSwift = mustBytes(sec, "LIMIT_SIZE_SWIFT")
Packages.LimitSizeVagrant = mustBytes(sec, "LIMIT_SIZE_VAGRANT")
Packages.DefaultRPMSignEnabled = sec.Key("DEFAULT_RPM_SIGN_ENABLED").MustBool(false)
return nil
}

Expand Down
16 changes: 15 additions & 1 deletion routers/api/packages/rpm/rpm.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,21 @@ func UploadPackageFile(ctx *context.Context) {
}
defer buf.Close()

// if rpm sign enabled
if setting.Packages.DefaultRPMSignEnabled || ctx.FormBool("sign") {
pri, _, err := rpm_service.GetOrCreateKeyPair(ctx, ctx.Package.Owner.ID)
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
}
buf, err = rpm_service.SignPackage(buf, pri)
if err != nil {
// Not in rpm format, parsing failed.
apiError(ctx, http.StatusBadRequest, err)
return
}
}

pck, err := rpm_module.ParsePackage(buf)
if err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
Expand All @@ -142,7 +157,6 @@ func UploadPackageFile(ctx *context.Context) {
}
return
}

if _, err := buf.Seek(0, io.SeekStart); err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
Expand Down
38 changes: 35 additions & 3 deletions services/packages/rpm/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ import (
rpm_model "code.gitea.io/gitea/models/packages/rpm"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
packages_module "code.gitea.io/gitea/modules/packages"
rpm_module "code.gitea.io/gitea/modules/packages/rpm"
"code.gitea.io/gitea/modules/util"
packages_service "code.gitea.io/gitea/services/packages"

"github.com/keybase/go-crypto/openpgp"
"github.com/keybase/go-crypto/openpgp/armor"
"github.com/keybase/go-crypto/openpgp/packet"
"github.com/ProtonMail/go-crypto/openpgp"
"github.com/ProtonMail/go-crypto/openpgp/armor"
"github.com/ProtonMail/go-crypto/openpgp/packet"
"github.com/sassoftware/go-rpmutils"
)

// GetOrCreateRepositoryVersion gets or creates the internal repository package
Expand Down Expand Up @@ -641,3 +643,33 @@ func addDataAsFileToRepo(ctx context.Context, pv *packages_model.PackageVersion,
OpenSize: wc.Written(),
}, nil
}

func SignPackage(rpm *packages_module.HashedBuffer, privateKey string) (*packages_module.HashedBuffer, error) {
keyring, err := openpgp.ReadArmoredKeyRing(bytes.NewReader([]byte(privateKey)))
if err != nil {
// failed to parse key
return nil, err
}
entity := keyring[0]
h, err := rpmutils.SignRpmStream(rpm, entity.PrivateKey, nil)
if err != nil {
// error signing rpm
return nil, err
}
signBlob, err := h.DumpSignatureHeader(false)
if err != nil {
// error writing sig header
return nil, err
}
if len(signBlob)%8 != 0 {
log.Info("incorrect padding: got %d bytes, expected a multiple of 8", len(signBlob))
return nil, err
}

// move fp to sign end
if _, err := rpm.Seek(int64(h.OriginalSignatureHeaderSize()), io.SeekStart); err != nil {
return nil, err
}
// create signed rpm buf
return packages_module.CreateHashedBufferFromReader(io.MultiReader(bytes.NewReader(signBlob), rpm))
}
27 changes: 27 additions & 0 deletions tests/integration/api_packages_rpm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ import (
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/tests"

"github.com/ProtonMail/go-crypto/openpgp"
"github.com/sassoftware/go-rpmutils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestPackageRpm(t *testing.T) {
Expand Down Expand Up @@ -431,6 +434,30 @@ gpgkey=%sapi/packages/%s/rpm/repository.key`,
AddBasicAuth(user.Name)
MakeRequest(t, req, http.StatusNotFound)
})

t.Run("UploadSign", func(t *testing.T) {
defer tests.PrintCurrentTest(t)()
url := groupURL + "/upload?sign=true"
req := NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)).
AddBasicAuth(user.Name)
MakeRequest(t, req, http.StatusCreated)

gpgReq := NewRequest(t, "GET", rootURL+"/repository.key")
gpgResp := MakeRequest(t, gpgReq, http.StatusOK)
pub, err := openpgp.ReadArmoredKeyRing(gpgResp.Body)
require.NoError(t, err)

req = NewRequest(t, "GET", fmt.Sprintf("%s/package/%s/%s/%s", groupURL, packageName, packageVersion, packageArchitecture))
resp := MakeRequest(t, req, http.StatusOK)

_, sigs, err := rpmutils.Verify(resp.Body, pub)
require.NoError(t, err)
require.NotEmpty(t, sigs)

req = NewRequest(t, "DELETE", fmt.Sprintf("%s/package/%s/%s/%s", groupURL, packageName, packageVersion, packageArchitecture)).
AddBasicAuth(user.Name)
MakeRequest(t, req, http.StatusNoContent)
})
})
}
}