Skip to content

gpg fails to find key due to overriden locale #1130

Open
@jgalar

Description

@jgalar

Description

I am using GitPython to sign tags as such:

repo.git.tag(
            "-s",
            "v{}".format(str(new_version)),
            "-m Version {}".format(str(new_version)),
        )

This fails with the following error/exception:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/jgalar/.cache/pypoetry/virtualenvs/reml-06EzQDmo-py3.9/lib/python3.9/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/home/jgalar/.cache/pypoetry/virtualenvs/reml-06EzQDmo-py3.9/lib/python3.9/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/jgalar/.cache/pypoetry/virtualenvs/reml-06EzQDmo-py3.9/lib/python3.9/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/jgalar/.cache/pypoetry/virtualenvs/reml-06EzQDmo-py3.9/lib/python3.9/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/jgalar/EfficiOS/src/reml/reml/cli.py", line 93, in main
    release = project.release(
  File "/home/jgalar/EfficiOS/src/reml/reml/project.py", line 443, in release
    self._commit_and_tag(new_version)
  File "/home/jgalar/EfficiOS/src/reml/reml/lttngtools.py", line 41, in _commit_and_tag
    self._repo.git.tag(
  File "/home/jgalar/.cache/pypoetry/virtualenvs/reml-06EzQDmo-py3.9/lib/python3.9/site-packages/git/cmd.py", line 545, in <lambda>
    return lambda *args, **kwargs: self._call_process(name, *args, **kwargs)
  File "/home/jgalar/.cache/pypoetry/virtualenvs/reml-06EzQDmo-py3.9/lib/python3.9/site-packages/git/cmd.py", line 1011, in _call_process
    return self.execute(call, **exec_kwargs)
  File "/home/jgalar/.cache/pypoetry/virtualenvs/reml-06EzQDmo-py3.9/lib/python3.9/site-packages/git/cmd.py", line 828, in execute
    raise GitCommandError(command, status, stderr_value, stdout_value)
git.exc.GitCommandError: Cmd('git') failed due to: exit code(128)
  cmdline: git tag -s v2.12.4 -m Version 2.12.4
  stderr: 'error: gpg failed to sign the data
error: unable to sign the tag'

Debugging the problem

I was initially confused since I can sign tags correctly from the command line using the git tag -s ... command directly.

Digging a bit, I saw that git invokes gpg with the following arguments both when I tag using the gitclient directly or when using GitPython.

argv[0] = /usr/bin/gpg2
argv[1] = --status-fd=2
argv[2] = -bsau
argv[3] = Jérémie Galarneau <jeremie.galarneau@efficios.com>

This seemed to point to something more subtle, possibly related to the process's environment.

I couldn't find a way for git to provide the stderr of gpg to get a better error report. Thus, I modified GnuPG 2.2.27 and rebuilt it to output the errors to a log file. This yielded the following error:

[GNUPG:] INV_SGNR 9 Jérémie Galarneau <jeremie.galarneau@efficios.com>
[GNUPG:] FAILURE sign 17
gpg: signing failed: No secret key

If you look at the first line, you will see that the é characters in my name were changed to é.
This typically happens when my name is converted from UTF-8 to ISO/IEC 8859-1.

This clued me in that something funny related to locales was happening.

I dumped and compared the environment of the gpg process in the two scenarios (CLI use and GitPython) and saw that the only meaningful difference was that the LANGUAGE and LC_ALL environment variables were set to C when GitPython was involved.

Indeed, invoking git with LC_ALL="C" LANGUAGE="C" git tag -s [...] reproduced the problem.

Cause

Looking at the GitPython code, I found that git is invoked with those environment variables set:
https://github.com/gitpython-developers/GitPython/blame/b3778ec/git/cmd.py#L694

I am unsure what "parsing code" the comments are referring to so I can't comment on the reasons why this is done. However, forcing a C locale will cause these kinds of erroneous encoding conversions for people who, like me, have non-ASCII names.

For what it's worth, my locale is LANG=en_CA.utf8.

I would guess that forcing the locale to any UTF-8 English locale would work around most issues and still provide GitPython with an English output.

My workaround

I found out that setting the signingKey property to my KEYID in my .gitconfig causes git to invoke gpg with the KEYID instead of the name property.

[user]
	name = Jérémie Galarneau
	email = jeremie.galarneau@efficios.com
	signingKey = MY_KEY_ID_HERE

This works around the problem since no accented letters are used in the gpg invocation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions