Skip to content

Instantly share code, notes, and snippets.

@harshavardhana harshavardhana/main.go forked from FZambia/main.go
Created Aug 7, 2017

Embed
What would you like to do?
Verify armored GPG signature using Go language
package main
import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
"golang.org/x/crypto/openpgp/armor"
"golang.org/x/crypto/openpgp/packet"
)
var publicKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: GPGTools - https://gpgtools.org
mQENBFeXWTMBCAC++Yoc5IkDhWBHYOki7JaRCVwg++zWDP+hxoqEJhx1MjrDrSLH
AfmkagjmFY4phtXgDxnFx2MDgZ1ud8YV+YrRaOUQuKPjXlWCSG7CopqGGse+RvSk
3ic5ptqRBDyJ1qvHzCVNv/iMcaO1t7qmETBhkgIiBVRNiyaWi2bhqZvIQuyJn+0Y
LZEI9+ky4y07I4oMTZC2eFByTaAiiL4Xxg0U+MjCJyq4l+W0qJ8mfKJ8nh3NmgN7
MmZL+Cr2SLYZXcrS3/WwMGtDuwNXcEoBNqKDZtXNZTmFvr7KuzpKfp/G1JFGCWRA
wr882hOY0bJQhaWhtXiP185rrDHNxJROk3ELABEBAAG0JUFsZXhhbmRyIEVtZWxp
biA8ZW1lbGluQGNvcnAubWFpbC5ydT6JATcEEwEKACEFAleXWTMCGwMFCwkIBwMF
FQoJCAsFFgIDAQACHgECF4AACgkQ2xG6dGflDRk2fAgAkB//zbcY5bSLVBtBBMXk
ezImoA6U4TX6Kp4+nuB2IXrDreQJGC55oxWuoKOyM6oTmSLRKr5O/U70869W+9Mc
cPeV95W0Fh9RVtdWDOWjgWoMud70+lftIpRPoHwC2pN/M1ehvR4cKSkODOp10KBa
PQk+7E079NW53HeL27WcOeG8XW7xacdOq/sF8t/0UNlCLVkv4DujQPjtCfqZuKex
XppXjogaGo9I/032oGZ2xejVHhgSldAKJrDsi3GmLgcFHQYJwVkihxXbWN5C8onp
bqxIjR0guP8/BrXFh5QuC4F3N0nwdb1UyLW4bSWXf/xmmB/Ul7tioFiB1P8D/vEu
77kBDQRXl1kzAQgAzGdeOGrIBA19CvWFSdAvr5fZMC9jVca1k21xsaD/AxoM+IXE
kg+I7AL/g5BtGG/7h+lJcxWvUVIw5ijClmokIIh6YgoolHitkS3SQN/DG+NadcNt
TmK15wlICr8M4ahr4RyeJLGMBRt6Ew21gJgVtaroDuFozSQT181/2nYNUrqg+fXY
1p8q06p5IIz4mVLHFJ0Q+w3KXOoIjj4Ekcfh03ttJaNCKgeXeHivZ2ypTxGd34lo
nQrw4c7NvPqZYPr+0alvakq/y7jteCjVrPxhV0M1+JDjjrKoBUCchuhVIco+Irr1
J3CsHJjkx2h3QOdB+uFGZiSJAvtLq9TQA4MP8QARAQABiQEfBBgBCgAJBQJXl1kz
AhsMAAoJENsRunRn5Q0ZJMcH/RmNRH1w8cwHR+xsACU0Jp6vPPHyX0h6H3UZtJRg
qtDTL/K7R89LFdkGyp3qPraCSQGJfqKlaXjkrKaTNTHHQjDk6KTwl/ksWOkTY8Pc
iACS8wyroFntZX/2vd1Og6n7QY88gKXaEt04ZSue+z5rsqqIM7FeorB/3x8VhbLY
fqjPmKAhjOJ6LZY8kzar1SF2u4d2RvE3OuNIL+5DGTZQN7WEknnrc7DG7tChstij
FLNqzPVkYKNy/dkM0dqmbedmyNGW7gsJJiJP5/HNM5AuvxcvQLosevUiog0UczvJ
RU+3HpkK0754mIV/QrJg7Xb0pzkbtzhKMq3vwXmko4kAH2Q=
=G/wh
-----END PGP PUBLIC KEY BLOCK-----`
func checkSign(fileName, signatureFileName string) error {
fileContent, err := ioutil.ReadFile(fileName)
if err != nil {
return err
}
// Get a Reader for the signature file
sigFile, err := os.Open(signatureFileName)
if err != nil {
return err
}
defer func() {
if err := sigFile.Close(); err != nil {
panic(err)
}
}()
// Decode armored signature file
block, err := armor.Decode(sigFile)
if err != nil {
return fmt.Errorf("error decoding signature file: %s", err)
}
if block.Type != "PGP SIGNATURE" {
return errors.New("not an armored signature")
}
// Read signature body
pack, err := packet.Read(block.Body)
if err != nil {
return fmt.Errorf("error reading signature file: %s", err)
}
// Was it really a signature file ? If yes, get the Signature
signature, ok := pack.(*packet.Signature)
if !ok {
return errors.New("not a valid signature file")
}
// Decode armored public key
block, err = armor.Decode(bytes.NewReader([]byte(publicKey)))
if err != nil {
return fmt.Errorf("error decoding public key: %s", err)
}
if block.Type != "PGP PUBLIC KEY BLOCK" {
return errors.New("not an armored public key")
}
// Read the key
pack, err = packet.Read(block.Body)
if err != nil {
return fmt.Errorf("error reading public key: %s", err)
}
// Was it really a public key file ? If yes, get the PublicKey
publicKey, ok := pack.(*packet.PublicKey)
if !ok {
return errors.New("invalid public key")
}
// Get the hash method used for the signature
hash := signature.Hash.New()
// Hash the content of the file (if the file is big, that's where you have to change the code to avoid getting the whole file in memory, by reading and writting in small chunks)
_, err = hash.Write(fileContent)
if err != nil {
return err
}
// Check the signature
err = publicKey.VerifySignature(hash, signature)
if err != nil {
return err
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.