예제 #1
0
 public PolicyAce AddNextAce(PolicyAce nextAce)
 {
     if (this is TpmPolicyOr)
     {
         Globs.Throw<ArgumentException>("AddNextAce: Do not call AddNextAce for an OR node: Use AddPolicyBranch instead.");
     }
     if (NextAce != null)
     {
         Globs.Throw<ArgumentException>("AddNextAce: Policy ACE already has a child");
     }
     if (!String.IsNullOrEmpty(BranchIdentifier))
     {
         if (String.IsNullOrEmpty(nextAce.BranchIdentifier))
         {
             nextAce.BranchIdentifier = BranchIdentifier;
         }
         else if (nextAce.BranchIdentifier != BranchIdentifier)
         {
             Globs.Throw<ArgumentException>("AddNextAce: Policy ACE with non-empty BranchName can only have a child with the same or no branch name");
         }
         BranchIdentifier = "";
     }
     NextAce = nextAce;
     NextAce.PreviousAce = this;
     return nextAce;
 }
예제 #2
0
        private PolicyAce GetNodeIdInternal(PolicyAce n, string nodeId)
        {
            if (n.NodeId == nodeId)
            {
                return(n);
            }

            // ReSharper disable once CanBeReplacedWithTryCastAndCheckForNull
            if (n is TpmPolicyOr)
            {
                foreach (PolicyAce a in ((TpmPolicyOr)n).PolicyBranches)
                {
                    PolicyAce ace = GetNodeIdInternal(a, nodeId);
                    if (ace != null)
                    {
                        return(ace);
                    }
                }
            }

            if (n.NextAce != null)
            {
                return(GetNodeIdInternal(n.NextAce, nodeId));
            }

            return(null);
        }
예제 #3
0
        /// <summary>
        /// Create a simple policy chain (no ORs).
        /// </summary>
        public void Create(PolicyAce[] singlePolicyChain)
        {
            // ReSharper disable once RedundantExplicitArraySize
            var arr = new PolicyAce[1][] { singlePolicyChain };

            CreateNormalizedPolicy(arr);
        }
예제 #4
0
        // Returns the linked list as an array
        internal static PolicyAce[] GetArrayRepresentation(PolicyAce head)
        {
            int       numElems = 0;
            PolicyAce next     = head;

            do
            {
                if (next == null)
                {
                    break;
                }
                next = next.NextAce;
                numElems++;
            } while (true);

            var arr   = new PolicyAce[numElems];
            int count = 0;

            next = head;
            do
            {
                if (next == null)
                {
                    break;
                }
                arr[count] = next;
                next       = next.NextAce;
                count++;
            } while (true);

            return(arr);
        }
예제 #5
0
        /// <summary>
        /// Load a policy from a stream (MemoryStream, FileStream) in the specified format
        /// </summary>
        /// <param name="format"></param>
        /// <param name="sourceStream"></param>
        public void Deserialize(PolicySerializationFormat format, Stream sourceStream)
        {
            TpmPolicy pol = null;

            switch (format)
            {
            case PolicySerializationFormat.Xml:
            {
                var ser = new DataContractSerializer(typeof(TpmPolicy));
                pol = (TpmPolicy)ser.ReadObject(sourceStream);
                break;
            }

            case PolicySerializationFormat.Json:
            {
                var ser = new DataContractJsonSerializer(typeof(TpmPolicy));
                pol = (TpmPolicy)ser.ReadObject(sourceStream);
                break;
            }

            default:
                Globs.Throw <ArgumentException>("PolicyTree.Deserialize: Unknown format " + format);
                return;
            }
            pol.AssociatedPolicy = this;
            PolicyRoot           = pol.PolicyRoot;
        }
예제 #6
0
        internal static PolicyAce FromArrayRepresentation(PolicyAce[] arr, PolicyTree policy)
        {
            PolicyAce root     = null;
            PolicyAce current  = null;
            PolicyAce previous = null;

            // Makes a doubly linked list from an array
            foreach (PolicyAce a in arr)
            {
                // All ACEs have an associated policy tree
                a.AssociatedPolicy = policy;
                // we need a link to previous
                if (previous != null)
                {
                    a.PreviousAce = previous;
                }

                // previous needs a link to us
                if (current != null)
                {
                    current.NextAce = a;
                }

                current = a;
                if (root == null)
                {
                    root = current;
                }
                previous = a;
            }
            return(root);
        }
예제 #7
0
 public PolicyAce AddNextAce(PolicyAce nextAce)
 {
     if (this is TpmPolicyOr)
     {
         Globs.Throw <ArgumentException>("AddNextAce: Do not call AddNextAce for " +
                                         "an OR node. Use AddPolicyBranch instead.");
     }
     if (NextAce != null)
     {
         Globs.Throw <ArgumentException>("AddNextAce: Policy ACE already has a child");
     }
     if (!String.IsNullOrEmpty(BranchID))
     {
         if (String.IsNullOrEmpty(nextAce.BranchID))
         {
             nextAce.BranchID = BranchID;
         }
         else if (nextAce.BranchID != BranchID)
         {
             Globs.Throw <ArgumentException>(
                 "AddNextAce: Policy ACE with non-empty BranchName " +
                 "can only have a child with the same or no branch name");
         }
         BranchID = "";
     }
     NextAce             = nextAce;
     NextAce.PreviousAce = this;
     return(nextAce);
 }
예제 #8
0
파일: Policy.cs 프로젝트: Microsoft/TSS.MSR
 public PolicyTree InsertPolicyRoot(PolicyAce newRoot)
 {
     if (PolicyRoot != null)
         newRoot.AddNextAce(PolicyRoot);
     PolicyRoot = newRoot;
     return this;
 }
예제 #9
0
 public PolicyTree InsertPolicyRoot(PolicyAce newRoot)
 {
     if (PolicyRoot != null)
     {
         newRoot.AddNextAce(PolicyRoot);
     }
     SetPolicyRoot(newRoot);
     return(this);
 }
예제 #10
0
        public TpmHash GetPolicyDigest()
        {
            PolicyAce dummyAce = null;

            if (null == PolicyRoot)
            {
                return(new TpmHash(PolicyHash.HashAlg));
            }
            // First, check that the tree is OK. An exception is thrown if checks fail.
            CheckPolicy("", ref dummyAce);

            return(PolicyRoot.GetPolicyDigest(PolicyHash.HashAlg));
        }
예제 #11
0
        /// <summary>
        /// Returns the ticket associated with a prior policy execution (or null).
        /// </summary>
        /// <param name="nodeIdentifier"></param>
        /// <returns></returns>
        public TkAuth GetTicket(string nodeIdentifier)
        {
            MatchingNode = null;
            PolicyAce matchingAce = GetNodeIdInternal(PolicyRoot, nodeIdentifier);

            if (matchingAce == null)
            {
                return(null);
            }

            TkAuth tic = ((TpmPolicySigned)matchingAce).GetPolicyTicket();

            return(tic);
        }
예제 #12
0
        /// <summary>
        /// Run a path on the policy tree.  The path is identified by the leaf identifier string. A session is
        /// created and returned. If allowErrors is true then errors returned do not cause an exception (but
        /// are returned in the response code).
        /// </summary>
        /// <param name="tpm"></param>
        /// <param name="policySession"></param>
        /// <param name="branchToEvaluate"></param>
        /// <param name="allowErrors"></param>
        /// <returns></returns>
        public TpmRc RunPolicy(Tpm2 tpm, PolicyTree policyTree, string branchToEvaluate = null, bool allowErrors = false)
        {
            policyTree.AllowErrorsInPolicyEval = allowErrors;

            PolicyAce leafAce = null;

            // First, check that the policy is OK.
            policyTree.CheckPolicy(branchToEvaluate, ref leafAce);
            if (leafAce == null)
            {
                Globs.Throw("RunPolicy: Branch identifier " + branchToEvaluate + " does not exist");
            }

            var responseCode = TpmRc.Success;

            try
            {
                if (allowErrors)
                {
                    tpm._DisableExceptions();
                }

                tpm._InitializeSession(this);

                // Walk up the tree from the leaf..
                PolicyAce nextAce = leafAce;
                while (nextAce != null)
                {
                    responseCode = nextAce.Execute(tpm, this, policyTree);

                    if (responseCode != TpmRc.Success)
                    {
                        break;
                    }

                    // ..and continue along the path to the root
                    nextAce = nextAce.PreviousAce;
                }
            }
            finally
            {
                if (allowErrors)
                {
                    tpm._EnableExceptions();
                }
            }

            return(responseCode);
        }
예제 #13
0
 /// <summary>
 /// Sets the current policy tree to a policy branch represented by its leaf ACE.
 /// A policy branch can be constructed by means of the following expressions:
 ///     new TpmAce1().And(new TpmAce2()).And(new TpmAce3());
 /// or
 ///     new TpmAce1().AddNextAce(new TpmAce2()).AddNextAce(new TpmAce3());
 /// </summary>
 public void Set(PolicyAce leaf)
 {
     if (leaf == null)
     {
         PolicyRoot = null;
         return;
     }
     // The construction policyTree.Set()
     // evaluates to ace4.  We have to go back to the root.
     if (String.IsNullOrEmpty(leaf.BranchID))
     {
         leaf.BranchID = "leaf";
     }
     do
     {
         PolicyRoot = leaf;
         leaf       = leaf.PreviousAce;
     } while (leaf != null);
 }
예제 #14
0
        protected PolicyAce[] ChainToArray(PolicyAce ace)
        {
            int       count = 0;
            PolicyAce curr  = ace;

            while (curr.NextAce != null)
            {
                count++;
                curr = curr.NextAce;
            }
            PolicyAce[] arr = new PolicyAce[count];
            curr = ace;
            for (int i = 0; i < count; i++)
            {
                arr[i]             = curr;
                curr               = curr.NextAce;
                arr[i].PreviousAce = null;
                arr[i].NextAce     = null;
            }
            return(arr);
        }
예제 #15
0
        private PolicyAce FindNodeId(PolicyAce ace, string nodeId)
        {
            if (ace.NodeId == nodeId)
            {
                return(ace);
            }

            if (ace is TpmPolicyOr)
            {
                foreach (PolicyAce branchRoot in ((TpmPolicyOr)ace).PolicyBranches)
                {
                    PolicyAce a = FindNodeId(branchRoot, nodeId);
                    if (a != null)
                    {
                        return(a);
                    }
                }
            }

            return(ace.NextAce == null ? null : FindNodeId(ace.NextAce, nodeId));
        }
예제 #16
0
 public void AddPolicyBranches(PolicyAce[] arr)
 {
     PolicyBranches.Clear();
     foreach (PolicyAce a in arr)
     {
         PolicyBranches.Add(a);
     }
 }
예제 #17
0
        internal void CheckBranchIDs(PolicyAce ace, string branchIdToFind,
                                     ref PolicyAce matchingAce)
        {
            if (ace == null)
            {
                return;
            }

            ace.AssociatedPolicy = this;

            // ReSharper disable once CanBeReplacedWithTryCastAndCheckForNull
            if (ace is TpmPolicyOr)
            {
                // Go down each branch of the OR
                PolicyContainsOrs = true;
                var orAce = (TpmPolicyOr)ace;
                foreach (PolicyAce nextAce in orAce.PolicyBranches)
                {
                    CheckBranchIDs(nextAce, branchIdToFind, ref matchingAce);
                }
            }
            else
            {
                PolicyAce nextAce = ace.NextAce;
                if (nextAce != null)
                {
                    CheckBranchIDs(nextAce, branchIdToFind, ref matchingAce);
                    return;
                }

                // We are at the leaf. If there are no ORs in this chain then we are
                // done. If there  are ORs then check two things (1) that the leaf
                // has a non-empty BranchIdentifier, and (2) that the branchIdentifiers
                // are unique.
                if (!PolicyContainsOrs)
                {
                    matchingAce = ace;
                    if (String.IsNullOrEmpty(ace.BranchID))
                    {
                        ace.BranchID = "leaf";
                    }
                    return;
                }

                if (String.IsNullOrEmpty(ace.BranchID))
                {
                    Globs.Throw("CheckPolicyIdInternal: Branch leaf does not have a BranchID");
                }

                if (BranchIdCollection.Contains(ace.BranchID))
                {
                    Globs.Throw("CheckPolicyIdInternal: Replicated BranchID " + ace.BranchID);
                }

                BranchIdCollection.Add(ace.BranchID);
                if (ace.BranchID == branchIdToFind)
                {
                    matchingAce = ace;
                }
            }
        }
예제 #18
0
        internal void CheckPolicyIdInternal(PolicyAce ace, string branchIdToFind, ref PolicyAce matchingAce, string nodeIdToFind = "")
        {
            // we allow null sessions
            if (ace == null)
            {
                return;
            }

            ace.AssociatedPolicy = this;

            // ReSharper disable once CanBeReplacedWithTryCastAndCheckForNull
            if (ace is TpmPolicyOr)
            {
                // Go down each branch of the OR
                PolicyContainsOrs = true;
                var orAce = (TpmPolicyOr)ace;
                foreach (PolicyAce nextAce in orAce.PolicyBranches)
                {
                    CheckPolicyIdInternal(nextAce, branchIdToFind, ref matchingAce, nodeIdToFind);
                }
            }
            else
            {
                PolicyAce nextAce = ace.NextAce;
                if (nextAce != null)
                {
                    CheckPolicyIdInternal(nextAce, branchIdToFind, ref matchingAce, nodeIdToFind);
                    return;
                }

                // We are at the leaf. If there are no ORs in this chain then we are done. If there
                // are ORs then check two things (1) that the leaf has a non-empty BranchIdentifier,
                // and (2) that the branchIdentifiers are unique.
                if (!PolicyContainsOrs)
                {
                    matchingAce = ace;
                    if (String.IsNullOrEmpty(ace.BranchIdentifier))
                    {
                        ace.BranchIdentifier = "leaf";
                    }
                    return;
                }

                if (String.IsNullOrEmpty(ace.BranchIdentifier))
                {
                    throw new Exception("Branch leaf does not have a BranchIdentifier");
                }

                if (BranchIdCollection.Contains(ace.BranchIdentifier))
                {
                    throw new Exception("Replicated branch leaf" + ace.BranchIdentifier);
                }

                BranchIdCollection.Add(ace.BranchIdentifier);
                if (ace.BranchIdentifier == branchIdToFind)
                {
                    matchingAce = ace;
                }
                if (!String.IsNullOrEmpty(nodeIdToFind))
                {
                    if (nodeIdToFind == ace.NodeId)
                    {
                        MatchingNode = ace;
                        matchingAce  = ace;
                    }
                }
            }
        }
예제 #19
0
파일: Policy.cs 프로젝트: Microsoft/TSS.MSR
 /// <summary>
 /// Load a policy from a stream (MemoryStream, FileStream) in the specified format
 /// </summary>
 /// <param name="policyIdentifier"></param>
 /// <param name="fileName"></param>
 public void Deserialize(PolicySerializationFormat format, Stream sourceStream)
 {
     TpmPolicy pol = null;
     switch (format)
     {
         case PolicySerializationFormat.Xml:
         {
             var ser = new DataContractSerializer(typeof(TpmPolicy));
             pol = (TpmPolicy)ser.ReadObject(sourceStream);
             break;
         }
         case PolicySerializationFormat.Json:
         {
             var ser = new DataContractJsonSerializer(typeof(TpmPolicy));
             pol = (TpmPolicy)ser.ReadObject(sourceStream);
             break;
         }
         default:
             Globs.Throw<ArgumentException>("PolicyTree.Deserialize: Unknown format " + format);
             return;
     }
     pol.AssociatedPolicy = this;
     PolicyRoot = pol.PolicyRoot;
 }
예제 #20
0
 protected PolicyAce ArrayToChain(PolicyAce[] arr)
 {
     for (int j = 0; j < arr.Length - 1; j++)
     {
         arr[j].NextAce = arr[j + 1];
         arr[j + 1].PreviousAce = arr[j];
     }
     return arr[0];
 }
예제 #21
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;
        }
예제 #22
0
파일: Policy.cs 프로젝트: Microsoft/TSS.MSR
 /// <summary>
 /// Check to see if all branches have an ID and that the IDs are unique.
 /// </summary>
 /// <param name="branchIdToFind"></param>
 /// <param name="matchingAce"></param>
 internal void CheckPolicy(string branchIdToFind, ref PolicyAce matchingAce)
 {
     PolicyContainsOrs = false;
     BranchIdCollection = new HashSet<string>();
     CheckPolicyIdInternal(PolicyRoot, branchIdToFind, ref matchingAce);
 }
예제 #23
0
 // [Obsolete]
 public PolicyAce SetPolicyRoot(PolicyAce root)
 {
     PolicyRoot = root;
     return(PolicyRoot);
 }
예제 #24
0
파일: Policy.cs 프로젝트: Microsoft/TSS.MSR
        internal void CheckPolicyIdInternal(PolicyAce ace, string branchIdToFind, ref PolicyAce matchingAce, string nodeIdToFind = "") 
        {

            // we allow null sessions
            if (ace == null)
                return;

            ace.AssociatedPolicy = this;

            // ReSharper disable once CanBeReplacedWithTryCastAndCheckForNull
            if (ace is TpmPolicyOr)
            {
                // Go down each branch of the OR
                PolicyContainsOrs = true;
                var orAce = (TpmPolicyOr)ace;
                foreach (PolicyAce nextAce in orAce.PolicyBranches)
                {
                    CheckPolicyIdInternal(nextAce, branchIdToFind, ref matchingAce, nodeIdToFind);
                }
            }
            else
            {
                PolicyAce nextAce = ace.NextAce;
                if (nextAce != null)
                {
                    CheckPolicyIdInternal(nextAce, branchIdToFind, ref matchingAce, nodeIdToFind);
                    return;
                }

                // We are at the leaf. If there are no ORs in this chain then we are done. If there 
                // are ORs then check two things (1) that the leaf has a non-empty BranchIdentifier,
                // and (2) that the branchIdentifiers are unique.
                if (!PolicyContainsOrs)
                {
                    matchingAce = ace;
                    if (String.IsNullOrEmpty(ace.BranchIdentifier))
                    {
                        ace.BranchIdentifier = "leaf";
                    }
                    return;
                }

                if (String.IsNullOrEmpty(ace.BranchIdentifier))
                {
                    Globs.Throw("CheckPolicyIdInternal: Branch leaf does not have a BranchIdentifier");
                }

                if (BranchIdCollection.Contains(ace.BranchIdentifier))
                {
                    Globs.Throw("CheckPolicyIdInternal: Replicated branch leaf" + ace.BranchIdentifier);
                }

                BranchIdCollection.Add(ace.BranchIdentifier);
                if (ace.BranchIdentifier == branchIdToFind)
                {
                    matchingAce = ace;
                }
                if (!String.IsNullOrEmpty(nodeIdToFind))
                {
                    if (nodeIdToFind == ace.NodeId)
                    {
                        MatchingNode = ace;
                        matchingAce = ace;
                    }
                }
            }
        }
예제 #25
0
        /// <summary>
        /// This sample illustrates the use of a TpmPolicyOr.
        /// </summary>
        static void PolicyOr(Tpm2 tpm)
        {
            Console.WriteLine("PolicyOr sample:");

            //
            // Check if policy commands are implemented by TPM. This list
            // could include all the other used commands as well.
            // This check here makes sense for policy commands, because
            // usually a policy has to be executed in full. If a command
            // out of the chain of policy commands is not implemented in the
            // TPM, the policy cannot be satisfied.
            // 
            var usedCommands = new[] {
                                        TpmCc.PolicyLocality,
                                        TpmCc.PolicyPCR,
                                        TpmCc.PolicyAuthValue
            };
            foreach (var commandCode in usedCommands)
            {
                if (!tpm.Helpers.IsImplemented(commandCode))
                {
                    Console.WriteLine("Cancel Policy OR sample, because command {0} is not implemented by TPM.", commandCode);
                    return;
                }
            }

            var pcrs = new uint[] { 1, 2, 3 };
            var sel = new PcrSelection(TpmAlgId.Sha, pcrs);

            PcrSelection[] selOut;
            Tpm2bDigest[] pcrValues;

            //
            // First read the PCR values
            // 
            tpm.PcrRead(new[] { sel }, out selOut, out pcrValues);

            //
            // Save the current PCR values in a convenient data structure
            // 
            var expectedPcrVals = new PcrValueCollection(selOut, pcrValues);

            //
            // Tpm2Lib encapsulates a set of policy assertions as the PolicyTree class.  
            // 
            var policyTree = new PolicyTree(TpmAlgId.Sha256);

            //
            // First branch of PolicyOr
            // 
            var branch1 = new PolicyAce[]
            {
                new TpmPolicyLocality(LocalityAttr.TpmLocZero),
                new TpmPolicyPcr(expectedPcrVals), 
                "branch_1"
            };

            //
            // Second branch of PolicyOr
            //
            var branch2 = new PolicyAce[]
            {
                new TpmPolicyAuthValue(),
                "branch_2"
            };

            //
            // Create the policy. CreateNormalizedPolicy takes an array-of-arrays
            // of PolicyACEs that are to be OR'ed together (the branches themselves cannot
            // contain TpmPOlicyOrs). The library code constructs a policy tree with 
            // minimum number of TpmPolicyOrs at the root.  
            // 
            policyTree.CreateNormalizedPolicy(new[] {branch1, branch2});

            //
            // Ask Tpm2Lib for the expected policy-hash for this policy
            // 
            TpmHash expectedPolicyHash = policyTree.GetPolicyDigest();

            //
            // Create a sealed primary object with the policy-hash we just calculated
            // 
            var dataToSeal = new byte[] { 1, 2, 3, 4, 5, 4, 3, 2, 1 };
            var authVal = new byte[] { 1, 2 };
            TpmHandle primHandle = CreateSealedPrimaryObject(tpm, 
                                                             dataToSeal, 
                                                             authVal,
                                                             expectedPolicyHash.HashData);
            //
            // Create an actual TPM policy session to evaluate the policy
            // 
            AuthSession session = tpm.StartAuthSessionEx(TpmSe.Policy, TpmAlgId.Sha256);

            //
            // Run the policy on the TPM
            // 
            session.RunPolicy(tpm, policyTree, "branch_1");

            //
            // And unseal the object
            // 
            byte[] unsealedData = tpm[session].Unseal(primHandle);
            Console.WriteLine("Unsealed data for branch_1: " + BitConverter.ToString(unsealedData));
            
            //
            // Now run the other branch
            // 
            tpm.PolicyRestart(session.Handle);
            session.RunPolicy(tpm, policyTree, "branch_2");

            //
            // And the session will be unusable
            // 
            unsealedData = tpm[session].Unseal(primHandle);
            Console.WriteLine("Unsealed data for branch_2: " + BitConverter.ToString(unsealedData));

            //
            // Clean up
            // 
            tpm.FlushContext(session.Handle);
            tpm.FlushContext(primHandle);
        }
예제 #26
0
파일: Policy.cs 프로젝트: Microsoft/TSS.MSR
        /// <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;
        }
예제 #27
0
파일: Policy.cs 프로젝트: Microsoft/TSS.MSR
        internal static PolicyAce FromArrayRepresentation(PolicyAce[] arr, PolicyTree policy)
        {
            PolicyAce root = null;
            PolicyAce current = null;
            PolicyAce previous = null;
            // Makes a doubly linked list from an array
            foreach (PolicyAce a in arr)
            {
                // All ACEs have an associated policy tree
                a.AssociatedPolicy = policy;
                // we need a link to previous
                if (previous != null)
                {
                    a.PreviousAce = previous;
                }
                
                // previous needs a link to us
                if (current != null)
                {
                    current.NextAce = a;
                }

                current = a;
                if (root == null)
                {
                    root = current;
                }
                previous = a;
            }
            return root;
        }
예제 #28
0
파일: Policy.cs 프로젝트: Microsoft/TSS.MSR
        // Returns the linked list as an array
        internal static PolicyAce[] GetArrayRepresentation(PolicyAce head)
        {
            int numElems = 0;
            PolicyAce next = head;
            do
            {
                if (next == null)
                {
                    break;
                }
                next = next.NextAce;
                numElems++;
            } while (true);

            var arr = new PolicyAce[numElems];
            int count = 0;
            next = head;
            do
            {
                if (next == null)
                {
                    break;
                }
                arr[count] = next;
                next = next.NextAce;
                count++;
            } while (true);

            return arr;
        }
예제 #29
0
 // [Obsolete]
 public PolicyAce SetPolicyRoot(PolicyAce root)
 {
     PolicyRoot = root;
     _Digest    = null;
     return(PolicyRoot);
 }
예제 #30
0
파일: Policy.cs 프로젝트: Microsoft/TSS.MSR
 /// <summary>
 /// Sets the current policy tree to a policy branch represented by its leaf ACE.
 /// A policy branch can be constructed by means of the following expressions:
 ///     new TpmAce1().And(new TpmAce2()).And(new TpmAce3());
 /// or
 ///     new TpmAce1().AddNextAce(new TpmAce2()).AddNextAce(new TpmAce3());
 /// </summary>
 public void Set (PolicyAce leaf)
 {
     if (leaf == null)
     {
         PolicyRoot = null;
         return;
     }
     // The construction policyTree.Set()
     // evaluates to ace4.  We have to go back to the root.
     if (String.IsNullOrEmpty(leaf.BranchIdentifier))
     {
         leaf.BranchIdentifier = "leaf";
     }
     do
     {
         PolicyRoot = leaf;
         leaf = leaf.PreviousAce;
     } while (leaf != null);
 }
예제 #31
0
 /// <summary>
 /// Add an "OR-branch"
 /// </summary>
 /// <param name="newAce"></param>
 /// <returns></returns>
 public PolicyAce AddPolicyBranch(PolicyAce newAce)
 {
     PolicyBranches.Add(newAce);
     newAce.PreviousAce = this;
     return newAce;
 }
예제 #32
0
파일: Policy.cs 프로젝트: Microsoft/TSS.MSR
 /// <summary>
 /// Create a simple policy chain (no ORs). 
 /// </summary>
 public void Create(PolicyAce[] singlePolicyChain)
 {
     // ReSharper disable once RedundantExplicitArraySize
     var arr = new PolicyAce[1][] {singlePolicyChain};
     CreateNormalizedPolicy(arr);
 }
예제 #33
0
 public PolicyAce SetPolicyRoot(PolicyAce newRoot)
 {
     PolicyRoot = newRoot;
     return(PolicyRoot);
 }
예제 #34
0
 public PolicyAce And(PolicyAce nextAce)
 {
     return AddNextAce(nextAce);
 }
예제 #35
0
 /// <summary>
 /// Add an "OR-branch"
 /// </summary>
 /// <param name="newAce"></param>
 /// <returns></returns>
 public PolicyAce AddPolicyBranch(PolicyAce newAce)
 {
     PolicyBranches.Add(newAce);
     newAce.PreviousAce = this;
     return(newAce);
 }
예제 #36
0
 /// <summary>
 /// Check to see if all branches have an ID and that the IDs are unique.
 /// </summary>
 /// <param name="branchIdToFind"></param>
 /// <param name="matchingAce"></param>
 internal void CheckPolicy(string branchIdToFind, ref PolicyAce matchingAce)
 {
     PolicyContainsOrs  = false;
     BranchIdCollection = new HashSet <string>();
     CheckBranchIDs(PolicyRoot, branchIdToFind, ref matchingAce);
 }
예제 #37
0
 public PolicyAce And(PolicyAce nextAce)
 {
     return(AddNextAce(nextAce));
 }
예제 #38
0
파일: Policy.cs 프로젝트: Microsoft/TSS.MSR
 // [Obsolete]
 public PolicyAce SetPolicyRoot(PolicyAce root)
 {
     PolicyRoot = root;
     return PolicyRoot;
 }