Beispiel #1
0
        private async Task SendMessageAsync(Mocks.CloudBlobStorageProviderMock cloudStorage, Mocks.InboxHttpHandlerMock inboxMock, CryptoSettings senderCrypto, OwnEndpoint senderEndpoint, Endpoint receiverEndpoint)
        {
            Requires.NotNull(cloudStorage, "cloudStorage");
            Requires.NotNull(senderCrypto, "senderCrypto");
            Requires.NotNull(senderEndpoint, "senderEndpoint");
            Requires.NotNull(receiverEndpoint, "receiverEndpoint");

            var httpHandler = new Mocks.HttpMessageHandlerMock();

            cloudStorage.AddHttpHandler(httpHandler);

            inboxMock.Register(httpHandler);

            var sentMessage = Valid.Message;

            var channel = new Channel()
            {
                HttpClient = new HttpClient(httpHandler),
                CloudBlobStorage = cloudStorage,
                CryptoServices = senderCrypto,
                Endpoint = senderEndpoint,
                Logger = this.logger,
            };

            await channel.PostAsync(sentMessage, new[] { receiverEndpoint }, Valid.ExpirationUtc);
        }
Beispiel #2
0
        private async Task ReceiveMessageAsync(Mocks.CloudBlobStorageProviderMock cloudStorage, Mocks.InboxHttpHandlerMock inboxMock, CryptoSettings receiverCrypto, OwnEndpoint receiverEndpoint)
        {
            Requires.NotNull(cloudStorage, "cloudStorage");
            Requires.NotNull(receiverCrypto, "receiverCrypto");
            Requires.NotNull(receiverEndpoint, "receiverEndpoint");

            var httpHandler = new Mocks.HttpMessageHandlerMock();

            cloudStorage.AddHttpHandler(httpHandler);
            inboxMock.Register(httpHandler);

            var channel = new Channel
            {
                HttpClient = new HttpClient(httpHandler),
                HttpClientLongPoll = new HttpClient(httpHandler),
                CloudBlobStorage = cloudStorage,
                CryptoServices = receiverCrypto,
                Endpoint = receiverEndpoint,
                Logger = this.logger,
            };

            var messages = await channel.ReceiveAsync();
            Assert.Equal(1, messages.Count);
            Assert.Equal(Valid.Message, messages[0].Payload);
        }
Beispiel #3
0
            /// <summary>
            ///     Gets the settings.
            /// </summary>
            /// <param name="version">The version.</param>
            /// <returns></returns>
            /// <exception cref="System.ArgumentOutOfRangeException">version</exception>
            public static CryptoSettings GetSettings(int version = CryptoVersion10)
            {
                CryptoSettings settings;

                switch (version)
                {
                case CryptoVersion10:
                    settings = new CryptoSettings
                    {
                        Version        = version,
                        CryptoProvider = new Aes256CryptoProvider()
                    };
                    break;

                default:
                    settings = null;
                    break;
                }

                if (settings == null)
                {
                    throw new ArgumentOutOfRangeException(nameof(version));
                }

                return(settings);
            }
Beispiel #4
0
 public void CreateAddressBookEntry()
 {
     var ownContact = Valid.ReceivingEndpoint;
     CryptoSettings cryptoServices = new CryptoSettings(SecurityLevel.Minimum);
     var entry = ownContact.CreateAddressBookEntry(cryptoServices);
     Assert.NotEqual(0, entry.Signature?.Length);
     Assert.NotEqual(0, entry.SerializedEndpoint?.Length);
 }
Beispiel #5
0
        public void FillFileSystemTest()
        {
            ConfigurationTest.Initialize();
            Random r = new Random(1234);

            using (var io = ConfigurationTest.CreateMemoryIO()) {
                FileSystem fs = FileSystem.Create(io);

                byte[] data = new byte[1024 * 1024];

                Directory d = fs.RootDirectory;
                File      f = fs.CreateFile(d, "TEST");
                int       totalBytesWritten = 0;
                using (FileIO fio = new FileIO(fs, f)) {
                    int bytesWritten = 0;
                    do
                    {
                        r.NextBytes(data);
                        bytesWritten       = fio.WriteFile(data, f.Length);
                        totalBytesWritten += bytesWritten;
                    } while (bytesWritten != 0);
                }

                fs.Dispose();

                CryptoSettings cryptoSettings = Configuration.CryptoSettings;
                Options        options        = Configuration.Options;
                Configuration.Reset();
                Configuration.CryptoSettings = cryptoSettings;
                Configuration.Options        = options;

                fs = FileSystem.Mount(io);

                r = new Random(1234);
                f = fs.GetContainedFiles(fs.RootDirectory)["TEST"];
                Assert.AreEqual(f.Length, totalBytesWritten);
                int    totalBytesRead = 0;
                byte[] compare        = new byte[1024 * 1024];
                using (FileIO fio = new FileIO(fs, f)) {
                    int bytesRead = 0;
                    do
                    {
                        r.NextBytes(data);
                        bytesRead       = fio.ReadFile(compare, totalBytesRead);
                        totalBytesRead += bytesRead;
                        for (int i = 0; i < bytesRead; i++)
                        {
                            Assert.AreEqual(compare[i], data[i]);
                        }
                    } while (bytesRead != 0);
                }

                Assert.AreEqual(totalBytesRead, totalBytesWritten);

                fs.Dispose();
            }
        }
Beispiel #6
0
        private async Task TestSendAndReceiveAsync(
            CryptoSettings senderCrypto, OwnEndpoint senderEndpoint, CryptoSettings receiverCrypto, OwnEndpoint receiverEndpoint)
        {
            var inboxMock = new Mocks.InboxHttpHandlerMock(new[] { receiverEndpoint.PublicEndpoint });
            var cloudStorage = new Mocks.CloudBlobStorageProviderMock();

            await this.SendMessageAsync(cloudStorage, inboxMock, senderCrypto, senderEndpoint, receiverEndpoint.PublicEndpoint);
            await this.ReceiveMessageAsync(cloudStorage, inboxMock, receiverCrypto, receiverEndpoint);
        }
Beispiel #7
0
        public void CreateAddressBookEntry()
        {
            var            ownContact     = Valid.ReceivingEndpoint;
            CryptoSettings cryptoServices = new CryptoSettings(SecurityLevel.Minimum);
            var            entry          = ownContact.CreateAddressBookEntry(cryptoServices);

            Assert.NotEqual(0, entry.Signature?.Length);
            Assert.NotEqual(0, entry.SerializedEndpoint?.Length);
        }
        public void ExtractEndpoint()
        {
            var ownContact = new OwnEndpoint(Valid.ReceivingEndpoint.SigningKey, Valid.ReceivingEndpoint.EncryptionKey);
            var cryptoServices = new CryptoSettings(SecurityLevel.Minimum);
            var entry = ownContact.CreateAddressBookEntry(cryptoServices);

            var endpoint = entry.ExtractEndpoint();
            Assert.Equal(ownContact.PublicEndpoint, endpoint);
        }
        public void ExtractEndpoint()
        {
            var ownContact     = new OwnEndpoint(Valid.ReceivingEndpoint.SigningKey, Valid.ReceivingEndpoint.EncryptionKey);
            var cryptoServices = new CryptoSettings(SecurityLevel.Minimum);
            var entry          = ownContact.CreateAddressBookEntry(cryptoServices);

            var endpoint = entry.ExtractEndpoint();

            Assert.Equal(ownContact.PublicEndpoint, endpoint);
        }
Beispiel #10
0
        private async Task TestSendAndReceiveAsync(
            CryptoSettings senderCrypto, OwnEndpoint senderEndpoint, CryptoSettings receiverCrypto, OwnEndpoint receiverEndpoint)
        {
            var inboxMock    = new Mocks.InboxHttpHandlerMock(new[] { receiverEndpoint.PublicEndpoint });
            var cloudStorage = new Mocks.CloudBlobStorageProviderMock();

            await this.SendMessageAsync(cloudStorage, inboxMock, senderCrypto, senderEndpoint, receiverEndpoint.PublicEndpoint);

            await this.ReceiveMessageAsync(cloudStorage, inboxMock, receiverCrypto, receiverEndpoint);
        }
Beispiel #11
0
        public async Task CrossSecurityLevelAddressBookExchange()
        {
            var lowLevelCrypto = new CryptoSettings(SecurityLevel.Minimum);
            var lowLevelEndpoint = Valid.GenerateOwnEndpoint(lowLevelCrypto);

            var highLevelCrypto = new CryptoSettings(SecurityLevel.Minimum) { AsymmetricKeySize = 2048 };
            var highLevelEndpoint = Valid.GenerateOwnEndpoint(highLevelCrypto);

            await this.TestSendAndReceiveAsync(lowLevelCrypto, lowLevelEndpoint, highLevelCrypto, highLevelEndpoint);
            await this.TestSendAndReceiveAsync(highLevelCrypto, highLevelEndpoint, lowLevelCrypto, lowLevelEndpoint);
        }
Beispiel #12
0
        /// <summary>
        /// Encrypts and encodes the specified data.
        /// </summary>
        /// <param name="plainText">The plain text.</param>
        /// <returns></returns>
        public string EncryptAndEncode(string plainText)
        {
            if (string.IsNullOrEmpty(plainText))
            {
                return(plainText);
            }

            CryptoSettings  settings       = CryptoSettings.GetSettings();
            ICryptoProvider cryptoProvider = settings.CryptoProvider;

            byte[] iv         = cryptoProvider.GenerateRandomIv();
            byte[] cipherText = cryptoProvider.EncryptData(plainText, Initialise(), iv);
            return(EncodeCipherText(settings.Version, iv, cipherText));
        }
Beispiel #13
0
        public async Task CrossSecurityLevelAddressBookExchange()
        {
            var lowLevelCrypto   = new CryptoSettings(SecurityLevel.Minimum);
            var lowLevelEndpoint = Valid.GenerateOwnEndpoint(lowLevelCrypto);

            var highLevelCrypto = new CryptoSettings(SecurityLevel.Minimum)
            {
                AsymmetricKeySize = 2048
            };
            var highLevelEndpoint = Valid.GenerateOwnEndpoint(highLevelCrypto);

            await this.TestSendAndReceiveAsync(lowLevelCrypto, lowLevelEndpoint, highLevelCrypto, highLevelEndpoint);

            await this.TestSendAndReceiveAsync(highLevelCrypto, highLevelEndpoint, lowLevelCrypto, lowLevelEndpoint);
        }
Beispiel #14
0
        internal static OwnEndpoint GenerateOwnEndpoint(CryptoSettings cryptoProvider = null)
        {
            cryptoProvider = cryptoProvider ?? new CryptoSettings(SecurityLevel.Minimum);

            var inboxFactory = new Mock<IEndpointInboxFactory>();
            inboxFactory.Setup(f => f.CreateInboxAsync(CancellationToken.None)).Returns(
                Task.FromResult(
                    new InboxCreationResponse
                    { InboxOwnerCode = "some owner code", MessageReceivingEndpoint = MessageReceivingEndpoint.AbsoluteUri }));
            var endpointServices = new OwnEndpointServices
            {
                Channel = new Channel { CryptoServices = cryptoProvider },
                EndpointInboxFactory = inboxFactory.Object,
            };

            var ownContact = endpointServices.CreateAsync().Result;
            return ownContact;
        }
Beispiel #15
0
        public void PostAndReceiveAsync()
        {
            Task.Run(async delegate
            {
                var sender = Valid.GenerateOwnEndpoint();
                var receiver = Valid.GenerateOwnEndpoint();

                var cloudStorage = new Mocks.CloudBlobStorageProviderMock();
                var inboxMock = new Mocks.InboxHttpHandlerMock(new[] { receiver.PublicEndpoint });
                var cryptoProvider = new CryptoSettings(SecurityLevel.Minimum);

                var sentMessage = Valid.Message;
                await this.SendMessageAsync(cloudStorage, inboxMock, cryptoProvider, sender, receiver.PublicEndpoint, sentMessage);
                var messages = await this.ReceiveMessageAsync(cloudStorage, inboxMock, new CryptoSettings(SecurityLevel.Minimum), receiver);

                Assert.Equal(1, messages.Count);
                var receivedMessage = messages.Single();
                Assert.Equal(receivedMessage.Payload.ContentType, sentMessage.ContentType);
                Assert.Equal(receivedMessage.Payload.Content, sentMessage.Content);
            }).GetAwaiter().GetResult();
        }
Beispiel #16
0
        public void PostAndReceiveAsync()
        {
            Task.Run(async delegate
            {
                var sender   = Valid.GenerateOwnEndpoint();
                var receiver = Valid.GenerateOwnEndpoint();

                var cloudStorage   = new Mocks.CloudBlobStorageProviderMock();
                var inboxMock      = new Mocks.InboxHttpHandlerMock(new[] { receiver.PublicEndpoint });
                var cryptoProvider = new CryptoSettings(SecurityLevel.Minimum);

                var sentMessage = Valid.Message;
                await this.SendMessageAsync(cloudStorage, inboxMock, cryptoProvider, sender, receiver.PublicEndpoint, sentMessage);
                var messages = await this.ReceiveMessageAsync(cloudStorage, inboxMock, new CryptoSettings(SecurityLevel.Minimum), receiver);

                Assert.Equal(1, messages.Count);
                var receivedMessage = messages.Single();
                Assert.Equal(receivedMessage.Payload.ContentType, sentMessage.ContentType);
                Assert.Equal(receivedMessage.Payload.Content, sentMessage.Content);
            }).GetAwaiter().GetResult();
        }
Beispiel #17
0
        /// <summary>
        /// Decodes and decrypts the specified cipher text.
        /// </summary>
        /// <param name="encodedCipherText">The encoded cipher text.</param>
        /// <returns></returns>
        public string DecodeAndDecrypt(string encodedCipherText)
        {
            if (string.IsNullOrEmpty(encodedCipherText))
            {
                return(encodedCipherText);
            }

            int version;

            byte[] iv;
            byte[] cipherText;

            if (!TryDecodeEncodedCipherText(encodedCipherText, out version, out iv, out cipherText))
            {
                return(null);
            }

            CryptoSettings  settings       = CryptoSettings.GetSettings(version);
            ICryptoProvider cryptoProvider = settings.CryptoProvider;

            return(cryptoProvider.DecryptData(cipherText, Initialise(), iv));
        }
Beispiel #18
0
        public void FileDeleteTest()
        {
            ConfigurationTest.Initialize();
            Random r = new Random(1234);

            using (var io = ConfigurationTest.CreateMemoryIO()) {
                FileSystem fs = FileSystem.Create(io);

                byte[] data = new byte[1024 * 1024];
                r.NextBytes(data);

                Directory d = fs.RootDirectory;
                File      f = fs.CreateFile(d, "TEST");
                using (FileIO fio = new FileIO(fs, f)) {
                    Assert.AreEqual(data.Length, fio.WriteFile(data, 0));
                }

                fs.Dispose();

                CryptoSettings cryptoSettings = Configuration.CryptoSettings;
                Options        options        = Configuration.Options;
                Configuration.Reset();
                Configuration.CryptoSettings = cryptoSettings;
                Configuration.Options        = options;

                fs = FileSystem.Mount(io);
                byte[] data2 = new byte[data.Length];

                File f2 = fs.GetContainedFiles(fs.RootDirectory)["TEST"];

                fs.RemoveFile(f2);

                Assert.AreEqual(0, (from s in fs.ClusterStates where (s & ClusterState.Used) != 0 && (s & ClusterState.System) == 0 select s).Count());
                Assert.AreEqual(0, fs.GetContainedFiles(fs.RootDirectory).Count);

                fs.Dispose();
            }
        }
Beispiel #19
0
        internal static OwnEndpoint GenerateOwnEndpoint(CryptoSettings cryptoProvider = null)
        {
            cryptoProvider = cryptoProvider ?? new CryptoSettings(SecurityLevel.Minimum);

            var inboxFactory = new Mock <IEndpointInboxFactory>();

            inboxFactory.Setup(f => f.CreateInboxAsync(CancellationToken.None)).Returns(
                Task.FromResult(
                    new InboxCreationResponse
            {
                InboxOwnerCode = "some owner code", MessageReceivingEndpoint = MessageReceivingEndpoint.AbsoluteUri
            }));
            var endpointServices = new OwnEndpointServices
            {
                Channel = new Channel {
                    CryptoServices = cryptoProvider
                },
                EndpointInboxFactory = inboxFactory.Object,
            };

            var ownContact = endpointServices.CreateAsync().Result;

            return(ownContact);
        }
Beispiel #20
0
        /// <summary>
        /// Parse crypto settings from INI file
        /// </summary>
        public static CryptoSettings ParseCryptoSettings(DirectoryReference InProjectDirectory, UnrealTargetPlatform InTargetPlatform)
        {
            CryptoSettings Settings = new CryptoSettings();

            ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, InProjectDirectory, InTargetPlatform);

            Ini.GetBool("PlatformCrypto", "PlatformRequiresDataCrypto", out Settings.bDataCryptoRequired);

            // For now, we'll just not parse any keys if data crypto is disabled for this platform. In the future, we might want to use
            // these keys for non-data purposes (other general purpose encryption maybe?)
            if (!Settings.bDataCryptoRequired)
            {
                return(Settings);
            }

            {
                // Start by parsing the legacy encryption.ini settings
                Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Encryption, InProjectDirectory, InTargetPlatform);
                Ini.GetBool("Core.Encryption", "SignPak", out Settings.bEnablePakSigning);

                string[] SigningKeyStrings = new string[3];
                Ini.GetString("Core.Encryption", "rsa.privateexp", out SigningKeyStrings[0]);
                Ini.GetString("Core.Encryption", "rsa.modulus", out SigningKeyStrings[1]);
                Ini.GetString("Core.Encryption", "rsa.publicexp", out SigningKeyStrings[2]);

                if (String.IsNullOrEmpty(SigningKeyStrings[0]) || String.IsNullOrEmpty(SigningKeyStrings[1]) || String.IsNullOrEmpty(SigningKeyStrings[2]))
                {
                    SigningKeyStrings = null;
                }
                else
                {
                    Settings.SigningKey = new SigningKeyPair();
                    Settings.SigningKey.PrivateKey.Exponent = ParseHexStringToByteArray(SigningKeyStrings[0]);
                    Settings.SigningKey.PrivateKey.Modulus  = ParseHexStringToByteArray(SigningKeyStrings[1]);
                    Settings.SigningKey.PublicKey.Exponent  = ParseHexStringToByteArray(SigningKeyStrings[2]);
                    Settings.SigningKey.PublicKey.Modulus   = Settings.SigningKey.PrivateKey.Modulus;
                }

                Ini.GetBool("Core.Encryption", "EncryptPak", out Settings.bEnablePakIndexEncryption);
                Settings.bEnablePakFullAssetEncryption = false;
                Settings.bEnablePakUAssetEncryption    = false;
                Settings.bEnablePakIniEncryption       = Settings.bEnablePakIndexEncryption;

                string EncryptionKeyString;
                Ini.GetString("Core.Encryption", "aes.key", out EncryptionKeyString);
                Settings.EncryptionKey     = new EncryptionKey();
                Settings.EncryptionKey.Key = ParseAnsiStringToByteArray(EncryptionKeyString);
            }

            Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Crypto, InProjectDirectory, InTargetPlatform);
            string SectionName = "/Script/CryptoKeys.CryptoKeysSettings";
            ConfigHierarchySection CryptoSection = Ini.FindSection(SectionName);

            // If we have new format crypto keys, read them in over the top of the legacy settings
            if (CryptoSection != null && CryptoSection.KeyNames.Count() > 0)
            {
                Ini.GetBool(SectionName, "bEnablePakSigning", out Settings.bEnablePakSigning);
                Ini.GetBool(SectionName, "bEncryptPakIniFiles", out Settings.bEnablePakIniEncryption);
                Ini.GetBool(SectionName, "bEncryptPakIndex", out Settings.bEnablePakIndexEncryption);
                Ini.GetBool(SectionName, "bEncryptUAssetFiles", out Settings.bEnablePakUAssetEncryption);
                Ini.GetBool(SectionName, "bEncryptAllAssetFiles", out Settings.bEnablePakFullAssetEncryption);

                // Parse encryption key
                string EncryptionKeyString;
                Ini.GetString(SectionName, "EncryptionKey", out EncryptionKeyString);
                if (!string.IsNullOrEmpty(EncryptionKeyString))
                {
                    Settings.EncryptionKey     = new EncryptionKey();
                    Settings.EncryptionKey.Key = System.Convert.FromBase64String(EncryptionKeyString);

                    if (Settings.EncryptionKey.Key.Length != 32)
                    {
                        throw new Exception("The encryption key specified in the crypto config file must be 32 bytes long!");
                    }
                }

                // Parse signing key
                string PrivateExponent, PublicExponent, Modulus;
                Ini.GetString(SectionName, "SigningPrivateExponent", out PrivateExponent);
                Ini.GetString(SectionName, "SigningModulus", out Modulus);
                Ini.GetString(SectionName, "SigningPublicExponent", out PublicExponent);

                if (!String.IsNullOrEmpty(PrivateExponent) && !String.IsNullOrEmpty(PublicExponent) && !String.IsNullOrEmpty(Modulus))
                {
                    Settings.SigningKey = new SigningKeyPair();
                    Settings.SigningKey.PublicKey.Exponent  = System.Convert.FromBase64String(PublicExponent);
                    Settings.SigningKey.PublicKey.Modulus   = System.Convert.FromBase64String(Modulus);
                    Settings.SigningKey.PrivateKey.Exponent = System.Convert.FromBase64String(PrivateExponent);
                    Settings.SigningKey.PrivateKey.Modulus  = Settings.SigningKey.PublicKey.Modulus;
                }
            }

            return(Settings);
        }
Beispiel #21
0
        private async Task SendMessageAsync(Mocks.CloudBlobStorageProviderMock cloudStorage, Mocks.InboxHttpHandlerMock inboxMock, CryptoSettings senderCrypto, OwnEndpoint senderEndpoint, Endpoint receiverEndpoint)
        {
            Requires.NotNull(cloudStorage, "cloudStorage");
            Requires.NotNull(senderCrypto, "senderCrypto");
            Requires.NotNull(senderEndpoint, "senderEndpoint");
            Requires.NotNull(receiverEndpoint, "receiverEndpoint");

            var httpHandler = new Mocks.HttpMessageHandlerMock();

            cloudStorage.AddHttpHandler(httpHandler);

            inboxMock.Register(httpHandler);

            var sentMessage = Valid.Message;

            var channel = new Channel()
            {
                HttpClient       = new HttpClient(httpHandler),
                CloudBlobStorage = cloudStorage,
                CryptoServices   = senderCrypto,
                Endpoint         = senderEndpoint,
                Logger           = this.logger,
            };

            await channel.PostAsync(sentMessage, new[] { receiverEndpoint }, Valid.ExpirationUtc);
        }
 public AddressBookEntryTest()
 {
     this.desktopCryptoProvider = TestUtilities.CreateAuthenticCryptoProvider();
 }
Beispiel #23
0
        private async Task ReceiveMessageAsync(Mocks.CloudBlobStorageProviderMock cloudStorage, Mocks.InboxHttpHandlerMock inboxMock, CryptoSettings receiverCrypto, OwnEndpoint receiverEndpoint)
        {
            Requires.NotNull(cloudStorage, "cloudStorage");
            Requires.NotNull(receiverCrypto, "receiverCrypto");
            Requires.NotNull(receiverEndpoint, "receiverEndpoint");

            var httpHandler = new Mocks.HttpMessageHandlerMock();

            cloudStorage.AddHttpHandler(httpHandler);
            inboxMock.Register(httpHandler);

            var channel = new Channel
            {
                HttpClient         = new HttpClient(httpHandler),
                HttpClientLongPoll = new HttpClient(httpHandler),
                CloudBlobStorage   = cloudStorage,
                CryptoServices     = receiverCrypto,
                Endpoint           = receiverEndpoint,
                Logger             = this.logger,
            };

            var messages = await channel.ReceiveAsync();

            Assert.Equal(1, messages.Count);
            Assert.Equal(Valid.Message, messages[0].Payload);
        }
Beispiel #24
0
        /// <summary>
        /// Parse crypto settings from INI file
        /// </summary>
        public static CryptoSettings ParseCryptoSettings(DirectoryReference InProjectDirectory, UnrealTargetPlatform InTargetPlatform)
        {
            CryptoSettings Settings = new CryptoSettings();

            ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, InProjectDirectory, InTargetPlatform);

            Ini.GetBool("PlatformCrypto", "PlatformRequiresDataCrypto", out Settings.bDataCryptoRequired);

            // For now, we'll just not parse any keys if data crypto is disabled for this platform. In the future, we might want to use
            // these keys for non-data purposes (other general purpose encryption maybe?)
            if (!Settings.bDataCryptoRequired)
            {
                return(Settings);
            }

            {
                // Start by parsing the legacy encryption.ini settings
                Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Encryption, InProjectDirectory, InTargetPlatform);
                Ini.GetBool("Core.Encryption", "SignPak", out Settings.bEnablePakSigning);

                string[] SigningKeyStrings = new string[3];
                Ini.GetString("Core.Encryption", "rsa.privateexp", out SigningKeyStrings[0]);
                Ini.GetString("Core.Encryption", "rsa.modulus", out SigningKeyStrings[1]);
                Ini.GetString("Core.Encryption", "rsa.publicexp", out SigningKeyStrings[2]);

                if (String.IsNullOrEmpty(SigningKeyStrings[0]) || String.IsNullOrEmpty(SigningKeyStrings[1]) || String.IsNullOrEmpty(SigningKeyStrings[2]))
                {
                    SigningKeyStrings = null;
                }
                else
                {
                    Settings.SigningKey = new SigningKeyPair();
                    Settings.SigningKey.PrivateKey.Exponent = ParseHexStringToByteArray(ProcessSigningKeyInputStrings(SigningKeyStrings[0]), 64);
                    Settings.SigningKey.PrivateKey.Modulus  = ParseHexStringToByteArray(ProcessSigningKeyInputStrings(SigningKeyStrings[1]), 64);
                    Settings.SigningKey.PublicKey.Exponent  = ParseHexStringToByteArray(ProcessSigningKeyInputStrings(SigningKeyStrings[2]), 64);
                    Settings.SigningKey.PublicKey.Modulus   = Settings.SigningKey.PrivateKey.Modulus;

                    if ((Settings.SigningKey.PrivateKey.Exponent.Length > 64) ||
                        (Settings.SigningKey.PrivateKey.Modulus.Length > 64) ||
                        (Settings.SigningKey.PublicKey.Exponent.Length > 64) ||
                        (Settings.SigningKey.PublicKey.Modulus.Length > 64))
                    {
                        throw new Exception(string.Format("[{0}] Signing keys parsed from encryption.ini are too long. They must be a maximum of 64 bytes long!", InProjectDirectory));
                    }
                }

                Ini.GetBool("Core.Encryption", "EncryptPak", out Settings.bEnablePakIndexEncryption);
                Settings.bEnablePakFullAssetEncryption = false;
                Settings.bEnablePakUAssetEncryption    = false;
                Settings.bEnablePakIniEncryption       = Settings.bEnablePakIndexEncryption;

                string EncryptionKeyString;
                Ini.GetString("Core.Encryption", "aes.key", out EncryptionKeyString);
                Settings.EncryptionKey = new EncryptionKey();

                if (EncryptionKeyString.Length > 0)
                {
                    if (EncryptionKeyString.Length < 32)
                    {
                        Log.WriteLine(LogEventType.Warning, "AES key parsed from encryption.ini is too short. It must be 32 bytes, so will be padded with 0s, giving sub-optimal security!");
                    }
                    else if (EncryptionKeyString.Length > 32)
                    {
                        Log.WriteLine(LogEventType.Warning, "AES key parsed from encryption.ini is too long. It must be 32 bytes, so will be truncated!");
                    }

                    Settings.EncryptionKey.Key = ParseAnsiStringToByteArray(EncryptionKeyString, 32);
                }
            }

            Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Crypto, InProjectDirectory, InTargetPlatform);
            string SectionName = "/Script/CryptoKeys.CryptoKeysSettings";
            ConfigHierarchySection CryptoSection = Ini.FindSection(SectionName);

            // If we have new format crypto keys, read them in over the top of the legacy settings
            if (CryptoSection != null && CryptoSection.KeyNames.Count() > 0)
            {
                Ini.GetBool(SectionName, "bEnablePakSigning", out Settings.bEnablePakSigning);
                Ini.GetBool(SectionName, "bEncryptPakIniFiles", out Settings.bEnablePakIniEncryption);
                Ini.GetBool(SectionName, "bEncryptPakIndex", out Settings.bEnablePakIndexEncryption);
                Ini.GetBool(SectionName, "bEncryptUAssetFiles", out Settings.bEnablePakUAssetEncryption);
                Ini.GetBool(SectionName, "bEncryptAllAssetFiles", out Settings.bEnablePakFullAssetEncryption);

                // Parse encryption key
                string EncryptionKeyString;
                Ini.GetString(SectionName, "EncryptionKey", out EncryptionKeyString);
                if (!string.IsNullOrEmpty(EncryptionKeyString))
                {
                    Settings.EncryptionKey     = new EncryptionKey();
                    Settings.EncryptionKey.Key = System.Convert.FromBase64String(EncryptionKeyString);
                }

                // Parse signing key
                string PrivateExponent, PublicExponent, Modulus;
                Ini.GetString(SectionName, "SigningPrivateExponent", out PrivateExponent);
                Ini.GetString(SectionName, "SigningModulus", out Modulus);
                Ini.GetString(SectionName, "SigningPublicExponent", out PublicExponent);

                if (!String.IsNullOrEmpty(PrivateExponent) && !String.IsNullOrEmpty(PublicExponent) && !String.IsNullOrEmpty(Modulus))
                {
                    Settings.SigningKey = new SigningKeyPair();
                    Settings.SigningKey.PublicKey.Exponent  = System.Convert.FromBase64String(PublicExponent);
                    Settings.SigningKey.PublicKey.Modulus   = System.Convert.FromBase64String(Modulus);
                    Settings.SigningKey.PrivateKey.Exponent = System.Convert.FromBase64String(PrivateExponent);
                    Settings.SigningKey.PrivateKey.Modulus  = Settings.SigningKey.PublicKey.Modulus;
                }
            }

            return(Settings);
        }
 public AddressBookEntryTest()
 {
     this.desktopCryptoProvider = TestUtilities.CreateAuthenticCryptoProvider();
 }
Beispiel #26
0
        public void FileIOTest()
        {
            ConfigurationTest.Initialize();
            Random r = new Random(1234);

            using (var io = ConfigurationTest.CreateMemoryIO()) {
                FileSystem fs = FileSystem.Create(io);

                byte[] data = new byte[1024 * 1024];
                r.NextBytes(data);

                Directory d = fs.RootDirectory;
                File      f = fs.CreateFile(d, "TEST");
                using (FileIO fio = new FileIO(fs, f)) {
                    Assert.AreEqual(data.Length, fio.WriteFile(data, 0));
                    for (int j = 0; j < 100; j++)
                    {
                        switch (r.Next(3))
                        {
                        case 0: {
                            // Internal Overwrite
                            int offset = r.Next(data.Length);
                            int count  = r.Next(data.Length - offset);
                            if (count != 0)
                            {
                                byte[] newData = new byte[count];
                                r.NextBytes(newData);
                                Assert.AreEqual(newData.Length, fio.WriteFile(newData, offset));
                                Buffer.BlockCopy(newData, 0, data, offset, count);
                                Assert.AreEqual(data.Length, f.Length);
                            }
                            break;
                        }

                        case 1: {
                            // Append
                            int count = r.Next(2 * 1024 * 1024 - (int)f.Length);
                            if (count != 0)
                            {
                                int    offset  = (int)f.Length;
                                byte[] newData = new byte[count];
                                r.NextBytes(newData);
                                Assert.AreEqual(newData.Length, fio.WriteFile(newData, offset));
                                byte[] dt = new byte[count + data.Length];
                                Buffer.BlockCopy(data, 0, dt, 0, offset);
                                Buffer.BlockCopy(newData, 0, dt, offset, count);
                                data = dt;
                                Assert.AreEqual(data.Length, f.Length);
                            }
                            break;
                        }

                        case 2: {
                            // Set Length
                            int count = r.Next(2 * 1024 * 1024);
                            fio.SetEndOfFile(count);
                            byte[] newData = new byte[count];
                            Buffer.BlockCopy(data, 0, newData, 0, Math.Min(count, data.Length));
                            data = newData;
                            Assert.AreEqual(data.Length, f.Length);
                            break;
                        }
                        }
                    }
                }

                int length   = (int)f.Length;
                int clusters = length <= FileHeaderCluster.DataSize ? 1 :
                               (length - FileHeaderCluster.DataSize + FileDataCluster.DataSize - 1) / FileDataCluster.DataSize + 1;
                Assert.AreEqual(clusters, (from s in fs.ClusterStates where (s & ClusterState.Used) != 0 && (s & ClusterState.System) == 0 select s).Count());

                fs.Dispose();

                CryptoSettings cryptoSettings = Configuration.CryptoSettings;
                Options        options        = Configuration.Options;
                Configuration.Reset();
                Configuration.CryptoSettings = cryptoSettings;
                Configuration.Options        = options;

                fs = FileSystem.Mount(io);
                byte[] data2 = new byte[data.Length];

                File f2 = fs.GetContainedFiles(fs.RootDirectory)["TEST"];
                Assert.AreEqual(f.Length, f2.Length);
                using (FileIO fio = new FileIO(fs, f2)) {
                    Assert.AreEqual(data2.Length, fio.ReadFile(data2, 0));
                    Assert.AreEqual(0, fio.ReadFile(data2, data2.Length));
                }

                Assert.IsTrue(data.SequenceEqual(data2));

                length   = (int)f2.Length;
                clusters = length <= FileHeaderCluster.DataSize ? 1 :
                           (length - FileHeaderCluster.DataSize + FileDataCluster.DataSize - 1) / FileDataCluster.DataSize + 1;
                Assert.AreEqual(clusters, (from s in fs.ClusterStates where (s & ClusterState.Used) != 0 && (s & ClusterState.System) == 0 select s).Count());

                using (FileIO fio = new FileIO(fs, f2)) {
                    fio.SetEndOfFile(0);
                }

                Assert.AreEqual(0, f2.Length);
                Assert.AreEqual(0, (from s in fs.ClusterStates where (s & ClusterState.Used) != 0 && (s & ClusterState.System) == 0 select s).Count());

                fs.Dispose();

                Configuration.Reset();
                Configuration.CryptoSettings = cryptoSettings;
                Configuration.Options        = options;

                fs = FileSystem.Mount(io);
                File f3 = fs.GetContainedFiles(fs.RootDirectory)["TEST"];
                Assert.AreEqual(0, f3.Length);
                Assert.AreEqual(0, (from s in fs.ClusterStates where (s & ClusterState.Used) != 0 && (s & ClusterState.System) == 0 select s).Count());
            }
        }
Beispiel #27
0
        private async Task<IReadOnlyCollection<Channel.PayloadReceipt>> ReceiveMessageAsync(Mocks.CloudBlobStorageProviderMock cloudBlobStorage, Mocks.InboxHttpHandlerMock inboxMock, CryptoSettings cryptoProvider, OwnEndpoint receiver, bool expectMessage = true)
        {
            Requires.NotNull(cloudBlobStorage, "cloudBlobStorage");
            Requires.NotNull(receiver, "receiver");

            var httpHandler = new Mocks.HttpMessageHandlerMock();

            cloudBlobStorage.AddHttpHandler(httpHandler);
            inboxMock.Register(httpHandler);

            var channel = new Channel
            {
                HttpClient = new HttpClient(httpHandler),
                HttpClientLongPoll = new HttpClient(httpHandler),
                CloudBlobStorage = cloudBlobStorage,
                CryptoServices = cryptoProvider,
                Endpoint = receiver,
                Logger = this.logger,
            };

            var progressMessage = new TaskCompletionSource<Payload>();
            var progress = new Progress<Channel.PayloadReceipt>(m => progressMessage.SetResult(m.Payload));

            var messages = await channel.ReceiveAsync(progress: progress);
            if (expectMessage)
            {
                Assert.Equal(1, messages.Count);
                await progressMessage.Task;
                Assert.Same(progressMessage.Task.Result, messages.Single().Payload);
            }
            else
            {
                Assert.Equal(0, messages.Count);
            }

            return messages;
        }
Beispiel #28
0
        public void FileSystemCreateTest()
        {
            ConfigurationTest.Initialize();
            Random r = new Random(1234);

            using (var io = ConfigurationTest.CreateMemoryIO()) {
                FileSystem fs = FileSystem.Create(io);
                fs.Flush();

                ClusterState[] clusterStateArray = new ClusterState[Configuration.Geometry.DataClustersPerTrack * Configuration.Geometry.TrackCount];
                for (int i = 0; i < clusterStateArray.Length; i++)
                {
                    if ((fs.GetClusterState(i) & ClusterState.System) == 0)
                    {
                        ClusterState c = (ClusterState)r.Next(16);
                        clusterStateArray[i] = c;
                        fs.SetClusterState(i, c);
                    }
                    else
                    {
                        clusterStateArray[i] = fs.GetClusterState(i);
                    }
                }

                int[] nextClusterArray = new int[Configuration.Geometry.DataClustersPerTrack * Configuration.Geometry.TrackCount];
                for (int i = 0; i < nextClusterArray.Length; i++)
                {
                    if ((fs.GetClusterState(i) & ClusterState.System) == 0)
                    {
                        int c = r.Next();
                        nextClusterArray[i] = c;
                        fs.SetNextClusterAddress(i, c);
                    }
                    else
                    {
                        nextClusterArray[i] = fs.GetNextClusterAddress(i);
                    }
                }

                int[] bytesUsedArray = new int[Configuration.Geometry.DataClustersPerTrack * Configuration.Geometry.TrackCount];
                for (int i = 0; i < bytesUsedArray.Length; i++)
                {
                    if ((fs.GetClusterState(i) & ClusterState.System) == 0)
                    {
                        int c = r.Next();
                        bytesUsedArray[i] = c;
                        fs.SetBytesUsed(i, c);
                    }
                    else
                    {
                        bytesUsedArray[i] = fs.GetBytesUsed(i);
                    }
                }

                DateTime[] verifyTimeArray = new DateTime[Configuration.Geometry.ClustersPerTrack * Configuration.Geometry.TrackCount];
                for (int i = 0; i < verifyTimeArray.Length; i++)
                {
                    if (i >= Configuration.Geometry.DataClustersPerTrack * Configuration.Geometry.TrackCount ||
                        (fs.GetClusterState(i) & ClusterState.System) == 0)
                    {
                        DateTime c = new DateTime(r.Next());
                        verifyTimeArray[i] = c;
                        fs.SetVerifyTime(i, c);
                    }
                    else
                    {
                        verifyTimeArray[i] = fs.GetVerifyTime(i);
                    }
                }

                fs.Dispose();

                string         volumeName     = Configuration.VolumeName;
                Geometry       geometry       = Configuration.Geometry;
                CryptoSettings cryptoSettings = Configuration.CryptoSettings;
                Options        options        = Configuration.Options;
                Guid           guid           = Configuration.FileSystemID;
                Configuration.Reset();

                Configuration.CryptoSettings = cryptoSettings;
                Configuration.Options        = options;

                fs = FileSystem.Mount(io);

                Assert.AreEqual(volumeName, Configuration.VolumeName);
                Assert.AreEqual(geometry, Configuration.Geometry);
                Assert.AreEqual(guid, Configuration.FileSystemID);

                for (int i = 0; i < clusterStateArray.Length; i++)
                {
                    Assert.AreEqual(clusterStateArray[i], fs.GetClusterState(i));
                }

                for (int i = 0; i < nextClusterArray.Length; i++)
                {
                    Assert.AreEqual(nextClusterArray[i], fs.GetNextClusterAddress(i));
                }

                for (int i = 0; i < bytesUsedArray.Length; i++)
                {
                    Assert.AreEqual(bytesUsedArray[i], fs.GetBytesUsed(i));
                }

                for (int i = 0; i < verifyTimeArray.Length; i++)
                {
                    Assert.AreEqual(verifyTimeArray[i], fs.GetVerifyTime(i));
                }

                fs.Dispose();
            }
        }
Beispiel #29
0
 public ChannelTests(ITestOutputHelper logger)
 {
     this.logger = new Mocks.LoggerMock(logger);
     this.desktopCryptoProvider = TestUtilities.CreateAuthenticCryptoProvider();
 }
Beispiel #30
0
 public ChannelTests(ITestOutputHelper logger)
 {
     this.logger = new Mocks.LoggerMock(logger);
     this.desktopCryptoProvider = TestUtilities.CreateAuthenticCryptoProvider();
 }
Beispiel #31
0
        public void FileSystemPopulate()
        {
            ConfigurationTest.Initialize();
            Random r = new Random(1234);

            using (var io = ConfigurationTest.CreateMemoryIO()) {
                FileSystem fs = FileSystem.Create(io);
                fs.Flush();

                SortedList <int, DirInfo>  dirs  = new SortedList <int, DirInfo>();
                SortedList <int, FileInfo> files = new SortedList <int, FileInfo>();

                Directory d = fs.RootDirectory;
                dirs.Add(fs.RootDirectory.ID, new DirInfo(d));

                for (int i = 0; i < 1000; i++)
                {
                    var parent = dirs.Values[r.Next(dirs.Count)];
                    d = fs.CreateDirectory(parent.Directory, $"dir{nextID}");
                    nextID++;

                    DirInfo info = new DirInfo(d);
                    dirs.Add(d.ID, info);
                    dirs[d.ParentID].Subdirs.Add(d.ID);

                    FileSystemAccessRule accessRule = new FileSystemAccessRule(
                        WindowsIdentity.GetCurrent().User, FileSystemRights.FullControl, InheritanceFlags.None,
                        PropagationFlags.None, AccessControlType.Allow);
                    fs.AddAccessRule(d, accessRule);
                    info.AccessRules.Add(accessRule);

                    FileSystemAuditRule auditRule = new FileSystemAuditRule(
                        WindowsIdentity.GetCurrent().User, FileSystemRights.FullControl, InheritanceFlags.None,
                        PropagationFlags.None, AuditFlags.Success);
                    fs.AddAuditRule(d, auditRule);
                    info.AuditRules.Add(auditRule);
                }

                for (int i = 0; i < 1000; i++)
                {
                    var  parent = dirs.Values[r.Next(dirs.Count)];
                    File f      = fs.CreateFile(parent.Directory, $"file{nextID}");
                    nextID++;

                    FileInfo info = new FileInfo(f);
                    files.Add(f.ID, info);
                    dirs[f.ParentID].Files.Add(f.ID);

                    FileSystemAccessRule accessRule = new FileSystemAccessRule(
                        WindowsIdentity.GetCurrent().User, FileSystemRights.FullControl, InheritanceFlags.None,
                        PropagationFlags.None, AccessControlType.Allow);
                    fs.AddAccessRule(f, accessRule);
                    info.AccessRules.Add(accessRule);

                    FileSystemAuditRule auditRule = new FileSystemAuditRule(
                        WindowsIdentity.GetCurrent().User, FileSystemRights.FullControl, InheritanceFlags.None,
                        PropagationFlags.None, AuditFlags.Success);
                    fs.AddAuditRule(f, auditRule);
                    info.AuditRules.Add(auditRule);
                }

                checkDirectories(fs, fs.RootDirectory, dirs, files);
                fs.Dispose();

                CryptoSettings cryptoSettings = Configuration.CryptoSettings;
                Options        options        = Configuration.Options;
                Configuration.Reset();
                Configuration.CryptoSettings = cryptoSettings;
                Configuration.Options        = options;

                fs = FileSystem.Mount(io);
                checkDirectories(fs, fs.RootDirectory, dirs, files);
            }
        }
        /// <summary>
        /// Parse crypto settings from INI file
        /// </summary>
        public static CryptoSettings ParseCryptoSettings(DirectoryReference InProjectDirectory, UnrealTargetPlatform InTargetPlatform)
        {
            CryptoSettings Settings = new CryptoSettings();

            ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, InProjectDirectory, InTargetPlatform);

            Ini.GetBool("PlatformCrypto", "PlatformRequiresDataCrypto", out Settings.bDataCryptoRequired);
            Ini.GetBool("PlatformCrypto", "PakSigningRequired", out Settings.PakSigningRequired);
            Ini.GetBool("PlatformCrypto", "PakEncryptionRequired", out Settings.PakEncryptionRequired);

            {
                // Start by parsing the legacy encryption.ini settings
                Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Encryption, InProjectDirectory, InTargetPlatform);
                Ini.GetBool("Core.Encryption", "SignPak", out Settings.bEnablePakSigning);

                string[] SigningKeyStrings = new string[3];
                Ini.GetString("Core.Encryption", "rsa.privateexp", out SigningKeyStrings[0]);
                Ini.GetString("Core.Encryption", "rsa.modulus", out SigningKeyStrings[1]);
                Ini.GetString("Core.Encryption", "rsa.publicexp", out SigningKeyStrings[2]);

                if (String.IsNullOrEmpty(SigningKeyStrings[0]) || String.IsNullOrEmpty(SigningKeyStrings[1]) || String.IsNullOrEmpty(SigningKeyStrings[2]))
                {
                    SigningKeyStrings = null;
                }
                else
                {
                    Settings.SigningKey = new SigningKeyPair();
                    Settings.SigningKey.PrivateKey.Exponent = ParseHexStringToByteArray(ProcessSigningKeyInputStrings(SigningKeyStrings[0]), 64);
                    Settings.SigningKey.PrivateKey.Modulus  = ParseHexStringToByteArray(ProcessSigningKeyInputStrings(SigningKeyStrings[1]), 64);
                    Settings.SigningKey.PublicKey.Exponent  = ParseHexStringToByteArray(ProcessSigningKeyInputStrings(SigningKeyStrings[2]), 64);
                    Settings.SigningKey.PublicKey.Modulus   = Settings.SigningKey.PrivateKey.Modulus;

                    if ((Settings.SigningKey.PrivateKey.Exponent.Length > 64) ||
                        (Settings.SigningKey.PrivateKey.Modulus.Length > 64) ||
                        (Settings.SigningKey.PublicKey.Exponent.Length > 64) ||
                        (Settings.SigningKey.PublicKey.Modulus.Length > 64))
                    {
                        throw new Exception(string.Format("[{0}] Signing keys parsed from encryption.ini are too long. They must be a maximum of 64 bytes long!", InProjectDirectory));
                    }
                }

                Ini.GetBool("Core.Encryption", "EncryptPak", out Settings.bEnablePakIndexEncryption);
                Settings.bEnablePakFullAssetEncryption = false;
                Settings.bEnablePakUAssetEncryption    = false;
                Settings.bEnablePakIniEncryption       = Settings.bEnablePakIndexEncryption;

                string EncryptionKeyString;
                Ini.GetString("Core.Encryption", "aes.key", out EncryptionKeyString);
                Settings.EncryptionKey = new EncryptionKey();

                if (EncryptionKeyString.Length > 0)
                {
                    if (EncryptionKeyString.Length < 32)
                    {
                        Log.WriteLine(LogEventType.Warning, "AES key parsed from encryption.ini is too short. It must be 32 bytes, so will be padded with 0s, giving sub-optimal security!");
                    }
                    else if (EncryptionKeyString.Length > 32)
                    {
                        Log.WriteLine(LogEventType.Warning, "AES key parsed from encryption.ini is too long. It must be 32 bytes, so will be truncated!");
                    }

                    Settings.EncryptionKey.Key = ParseAnsiStringToByteArray(EncryptionKeyString, 32);
                }
            }

            Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Crypto, InProjectDirectory, InTargetPlatform);
            string SectionName = "/Script/CryptoKeys.CryptoKeysSettings";
            ConfigHierarchySection CryptoSection = Ini.FindSection(SectionName);

            // If we have new format crypto keys, read them in over the top of the legacy settings
            if (CryptoSection != null && CryptoSection.KeyNames.Count() > 0)
            {
                Ini.GetBool(SectionName, "bEnablePakSigning", out Settings.bEnablePakSigning);
                Ini.GetBool(SectionName, "bEncryptPakIniFiles", out Settings.bEnablePakIniEncryption);
                Ini.GetBool(SectionName, "bEncryptPakIndex", out Settings.bEnablePakIndexEncryption);
                Ini.GetBool(SectionName, "bEncryptUAssetFiles", out Settings.bEnablePakUAssetEncryption);
                Ini.GetBool(SectionName, "bEncryptAllAssetFiles", out Settings.bEnablePakFullAssetEncryption);

                // Parse encryption key
                string EncryptionKeyString;
                Ini.GetString(SectionName, "EncryptionKey", out EncryptionKeyString);
                if (!string.IsNullOrEmpty(EncryptionKeyString))
                {
                    Settings.EncryptionKey      = new EncryptionKey();
                    Settings.EncryptionKey.Key  = System.Convert.FromBase64String(EncryptionKeyString);
                    Settings.EncryptionKey.Guid = Guid.Empty.ToString();
                    Settings.EncryptionKey.Name = "Embedded";
                }

                // Parse secondary encryption keys
                List <EncryptionKey> SecondaryEncryptionKeys = new List <EncryptionKey>();
                List <string>        SecondaryEncryptionKeyStrings;

                if (Ini.GetArray(SectionName, "SecondaryEncryptionKeys", out SecondaryEncryptionKeyStrings))
                {
                    foreach (string KeySource in SecondaryEncryptionKeyStrings)
                    {
                        EncryptionKey NewKey = new EncryptionKey();
                        SecondaryEncryptionKeys.Add(NewKey);

                        Regex Search = new Regex("\\(Guid=(?\'Guid\'.*),Name=\\\"(?\'Name\'.*)\\\",Key=\\\"(?\'Key\'.*)\\\"\\)");
                        Match Match  = Search.Match(KeySource);
                        if (Match.Success)
                        {
                            foreach (string GroupName in Search.GetGroupNames())
                            {
                                string Value = Match.Groups[GroupName].Value;
                                if (GroupName == "Guid")
                                {
                                    NewKey.Guid = Value;
                                }
                                else if (GroupName == "Name")
                                {
                                    NewKey.Name = Value;
                                }
                                else if (GroupName == "Key")
                                {
                                    NewKey.Key = System.Convert.FromBase64String(Value);
                                }
                            }
                        }
                    }
                }

                Settings.SecondaryEncryptionKeys = SecondaryEncryptionKeys.ToArray();

                // Parse signing key
                string PrivateExponent, PublicExponent, Modulus;
                Ini.GetString(SectionName, "SigningPrivateExponent", out PrivateExponent);
                Ini.GetString(SectionName, "SigningModulus", out Modulus);
                Ini.GetString(SectionName, "SigningPublicExponent", out PublicExponent);

                if (!String.IsNullOrEmpty(PrivateExponent) && !String.IsNullOrEmpty(PublicExponent) && !String.IsNullOrEmpty(Modulus))
                {
                    Settings.SigningKey = new SigningKeyPair();
                    Settings.SigningKey.PublicKey.Exponent  = System.Convert.FromBase64String(PublicExponent);
                    Settings.SigningKey.PublicKey.Modulus   = System.Convert.FromBase64String(Modulus);
                    Settings.SigningKey.PrivateKey.Exponent = System.Convert.FromBase64String(PrivateExponent);
                    Settings.SigningKey.PrivateKey.Modulus  = Settings.SigningKey.PublicKey.Modulus;
                }
            }

            // Parse project dynamic keychain keys
            if (InProjectDirectory != null)
            {
                ConfigHierarchy GameIni = ConfigCache.ReadHierarchy(ConfigHierarchyType.Game, InProjectDirectory, InTargetPlatform);
                if (GameIni != null)
                {
                    string Filename;
                    if (GameIni.GetString("ContentEncryption", "ProjectKeyChain", out Filename))
                    {
                        FileReference ProjectKeyChainFile = FileReference.Combine(InProjectDirectory, "Content", Filename);
                        if (FileReference.Exists(ProjectKeyChainFile))
                        {
                            List <EncryptionKey> EncryptionKeys = new List <EncryptionKey>();

                            if (Settings.SecondaryEncryptionKeys != null)
                            {
                                EncryptionKeys.AddRange(Settings.SecondaryEncryptionKeys);
                            }

                            string[] Lines = FileReference.ReadAllLines(ProjectKeyChainFile);
                            foreach (string Line in Lines)
                            {
                                string[] KeyParts = Line.Split(':');
                                if (KeyParts.Length == 4)
                                {
                                    EncryptionKey NewKey = new EncryptionKey();

                                    NewKey.Name = KeyParts[0];
                                    NewKey.Guid = KeyParts[2];
                                    NewKey.Key  = System.Convert.FromBase64String(KeyParts[3]);

                                    EncryptionKey ExistingKey = EncryptionKeys.Find((EncryptionKey OtherKey) => { return(OtherKey.Guid == NewKey.Guid); });
                                    if (ExistingKey != null && !CompareKey(ExistingKey.Key, NewKey.Key))
                                    {
                                        throw new Exception("Found multiple encryption keys with the same guid but different AES keys while merging secondary keys from the project key-chain!");
                                    }

                                    EncryptionKeys.Add(NewKey);
                                }
                            }

                            Settings.SecondaryEncryptionKeys = EncryptionKeys.ToArray();
                        }
                    }
                }
            }

            if (!Settings.bDataCryptoRequired)
            {
                CryptoSettings NewSettings = new CryptoSettings();
                NewSettings.SecondaryEncryptionKeys = Settings.SecondaryEncryptionKeys;
                Settings = NewSettings;
            }
            else
            {
                if (!Settings.PakSigningRequired)
                {
                    Settings.bEnablePakSigning = false;
                    Settings.SigningKey        = null;
                }

                if (!Settings.PakEncryptionRequired)
                {
                    Settings.bEnablePakFullAssetEncryption = false;
                    Settings.bEnablePakIndexEncryption     = false;
                    Settings.bEnablePakIniEncryption       = false;
                    Settings.EncryptionKey = null;
                    Settings.SigningKey    = null;
                }
            }

            // Check if we have a valid signing key that is of the old short form
            if (Settings.SigningKey != null && Settings.SigningKey.IsValid() && Settings.SigningKey.IsUnsecureLegacyKey())
            {
                Log.TraceWarningOnce("Project signing keys found in '{0}' are of the old insecure short format. Please regenerate them using the project crypto settings panel in the editor!", InProjectDirectory);
            }

            // Validate the settings we have read
            if (Settings.bDataCryptoRequired && Settings.bEnablePakSigning && (Settings.SigningKey == null || !Settings.SigningKey.IsValid()))
            {
                Log.TraceWarningOnce("Pak signing is enabled, but no valid signing keys were found. Please generate a key in the editor project crypto settings. Signing will be disabled");
                Settings.bEnablePakSigning = false;
            }

            if (Settings.bDataCryptoRequired && Settings.IsAnyEncryptionEnabled() && (Settings.EncryptionKey == null || !Settings.EncryptionKey.IsValid()))
            {
                Log.TraceWarningOnce("Pak encryption is enabled, but no valid encryption key was found. Please generate a key in the editor project crypto settings. Encryption will be disabled");
                Settings.bEnablePakUAssetEncryption    = false;
                Settings.bEnablePakFullAssetEncryption = false;
                Settings.bEnablePakIndexEncryption     = false;
                Settings.bEnablePakIniEncryption       = false;
            }

            return(Settings);
        }
Beispiel #33
0
        private async Task <IReadOnlyCollection <Channel.PayloadReceipt> > ReceiveMessageAsync(Mocks.CloudBlobStorageProviderMock cloudBlobStorage, Mocks.InboxHttpHandlerMock inboxMock, CryptoSettings cryptoProvider, OwnEndpoint receiver, bool expectMessage = true)
        {
            Requires.NotNull(cloudBlobStorage, "cloudBlobStorage");
            Requires.NotNull(receiver, "receiver");

            var httpHandler = new Mocks.HttpMessageHandlerMock();

            cloudBlobStorage.AddHttpHandler(httpHandler);
            inboxMock.Register(httpHandler);

            var channel = new Channel
            {
                HttpClient         = new HttpClient(httpHandler),
                HttpClientLongPoll = new HttpClient(httpHandler),
                CloudBlobStorage   = cloudBlobStorage,
                CryptoServices     = cryptoProvider,
                Endpoint           = receiver,
                Logger             = this.logger,
            };

            var progressMessage = new TaskCompletionSource <Payload>();
            var progress        = new Progress <Channel.PayloadReceipt>(m => progressMessage.SetResult(m.Payload));

            var messages = await channel.ReceiveAsync(progress : progress);

            if (expectMessage)
            {
                Assert.Equal(1, messages.Count);
                await progressMessage.Task;
                Assert.Same(progressMessage.Task.Result, messages.Single().Payload);
            }
            else
            {
                Assert.Equal(0, messages.Count);
            }

            return(messages);
        }