Skip to content

x/crypto/openpgp: Treat PubKeyAlgoRSA and PubKeyAlgoRSASignOnly as equivalent for signatures #27888

@Merovius

Description

@Merovius

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

go version go1.11 linux/amd64

Also golang/crypto@0e37d00

Does this issue reproduce with the latest release?

yes.

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

GOARCH="amd64"
GOOS="linux"

What did you do?

This program is a slightly modified version of TestRSAPrivateKey using NewSignerPrivateKey:

package main

import (
	"crypto"
	"crypto/rsa"
	"crypto/x509"
	"encoding/hex"
	"hash"
	"time"

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

func main() {
	privKeyDER, _ := hex.DecodeString(pkcs1PrivKeyHex)
	rsaPriv, err := x509.ParsePKCS1PrivateKey(privKeyDER)
	if err != nil {
		panic(err)
	}

	priv := packet.NewSignerPrivateKey(time.Now(), &rsaSigner{*rsaPriv})

	sig := &packet.Signature{
		PubKeyAlgo: packet.PubKeyAlgoRSA,
		Hash:       crypto.SHA256,
	}
	msg := []byte("Hello World!")

	h, err := populateHash(sig.Hash, msg)
	if err != nil {
		panic(err)
	}
	if err := sig.Sign(h, priv, nil); err != nil {
		panic(err)
	}

	if h, err = populateHash(sig.Hash, msg); err != nil {
		panic(err)
	}
	if err := priv.VerifySignature(h, sig); err != nil {
		panic(err)
	}
}

type rsaSigner struct {
	rsa.PrivateKey
}

func (s *rsaSigner) Public() crypto.PublicKey {
	return s.PublicKey
}

func populateHash(hashFunc crypto.Hash, msg []byte) (hash.Hash, error) {
	h := hashFunc.New()
	if _, err := h.Write(msg); err != nil {
		return nil, err
	}
	return h, nil
}

const pkcs1PrivKeyHex = "3082025d02010002818100e98edfa1c3b35884a54d0b36a6a603b0290fa85e49e30fa23fc94fef9c6790bc4849928607aa48d809da326fb42a969d06ad756b98b9c1a90f5d4a2b6d0ac05953c97f4da3120164a21a679793ce181c906dc01d235cc085ddcdf6ea06c389b6ab8885dfd685959e693138856a68a7e5db263337ff82a088d583a897cf2d59e9020301000102818100b6d5c9eb70b02d5369b3ee5b520a14490b5bde8a317d36f7e4c74b7460141311d1e5067735f8f01d6f5908b2b96fbd881f7a1ab9a84d82753e39e19e2d36856be960d05ac9ef8e8782ea1b6d65aee28fdfe1d61451e8cff0adfe84322f12cf455028b581cf60eb9e0e140ba5d21aeba6c2634d7c65318b9a665fc01c3191ca21024100fa5e818da3705b0fa33278bb28d4b6f6050388af2d4b75ec9375dd91ccf2e7d7068086a8b82a8f6282e4fbbdb8a7f2622eb97295249d87acea7f5f816f54d347024100eecf9406d7dc49cdfb95ab1eff4064de84c7a30f64b2798936a0d2018ba9eb52e4b636f82e96c49cc63b80b675e91e40d1b2e4017d4b9adaf33ab3d9cf1c214f024100c173704ace742c082323066226a4655226819a85304c542b9dacbeacbf5d1881ee863485fcf6f59f3a604f9b42289282067447f2b13dfeed3eab7851fc81e0550240741fc41f3fc002b382eed8730e33c5d8de40256e4accee846667f536832f711ab1d4590e7db91a8a116ac5bff3be13d3f9243ff2e976662aa9b395d907f8e9c9024046a5696c9ef882363e06c9fa4e2f5b580906452befba03f4a99d0f873697ef1f851d2226ca7934b30b7c3e80cb634a67172bbbf4781735fe3e09263e2dd723e7"

What did you expect to see?

No output.

What did you see instead?

panic: openpgp: invalid argument: public key and signature use different algorithms

goroutine 1 [running]:
main.main()
	/home/mero/tmp/rsa.go:41 +0x341
exit status 2

NewSignerPrivateKey sets the signature algorithm to RSASignOnly, which is unequal to RSA, causing the signature verification to fail. I have a fix prepared, this is just to track the issue.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions