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
x/crypto/openpgp: cannot encrypt a message to key id 83378a94fa6c4994 because it has no encryption keys #26468
Comments
CC @FiloSottile @agl |
i tried reproducing this, but couldn't. This is what I tried:
Output:
This is with @w8rbt Can you try to reproduce this on go1.11, the latest version of x/crypto and with a fresh GNUPGHOME? It would help to make sure that this isn't related to your config (though I'm having trouble coming up with a scenario where that would cause this). |
Thanks @Merovius Yes, I still see the issue using the steps you outlined. I updated to go1.11 and ensured that I have the most recent x/crypto/openpgp code. As you can see, when I remove that key it works. When I add it it fails. I can produce other keys that cause failure too. Of note, I can't reproduce this on Ubuntu, but can on Debian. Not sure why as in both cases I compile go from source obtained from golang.org and use go get -u golang.org/x/crypto/openpgp $ cat /etc/issue $ gpg --list-keys
|
Just to be absolutely sure: Can you check that you run your self-built version of go (i.e. that |
@w8rbt Can you maybe upload an exported public key file which reproduces this issue? i.e. don't send it to a keyserver, but upload a single |
OK @Merovius here's a different key and the original one exported from the Debian 9 box that has the issue. Also, I am using the go binary built from golang.org on all my machines. $ which go $ go run repro.go foo.txt gpg -a --export 7D9D159F210BDF5A > keys/jerad.pub.key.asc.txt I could not upload the binary keys here, only the ASCII armored ones. jerad.pub.key.asc.txt Edit: Also, I obtained both of those from key servers in the past. If you mean a key that has never been uploaded to a key server, I can try to generate some locally and (hopefully find one that fails) and post that directly here. |
Hooray, I managed to reproduce \o/ I used this little program to strip the armor: package main
import (
"io"
"os"
"golang.org/x/crypto/openpgp/armor"
)
func main() {
b, err := armor.Decode(os.Stdin)
if err != nil {
panic(err)
}
_, err = io.Copy(os.Stdout, b.Body)
if err != nil {
panic(err)
}
} When dearmoring the keys to ~/keys, I get the same error as you. When first importing the armored keys and then exporting them without armor, I don't get the error. This seems to confirm that it's something specific to the version of gpg you are using - it seems to encode something wrongly. I can look into this a bit further now :) |
Okay, so, it seems that the key you have has an expired signature on it:
There is a second, non-expired signature after that. When reading the key, x/crypto/openpgp only uses the first signature on the key, so it only retains the expired one. gpg strips the expired signature on export, which is why importing/exporting the key repairs it. There are multiple ways we could solve this, with different implications on usability/security. The RFC recommends (last sentence in that section)
I'll send a CL to that effect, unless @FiloSottile wants to object. |
Awesome work @Merovius Thanks for taking time to look at this. |
This is the logic that was recently touched by @aviau in https://go-review.googlesource.com/c/crypto/+/118957, which quotes the very same spec snippet :) |
There is an implementation of this part of the spec in golang/crypto#57. The implementation looks good, it lacks a test. I am willing to write a test if the author does not want to. |
It looks good, happy to submit it if you chain a test CL to it and the chained CL passes tests. |
Change https://golang.org/cl/135357 mentions this issue: |
Okay, I will do that and ping you here when done. Cheers, |
Just for the record, it would've been nice to at least acknowledge that I mentioned I was going to send out a CL after I spend a bunch of time debugging this today. I was in the process of adding a test, when I saw that someone else had taken over… Yes, I know it's ultimately just less work for me. But it still doesn't send a great message. |
@Merovius I am not sure that I understand. Do you know that golang/crypto#57 was opened 14 days ago? We linked it to this issue as soon as we saw that they were related. |
D'oh, apologies, I actually didn't see that it's the same repo m( now i'm embarrassed |
We should close this as a dup of #26468 then, BTW. I already confirmed that it solves the problem by testing against a patched version. |
Rather than using the first subkey binding signature encountered, use the one with the most recent creation data, as per the recommendation from RFC 4880: > An implementation that encounters multiple self-signatures on the > same object may resolve the ambiguity in any way it sees fit, but it > is RECOMMENDED that priority be given to the most recent self- > signature. This allows subkeys to approach expiry then be re-signed with a new expiry. This extends the recent commit 0e37d00 by @aviau and @FiloSottile. Fixes golang/go#26468 Change-Id: I7f12706727373259c188bfee4254306ef9d4e935 GitHub-Last-Rev: 0da814166411a3c3334312576d3f7f8f2bba4ff4 GitHub-Pull-Request: golang/crypto#57 Reviewed-on: https://go-review.googlesource.com/135357 Reviewed-by: Filippo Valsorda <filippo@golang.org>
Rather than using the first subkey binding signature encountered, use the one with the most recent creation data, as per the recommendation from RFC 4880: > An implementation that encounters multiple self-signatures on the > same object may resolve the ambiguity in any way it sees fit, but it > is RECOMMENDED that priority be given to the most recent self- > signature. This allows subkeys to approach expiry then be re-signed with a new expiry. This extends the recent commit 0e37d00 by @aviau and @FiloSottile. Fixes golang/go#26468 Change-Id: I7f12706727373259c188bfee4254306ef9d4e935 GitHub-Last-Rev: 0da814166411a3c3334312576d3f7f8f2bba4ff4 GitHub-Pull-Request: golang/crypto#57 Reviewed-on: https://go-review.googlesource.com/135357 Reviewed-by: Filippo Valsorda <filippo@golang.org>
Rather than using the first subkey binding signature encountered, use the one with the most recent creation data, as per the recommendation from RFC 4880: > An implementation that encounters multiple self-signatures on the > same object may resolve the ambiguity in any way it sees fit, but it > is RECOMMENDED that priority be given to the most recent self- > signature. This allows subkeys to approach expiry then be re-signed with a new expiry. This extends the recent commit 0e37d00 by @aviau and @FiloSottile. Fixes golang/go#26468 Change-Id: I7f12706727373259c188bfee4254306ef9d4e935 GitHub-Last-Rev: 0da814166411a3c3334312576d3f7f8f2bba4ff4 GitHub-Pull-Request: golang/crypto#57 Reviewed-on: https://go-review.googlesource.com/135357 Reviewed-by: Filippo Valsorda <filippo@golang.org>
Rather than using the first subkey binding signature encountered, use the one with the most recent creation data, as per the recommendation from RFC 4880: > An implementation that encounters multiple self-signatures on the > same object may resolve the ambiguity in any way it sees fit, but it > is RECOMMENDED that priority be given to the most recent self- > signature. This allows subkeys to approach expiry then be re-signed with a new expiry. This extends the recent commit 0e37d00 by @aviau and @FiloSottile. Fixes golang/go#26468 Change-Id: I7f12706727373259c188bfee4254306ef9d4e935 GitHub-Last-Rev: 0da814166411a3c3334312576d3f7f8f2bba4ff4 GitHub-Pull-Request: golang/crypto#57 Reviewed-on: https://go-review.googlesource.com/135357 Reviewed-by: Filippo Valsorda <filippo@golang.org>
Rather than using the first subkey binding signature encountered, use the one with the most recent creation data, as per the recommendation from RFC 4880: > An implementation that encounters multiple self-signatures on the > same object may resolve the ambiguity in any way it sees fit, but it > is RECOMMENDED that priority be given to the most recent self- > signature. This allows subkeys to approach expiry then be re-signed with a new expiry. This extends the recent commit 8edf234 by @aviau and @FiloSottile. Fixes golang/go#26468 Change-Id: I7f12706727373259c188bfee4254306ef9d4e935 GitHub-Last-Rev: 0da814166411a3c3334312576d3f7f8f2bba4ff4 GitHub-Pull-Request: golang/crypto#57 Reviewed-on: https://go-review.googlesource.com/135357 Reviewed-by: Filippo Valsorda <filippo@golang.org>
Rather than using the first subkey binding signature encountered, use the one with the most recent creation data, as per the recommendation from RFC 4880: > An implementation that encounters multiple self-signatures on the > same object may resolve the ambiguity in any way it sees fit, but it > is RECOMMENDED that priority be given to the most recent self- > signature. This allows subkeys to approach expiry then be re-signed with a new expiry. This extends the recent commit 0e37d00 by @aviau and @FiloSottile. Fixes golang/go#26468 Change-Id: I7f12706727373259c188bfee4254306ef9d4e935 GitHub-Last-Rev: 0da8141 GitHub-Pull-Request: golang#57 Reviewed-on: https://go-review.googlesource.com/135357 Reviewed-by: Filippo Valsorda <filippo@golang.org>
What version of Go are you using (
go version
)?go version go1.10.2 linux/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?GOARCH="amd64"
GOBIN=""
GOCACHE="/home/rbt/.cache/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/rbt/go"
GORACE=""
GOROOT="/home/rbt/go1.10"
GOTMPDIR=""
GOTOOLDIR="/home/rbt/go1.10/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build778390304=/tmp/go-build -gno-record-gcc-switches"
What did you do?
I ran this program that I wrote. It encrypts a file to PGP keys, but some keys fail with the error below even though they are valid and have encryption sub-keys.
If possible, provide a recipe for reproducing the error.
What did you expect to see?
I expected the file to be encrypted. The key is valid and has an encryption sub-key. And, many other keys work just fine, but several do not.
2018/07/19 09:45:19 Using key file: /home/rbt/keys/brad.pub.key
2018/07/19 09:45:19 Using key file: /home/rbt/keys/itso.pub.key
2018/07/19 09:45:19 Using key file: /home/rbt/keys/jeff.pub.key
2018/07/19 09:45:19 Using key file: /home/rbt/keys/phil.pub.key
2018/07/19 09:45:19 Using key file: /home/rbt/keys/tester.pub.key
2018/07/19 09:45:19 Encrypting to Key FP: 83CBAF6B683329125FE436CCE915EE8B2FE6EC56
2018/07/19 09:45:19 Encrypting to Key FP: F3D2F6714EF6B251BDFF18947279C76A0FAC6413
2018/07/19 09:45:19 Encrypting to Key FP: 4952772637B2B44012070E47B87FE76E05BAA569
2018/07/19 09:45:19 Encrypting to Key FP: 5CD5EFA3E1C520B1B0EDE38C83378A94FA6C4994
2018/07/19 09:45:19 Encrypting to Key FP: E2958B99360A0F93AD440FD01E7854496A3E0199
2018/07/19 09:45:19 openpgp: invalid argument: cannot encrypt a message to key id 83378a94fa6c4994 because it has no encryption keys
What did you see instead?
openpgp: invalid argument: cannot encrypt a message to key id 83378a94fa6c4994 because it has no encryption keys
Get the key that causes the error
This is a public key on public key servers. You can download it and re-create the issue.
The text was updated successfully, but these errors were encountered: