github.com/hashicorp/terraform-plugin-sdk@v1.17.2/internal/vault/helper/pgpkeys/encrypt_decrypt.go (about) 1 package pgpkeys 2 3 import ( 4 "bytes" 5 "encoding/base64" 6 "fmt" 7 8 "github.com/hashicorp/errwrap" 9 "github.com/keybase/go-crypto/openpgp" 10 "github.com/keybase/go-crypto/openpgp/packet" 11 ) 12 13 // EncryptShares takes an ordered set of byte slices to encrypt and the 14 // corresponding base64-encoded public keys to encrypt them with, encrypts each 15 // byte slice with the corresponding public key. 16 // 17 // Note: There is no corresponding test function; this functionality is 18 // thoroughly tested in the init and rekey command unit tests 19 func EncryptShares(input [][]byte, pgpKeys []string) ([]string, [][]byte, error) { 20 if len(input) != len(pgpKeys) { 21 return nil, nil, fmt.Errorf("mismatch between number items to encrypt and number of PGP keys") 22 } 23 encryptedShares := make([][]byte, 0, len(pgpKeys)) 24 entities, err := GetEntities(pgpKeys) 25 if err != nil { 26 return nil, nil, err 27 } 28 for i, entity := range entities { 29 ctBuf := bytes.NewBuffer(nil) 30 pt, err := openpgp.Encrypt(ctBuf, []*openpgp.Entity{entity}, nil, nil, nil) 31 if err != nil { 32 return nil, nil, errwrap.Wrapf("error setting up encryption for PGP message: {{err}}", err) 33 } 34 _, err = pt.Write(input[i]) 35 if err != nil { 36 return nil, nil, errwrap.Wrapf("error encrypting PGP message: {{err}}", err) 37 } 38 pt.Close() 39 encryptedShares = append(encryptedShares, ctBuf.Bytes()) 40 } 41 42 fingerprints, err := GetFingerprints(nil, entities) 43 if err != nil { 44 return nil, nil, err 45 } 46 47 return fingerprints, encryptedShares, nil 48 } 49 50 // GetFingerprints takes in a list of openpgp Entities and returns the 51 // fingerprints. If entities is nil, it will instead parse both entities and 52 // fingerprints from the pgpKeys string slice. 53 func GetFingerprints(pgpKeys []string, entities []*openpgp.Entity) ([]string, error) { 54 if entities == nil { 55 var err error 56 entities, err = GetEntities(pgpKeys) 57 58 if err != nil { 59 return nil, err 60 } 61 } 62 ret := make([]string, 0, len(entities)) 63 for _, entity := range entities { 64 ret = append(ret, fmt.Sprintf("%x", entity.PrimaryKey.Fingerprint)) 65 } 66 return ret, nil 67 } 68 69 // GetEntities takes in a string array of base64-encoded PGP keys and returns 70 // the openpgp Entities 71 func GetEntities(pgpKeys []string) ([]*openpgp.Entity, error) { 72 ret := make([]*openpgp.Entity, 0, len(pgpKeys)) 73 for _, keystring := range pgpKeys { 74 data, err := base64.StdEncoding.DecodeString(keystring) 75 if err != nil { 76 return nil, errwrap.Wrapf("error decoding given PGP key: {{err}}", err) 77 } 78 entity, err := openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(data))) 79 if err != nil { 80 return nil, errwrap.Wrapf("error parsing given PGP key: {{err}}", err) 81 } 82 ret = append(ret, entity) 83 } 84 return ret, nil 85 }