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 }