Skip to content

Add the ability to specify the secrete key #23

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

Merged
merged 4 commits into from
Jun 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
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
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,35 @@ So you may skip them in command line invocation in case you have aws config.
* `--sign` - /(optional) sign package metadata
* `path` - specify list of path to scan for repositories

## Environment variables reference

`GPG_SIGN_KEY` - the name of the key that will be used to sign package metadata.

<details><summary>Tips for working with GPG keys</summary>

* Create a new key:
``` bash
gpg --full-generate-key
```
* To view all your keys, you can use:
``` bash
gpg --list-secret-keys --keyid-format LONG
```
* Scripts can use something like this to get the Key ID:
``` bash
export GPG_SIGN_KEY="$(gpg --list-secret-keys --with-colons | grep ^sec: | cut -d: -f5)"
```
* Export the key in ASCII armored format:
``` bash
gpg --armor --export-secret-keys MYKEYID > mykeys.asc
```
* Import the key:
``` bash
cat mykeys.asc | gpg --batch --import
```

</details>

## How it works

`mkrepo` searches the supplied path for either `Packages` or `pool` subdir. If
Expand Down
27 changes: 19 additions & 8 deletions debrepo.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ def bz2_bytes(data):


def gpg_sign_string(data, keyname=None, inline=False):
"""Signing data according to the specified options.

Keyword arguments:
data - data for sign (Unicode string).
keyname - name of the gpg key that will be used to sign the
data (string, default: None).
inline - option specifies whether to use a cleartext
signature (bool, default: False).

Return signed data in binary format.
"""

cmd = "gpg --armor --digest-algo SHA256"

if inline:
Expand All @@ -53,14 +65,14 @@ def gpg_sign_string(data, keyname=None, inline=False):
cmd += " --detach-sign"

if keyname is not None:
cmd += " --default-key='%s'" % keyname
cmd += " --local-user '%s'" % keyname

proc = subprocess.Popen(cmd,
shell=True,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.STDOUT)
stdout = proc.communicate(input=data)[0]
stdout = proc.communicate(input=data.encode('utf-8'))[0]

if proc.returncode != 0:
raise RuntimeError("Failed to sign file: %s" % stdout)
Expand Down Expand Up @@ -431,9 +443,8 @@ def update_repo(storage, sign, tempdir):
release_str.encode('utf-8'))

if sign:
release_str_signature = gpg_sign_string(release_str)
release_str_inline = gpg_sign_string(release_str, inline=True)
storage.write_file('dists/%s/Release.gpg' % dist,
release_str_signature.encode('utf-8'))
storage.write_file('dists/%s/InRelease' % dist,
release_str_inline.encode('utf-8'))
keyname = os.getenv('GPG_SIGN_KEY')
release_signature = gpg_sign_string(release_str, keyname)
release_inline = gpg_sign_string(release_str, keyname, True)
storage.write_file('dists/%s/Release.gpg' % dist, release_signature)
storage.write_file('dists/%s/InRelease' % dist, release_inline)
22 changes: 17 additions & 5 deletions rpmrepo.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,18 @@ def bytes_checksum(data, checksum_type):


def gpg_sign_string(data, keyname=None, inline=False):
"""Signing data according to the specified options.

Keyword arguments:
data - data for sign (Unicode string).
keyname - name of the gpg key that will be used to sign the
data (string, default: None).
inline - option specifies whether to use a cleartext
signature (bool, default: False).

Return signed data in binary format.
"""

cmd = "gpg --armor --digest-algo SHA256"

if inline:
Expand All @@ -66,14 +78,14 @@ def gpg_sign_string(data, keyname=None, inline=False):
cmd += " --detach-sign"

if keyname is not None:
cmd += " --default-key='%s'" % keyname
cmd += " --local-user '%s'" % keyname

proc = subprocess.Popen(cmd,
shell=True,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.STDOUT)
stdout = proc.communicate(input=data)[0]
stdout = proc.communicate(input=data.encode('utf-8'))[0]

if proc.returncode != 0:
raise RuntimeError("Failed to sign file: %s" % stdout)
Expand Down Expand Up @@ -836,9 +848,9 @@ def update_repo(storage, sign, tempdir):
storage.delete_file(initial_primary)

if sign:
repomd_str_signed = gpg_sign_string(repomd_str)
storage.write_file('repodata/repomd.xml.asc',
repomd_str_signed.encode('utf-8'))
keyname = os.getenv('GPG_SIGN_KEY')
repomd_signed = gpg_sign_string(repomd_str, keyname)
storage.write_file('repodata/repomd.xml.asc', repomd_signed)


def main():
Expand Down