Example #1
0
        public static IEqualityComparer <T1, T2> ToEqualityComparer <T1, T2>([NotNull] this Func <T1, T2, Boolean> comparison)
        {
            if (comparison is null)
            {
                throw new ArgumentNullException(nameof(comparison));
            }

            return(CustomEqualityComparer.Create(comparison));
        }
Example #2
0
        public void TryGetValue()
        {
            var actual           = new object();
            var check            = new object();
            var equalityComparer = new CustomEqualityComparer <object>(FuncHelper.GetTautologyFunc <object, object>(), _ => 0);
            var hashSet          = new HashSetEx <object>(equalityComparer)
            {
                actual
            };
            var test = hashSet.TryGetValue(check, out var found);

            Assert.IsTrue(test);
            Assert.AreSame(actual, found);
            Assert.AreNotSame(check, found);
        }
Example #3
0
        public async ValueTask Handshake(CancellationToken cancellationToken = default)
        {
            ProfileMessage myProfileMessage;
            ProfileMessage?otherProfileMessage = null;
            {
                {
                    var sessionId = new byte[32];
                    using (var randomNumberGenerator = RandomNumberGenerator.Create())
                    {
                        randomNumberGenerator.GetBytes(sessionId);
                    }

                    myProfileMessage = new ProfileMessage(
                        sessionId,
                        (_passwords.Count == 0) ? AuthenticationType.None : AuthenticationType.Password,
                        new[] { KeyExchangeAlgorithm.EcDh_P521_Sha2_256 },
                        new[] { KeyDerivationAlgorithm.Pbkdf2 },
                        new[] { CryptoAlgorithm.Aes_Gcm_256 },
                        new[] { HashAlgorithm.Sha2_256 });
                }

                var enqueueTask = _connection.EnqueueAsync((bufferWriter) => myProfileMessage.Export(bufferWriter, _bytesPool), cancellationToken);
                var dequeueTask = _connection.DequeueAsync((sequence) => otherProfileMessage = ProfileMessage.Import(sequence, _bytesPool), cancellationToken);

                await ValueTaskHelper.WhenAll(enqueueTask, dequeueTask);

                if (otherProfileMessage is null)
                {
                    throw new NullReferenceException();
                }
                if (myProfileMessage.AuthenticationType != otherProfileMessage.AuthenticationType)
                {
                    throw new OmniSecureConnectionException("AuthenticationType does not match.");
                }
            }

            var keyExchangeAlgorithm   = GetOverlapMaxEnum(myProfileMessage.KeyExchangeAlgorithms, otherProfileMessage.KeyExchangeAlgorithms);
            var keyDerivationAlgorithm = GetOverlapMaxEnum(myProfileMessage.KeyDerivationAlgorithms, otherProfileMessage.KeyDerivationAlgorithms);
            var cryptoAlgorithm        = GetOverlapMaxEnum(myProfileMessage.CryptoAlgorithms, otherProfileMessage.CryptoAlgorithms);
            var hashAlgorithm          = GetOverlapMaxEnum(myProfileMessage.HashAlgorithms, otherProfileMessage.HashAlgorithms);

            if (!EnumHelper.IsValid(keyExchangeAlgorithm))
            {
                throw new OmniSecureConnectionException("key exchange algorithm does not match.");
            }
            if (!EnumHelper.IsValid(keyDerivationAlgorithm))
            {
                throw new OmniSecureConnectionException("key derivation algorithm does not match.");
            }
            if (!EnumHelper.IsValid(cryptoAlgorithm))
            {
                throw new OmniSecureConnectionException("Crypto algorithm does not match.");
            }
            if (!EnumHelper.IsValid(hashAlgorithm))
            {
                throw new OmniSecureConnectionException("Hash algorithm does not match.");
            }

            ReadOnlyMemory <byte> secret = null;

            if (keyExchangeAlgorithm.HasFlag(KeyExchangeAlgorithm.EcDh_P521_Sha2_256))
            {
                var myAgreement = OmniAgreement.Create(OmniAgreementAlgorithmType.EcDh_P521_Sha2_256);

                OmniAgreementPrivateKey myAgreementPrivateKey;
                OmniAgreementPublicKey? otherAgreementPublicKey = null;
                {
                    {
                        myAgreementPrivateKey = myAgreement.GetOmniAgreementPrivateKey();

                        var enqueueTask = _connection.EnqueueAsync((bufferWriter) => myAgreement.GetOmniAgreementPublicKey().Export(bufferWriter, _bytesPool), cancellationToken);
                        var dequeueTask = _connection.DequeueAsync((sequence) => otherAgreementPublicKey = OmniAgreementPublicKey.Import(sequence, _bytesPool), cancellationToken);

                        await ValueTaskHelper.WhenAll(enqueueTask, dequeueTask);

                        if (otherAgreementPublicKey is null)
                        {
                            throw new NullReferenceException();
                        }
                        if ((DateTime.UtcNow - otherAgreementPublicKey.CreationTime.ToDateTime()).TotalMinutes > 30)
                        {
                            throw new OmniSecureConnectionException("Agreement public key has Expired.");
                        }
                    }

                    if (_passwords.Count > 0)
                    {
                        AuthenticationMessage myAuthenticationMessage;
                        AuthenticationMessage?otherAuthenticationMessage = null;
                        {
                            {
                                var myHashAndPasswordList = this.GetHashes(myProfileMessage, myAgreement.GetOmniAgreementPublicKey(), hashAlgorithm).ToList();

                                _random.Shuffle(myHashAndPasswordList);
                                myAuthenticationMessage = new AuthenticationMessage(myHashAndPasswordList.Select(n => n.Item1).ToArray());
                            }

                            var enqueueTask = _connection.EnqueueAsync((bufferWriter) => myAuthenticationMessage.Export(bufferWriter, _bytesPool), cancellationToken);
                            var dequeueTask = _connection.DequeueAsync((sequence) => otherAuthenticationMessage = AuthenticationMessage.Import(sequence, _bytesPool), cancellationToken);

                            await ValueTaskHelper.WhenAll(enqueueTask, dequeueTask);

                            if (otherAuthenticationMessage is null)
                            {
                                throw new NullReferenceException();
                            }

                            var matchedPasswords = new List <string>();
                            {
                                var equalityComparer = new CustomEqualityComparer <ReadOnlyMemory <byte> >((x, y) => BytesOperations.Equals(x.Span, y.Span), (x) => Fnv1_32.ComputeHash(x.Span));
                                var receiveHashes    = new HashSet <ReadOnlyMemory <byte> >(otherAuthenticationMessage.Hashes, equalityComparer);

                                foreach (var(hash, password) in this.GetHashes(otherProfileMessage, otherAgreementPublicKey, hashAlgorithm))
                                {
                                    if (receiveHashes.Contains(hash))
                                    {
                                        matchedPasswords.Add(password);
                                    }
                                }
                            }

                            if (matchedPasswords.Count == 0)
                            {
                                throw new OmniSecureConnectionException("Password does not match.");
                            }

                            _matchedPasswords = matchedPasswords.ToArray();
                        }
                    }
                }

                if (hashAlgorithm.HasFlag(HashAlgorithm.Sha2_256))
                {
                    secret = OmniAgreement.GetSecret(otherAgreementPublicKey, myAgreementPrivateKey);
                }
            }

            byte[] myCryptoKey;
            byte[] otherCryptoKey;
            byte[] myNonce;
            byte[] otherNonce;

            if (keyDerivationAlgorithm.HasFlag(KeyDerivationAlgorithm.Pbkdf2))
            {
                byte[] xorSessionId = new byte[Math.Max(myProfileMessage.SessionId.Length, otherProfileMessage.SessionId.Length)];
                BytesOperations.Xor(myProfileMessage.SessionId.Span, otherProfileMessage.SessionId.Span, xorSessionId);

                int cryptoKeyLength = 0;
                int nonceLength     = 0;

                if (cryptoAlgorithm.HasFlag(CryptoAlgorithm.Aes_Gcm_256))
                {
                    cryptoKeyLength = 32;
                    nonceLength     = 12;
                }

                myCryptoKey    = new byte[cryptoKeyLength];
                otherCryptoKey = new byte[cryptoKeyLength];
                myNonce        = new byte[nonceLength];
                otherNonce     = new byte[nonceLength];

                var kdfResult = new byte[(cryptoKeyLength + nonceLength) * 2];

                if (hashAlgorithm.HasFlag(HashAlgorithm.Sha2_256))
                {
                    Pbkdf2_Sha2_256.TryComputeHash(secret.Span, xorSessionId, 1024, kdfResult);
                }

                using (var stream = new MemoryStream(kdfResult))
                {
                    if (_type == OmniSecureConnectionType.Connected)
                    {
                        stream.Read(myCryptoKey, 0, myCryptoKey.Length);
                        stream.Read(otherCryptoKey, 0, otherCryptoKey.Length);
                        stream.Read(myNonce, 0, myNonce.Length);
                        stream.Read(otherNonce, 0, otherNonce.Length);
                    }
                    else if (_type == OmniSecureConnectionType.Accepted)
                    {
                        stream.Read(otherCryptoKey, 0, otherCryptoKey.Length);
                        stream.Read(myCryptoKey, 0, myCryptoKey.Length);
                        stream.Read(otherNonce, 0, otherNonce.Length);
                        stream.Read(myNonce, 0, myNonce.Length);
                    }
                }
            }
            else
            {
                throw new NotSupportedException(nameof(keyDerivationAlgorithm));
            }

            _state = new State(cryptoAlgorithm, hashAlgorithm, myCryptoKey, otherCryptoKey, myNonce, otherNonce);
        }
        public void WithEqualityComparerShouldNotThrowExceptionWithCorrectValue()
        {
            var jsonSettings = TestObjectFactory.GetJsonSerializerSettings();
            var equalityComparer = new CustomEqualityComparer();
            jsonSettings.EqualityComparer = equalityComparer;

            MyController<MvcController>
                .Instance()
                .WithoutValidation()
                .Calling(c => c.JsonWithSpecificSettingsAction(jsonSettings))
                .ShouldReturn()
                .Json()
                .WithJsonSerializerSettings(s =>
                    s.WithEqualityComparer(equalityComparer));
        }
Example #5
0
        public static void Test()
        {
            var version           = "2.1";
            var skippedNamespaces = new []
            {
                "System.Xml",
                "System.Data",
                "System.Net",
                "System.IO",
                "System.Drawing",
                "System.Runtime.Serialization",
                "System.Security.Cryptography"
            };
            // ---
            var url      = $"https://raw.githubusercontent.com/dotnet/standard/master/docs/versions/netstandard{version}_ref.md";
            var text     = new WebClient().DownloadString(url);
            var parser   = new StringProcessor(text);
            var keywords = new []
            {
                "class",
                "static class",
                "abstract class",
                "sealed class",
                "struct",
                "enum",
                "interface"
            };
            var entryAssembly        = typeof(ApiListTest).Assembly;
            var entryAssemblyName    = entryAssembly.GetName();
            var assemblyNameComparer = new CustomEqualityComparer <AssemblyName>
                                       (
                (left, right) => left.FullName == right.FullName,
                name => name.FullName.GetHashCode()
                                       );
            var assemblyDictionary = new Dictionary <AssemblyName, Assembly>(assemblyNameComparer)
            {
                { entryAssemblyName, entryAssembly }
            };
            var loadedAssemblies = GraphHelper.ExploreBreadthFirstGraph
                                   (
                entryAssemblyName,
                assemblyName =>
            {
                Assembly assembly = GetAssembly(assemblyName, assemblyDictionary);
                return(assembly.GetReferencedAssemblies());
            },
                assemblyNameComparer
                                   );
            var types = loadedAssemblies.SelectMany
                        (
                assemblyName => GetAssembly(assemblyName, assemblyDictionary).GetTypes()
                        );
            var lookup = new ProgressiveLookup <string, Type>(types.GroupProgressiveBy(type => type.FullName));

            parser.SkipUntilAfter("```C#");
            while (!parser.EndOfString)
            {
                parser.SkipWhile(CharHelper.IsClassicWhitespace);
                if (parser.Read("namespace"))
                {
                    parser.SkipWhile(CharHelper.IsClassicWhitespace);
                    var @namespace       = parser.ReadUntil(CharHelper.IsClassicWhitespace);
                    var includeNamespace = true;
                    foreach (var skippedNamespace in skippedNamespaces)
                    {
                        if (@namespace.StartsWith(skippedNamespace))
                        {
                            includeNamespace = false;
                            break;
                        }
                    }
                    parser.SkipWhile(CharHelper.IsClassicWhitespace);
                    parser.Read("{");
                    parser.SkipWhile(CharHelper.IsClassicWhitespace);
                    while (true)
                    {
                        if (parser.Read("public"))
                        {
                            parser.SkipWhile(CharHelper.IsClassicWhitespace);
                            if (parser.Read("delegate"))
                            {
                                parser.SkipWhile(CharHelper.IsClassicWhitespace);
                                parser.SkipUntil(CharHelper.IsClassicWhitespace);
                                parser.SkipWhile(CharHelper.IsClassicWhitespace);
                                ReadType(parser, @namespace, lookup, includeNamespace);
                                parser.ReadUntil(new[] { '\n', '\r', '{' });
                                if (parser.Peek('\n') || parser.Peek('\r'))
                                {
                                    continue;
                                }
                            }
                            else if (parser.Read(keywords) != null)
                            {
                                parser.SkipWhile(CharHelper.IsClassicWhitespace);
                                ReadType(parser, @namespace, lookup, includeNamespace);
                            }
                            var count = 0;
                            do
                            {
                                if (parser.ReadUntil(new[] { '{', '}' }) == null)
                                {
                                    break;
                                }
                                if (parser.Read() == '{')
                                {
                                    count++;
                                }
                                else
                                {
                                    count--;
                                }
                            } while (count != 0);
                        }
                        parser.SkipWhile(CharHelper.IsClassicWhitespace);
                        if (parser.Read("}"))
                        {
                            break;
                        }
                    }
                }
                parser.Read("```");
            }
        }