func (g *GoVerifier) AddKeyring(keyring string) {
	g.keyRingFiles = append(g.keyRingFiles, keyring)
}
AddKeyring adds custom keyrings to the list
package pgp
import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"syscall"
	"time"
	"github.com/pkg/errors"
	"golang.org/x/crypto/openpgp"
	"golang.org/x/crypto/openpgp/clearsign"
	openpgp_errors "golang.org/x/crypto/openpgp/errors"
	"golang.org/x/crypto/openpgp/packet"
	"golang.org/x/crypto/ssh/terminal"
)
var (
	_ Signer   = &GoSigner{}
	_ Verifier = &GoVerifier{}
)
var (
	errWrongPassphrase = errors.New("unable to decrypt the key, passphrase is wrong")
)
type GoSigner struct {
	keyRef                         string
	keyringFile, secretKeyringFile string
	passphrase, passphraseFile     string
	batch                          bool
	publicKeyring openpgp.EntityList
	secretKeyring openpgp.EntityList
	signer        *openpgp.Entity
	signerConfig  *packet.Config
}
func (g *GoSigner) SetBatch(batch bool) {
	g.batch = batch
}
func (g *GoSigner) SetKey(keyRef string) {
	g.keyRef = keyRef
}
func (g *GoSigner) SetKeyRing(keyring, secretKeyring string) {
	g.keyringFile, g.secretKeyringFile = keyring, secretKeyring
}
func (g *GoSigner) SetPassphrase(passphrase, passphraseFile string) {
	g.passphrase, g.passphraseFile = passphrase, passphraseFile
}
func (g *GoSigner) Init() error {
	g.signerConfig = &packet.Config{
		DefaultCompressionAlgo: packet.CompressionZLIB,
		CompressionConfig: &packet.CompressionConfig{
			Level: 9,
		},
	}
	if g.passphraseFile != "" {
		passF, err := os.Open(g.passphraseFile)
		if err != nil {
			return errors.Wrap(err, "error opening passphrase file")
		}
		defer passF.Close()
		contents, err := ioutil.ReadAll(passF)
		if err != nil {
			return errors.Wrap(err, "error reading passphrase file")
		}
		g.passphrase = strings.TrimSpace(string(contents))
	}
	if g.keyringFile == "" {
		g.keyringFile = "pubring.gpg"
	}
	if g.secretKeyringFile == "" {
		g.secretKeyringFile = "secring.gpg"
	}
	var err error
	g.publicKeyring, err = loadKeyRing(g.keyringFile, false)
	if err != nil {
		return errors.Wrap(err, "error loading public keyring")
	}
	g.secretKeyring, err = loadKeyRing(g.secretKeyringFile, false)
	if err != nil {
		return errors.Wrap(err, "error load secret keyring")
	}
	if g.keyRef == "" {
		for _, signer := range g.secretKeyring {
			if !validEntity(signer) {
				continue
			}
			g.signer = signer
			break
		}
		if g.signer == nil {
			return fmt.Errorf("looks like there are no keys in gpg, please create one (official manual: http://www.gnupg.org/gph/en/manual.html)")
		}
	} else {
	pickKeyLoop:
		for _, signer := range g.secretKeyring {
			key := KeyFromUint64(signer.PrimaryKey.KeyId)
			if key.Matches(Key(g.keyRef)) {
				g.signer = signer
				break
			}
			if !validEntity(signer) {
				continue
			}
			for name := range signer.Identities {
				if strings.Contains(name, g.keyRef) {
					g.signer = signer
					break pickKeyLoop
				}
			}
		}
		if g.signer == nil {
			return errors.Errorf("couldn't find key for key reference %v", g.keyRef)
		}
	}
	if g.signer.PrivateKey.Encrypted {
		i := 0
		for name := range g.signer.Identities {
			if i == 0 {
				fmt.Printf("openpgp: Passphrase is required to unlock private key \"%s\"\n", name)
			} else {
				fmt.Printf("                         				          aka \"%s\"\n", name)
			}
			i++
		}
		fmt.Printf("openpgp: %s-bit %s key, ID %s, created %s\n",
			keyBits(g.signer.PrimaryKey.PublicKey),
			pubkeyAlgorithmName(g.signer.PrimaryKey.PubKeyAlgo),
			KeyFromUint64(g.signer.PrimaryKey.KeyId),
			g.signer.PrimaryKey.CreationTime.Format("2006-01-02"))
		if g.passphrase == "" {
			if g.batch {
				return errors.New("key is locked with passphrase, but no passphrase was given in batch mode")
			}
			for attempt := 0; attempt < 3; attempt++ {
				fmt.Print("\nEnter passphrase: ")
				var bytePassphrase []byte
				bytePassphrase, err = terminal.ReadPassword(int(syscall.Stdin))
				if err != nil {
					return errors.Wrap(err, "error reading passphare")
				}
				g.passphrase = string(bytePassphrase)
				err = g.decryptKey()
				if err == nil || err != errWrongPassphrase {
					break
				}
				fmt.Print("\nWrong passphrase, please try again.\n")
			}
		} else {
			err = g.decryptKey()
		}
		if err != nil {
			return err
		}
	}
	return nil
}
func (g *GoSigner) decryptKey() error {
	err := g.signer.PrivateKey.Decrypt([]byte(g.passphrase))
	if err == nil {
		return nil
	}
	if e, ok := err.(openpgp_errors.StructuralError); ok {
		if string(e) == "private key checksum failure" {
			return errWrongPassphrase
		}
	}
	return errors.Wrap(err, "error unlocking private key")
}
func (g *GoSigner) DetachedSign(source string, destination string) error {
	fmt.Printf("openpgp: signing file '%s'...\n", filepath.Base(source))
	message, err := os.Open(source)
	if err != nil {
		return errors.Wrap(err, "error opening source file")
	}
	defer message.Close()
	signature, err := os.Create(destination)
	if err != nil {
		return errors.Wrap(err, "error creating signature file")
	}
	defer signature.Close()
	err = openpgp.ArmoredDetachSign(signature, g.signer, message, g.signerConfig)
	if err != nil {
		return errors.Wrap(err, "error creating detached signature")
	}
	return nil
}
func (g *GoSigner) ClearSign(source string, destination string) error {
	fmt.Printf("openpgp: clearsigning file '%s'...\n", filepath.Base(source))
	message, err := os.Open(source)
	if err != nil {
		return errors.Wrap(err, "error opening source file")
	}
	defer message.Close()
	clearsigned, err := os.Create(destination)
	if err != nil {
		return errors.Wrap(err, "error creating clearsigned file")
	}
	defer clearsigned.Close()
	stream, err := clearsign.Encode(clearsigned, g.signer.PrivateKey, g.signerConfig)
	if err != nil {
		return errors.Wrap(err, "error initializing clear signer")
	}
	_, err = io.Copy(stream, message)
	if err != nil {
		stream.Close()
		return errors.Wrap(err, "error generating clearsigned signature")
	}
	err = stream.Close()
	if err != nil {
		return errors.Wrap(err, "error generating clearsigned signature")
	}
	return nil
}
type GoVerifier struct {
	keyRingFiles []string
	trustedKeyring openpgp.EntityList
}
func (g *GoVerifier) InitKeyring() error {
	var err error
	if len(g.keyRingFiles) == 0 {
		g.trustedKeyring, err = loadKeyRing("trustedkeys.gpg", true)
		if err != nil {
			return errors.Wrap(err, "failure loading trustedkeys.gpg keyring")
		}
	} else {
		for _, file := range g.keyRingFiles {
			var keyring openpgp.EntityList
			keyring, err = loadKeyRing(file, false)
			if err != nil {
				return errors.Wrapf(err, "failure loading %s keyring", file)
			}
			g.trustedKeyring = append(g.trustedKeyring, keyring...)
		}
	}
	if len(g.trustedKeyring) == 0 {
		fmt.Printf("\nLooks like your keyring with trusted keys is empty. You might consider importing some keys.\n")
		if len(g.keyRingFiles) == 0 {
			fmt.Printf("If you're running Debian or Ubuntu, it's a good idea to import current archive keys by running:\n\n")
			fmt.Printf("  gpg --no-default-keyring --keyring /usr/share/keyrings/debian-archive-keyring.gpg --export | gpg --no-default-keyring --keyring trustedkeys.gpg --import\n")
			fmt.Printf("\n(for Ubuntu, use /usr/share/keyrings/ubuntu-archive-keyring.gpg)\n\n")
		}
	}
	return nil
}