-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
What I'm trying to do is programmatically generate a PGP keypair, store the private key somewhere only this program has access to write to, such as KMS or something, then use the public key. The problem I'm facing is that it seems my method of creating a key pair is not working such that it can be re-ingested by this same library.
I'm fully aware that I may be doing something wrong here, but on the off chance this is an actual error in the openpgp package I figured I might as well submit an issue.
What version of Go are you using (go version)?
go version go1.10.2 darwin/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env)?
Mac OSX
What did you do?
I'm trying to autogenerate a PGP key pair and validate the public key armored using the openpgp package in the following way:
package main
import (
"bytes"
"encoding/base64"
"fmt"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/armor"
"golang.org/x/crypto/openpgp/packet"
"log"
)
func main() {
buf := createKeyPair()
fmt.Println(buf)
encoded, err := readPGP(buf)
if err != nil {
log.Fatal(err)
}
validate(encoded)
}
func createKeyPair() *bytes.Buffer {
conf := &packet.Config{
RSABits: 2048,
}
entity, err := openpgp.NewEntity("Rick Sanchez", "Autogenerated GPG Key", "test@example.com", conf)
// TODO: Store private key somewhere safe
if err != nil {
log.Fatal(err)
}
serializedEntity := bytes.NewBuffer(nil)
entity.Serialize(serializedEntity)
buf := bytes.NewBuffer(nil)
headers := map[string]string{"Version": "GnuPG v1"}
w, err := armor.Encode(buf, openpgp.PublicKeyType, headers)
if err != nil {
log.Fatal(err)
}
_, err = w.Write(serializedEntity.Bytes())
if err != nil {
log.Fatalf("error armoring serializedEntity: %s")
}
w.Close()
return buf
}
func validate(keystring string) {
data, err := base64.StdEncoding.DecodeString(keystring)
if err != nil {
log.Fatalf("error decoding given PGP key: %s", err)
}
_, err = openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(data)))
if err != nil {
log.Fatalf("error parsing given PGP key: %s", err)
}
fmt.Println("PASSED")
}
func readPGP(armoredKey *bytes.Buffer) (string, error) {
keyReader := bytes.NewReader(armoredKey.Bytes())
entityList, err := openpgp.ReadArmoredKeyRing(keyReader)
if err != nil {
log.Fatalf("error reading armored key %s", err)
}
serializedEntity := bytes.NewBuffer(nil)
err = entityList[0].Serialize(serializedEntity)
if err != nil {
return "", fmt.Errorf("error serializing entity for file %s", err)
}
return base64.StdEncoding.EncodeToString(serializedEntity.Bytes()), nil
}
What did you expect to see?
<public key>
PASSED
What did you see instead?
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1
xsBNBFr/vScBCADL8q0l5c/H1H5cvIRRvmX0Ulw3CuVodJ8JpMUM288xlkrYRgyE
mJzGyi2puZYXz1MAeutOZQTVjCRz4ReJ0aXOposVZek5wN3Mg/KGh9P8OAZuMFVP
F/KgzWpYxxxVeIglEyka1/5b0k2nv9ypkwsmRlQ1n78hgYzNT+bFi3ElWhVcLV7s
yNV+YHh0YzRLQsR73Ip9Mi5/NbZv4YegdAVJKPAV2ab+oDYiVnatYIxePNuOeGYu
oTGh41M+luqikgryYO61Z8VkQNFf2BuFTUQdMpbH3FIVBqWFDZAJ9kzFD+mNBYeA
fgk9AvnC/fAFCJw732VjcRaeX2D5O6E+I68/ABEBAAHNN1JpY2sgU2FuY2hleiAo
QXV0b2dlbmVyYXRlZCBHUEcgS2V5KSA8dGVzdEBleGFtcGxlLmNvbT4=
=vSR7
-----END PGP PUBLIC KEY BLOCK-----
2018/05/18 22:59:03 error reading armored key unexpected EOF
exit status 1
Also, using this same createKeyPair method but just outputting it to stdout then attempting to import it to gpg (instead of this validation code) also did not work but with a different error:
$ go run gpg_test.go | gpg --import
gpg: key 962282668E9C926F: no valid user IDs
gpg: this may be caused by a missing self-signature
gpg: Total number processed: 1
gpg: w/o user IDs: 1