Ejemplo n.º 1
0
        private KDC_REQ_BODY CreateKdcRequestBody(KdcOptions kdcOptions, PrincipalName sName, AuthorizationData authData = null)
        {
            KDC_REQ_BODY kdcReqBody = this.CreateKdcRequestBody(kdcOptions, sName);

            if (authData == null)
            {
                return(kdcReqBody);
            }

            Asn1BerEncodingBuffer asnEncBuffer = new Asn1BerEncodingBuffer();

            authData.BerEncode(asnEncBuffer, true);

            EncryptedData encryptData = new EncryptedData();

            encryptData.etype = new KerbInt32(0);
            byte[] encryptAsnEncoded = asnEncBuffer.Data;
            if (this.Context.SessionKey != null && this.Context.SessionKey.keytype != null && this.Context.SessionKey.keyvalue != null && this.Context.SessionKey.keyvalue.Value != null)
            {
                encryptAsnEncoded = KerberosUtility.Encrypt(
                    (EncryptionType)this.Context.SessionKey.keytype.Value,
                    this.Context.SessionKey.keyvalue.ByteArrayValue,
                    encryptAsnEncoded,
                    (int)KeyUsageNumber.TGS_REQ_KDC_REQ_BODY_AuthorizationData
                    );

                encryptData.etype = new KerbInt32(this.Context.SessionKey.keytype.Value);
            }
            encryptData.cipher = new Asn1OctetString(encryptAsnEncoded);
            kdcReqBody.enc_authorization_data = encryptData;

            return(kdcReqBody);
        }
Ejemplo n.º 2
0
        private void SendTgsRequest(string sName, KdcOptions kdcOptions, Asn1SequenceOf <PA_DATA> seqPadata = null, AuthorizationData dataInAuthentiator = null, AuthorizationData dataInEncAuthData = null, MsgType msgType = MsgType.KRB_TGS_REQ)
        {
            if (string.IsNullOrEmpty(sName))
            {
                throw new ArgumentNullException("sName");
            }
            PrincipalName sname = new PrincipalName(new KerbInt32((int)PrincipalType.NT_SRV_INST), KerberosUtility.String2SeqKerbString(sName.Split('/')));

            KDC_REQ_BODY          kdcReqBody = this.CreateKdcRequestBody(kdcOptions, sname, dataInEncAuthData); // almost same as AS request
            Asn1BerEncodingBuffer bodyBuffer = new Asn1BerEncodingBuffer();

            kdcReqBody.BerEncode(bodyBuffer);

            ChecksumType checksumType = KerberosUtility.GetChecksumType(this.Context.SelectedEType);
            PA_DATA      paTgsReq     = CreatePaTgsReqest(checksumType, bodyBuffer.Data, dataInAuthentiator); // use AS session key encrypt authenticator.

            Asn1SequenceOf <PA_DATA> tempPaData = null;

            if (seqPadata == null || seqPadata.Elements == null || seqPadata.Elements.Length == 0)
            {
                tempPaData = new Asn1SequenceOf <PA_DATA>(new PA_DATA[] { paTgsReq });
            }
            else
            {
                PA_DATA[] paDatas = new PA_DATA[seqPadata.Elements.Length + 1];
                Array.Copy(seqPadata.Elements, paDatas, seqPadata.Elements.Length);
                paDatas[seqPadata.Elements.Length] = paTgsReq;
                tempPaData = new Asn1SequenceOf <PA_DATA>(paDatas);
            }

            KerberosTgsRequest tgsRequest = new KerberosTgsRequest(KerberosConstValue.KERBEROSV5, kdcReqBody, tempPaData, Context.TransportType);

            tgsRequest.Request.msg_type.Value = (long)msgType;
            this.client.SendPdu(tgsRequest);
        }
Ejemplo n.º 3
0
        public PaEncTimeStamp(string timeStamp, int usec, EncryptionType eType, string password, string salt)
        {
            this.TimeStamp = timeStamp;
            this.Usec      = usec;
            byte[] key = KeyGenerator.MakeKey(eType, password, salt);
            this.Key = new EncryptionKey(new KerbInt32((long)eType), new Asn1OctetString(key));

            // create a timestamp
            PA_ENC_TS_ENC         paEncTsEnc          = new PA_ENC_TS_ENC(new KerberosTime(this.TimeStamp), new Microseconds(this.Usec));
            Asn1BerEncodingBuffer currTimeStampBuffer = new Asn1BerEncodingBuffer();

            paEncTsEnc.BerEncode(currTimeStampBuffer);
            var rawData = currTimeStampBuffer.Data;

            KerberosUtility.OnDumpMessage("KRB5:PA-ENC-TS-ENC",
                                          "Encrypted Timestamp Pre-authentication",
                                          KerberosUtility.DumpLevel.PartialMessage,
                                          rawData);
            // encrypt the timestamp
            byte[] encTimeStamp = KerberosUtility.Encrypt((EncryptionType)this.Key.keytype.Value,
                                                          this.Key.keyvalue.ByteArrayValue,
                                                          rawData,
                                                          (int)KeyUsageNumber.PA_ENC_TIMESTAMP);

            // create an encrypted timestamp
            PA_ENC_TIMESTAMP paEncTimeStamp =
                new PA_ENC_TIMESTAMP(new KerbInt32(this.Key.keytype.Value), null, new Asn1OctetString(encTimeStamp));
            Asn1BerEncodingBuffer paEncTimestampBuffer = new Asn1BerEncodingBuffer();

            paEncTimeStamp.BerEncode(paEncTimestampBuffer, true);

            Data = new PA_DATA(new KerbInt32((long)PaDataType.PA_ENC_TIMESTAMP), new Asn1OctetString(paEncTimestampBuffer.Data));
        }
        public static void UpdateAuthDataInTicket(Ticket ticket, byte[] key, AuthorizationData authorizationData)
        {
            EncryptionType encryptType = (EncryptionType)ticket.enc_part.etype.Value;

            byte[] clearText = KileUtility.Decrypt(
                encryptType,
                key,
                ticket.enc_part.cipher.ByteArrayValue,
                (int)KeyUsageNumber.AS_REP_TicketAndTGS_REP_Ticket);

            // Decode the ticket.
            Asn1DecodingBuffer decodeBuffer  = new Asn1DecodingBuffer(clearText);
            EncTicketPart      encTicketPart = new EncTicketPart();

            encTicketPart.BerDecode(decodeBuffer);

            // Set with new authorization data
            encTicketPart.authorization_data = authorizationData;
            Asn1BerEncodingBuffer ticketBerBuffer = new Asn1BerEncodingBuffer();

            encTicketPart.BerEncode(ticketBerBuffer, true);

            byte[] cipherData = KileUtility.Encrypt(
                encryptType,
                key,
                ticketBerBuffer.Data,
                (int)KeyUsageNumber.AS_REP_TicketAndTGS_REP_Ticket);
            ticket.enc_part = new EncryptedData(new KerbInt32((int)encryptType), null, new Asn1OctetString(cipherData));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Encode this class into byte array.
        /// </summary>
        /// <returns>The byte array of the class.</returns>
        public override byte[] ToBytes()
        {
            Asn1BerEncodingBuffer asBerBuffer = new Asn1BerEncodingBuffer();

            this.Request.BerEncode(asBerBuffer, true);
            return(asBerBuffer.Data);
        }
        /// <summary>
        /// Encode this class into byte array.
        /// </summary>
        /// <returns>The byte array of the class.</returns>
        public byte[] ToBytes()
        {
            Asn1BerEncodingBuffer asBerBuffer = new Asn1BerEncodingBuffer();

            this.Message.BerEncode(asBerBuffer, true);
            return(asBerBuffer.Data);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Encode an Asn.1 formatted type into a byte array
        /// </summary>
        /// <param name="type">Asn.1 formatted type to be encoded</param>
        /// <returns>encoded byte array</returns>
        public static byte[] EncodeAsn1(Asn1Object type)
        {
            Asn1BerEncodingBuffer buffer = new Asn1BerEncodingBuffer();

            type.BerEncode(buffer);

            return(buffer.Data);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Client initialize with server token
        /// </summary>
        /// <param name="serverToken">Server token</param>
        private void ClientInitialize(byte[] serverToken)
        {
            KerberosApResponse apRep = this.GetApResponseFromToken(serverToken, KerberosConstValue.GSSToken.GSSAPI);

            this.VerifyApResponse(apRep);

            token = null;
            if ((contextAttribute & ClientSecurityContextAttribute.DceStyle) == ClientSecurityContextAttribute.DceStyle)
            {
                KerberosApResponse apResponse = this.CreateApResponse(null);

                var apBerBuffer = new Asn1BerEncodingBuffer();

                if (apResponse.ApEncPart != null)
                {
                    // Encode enc_part
                    apResponse.ApEncPart.BerEncode(apBerBuffer, true);

                    EncryptionKey key = this.Context.ApSessionKey;

                    if (key == null || key.keytype == null || key.keyvalue == null || key.keyvalue.Value == null)
                    {
                        throw new ArgumentException("Ap session key is not valid");
                    }

                    // Encrypt enc_part
                    EncryptionType eType      = (EncryptionType)key.keytype.Value;
                    byte[]         cipherData = KerberosUtility.Encrypt(
                        eType,
                        key.keyvalue.ByteArrayValue,
                        apBerBuffer.Data,
                        (int)KeyUsageNumber.AP_REP_EncAPRepPart);
                    apResponse.Response.enc_part = new EncryptedData(new KerbInt32((int)eType), null, new Asn1OctetString(cipherData));
                }

                // Encode AP Response
                apResponse.Response.BerEncode(apBerBuffer, true);

                if ((this.Context.ChecksumFlag & ChecksumFlags.GSS_C_DCE_STYLE) == ChecksumFlags.GSS_C_DCE_STYLE)
                {
                    // In DCE mode, the AP-REP message MUST NOT have GSS-API wrapping.
                    // It is sent as is without encapsulating it in a header ([RFC2743] section 3.1).
                    this.token = apBerBuffer.Data;
                }
                else
                {
                    this.token = KerberosUtility.AddGssApiTokenHeader(ArrayUtility.ConcatenateArrays(
                                                                          BitConverter.GetBytes(KerberosUtility.ConvertEndian((ushort)TOK_ID.KRB_AP_REP)),
                                                                          apBerBuffer.Data));
                }
            }

            this.needContinueProcessing = false;      // SEC_E_OK;
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Create an instance.
        /// </summary>
        public KpasswordRequest(KerberosTicket ticket, Authenticator authenticator, string newPwd, bool isAuthErrorRequired = false)
        {
            //Create KerberosApRequest
            long              pvno   = KerberosConstValue.KERBEROSV5;
            APOptions         option = new APOptions(KerberosUtility.ConvertInt2Flags((int)ApOptions.None));
            KerberosApRequest ap_req = new KerberosApRequest(pvno, option, ticket, authenticator, KeyUsageNumber.AP_REQ_Authenticator);
            //Create KRB_PRIV
            ChangePasswdData pwd_data = new ChangePasswdData(new Asn1OctetString(newPwd), null, null);

            priv_enc_part            = new EncKrbPrivPart();
            priv_enc_part.user_data  = pwd_data.newpasswd;
            priv_enc_part.usec       = authenticator.cusec;
            priv_enc_part.seq_number = authenticator.seq_number;
            priv_enc_part.s_address  = new HostAddress(new KerbInt32((int)AddressType.NetBios), new Asn1OctetString(Encoding.ASCII.GetBytes(System.Net.Dns.GetHostName())));
            Asn1BerEncodingBuffer asnBuffPriv = new Asn1BerEncodingBuffer();

            priv_enc_part.BerEncode(asnBuffPriv, true);
            byte[] encAsnEncodedPriv = null;

            if (!isAuthErrorRequired)
            {
                encAsnEncodedPriv = KerberosUtility.Encrypt((EncryptionType)authenticator.subkey.keytype.Value,
                                                            authenticator.subkey.keyvalue.ByteArrayValue,
                                                            asnBuffPriv.Data,
                                                            (int)KeyUsageNumber.KRB_PRIV_EncPart);
            }
            else
            {
                encAsnEncodedPriv = KerberosUtility.Encrypt((EncryptionType)authenticator.subkey.keytype.Value,
                                                            authenticator.subkey.keyvalue.ByteArrayValue,
                                                            asnBuffPriv.Data,
                                                            (int)KeyUsageNumber.None);
            }

            var encrypted = new EncryptedData();

            encrypted.etype  = new KerbInt32(authenticator.subkey.keytype.Value);
            encrypted.cipher = new Asn1OctetString(encAsnEncodedPriv);
            KRB_PRIV krb_priv = new KRB_PRIV(new Asn1Integer(pvno), new Asn1Integer((long)MsgType.KRB_PRIV), encrypted);

            //Calculate the msg_length and ap_req_length
            krb_priv.BerEncode(privBuffer, true);
            ap_req.Request.BerEncode(apBuffer, true);
            version       = 0x0001;
            ap_req_length = (ushort)apBuffer.Data.Length;
            msg_length    = (ushort)(ap_req_length + privBuffer.Data.Length + 3 * sizeof(ushort));
            //Convert Endian
            version       = KerberosUtility.ConvertEndian(version);
            ap_req_length = KerberosUtility.ConvertEndian(ap_req_length);
            msg_length    = KerberosUtility.ConvertEndian(msg_length);
        }
        public byte[] ToBytes(TransportType transportType)
        {
            Asn1BerEncodingBuffer asBerBuffer = new Asn1BerEncodingBuffer();

            this.FastReq.BerEncode(asBerBuffer, true);
            if (transportType == TransportType.TCP)
            {
                return(KerberosUtility.WrapLength(asBerBuffer.Data, true));
            }
            else
            {
                return(asBerBuffer.Data);
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Encode the Krb Error to bytes
        /// </summary>
        /// <param name="buffer">The byte array to be decoded.</param>
        public override byte[] ToBytes()
        {
            Asn1BerEncodingBuffer errorBerBuffer = new Asn1BerEncodingBuffer();

            this.KrbError.BerEncode(errorBerBuffer, true);

            if (transportType == TransportType.TCP)
            {
                return(KerberosUtility.WrapLength(errorBerBuffer.Data, true));
            }
            else
            {
                return(errorBerBuffer.Data);
            }
        }
Ejemplo n.º 12
0
        private EncryptedData EncryptTicket(EncTicketPart encTicketPart, EncryptionKey serviceKey)
        {
            Asn1BerEncodingBuffer encodeBuffer = new Asn1BerEncodingBuffer();

            encTicketPart.BerEncode(encodeBuffer, true);
            byte[] encData = KerberosUtility.Encrypt(
                (EncryptionType)serviceKey.keytype.Value,
                serviceKey.keyvalue.ByteArrayValue,
                encodeBuffer.Data,
                (int)KeyUsageNumber.AS_REP_TicketAndTGS_REP_Ticket);

            return(new EncryptedData(
                       new KerbInt32(serviceKey.keytype.Value),
                       null,
                       new Asn1OctetString(encData)));
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Encode this class into byte array.
        /// </summary>
        /// <returns>The byte array of the class.</returns>
        public override byte[] ToBytes()
        {
            Asn1BerEncodingBuffer tgsBerBuffer = new Asn1BerEncodingBuffer();

            this.Request.BerEncode(tgsBerBuffer, true);
            KerberosUtility.OnDumpMessage("KRB5:KrbMessage",
                                          "Kerberos Message",
                                          KerberosUtility.DumpLevel.WholeMessage,
                                          tgsBerBuffer.Data);
            if (transportType == TransportType.TCP)
            {
                return(KerberosUtility.WrapLength(tgsBerBuffer.Data, true));
            }
            else
            {
                return(tgsBerBuffer.Data);
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Construct PA_TGS_REQ for TGS request.
        /// </summary>
        /// <param name="cRealm">This field contains the name of the realm in which the client is registered and in
        /// which initial authentication took place.</param>
        /// <param name="cName">This field contains the name part of the client's principal identifier.</param>
        /// <param name="checksumType">The checksum type in Authenticator.</param>
        /// <param name="checksumBody">The data to compute checksum.</param>
        /// <returns>The constructed PaData.</returns>
        private PA_DATA ConstructTgsPaData(Realm cRealm, PrincipalName cName, ChecksumType checksumType, byte[] checksumBody)
        {
            AP_REQ request = new AP_REQ();

            KerbAuthDataTokenRestrictions adRestriction =
                ConstructKerbAuthDataTokenRestrictions(0,
                                                       (uint)LSAP_TOKEN_INFO_INTEGRITY_Flags.FULL_TOKEN,
                                                       (uint)LSAP_TOKEN_INFO_INTEGRITY_TokenIL.Medium,
                                                       new Guid().ToString());
            AuthorizationData authData = ConstructAuthorizationData(adRestriction);

            // create and encrypt authenticator
            Authenticator authenticator = CreateAuthenticator(cRealm,
                                                              cName,
                                                              checksumType,
                                                              0,
                                                              0,
                                                              null,
                                                              authData,
                                                              context.TgsSessionKey,
                                                              checksumBody);
            Asn1BerEncodingBuffer asnBuffPlainAuthenticator = new Asn1BerEncodingBuffer();

            authenticator.BerEncode(asnBuffPlainAuthenticator, true);
            byte[] encAsnEncodedAuth =
                KileUtility.Encrypt((EncryptionType)context.TgsSessionKey.keytype.Value,
                                    context.TgsSessionKey.keyvalue.ByteArrayValue,
                                    asnBuffPlainAuthenticator.Data,
                                    (int)KeyUsageNumber.TG_REQ_PA_TGS_REQ_padataOR_AP_REQ_Authenticator);
            request.authenticator        = new EncryptedData();
            request.authenticator.etype  = new Microsoft.Protocols.TestTools.StackSdk.Security.KerberosLib.KerbInt32(context.TgsSessionKey.keytype.Value);
            request.authenticator.cipher = new Asn1OctetString(encAsnEncodedAuth);

            // create AP request
            request.ap_options = new APOptions(KileUtility.ConvertInt2Flags((int)ApOptions.None));
            request.msg_type   = new Asn1Integer((int)MsgType.KRB_AP_REQ);
            request.pvno       = new Asn1Integer(ConstValue.KERBEROSV5);
            request.ticket     = context.TgsTicket;
            Asn1BerEncodingBuffer apBerBuffer = new Asn1BerEncodingBuffer();

            request.BerEncode(apBerBuffer, true);

            return(new PA_DATA(new KerbInt32((int)PaDataType.PA_TGS_REQ), new Asn1OctetString(apBerBuffer.Data)));
        }
        /// <summary>
        /// Converts the packet to a byte array that transmits on the wire.
        /// </summary>
        /// <returns>The byte array.</returns>
        public override byte[] ToBytes()
        {
            Asn1BerEncodingBuffer berEncoder = new Asn1BerEncodingBuffer();

            LdapV2.LDAPMessage ldapv2Msg = ldapMessagev2 as LdapV2.LDAPMessage;
            if (ldapv2Msg != null)
            {
                ldapv2Msg.BerEncode(berEncoder);
                return(berEncoder.Data);
            }

            LdapV3.LDAPMessage ldapv3Msg = ldapMessagev3 as LdapV3.LDAPMessage;
            if (ldapv3Msg != null)
            {
                ldapv3Msg.BerEncode(berEncoder);
                return(berEncoder.Data);
            }

            throw new StackException("The LDAP v2 and v3 messages cannot be both null");
        }
        public static byte[] EncodeInitialNegToken(byte[] token,
                                                   KerberosConstValue.OidPkt oidPkt)
        {
            int[] oidInt;
            if (oidPkt == KerberosConstValue.OidPkt.KerberosToken)
            {
                oidInt = KerberosConstValue.GetKerberosOidInt();
            }
            else if (oidPkt == KerberosConstValue.OidPkt.MSKerberosToken)
            {
                oidInt = KerberosConstValue.GetMsKerberosOidInt();
            }
            else
            {
                throw new NotSupportedException("oid not support");
            }

            MechTypeList mechTypeList = new MechTypeList(
                new MechType[]
            {
                new MechType(oidInt)
            }
                );

            Asn1OctetString octetString = new Asn1OctetString(token);
            NegTokenInit    init        = new NegTokenInit(mechTypeList, null, new Asn1OctetString(octetString.ByteArrayValue), new Asn1OctetString((byte[])null));

            NegotiationToken negToken = new NegotiationToken(NegotiationToken.negTokenInit, init);

            MechType        spnegoMech = new MechType(KerberosConstValue.GetSpngOidInt());
            InitialNegToken initToken  = new InitialNegToken(spnegoMech, negToken);

            Asn1BerEncodingBuffer buffer = new Asn1BerEncodingBuffer();

            initToken.BerEncode(buffer);

            return(buffer.Data);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Create an instance.
        /// </summary>
        public KerberosApRequest(long pvno, APOptions ap_options, KerberosTicket ticket, Authenticator authenticator, KeyUsageNumber keyUsageNumber)
        {
            Asn1BerEncodingBuffer asnBuffPlainAuthenticator = new Asn1BerEncodingBuffer();

            authenticator.BerEncode(asnBuffPlainAuthenticator, true);
            KerberosUtility.OnDumpMessage("KRB5:Authenticator",
                                          "Authenticator in AP-REQ structure",
                                          KerberosUtility.DumpLevel.PartialMessage,
                                          asnBuffPlainAuthenticator.Data);
            byte[] encAsnEncodedAuth = KerberosUtility.Encrypt((EncryptionType)ticket.SessionKey.keytype.Value,
                                                               ticket.SessionKey.keyvalue.ByteArrayValue,
                                                               asnBuffPlainAuthenticator.Data,
                                                               (int)keyUsageNumber);
            var encrypted = new EncryptedData();

            encrypted.etype  = new KerbInt32(ticket.SessionKey.keytype.Value);
            encrypted.cipher = new Asn1OctetString(encAsnEncodedAuth);

            long msg_type = (long)MsgType.KRB_AP_REQ;

            Request       = new AP_REQ(new Asn1Integer(pvno), new Asn1Integer(msg_type), ap_options, ticket.Ticket, encrypted);
            Authenticator = authenticator;
        }
Ejemplo n.º 18
0
        public PaEncryptedChallenge(EncryptionType type, string timeStamp, int usec, EncryptionKey armorKey, EncryptionKey userLongTermKey)
        {
            this.TimeStamp = timeStamp;
            this.Usec      = usec;

            var keyvalue = KeyGenerator.KrbFxCf2(
                (EncryptionType)armorKey.keytype.Value,
                armorKey.keyvalue.ByteArrayValue,
                userLongTermKey.keyvalue.ByteArrayValue,
                "clientchallengearmor",
                "challengelongterm");

            switch (type)
            {
            case EncryptionType.AES256_CTS_HMAC_SHA1_96:
            {
                var key = new EncryptionKey(new KerbInt32((long)EncryptionType.AES256_CTS_HMAC_SHA1_96), new Asn1OctetString(keyvalue));
                this.Key = key;
                break;
            }

            case EncryptionType.RC4_HMAC:
            {
                var key = new EncryptionKey(new KerbInt32((long)EncryptionType.RC4_HMAC), new Asn1OctetString(keyvalue));
                this.Key = key;
                break;
            }

            default:
                throw new ArgumentException("Unsupported encryption type.");
            }

            // create a timestamp
            PA_ENC_TS_ENC         paEncTsEnc          = new PA_ENC_TS_ENC(new KerberosTime(this.TimeStamp), new Microseconds(this.Usec));
            Asn1BerEncodingBuffer currTimeStampBuffer = new Asn1BerEncodingBuffer();

            paEncTsEnc.BerEncode(currTimeStampBuffer);

            var rawData = currTimeStampBuffer.Data;

            KerberosUtility.OnDumpMessage("KRB5:PA-ENC-TS-ENC",
                                          "Encrypted Timestamp Pre-authentication",
                                          KerberosUtility.DumpLevel.PartialMessage,
                                          rawData);

            // encrypt the timestamp
            byte[] encTimeStamp = KerberosUtility.Encrypt((EncryptionType)this.Key.keytype.Value,
                                                          this.Key.keyvalue.ByteArrayValue,
                                                          rawData,
                                                          (int)KeyUsageNumber.ENC_CHALLENGE_CLIENT);

            EncryptedChallenge encryptedChallenge = new EncryptedChallenge(new KerbInt32((long)this.Key.keytype.Value),
                                                                           null,
                                                                           new Asn1OctetString(encTimeStamp));

            Asn1BerEncodingBuffer paEncTimestampBuffer = new Asn1BerEncodingBuffer();

            encryptedChallenge.BerEncode(paEncTimestampBuffer, true);

            Data = new PA_DATA(new KerbInt32((long)PaDataType.PA_ENCRYPTED_CHALLENGE), new Asn1OctetString(paEncTimestampBuffer.Data));
        }
Ejemplo n.º 19
0
        public KileTgsRequest CreateTgsRequest(
            Realm cRealm,
            PrincipalName cName,
            PrincipalName sName,
            KRBFlags kdcOptions,
            KerbUInt32 nonce,
            Realm realm,
            Asn1SequenceOf <PA_DATA> paData,
            ChecksumType checksumType,
            Ticket additionalTicket,
            AuthorizationData authorizationData)
        {
            if (cRealm == null)
            {
                throw new ArgumentNullException("cRealm");
            }
            if (cName == null)
            {
                throw new ArgumentNullException("cName");
            }
            if (sName == null)
            {
                throw new ArgumentNullException("sName");
            }
            if (realm == null)
            {
                throw new ArgumentNullException("realm");
            }

            KileTgsRequest request = new KileTgsRequest(context);

            request.Request.msg_type = new Asn1Integer((int)MsgType.KRB_TGS_REQ);
            request.Request.pvno     = new Asn1Integer(ConstValue.KERBEROSV5);

            #region construct req_body
            request.Request.req_body             = new KDC_REQ_BODY();
            request.Request.req_body.kdc_options = new KDCOptions(KileUtility.ConvertInt2Flags((int)kdcOptions));
            request.Request.req_body.nonce       = nonce;
            request.Request.req_body.till        = new KerberosTime(ConstValue.TGT_TILL_TIME);
            request.Request.req_body.etype       = context.ClientEncryptionTypes;
            request.Request.req_body.realm       = realm;

            if (additionalTicket != null)
            {
                request.Request.req_body.additional_tickets = new Asn1SequenceOf <Ticket>(new Ticket[] { additionalTicket });
            }
            request.Request.req_body.sname = sName;
            request.EncAuthorizationData   = authorizationData;

            if (authorizationData != null)
            {
                Asn1BerEncodingBuffer asnBuffer = new Asn1BerEncodingBuffer();
                authorizationData.BerEncode(asnBuffer, true);

                request.Request.req_body.enc_authorization_data       = new EncryptedData();
                request.Request.req_body.enc_authorization_data.etype = new KerbInt32(0);
                byte[] encAsnEncoded = asnBuffer.Data;
                if (context.TgsSessionKey != null && context.TgsSessionKey.keytype != null &&
                    context.TgsSessionKey.keyvalue != null && context.TgsSessionKey.keyvalue.Value != null)
                {
                    encAsnEncoded = KileUtility.Encrypt((EncryptionType)context.TgsSessionKey.keytype.Value,
                                                        context.TgsSessionKey.keyvalue.ByteArrayValue,
                                                        asnBuffer.Data,
                                                        (int)KeyUsageNumber.TGS_REQ_KDC_REQ_BODY_AuthorizationData);
                    request.Request.req_body.enc_authorization_data.etype =
                        new KerbInt32(context.TgsSessionKey.keytype.Value);
                }

                request.Request.req_body.enc_authorization_data.cipher = new Asn1OctetString(encAsnEncoded);
            }
            #endregion construct req_body

            #region construct PA_DATA
            Asn1BerEncodingBuffer bodyBuffer = new Asn1BerEncodingBuffer();
            request.Request.req_body.BerEncode(bodyBuffer);
            PA_DATA tgsPaData = ConstructTgsPaData(cRealm, cName, checksumType, bodyBuffer.Data);

            request.Request.padata = new Asn1SequenceOf <PA_DATA>();
            if (paData == null || paData.Elements == null || paData.Elements.Length == 0)
            {
                request.Request.padata.Elements = new PA_DATA[] { tgsPaData };
            }
            else
            {
                request.Request.padata.Elements = new PA_DATA[paData.Elements.Length + 1];
                Array.Copy(paData.Elements, request.Request.padata.Elements, paData.Elements.Length);
                request.Request.padata.Elements[paData.Elements.Length] = tgsPaData;
            }
            #endregion construct PA_DATA

            return(request);
        }
Ejemplo n.º 20
0
        private void Smb2KerberosAuthentication(CaseVariant variant)
        {
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Initialize Kerberos Functional Client");
            KerberosFunctionalClient kerberosClient = new KerberosFunctionalClient(
                TestConfig.DomainName,
                TestConfig.UserName,
                TestConfig.UserPassword,
                KerberosAccountType.User,
                KDCIP,
                KDCPort,
                TransportType.TCP,
                OidPkt,
                BaseTestSite);

            #region Service Ticket
            EncryptionKey serviceKey;
            EncTicketPart encTicketPart = RetrieveAndDecryptServiceTicket(kerberosClient, out serviceKey);

            Ticket serviceTicket = kerberosClient.Context.Ticket.Ticket;

            Realm crealm = serviceTicket.realm;
            BaseTestSite.Assert.AreEqual(TestConfig.DomainName.ToLower(),
                                         encTicketPart.crealm.Value.ToLower(),
                                         "Realm name in service ticket encrypted part should match as expected, case insensitive");
            BaseTestSite.Assert.AreEqual(TestConfig.UserName.ToLower(),
                                         KerberosUtility.PrincipalName2String(encTicketPart.cname).ToLower(),
                                         "User name in service ticket encrypted part should match as expected, case insensitive.");

            if (variant.HasFlag(CaseVariant.AUTHDATA_UNKNOWN_TYPE_IN_TKT))
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Add a type-unknown AuthorizationData to the ticket");
                AuthorizationDataElement unknownElement = GenerateUnKnownAuthorizationDataElement();
                AppendNewAuthDataElement(encTicketPart.authorization_data, unknownElement);
            }

            if (variant.HasFlag(CaseVariant.AUTHDATA_UNKNOWN_TYPE_IN_TKT_OPTIONAL))
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Add a type-unknown AuthorizationData which is inside AD_IF_RELEVANT to the ticket");
                AuthorizationDataElement unknownElement    = GenerateUnKnownAuthorizationDataElement();
                AD_IF_RELEVANT           ifRelavantElement =
                    new AD_IF_RELEVANT(new[] { unknownElement });
                var dataBuffer = new Asn1BerEncodingBuffer();
                ifRelavantElement.BerEncode(dataBuffer);
                AuthorizationDataElement unknownElementOptional =
                    new AuthorizationDataElement(new KerbInt32((long)AuthorizationData_elementType.AD_IF_RELEVANT), new Asn1OctetString(dataBuffer.Data));
                AppendNewAuthDataElement(encTicketPart.authorization_data, unknownElementOptional);
            }

            if (variant.HasFlag(CaseVariant.TICKET_NOT_VALID))
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Change the Ticket start time to tomorrow");
                DateTime tomorrow       = DateTime.Now.AddDays(1);
                string   kerbTimeString = tomorrow.ToUniversalTime().ToString("yyyyMMddhhmmssZ");
                encTicketPart.starttime = new KerberosTime(kerbTimeString, true);
            }
            if (variant.HasFlag(CaseVariant.TICKET_EXPIRED))
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Change the Ticket end time to yesterday");
                DateTime yesterday      = DateTime.Now.AddDays(-1);
                string   kerbTimeString = yesterday.ToUniversalTime().ToString("yyyyMMddhhmmssZ");
                encTicketPart.endtime = new KerberosTime(kerbTimeString, true);
            }

            if (variant.HasFlag(CaseVariant.TICKET_WRONG_ENC_KEY))
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Modify the Ticket, making it encrypted with wrong key");
                serviceKey = KerberosUtility.GenerateKey(serviceKey);
            }

            EncryptedData data = EncryptTicket(encTicketPart, serviceKey);
            serviceTicket.enc_part = data;

            if (variant.HasFlag(CaseVariant.TICKET_WRONG_REALM))
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Change the Realm in the Ticket to an unknown realm");
                serviceTicket.realm = new Realm("kerb.com");
            }
            if (variant.HasFlag(CaseVariant.TICKET_WRONG_SNAME))
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Change the SNAME in the Ticket to an unknown service name");
                serviceTicket.sname = new PrincipalName(new KerbInt32((long)PrincipalType.NT_SRV_INST),
                                                        KerberosUtility.String2SeqKerbString("UnknownService", TestConfig.DomainName));
            }
            if (variant.HasFlag(CaseVariant.TICKET_WRONG_KVNO))
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep,
                                     "Change the KVNO in the Ticket to an invalid Key Version Number (Int32.MaxValue)");
                const int invalidKvno = System.Int32.MaxValue;
                serviceTicket.enc_part.kvno = new KerbInt32(invalidKvno);
            }
            #endregion

            #region Authenticator
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Create Authenticator");
            EncryptionKey subkey = KerberosUtility.GenerateKey(kerberosClient.Context.SessionKey);
            PrincipalName cname;
            if (variant.HasFlag(CaseVariant.AUTHENTICATOR_CNAME_NOT_MATCH))
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Use wrong cname in the Authenticator");
                cname = new PrincipalName(new KerbInt32((long)PrincipalType.NT_PRINCIPAL),
                                          KerberosUtility.String2SeqKerbString(TestConfig.NonAdminUserName, TestConfig.DomainName));
            }
            else
            {
                cname = kerberosClient.Context.CName.Name;
            }

            Authenticator authenticator = CreateAuthenticator(cname, crealm, subkey);
            if (variant.HasFlag(CaseVariant.AUTHENTICATOR_CREALM_NOT_MATCH))
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Use wrong crealm in the Authenticator");
                authenticator.crealm = new Realm("kerb.com");
            }

            if (variant.HasFlag(CaseVariant.AUTHENTICATOR_EXCEED_TIME_SKEW))
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Change the ctime in the Authenticator to one hour later");
                DateTime oneHourLater   = DateTime.Now.AddHours(1);
                string   kerbTimeString = oneHourLater.ToUniversalTime().ToString("yyyyMMddhhmmssZ");
                authenticator.ctime = new KerberosTime(kerbTimeString, true);
            }

            if (variant.HasFlag(CaseVariant.AUTHDATA_UNKNOWN_TYPE_IN_AUTHENTICATOR))
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Add a type-unknown AuthorizationData to the Authenticator");
                AuthorizationDataElement unknownElement = GenerateUnKnownAuthorizationDataElement();
                authenticator.authorization_data = new AuthorizationData(new[] { unknownElement });
            }

            if (variant.HasFlag(CaseVariant.AUTHDATA_UNKNOWN_TYPE_IN_AUTHENTICATOR_OPTIONAL))
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep,
                                     "Add a type-unknown AuthorizationData which is inside AD_IF_RELEVANT to the Authenticator");
                AuthorizationDataElement unknownElement    = GenerateUnKnownAuthorizationDataElement();
                AD_IF_RELEVANT           ifRelavantElement =
                    new AD_IF_RELEVANT(new[] { unknownElement });
                var dataBuffer = new Asn1BerEncodingBuffer();
                ifRelavantElement.BerEncode(dataBuffer);
                AuthorizationDataElement unknownElementOptional =
                    new AuthorizationDataElement(new KerbInt32((long)AuthorizationData_elementType.AD_IF_RELEVANT), new Asn1OctetString(dataBuffer.Data));
                authenticator.authorization_data = new AuthorizationData(new[] { unknownElementOptional });
            }

            #endregion

            #region AP Request
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Create AP Request");
            if (variant.HasFlag(CaseVariant.AUTHENTICATOR_WRONG_ENC_KEY))
            {
                BaseTestSite.Log.Add(LogEntryKind.TestStep, "Use wrong key to encrypt the Authenticator");
                kerberosClient.Context.Ticket.SessionKey = KerberosUtility.GenerateKey(kerberosClient.Context.Ticket.SessionKey);
            }
            KerberosApRequest request = new KerberosApRequest(
                kerberosClient.Context.Pvno,
                new APOptions(KerberosUtility.ConvertInt2Flags((int)ApOptions.MutualRequired)),
                kerberosClient.Context.Ticket,
                authenticator,
                KeyUsageNumber.AP_REQ_Authenticator
                );
            #endregion

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Create GSS Token");
            byte[] token = KerberosUtility.AddGssApiTokenHeader(request, OidPkt, GssToken);

            Smb2FunctionalClientForKerbAuth smb2Client = new Smb2FunctionalClientForKerbAuth(TestConfig.Timeout, TestConfig, BaseTestSite);
            smb2Client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);

            #region Check the result

            byte[] repToken;
            uint   status = DoSessionSetupWithGssToken(smb2Client, token, out repToken);

            if (variant.HasFlag(CaseVariant.AUTHENTICATOR_CNAME_NOT_MATCH) || variant.HasFlag(CaseVariant.AUTHENTICATOR_CREALM_NOT_MATCH))
            {
                BaseTestSite.Assert.AreNotEqual(Smb2Status.STATUS_SUCCESS, status,
                                                "Session Setup should fail because the cname or crealm in the authenticator does not match the same field in the Ticket");
                if (TestConfig.IsWindowsPlatform)
                {
                    KerberosKrbError krbError = kerberosClient.GetKrbErrorFromToken(repToken);
                    BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KRB_AP_ERR_BADMATCH, krbError.ErrorCode,
                                                 "SMB Server should return {0}", KRB_ERROR_CODE.KRB_AP_ERR_BADMATCH);
                }
                smb2Client.Disconnect();
                return;
            }
            if (variant.HasFlag(CaseVariant.AUTHENTICATOR_WRONG_ENC_KEY) || variant.HasFlag(CaseVariant.TICKET_WRONG_ENC_KEY))
            {
                BaseTestSite.Assert.AreNotEqual(Smb2Status.STATUS_SUCCESS, status,
                                                "Session Setup should fail because Ticket or Authenticator cannot be correctly decrypted");
                if (TestConfig.IsWindowsPlatform)
                {
                    KerberosKrbError krbError = kerberosClient.GetKrbErrorFromToken(repToken);
                    BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KRB_AP_ERR_MODIFIED, krbError.ErrorCode,
                                                 "SMB Server should return {0}", KRB_ERROR_CODE.KRB_AP_ERR_MODIFIED);
                }
                smb2Client.Disconnect();
                return;
            }
            if (variant.HasFlag(CaseVariant.AUTHENTICATOR_EXCEED_TIME_SKEW))
            {
                BaseTestSite.Assert.AreNotEqual(Smb2Status.STATUS_SUCCESS, status,
                                                "Session Setup should fail because the server time and the client time " +
                                                "in the Authenticator differ by (1 hour) more than the allowable clock skew");
                if (TestConfig.IsWindowsPlatform)
                {
                    KerberosKrbError krbError = kerberosClient.GetKrbErrorFromToken(repToken);
                    BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KRB_AP_ERR_SKEW, krbError.ErrorCode,
                                                 "SMB Server should return {0}", KRB_ERROR_CODE.KRB_AP_ERR_SKEW);
                }
                smb2Client.Disconnect();
                return;
            }
            if (variant.HasFlag(CaseVariant.TICKET_WRONG_KVNO) ||
                variant.HasFlag(CaseVariant.TICKET_WRONG_REALM) ||
                variant.HasFlag(CaseVariant.TICKET_WRONG_SNAME))
            {
                BaseTestSite.Log.Add(LogEntryKind.Comment, "If decryption fails, server would try other keys");
            }
            if (variant.HasFlag(CaseVariant.TICKET_NOT_VALID))
            {
                BaseTestSite.Assert.AreNotEqual(Smb2Status.STATUS_SUCCESS, status,
                                                "Session Setup should fail because the starttime (tomorrow) in the Ticket " +
                                                "is later than the current time by more than the allowable clock skew");
                if (TestConfig.IsWindowsPlatform)
                {
                    KerberosKrbError krbError = kerberosClient.GetKrbErrorFromToken(repToken);
                    BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KRB_AP_ERR_TKT_NYV, krbError.ErrorCode,
                                                 "SMB Server should return {0}", KRB_ERROR_CODE.KRB_AP_ERR_TKT_NYV);
                }
                smb2Client.Disconnect();
                return;
            }
            if (variant.HasFlag(CaseVariant.TICKET_EXPIRED))
            {
                BaseTestSite.Assert.AreNotEqual(Smb2Status.STATUS_SUCCESS, status,
                                                "Session Setup should fail because the current time is later than the endtime (yesterday)" +
                                                " in the Ticket by more than the allowable clock skew");
                if (TestConfig.IsWindowsPlatform)
                {
                    KerberosKrbError krbError = kerberosClient.GetKrbErrorFromToken(repToken);
                    BaseTestSite.Assert.AreEqual(KRB_ERROR_CODE.KRB_AP_ERR_TKT_EXPIRED, krbError.ErrorCode,
                                                 "SMB Server should return {0}", KRB_ERROR_CODE.KRB_AP_ERR_TKT_EXPIRED);
                }
                smb2Client.Disconnect();
                return;
            }
            if (variant.HasFlag(CaseVariant.AUTHDATA_UNKNOWN_TYPE_IN_TKT))
            {
                BaseTestSite.Assert.AreNotEqual(Smb2Status.STATUS_SUCCESS, status,
                                                "Session Setup should fail because of the unknown AutherizationData in the ticket");
                smb2Client.Disconnect();
                return;
            }
            if (variant.HasFlag(CaseVariant.AUTHDATA_UNKNOWN_TYPE_IN_AUTHENTICATOR))
            {
                BaseTestSite.Log.Add(LogEntryKind.Comment,
                                     "Unknown AuthorizationData in the Authenticator should not fail the request");
            }
            if (variant.HasFlag(CaseVariant.AUTHDATA_UNKNOWN_TYPE_IN_TKT_OPTIONAL) ||
                variant.HasFlag(CaseVariant.AUTHDATA_UNKNOWN_TYPE_IN_AUTHENTICATOR_OPTIONAL))
            {
                BaseTestSite.Log.Add(LogEntryKind.Comment, "Unknown AuthorizationData in AD_IF_RELEVANT is optional. " +
                                     "Server should not fail the request.");
            }

            KerberosApResponse apRep = kerberosClient.GetApResponseFromToken(repToken, GssToken);
            // Get subkey from AP response, which used for signing in smb2
            apRep.Decrypt(kerberosClient.Context.Ticket.SessionKey.keyvalue.ByteArrayValue);
            smb2Client.SetSessionSigningAndEncryption(true, false, apRep.ApEncPart.subkey.keyvalue.ByteArrayValue);

            string path = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            AccessFile(smb2Client, path);
            #endregion

            smb2Client.LogOff();
            smb2Client.Disconnect();
        }