/// <summary>
 /// Create an instance.
 /// </summary>
 public KpasswordResponse()
     : base()
 {
     ap_rep = new KerberosApResponse();
     krb_priv = new KRB_PRIV();
     priv_enc_part = new EncKrbPrivPart();
 }
 /// <summary>
 /// Create an instance.
 /// </summary>
 public KpasswordResponse()
     : base()
 {
     ap_rep        = new KerberosApResponse();
     krb_priv      = new KRB_PRIV();
     priv_enc_part = new EncKrbPrivPart();
 }
示例#3
0
        /// <summary>
        /// Decode GSSAPI token to AP-REP
        /// </summary>
        /// <param name="token">GSSAPI token</param>
        /// <returns></returns>
        private KerberosApResponse GetApResponseFromToken(byte[] token, KerberosConstValue.GSSToken gssToken = KerberosConstValue.GSSToken.GSSSPNG)
        {
            if (gssToken == KerberosConstValue.GSSToken.GSSSPNG)
            {
                token = KerberosUtility.DecodeNegotiationToken(token);
            }

            if (token[0] == KerberosConstValue.KERBEROS_TAG)
            {
                byte[] apData = KerberosUtility.VerifyGssApiTokenHeader(token, this.client.OidPkt);

                // Check if it has a two-byte tok_id
                if (null == apData || apData.Length <= sizeof(TOK_ID))
                {
                    throw new FormatException(
                              "Data length is shorter than a valid AP Response data length.");
                }

                // verify TOK_ID
                byte[] tokenID = ArrayUtility.SubArray <byte>(apData, 0, sizeof(TOK_ID));
                Array.Reverse(tokenID);
                TOK_ID id = (TOK_ID)BitConverter.ToUInt16(tokenID, 0);

                if (!id.Equals(TOK_ID.KRB_AP_REP))
                {
                    throw new Exception("ApResponse Token ID should be KRB_AP_REP");
                }

                // Get apBody
                token = ArrayUtility.SubArray(apData, sizeof(TOK_ID));
            }

            KerberosApResponse apRep = new KerberosApResponse();

            apRep.FromBytes(token);

            // Get the current encryption type, cipher data
            EncryptionType encryptType = (EncryptionType)apRep.Response.enc_part.etype.Value;

            byte[] cipherData = apRep.Response.enc_part.cipher.ByteArrayValue;
            byte[] sessionKey = this.Context.ApSessionKey.keyvalue.ByteArrayValue;

            // decrypt enc_part to clear text
            byte[] clearText = KerberosUtility.Decrypt(encryptType, sessionKey, cipherData, (int)KeyUsageNumber.AP_REP_EncAPRepPart);

            // decode enc_part
            Asn1DecodingBuffer decodeBuffer = new Asn1DecodingBuffer(clearText);

            apRep.ApEncPart = new EncAPRepPart();
            apRep.ApEncPart.BerDecode(decodeBuffer);

            this.client.UpdateContext(apRep);

            return(apRep);
        }
示例#4
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;
        }
        private void UpdateContext(KerberosApResponse response)
        {
            if (response.ApEncPart != null)
            {
                if (response.ApEncPart.seq_number != null)
                {
                    this.Context.CurrentRemoteSequenceNumber = (uint)response.ApEncPart.seq_number.Value;
                }

                if (response.ApEncPart.subkey != null)
                {
                    this.Context.AcceptorSubKey = response.ApEncPart.subkey;
                    this.Context.SessionKey     = response.ApEncPart.subkey;
                }
            }
        }
        /// <summary>
        /// Updated context based on Kerberos pdu
        /// </summary>
        /// <param name="pdu">Kerberos pdu</param>
        public override void UpdateContext(KerberosPdu pdu)
        {
            if (pdu is KerberosAsRequest)
            {
                KerberosAsRequest request = (KerberosAsRequest)pdu;
                UpdateContext(request);
            }
            if (pdu is KerberosKrbError)
            {
                KerberosKrbError error = (KerberosKrbError)pdu;
                UpdateContext(error);
            }
            if (pdu is KerberosAsResponse)
            {
                KerberosAsResponse response = (KerberosAsResponse)pdu;
                UpdateContext(response);
            }

            if (pdu is KerberosTgsRequest)
            {
                KerberosTgsRequest request = pdu as KerberosTgsRequest;
                UpdateContext(request);
            }

            if (pdu is KerberosTgsResponse)
            {
                KerberosTgsResponse response = pdu as KerberosTgsResponse;
                UpdateContext(response);
            }

            if (pdu is KerberosApRequest)
            {
                KerberosApRequest request = pdu as KerberosApRequest;
                UpdateContext(request);
            }

            if (pdu is KerberosApResponse)
            {
                KerberosApResponse response = pdu as KerberosApResponse;
                UpdateContext(response);
            }

            this.expectedPduType = null;
        }
示例#7
0
        public KerberosApResponse CreateApResponse(EncryptionKey subkey)
        {
            var response = new KerberosApResponse();

            response.Response.msg_type = new Asn1Integer((int)MsgType.KRB_AP_RESP);
            response.Response.pvno     = new Asn1Integer(KerberosConstValue.KERBEROSV5);

            // Set EncAPRepPart
            var apEncPart = new EncAPRepPart();

            apEncPart.ctime      = Context.Time;
            apEncPart.cusec      = Context.Cusec;
            apEncPart.subkey     = null;
            apEncPart.seq_number = new KerbUInt32((long)Context.currentRemoteSequenceNumber);
            response.ApEncPart   = apEncPart;

            this.client.UpdateContext(response);
            return(response);
        }
示例#8
0
 private void VerifyApResponse(KerberosApResponse apRep)
 {
     apRep.Decrypt(this.Context.ApSessionKey.keyvalue.ByteArrayValue);
     if (apRep.ApEncPart != null)
     {
         if (apRep.ApEncPart.ctime.Value != this.ApRequestAuthenticator.ctime.Value)
         {
             throw new NotSupportedException("ctime is not match with KRB_AP_REQ ctime");
         }
         if (apRep.ApEncPart.cusec.Value != this.ApRequestAuthenticator.cusec.Value)
         {
             throw new NotSupportedException("cusec is not match with KRB_AP_REQ cusec");
         }
         if (apRep.ApEncPart.seq_number.Value == null || apRep.ApEncPart.seq_number.Value <= 0)
         {
             throw new NotSupportedException("seq_number should be a valid value");
         }
     }
     else
     {
         throw new NotSupportedException("KRB_AP_REP decrypt failed");
     }
 }
        /// <summary>
        /// Decode GSSAPI token to AP-REP
        /// </summary>
        /// <param name="token">GSSAPI token</param>
        /// <returns></returns>
        public KerberosApResponse GetApResponseFromToken(byte[] token, KerberosConstValue.GSSToken gssToken = KerberosConstValue.GSSToken.GSSSPNG)
        {
            if (gssToken == KerberosConstValue.GSSToken.GSSSPNG)
                token = KerberosUtility.DecodeNegotiationToken(token);

            if (token[0] == KerberosConstValue.KERBEROS_TAG)
            {
                byte[] apData = KerberosUtility.VerifyGssApiTokenHeader(token, this.oidPkt);

                // Check if it has a two-byte tok_id
                if (null == apData || apData.Length <= sizeof(TOK_ID))
                {
                    throw new FormatException(
                        "Data length is shorter than a valid AP Response data length.");
                }

                // verify TOK_ID
                byte[] tokenID = ArrayUtility.SubArray<byte>(apData, 0, sizeof(TOK_ID));
                Array.Reverse(tokenID);
                TOK_ID id = (TOK_ID)BitConverter.ToUInt16(tokenID, 0);

                this.testSite.Assert.AreEqual(TOK_ID.KRB_AP_REP, id, "The Token ID should be KRB_AP_REP");

                // Get apBody
                token = ArrayUtility.SubArray(apData, sizeof(TOK_ID));
            }

            KerberosApResponse response = new KerberosApResponse();
            response.FromBytes(token);

            return response;
        }