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

x/crypto/openpgp: infinite loop on unknown cipher type / key #28786

Open
jdevelop opened this issue Nov 14, 2018 · 2 comments
Open

x/crypto/openpgp: infinite loop on unknown cipher type / key #28786

jdevelop opened this issue Nov 14, 2018 · 2 comments
Labels
Milestone

Comments

@jdevelop
Copy link

jdevelop commented Nov 14, 2018

What version of Go are you using (go version)?

go version go1.11.2 linux/amd64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env

go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/user/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/user/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/lib/go"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
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-build954256754=/tmp/go-build -gno-record-gcc-switches"

What did you do?

A simple test case to illustrate the problem:

package main

import (
	"bytes"
	"errors"
	"io"
	"io/ioutil"
	"testing"

	"golang.org/x/crypto/openpgp"
)

const (
	pass      = "passwordok"
	wrongPass = "passwordfailed"
	message   = "hello world"
)

var noSymmetric = errors.New("Symmetric not set")

func TestHelloWorld(t *testing.T) {
	var out = bytes.Buffer{}
	var in = bytes.NewReader([]byte(message))
	w, err := openpgp.SymmetricallyEncrypt(&out, []byte(pass), nil, nil)
	if err != nil {
		t.Fatal(err)
	}
	if _, err = io.Copy(w, in); err != nil {
		t.Fatal(err)
	}
	if err := w.Close(); err != nil {
		t.Fatal(err)
	}

	encryptedSrc := bytes.NewReader(out.Bytes())

	md, err := openpgp.ReadMessage(encryptedSrc, nil, func(keys []openpgp.Key, symmetric bool) ([]byte, error) {
		if !symmetric {
			return nil, noSymmetric
		}
		return []byte(wrongPass), nil
	}, nil)
	if err != nil {
		t.Fatal(err)
	}
	content, err := ioutil.ReadAll(md.UnverifiedBody)
	if err != nil {
		t.Fatal(err)
	}
	if string(content) != message {
		t.Fatalf("Expected %s actual %s", message, content)
	}
}

What did you expect to see?

An error should be returned from ReadMessage

What did you see instead?

An infinite loop.

@gopherbot gopherbot added this to the Unreleased milestone Nov 14, 2018
@gopherbot
Copy link

Change https://golang.org/cl/149677 mentions this issue: x/crypto: fix infinite loop on unknown cipher type / key

@FiloSottile FiloSottile changed the title x/crypto: infinite loop on unknown cipher type / key x/crypto/openpgp: infinite loop on unknown cipher type / key Feb 9, 2019
@sashabaranov
Copy link

For me solution was to modify prompt function to return key only once, and when called second time return error.

This approach is inspired by openpgp's test suite: https://github.com/golang/crypto/blob/master/openpgp/read_test.go#L258

uwehdaub pushed a commit to uwehdaub/sops that referenced this issue Jul 8, 2020
This fixes getsops#665
See also golang/go#28786

In some strange situations it can happen, that openpgp.ReadMessage()
runs into a endless loop. This seems to be triggered by a slightly
inconsistency in key settings.
It happened to me, but I wasn't able to reproduce it with a fresh key.
A proposed solution from the x/crypto community was, to break this loop
in the callback passphrasePrompt.
autrilla pushed a commit to getsops/sops that referenced this issue Jul 14, 2020
* Fix tests

* Fix endless loop in x/crypto/openpgp func ReadMessage

This fixes #665
See also golang/go#28786

In some strange situations it can happen, that openpgp.ReadMessage()
runs into a endless loop. This seems to be triggered by a slightly
inconsistency in key settings.
It happened to me, but I wasn't able to reproduce it with a fresh key.
A proposed solution from the x/crypto community was, to break this loop
in the callback passphrasePrompt.

* Revert "Fix tests"

This reverts commit 285f4dc.

* Improve error description

#690 (comment)
clelange pushed a commit to clelange/sops that referenced this issue Jul 19, 2020
* Fix tests

* Fix endless loop in x/crypto/openpgp func ReadMessage

This fixes getsops#665
See also golang/go#28786

In some strange situations it can happen, that openpgp.ReadMessage()
runs into a endless loop. This seems to be triggered by a slightly
inconsistency in key settings.
It happened to me, but I wasn't able to reproduce it with a fresh key.
A proposed solution from the x/crypto community was, to break this loop
in the callback passphrasePrompt.

* Revert "Fix tests"

This reverts commit 285f4dc.

* Improve error description

getsops#690 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants