internal override void DecodeBuffer(byte[] buffer, int index, int count)
        {
            NativeClaimsSetMetadata = PacUtility.NdrUnmarshal <PAC_CLIENT_CLAIMS_INFO>(
                buffer,
                index,
                count,
                FormatString.OffsetClientClaim, false, 4);

            byte[] decompressed    = null;
            int    decompressedLen = -1;

            if (NativeClaimsSetMetadata.Claims.usCompressionFormat != CLAIMS_COMPRESSION_FORMAT.COMPRESSION_FORMAT_NONE)
            {
                decompressed = ClaimsCompression.Decompress(NativeClaimsSetMetadata.Claims.usCompressionFormat,
                                                            NativeClaimsSetMetadata.Claims.ClaimsSet,
                                                            (int)NativeClaimsSetMetadata.Claims.ulUncompressedClaimsSetSize);
                decompressedLen = decompressed.Length;
            }
            else
            {
                decompressed    = NativeClaimsSetMetadata.Claims.ClaimsSet;
                decompressedLen = (int)NativeClaimsSetMetadata.Claims.ulClaimsSetSize;
            }
            NativeClaimSet = PacUtility.NdrUnmarshal <CLAIMS_SET>(
                decompressed,
                0,
                decompressedLen,
                FormatString.OffsetClaimSet, false, 4);
        }
        public void Kerberos_SingleRealm_ADSource_User_Only()
        {
            CLAIMS_SET?claims = GetADUserClaims_SingleRealm(
                this.testConfig.LocalRealm.RealmName,
                this.testConfig.LocalRealm.User[2].Username,
                this.testConfig.LocalRealm.User[2].Password,
                this.testConfig.LocalRealm.KDC[0].IPAddress,
                this.testConfig.LocalRealm.FileServer[0].DefaultServiceName,
                this.testConfig.LocalRealm.FileServer[0].Password);

            BaseTestSite.Assert.IsTrue(claims.HasValue, "CLAIMS_SET is returned for user claims");

            CLAIMS_SET val = claims.Value;

            BaseTestSite.Log.Add(LogEntryKind.Checkpoint, "Start load claims from ad");
            string ClaimLocalforestUserDN = "cn=" + this.testConfig.LocalRealm.User[2].Username + ",cn=users,dc=" + this.testConfig.LocalRealm.RealmName.Replace(".", ",dc=");

            ClaimHelper.LoadClaims(ClaimLocalforestUserDN, ClaimsPrincipalClass.User,
                                   this.testConfig.LocalRealm.KDC[0].IPAddress, this.testConfig.LocalRealm.RealmName, this.testConfig.LocalRealm.Admin.Username,
                                   this.testConfig.LocalRealm.Admin.Password);


            BaseTestSite.Log.Add(LogEntryKind.Checkpoint, "Start compare claims between AD and Kerberos Ticket");
            for (int i = 0; i < val.ClaimsArrays.Length; i++)
            {
                for (int j = 0; j < val.ClaimsArrays[i].ClaimEntries.Length; j++)
                {
                    CLAIM_ENTRY entry = val.ClaimsArrays[i].ClaimEntries[j];
                    string      str   = ClaimUtility.ConvertEntryUniontoString(entry.Type, entry.Values);
                    BaseTestSite.Assert.IsTrue(ClaimHelper.FoundMatchedClaim(this.testConfig.LocalRealm.User[2].Username,
                                                                             ClaimsPrincipalClass.User,
                                                                             CLAIMS_SOURCE_TYPE.CLAIMS_SOURCE_TYPE_AD,
                                                                             entry.Id,
                                                                             entry.Type,
                                                                             str),
                                               "Should find same claim in AD");
                }
            }
        }
        internal override void DecodeBuffer(byte[] buffer, int index, int count)
        {
            byte[] RawData = new byte[count];
            Array.ConstrainedCopy(buffer, index, RawData, 0, count);

            NativeClaimsSetMetadata = PacUtility.NdrUnmarshal <PAC_DEVICE_CLAIMS_INFO>(
                buffer,
                index,
                count,
                FormatString.OffsetClientClaim, false, 4);

            byte[] decompressed    = null;
            int    decompressedLen = -1;

            if (NativeClaimsSetMetadata.Claims.usCompressionFormat != CLAIMS_COMPRESSION_FORMAT.COMPRESSION_FORMAT_NONE)
            {
                uint err = ClaimsCompression.Decompress(NativeClaimsSetMetadata.Claims.usCompressionFormat,
                                                        NativeClaimsSetMetadata.Claims.ClaimsSet,
                                                        (int)NativeClaimsSetMetadata.Claims.ulUncompressedClaimsSetSize,
                                                        out decompressed);
                if (err != 0)
                {
                    throw new Exception("Failed to decompress CLAIMS_SET data, error code is :" + err);
                }
                decompressedLen = decompressed.Length;
            }
            else
            {
                decompressed    = NativeClaimsSetMetadata.Claims.ClaimsSet;
                decompressedLen = (int)NativeClaimsSetMetadata.Claims.ulClaimsSetSize;
            }
            NativeClaimSet = PacUtility.NdrUnmarshal <CLAIMS_SET>(
                decompressed,
                0,
                decompressedLen,
                FormatString.OffsetClaimSet, false, 4);
        }
        private void claimsTest_Kerberos_CrossRealm_ADSource_User_Only(bool ctaFromConfig)
        {
            client = new KerberosTestClient(this.testConfig.LocalRealm.RealmName,
                                            this.testConfig.LocalRealm.User[2].Username,
                                            this.testConfig.LocalRealm.User[2].Password,
                                            KerberosAccountType.User,
                                            testConfig.LocalRealm.KDC[0].IPAddress,
                                            testConfig.LocalRealm.KDC[0].Port,
                                            testConfig.TransportType,
                                            testConfig.SupportedOid);

            //Create and send AS request
            KdcOptions options = KdcOptions.FORWARDABLE | KdcOptions.CANONICALIZE | KdcOptions.RENEWABLE;

            client.SendAsRequest(options, null);
            //Recieve preauthentication required error
            METHOD_DATA      methodData;
            KerberosKrbError krbError = client.ExpectPreauthRequiredError(out methodData);

            //Create sequence of PA data
            string         timeStamp      = KerberosUtility.CurrentKerberosTime.Value;
            PaEncTimeStamp paEncTimeStamp = new PaEncTimeStamp(timeStamp,
                                                               0,
                                                               this.client.Context.SelectedEType,
                                                               this.client.Context.CName.Password,
                                                               this.client.Context.CName.Salt);
            PaPacRequest             paPacRequest = new PaPacRequest(true);
            PaPacOptions             paPacOptions = new PaPacOptions(PacOptions.Claims | PacOptions.ForwardToFullDc);
            Asn1SequenceOf <PA_DATA> seqOfPaData  = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data, paPacOptions.Data });

            //Create and send AS request
            client.SendAsRequest(options, seqOfPaData);
            KerberosAsResponse       asResponse   = client.ExpectAsResponse();
            Asn1SequenceOf <PA_DATA> seqOfPaData2 = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paEncTimeStamp.Data, paPacRequest.Data });

            //Create and send TGS request
            client.SendTgsRequest(this.testConfig.TrustedRealm.KDC[0].DefaultServiceName, options, seqOfPaData2);

            BaseTestSite.Log.Add(LogEntryKind.Comment, "Create and send TGS request");
            KerberosTgsResponse tgsResponse = client.ExpectTgsResponse();

            BaseTestSite.Log.Add(LogEntryKind.Comment, "Receive a referral TGS response.");

            BaseTestSite.Assert.AreEqual(this.testConfig.TrustedRealm.KDC[0].DefaultServiceName,
                                         KerberosUtility.PrincipalName2String(tgsResponse.Response.ticket.sname),
                                         "The service principal name in referral ticket should match expected.");
            BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(),
                                         tgsResponse.Response.ticket.realm.Value.ToLower(),
                                         "The realm name in referral ticket should match expected.");

            EncryptionKey key = testConfig.QueryKey(this.testConfig.TrustedRealm.KDC[0].DefaultServiceName + "@" + this.testConfig.LocalRealm.RealmName, client.Context.Realm.ToString(), client.Context.SelectedEType);

            tgsResponse.DecryptTicket(key);

            CLAIMS_SET claims      = new CLAIMS_SET();
            AdWin2KPac adWin2kPac  = FindOneInAuthData <AdWin2KPac>(tgsResponse.TicketEncPart.authorization_data.Elements);
            bool       foundClaims = false;

            foreach (PacInfoBuffer buf in adWin2kPac.Pac.PacInfoBuffers)
            {
                if (buf.GetType() == typeof(ClientClaimsInfo))
                {
                    claims      = ((ClientClaimsInfo)buf).NativeClaimSet;
                    foundClaims = true;
                }
            }
            BaseTestSite.Assert.IsTrue(foundClaims, "Found claims in referral TGS Ticket");
            foundClaims = false;

            #region genertaed transformed claims
            Dictionary <string, string> expectedClaims = new Dictionary <string, string>();
            if (!ctaFromConfig)
            {
                ClaimTransformer    transformer = new ClaimTransformer(this.testConfig.TrustedRealm.KDC[0].IPAddress, this.testConfig.TrustedRealm.RealmName, this.testConfig.TrustedRealm.Admin.Username, this.testConfig.TrustedRealm.Admin.Password);
                List <CLAIMS_ARRAY> transformed = null;
                BaseTestSite.Assert.AreEqual <Win32ErrorCode_32>(Win32ErrorCode_32.ERROR_SUCCESS, transformer.TransformClaimsOnTrustTraversal(claims.ClaimsArrays, this.testConfig.LocalRealm.RealmName, true, out transformed), "should successfully transform claims");
                foreach (CLAIMS_ARRAY array in transformed)
                {
                    foreach (CLAIM_ENTRY entry in array.ClaimEntries)
                    {
                        string id    = entry.Id;
                        string value = null;
                        switch (entry.Type)
                        {
                        case CLAIM_TYPE.CLAIM_TYPE_BOOLEAN:
                            value = entry.Values.Struct4.BooleanValues[0].ToString();
                            break;

                        case CLAIM_TYPE.CLAIM_TYPE_INT64:
                            value = entry.Values.Struct1.Int64Values[0].ToString();
                            break;

                        case CLAIM_TYPE.CLAIM_TYPE_STRING:
                            value = entry.Values.Struct3.StringValues[0].ToString();
                            break;

                        case CLAIM_TYPE.CLAIM_TYPE_UINT64:
                            value = entry.Values.Struct2.Uint64Values[0].ToString();
                            break;

                        default:
                            BaseTestSite.Assert.Fail("Found invalid claim type during transform, value:" + (int)entry.Type);
                            break;
                        }
                        expectedClaims.Add(id.ToLower(), value.ToLower());
                    }
                }
            }
            else
            {
                string[] tmp = this.testConfig.LocalRealm.User[2].TransformedClaims.ToLower().Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
                BaseTestSite.Assert.IsTrue(tmp != null && tmp.Length % 2 == 0, "Claim.Crossforest.TransformedClaims in PTFConfig should be valid and not empty");
                for (int i = 0; i < tmp.Length; i += 2)
                {
                    expectedClaims.Add(tmp[i], tmp[i + 1]);
                }
            }
            #endregion
            //Change realm
            client.ChangeRealm(this.testConfig.TrustedRealm.RealmName,
                               this.testConfig.TrustedRealm.KDC[0].IPAddress,
                               this.testConfig.TrustedRealm.KDC[0].Port,
                               this.testConfig.TransportType);

            //Create and send referal TGS request
            client.SendTgsRequest(this.testConfig.TrustedRealm.FileServer[0].Smb2ServiceName, options);
            KerberosTgsResponse refTgsResponse = client.ExpectTgsResponse();

            BaseTestSite.Assert.AreEqual(this.testConfig.TrustedRealm.FileServer[0].Smb2ServiceName,
                                         KerberosUtility.PrincipalName2String(refTgsResponse.Response.ticket.sname),
                                         "The service principal name in service ticket should match expected.");
            BaseTestSite.Assert.AreEqual(this.testConfig.TrustedRealm.RealmName.ToLower(),
                                         refTgsResponse.Response.ticket.realm.Value.ToLower(),
                                         "The realm name in service ticket should match expected.");

            key = testConfig.QueryKey(this.testConfig.TrustedRealm.FileServer[0].Smb2ServiceName, client.Context.Realm.ToString(), client.Context.SelectedEType);
            refTgsResponse.DecryptTicket(key);

            BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.RealmName.ToLower(),
                                         refTgsResponse.TicketEncPart.crealm.Value.ToLower(),
                                         "Realm name in service ticket encrypted part should match expected.");
            BaseTestSite.Assert.AreEqual(this.testConfig.LocalRealm.User[2].Username,
                                         KerberosUtility.PrincipalName2String(refTgsResponse.TicketEncPart.cname).ToLower(),
                                         "User name in service ticket encrypted part should match expected.");

            adWin2kPac = FindOneInAuthData <AdWin2KPac>(refTgsResponse.TicketEncPart.authorization_data.Elements);
            foreach (PacInfoBuffer buf in adWin2kPac.Pac.PacInfoBuffers)
            {
                if (buf.GetType() == typeof(ClientClaimsInfo))
                {
                    foundClaims = true;
                    claims      = ((ClientClaimsInfo)buf).NativeClaimSet;
                }
            }

            int errors = 0;
            BaseTestSite.Assert.IsTrue(foundClaims, "Found claims in reference TGS Ticket");
            for (int i = 0; i < claims.ClaimsArrays[0].ClaimEntries.Length; i++)
            {
                string claimvalue = null;
                if (!expectedClaims.TryGetValue(claims.ClaimsArrays[0].ClaimEntries[i].Id.ToLower(), out claimvalue))
                {
                    errors++;
                    BaseTestSite.Log.Add(LogEntryKind.CheckFailed, "Found unexpected claim with id: " + claims.ClaimsArrays[0].ClaimEntries[i].Id + " after transform");
                }
                else
                {
                    if (claimvalue != claims.ClaimsArrays[0].ClaimEntries[i].Values.Struct3.StringValues[0].ToLower())
                    {
                        errors++;
                        BaseTestSite.Log.Add(
                            LogEntryKind.CheckFailed,
                            "Value of claim \"" + claims.ClaimsArrays[0].ClaimEntries[i].Id + "\" is not expected, expected: " + claimvalue + " ,actual: " + claims.ClaimsArrays[0].ClaimEntries[i].Values.Struct3.StringValues[0]);
                    }
                    expectedClaims.Remove(claims.ClaimsArrays[0].ClaimEntries[i].Id);
                }
            }

            BaseTestSite.Assert.AreEqual(expectedClaims.Count, claims.ClaimsArrays[0].ClaimEntries.Count(), "Claims count should be equal.");
            BaseTestSite.Assert.AreEqual <int>(0, errors, "Expect no error should be found when compare claims from reference TGS ticket");
        }