Example #1
0
        /// <summary>
        /// Calculate Server checksum (TD section 2.8.1) of the PAC message,
        /// place the checksum as a PacInfoBuffer whose ulType_Values is V3.
        /// Then calculate KDC checksum (TD section 2.8.2) of the PAC message,
        /// place the checksum as a PacInfoBuffer whose ulType_Values is V4.
        /// </summary>
        /// <param name="serverSignKey">The server signature key used to generate server signature.</param>
        /// <param name="kdcSignKey">The KDC signature key used to generate KDC signature.</param>
        /// <exception cref="ArgumentNullException">serverSignkey or kdcSignKey is null.</exception>
        public void Sign(byte[] serverSignKey, byte[] kdcSignKey)
        {
            // locate server and KDC signatures.
            PacSignatureData serverSign;
            PacSignatureData kdcSign;

            FindSignatures(out serverSign, out kdcSign);

            // types
            PAC_SIGNATURE_DATA_SignatureType_Values serversignType = serverSign.NativePacSignatureData.SignatureType;
            PAC_SIGNATURE_DATA_SignatureType_Values kdcSignType    = kdcSign.NativePacSignatureData.SignatureType;

            // clear signatures.
            int serverLength = PacSignatureData.CalculateSignatureLength(serversignType);

            serverSign.NativePacSignatureData.Signature = new byte[serverLength];

            int kdcLength = PacSignatureData.CalculateSignatureLength(kdcSignType);

            kdcSign.NativePacSignatureData.Signature = new byte[kdcLength];

            // sign server
            byte[] serverSignResult = PacSignatureData.Sign(
                ToBytes(), serversignType, serverSignKey);
            serverSign.NativePacSignatureData.Signature = serverSignResult;

            // sign KDC
            kdcSign.NativePacSignatureData.Signature = PacSignatureData.Sign(
                serverSignResult, kdcSignType, kdcSignKey);
        }
        /// <summary>
        /// Sign input plaintext bytes into checksum bytes.
        /// </summary>
        /// <param name="input">The specified plaintext bytes.</param>
        /// <param name="type">The specified checksum algorithm.</param>
        /// <param name="key">The specified key.</param>
        /// <returns>The signed checksum bytes.</returns>
        internal static byte[] Sign(byte[] input, PAC_SIGNATURE_DATA_SignatureType_Values type, byte[] key)
        {
            switch (type)
            {
            case PAC_SIGNATURE_DATA_SignatureType_Values.HMAC_SHA1_96_AES128:
                return(HmacSha1AesChecksum.GetMic(
                           key,
                           input,
                           PacSignatureData.KerbNonKerbCksumSalt,
                           AesKeyType.Aes128BitsKey));

            case PAC_SIGNATURE_DATA_SignatureType_Values.HMAC_SHA1_96_AES256:
                return(HmacSha1AesChecksum.GetMic(
                           key,
                           input,
                           PacSignatureData.KerbNonKerbCksumSalt,
                           AesKeyType.Aes256BitsKey));

            case PAC_SIGNATURE_DATA_SignatureType_Values.KERB_CHECKSUM_HMAC_MD5:
                return(HmacMd5StringChecksum.GetMic(
                           key,
                           input,
                           PacSignatureData.KerbNonKerbCksumSalt));

            default:
                throw new ArgumentOutOfRangeException("type");
            }
        }
        /// <summary>
        /// Calculate size of current instance's encoded buffer, in bytes.
        /// </summary>
        /// <returns>The size of current instance's encoded buffer, in bytes.</returns>
        internal override int CalculateSize()
        {
            PAC_SIGNATURE_DATA_SignatureType_Values type = NativePacSignatureData.SignatureType;

            // The structure contains following part:
            // SignatureType (4 bytes)
            // Signature (variable, calculated by SignatureType)
            return(sizeof(uint) + CalculateSignatureLength(type));
        }
 /// <summary>
 /// Creates an PacType instance using the specified signature types and PacInfoBuffers
 /// </summary>
 /// <param name="serverSignatureType">Server signature signatureType.</param>
 /// <param name="serverSignKey">The server signature key used to generate server signature.</param>
 /// <param name="kdcSignatureType">KDC signature Type.</param>
 /// <param name="kdcSignKey">The KDC signature key used to generate KDC signature.</param>
 /// <param name="pacInfoBuffers">A list of PacInfoBuffer used to create the PacType.
 /// Note: DO NOT include the signatures (server signature and KDC signature)!</param>
 /// <returns>The created PacType instance.</returns>
 public static PacType CreatePacType(
     PAC_SIGNATURE_DATA_SignatureType_Values serverSignatureType,
     byte[] serverSignKey,
     PAC_SIGNATURE_DATA_SignatureType_Values kdcSignatureType,
     byte[] kdcSignKey,
     params PacInfoBuffer[] pacInfoBuffers)
 {
     return(new PacType(
                serverSignatureType,
                serverSignKey,
                kdcSignatureType,
                kdcSignKey,
                pacInfoBuffers));
 }
        /// <summary>
        /// Calculate checksum length according to specified checksum type.
        /// </summary>
        /// <param name="signatureType">The specified checksum type.</param>
        /// <returns>The calculated checksum length.</returns>
        internal static int CalculateSignatureLength(PAC_SIGNATURE_DATA_SignatureType_Values signatureType)
        {
            switch (signatureType)
            {
            case PAC_SIGNATURE_DATA_SignatureType_Values.KERB_CHECKSUM_HMAC_MD5:
                return(KerbChecksumHmacMd5Size);

            case PAC_SIGNATURE_DATA_SignatureType_Values.HMAC_SHA1_96_AES128:
                return(KerbChecksumHmacSha1Size);

            case PAC_SIGNATURE_DATA_SignatureType_Values.HMAC_SHA1_96_AES256:
                return(KerbChecksumHmacSha1Size);

            default:
                throw new ArgumentOutOfRangeException("signatureType");
            }
        }
        /// <summary>
        /// Creates an PacType instance using the specified signature types and PacInfoBuffers
        /// </summary>
        /// <param name="serverSignatureType">Server signature signatureType.</param>
        /// <param name="serverSignKey">The server signature key used to generate server signature.</param>
        /// <param name="kdcSignatureType">KDC signature Type.</param>
        /// <param name="kdcSignKey">The KDC signature key used to generate KDC signature.</param>
        /// <param name="buffers">A list of PacInfoBuffer used to create the PacType.
        /// Note: DO NOT include the signatures (server signature and KDC signature)!</param>
        /// <returns>The created PacType instance.</returns>
        internal PacType(
            PAC_SIGNATURE_DATA_SignatureType_Values serverSignatureType,
            byte[] serverSignKey,
            PAC_SIGNATURE_DATA_SignatureType_Values kdcSignatureType,
            byte[] kdcSignKey,
            params PacInfoBuffer[] buffers)
        {
            if (buffers == null || buffers.Length == 0)
            {
                throw new ArgumentNullException("buffers");
            }

            InitializePacInfoBuffers(serverSignatureType, kdcSignatureType, buffers);

            InitializeNativePacType();

            Sign(serverSignKey, kdcSignKey);
            // after Sign(), the contentd of signature buffers are filled,
            // and the lengths of which are changed.
            // Then update interrelated fields, mainly totalLength and offset.
            UpdateInterrelatedFields();
        }
Example #7
0
        /// <summary>
        /// Creates an PacType instance using the specified signature types and PacInfoBuffers
        /// </summary>
        /// <param name="serverSignatureType">Server signature signatureType.</param>
        /// <param name="serverSignKey">The server signature key used to generate server signature.</param>
        /// <param name="kdcSignatureType">KDC signature Type.</param>
        /// <param name="kdcSignKey">The KDC signature key used to generate KDC signature.</param>
        /// <param name="buffers">A list of PacInfoBuffer used to create the PacType.
        /// Note: DO NOT include the signatures (server signature and KDC signature)!</param>
        /// <returns>The created PacType instance.</returns>
        internal PacType(
            PAC_SIGNATURE_DATA_SignatureType_Values serverSignatureType,
            byte[] serverSignKey,
            PAC_SIGNATURE_DATA_SignatureType_Values kdcSignatureType,
            byte[] kdcSignKey,
            params PacInfoBuffer[] buffers)
        {
            if (buffers == null || buffers.Length == 0)
            {
                throw new ArgumentNullException("buffers");
            }

            InitializePacInfoBuffers(serverSignatureType, kdcSignatureType, buffers);

            InitializeNativePacType();

            Sign(serverSignKey, kdcSignKey);
            // after Sign(), the contentd of signature buffers are filled,
            // and the lengths of which are changed.
            // Then update interrelated fields, mainly totalLength and offset.
            UpdateInterrelatedFields();
        }
Example #8
0
        /// <summary>
        /// In constructor, initialize the member PacInfoBuffer array.
        /// </summary>
        /// <param name="serverSignatureType">The specified
        /// Server Signature Type.</param>
        /// <param name="kdcSignatureType">The specified
        /// KDC Signature Type.</param>
        /// <param name="buffers">PacInfoBuffers not including signatures.</param>
        private void InitializePacInfoBuffers(
            PAC_SIGNATURE_DATA_SignatureType_Values serverSignatureType,
            PAC_SIGNATURE_DATA_SignatureType_Values kdcSignatureType,
            PacInfoBuffer[] buffers)
        {
            // allocate 2 more buffers for server signature and KDC signature.
            pacInfoBuffers = new PacInfoBuffer[buffers.Length + 2];
            for (int i = 0; i < buffers.Length; i++)
            {
                pacInfoBuffers[i] = buffers[i];
            }
            // construct a n empty server signature
            PacServerSignature serverSign = new PacServerSignature();

            serverSign.NativePacSignatureData.SignatureType = serverSignatureType;
            serverSign.NativePacSignatureData.Signature     = new byte[0];
            pacInfoBuffers[pacInfoBuffers.Length - 2]       = serverSign;
            // construct a n empty KDC signature
            PacKdcSignature kdcSign = new PacKdcSignature();

            kdcSign.NativePacSignatureData.SignatureType = kdcSignatureType;
            kdcSign.NativePacSignatureData.Signature     = new byte[0];
            pacInfoBuffers[pacInfoBuffers.Length - 1]    = kdcSign;
        }
 /// <summary>
 /// In constructor, initialize the member PacInfoBuffer array.
 /// </summary>
 /// <param name="serverSignatureType">The specified
 /// Server Signature Type.</param>
 /// <param name="kdcSignatureType">The specified
 /// KDC Signature Type.</param>
 /// <param name="buffers">PacInfoBuffers not including signatures.</param>
 private void InitializePacInfoBuffers(
     PAC_SIGNATURE_DATA_SignatureType_Values serverSignatureType,
     PAC_SIGNATURE_DATA_SignatureType_Values kdcSignatureType,
     PacInfoBuffer[] buffers)
 {
     // allocate 2 more buffers for server signature and KDC signature.
     pacInfoBuffers = new PacInfoBuffer[buffers.Length + 2];
     for (int i = 0; i < buffers.Length; i++)
     {
         pacInfoBuffers[i] = buffers[i];
     }
     // construct a n empty server signature
     PacServerSignature serverSign = new PacServerSignature();
     serverSign.NativePacSignatureData.SignatureType = serverSignatureType;
     serverSign.NativePacSignatureData.Signature = new byte[0];
     pacInfoBuffers[pacInfoBuffers.Length - 2] = serverSign;
     // construct a n empty KDC signature
     PacKdcSignature kdcSign = new PacKdcSignature();
     kdcSign.NativePacSignatureData.SignatureType = kdcSignatureType;
     kdcSign.NativePacSignatureData.Signature = new byte[0];
     pacInfoBuffers[pacInfoBuffers.Length - 1] = kdcSign;
 }
        /// <summary>
        /// Sign input plaintext bytes into checksum bytes.
        /// </summary>
        /// <param name="input">The specified plaintext bytes.</param>
        /// <param name="type">The specified checksum algorithm.</param>
        /// <param name="key">The specified key.</param>
        /// <returns>The signed checksum bytes.</returns>
        internal static byte[] Sign(byte[] input, PAC_SIGNATURE_DATA_SignatureType_Values type, byte[] key)
        {
            switch (type)
            {
                case PAC_SIGNATURE_DATA_SignatureType_Values.HMAC_SHA1_96_AES128:
                    return HmacSha1AesChecksum.GetMic(
                        key,
                        input,
                        PacSignatureData.KerbNonKerbCksumSalt,
                        AesKeyType.Aes128BitsKey);

                case PAC_SIGNATURE_DATA_SignatureType_Values.HMAC_SHA1_96_AES256:
                    return HmacSha1AesChecksum.GetMic(
                        key,
                        input,
                        PacSignatureData.KerbNonKerbCksumSalt,
                        AesKeyType.Aes256BitsKey);

                case PAC_SIGNATURE_DATA_SignatureType_Values.KERB_CHECKSUM_HMAC_MD5:
                    return HmacMd5StringChecksum.GetMic(
                        key,
                        input,
                        PacSignatureData.KerbNonKerbCksumSalt);

                default:
                    throw new ArgumentOutOfRangeException("type");
            }
        }
 /// <summary>
 /// Calculate checksum length according to specified checksum type.
 /// </summary>
 /// <param name="signatureType">The specified checksum type.</param>
 /// <returns>The calculated checksum length.</returns>
 internal static int CalculateSignatureLength(PAC_SIGNATURE_DATA_SignatureType_Values signatureType)
 {
     switch (signatureType)
     {
         case PAC_SIGNATURE_DATA_SignatureType_Values.KERB_CHECKSUM_HMAC_MD5:
             return KerbChecksumHmacMd5Size;
         case PAC_SIGNATURE_DATA_SignatureType_Values.HMAC_SHA1_96_AES128:
             return KerbChecksumHmacSha1Size;
         case PAC_SIGNATURE_DATA_SignatureType_Values.HMAC_SHA1_96_AES256:
             return KerbChecksumHmacSha1Size;
         default:
             throw new ArgumentOutOfRangeException("signatureType");
     }
 }
Example #12
0
        /// <summary>
        /// Verify Server checksum (TD section 2.8.1) and KDC checksum (TD section 2.8.2)
        /// of the PAC message.
        /// </summary>
        /// <param name="serverSignKey">The server signature key used to generate server signature.</param>
        /// <param name="kdcSignKey">The KDC signature key used to generate KDC signature.</param>
        /// <param name="isServerSignValid">true if server signature is valid.</param>
        /// <param name="isKdcSignValid">true if KDC signature is valid.</param>
        /// <exception cref="ArgumentNullException">serverSignkey or kdcSignKey is null.</exception>
        public void ValidateSign(byte[] serverSignKey, byte[] kdcSignKey,
                                 out bool isServerSignValid, out bool isKdcSignValid)
        {
            if (serverSignKey == null)
            {
                throw new ArgumentNullException("serverSignKey");
            }
            if (kdcSignKey == null)
            {
                throw new ArgumentNullException("kdcSignKey");
            }

            // locate server and KDC signatures.
            PacSignatureData serverSign;
            PacSignatureData kdcSign;

            FindSignatures(out serverSign, out kdcSign);

            // these validate operation will change signature values, so must backup and restore.
            byte[] oldServerSign = null;
            byte[] oldKdcSign    = null;

            isServerSignValid = false;
            isKdcSignValid    = false;

            try
            {
                // types
                PAC_SIGNATURE_DATA_SignatureType_Values serverSignType = serverSign.NativePacSignatureData.SignatureType;
                PAC_SIGNATURE_DATA_SignatureType_Values kdcSignType    = kdcSign.NativePacSignatureData.SignatureType;

                // backup and clear signatures.
                int serverLength = PacSignatureData.CalculateSignatureLength(serverSignType);
                oldServerSign = serverSign.NativePacSignatureData.Signature;
                serverSign.NativePacSignatureData.Signature = new byte[serverLength];

                int kdcLength = PacSignatureData.CalculateSignatureLength(kdcSignType);
                oldKdcSign = kdcSign.NativePacSignatureData.Signature;
                kdcSign.NativePacSignatureData.Signature = new byte[kdcLength];

                // validate server sign
                byte[] serverSignResult = PacSignatureData.Sign(
                    ToBytes(), serverSignType, serverSignKey);
                isServerSignValid = ArrayUtility.CompareArrays <byte>(serverSignResult, oldServerSign);

                // validate KDC sign
                byte[] kdcSignResult = PacSignatureData.Sign(
                    serverSignResult, kdcSignType, kdcSignKey);
                isKdcSignValid = ArrayUtility.CompareArrays <byte>(kdcSignResult, oldKdcSign);
            }
            finally
            {
                // restore server signature
                if (oldServerSign != null)
                {
                    serverSign.NativePacSignatureData.Signature = oldServerSign;
                }
                // restore KDC signature
                if (oldKdcSign != null)
                {
                    kdcSign.NativePacSignatureData.Signature = oldKdcSign;
                }
            }
        }
Example #13
0
        internal static int CalculateSignatureLength(IEvaluationContext context)
        {
            PAC_SIGNATURE_DATA_SignatureType_Values signatureType = (PAC_SIGNATURE_DATA_SignatureType_Values)context.Variables["SignatureType"];

            return(PacSignatureData.CalculateSignatureLength(signatureType));
        }