github.phpd.cn/thought-machine/please@v12.2.0+incompatible/tools/release_signer/signer/signer.go (about)

     1  package signer
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  
     7  	"golang.org/x/crypto/openpgp"
     8  )
     9  
    10  // SignFile creates a detached ASCII-armoured signature for the given file.
    11  func SignFile(filename, output, keyring, user, password string) error {
    12  	f, err := os.Open(keyring)
    13  	if err != nil {
    14  		return err
    15  	}
    16  	defer f.Close()
    17  	entities, err := openpgp.ReadArmoredKeyRing(f)
    18  	if err != nil {
    19  		return err
    20  	}
    21  	signer, err := findSigningEntity(entities, user)
    22  	if err != nil {
    23  		return err
    24  	}
    25  	if err := signer.PrivateKey.Decrypt([]byte(password)); err != nil {
    26  		return err
    27  	}
    28  	w, err := os.Create(output)
    29  	if err != nil {
    30  		return err
    31  	}
    32  	defer w.Close()
    33  	f2, err := os.Open(filename)
    34  	if err != nil {
    35  		return err
    36  	}
    37  	return openpgp.ArmoredDetachSign(w, signer, f2, nil)
    38  }
    39  
    40  // findSigningEntity finds the entity in a list with the given name.
    41  func findSigningEntity(entities openpgp.EntityList, user string) (*openpgp.Entity, error) {
    42  	for _, entity := range entities {
    43  		for name, identity := range entity.Identities {
    44  			if name == user || identity.UserId.Name == user || identity.UserId.Email == user {
    45  				return entity, nil
    46  			}
    47  		}
    48  	}
    49  	return nil, fmt.Errorf("No entity found for the given user")
    50  }