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);
        }
Пример #2
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);
        }