func createCredentialGraph(ctx context.Context, credBody *PlaintextCredential,
	parent registry.CredentialGraph, sigID *identity.ID, encID *identity.ID, kp *crypto.KeyPairs,
	client *registry.Client, engine *crypto.Engine) (*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().ID
		keyringBody.KeyringVersion = parent.KeyringVersion() + 1
	}

	keyring, err := engine.SignedEnvelope(ctx, keyringBody, sigID, &kp.Signature)
	if err != nil {
		return nil, err
	}

	// XXX: sensitive value. protect with OS things.
	mek := make([]byte, 64)
	_, err = rand.Read(mek)
	if err != nil {
		return nil, err
	}

	teams, err := client.Teams.List(ctx, credBody.OrgID)
	if err != nil {
		return nil, err
	}

	membersTeam, machinesTeam, err := findSystemTeams(teams)
	if err != nil {
		return nil, err
	}

	userMembers, err := client.Memberships.List(ctx, credBody.OrgID, membersTeam.ID, nil)
	if err != nil {
		return nil, err
	}

	machineMembers, err := client.Memberships.List(ctx, credBody.OrgID, machinesTeam.ID, nil)
	if err != nil {
		return nil, err
	}

	claimTrees, err := client.ClaimTree.List(ctx, credBody.OrgID, nil)
	if err != nil {
		return nil, err
	}

	if len(claimTrees) != 1 {
		return nil, &apitypes.Error{
			Type: apitypes.NotFoundError,
			Err: []string{
				fmt.Sprintf("Claim tree not found for org: %s", credBody.OrgID),
			},
		}
	}

	// get users in the members group of this org.
	// XXX: we need to filter this down based on ACL
	var subjects []identity.ID
	for _, membership := range userMembers {
		subjects = append(subjects, *membership.Body.(*primitive.Membership).OwnerID)
	}

	for _, membership := range machineMembers {
		machineID := membership.Body.(*primitive.Membership).OwnerID
		segment, err := client.Machines.Get(ctx, machineID)
		if err != nil {
			return nil, err
		}

		for _, token := range segment.Tokens {
			if token.Token.Body.State == primitive.MachineTokenActiveState {
				subjects = append(subjects, *token.Token.ID)
				break
			}
		}
	}

	// use their public key to encrypt the mek with a random nonce.
	members := []registry.KeyringMember{}
	for _, subject := range subjects {
		// For this user, find their public encryption key
		encPubKey, err := findEncryptionPublicKey(claimTrees, credBody.OrgID, &subject)
		if err != nil {
			return nil, err
		}

		pubKey := encPubKey.Body.(*primitive.PublicKey)
		encmek, nonce, err := engine.Box(ctx, mek, &kp.Encryption, []byte(*pubKey.Key.Value))
		if err != nil {
			return nil, err
		}

		key := &primitive.KeyringMemberKey{
			Algorithm: crypto.EasyBox,
			Nonce:     base64.NewValue(nonce),
			Value:     base64.NewValue(encmek),
		}

		member, err := newV2KeyringMember(ctx, engine, credBody.OrgID, keyring.ID,
			pubKey.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.Signed{},
			Members: members,
		},
	}

	return &graph, nil
}
// createCredentialGraph generates, signs, and posts a new CredentialGraph
// to the registry.
createCredentialGraph generates, signs, and posts a new CredentialGraph
to the registry.
// createCredentialGraph generates signs and posts a new CredentialGraph // to the registry .
func createCredentialGraph(ctx context.Context, credBody *PlaintextCredential,
	parent registry.CredentialGraph, sigID *identity.ID, encID *identity.ID, kp *crypto.KeyPairs,
	client *registry.Client, engine *crypto.Engine) (*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().ID
		keyringBody.KeyringVersion = parent.KeyringVersion() + 1
	}
	keyring, err := engine.SignedEnvelope(ctx, keyringBody, sigID, &kp.Signature)
	if err != nil {
		return nil, err
	}
	mek := make([]byte, 64)
	_, err = rand.Read(mek)
	if err != nil {
		return nil, err
	}
	teams, err := client.Teams.List(ctx, credBody.OrgID)
	if err != nil {
		return nil, err
	}
	membersTeam, machinesTeam, err := findSystemTeams(teams)
	if err != nil {
		return nil, err
	}
	userMembers, err := client.Memberships.List(ctx, credBody.OrgID, membersTeam.ID, nil)
	if err != nil {
		return nil, err
	}
	machineMembers, err := client.Memberships.List(ctx, credBody.OrgID, machinesTeam.ID, nil)
	if err != nil {
		return nil, err
	}
	claimTrees, err := client.ClaimTree.List(ctx, credBody.OrgID, nil)
	if err != nil {
		return nil, err
	}
	if len(claimTrees) != 1 {
		return nil, &apitypes.Error{
			Type: apitypes.NotFoundError,
			Err: []string{
				fmt.Sprintf("Claim tree not found for org: %s", credBody.OrgID),
			},
		}
	}
	var subjects []identity.ID
	for _, membership := range userMembers {
		subjects = append(subjects, *membership.Body.(*primitive.Membership).OwnerID)
	}
	for _, membership := range machineMembers {
		machineID := membership.Body.(*primitive.Membership).OwnerID
		segment, err := client.Machines.Get(ctx, machineID)
		if err != nil {
			return nil, err
		}
		for _, token := range segment.Tokens {
			if token.Token.Body.State == primitive.MachineTokenActiveState {
				subjects = append(subjects, *token.Token.ID)
				break
			}
		}
	}
	members := []registry.KeyringMember{}
	for _, subject := range subjects {
		encPubKey, err := findEncryptionPublicKey(claimTrees, credBody.OrgID, &subject)
		if err != nil {
			return nil, err
		}
		pubKey := encPubKey.Body.(*primitive.PublicKey)
		encmek, nonce, err := engine.Box(ctx, mek, &kp.Encryption, []byte(*pubKey.Key.Value))
		if err != nil {
			return nil, err
		}
		key := &primitive.KeyringMemberKey{
			Algorithm: crypto.EasyBox,
			Nonce:     base64.NewValue(nonce),
			Value:     base64.NewValue(encmek),
		}
		member, err := newV2KeyringMember(ctx, engine, credBody.OrgID, keyring.ID,
			pubKey.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.Signed{},
			Members: members,
		},
	}
	return &graph, nil
}
func createCredentialGraph ( ctx context . Context , credBody * PlaintextCredential , parent registry . CredentialGraph , sigID * identity . ID , encID * identity . ID , kp * crypto . KeyPairs , client * registry . Client , engine * crypto . Engine ) ( * 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 ( ) . ID keyringBody . KeyringVersion = parent . KeyringVersion ( ) + 1 } keyring , err := engine . SignedEnvelope ( ctx , keyringBody , sigID , & kp . Signature ) if err != nil { return nil , err } mek := make ( [ ] byte , 64 ) _ , err = rand . Read ( mek ) if err != nil { return nil , err } teams , err := client . Teams . List ( ctx , credBody . OrgID ) if err != nil { return nil , err } membersTeam , machinesTeam , err := findSystemTeams ( teams ) if err != nil { return nil , err } userMembers , err := client . Memberships . List ( ctx , credBody . OrgID , membersTeam . ID , nil ) if err != nil { return nil , err } machineMembers , err := client . Memberships . List ( ctx , credBody . OrgID , machinesTeam . ID , nil ) if err != nil { return nil , err } claimTrees , err := client . ClaimTree . List ( ctx , credBody . OrgID , nil ) if err != nil { return nil , err } if len ( claimTrees ) != 1 { return nil , & apitypes . Error { Type : apitypes . NotFoundError , Err : [ ] string { fmt . Sprintf ( " " , credBody . OrgID ) , } , } } var subjects [ ] identity . ID for _ , membership := range userMembers { subjects = append ( subjects , * membership . Body . ( * primitive . Membership ) . OwnerID ) } for _ , membership := range machineMembers { machineID := membership . Body . ( * primitive . Membership ) . OwnerID segment , err := client . Machines . Get ( ctx , machineID ) if err != nil { return nil , err } for _ , token := range segment . Tokens { if token . Token . Body . State == primitive . MachineTokenActiveState { subjects = append ( subjects , * token . Token . ID ) break } } } members := [ ] registry . KeyringMember { } for _ , subject := range subjects { encPubKey , err := findEncryptionPublicKey ( claimTrees , credBody . OrgID , & subject ) if err != nil { return nil , err } pubKey := encPubKey . Body . ( * primitive . PublicKey ) encmek , nonce , err := engine . Box ( ctx , mek , & kp . Encryption , [ ] byte ( * pubKey . Key . Value ) ) if err != nil { return nil , err } key := & primitive . KeyringMemberKey { Algorithm : crypto . EasyBox , Nonce : base64 . NewValue ( nonce ) , Value : base64 . NewValue ( encmek ) , } member , err := newV2KeyringMember ( ctx , engine , credBody . OrgID , keyring . ID , pubKey . 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 . Signed { } , Members : members , } , } return & graph , nil }
createCredentialGraph generates, signs, and posts a new CredentialGraph
to the registry.
createCredentialGraph generates signs and posts a new CredentialGraph to the registry .
// XXX: sensitive value. protect with OS things. // get users in the members group of this org. // XXX: we need to filter this down based on ACL // use their public key to encrypt the mek with a random nonce. // For this user, find their public encryption key