/// <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); } }
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); }
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(); }
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); }
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); }
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]; }
/// <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); }
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); }
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))); }
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)); }
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())); }
/// <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); } }
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); }