public override ReadOnlyMemory <byte> ExecuteCore(PreAuthenticationContext context)
        {
            // 1. check what pre-auth validation is required for user
            // 2. enumerate all pre-auth handlers that are available
            //      - fail hard if required doesn't intersect available
            // 3. if pre-auth is required and not present, return error prompting for it
            // 4. if pre-auth is present, validate it
            // 5. if pre-auth failed, return error
            // 6. if some pre-auth succeeded, return error
            // 7. if all required validation succeeds, generate PAC, TGT, and return it

            if (context.Failure != null)
            {
                return(PreAuthFailed(context));
            }

            KrbAsReq asReq = (KrbAsReq)context.Message;

            if (context.Principal == null)
            {
                logger.LogInformation("User {User} not found in realm {Realm}", asReq.Body.CName.FullyQualifiedName, RealmService.Name);

                return(GenerateError(KerberosErrorCode.KDC_ERR_C_PRINCIPAL_UNKNOWN, null, RealmService.Name, asReq.Body.CName.FullyQualifiedName));
            }

            if (!context.PreAuthenticationSatisfied)
            {
                return(RequirePreAuth(context));
            }

            return(GenerateAsRep(asReq, context));
        }
        public override void QueryPreValidate(PreAuthenticationContext context)
        {
            KrbAsReq asReq = (KrbAsReq)context.Message;

            context.Principal        = RealmService.Principals.Find(asReq.Body.CName);
            context.ServicePrincipal = RealmService.Principals.Find(KrbPrincipalName.WellKnown.Krbtgt());
        }
Example #3
0
        public Task Setup()
        {
            this.Port = new Random().Next(20000, 40000);

            var options = new ListenerOptions
            {
                DefaultRealm = "corp2.identityintervention.com".ToUpper(),
                RealmLocator = realm => LocateRealm(realm),
                Log          = Logger
            };

            options.Configuration.KdcDefaults.TcpListenBacklog = int.MaxValue;
            options.Configuration.KdcDefaults.ReceiveTimeout   = TimeSpan.FromSeconds(15);
            options.Configuration.KdcDefaults.KdcTcpListenEndpoints.Clear();
            options.Configuration.KdcDefaults.KdcTcpListenEndpoints.Add($"127.0.0.1:{this.Port}");

            this.listener = new KdcServiceListener(options);
            _             = this.listener.Start();

            this.credential = Creds.GetOrAdd(this.AlgorithmType, a => new KerberosPasswordCredential(a + this.user, this.password));

            this.asReq = new ReadOnlySequence <byte>(KrbAsReq.CreateAsReq(this.credential, DefaultAuthentication).EncodeApplication());

            return(Task.CompletedTask);
        }
        private void ProcessKdcProxy(KdcProxyMessage proxyMessage, string source)
        {
            var message = proxyMessage.UnwrapMessage();

            var kdcBody = new
            {
                AsReq    = TryDecode(message, m => KrbAsReq.DecodeApplication(m)),
                AsRep    = TryDecode(message, m => KrbAsRep.DecodeApplication(m)),
                TgsReq   = TryDecode(message, m => KrbTgsReq.DecodeApplication(m)),
                TgsRep   = TryDecode(message, m => KrbTgsRep.DecodeApplication(m)),
                KrbError = TryDecode(message, m => KrbError.DecodeApplication(m))
            };

            if (kdcBody.AsReq != null)
            {
                ExplodeObject(kdcBody.AsReq, $"AS-REQ ({source})");
            }
            else if (kdcBody.AsRep != null)
            {
                ExplodeObject(kdcBody.AsRep, $"AS-REP ({source})");
            }
            else if (kdcBody.TgsReq != null)
            {
                ExplodeObject(kdcBody.TgsReq, $"TGS-REQ ({source})");
            }
            else if (kdcBody.TgsRep != null)
            {
                ExplodeObject(kdcBody.TgsRep, $"TGS-REP ({source})");
            }
            else if (kdcBody.KrbError != null)
            {
                ExplodeObject(kdcBody.KrbError, $"Krb-Error ({source})");
            }
        }
Example #5
0
        public async Task ParseKdcProxyMessage_WithoutLength()
        {
            var req = KrbAsReq.CreateAsReq(
                new KerberosPasswordCredential("*****@*****.**", "P@ssw0rd!"),
                0
                ).EncodeApplication();

            var domain = "corp.identityintervention.com";
            var hint   = DcLocatorHint.DS_AVOID_SELF;

            var message = KdcProxyMessage.WrapMessage(req, domain, hint, mode: KdcProxyMessageMode.NoPrefix);

            var kdc = new KdcServer(new KdcServerOptions {
                RealmLocator = realm => new FakeRealmService(realm)
            });

            var response = await kdc.ProcessMessage(message.Encode());

            Assert.IsTrue(response.Length > 0);
            Assert.IsFalse(KrbError.CanDecode(response));

            var proxy = KdcProxyMessage.Decode(response);

            var preAuthReq = KrbError.DecodeApplication(proxy.UnwrapMessage(out KdcProxyMessageMode mode));

            Assert.AreEqual(KdcProxyMessageMode.NoPrefix, mode);

            Assert.AreEqual(KerberosErrorCode.KDC_ERR_PREAUTH_REQUIRED, preAuthReq.ErrorCode);
        }
Example #6
0
        public void Setup()
        {
            options = new ListenerOptions
            {
                DefaultRealm = Realm,
                RealmLocator = LocateRealm
            };

            credential = Creds.GetOrAdd(AlgorithmType, a => new KerberosPasswordCredential(a + user, password));

            asReq = KrbAsReq.CreateAsReq(credential, DefaultAuthentication).EncodeApplication();

            switch (AlgorithmType)
            {
            case "RC4":
                etype = EncryptionType.RC4_HMAC_NT;
                break;

            case "AES128":
                etype = EncryptionType.AES128_CTS_HMAC_SHA1_96;
                break;

            case "AES256":
                etype = EncryptionType.AES256_CTS_HMAC_SHA1_96;
                break;
            }
        }
        protected override async Task <ReadOnlyMemory <byte> > ExecuteCore(IKerberosMessage message)
        {
            // 1. check what pre-auth validation is required for user
            // 2. enumerate all pre-auth handlers that are available
            //      - fail hard if required doesn't intersect available
            // 3. if pre-auth is required and not present, return error prompting for it
            // 4. if pre-auth is present, validate it
            // 5. if pre-auth failed, return error
            // 6. if some pre-auth succeeded, return error
            // 7. if all required validation succeeds, generate PAC, TGT, and return it

            KrbAsReq asReq = (KrbAsReq)message;

            var principal = await RealmService.Principals.Find(asReq.Body.CName.FullyQualifiedName);

            try
            {
                var preAuthRequests = await ProcessPreAuth(asReq, principal);

                if (preAuthRequests.Count() > 0)
                {
                    return(RequirePreAuth(preAuthRequests, principal));
                }
            }
            catch (KerberosValidationException kex)
            {
                Log(kex);

                return(PreAuthFailed(kex, principal));
            }

            return(await GenerateAsRep(asReq, principal));
        }
        public override async Task QueryPreValidateAsync(PreAuthenticationContext context)
        {
            KrbAsReq asReq = (KrbAsReq)context.Message;

            context.Principal = await RealmService.Principals.FindAsync(asReq.Body.CName);

            context.ServicePrincipal = await RealmService.Principals.FindAsync(KrbPrincipalName.WellKnown.Krbtgt());
        }
        public async Task HttpsTransportReceivesFailure()
        {
            var transport = new HandledHttpsKerberosTransport(new FailureKdcMessageDelegatingHandler());

            var asReq = KrbAsReq.CreateAsReq(new KerberosPasswordCredential(UserUpn, "P@ssw0rd!"), AuthenticationOptions.Forwardable);

            await transport.SendMessage <KrbAsRep>("adasdf", asReq.EncodeApplication());
        }
Example #10
0
        protected override IKerberosMessage DecodeMessageCore(ReadOnlyMemory <byte> message)
        {
            var asReq = KrbAsReq.DecodeApplication(message);

            this.SetRealmContext(asReq.Realm);

            return(asReq);
        }
Example #11
0
        public void TestParseAsReqWithPaData()
        {
            var asReqBin = ReadDataFile("messages\\as-req-preauth").Skip(4).ToArray();

            var asreq = KrbAsReq.DecodeApplication(asReqBin);

            Assert.IsNotNull(asreq);

            var bytes = asreq.Encode();

            Assert.IsTrue(bytes.Length > 0);
        }
Example #12
0
        public void AsReqRoundtripParse()
        {
            var creds = new KerberosPasswordCredential("sdfsdfsdf", "sdfsdfsdf", "sdfsdfsdf");

            var asReq = KrbAsReq.CreateAsReq(creds, AuthenticationOptions.AllAuthentication);

            var encoded = asReq.EncodeApplication();

            var decoded = KrbAsReq.DecodeApplication(encoded);

            Assert.IsNotNull(decoded);
        }
Example #13
0
        public void ParseAsReqApplicationMessage()
        {
            var asReqBin = ReadDataFile("messages\\as-req").Skip(4).ToArray();

            var asReq = KrbAsReq.DecodeApplication(asReqBin);

            Assert.IsNotNull(asReq);

            var addr = asReq.Body.Addresses[0].DecodeAddress();

            Assert.IsNotNull(addr);
            Assert.AreEqual("APP03           ", addr);
        }
Example #14
0
        public void Message_AsReqPreAuth()
        {
            var file = ReadDataFile("messages\\as-req-preauth");

            var decoded = TestSimpleRoundtrip(
                "as-req-preauth",
                file.Skip(4).ToArray(),
                v => KrbAsReq.DecodeApplication(v),
                t => t.EncodeApplication().ToArray()
                );

            Assert.IsNotNull(decoded);
        }
Example #15
0
        public override void QueryPreValidate(PreAuthenticationContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            KrbAsReq         asReq      = (KrbAsReq)context.Message;
            KrbPrincipalName krbtgtName = KrbPrincipalName.WellKnown.Krbtgt(asReq.Body.Realm);

            context.Principal        = this.RealmService.Principals.Find(asReq.Body.CName, asReq.Realm);
            context.ServicePrincipal = this.RealmService.Principals.Find(krbtgtName, asReq.Realm);
        }
Example #16
0
        public void DecryptAsReqApplicationMessage()
        {
            var asReqBin = ReadDataFile("messages\\as-req-preauth").Skip(4).ToArray();

            var asReq = KrbAsReq.DecodeApplication(asReqBin);

            Assert.IsNotNull(asReq);

            KerberosKey key = CreateKey();

            var ts = asReq.DecryptTimestamp(key);

            Assert.AreEqual(636985444450060358L, ts.Ticks);
        }
Example #17
0
        public override async Task QueryPreValidateAsync(PreAuthenticationContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            KrbAsReq         asReq      = (KrbAsReq)context.Message;
            KrbPrincipalName krbtgtName = KrbPrincipalName.WellKnown.Krbtgt(asReq.Body.Realm);

            context.Principal = await this.RealmService.Principals.FindAsync(asReq.Body.CName, asReq.Realm).ConfigureAwait(false);

            context.ServicePrincipal = await this.RealmService.Principals.FindAsync(krbtgtName, asReq.Realm).ConfigureAwait(false);
        }
Example #18
0
        public async Task HttpsTransportReceivesSuccess()
        {
            var transport = new HandledHttpsKerberosTransport(new SuccessKdcMessageDelegatingHandler());

            transport.DomainPaths["adasdf"] = new Uri("https://test.internal/fake");

            var asReq = KrbAsReq.CreateAsReq(new KerberosPasswordCredential(UserUpn, "P@ssw0rd!"), AuthenticationOptions.Forwardable);

            var response = await transport.SendMessage <KrbAsRep>("adasdf", asReq.EncodeApplication());

            Assert.IsNotNull(response);

            transport.Dispose();
        }
Example #19
0
        public void AsReqPreAuth_PkinitCertificateAccessible()
        {
            var credCert = new X509Certificate2(ReadDataFile("testuser.pfx"), "p");

            var cred = new TrustedAsymmetricCredential(credCert, "*****@*****.**");

            var asReq = KrbAsReq.CreateAsReq(cred, AuthenticationOptions.AllAuthentication);

            var handler = new KdcAsReqMessageHandler(
                asReq.EncodeApplication(),
                new ListenerOptions
            {
                DefaultRealm = "corp.identityintervention.com",
                RealmLocator = realm => new FakeRealmService(realm)
            });

            handler.PreAuthHandlers[PaDataType.PA_PK_AS_REQ] = service => new PaDataPkAsReqHandler(service)
            {
                IncludeOption = X509IncludeOption.EndCertOnly
            };

            var context = new PreAuthenticationContext();

            handler.DecodeMessage(context);
            handler.ExecutePreValidate(context);
            handler.QueryPreValidate(context);
            handler.ValidateTicketRequest(context);
            handler.QueryPreExecute(context);
            handler.ExecuteCore(context);

            Assert.AreEqual(PaDataType.PA_PK_AS_REQ, context.ClientAuthority);

            Assert.AreEqual(1, context.PreAuthenticationState.Count);

            Assert.IsTrue(context.PreAuthenticationState.TryGetValue(PaDataType.PA_PK_AS_REQ, out PaDataState paState));

            var state = paState as PkInitState;

            Assert.IsNotNull(state);

            Assert.IsNotNull(state.ClientCertificate);
            Assert.AreEqual(1, state.ClientCertificate.Count);

            var clientCert = state.ClientCertificate[0];

            Assert.IsFalse(clientCert.HasPrivateKey);

            Assert.AreEqual(credCert.Thumbprint, clientCert.Thumbprint);
        }
        protected override async Task <ReadOnlyMemory <byte> > ExecuteCore(IKerberosMessage message)
        {
            // 1. check what pre-auth validation is required for user
            // 2. enumerate all pre-auth handlers that are available
            //      - fail hard if required doesn't intersect available
            // 3. if pre-auth is required and not present, return error prompting for it
            // 4. if pre-auth is present, validate it
            // 5. if pre-auth failed, return error
            // 6. if some pre-auth succeeded, return error
            // 7. if all required validation succeeds, generate PAC, TGT, and return it

            KrbAsReq asReq = (KrbAsReq)message;

            var username = asReq.Body.CName.FullyQualifiedName;

            var principal = await RealmService.Principals.Find(username);

            if (principal == null)
            {
                logger.LogInformation("User {User} not found in realm {Realm}", username, RealmService.Name);

                return(GenerateError(KerberosErrorCode.KDC_ERR_S_PRINCIPAL_UNKNOWN, null, RealmService.Name, username));
            }

            var preauth = new PreAuthenticationContext
            {
                Principal = principal
            };

            try
            {
                var preAuthRequests = await ProcessPreAuth(preauth, asReq);

                if (preAuthRequests.Count() > 0)
                {
                    return(RequirePreAuth(preAuthRequests, principal));
                }
            }
            catch (KerberosValidationException kex)
            {
                logger.LogWarning(kex, "AS-REQ failed processing for principal {Principal}", principal);

                return(PreAuthFailed(kex, principal));
            }

            return(await GenerateAsRep(preauth, asReq));
        }
        private ReadOnlyMemory <byte> GenerateAsRep(KrbAsReq asReq, PreAuthenticationContext context)
        {
            // 1. detect if specific PAC contents are requested (claims)
            // 2. if requested generate PAC for user
            // 3. stuff PAC into ad-if-relevant pa-data of krbtgt ticket
            // 4. look up krbtgt account
            // 5. encrypt against krbtgt
            // 6. done

            var rst = new ServiceTicketRequest
            {
                Principal        = context.Principal,
                EncryptedPartKey = context.EncryptedPartKey,
                ServicePrincipal = context.ServicePrincipal,
                Addresses        = asReq.Body.Addresses,
                Nonce            = asReq.Body.Nonce,
                IncludePac       = true,
                Flags            = TicketFlags.Initial | KrbKdcRep.DefaultFlags
            };

            if (!asReq.Body.KdcOptions.HasFlag(KdcOptions.Canonicalize))
            {
                rst.SamAccountName = asReq.Body.CName.FullyQualifiedName;
            }

            if (context.ClientAuthority != PaDataType.PA_NONE)
            {
                rst.Flags |= TicketFlags.PreAuthenticated;
            }

            if (rst.EncryptedPartKey == null)
            {
                rst.EncryptedPartKey = rst.Principal.RetrieveLongTermCredential();
            }

            rst.IncludePac = DetectPacRequirement(asReq) ?? false;

            var asRep = KrbAsRep.GenerateTgt(rst, RealmService);

            if (context.PaData != null)
            {
                asRep.PaData = context.PaData.ToArray();
            }

            return(asRep.EncodeApplication());
        }
Example #22
0
        private static KrbAsRep RequestTgt(out KrbEncryptionKey sessionKey)
        {
            var cred = new KerberosPasswordCredential(Upn, "P@ssw0rd!")
            {
                // cheating by skipping the initial leg of requesting PA-type

                Salts = new[]
                {
                    new KeyValuePair <EncryptionType, string>(
                        EncryptionType.AES256_CTS_HMAC_SHA1_96,
                        "*****@*****.**"
                        )
                },
                Configuration = Krb5Config.Default()
            };

            var asReq = KrbAsReq.CreateAsReq(
                cred,
                AuthenticationOptions.AllAuthentication
                );

            var handler = new KdcAsReqMessageHandler(asReq.EncodeApplication(), new KdcServerOptions
            {
                DefaultRealm = Realm,
                IsDebug      = true,
                RealmLocator = realm => new FakeRealmService(realm)
            });

            handler.PreAuthHandlers[PaDataType.PA_ENC_TIMESTAMP] = service => new PaDataTimestampHandler(service);

            var results = handler.Execute();

            var decoded = KrbAsRep.DecodeApplication(results);

            var decrypted = cred.DecryptKdcRep(
                decoded,
                KeyUsage.EncAsRepPart,
                d => KrbEncAsRepPart.DecodeApplication(d)
                );

            sessionKey = decrypted.Key;

            return(decoded);
        }
        private async Task <ReadOnlyMemory <byte> > GenerateAsRep(KrbAsReq asReq, IKerberosPrincipal principal)
        {
            // 1. detect if specific PAC contents are requested (claims)
            // 2. if requested generate PAC for user
            // 3. stuff PAC into ad-if-relevant pa-data of krbtgt ticket
            // 4. look up krbtgt account
            // 5. encrypt against krbtgt
            // 6. done

            var requirements = new List <KrbPaData>();

            foreach (var handler in postProcessAuthHandlers)
            {
                await InvokePreAuthHandler(null, principal, requirements, handler.Value);
            }

            var rst = new ServiceTicketRequest
            {
                Principal  = principal,
                Addresses  = asReq.Body.Addresses,
                Nonce      = asReq.Body.Nonce,
                IncludePac = true,
                Flags      = TicketFlags.Initial | KrbKdcRep.DefaultFlags
            };

            rst.EncryptedPartKey = await principal.RetrieveLongTermCredential();

            var pacRequest = asReq.PaData.FirstOrDefault(pa => pa.Type == PaDataType.PA_PAC_REQUEST);

            if (pacRequest != null)
            {
                var paPacRequest = KrbPaPacRequest.Decode(pacRequest.Value);

                rst.IncludePac = paPacRequest.IncludePac;
            }

            var asRep = await KrbAsRep.GenerateTgt(rst, RealmService);

            asRep.PaData = requirements.ToArray();

            return(asRep.EncodeApplication());
        }
Example #24
0
        public override async Task <PreAuthenticationContext> ValidateTicketRequest(IKerberosMessage message)
        {
            KrbAsReq asReq = (KrbAsReq)message;

            await SetRealmContext(asReq.Realm);

            var username = asReq.Body.CName.FullyQualifiedName;

            var principal = await RealmService.Principals.Find(username);

            var preauth = new PreAuthenticationContext {
                Principal = principal
            };

            if (preauth.Principal == null)
            {
                return(preauth);
            }

            try
            {
                var preauthReq = await ProcessPreAuth(preauth, asReq);

                if (preauth.PaData == null)
                {
                    preauth.PaData = Array.Empty <KrbPaData>();
                }

                preauth.PaData = preauth.PaData.Union(preauthReq).ToArray();
            }
            catch (KerberosValidationException kex)
            {
                logger.LogWarning(kex, "AS-REQ failed processing for principal {Principal}", principal);

                preauth.Failure = kex;
            }

            return(preauth);
        }
Example #25
0
        public Task Setup()
        {
            Port = new Random().Next(20000, 40000);

            var options = new ListenerOptions
            {
                ListeningOn    = new IPEndPoint(IPAddress.Loopback, Port),
                DefaultRealm   = "corp2.identityintervention.com".ToUpper(),
                RealmLocator   = realm => LocateRealm(realm),
                QueueLength    = 10 * 1000,
                ReceiveTimeout = TimeSpan.FromMinutes(60),
                Log            = null
            };

            listener = new KdcServiceListener(options);
            _        = listener.Start();

            credential = Creds.GetOrAdd(AlgorithmType, a => new KerberosPasswordCredential(a + user, password));

            asReq = new ReadOnlySequence <byte>(KrbAsReq.CreateAsReq(credential, DefaultAuthentication).EncodeApplication());

            return(Task.CompletedTask);
        }
Example #26
0
        public static async Task <PingResult> Ping(KerberosCredential credential, Krb5Config config, ILoggerFactory logger = null)
        {
            credential.Configuration = config;

            var asReqMessage = KrbAsReq.CreateAsReq(credential, AuthenticationOptions.Renewable);

            var asReq = asReqMessage.EncodeApplication();

            var transport = new KerberosTransportSelector(
                new IKerberosTransport[]
            {
                new TcpKerberosTransport(logger),
                new UdpKerberosTransport(logger),
                new HttpsKerberosTransport(logger)
            },
                config,
                logger
                )
            {
                ConnectTimeout = TimeSpan.FromSeconds(5)
            };

            var result = new PingResult {
                AsReq = asReqMessage
            };

            try
            {
                result.AsRep = await transport.SendMessage <KrbAsRep>(credential.Domain, asReq);
            }
            catch (KerberosProtocolException pex)
            {
                result.Error = pex.Error;
            }

            return(result);
        }
Example #27
0
        public async Task ParseKdcProxyMessage()
        {
            var req = KrbAsReq.CreateAsReq(
                new KerberosPasswordCredential("*****@*****.**", "P@ssw0rd!"),
                0
                ).EncodeApplication();

            var domain = "corp.identityintervention.com";
            var hint   = DcLocatorHint.DS_AVOID_SELF;

            var messageBytes = new Memory <byte>(new byte[req.Length + 4]);

            Endian.ConvertToBigEndian(req.Length, messageBytes.Slice(0, 4));
            req.CopyTo(messageBytes.Slice(4, req.Length));

            var message = new KdcProxyMessage
            {
                TargetDomain  = domain,
                KerbMessage   = messageBytes,
                DcLocatorHint = hint
            };

            var kdc = new KdcServer(new ListenerOptions {
                RealmLocator = LocateFakeRealm
            });

            var response = await kdc.ProcessMessage(new ReadOnlySequence <byte>(message.Encode()));

            Assert.IsTrue(response.Length > 0);
            Assert.IsFalse(KrbError.CanDecode(response));

            var proxy = KdcProxyMessage.Decode(response);

            var preAuthReq = KrbError.DecodeApplication(proxy.UnwrapMessage());

            Assert.AreEqual(KerberosErrorCode.KDC_ERR_PREAUTH_REQUIRED, preAuthReq.ErrorCode);
        }
Example #28
0
        public async Task ProcessAsReq()
        {
            var requestCounter = 0;

            for (var i = 0; i < AuthenticationAttempts; i++)
            {
                var credential = Creds.GetOrAdd(AlgorithmType, a => new KerberosPasswordCredential(a + user, password));

                var asReq = KrbAsReq.CreateAsReq(credential, DefaultAuthentication).EncodeApplication();

                var message = new ReadOnlySequence <byte>(asReq);

                KdcAsReqMessageHandler handler = new KdcAsReqMessageHandler(message, listener.Options);

                var response = await handler.Execute();

                Assert.IsNotNull(response);

                if (DisplayProgress)
                {
                    CountItOut(ref requestCounter);
                }
            }
        }
Example #29
0
        public void GenerateAsReqApplicationMessage()
        {
            var ts = new KrbPaEncTsEnc
            {
                PaTimestamp = new DateTimeOffset(636973454050000000, TimeSpan.Zero),
                PaUSec      = 868835
            };

            var key = CreateKey();

            var tsEncoded = ts.Encode();

            KrbEncryptedData encData = KrbEncryptedData.Encrypt(
                tsEncoded,
                key,
                KeyUsage.PaEncTs
                );

            Assert.IsTrue(tsEncoded.Span.SequenceEqual(encData.Decrypt(key, KeyUsage.PaEncTs, d => KrbPaEncTsEnc.Decode(d)).Encode().Span));

            var asreq = new KrbAsReq()
            {
                MessageType           = MessageType.KRB_AP_REQ,
                ProtocolVersionNumber = 5,
                Body = new KrbKdcReqBody
                {
                    Addresses = new[] {
                        new KrbHostAddress {
                            AddressType = AddressType.NetBios,
                            Address     = Encoding.ASCII.GetBytes("APP03           ")
                        }
                    },
                    CName = new KrbPrincipalName
                    {
                        Name = new[] { "*****@*****.**" },
                        Type = PrincipalNameType.NT_ENTERPRISE
                    },
                    EType = new[] {
                        EncryptionType.AES256_CTS_HMAC_SHA1_96,
                        EncryptionType.AES128_CTS_HMAC_SHA1_96,
                        EncryptionType.RC4_HMAC_NT,
                        EncryptionType.RC4_HMAC_NT_EXP,
                        EncryptionType.RC4_HMAC_OLD_EXP,
                        EncryptionType.DES_CBC_MD5
                    },
                    KdcOptions = KdcOptions.RenewableOk | KdcOptions.Canonicalize | KdcOptions.Renewable | KdcOptions.Forwardable,
                    Nonce      = 717695934,
                    RTime      = new DateTimeOffset(642720196850000000L, TimeSpan.Zero),
                    Realm      = "CORP.IDENTITYINTERVENTION.COM",
                    SName      = new KrbPrincipalName
                    {
                        Type = PrincipalNameType.NT_SRV_INST,
                        Name = new[] { "krbtgt", "CORP.IDENTITYINTERVENTION.COM" }
                    },
                    Till = new DateTimeOffset(642720196850000000L, TimeSpan.Zero)
                },
                PaData = new[] {
                    new KrbPaData {
                        Type  = PaDataType.PA_ENC_TIMESTAMP,
                        Value = new ReadOnlyMemory <byte>(encData.Encode().ToArray())
                    },
                    new KrbPaData {
                        Type  = PaDataType.PA_PAC_REQUEST,
                        Value = new ReadOnlyMemory <byte>(new KrbPaPacRequest {
                            IncludePac = true
                        }.Encode().ToArray())
                    }
                }
            };

            var encodedAsReq = asreq.Encode().ToArray();

            var roundtrip = KrbKdcReq.Decode(encodedAsReq);

            Assert.IsNotNull(roundtrip);
        }
Example #30
0
        public void TestParseAllMessagesRoundtrip()
        {
            var allMessages = ReadDataFiles("messages\\");

            foreach (var file in allMessages)
            {
                var key = file.Key.Substring(file.Key.LastIndexOf('\\') + 1);

                Debug.WriteLine(file.Value.HexDump());

                switch (key)
                {
                case "as-rep":
                    var asrep = TestSimpleRoundtrip(
                        key,
                        file.Value.Skip(4).ToArray(),
                        v => new KrbAsRep().DecodeAsApplication(v),
                        t => t.EncodeApplication().ToArray()
                        );
                    break;

                case "as-req":
                    TestSimpleRoundtrip(
                        key,
                        file.Value.Skip(4).ToArray(),
                        v => KrbAsReq.DecodeApplication(v),
                        t => t.EncodeApplication().ToArray());
                    break;

                case "as-req-preauth":
                    TestSimpleRoundtrip(
                        key,
                        file.Value.Skip(4).ToArray(),
                        v => KrbAsReq.DecodeApplication(v),
                        t => t.EncodeApplication().ToArray());
                    break;

                case "krb-error-preauth-required":
                    TestSimpleRoundtrip(
                        key,
                        file.Value.Skip(4).ToArray(),
                        v => KrbError.DecodeApplication(v),
                        t => t.EncodeApplication().ToArray());
                    break;

                case "tgs-rep-testuser-host-app03":
                    TestSimpleRoundtrip(
                        key,
                        file.Value.Skip(4).ToArray(),
                        v => KrbTgsRep.DecodeApplication(v),
                        t => t.EncodeApplication().ToArray()
                        );
                    break;

                case "tgs-rep-testuser-host-appservice":
                    TestSimpleRoundtrip(
                        key,
                        file.Value.Skip(4).ToArray(),
                        v => KrbTgsRep.DecodeApplication(v),
                        t => t.EncodeApplication().ToArray()
                        );
                    break;

                case "tgs-rep-testuser-krbtgt-renew":
                    TestSimpleRoundtrip(
                        key,
                        file.Value.Skip(4).ToArray(),
                        v => KrbTgsRep.DecodeApplication(v),
                        t => t.EncodeApplication().ToArray()
                        );
                    break;

                case "tgs-req-testuser-host-app03":
                    var thing = TestSimpleRoundtrip(
                        key,
                        file.Value.Skip(4).ToArray(),
                        v => KrbTgsReq.DecodeApplication(v),
                        t => t.EncodeApplication().ToArray()
                        );
                    break;

                case "tgs-req-testuser-host-appservice":
                    TestSimpleRoundtrip(
                        key,
                        file.Value.Skip(4).ToArray(),
                        v => KrbTgsReq.DecodeApplication(v),
                        t => t.EncodeApplication().ToArray());
                    break;

                case "tgs-req-testuser-krbtgt-renew":
                    TestSimpleRoundtrip(
                        key,
                        file.Value.Skip(4).ToArray(),
                        v => KrbTgsReq.DecodeApplication(v),
                        t => t.EncodeApplication().ToArray());
                    break;
                }
            }
        }