Skip to content
Commits on Source (13)
  • Renovate-Bot's avatar
    8547b1d3
  • Kevin Daudt's avatar
    merge: deps: update golang.org/x/exp digest to 9212866 · e0def0ed
    Kevin Daudt authored
    This MR contains the following updates:
    
    | Package | Type | Update | Change |
    |---|---|---|---|
    | golang.org/x/exp | require | digest | `d852ddb` -> `9212866` |
    
    ---
    
    ### Configuration
    
    📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
    
    🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.
    
    ♻️ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.
    
    🔕 **Ignore**: Close this MR and you won't be reminded about this update again.
    
    ---
    
     - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box
    
    ---
    
    This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
    <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi43OC44IiwidXBkYXRlZEluVmVyIjoiMzYuNzguOCIsInRhcmdldEJyYW5jaCI6Im1hc3RlciJ9-->
    
    See: !37
    e0def0ed
  • Ariadne Conill's avatar
  • Kevin Daudt's avatar
  • Renovate-Bot's avatar
    ede38e4e
  • Kevin Daudt's avatar
    merge: deps: update golang.org/x/exp digest to 3e424a5 · 56dbe46d
    Kevin Daudt authored
    This MR contains the following updates:
    
    | Package | Type | Update | Change |
    |---|---|---|---|
    | golang.org/x/exp | require | digest | `9212866` -> `3e424a5` |
    
    ---
    
    ### Configuration
    
    📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
    
    🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.
    
    ♻️ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.
    
    🔕 **Ignore**: Close this MR and you won't be reminded about this update again.
    
    ---
    
     - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box
    
    ---
    
    This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
    <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4xMDkuNCIsInVwZGF0ZWRJblZlciI6IjM2LjEwOS40IiwidGFyZ2V0QnJhbmNoIjoibWFzdGVyIn0=-->
    
    See: !39
    56dbe46d
  • Renovate-Bot's avatar
    ed753e2e
  • Kevin Daudt's avatar
    merge: deps: update golangci/golangci-lint Docker tag to v1.55 · ed069779
    Kevin Daudt authored
    This MR contains the following updates:
    
    | Package | Type | Update | Change |
    |---|---|---|---|
    | golangci/golangci-lint | image | minor | `v1.54-alpine` -> `v1.55-alpine` |
    
    ---
    
    ### Configuration
    
    📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
    
    🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.
    
    ♻️ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.
    
    🔕 **Ignore**: Close this MR and you won't be reminded about this update again.
    
    ---
    
     - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box
    
    ---
    
    This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
    <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4xMDkuNCIsInVwZGF0ZWRJblZlciI6IjM2LjEwOS40IiwidGFyZ2V0QnJhbmNoIjoibWFzdGVyIn0=-->
    
    See: !41
    ed069779
  • Adam Bouqdib's avatar
    repository: sign apk index · f9f3b121
    Adam Bouqdib authored and Kevin Daudt's avatar Kevin Daudt committed
    f9f3b121
  • Kevin Daudt's avatar
    merge: repository: sign apk index · 25f07d68
    Kevin Daudt authored
    This PR adds a `repository.SignArchive` function to allow signing an archive created with `repository.ArchiveFromIndex`.
    
    Also, `repository.ArchiveFromIndex` no longer writes an empty description file if no description is provided (to match the `apk index` command's behaviour)
    
    See: !42
    25f07d68
  • Renovate-Bot's avatar
    deps: update golang.org/x/exp digest to db7319d · 34c3e080
    Renovate-Bot authored and Kevin Daudt's avatar Kevin Daudt committed
    34c3e080
  • Kevin Daudt's avatar
    merge: deps: update golang.org/x/exp digest to db7319d · 0dd70ac8
    Kevin Daudt authored
    This MR contains the following updates:
    
    | Package | Type | Update | Change |
    |---|---|---|---|
    | golang.org/x/exp | require | digest | `3e424a5` -> `db7319d` |
    
    ---
    
    ### Configuration
    
    📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).
    
    🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.
    
    ♻️ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.
    
    🔕 **Ignore**: Close this MR and you won't be reminded about this update again.
    
    ---
    
     - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box
    
    ---
    
    This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
    <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNi4xMDkuNCIsInVwZGF0ZWRJblZlciI6IjM3LjEyNi4zIiwidGFyZ2V0QnJhbmNoIjoibWFzdGVyIn0=-->
    
    See: !40
    0dd70ac8
  • Kevin Daudt's avatar
    release: add changelog for 0.9.0 · d3cce637
    Kevin Daudt authored
    d3cce637
......@@ -12,7 +12,7 @@ tests:
linting:
stage: verify
image: golangci/golangci-lint:v1.54-alpine
image: golangci/golangci-lint:v1.55-alpine
script:
- golangci-lint run -v
tags:
......
......@@ -2,6 +2,20 @@
All notable changes to this project will be documented in this file.
## [0.9.0] - 2024-01-17
### Dependencies
- Update golang.org/x/exp digest to 9212866
- Update golang.org/x/exp digest to 3e424a5
- Update golangci/golangci-lint Docker tag to v1.55
- Update golang.org/x/exp digest to db7319d
### repository
- Package: add support for the provider_priority field
- Sign apk index
## [0.8.0] - 2023-09-03
### Dependencies
......
......@@ -5,7 +5,7 @@ go 1.19
require (
github.com/MakeNowJust/heredoc/v2 v2.0.1
github.com/stretchr/testify v1.8.4
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3
gopkg.in/ini.v1 v1.67.0
gopkg.in/yaml.v3 v3.0.1
mvdan.cc/sh/v3 v3.7.0
......@@ -15,6 +15,6 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sync v0.2.0 // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/sys v0.12.0 // indirect
golang.org/x/term v0.8.0 // indirect
)
......@@ -12,12 +12,12 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/rogpeppe/go-internal v1.10.1-0.20230524175051-ec119421bb97 h1:3RPlVWzZ/PDqmVuf/FKHARG5EMid/tl7cv54Sw/QRVY=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8=
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o=
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
......
......@@ -5,6 +5,10 @@ import (
"bufio"
"bytes"
"compress/gzip"
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"encoding/base64"
"fmt"
"io"
......@@ -17,8 +21,10 @@ import (
"github.com/MakeNowJust/heredoc/v2"
)
const apkIndexFilename = "APKINDEX"
const descriptionFilename = "DESCRIPTION"
const (
apkIndexFilename = "APKINDEX"
descriptionFilename = "DESCRIPTION"
)
// Go template for generating the APKINDEX file from an ApkIndex struct
var apkIndexTemplate = template.Must(template.New(apkIndexFilename).Funcs(
......@@ -181,7 +187,6 @@ func ParsePackageIndex(apkIndexUnpacked io.Reader) (packages []*Package, err err
func IndexFromArchive(archive io.ReadCloser) (apkindex *ApkIndex, err error) {
gzipReader, err := gzip.NewReader(archive)
if err != nil {
return
}
......@@ -247,24 +252,14 @@ func ArchiveFromIndex(apkindex *ApkIndex) (archive io.Reader, err error) {
defer tw.Close()
// Add APKINDEX and DESCRIPTION files to the tarball
for _, item := range []struct {
filename string
contents []byte
}{
{apkIndexFilename, apkindexContents.Bytes()},
{descriptionFilename, []byte(apkindex.Description)},
} {
var info os.FileInfo = &tarballItemFileInfo{item.filename, int64(len(item.contents))}
header, err := tar.FileInfoHeader(info, item.filename)
err = tarWrite(tw, apkIndexFilename, apkindexContents.Bytes())
if err != nil {
return nil, err
}
if apkindex.Description != "" {
err = tarWrite(tw, descriptionFilename, []byte(apkindex.Description))
if err != nil {
return nil, fmt.Errorf("creating tar header for %s: %w", item.filename, err)
}
header.Name = item.filename
if err := tw.WriteHeader(header); err != nil {
return nil, fmt.Errorf("writing tar header for %s: %w", item.filename, err)
}
if _, err = io.Copy(tw, bytes.NewReader(item.contents)); err != nil {
return nil, fmt.Errorf("copying tar contents for %s: %w", item.filename, err)
return nil, err
}
}
......@@ -272,6 +267,50 @@ func ArchiveFromIndex(apkindex *ApkIndex) (archive io.Reader, err error) {
return &tarballContents, nil
}
// SignArchive signs an unsigned APKINDEX archive e.g. APKINDEX.unsigned.tar.gz.
func SignArchive(archive io.Reader, privateKey *rsa.PrivateKey, keyName string) (signedArchive io.Reader, err error) {
archiveBytes, err := io.ReadAll(archive)
if err != nil {
return nil, err
}
var signature bytes.Buffer
gw := gzip.NewWriter(&signature)
defer gw.Close()
tw := tar.NewWriter(gw)
sum := sha1.Sum(archiveBytes)
sig, err := privateKey.Sign(rand.Reader, sum[:], crypto.SHA1)
if err != nil {
return nil, err
}
if err = tarWrite(tw, ".SIGN.RSA."+keyName, sig); err != nil {
return nil, err
}
if err = tw.Flush(); err != nil {
return nil, err
}
// Concatenate the signature and unsigned archive.
return io.MultiReader(&signature, bytes.NewReader(archiveBytes)), nil
}
func tarWrite(tw *tar.Writer, filename string, content []byte) error {
info := &tarballItemFileInfo{filename, int64(len(content))}
header, err := tar.FileInfoHeader(info, filename)
if err != nil {
return fmt.Errorf("creating tar header for %s: %w", filename, err)
}
if err = tw.WriteHeader(header); err != nil {
return fmt.Errorf("writing tar header for %s: %w", filename, err)
}
if _, err = tw.Write(content); err != nil {
return fmt.Errorf("copying tar contents for %s: %w", filename, err)
}
return nil
}
// This type implements os.FileInfo, allowing us to construct
// a tar header without needing to run os.Stat on a file
type tarballItemFileInfo struct {
......@@ -281,7 +320,7 @@ type tarballItemFileInfo struct {
func (info *tarballItemFileInfo) Name() string { return info.name }
func (info *tarballItemFileInfo) Size() int64 { return info.size }
func (info *tarballItemFileInfo) Mode() os.FileMode { return 0644 }
func (info *tarballItemFileInfo) Mode() os.FileMode { return 0o644 }
func (info *tarballItemFileInfo) ModTime() time.Time { return time.Time{} }
func (info *tarballItemFileInfo) IsDir() bool { return false }
func (info *tarballItemFileInfo) Sys() interface{} { return nil }
......
......@@ -2,7 +2,12 @@ package repository
import (
"archive/tar"
"bytes"
"compress/gzip"
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"fmt"
"io"
"os"
......@@ -135,6 +140,58 @@ func TestParseFromArchive(t *testing.T) {
assert.Len(apkIndex.Packages, 2)
}
func TestSignArchive(t *testing.T) {
apkindex := &ApkIndex{
Description: "test",
Packages: []*Package{
{
Name: "test-package",
Version: "1.2.3-r0",
},
},
}
unsignedArchive, err := ArchiveFromIndex(apkindex)
require.NoError(t, err)
unsigned, err := io.ReadAll(unsignedArchive)
require.NoError(t, err)
priv, err := rsa.GenerateKey(rand.Reader, 2048)
require.NoError(t, err)
signedArchive, err := SignArchive(bytes.NewReader(unsigned), priv, "test@example.com.rsa.pub")
require.NoError(t, err)
signed, err := io.ReadAll(signedArchive)
require.NoError(t, err)
apkindex, err = IndexFromArchive(io.NopCloser(bytes.NewReader(signed)))
require.NoError(t, err)
sum := sha1.Sum(unsigned)
assert.NoError(t, rsa.VerifyPKCS1v15(&priv.PublicKey, crypto.SHA1, sum[:], apkindex.Signature))
gr, err := gzip.NewReader(bytes.NewReader(signed))
require.NoError(t, err)
// Ensure signature file is correctly named.
tr := tar.NewReader(gr)
var foundSignature bool
for {
hdr, err := tr.Next()
if err == io.EOF {
break
}
require.NoError(t, err)
if hdr.Name == ".SIGN.RSA.test@example.com.rsa.pub" {
foundSignature = true
break
}
}
assert.Truef(t, foundSignature, "Could not locate signature in archive")
}
// Test reading from io.Reader that doesn't implement io.Closer
func TestSinglePackageOnlyReader(t *testing.T) {
apkIndexFile := strings.NewReader(heredoc.Doc(`
......
......@@ -101,6 +101,8 @@ func ParsePackage(apkPackage io.Reader) (*Package, error) {
RepoCommit: info.Commit,
BuildTime: time.Unix(info.BuildDate, 0).UTC(),
Replaces: info.Replaces,
ProviderPriority: info.ProviderPriority,
}, nil
}
......@@ -120,4 +122,6 @@ type apkInfo struct {
Replaces string `ini:"replaces"`
Depend []string `ini:"depend,,allowshadow"`
Provides []string `ini:"provides,,allowshadow"`
ProviderPriority uint64 `ini:"provider_priority"`
}