This command allows options in authorizations without requiring that the TPM evaluate all of the options. If a policy may be satisfied by different sets of conditions, the TPM need only evaluate one set that satisfies the policy. This command will indicate that one of the required sets of conditions has been satisfied.
Inheritance: PolicyAce
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;
        }
Ejemplo n.º 2
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.BranchIdentifier;
                    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.BranchIdentifier))
                {
                    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;
        }