github.phpd.cn/thought-machine/please@v12.2.0+incompatible/src/update/verify.go (about)

     1  // +build !bootstrap
     2  
     3  package update
     4  
     5  import (
     6  	"bytes"
     7  	"io"
     8  	"io/ioutil"
     9  
    10  	"golang.org/x/crypto/openpgp"
    11  )
    12  
    13  // identity is the signing identity of this key.
    14  const identity = "Please Releases <releases@please.build>"
    15  
    16  // verifySignature verifies an OpenPGP detached signature of a file.
    17  // It returns true if the signature is correct according to our key.
    18  func verifySignature(signed, signature io.Reader) bool {
    19  	entities, err := openpgp.ReadArmoredKeyRing(bytes.NewReader(MustAsset("pubkey.gpg.asc")))
    20  	if err != nil {
    21  		log.Fatalf("%s", err) // Shouldn't happen
    22  	}
    23  	signer, err := openpgp.CheckArmoredDetachedSignature(entities, signed, signature)
    24  	if err != nil {
    25  		log.Error("Bad signature: %s", err)
    26  		return false
    27  	}
    28  	log.Notice("Good signature from %s", signer.Identities[identity].UserId.Email)
    29  	return true
    30  }
    31  
    32  // verifyDownload fetches a detached signature for a download and verifies it's OK.
    33  // It returns a reader to the verified content.
    34  func verifyDownload(signed io.Reader, url string) io.Reader {
    35  	signature := mustDownload(url+".asc", false)
    36  	defer signature.Close()
    37  	return mustVerifySignature(signed, signature)
    38  }
    39  
    40  // mustVerifySignature verifies an OpenPGP detached signature of a file.
    41  // It panics if the signature is not correct.
    42  // On success it returns an equivalent reader to the original.
    43  func mustVerifySignature(signed, signature io.Reader) io.Reader {
    44  	// We need to be able to reuse the body again afterwards so we have to
    45  	// download the original into a buffer.
    46  	b, err := ioutil.ReadAll(signed)
    47  	if err != nil {
    48  		panic(err)
    49  	}
    50  	log.Notice("Verifying signature of downloaded tarball...")
    51  	if !verifySignature(bytes.NewReader(b), signature) {
    52  		panic("Invalid signature on downloaded file, possible tampering; will not continue.")
    53  	}
    54  	return bytes.NewReader(b)
    55  }