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: Cannot encrypt with ECDSA #30388

Closed
ghost opened this issue Feb 25, 2019 · 7 comments
Closed

x/crypto/openpgp: Cannot encrypt with ECDSA #30388

ghost opened this issue Feb 25, 2019 · 7 comments
Labels
ExpertNeeded FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@ghost
Copy link

ghost commented Feb 25, 2019

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

$ go version
go version go1.11 darwin/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
GOARCH="amd64"
GOBIN="/Users/samuel/Documents/code/go/bin"
GOCACHE="/Users/samuel/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/samuel/Documents/code/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/Cellar/go/1.11/libexec"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.11/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
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 -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/nh/t0dtwkp10y972qpr3jck0wnw0000gn/T/go-build798446226=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

I created a ECDSA key based on the crypto/elliptic package.
Then I used it with openpgp: packet.NewECDSAPrivateKey(time.Now(), key)
Then I created an entity

e := &openpgp.Entity{
	PrivateKey: pv,
	PrimaryKey: &pv.PublicKey,
	Identities: map[string]*openpgp.Identity{},
}
isPrimary := true
uid := packet.NewUserId("sam", "", "")
e.Identities[uid.Id] = &openpgp.Identity{
	Name:   uid.Id,
	UserId: uid,
	SelfSignature: &packet.Signature{
		CreationTime: time.Now(),
		PubKeyAlgo:   packet.PubKeyAlgoECDSA,
		IsPrimaryId:  &isPrimary,
		IssuerKeyId:  &e.PrimaryKey.KeyId,
		Hash:         crypto.SHA256,
	},
}
e.Identities[uid.Id].SelfSignature.SignUserId(uid.Id, e.PrimaryKey, e.PrivateKey, nil)

Then I tried to encrypt using this entity

buf := new(bytes.Buffer)
res, err := openpgp.Encrypt(buf, []*openpgp.Entity{e}, nil, nil, nil)
if err != nil {
	log.Fatal(err)
}
res.Write([]byte("Hello"))
res.Close()

And I got this error: openpgp: unsupported feature: encrypting a key to public key of type 19

After searching in the codebase, I found that Encrypt call the method SerializeEncryptedKey which not handle ECDSA keys

switch pub.PubKeyAlgo {
	case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly:
		return serializeEncryptedKeyRSA(w, config.Random(), buf, pub.PublicKey.(*rsa.PublicKey), keyBlock)
	case PubKeyAlgoElGamal:
		return serializeEncryptedKeyElGamal(w, config.Random(), buf, pub.PublicKey.(*elgamal.PublicKey), keyBlock)
	case PubKeyAlgoDSA, PubKeyAlgoRSASignOnly:
		return errors.InvalidArgumentError("cannot encrypt to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo)))
	}

	return errors.UnsupportedError("encrypting a key to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo)))
@gopherbot gopherbot added this to the Unreleased milestone Feb 25, 2019
@bcmills
Copy link
Contributor

bcmills commented Feb 25, 2019

CC @bradfitz @FiloSottile @agl for x/crypto/openpgp

(See also the lengthy discussion of the future of openpgp in #30141.)

@antong
Copy link
Contributor

antong commented Feb 25, 2019

DSA stands for Digital Signature Algorithm. You can only sign with it, not encrypt, if I don't misunderstand the issue.

@ghost
Copy link
Author

ghost commented Feb 25, 2019

We can make some encryption with ECC.
By example using gpg2 tool we can encrypt using an elliptic curve. So why the encrypt method of openpgp does not support?

@antong
Copy link
Contributor

antong commented Feb 26, 2019

@samuel-uniris , I don't think even gpg will accept a key such as the one you made in your example code. You can add code to write out the public key, import it in gpg and see what it says. It is true that there there are specifications for encrypting with ECC in OpenPGP (RFC6637). I'm no expert, but I couldn't find a way to do this with x/crypto/openpgp (see my attempt: #22015 (comment)).

Can you tell a bit more about what you are trying to achieve? Do you need to interoperate with PGP, or do you just need to encrypt messages or files within your application or system? In case you don't need to interoperate with PGP, there are more modern libraries that are much easier and safer to use. See for instance nacl/box or saltpack.

@ghost
Copy link
Author

ghost commented Feb 26, 2019

Actually I implemented an ECIES using ECDSA with x509 standard and wanted to do the same with OpenPGP standard . But maybe the lib is outdated or no Gpg2 compliant.

@Merovius
Copy link
Contributor

It might be interesting to have this. If I find the time, I might have a go. Though right now it's not quite clear how that works - AIUI the question of maintainership of x/crypto/openpgp isn't fully settled.

@bcmills bcmills added ExpertNeeded NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Feb 28, 2019
@FiloSottile
Copy link
Contributor

Per the accepted #44226 proposal and due to lack of maintenance, the golang.org/x/crypto/openpgp package is now frozen and deprecated. No new changes will be accepted except for security fixes. The package will not be removed.

If this is a security issue, please email security@golang.org and we will assess it and provide a fix.

If you're looking for alternatives, consider the crypto/ed25519 package for simple signatures, golang.org/x/mod/sumdb/note for inline signatures, or filippo.io/age for encryption. You can read a summary of OpenPGP issues and alternatives here.

If you are required to interoperate with OpenPGP systems and need a maintained package, we suggest considering one of multiple community forks of golang.org/x/crypto/openpgp. We don't endorse any specific one.

@golang golang locked and limited conversation to collaborators Mar 29, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
ExpertNeeded FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants