Tpm2Lib.TpmPolicyOr.AddPolicyBranch C# (CSharp) Method

AddPolicyBranch() public method

Add an "OR-branch"
public AddPolicyBranch ( PolicyAce newAce ) : PolicyAce
newAce PolicyAce
return PolicyAce
        public PolicyAce AddPolicyBranch(PolicyAce newAce)
        {
            PolicyBranches.Add(newAce);
            newAce.PreviousAce = this;
            return newAce;
        }

Usage Example

Ejemplo n.º 1
0
        /// <summary>
        /// A "normalized" policy is one transformed into disjunctive normal form,
        /// in which a collection  of policy "AND chains" is combined with PolicyOR
        /// before submission to the TPM.
        /// Callers must provide an-array-of-arrays of TpmPolicyACEs. The arrays may NOT
        /// contain PolicyOr (these will be added automatically), but each array MUST be
        /// terminated  with a unique string identifier encoded in a TpmPolicyChainId.
        /// </summary>
        /// <param name="policy"></param>
        public void CreateNormalizedPolicy(PolicyAce[][] policy)
        {
            // To validate that the input does not have any repeated branchIds or ACEs
            var  branchIdDict    = new Dictionary <string, string>();
            var  aces            = new HashSet <object>();
            int  numBranches     = 0;
            bool unnamedBranches = false;

            // The following code validates and transforms the array-of-arrays into a linked
            // list + OR nodes tree. First collect lists of chains in the chains collection.
            var chains = new List <PolicyAce>();

            foreach (PolicyAce[] chain in policy)
            {
                numBranches++;
                PolicyAce leaf        = null;
                PolicyAce previousAce = null;
                PolicyAce root        = null;
                // Turn the array into a doubly-linked list
                foreach (PolicyAce ace in chain)
                {
                    // Repeats are illegal
                    if (aces.Contains(ace))
                    {
                        Globs.Throw <ArgumentException>("CreateNormalizedPolicy: " +
                                                        "Repeated ACE in policy");
                    }

                    // Already associated with a session is illegal
                    if (ace.AssociatedPolicy != null)
                    {
                        Globs.Throw <ArgumentException>("CreateNormalizedPolicy: " +
                                                        "ACE is already associated with a policy");
                    }

                    ace.AssociatedPolicy = this;
                    aces.Add(ace);

                    // OR is illegal in normal form (these are added automatically
                    // at the root to union the arrays that are input to this function).
                    if (ace is TpmPolicyOr)
                    {
                        Globs.Throw <ArgumentException>("CreateNormalizedPolicy: " +
                                                        "Normalized form cannot contain TpmPolicyOr");
                    }

                    if (previousAce != null)
                    {
                        previousAce.NextAce = ace;
                    }

                    ace.PreviousAce = previousAce;
                    previousAce     = ace;

                    // Is the branchId valid?
                    string branchId = ace.BranchID;
                    if (!String.IsNullOrEmpty(branchId))
                    {
                        if (branchIdDict.ContainsKey(branchId))
                        {
                            Globs.Throw <ArgumentException>("CreateNormalizedPolicy: " +
                                                            "Repeated branch-identifier " + branchId);
                        }
                        branchIdDict.Add(branchId, "");
                    }
                    if (root == null)
                    {
                        root = ace;
                    }
                    leaf = ace;
                }

                // Does the leaf have a branch ID?
                if (leaf != null && String.IsNullOrEmpty(leaf.BranchID))
                {
                    unnamedBranches = true;
                }

                // Else we have a good chain starting at root
                chains.Add(root);
            }

            if (unnamedBranches && numBranches != 1)
            {
                throw new ArgumentException("Policy-chain leaf does not have a branch identifier");
            }

            // We now have a list of chains in chains.
            int numChains = chains.Count;

            // A single chain (no ORs)
            if (numChains == 1)
            {
                PolicyRoot = chains[0];
                return;
            }

            // Each TPM_or can take up to 8 inputs. We will add OR-aces to the root
            // to capture all chains. The algorithm is that we create an OR and keep
            // adding chains in the input order until full (if it is the last chain)
            // or one-less than full. Then create a new OR, attach it to the last OR
            // and keep filling as before.

            var         theRoot      = new TpmPolicyOr();
            TpmPolicyOr currentOrAce = theRoot;

            for (int j = 0; j < numChains; j++)
            {
                bool lastChain = (j == numChains - 1);
                if ((currentOrAce.PolicyBranches.Count < 7) || lastChain)
                {
                    currentOrAce.AddPolicyBranch(chains[j]);
                }
                else
                {
                    // We have overflowed the TpmPolicyOr so add a new child-OR
                    // attached to the previous as the final (8th) branch.
                    var nextOr = new TpmPolicyOr();
                    currentOrAce.AddPolicyBranch(nextOr);
                    currentOrAce = nextOr;
                    currentOrAce.AddPolicyBranch(chains[j]);
                }
            }
            // All input chains are connected up to one or more ORs at the root so we are done.
            PolicyRoot = theRoot;
        }