예제 #1
0
        /// <summary>
        /// Try and parse data into an ASN1 authentication token.
        /// </summary>
        /// <param name="data">The data to parse.</param>
        /// <param name="token">The Negotiate authentication token.</param>
        /// <param name="values">Parsed DER Values.</param>
        internal static bool TryParse(byte[] data, DERValue[] values, out KerberosAuthenticationToken token)
        {
            token = null;
            try
            {
                var ret = new KerberosTGTRequestAuthenticationToken(data, values);

                if (values.Length != 1 || !values[0].HasChildren())
                {
                    return(false);
                }

                Queue <DERValue> queue = new Queue <DERValue>(values[0].Children);
                while (queue.Count > 0)
                {
                    var next = queue.Dequeue();
                    if (next.Type != DERTagType.ContextSpecific)
                    {
                        return(false);
                    }
                    switch (next.Tag)
                    {
                    case 0:
                        if (next.ReadChildInteger() != 5)
                        {
                            return(false);
                        }
                        break;

                    case 1:
                        if ((KRB_MSG_TYPE)next.ReadChildInteger() != KRB_MSG_TYPE.KRB_TGT_REQ)
                        {
                            return(false);
                        }
                        break;

                    case 2:
                        if (!next.Children[0].CheckSequence())
                        {
                            return(false);
                        }
                        ret.ServerName = KerberosPrincipalName.Parse(next.Children[0]);
                        break;

                    case 3:
                        ret.Realm = next.ReadChildGeneralString();
                        break;

                    default:
                        return(false);
                    }
                }
                token = ret;
                return(true);
            }
            catch (InvalidDataException)
            {
                return(false);
            }
        }
예제 #2
0
        internal static KerberosPrincipalName Parse(DERValue value)
        {
            if (!value.HasChildren())
            {
                throw new InvalidDataException();
            }
            KerberosPrincipalName ret = new KerberosPrincipalName();

            foreach (var next in value.Children)
            {
                if (next.Type != DERTagType.ContextSpecific)
                {
                    throw new InvalidDataException();
                }
                switch (next.Tag)
                {
                case 0:
                    ret.NameType = (KerberosNameType)next.ReadChildInteger();
                    break;

                case 1:
                    ret.Names = next.ReadChildStringSequence().AsReadOnly();
                    break;

                default:
                    throw new InvalidDataException();
                }
            }
            return(ret);
        }
예제 #3
0
 private protected KerberosTGTRequestAuthenticationToken(byte[] data, DERValue[] values)
     : base(data, values)
 {
     ProtocolVersion = 5;
     MessageType     = KRB_MSG_TYPE.KRB_TGT_REQ;
     Realm           = string.Empty;
     ServerName      = new KerberosPrincipalName();
 }
예제 #4
0
 internal bool Decrypt(KerberosKeySet keyset, string realm, KerberosPrincipalName server_name, RC4KeyUsage key_usage, out byte[] decrypted)
 {
     if (EncryptionType == KerberosEncryptionType.ARCFOUR_HMAC_MD5)
     {
         return(DecryptRC4(keyset, realm, server_name, key_usage, out decrypted));
     }
     decrypted = null;
     return(false);
 }
예제 #5
0
        internal static KerberosTicket Parse(DERValue value)
        {
            if (!value.CheckApplication(1) || !value.HasChildren())
            {
                throw new InvalidDataException();
            }

            if (!value.Children[0].CheckSequence())
            {
                throw new InvalidDataException();
            }

            KerberosTicket ret = new KerberosTicket();

            foreach (var next in value.Children[0].Children)
            {
                if (next.Type != DERTagType.ContextSpecific)
                {
                    throw new InvalidDataException();
                }
                switch (next.Tag)
                {
                case 0:
                    if (next.ReadChildInteger() != 5)
                    {
                        throw new InvalidDataException();
                    }
                    break;

                case 1:
                    ret.Realm = next.ReadChildGeneralString();
                    break;

                case 2:
                    if (!next.Children[0].CheckSequence())
                    {
                        throw new InvalidDataException();
                    }
                    ret.ServerName = KerberosPrincipalName.Parse(next.Children[0]);
                    break;

                case 3:
                    if (!next.HasChildren())
                    {
                        throw new InvalidDataException();
                    }
                    ret.EncryptedData = KerberosEncryptedData.Parse(next.Children[0]);
                    break;

                default:
                    throw new InvalidDataException();
                }
            }
            return(ret);
        }
예제 #6
0
 private protected KerberosErrorAuthenticationToken(byte[] data, DERValue[] values)
     : base(data, values, KerberosMessageType.KRB_ERROR)
 {
     ClientRealm = string.Empty;
     ClientName  = new KerberosPrincipalName();
     ClientTime  = string.Empty;
     ServerRealm = string.Empty;
     ServerName  = new KerberosPrincipalName();
     ServerTime  = string.Empty;
     ErrorText   = string.Empty;
     ErrorData   = new byte[0];
 }
예제 #7
0
        /// <summary>
        /// Create a new KRB-ERROR authentication token.
        /// </summary>
        /// <param name="client_time">Optional client time.</param>
        /// <param name="server_time">Server time.</param>
        /// <param name="error_code">Error code.</param>
        /// <param name="client_realm">Optional client realm.</param>
        /// <param name="client_name">Optional client name.</param>
        /// <param name="server_realm">Server realm</param>
        /// <param name="server_name">Server name.</param>
        /// <param name="error_text">Optional error text.</param>
        /// <param name="error_data">Optional error data.</param>
        /// <returns>The KRB-ERROR authentication token.</returns>
        public static KerberosErrorAuthenticationToken Create(DateTime server_time, KerberosErrorType error_code,
                                                              string server_realm, KerberosPrincipalName server_name, DateTime?client_time = null, string client_realm = null,
                                                              KerberosPrincipalName client_name = null, string error_text = null, byte[] error_data = null)
        {
            if (server_realm is null)
            {
                throw new ArgumentNullException(nameof(server_realm));
            }

            if (server_name is null)
            {
                throw new ArgumentNullException(nameof(server_name));
            }

            DERBuilder builder = new DERBuilder();

            using (var app = builder.CreateApplication(30))
            {
                using (var seq = app.CreateSequence())
                {
                    seq.WriteKerberosHeader(KerberosMessageType.KRB_ERROR);
                    if (client_time.HasValue)
                    {
                        seq.WriteKerberosTime(2, client_time.Value);
                    }
                    seq.WriteKerberosTime(4, server_time);
                    seq.WriteContextSpecific(6, b => b.WriteInt32((int)error_code));
                    if (client_realm != null)
                    {
                        seq.WriteContextSpecific(7, b => b.WriteGeneralString(client_realm));
                    }
                    if (client_name != null)
                    {
                        seq.WriteContextSpecific(8, b => b.WritePrincipalName(client_name));
                    }
                    seq.WriteContextSpecific(9, b => b.WriteGeneralString(server_realm));
                    seq.WriteContextSpecific(10, b => b.WritePrincipalName(server_name));
                    if (error_text != null)
                    {
                        seq.WriteContextSpecific(11, b => b.WriteGeneralString(error_text));
                    }
                    if (error_data != null)
                    {
                        seq.WriteContextSpecific(12, b => b.WriteOctetString(error_data));
                    }
                }
            }
            return((KerberosErrorAuthenticationToken)Parse(builder.CreateGssApiWrapper(OIDValues.KERBEROS, 0x300)));
        }
        private static DERBuilder CreateBuilder(string realm, KerberosPrincipalName server_name)
        {
            DERBuilder builder = new DERBuilder();

            using (var seq = builder.CreateSequence())
            {
                seq.WriteKerberosHeader(KerberosMessageType.KRB_TGT_REQ);
                if (server_name != null)
                {
                    seq.WriteContextSpecific(2, b => b.WritePrincipalName(server_name));
                }
                if (realm != null)
                {
                    seq.WriteContextSpecific(3, b => b.WriteGeneralString(realm));
                }
            }
            return(builder);
        }
예제 #9
0
        private bool DecryptRC4(KerberosKeySet keyset, string realm, KerberosPrincipalName server_name, RC4KeyUsage key_usage, out byte[] decrypted)
        {
            KerberosKey key = keyset.FindKey(EncryptionType, server_name.NameType, server_name.GetPrincipal(realm), KeyVersion ?? 0);

            if (key != null)
            {
                if (DecryptRC4WithKey(key, key_usage, out decrypted))
                {
                    return(true);
                }
            }
            foreach (var next in keyset.GetKeysForEncryption(EncryptionType))
            {
                if (DecryptRC4WithKey(key, key_usage, out decrypted))
                {
                    return(true);
                }
            }
            decrypted = null;
            return(false);
        }
예제 #10
0
        internal static KerberosKey Parse(DERValue value, string realm, KerberosPrincipalName name)
        {
            if (!value.CheckSequence())
            {
                throw new InvalidDataException();
            }
            KerberosEncryptionType enc_type = 0;

            byte[] key = null;
            foreach (var next in value.Children)
            {
                if (next.Type != DERTagType.ContextSpecific)
                {
                    throw new InvalidDataException();
                }
                switch (next.Tag)
                {
                case 0:
                    enc_type = (KerberosEncryptionType)next.ReadChildInteger();
                    break;

                case 1:
                    key = next.ReadChildOctetString();
                    break;

                default:
                    throw new InvalidDataException();
                }
            }

            if (enc_type == 0 || key == null)
            {
                throw new InvalidDataException();
            }
            return(new KerberosKey(enc_type, key, name.NameType, realm, name.Names.ToArray(), DateTime.Now, 0));
        }
 /// <summary>
 /// Create a new TGT-REQ authentication token.
 /// </summary>
 /// <param name="realm">Optional realm string.</param>
 /// <param name="server_name">Optional server name.</param>
 /// <returns>The new TGT-REQ authentication token.</returns>
 public static KerberosTGTRequestAuthenticationToken Create(string realm, KerberosPrincipalName server_name)
 {
     return((KerberosTGTRequestAuthenticationToken)Parse(CreateBuilder(realm,
                                                                       server_name).CreateGssApiWrapper(OIDValues.KERBEROS_USER_TO_USER, 0x400)));
 }
예제 #12
0
 private static KerberosAuthenticationKey ParseKey(KerberosPrincipalName server_name, string realm, KERB_CRYPTO_KEY key)
 {
     byte[] key_data = new byte[key.Length];
     Marshal.Copy(key.Value, key_data, 0, key.Length);
     return(new KerberosAuthenticationKey(key.KeyType, key_data, server_name.NameType, realm, server_name.Names, DateTime.Now, 0));
 }
예제 #13
0
 internal KerberosTicket()
 {
     TicketVersion = 5;
     Realm         = string.Empty;
     ServerName    = new KerberosPrincipalName();
 }
        internal static bool Parse(KerberosTicket orig_ticket, KerberosEncryptedData orig_data, byte[] decrypted, KerberosKeySet keyset, out KerberosEncryptedData ticket)
        {
            ticket = null;
            try
            {
                DERValue[] values = DERParser.ParseData(decrypted, 0);
                if (values.Length != 1)
                {
                    return(false);
                }
                DERValue value = values[0];
                if (!value.CheckApplication(2) || !value.HasChildren())
                {
                    return(false);
                }
                if (!value.Children[0].CheckSequence())
                {
                    return(false);
                }
                var ret = new KerberosAuthenticator(orig_data);
                foreach (var next in value.Children[0].Children)
                {
                    if (next.Type != DERTagType.ContextSpecific)
                    {
                        return(false);
                    }
                    switch (next.Tag)
                    {
                    case 0:
                        if (next.ReadChildInteger() != 5)
                        {
                            return(false);
                        }
                        break;

                    case 1:
                        ret.ClientRealm = next.ReadChildGeneralString();
                        break;

                    case 2:
                        if (!next.Children[0].CheckSequence())
                        {
                            return(false);
                        }
                        ret.ClientName = KerberosPrincipalName.Parse(next.Children[0]);
                        break;

                    case 3:
                        if (!next.Children[0].CheckSequence())
                        {
                            return(false);
                        }
                        ret.Checksum = KerberosChecksum.Parse(next.Children[0]);
                        break;

                    case 4:
                        ret.ClientUSec = next.ReadChildInteger();
                        break;

                    case 5:
                        ret.ClientTime = next.ReadChildGeneralizedTime();
                        break;

                    case 6:
                        if (!next.HasChildren())
                        {
                            return(false);
                        }
                        ret.SubKey = KerberosAuthenticationKey.Parse(next.Children[0], orig_ticket.Realm, orig_ticket.ServerName);
                        break;

                    case 7:
                        ret.SequenceNumber = next.ReadChildInteger();
                        break;

                    case 8:
                        if (!next.HasChildren())
                        {
                            return(false);
                        }
                        ret.AuthorizationData = KerberosAuthorizationData.ParseSequence(next.Children[0]);
                        break;

                    default:
                        return(false);
                    }
                }

                if (ret.Checksum is KerberosChecksumGSSApi gssapi && gssapi.Credentials != null)
                {
                    KerberosKeySet tmp_keyset = new KerberosKeySet(keyset.AsEnumerable() ?? new KerberosAuthenticationKey[0]);
                    if (ret.SubKey != null)
                    {
                        tmp_keyset.Add(ret.SubKey);
                    }

                    gssapi.Decrypt(tmp_keyset);
                }

                ticket = ret;
            }
            catch (InvalidDataException)
            {
                return(false);
            }
            catch (EndOfStreamException)
            {
                return(false);
            }
            return(true);
        }
 private protected KerberosTGTRequestAuthenticationToken(byte[] data, DERValue[] values)
     : base(data, values, KerberosMessageType.KRB_TGT_REQ)
 {
     Realm      = string.Empty;
     ServerName = new KerberosPrincipalName();
 }
 /// <summary>
 /// Create a new TGT-REQ authentication token without the GSS-API wrapper.
 /// </summary>
 /// <param name="realm">Optional realm string.</param>
 /// <param name="server_name">Optional server name.</param>
 /// <returns>The new TGT-REQ authentication token.</returns>
 public static KerberosTGTRequestAuthenticationToken CreateNoGSSAPI(string realm, KerberosPrincipalName server_name)
 {
     return((KerberosTGTRequestAuthenticationToken)Parse(CreateBuilder(realm, server_name).ToArray()));
 }
예제 #17
0
        /// <summary>
        /// Try and parse data into an ASN1 authentication token.
        /// </summary>
        /// <param name="data">The data to parse.</param>
        /// <param name="token">The Negotiate authentication token.</param>
        /// <param name="values">Parsed DER Values.</param>
        internal static bool TryParse(byte[] data, DERValue[] values, out KerberosAuthenticationToken token)
        {
            token = null;
            try {
                var ret = new KerberosErrorAuthenticationToken(data, values);

                if (values.Length != 1 || !values[0].CheckMsg(KerberosMessageType.KRB_ERROR) || !values[0].HasChildren())
                {
                    return(false);
                }

                values = values[0].Children;
                if (values.Length != 1 || !values[0].CheckSequence() || !values[0].HasChildren())
                {
                    return(false);
                }

                foreach (var next in values[0].Children)
                {
                    if (next.Type != DERTagType.ContextSpecific)
                    {
                        return(false);
                    }
                    switch (next.Tag)
                    {
                    case 0:
                        if (next.ReadChildInteger() != 5)
                        {
                            return(false);
                        }
                        break;

                    case 1:
                        if ((KerberosMessageType)next.ReadChildInteger() != KerberosMessageType.KRB_ERROR)
                        {
                            return(false);
                        }
                        break;

                    case 2:
                        ret.ClientTime = next.ReadChildGeneralizedTime();
                        break;

                    case 3:
                        ret.ClientUSec = next.ReadChildInteger();
                        break;

                    case 4:
                        ret.ServerTime = next.ReadChildGeneralizedTime();
                        break;

                    case 5:
                        ret.ServerUSec = next.ReadChildInteger();
                        break;

                    case 6:
                        ret.ErrorCode = (KerberosErrorType)next.ReadChildInteger();
                        break;

                    case 7:
                        ret.ClientRealm = next.ReadChildGeneralString();
                        break;

                    case 8:
                        if (!next.Children[0].CheckSequence())
                        {
                            throw new InvalidDataException();
                        }
                        ret.ClientName = KerberosPrincipalName.Parse(next.Children[0]);
                        break;

                    case 9:
                        ret.ServerRealm = next.ReadChildGeneralString();
                        break;

                    case 10:
                        if (!next.Children[0].CheckSequence())
                        {
                            throw new InvalidDataException();
                        }
                        ret.ServerName = KerberosPrincipalName.Parse(next.Children[0]);
                        break;

                    case 11:
                        ret.ErrorText = next.ReadChildGeneralString();
                        break;

                    case 12:
                        ret.ErrorData = next.ReadChildOctetString();
                        break;

                    default:
                        return(false);
                    }
                }
                token = ret;
                return(true);
            } catch (InvalidDataException) {
                return(false);
            }
        }
예제 #18
0
        internal static bool Parse(KerberosTicket orig_ticket, byte[] decrypted, KerberosKeySet keyset, out KerberosTicket ticket)
        {
            ticket = null;
            try {
                DERValue[] values = DERParser.ParseData(decrypted, 0);
                if (values.Length != 1)
                {
                    return(false);
                }
                DERValue value = values[0];
                if (!value.CheckApplication(3) || !value.HasChildren())
                {
                    return(false);
                }
                if (!value.Children[0].CheckSequence())
                {
                    return(false);
                }
                var ret = new KerberosTicketDecrypted(orig_ticket);
                foreach (var next in value.Children[0].Children)
                {
                    if (next.Type != DERTagType.ContextSpecific)
                    {
                        return(false);
                    }
                    switch (next.Tag)
                    {
                    case 0:
                        ret.Flags = ConvertTicketFlags(next.ReadChildBitString());
                        break;

                    case 1:
                        if (!next.HasChildren())
                        {
                            return(false);
                        }
                        ret.Key = KerberosAuthenticationKey.Parse(next.Children[0], orig_ticket.Realm, orig_ticket.ServerName);
                        keyset.Add(ret.Key);
                        break;

                    case 2:
                        ret.ClientRealm = next.ReadChildGeneralString();
                        break;

                    case 3:
                        if (!next.Children[0].CheckSequence())
                        {
                            return(false);
                        }
                        ret.ClientName = KerberosPrincipalName.Parse(next.Children[0]);
                        break;

                    case 4:
                        if (!next.HasChildren())
                        {
                            return(false);
                        }
                        ret.TransitedType = KerberosTransitedEncoding.Parse(next.Children[0]);
                        break;

                    case 5:
                        ret.AuthTime = next.ReadChildGeneralizedTime();
                        break;

                    case 6:
                        ret.StartTime = next.ReadChildGeneralizedTime();
                        break;

                    case 7:
                        ret.EndTime = next.ReadChildGeneralizedTime();
                        break;

                    case 8:
                        ret.RenewTill = next.ReadChildGeneralizedTime();
                        break;

                    case 9:
                        if (!next.HasChildren())
                        {
                            return(false);
                        }
                        ret.HostAddresses = KerberosHostAddress.ParseSequence(next.Children[0]);
                        break;

                    case 10:
                        if (!next.HasChildren())
                        {
                            return(false);
                        }
                        ret.AuthorizationData = KerberosAuthorizationData.ParseSequence(next.Children[0]);
                        break;

                    default:
                        return(false);
                    }
                }
                ticket = ret;
            } catch (InvalidDataException) {
                return(false);
            } catch (EndOfStreamException) {
                return(false);
            }
            return(true);
        }