/// <summary> /// Encode the instance of current class into bytes. /// </summary> /// <returns>The encoded bytes.</returns> public byte[] ToBytes() { UpdateInterrelatedFields(); byte[] header = PacUtility.ObjectToMemory(NativePacType); byte[][] bodyReferences = new byte[NativePacType.cBuffers][]; for (int i = 0; i < NativePacType.cBuffers; i++) { if (pacInfoBuffers[i] == null) { continue; } bodyReferences[i] = pacInfoBuffers[i].EncodeBuffer(); int length = bodyReferences[i].Length; // double check the totalLength // NativePacType.Buffers[index].cbBufferSize has been updated in previous // UpdateInterrelatedFields() method, given by each pacInfoBuffer's // CalculateSize() method. // following evaluation double check whether CalculateSize() method's // result conforms to EncodeBuffer() method's result. // Note: some kind of pacInfoBuffers return EncodeBuffer().Length as the // CalculateSize(), such as NDR encoded structures. But some other // pacInfoBuffers can calculate totalLength without encoding the structure. AssertBufferSize(NativePacType.Buffers, i, length); } return(ConcatenateBuffers(header, bodyReferences)); }
/// <summary> /// Encode the instance of current class into byte array, /// according to TD specification. /// </summary> /// <returns>The encoded byte array</returns> internal override byte[] EncodeBuffer() { using (SafeIntPtr ptr = TypeMarshal.ToIntPtr(NativeS4uDelegationInfo)) { return(PacUtility.NdrMarshal(ptr, FormatString.OffsetS4u)); } }
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); }
internal override byte[] EncodeBuffer() { using (SafeIntPtr ptr = TypeMarshal.ToIntPtr(NativeClaimsSetMetadata)) { return(PacUtility.NdrMarshal(ptr, FormatString.OffsetClientClaim)); } }
/// <summary> /// Decode specified buffer from specified index, with specified count /// of bytes, into the instance of current class. /// </summary> /// <param name="buffer">The specified buffer.</param> /// <param name="index">The specified index from beginning of buffer.</param> /// <param name="count">The specified count of bytes to be decoded.</param> internal override void DecodeBuffer(byte[] buffer, int index, int count) { NativeKerbValidationInfo = PacUtility.NdrUnmarshal <KERB_VALIDATION_INFO>( buffer, index, count, FormatString.OffsetKerb); }
/// <summary> /// Decode specified buffer from specified index, with specified count /// of bytes, into the instance of current class. /// </summary> /// <param name="buffer">The specified buffer.</param> /// <param name="index">The specified index from beginning of buffer.</param> /// <param name="count">The specified count of bytes to be decoded.</param> internal override void DecodeBuffer(byte[] buffer, int index, int count) { NativeS4uDelegationInfo = PacUtility.NdrUnmarshal <_S4U_DELEGATION_INFO>( buffer, index, count, FormatString.OffsetS4u); }
/// <summary> /// Update length and offset of UPN and DNS Domain. /// </summary> private void UpdateOffsetLength() { int upnOffset = Marshal.SizeOf(NativeUpnDnsInfo.GetType()); NativeUpnDnsInfo.UpnOffset = (ushort)PacUtility.AlignTo(upnOffset, UpnDnsAlignUnit); NativeUpnDnsInfo.UpnLength = (ushort)(Encoding.Unicode.GetByteCount(Upn)); int dnsOffset = NativeUpnDnsInfo.UpnOffset + NativeUpnDnsInfo.UpnLength; NativeUpnDnsInfo.DnsDomainNameOffset = (ushort)PacUtility.AlignTo(dnsOffset, UpnDnsAlignUnit); NativeUpnDnsInfo.DnsDomainNameLength = (ushort)(Encoding.Unicode.GetByteCount(DnsDomain)); }
/// <summary> /// Decode specified buffer from specified index, with specified count /// of bytes, into the instance of current class. /// </summary> /// <param name="buffer">The specified buffer.</param> /// <param name="index">The specified index from beginning of buffer.</param> /// <param name="count">The specified count of bytes to be decoded.</param> internal override void DecodeBuffer(byte[] buffer, int index, int count) { NativePacCredentialInfo = PacUtility.MemoryToObject <PAC_CREDENTIAL_INFO>(buffer, index, count); int headerLength = sizeof(uint) + sizeof(uint); // This is vary length member without pre-defined calculate method. // Need to decode manually. NativePacCredentialInfo.SerializedData = new byte[count - headerLength]; Buffer.BlockCopy(buffer, index + headerLength, NativePacCredentialInfo.SerializedData, 0, count - headerLength); }
/// <summary> /// Encrypt a PacCredentialData instance. The encrypted data /// can be accessed from SerializedData property. /// </summary> /// <param name="credentialData">The _PAC_CREDENTIAL_DATA instance to be encrypted.</param> /// <param name="key">The encrypt key.</param> public void Encrypt(_PAC_CREDENTIAL_DATA credentialData, byte[] key) { if (key == null) { throw new ArgumentNullException("key"); } byte[] plain = null; using (SafeIntPtr ptr = TypeMarshal.ToIntPtr(credentialData)) { plain = PacUtility.NdrMarshal(ptr, FormatString.OffsetCredentialData); } NativePacCredentialInfo.SerializedData = Encrypt(key, plain, NativePacCredentialInfo.EncryptionType); }
/// <summary> /// Decrypt the data of SerializedData property into /// a PacCredentialData instance. /// </summary> /// <param name="key">The decrypt key.</param> /// <returns>The decrypted _PAC_CREDENTIAL_DATA instance.</returns> public _PAC_CREDENTIAL_DATA Decrypt(byte[] key) { if (key == null) { throw new ArgumentNullException("key"); } byte[] plain = Decrypt( key, NativePacCredentialInfo.SerializedData, NativePacCredentialInfo.EncryptionType); return(PacUtility.NdrUnmarshal <_PAC_CREDENTIAL_DATA>(plain, 0, plain.Length, FormatString.OffsetCredentialData)); }
/// <summary> /// Decode specified buffer from specified index, with specified count /// of bytes, into the instance of current class. /// </summary> /// <param name="buffer">The specified buffer.</param> /// <param name="index">The specified index from beginning of buffer.</param> /// <param name="count">The specified count of bytes to be decoded.</param> internal override void DecodeBuffer(byte[] buffer, int index, int count) { NativeUpnDnsInfo = PacUtility.MemoryToObject <UPN_DNS_INFO>(buffer, index, count); upn = ReadUtf16String( buffer, index + NativeUpnDnsInfo.UpnOffset, NativeUpnDnsInfo.UpnLength); dnsDomain = ReadUtf16String( buffer, index + NativeUpnDnsInfo.DnsDomainNameOffset, NativeUpnDnsInfo.DnsDomainNameLength); UpdateOffsetLength(); }
/// <summary> /// Concatenate specified header buffer and specified body buffers. /// </summary> /// <param name="header">The specified header buffer.</param> /// <param name="bodyReferences">The specified body buffers.</param> /// <returns>The integrated buffer.</returns> private byte[] ConcatenateBuffers(byte[] header, byte[][] bodyReferences) { // calculate total totalLength int totalLength = header.Length; for (int i = 0; i < NativePacType.cBuffers; i++) { if (bodyReferences[i] == null) { continue; } int length = bodyReferences[i].Length; // double check the length // NativePacType.Buffers[index].cbBufferSize has been updated in previous // UpdateInterrelatedFields() method, given by each pacInfoBuffer's // CalculateSize() method. // following evaluation double check whether CalculateSize() method's // result conforms to EncodeBuffer() method's result. // Note: some kind of pacInfoBuffers return EncodeBuffer().Length as the // CalculateSize(), such as NDR encoded structures. But some other // pacInfoBuffers can calculate totalLength without encoding the structure. AssertBufferSize(NativePacType.Buffers, i, length); totalLength += PacUtility.AlignTo(length, PacTypeAlignUnit); } byte[] total = new byte[totalLength]; int offset = 0; Buffer.BlockCopy(header, 0, total, offset, header.Length); offset += header.Length; for (int i = 0; i < bodyReferences.Length; ++i) { if (bodyReferences[i] == null) { continue; } int length = bodyReferences[i].Length; Buffer.BlockCopy(bodyReferences[i], 0, total, offset, length); offset += PacUtility.AlignTo(length, PacTypeAlignUnit); } return(total); }
/// <summary> /// Construct an instance of current class by decoding specified bytes. /// </summary> /// <param name="buffer">The specified bytes.</param> internal PacType(byte[] buffer) { NativePacType = PacUtility.MemoryToObject <PACTYPE>(buffer); pacInfoBuffers = new PacInfoBuffer[NativePacType.Buffers.Length]; for (int i = 0; i < NativePacType.Buffers.Length; ++i) { if (NativePacType.Buffers[i].cbBufferSize > 0) { PacInfoBuffers[i] = PacInfoBuffer.DecodeBuffer( NativePacType.Buffers[i], buffer); } else { PacInfoBuffers[i] = null; } } }
/// <summary> /// Encode the instance of current class into byte array, /// according to TD specification. /// </summary> /// <returns>The encoded byte array</returns> internal override byte[] EncodeBuffer() { byte[] header = PacUtility.ObjectToMemory(NativeUpnDnsInfo); int length = CalculateSize(); byte[] result = new byte[length]; // header Buffer.BlockCopy(header, 0, result, 0, header.Length); // upn content Buffer.BlockCopy(Encoding.Unicode.GetBytes(upn), 0, result, NativeUpnDnsInfo.UpnOffset, NativeUpnDnsInfo.UpnLength); // dns domain content Buffer.BlockCopy(Encoding.Unicode.GetBytes(dnsDomain), 0, result, NativeUpnDnsInfo.DnsDomainNameOffset, NativeUpnDnsInfo.DnsDomainNameLength); return(result); }
/// <summary> /// Update cbBufferSize and Offset of all PAC_INFO_BUFFERs /// after the buffers' content updated. /// </summary> public void UpdateInterrelatedFields() { AssertBuffersCount(pacInfoBuffers.Length, NativePacType.Buffers.Length); int offset = CalculateHeaderSize(); for (int i = 0; i < pacInfoBuffers.Length; i++) { NativePacType.Buffers[i].Offset = (ulong)offset; if (pacInfoBuffers[i] == null) { continue; } int size = pacInfoBuffers[i].CalculateSize(); NativePacType.Buffers[i].cbBufferSize = (uint)size; offset += size; //TD section 2.3: "All PAC elements MUST be placed on an 8-byte boundary." offset = PacUtility.AlignTo(offset, PacTypeAlignUnit); } }
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); }
/// <summary> /// Decode specified buffer from specified index, with specified count /// of bytes, into the instance of current class. /// </summary> /// <param name="buffer">The specified buffer.</param> /// <param name="index">The specified index from beginning of buffer.</param> /// <param name="count">The specified count of bytes to be decoded.</param> internal override void DecodeBuffer(byte[] buffer, int index, int count) { NativePacClientInfo = PacUtility.MemoryToObject <PAC_CLIENT_INFO>(buffer, index, count); }
/// <summary> /// Encode the instance of current class into byte array, /// according to TD specification. /// </summary> /// <returns>The encoded byte array</returns> internal override byte[] EncodeBuffer() { return(PacUtility.ObjectToMemory(NativePacClientInfo)); }
public _NTLM_SUPPLEMENTAL_CREDENTIAL GetNtlmCredential() { return(PacUtility.MemoryToObject <_NTLM_SUPPLEMENTAL_CREDENTIAL>(Credentials, 0, Credentials.Length)); }
/// <summary> /// Set _NTLM_SUPPLEMENTAL_CREDENTIAL to Credentials. /// Credentials is a pointer, pointing to a byte array. /// The byte array is the NDR-encoded _NTLM_SUPPLEMENTAL_CREDENTIAL. /// </summary> /// <param name="ntlmCredential">the embedded _NTLM_SUPPLEMENTAL_CREDENTIAL instance.</param> public void SetNtlmCredential(_NTLM_SUPPLEMENTAL_CREDENTIAL ntlmCredential) { Credentials = PacUtility.ObjectToMemory <_NTLM_SUPPLEMENTAL_CREDENTIAL>(ntlmCredential); CredentialSize = (uint)Credentials.Length; }
/// <summary> /// Encode the instance of current class into byte array, /// according to TD specification. /// </summary> /// <returns>The encoded byte array</returns> internal override byte[] EncodeBuffer() { return(PacUtility.ObjectToMemory(NativePacSignatureData)); }
/// <summary> /// Decode specified buffer from specified index, with specified count /// of bytes, into the instance of current class. /// </summary> /// <param name="buffer">The specified buffer.</param> /// <param name="index">The specified index from beginning of buffer.</param> /// <param name="count">The specified count of bytes to be decoded.</param> internal override void DecodeBuffer(byte[] buffer, int index, int count) { NativePacSignatureData = PacUtility.MemoryToObject <PAC_SIGNATURE_DATA>(buffer, index, count); }