func fetchKeyPairs(k *registry.Keypairs, orgID *identity.ID) (
	*identity.ID, *identity.ID, *crypto.KeyPairs, error) {
	enc, err := k.Select(orgID, primitive.EncryptionKeyType)
	if err != nil {
		return nil, nil, nil, err
	}
	sig, err := k.Select(orgID, primitive.SigningKeyType)
	if err != nil {
		return nil, nil, nil, err
	}
	kp := bundleKeypairs(sig, enc)
	return sig.PublicKey.ID, enc.PublicKey.ID, kp, nil
}
fetchKeyPairs fetches and bundles the user's signing and encryption keypairs
from the given keypairs struct
package logic
import (
	"context"
	"encoding/json"
	"log"
	"strconv"
	"time"
	"golang.org/x/crypto/ed25519"
	"github.com/manifoldco/go-base64"
	"github.com/manifoldco/torus-cli/apitypes"
	"github.com/manifoldco/torus-cli/envelope"
	"github.com/manifoldco/torus-cli/identity"
	"github.com/manifoldco/torus-cli/primitive"
	"github.com/manifoldco/torus-cli/registry"
	"github.com/manifoldco/torus-cli/daemon/crypto"
	"github.com/manifoldco/torus-cli/daemon/crypto/secure"
	"github.com/manifoldco/torus-cli/daemon/session"
)
func packageSigningKeypair(ctx context.Context, c *crypto.Engine, authID, orgID *identity.ID,
	kp *crypto.KeyPairs) (*envelope.PublicKey, *envelope.PrivateKey, error) {
	pubsig, err := packagePublicKey(ctx, c, authID, orgID,
		primitive.SigningKeyType, kp.Signature.Public, nil, &kp.Signature)
	if err != nil {
		return nil, nil, err
	}
	privsig, err := packagePrivateKey(ctx, c, authID, orgID, kp.Signature.PNonce,
		kp.Signature.Private, pubsig.ID, pubsig.ID, &kp.Signature)
	if err != nil {
		return nil, nil, err
	}
	return pubsig, privsig, nil
}
func packageEncryptionKeypair(ctx context.Context, c *crypto.Engine, authID, orgID *identity.ID,
	kp *crypto.KeyPairs, pubsig *envelope.PublicKey) (*envelope.PublicKey, *envelope.PrivateKey, error) {
	pubenc, err := packagePublicKey(ctx, c, authID, orgID, primitive.EncryptionKeyType,
		kp.Encryption.Public[:], pubsig.ID, &kp.Signature)
	if err != nil {
		return nil, nil, err
	}
	privenc, err := packagePrivateKey(ctx, c, authID, orgID, kp.Encryption.PNonce,
		kp.Encryption.Private, pubenc.ID, pubsig.ID, &kp.Signature)
	if err != nil {
		return nil, nil, err
	}
	return pubenc, privenc, nil
}
func packagePlaintextCred(c envelope.CredentialInf, value string) PlaintextCredentialEnvelope {
	state := "set"
	return PlaintextCredentialEnvelope{
		ID:      c.GetID(),
		Version: c.GetVersion(),
		Body: &PlaintextCredential{
			Name:      c.Name(),
			PathExp:   c.PathExp(),
			ProjectID: c.ProjectID(),
			OrgID:     c.OrgID(),
			Value:     value,
			State:     &state,
		},
	}
}
func extractCredentialValue(pt []byte) (*apitypes.CredentialValue, error) {
	cValue := &apitypes.CredentialValue{}
	err := json.Unmarshal([]byte(strconv.Quote(string(pt))), cValue)
	if err != nil {
		return nil, err
	}
	return cValue, nil
}
func createCredentialGraph(ctx context.Context, credBody *PlaintextCredential,
	parent registry.CredentialGraph, sigID *identity.ID, encID *identity.ID,
	kp *crypto.KeyPairs, ct *registry.ClaimTree, client *registry.Client,
	engine *crypto.Engine, g *secure.Guard) (*registry.CredentialGraphV2, error) {
	pathExp, err := credBody.PathExp.WithInstance("*")
	if err != nil {
		return nil, err
	}
	keyringBody := primitive.NewKeyring(credBody.OrgID, credBody.ProjectID, pathExp)
	if parent != nil {
		keyringBody.Previous = parent.GetKeyring().GetID()
		keyringBody.KeyringVersion = parent.KeyringVersion() + 1
	}
	keyring, err := engine.SignedKeyring(ctx, keyringBody, sigID, &kp.Signature)
	if err != nil {
		return nil, err
	}
	mek, err := g.Random(64)
	defer mek.Destroy()
	if err != nil {
		return nil, err
	}
	subjects, err := getKeyringMembers(ctx, client, credBody.OrgID)
	if err != nil {
		return nil, err
	}
	members := []registry.KeyringMember{}
	for _, subject := range subjects {
		for _, id := range subject.KeyOwnerIDs() {
			enc, err := ct.FindActive(&id, primitive.EncryptionKeyType)
			if err == registry.ErrMissingKeyForOwner {
				continue
			}
			if err != nil {
				return nil, err
			}
			encPubKey := enc.PublicKey
			encmek, nonce, err := engine.Box(ctx, mek, &kp.Encryption, []byte(*encPubKey.Body.Key.Value))
			if err != nil {
				return nil, err
			}
			key := &primitive.KeyringMemberKey{
				Algorithm: crypto.EasyBox,
				Nonce:     base64.New(nonce),
				Value:     base64.New(encmek),
			}
			member, err := newV2KeyringMember(ctx, engine, credBody.OrgID, keyring.ID,
				encPubKey.Body.OwnerID, encPubKey.ID, encID, sigID, key, kp)
			if err != nil {
				return nil, err
			}
			members = append(members, *member)
		}
	}
	graph := registry.CredentialGraphV2{
		KeyringSectionV2: registry.KeyringSectionV2{
			Keyring: keyring,
			Claims:  []envelope.KeyringMemberClaim{},
			Members: members,
		},
	}
	return &graph, nil
}
func newV1KeyringMember(ctx context.Context, engine *crypto.Engine,
	orgID, projectID, keyringID, ownerID, pubKeyID, encKeyID, sigID *identity.ID,
	key *primitive.KeyringMemberKey, kp *crypto.KeyPairs) (*envelope.KeyringMemberV1, error) {
	now := time.Now().UTC()
	return engine.SignedKeyringMemberV1(ctx, &primitive.KeyringMemberV1{
		Created:         now,
		OrgID:           orgID,
		ProjectID:       projectID,
		KeyringID:       keyringID,
		OwnerID:         ownerID,
		PublicKeyID:     pubKeyID,
		EncryptingKeyID: encKeyID,
		Key:             key,
	}, sigID, &kp.Signature)
}
func newV2KeyringMember(ctx context.Context, engine *crypto.Engine,
	orgID, keyringID, ownerID, pubKeyID, encKeyID, sigID *identity.ID,
	key *primitive.KeyringMemberKey, kp *crypto.KeyPairs) (*registry.KeyringMember, error) {
	now := time.Now().UTC()
	member, err := engine.SignedKeyringMember(ctx, &primitive.KeyringMember{
		Created:         now,
		OrgID:           orgID,
		KeyringID:       keyringID,
		OwnerID:         ownerID,
		PublicKeyID:     pubKeyID,
		EncryptingKeyID: encKeyID,
	}, sigID, &kp.Signature)
	if err != nil {
		return nil, err
	}
	mekshare, err := engine.SignedMEKShare(ctx, &primitive.MEKShare{
		Created:         now,
		OrgID:           orgID,
		OwnerID:         ownerID,
		KeyringID:       keyringID,
		KeyringMemberID: member.ID,
		Key:             key,
	}, sigID, &kp.Signature)
	if err != nil {
		return nil, err
	}
	return &registry.KeyringMember{
		Member:   member,
		MEKShare: mekshare,
	}, nil
}
func createKeyringMemberships(ctx context.Context, c *crypto.Engine, client *registry.Client,
	s session.Session, orgID, ownerID *identity.ID) ([]envelope.KeyringMemberV1, []registry.KeyringMember, error) {
	keypairs, err := client.KeyPairs.List(ctx, orgID)
	if err != nil {
		log.Printf("could not fetch keypairs for org: %s", err)
		return nil, nil, err
	}
	sigID, encID, kp, err := fetchKeyPairs(keypairs, orgID)
	if err != nil {
		log.Printf("could not fetch keypairs for org: %s", err)
		return nil, nil, err
	}
	claimTree, err := client.ClaimTree.Get(ctx, orgID, nil)
	if err != nil {
		log.Printf("could not retrieve claim tree for invite approval: %s", err)
		return nil, nil, err
	}
	org, err := client.Orgs.Get(ctx, orgID)
	if err != nil {
		return nil, nil, err
	}
	projects, err := client.Projects.List(ctx, org.ID)
	if err != nil {
		return nil, nil, err
	}
	var graphs []registry.CredentialGraph
	for _, project := range projects {
		projGraphs, err := client.CredentialGraph.Search(ctx,
			"/"+org.Body.Name+"/"+project.Body.Name+"/*/*/*/*", s.AuthID(), nil)
		if err != nil {
			log.Printf("Error retrieving credential graphs: %s", err)
			return nil, nil, err
		}
		graphs = append(graphs, projGraphs...)
	}
	targetKeySegment, err := claimTree.FindActive(ownerID, primitive.EncryptionKeyType)
	if err != nil {
		log.Printf("could not find encryption key for owner id: %s", ownerID.String())
		return nil, nil, err
	}
	targetPubKey := targetKeySegment.PublicKey
	cgs := newCredentialGraphSet()
	err = cgs.Add(graphs...)
	if err != nil {
		return nil, nil, err
	}
	activeGraphs, err := cgs.Active()
	if err != nil {
		return nil, nil, err
	}
	v1members := []envelope.KeyringMemberV1{}
	v2members := []registry.KeyringMember{}
	for _, graph := range activeGraphs {
		krm, mekshare, err := graph.FindMember(s.AuthID())
		if err != nil {
			log.Printf("could not find keyring membership: %s", err)
			return nil, nil, &apitypes.Error{
				Type: apitypes.NotFoundError,
				Err:  []string{"Keyring membership not found."},
			}
		}
		encPubKeySegment, err := claimTree.Find(krm.EncryptingKeyID, false)
		if err != nil {
			log.Printf("could not find encrypting public key for membership: %s", err)
			return nil, nil, err
		}
		encPubKey := encPubKeySegment.PublicKey
		encMek, nonce, err := c.CloneMembership(ctx, *mekshare.Key.Value,
			*mekshare.Key.Nonce, &kp.Encryption, *encPubKey.Body.Key.Value, *targetPubKey.Body.Key.Value)
		if err != nil {
			log.Printf("could not clone keyring membership: %s", err)
			return nil, nil, err
		}
		key := &primitive.KeyringMemberKey{
			Algorithm: crypto.EasyBox,
			Nonce:     base64.New(nonce),
			Value:     base64.New(encMek),
		}
		switch k := graph.GetKeyring().(type) {
		case *envelope.KeyringV1:
			projectID := k.Body.ProjectID
			member, err := newV1KeyringMember(ctx, c, krm.OrgID, projectID,
				krm.KeyringID, ownerID, targetPubKey.ID, encID, sigID, key, kp)
			if err != nil {
				return nil, nil, err
			}
			v1members = append(v1members, *member)
		case *envelope.Keyring:
			member, err := newV2KeyringMember(ctx, c, krm.OrgID, krm.KeyringID,
				ownerID, targetPubKey.ID, encID, sigID, key, kp)
			if err != nil {
				return nil, nil, err
			}
			v2members = append(v2members, *member)
		default:
			return nil, nil, &apitypes.Error{
				Type: apitypes.InternalServerError,
				Err:  []string{"Unknown keyring schema version"},
			}
		}
	}
	return v1members, v2members, nil
}