github.com/tiagovtristao/plz@v13.4.0+incompatible/tools/release_signer/signer/signer.go (about)

     1  package signer
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/base64"
     6  	"fmt"
     7  	"io"
     8  	"os"
     9  	"strings"
    10  
    11  	"golang.org/x/crypto/openpgp"
    12  )
    13  
    14  // SignFile creates a detached ASCII-armoured signature for the given file.
    15  func SignFile(filename, output, keyring, user, password string) error {
    16  	if strings.HasPrefix(keyring, "-----BEGIN PGP") {
    17  		// Keyring is an actual key, not a file.
    18  		return signFile(filename, output, user, password, strings.NewReader(keyring))
    19  	} else if strings.HasPrefix(keyring, "LS0tLS1") {
    20  		// Keyring is a base64 encoded key
    21  		b, err := base64.StdEncoding.DecodeString(keyring)
    22  		if err != nil {
    23  			return err
    24  		}
    25  		return signFile(filename, output, user, password, bytes.NewReader(b))
    26  	}
    27  	f, err := os.Open(keyring)
    28  	if err != nil {
    29  		return err
    30  	}
    31  	defer f.Close()
    32  	return signFile(filename, output, user, password, f)
    33  }
    34  
    35  func signFile(filename, output, user, password string, keyring io.Reader) error {
    36  	entities, err := openpgp.ReadArmoredKeyRing(keyring)
    37  	if err != nil {
    38  		return err
    39  	}
    40  	signer, err := findSigningEntity(entities, user)
    41  	if err != nil {
    42  		return err
    43  	}
    44  	if err := signer.PrivateKey.Decrypt([]byte(password)); err != nil {
    45  		return err
    46  	}
    47  	w, err := os.Create(output)
    48  	if err != nil {
    49  		return err
    50  	}
    51  	defer w.Close()
    52  	f2, err := os.Open(filename)
    53  	if err != nil {
    54  		return err
    55  	}
    56  	return openpgp.ArmoredDetachSign(w, signer, f2, nil)
    57  }
    58  
    59  // findSigningEntity finds the entity in a list with the given name.
    60  func findSigningEntity(entities openpgp.EntityList, user string) (*openpgp.Entity, error) {
    61  	for _, entity := range entities {
    62  		for name, identity := range entity.Identities {
    63  			if name == user || identity.UserId.Name == user || identity.UserId.Email == user {
    64  				return entity, nil
    65  			}
    66  		}
    67  	}
    68  	return nil, fmt.Errorf("No entity found for the given user")
    69  }