예제 #1
0
        public void AuthenticatorChecksum_ChecksumSource()
        {
            var key = new KerberosKey(key: new byte[32], etype: EncryptionType.AES256_CTS_HMAC_SHA1_96);

            var rst = new RequestServiceTicket {
                AuthenticatorChecksumSource = new byte[345]
            };
            KrbApReq apreq = GenerateApReq(rst, out KrbAuthenticator authenticator);

            Assert.IsNotNull(apreq);
            Assert.IsNotNull(authenticator);
            Assert.IsNotNull(authenticator.Checksum);

            var expected = KrbChecksum.Create(
                rst.AuthenticatorChecksumSource,
                key,
                KeyUsage.AuthenticatorChecksum
                );

            Assert.IsTrue(
                KerberosCryptoTransformer.AreEqualSlow(
                    expected.Checksum.Span,
                    authenticator.Checksum.Checksum.Span
                    )
                );
        }
예제 #2
0
        public void MsKileInterop()
        {
            var rawKey = new byte[] {
                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
            };

            // DOMAIN.COMhostclient.domain.com
            var key = new KerberosKey(
                password: rawKey,
                host: "client",
                principal: new PrincipalName(PrincipalNameType.NT_PRINCIPAL, "domain.com", new[] { "client" }),
                etype: EncryptionType.AES128_CTS_HMAC_SHA1_96,
                iterationParams: new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8 }
                );

            var expectedKey = new byte[] { 0xb8, 0x2e, 0xe1, 0x22, 0x53, 0x1c, 0x2d, 0x94, 0x82, 0x1a, 0xc7, 0x55, 0xbc, 0xcb, 0x58, 0x79 };

            var gen = key.GetKey();

            Assert.IsTrue(KerberosCryptoTransformer.AreEqualSlow(gen.Span, expectedKey));
        }
예제 #3
0
        public void AuthenticatorChecksum_AppChecksum()
        {
            var rst = new RequestServiceTicket
            {
                AuthenticatorChecksum = new KrbChecksum
                {
                    Type     = ChecksumType.HMAC_SHA256_128_AES128,
                    Checksum = new byte[245]
                }
            };

            KrbApReq apreq = GenerateApReq(rst, out KrbAuthenticator authenticator);

            Assert.IsNotNull(apreq);
            Assert.IsNotNull(authenticator);
            Assert.IsNotNull(authenticator.Checksum);

            Assert.AreEqual(ChecksumType.HMAC_SHA256_128_AES128, authenticator.Checksum.Type);

            Assert.IsTrue(
                KerberosCryptoTransformer.AreEqualSlow(
                    new byte[245],
                    authenticator.Checksum.Checksum.Span
                    )
                );
        }
예제 #4
0
        public void TryGettingSspiTicketTest()
        {
            using (var contextSender = new SspiContext($"host/{Environment.MachineName}", "negotiate"))
                using (var contextReceiver = new SspiContext($"host/{Environment.MachineName}", "negotiate"))
                {
                    byte[] token          = null;
                    byte[] serverResponse = null;

                    do
                    {
                        token = contextSender.RequestToken(serverResponse);

                        Assert.IsNotNull(token);

                        if (token != null && token.Length > 0)
                        {
                            contextReceiver.AcceptToken(token, out serverResponse);
                            Assert.IsNotNull(serverResponse);
                        }
                    }while (token != null && token.Length > 0);

                    var serverContext = NegotiationToken.Decode(serverResponse);

                    Assert.IsNotNull(serverContext);
                    Assert.IsNotNull(serverContext.ResponseToken);
                    Assert.IsNull(serverContext.InitialToken);

                    Assert.IsNotNull(contextSender.SessionKey);

                    Assert.IsTrue(KerberosCryptoTransformer.AreEqualSlow(contextSender.SessionKey, contextReceiver.SessionKey));
                }
        }
예제 #5
0
        public void ValidateChecksum(KerberosKey key)
        {
            var expected = GenerateChecksum(key, this.UserName, this.UserRealm, this.AuthPackage);

            if (!KerberosCryptoTransformer.AreEqualSlow(expected.Checksum.Span, this.Checksum.Checksum.Span))
            {
                throw new SecurityException("Invalid checksum");
            }
        }
예제 #6
0
        private static void AssertSaltGeneration(EncryptionType etype, SaltType saltType, byte[] expectedKey)
        {
            var key = new KerberosKey(
                "P@ssw0rd!",
                principalName: new PrincipalName(PrincipalNameType.NT_PRINCIPAL, "domain.com", new string[] { "appservice" }),
                host: "appservice",
                etype: etype,
                saltType: saltType
                );

            Assert.AreEqual(saltType, key.SaltFormat);

            var gen = key.GetKey();

            Assert.IsTrue(KerberosCryptoTransformer.AreEqualSlow(gen.Span, expectedKey));
        }
        private void ValidateAuthenticator(KrbPKAuthenticator authenticator, KrbKdcReqBody body)
        {
            using (var sha1 = CryptoPal.Platform.Sha1())
            {
                var encoded = body.Encode();

                var paChecksum = sha1.ComputeHash(encoded.Span);

                if (!KerberosCryptoTransformer.AreEqualSlow(paChecksum.Span, authenticator.PaChecksum.Value.Span))
                {
                    throw new SecurityException("Invalid checksum");
                }
            }

            if (!KerberosConstants.WithinSkew(Service.Now(), authenticator.CTime, authenticator.CuSec, Service.Settings.MaximumSkew))
            {
                throw new KerberosValidationException($"PKAuthenticator time skew too great");
            }

            ValidateNonce(authenticator.Nonce);
        }
예제 #8
0
        private static void Rfc4120TestCase(
            int iterationCount,
            string password,
            string salt,
            PrincipalName principal,
            byte[] expectedKey,
            EncryptionType etype
            )
        {
            byte[] iterations = BitConverter.GetBytes(iterationCount);

            Array.Reverse(iterations);

            var keyFixedSalt = new KerberosKey(
                password: password,
                salt: salt,
                etype: etype,
                iterationParams: iterations
                );

            var fixedKey = keyFixedSalt.GetKey();

            Assert.IsTrue(KerberosCryptoTransformer.AreEqualSlow(fixedKey.Span, expectedKey));

            var keyDerivedSalt = new KerberosKey(
                password: password,
                principalName: principal,
                etype: etype,
                iterationParams: iterations,
                saltType: SaltType.Rfc4120
                );

            var derived = keyDerivedSalt.GetKey();

            Assert.IsTrue(KerberosCryptoTransformer.AreEqualSlow(derived.Span, expectedKey));
        }
예제 #9
0
        public void AssertRfc4120CaseSensitivity()
        {
            var lowerCaseKey = new KerberosKey(
                "P@ssw0rd!",
                principalName: new PrincipalName(PrincipalNameType.NT_PRINCIPAL, "domain.com", new string[] { "appservice" }),
                host: "appservice",
                etype: EncryptionType.AES128_CTS_HMAC_SHA1_96,
                saltType: SaltType.Rfc4120
                );

            var lowerCase = lowerCaseKey.GetKey();

            var upperCaseKey = new KerberosKey(
                "P@ssw0rd!",
                principalName: new PrincipalName(PrincipalNameType.NT_PRINCIPAL, "DOMAIN.COM", new string[] { "appservice" }),
                host: "appservice",
                etype: EncryptionType.AES128_CTS_HMAC_SHA1_96,
                saltType: SaltType.Rfc4120
                );

            var upperCase = upperCaseKey.GetKey();

            Assert.IsFalse(KerberosCryptoTransformer.AreEqualSlow(lowerCase.Span, upperCase.Span));
        }
예제 #10
0
 public void ConstantTimeComparisonDoesntThrowOnMismatchLength()
 {
     Assert.IsFalse(KerberosCryptoTransformer.AreEqualSlow(new byte[] { 3, 3, 3 }, new byte[] { 4, 4, 4, 4 }));
     Assert.IsFalse(KerberosCryptoTransformer.AreEqualSlow(new byte[] { 4, 4, 4, 4 }, new byte[] { 3, 3, 3 }));
 }
예제 #11
0
        protected static async Task ValidateTicket(
            ApplicationSessionContext context,
            bool encodeNego = false,
            bool includePac = true,
            string spn      = FakeAppServiceSpn,
            bool mutualAuth = true
            )
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var ticket = context.ApReq;

            byte[] encoded;

            if (encodeNego)
            {
                encoded = ticket.EncodeGssApi().ToArray();
            }
            else
            {
                encoded = ticket.EncodeApplication().ToArray();
            }

            var authenticator = new KerberosAuthenticator(
                new KeyTable(
                    new KerberosKey(
                        FakeAdminAtCorpPassword,
                        principalName: new PrincipalName(
                            PrincipalNameType.NT_PRINCIPAL,
                            "CORP.IDENTITYINTERVENTION.com",
                            new[] { spn }
                            ),
                        saltType: SaltType.ActiveDirectoryUser
                        )
                    )
                );

            var validated = (KerberosIdentity)await authenticator.Authenticate(encoded);

            Assert.IsNotNull(validated);

            var sidClaim = validated.FindFirst(ClaimTypes.Sid);

            if (includePac)
            {
                Assert.AreEqual("S-1-5-123-456-789-12-321-888", sidClaim?.Value);
            }
            else
            {
                Assert.IsNull(sidClaim);
            }

            if (mutualAuth)
            {
                var sessionKey = context.AuthenticateServiceResponse(validated.ApRep);

                Assert.IsNotNull(sessionKey);
            }
            else
            {
                Assert.IsNull(validated.ApRep);
            }

            Assert.IsTrue(KerberosCryptoTransformer.AreEqualSlow(context.SessionKey.KeyValue.Span, validated.SessionKey.Span));
        }