Exemplo n.º 1
0
        public void SrpParametersUsePadding()
        {
            var value      = SrpInteger.FromHex("1234");
            var parameters = new SrpParameters(paddedLength: 10);

            Assert.AreEqual("0000001234", parameters.Pad(value).ToHex());
        }
Exemplo n.º 2
0
        private AuthResponse AuthStep1(AuthRequest authRequest)
        {
            // first step never fails: User -> Host: I, A = g^a (identifies self, a = random number)
            var userName = authRequest.GetUserName();
            var clientEphemeralPublic = authRequest.GetClientPublicEphemeral();
            var account = AuthRepository.FindByName(userName);

            if (account != null)
            {
                // save the data for the second authentication step
                var salt            = account.Salt;
                var verifier        = account.Verifier;
                var serverEphemeral = SrpServer.GenerateEphemeral(verifier);
                PendingAuthentications[authRequest.GetLoginSession()] = new Step1Data
                {
                    Account = account,
                    ClientEphemeralPublic = clientEphemeralPublic,
                    ServerEphemeral       = serverEphemeral,
                };

                // Host -> User: s, B = kv + g^b (sends salt, b = random number)
                return(ResponseStep1(salt, serverEphemeral.Public, authRequest.GetLoginSession()));
            }

            var fakeSalt      = SrpParameters.Hash(userName + UnknownUserSalt).ToHex();
            var fakeEphemeral = SrpServer.GenerateEphemeral(fakeSalt);

            return(ResponseStep1(fakeSalt, fakeEphemeral.Public, authRequest.GetLoginSession()));
        }
Exemplo n.º 3
0
        public void SrpParametersCanOverridePaddedLength()
        {
            var parameters = SrpParameters.Create <SHA1>(SrpConstants.SafePrime1024, SrpConstants.Generator1024, 1000);

            Assert.AreEqual(1000, parameters.PaddedLength);
            Assert.IsNotEmpty(parameters.ToString());
        }
Exemplo n.º 4
0
        private AuthResponseMessage AuthStep1(AuthRequestMessage authRequest)
        {
            // first step never fails: User -> Host: I, A = g^a (identifies self, a = random number)
            var userName = (string)authRequest.Credentials[SrpProtocolConstants.SRP_USERNAME];
            var clientEphemeralPublic = (string)authRequest.Credentials[SrpProtocolConstants.SRP_CLIENT_PUBLIC_EPHEMERAL];
            var account = AuthRepository.FindByName(userName);

            if (account != null)
            {
                // save the data for the second authentication step
                var salt            = account.Salt;
                var verifier        = account.Verifier;
                var serverEphemeral = SrpServer.GenerateEphemeral(verifier);
                PendingAuthentications[authRequest.SessionID] = new Step1Data
                {
                    Account = account,
                    ClientEphemeralPublic = clientEphemeralPublic,
                    ServerEphemeral       = serverEphemeral
                };

                // Host -> User: s, B = kv + g^b (sends salt, b = random number)
                return(ResponseStep1(salt, serverEphemeral.Public));
            }

            // generate fake salt and B values so that attacker cannot tell whether the given user exists or not
            var fakeSalt      = SrpParameters.Hash(userName + UnknownUserSalt).ToHex();
            var fakeEphemeral = SrpServer.GenerateEphemeral(fakeSalt);

            return(ResponseStep1(fakeSalt, fakeEphemeral.Public));
        }
Exemplo n.º 5
0
 public SrpAuthProvider(ISrpAccountRepository repository, SrpParameters parameters = null)
 {
     AuthRepository  = repository;
     SrpParameters   = parameters ?? new SrpParameters();
     SrpServer       = new SrpServer(SrpParameters);
     UnknownUserSalt = new SrpClient(parameters).GenerateSalt();
 }
Exemplo n.º 6
0
        public SrpTests()
        {
            var customParams = SrpParameters.Create3072 <SHA512>();

            _saltInt   = SrpInteger.FromByteArray(SrpSalt);
            _srpClient = new SrpClient(customParams);
        }
Exemplo n.º 7
0
        public void SrpParametersCanUseCustomHashAlgorithm()
        {
            var parameters = new SrpParameters(MD5.Create);

            Assert.NotNull(parameters.Prime);
            Assert.NotNull(parameters.Generator);
            Assert.AreEqual(16, parameters.HashSizeBytes);
            Assert.AreEqual(512, parameters.PaddedLength);
        }
Exemplo n.º 8
0
        public void SrpParameterDefaultsAreReasonable()
        {
            var parameters = new SrpParameters();

            Assert.NotNull(parameters.Prime);
            Assert.NotNull(parameters.Generator);
            Assert.AreEqual(32, parameters.HashSizeBytes);
            Assert.AreEqual(512, parameters.PaddedLength);
        }
        public void SrpIntegerModPowRegressionTest()
        {
            var p = new SrpParameters();
            var g = p.Generator;
            var N = p.Prime;

            var a = SrpInteger.FromHex("64e1124e73967bb4806cf5e3f151c574d0012147255e10fca02e9b4bafc8f4ba");
            var A = g.ModPow(a, N);

            Assert.AreEqual("07be00c7e6aa8198eddc42cc2f251901f3bc05795fefd5f40f90f0a6bfe66743954ef18ece62d229095a704197be18c0d1ca3a280381c8a53b42173df36867c29c564e8c974cf4ff4718547d27bd9c08eb9a909fb984e8e23a109eaf4f57a337c9cbe1609e35b9fddbc9f847825b1c37167cb3f10b3b284a7370323818571e6369e91b4ac6f6eedcdbc1c7d8d57b2020d43be7fec3df14a120c76d27ebabc8d93cdc555362a4c7c08a1052e67647e9f3f879846389672e7a5d6e1ff93940d4196bef451e8d6a3b410a5062ac29cee3783e9a5aeac9724ad1375a2189c3b5a8dbf671dfad990132d2e5b73eb5a2e3d2034b6b908210f5fe61272b2cf4d1e3a4aa", A.ToHex());
        }
Exemplo n.º 10
0
 private void SrpAuthenticationUsingStandardParameters <T>(string username, string password) where T : HashAlgorithm
 {
     // test all standard groups using the same hashing algorithm
     SrpAuthentication(username, password, SrpParameters.Create1024 <T>());
     SrpAuthentication(username, password, SrpParameters.Create1536 <T>());
     SrpAuthentication(username, password, SrpParameters.Create2048 <T>());
     SrpAuthentication(username, password, SrpParameters.Create3072 <T>());
     SrpAuthentication(username, password, SrpParameters.Create4096 <T>());
     SrpAuthentication(username, password, SrpParameters.Create6144 <T>());
     SrpAuthentication(username, password, SrpParameters.Create8192 <T>());
 }
        private void SrpImplementationGeneratesValidSaltAndVerifier <T>(string prime, string generator)
            where T : HashAlgorithm
        {
            // generate values
            var parameters = SrpParameters.Create <T>(prime, generator);
            var client     = new SrpClient(parameters);
            var salt       = client.GenerateSalt();
            var privateKey = client.DerivePrivateKey(salt, "root", "123");
            var verifier   = client.DeriveVerifier(privateKey);

            // verify generated values
            Assert.IsTrue(parameters.IsValidSalt(salt));
            Assert.IsTrue(parameters.IsValidVerifier(verifier));
        }
Exemplo n.º 12
0
            public SampleAccountRepository(SrpParameters parameters = null)
            {
                // create sample user account
                var srpClient  = new SrpClient(parameters);
                var salt       = srpClient.GenerateSalt();
                var privateKey = srpClient.DerivePrivateKey(salt, UserName, Password);
                var verifier   = srpClient.DeriveVerifier(privateKey);

                SampleAccount = new SrpAccount
                {
                    UserName = UserName,
                    Salt     = salt,
                    Verifier = verifier,
                };
            }
Exemplo n.º 13
0
        public void SrpShouldAuthenticateAUser()
        {
            // default parameters: RFC5054, 2048-bit group
            SrpAuthentication("*****@*****.**", "$uper$ecure");

            // sha512, 512-bit prime number
            var parameters = SrpParameters.Create <SHA512>("D4C7F8A2B32C11B8FBA9581EC4BA4F1B04215642EF7355E37C0FC0443EF756EA2C6B8EEB755A1C723027663CAA265EF785B8FF6A9B35227A52D86633DBDFCA43", "03");

            SrpAuthentication("*****@*****.**", "h4ck3r$", parameters);

            // md5, 1024-bit prime number from wikipedia (generated using "openssl dhparam -text 1024")
            parameters = SrpParameters.Create <SHA384>("00c037c37588b4329887e61c2da3324b1ba4b81a63f9748fed2d8a410c2fc21b1232f0d3bfa024276cfd88448197aae486a63bfca7b8bf7754dfb327c7201f6fd17fd7fd74158bd31ce772c9f5f8ab584548a99a759b5a2c0532162b7b6218e8f142bce2c30d7784689a483e095e701618437913a8c39c3dd0d4ca3c500b885fe3", "07");
            SrpAuthentication("bozo", "h4ck3r", parameters);

            // sha1 hash function, default N and g values for all standard groups
            SrpAuthenticationUsingStandardParameters <SHA1>("hello", "world");
        }
Exemplo n.º 14
0
        public async Task ParallelAuthenticationTest()
        {
            var username   = "******";
            var password   = "******";
            var parameters = new SrpParameters();
            var server     = new SrpServer(parameters);

            // spawn multiple parallel threads reusing the same SrpParameters instance
            var tasks = Enumerable.Range(0, 100).Select(i => Task.Run(() =>
            {
                var client = new SrpClient(parameters);

                // sign up
                var salt       = client.GenerateSalt();
                var privateKey = client.DerivePrivateKey(salt, username, password);
                var verifier   = client.DeriveVerifier(privateKey);

                // authenticate
                var clientEphemeral = client.GenerateEphemeral();
                var serverEphemeral = server.GenerateEphemeral(verifier);
                var clientSession   = client.DeriveSession(clientEphemeral.Secret, serverEphemeral.Public, salt, username, privateKey);

                var serverSession = server.DeriveSession(serverEphemeral.Secret, clientEphemeral.Public, salt, username, verifier, clientSession.Proof);
                client.VerifySession(clientEphemeral.Public, clientSession, serverSession.Proof);

                // make sure both the client and the server have the same session key
                Assert.AreEqual(clientSession.Key, serverSession.Key);

                // verify padded length of all parameters
                Assert.AreEqual(verifier.Length, parameters.PaddedLength);
                Assert.AreEqual(clientEphemeral.Public.Length, parameters.PaddedLength);
                Assert.AreEqual(clientEphemeral.Secret.Length, parameters.HashSizeBytes * 2);
                Assert.AreEqual(serverEphemeral.Public.Length, parameters.PaddedLength);
                Assert.AreEqual(serverEphemeral.Secret.Length, parameters.HashSizeBytes * 2);
                Assert.AreEqual(serverSession.Key.Length, parameters.HashSizeBytes * 2);
                Assert.AreEqual(clientSession.Key.Length, parameters.HashSizeBytes * 2);
                Assert.AreEqual(serverSession.Proof.Length, parameters.HashSizeBytes * 2);
                Assert.AreEqual(clientSession.Proof.Length, parameters.HashSizeBytes * 2);
            }));

            await Task.WhenAll(tasks);
        }
Exemplo n.º 15
0
        public void SrpServerDeriveSessionRegressionTest2()
        {
            // regression test:
            var parameters      = new SrpParameters();
            var clientEphemeral = new SrpEphemeral
            {
                Secret = "64e1124e73967bb4806cf5e3f151c574d0012147255e10fca02e9b4bafc8f4ba",
                Public = "07be00c7e6aa8198eddc42cc2f251901f3bc05795fefd5f40f90f0a6bfe66743954ef18ece62d229095a704197be18c0d1ca3a280381c8a53b42173df36867c29c564e8c974cf4ff4718547d27bd9c08eb9a909fb984e8e23a109eaf4f57a337c9cbe1609e35b9fddbc9f847825b1c37167cb3f10b3b284a7370323818571e6369e91b4ac6f6eedcdbc1c7d8d57b2020d43be7fec3df14a120c76d27ebabc8d93cdc555362a4c7c08a1052e67647e9f3f879846389672e7a5d6e1ff93940d4196bef451e8d6a3b410a5062ac29cee3783e9a5aeac9724ad1375a2189c3b5a8dbf671dfad990132d2e5b73eb5a2e3d2034b6b908210f5fe61272b2cf4d1e3a4aa",
            };

            var serverEphemeral = new SrpEphemeral
            {
                Secret = "54f5f01dc134a3decef47e5e74feb20ce60716965c1908aa422ec701e5c2ce23",
                Public = "47b1e293dff41447e74d33b6a13cfd3dc77e17580a6d724c633d106827dcba9578d222ea6931dfb37ba282998df04dae849eafc57e4bdbf8478f0fd312b4393af8d6512f6013ab4199b831673ce99f14240ef3202803bb4ced05cb046c42a108b2342fdd3e30f8ba7b8f154243b6873a30c467d368888a5a95ed7abaad10ba0bd093717c1479e46e8e15b20809bc7e2f3bc316d09c0b6a3289852ac4d441be50d3ce1ec76ded2f44c643e8fbfa762a62f3311e3425c7f6730d7b35f9037dc07d6165968ece3b4885b5d5cb264a50595cf989622b2fe156a0d98101e5f14f808a3595da761885188f50230fcddc4dd34ec38de5f64a44fdcd1f535f5f83f900d7",
            };

            var salt               = "31c3af4879262b1ee85295480b14800672cbb59870e7ae1980a07ee56eaa25fc";
            var username           = "******";
            var privateKey         = "d3f37035827919d8803d246d0a81dcf0118e84f85e45c4c06f2c362262422118";
            var verifier           = "1786105be4cde9793d4896047cd178260ded3a0623491d18b0e942469107012f0a8d67d40c41d5b4863233ee5cd6b765bf3bffd56d0b429445be5af163303d42ae5ced9ff29e3cd275eeba482d3dad3bac3d6f2cf2113c6be5c50dfd2e3a2a9a1bbf2d829d4a5538c36e94197dfce12e990d030a124ee77ebb843c416701d85f0e00f1001a93051aef27d6e7c7120d00f08c52e4b1ea99b050c6d4080d59c0080af439f9291d07e384f13d121c1374d71f0d168e6fbfab9408974bf652844c7ac07b77b5dbc3cb53cb89de9d7fdcaf33f21e1e73c16bdc487732b2773aa34da0777b1d057a8aa3fc3a0679661956fa2ee01f69bcc1535d381feaaa973e7d802c";
            var clientSessionProof = "ddc8c78aafe9c471086b3d20a4e4eb2401de2fcaa48081fea5357114dc508a23";
            var serverSessionKey   = "bd0079ddefc205d65da9241ba416c44a131440c723e20de6e3bdb5bd662c9de0";
            var serverSessionProof = "01a62474121b11347f84d422088b469b949d9a376f89b87b8080f17931846ef5";

            var clientSession = new SrpClient(parameters).DeriveSession(clientEphemeral.Secret, serverEphemeral.Public, salt, username, privateKey);

            Assert.IsNotNull(clientSession);
            Assert.AreEqual(serverSessionKey, clientSession.Key);
            Assert.AreEqual(clientSessionProof, clientSession.Proof);

            var serverSession = new SrpServer(parameters).DeriveSession(serverEphemeral.Secret, clientEphemeral.Public, salt, username, verifier, clientSessionProof);

            Assert.IsNotNull(serverSession);
            Assert.AreEqual(serverSessionKey, serverSession.Key);
            Assert.AreEqual(serverSessionProof, serverSession.Proof);
        }
Exemplo n.º 16
0
        // THIS GITHUB ISSUE THREAD IS LITERALLY GOLD: https://github.com/horrorho/InflatableDonkey/issues/87 GIVE THEM LOVE, ESPECIALLY TO RobLinux
        public static async Task Main(string[] args)
        {
            // Apple ID for testing, use temp-mail.org to login.
            // Security Questions: Mailart, Montcuq
            var email    = "*****@*****.**";
            var password = "******";

            Cookies.Add(new Cookie("dslang", "US-EN", "/", "gsa.apple.com"));
            ServicePointManager
            .ServerCertificateValidationCallback =
                (sender, cert, chain, sslPolicyErrors) => true;

            // Initiate SRP Client, and generate ephemeral keys
            var srpClient = new SrpClient(SrpParameters.Create2048 <SHA256>());

            var eph = srpClient.GenerateEphemeral();

            // Split keys into lines
            var splitPublic = "\t\t" + string.Join("\r\n\t\t", SplitInParts(ToB64(eph.Public), 60)) + "\r\n";

            var post1 = string.Format(string.Concat(
                                          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n",
                                          "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\r\n",
                                          "<plist version=\"1.0\">\r\n",
                                          "<dict>\r\n",
                                          "\t<key>Header</key>\r\n",
                                          "\t<dict>\r\n",
                                          "\t\t<key>Version</key>\r\n",
                                          "\t\t<string>1.0.1</string>\r\n",
                                          "\t</dict>\r\n",
                                          "\t<key>Request</key>\r\n",
                                          "\t<dict>\r\n",
                                          // A field of SRP
                                          "\t\t<key>A2k</key>\r\n",
                                          "\t\t<data>\r\n",
                                          "{1}",
                                          "\t\t</data>\r\n",
                                          "\t\t<key>cpd</key>\r\n",
                                          "\t\t<dict>\r\n",
                                          "\t\t\t<key>X-Apple-I-Client-Time</key>\r\n",
                                          "\t\t\t<string>2019-11-30T22:10:15Z</string>\r\n",
                                          "\t\t\t<key>X-Apple-I-Locale</key>\r\n",
                                          "\t\t\t<string>en_FR</string>\r\n",
                                          "\t\t\t<key>X-Apple-I-SRL-NO</key>\r\n",
                                          "\t\t\t<string>DNPS88X1HG82</string>\r\n",
                                          // Fields of Anisette data
                                          "\t\t\t<key>X-Apple-I-MD</key>\r\n",
                                          "\t\t\t<string>AAAABQAAABCZg6d+upDLWkNW98xGuiOXAAAAAw==</string>\r\n",
                                          "\t\t\t<key>X-Apple-I-MD-M</key>\r\n",
                                          "\t\t\t<string>faFsm6glupJEkv10H8HxT+cpTVQ/q8mWyPiJRkYfbXJDfIK+eL52Z7GyRCamzWYnvv1N/US6VaawwZG9</string>\r\n",
                                          "\t\t\t<key>X-Apple-I-MD-RINFO</key>\r\n",
                                          "\t\t\t<string>17106176</string>\r\n",
                                          "\t\t\t<key>X-Apple-I-TimeZone</key>\r\n",
                                          "\t\t\t<string>CET</string>\r\n",
                                          "\t\t\t<key>X-Apple-Locale</key>\r\n",
                                          "\t\t\t<string>en_FR</string>\r\n",
                                          "\t\t\t<key>bootstrap</key>\r\n",
                                          "\t\t\t<true/>\r\n",
                                          "\t\t\t<key>icscrec</key>\r\n",
                                          "\t\t\t<true/>\r\n",
                                          "\t\t\t<key>loc</key>\r\n",
                                          "\t\t\t<string>en_FR</string>\r\n",
                                          "\t\t\t<key>pbe</key>\r\n",
                                          "\t\t\t<false/>\r\n",
                                          "\t\t\t<key>prkgen</key>\r\n",
                                          "\t\t\t<true/>\r\n",
                                          "\t\t\t<key>svct</key>\r\n",
                                          "\t\t\t<string>iCloud</string>\r\n",
                                          "\t\t</dict>\r\n",
                                          "\t\t<key>o</key>\r\n",
                                          "\t\t<string>init</string>\r\n",
                                          "\t\t<key>ps</key>\r\n",
                                          "\t\t<array>\r\n",
                                          "\t\t\t<string>s2k</string>\r\n",
                                          "\t\t\t<string>s2k_fo</string>\r\n",
                                          "\t\t</array>\r\n",
                                          "\t\t<key>u</key>\r\n",
                                          "\t\t<string>{0}</string>\r\n",
                                          "\t</dict>\r\n",
                                          "</dict>\r\n",
                                          "</plist>\r\n"
                                          ), email,
                                      splitPublic);

            Console.WriteLine(post1);
            var res1 = PList.ParsePList(new PList(await PostRequest("https://gsa.apple.com/grandslam/GsService2", post1)));

            Console.WriteLine(res1);

            // c is a string in the form x-xxx-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:AAA with x lower case hexadecimal numbers and A letters in upper case
            var c = res1["Response"]["c"].ToString();

            // Convert in hexa for SRP.NET
            var b    = new BigInteger(Convert.FromBase64String(res1["Response"]["B"].ToString())).ToString("X");
            var salt = Convert.FromBase64String(res1["Response"]["s"].ToString());

            // Generate keys for Apple SRP protocol
            var pk            = srpClient.DerivePrivateKey(salt, int.Parse(res1["Response"]["i"].ToString()), password);
            var clientSession = srpClient.DeriveSession(eph.Secret,
                                                        b, salt, email, pk);

            // POST request to Apple, but it fails 'Your Apple ID or password is incorrect'
            var post2 = string.Format(string.Concat(
                                          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n",
                                          "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\r\n",
                                          "<plist version=\"1.0\">\r\n",
                                          "<dict>\r\n",
                                          "\t<key>Header</key>\r\n",
                                          "\t<dict>\r\n",
                                          "\t\t<key>Version</key>\r\n",
                                          "\t\t<string>1.0.1</string>\r\n",
                                          "\t</dict>\r\n",
                                          "\t<key>Request</key>\r\n",
                                          "\t<dict>\r\n",
                                          // A field of SRP
                                          "\t\t<key>M1</key>\r\n",
                                          "\t\t<data>\r\n",
                                          "\t\t{2}\r\n",
                                          "\t\t</data>\r\n",
                                          // A field of Apple's GrandSlam
                                          "\t\t<key>c</key>\r\n",
                                          "\t\t<string>{1}</string>\r\n",
                                          "\t\t<key>cpd</key>\r\n",
                                          "\t\t<dict>\r\n",
                                          "\t\t\t<key>X-Apple-I-Client-Time</key>\r\n",
                                          "\t\t\t<string>2019-11-30T22:10:15Z</string>\r\n",
                                          "\t\t\t<key>X-Apple-I-Locale</key>\r\n",
                                          "\t\t\t<string>en_FR</string>\r\n",
                                          "\t\t\t<key>X-Apple-I-SRL-NO</key>\r\n",
                                          "\t\t\t<string>DNPS88X1HG82</string>\r\n",
                                          // Fields of Anisette data
                                          "\t\t\t<key>X-Apple-I-MD</key>\r\n",
                                          "\t\t\t<string>AAAABQAAABCZg6d+upDLWkNW98xGuiOXAAAAAw==</string>\r\n",
                                          "\t\t\t<key>X-Apple-I-MD-M</key>\r\n",
                                          "\t\t\t<string>faFsm6glupJEkv10H8HxT+cpTVQ/q8mWyPiJRkYfbXJDfIK+eL52Z7GyRCamzWYnvv1N/US6VaawwZG9</string>\r\n",
                                          "\t\t\t<key>X-Apple-I-MD-RINFO</key>\r\n",
                                          "\t\t\t<string>17106176</string>\r\n",
                                          "\t\t\t<key>X-Apple-I-TimeZone</key>\r\n",
                                          "\t\t\t<string>CET</string>\r\n",
                                          "\t\t\t<key>X-Apple-Locale</key>\r\n",
                                          "\t\t\t<string>en_FR</string>\r\n",
                                          "\t\t\t<key>bootstrap</key>\r\n",
                                          "\t\t\t<true/>\r\n",
                                          "\t\t\t<key>icscrec</key>\r\n",
                                          "\t\t\t<true/>\r\n",
                                          "\t\t\t<key>loc</key>\r\n",
                                          "\t\t\t<string>en_FR</string>\r\n",
                                          "\t\t\t<key>pbe</key>\r\n",
                                          "\t\t\t<false/>\r\n",
                                          "\t\t\t<key>prkgen</key>\r\n",
                                          "\t\t\t<true/>\r\n",
                                          "\t\t\t<key>svct</key>\r\n",
                                          "\t\t\t<string>iCloud</string>\r\n",
                                          "\t\t</dict>\r\n",
                                          "\t\t<key>o</key>\r\n",
                                          "\t\t<string>complete</string>\r\n",
                                          "\t\t<key>u</key>\r\n",
                                          "\t\t<string>{0}</string>\r\n",
                                          "\t</dict>\r\n",
                                          "</dict>\r\n",
                                          "</plist>\r\n"
                                          ), email,
                                      c,
                                      Convert.ToBase64String(clientSession.Proof));

            Console.WriteLine(post2);
            var res2 = PList.ParsePList(new PList(await PostRequest("https://gsa.apple.com/grandslam/GsService2", post2)));

            Console.WriteLine(res2);

            Console.ReadKey();
        }
Exemplo n.º 17
0
 public SrpGenerator(SrpParameters parameters)
 {
     _srpClient = new SrpClient(parameters);
     _srpServer = new SrpServer(parameters);
 }
Exemplo n.º 18
0
        public PairSetupReturn Post(Tlv parts)
        {
            var customParams = SrpParameters.Create3072 <SHA512>();

            var state = parts.GetTypeAsInt(Constants.State);

            if (state == 1) //srp sign up
            {
                var rnd = new Random();
                _salt = new byte[16];
                rnd.NextBytes(_salt);

                _saltInt = SrpInteger.FromByteArray(_salt);

                var srp = new SrpClient(customParams);
                _privateKey = srp.DerivePrivateKey(_saltInt.ToHex(), Username, _code);
                _verifier   = srp.DeriveVerifier(_privateKey);

                _server          = new SrpServer(customParams);
                _serverEphemeral = _server.GenerateEphemeral(_verifier);

                var responseTlv = new Tlv();
                responseTlv.AddType(Constants.State, 2);
                responseTlv.AddType(Constants.PublicKey, StringToByteArray(_serverEphemeral.Public));
                responseTlv.AddType(Constants.Salt, _salt);

                return(new PairSetupReturn
                {
                    State = 1,
                    TlvData = responseTlv,
                    Ok = true
                });
            }

            if (state == 3) //srp authenticate
            {
                _logger.LogDebug("Pair Setup Step 3/6");
                _logger.LogDebug("SRP Verify Request");

                var pubKey = parts.GetType(Constants.PublicKey);
                var proof  = parts.GetType(Constants.Proof);

                var iOsPublicKey = SrpInteger.FromByteArray(pubKey);
                var iOsProof     = SrpInteger.FromByteArray(proof);


                var responseTlv = new Tlv();
                responseTlv.AddType(Constants.State, 4);
                var ok = true;
                try
                {
                    _serverSession = _server.DeriveSession(_serverEphemeral.Secret, iOsPublicKey.ToHex(), _saltInt.ToHex(), Username, _verifier,
                                                           iOsProof.ToHex());
                    _logger.LogInformation("Verification was successful. Generating Server Proof (M2)");

                    responseTlv.AddType(Constants.Proof, StringToByteArray(_serverSession.Proof));
                }
                catch (Exception)
                {
                    ok = false;
                    _logger.LogError("Verification failed as iOS provided code was incorrect");
                    responseTlv.AddType(Constants.Error, ErrorCodes.Authentication);
                }
                return(new PairSetupReturn
                {
                    State = 3,
                    Ok = ok,
                    TlvData = responseTlv
                });
            }

            if (state == 5)
            {
                _logger.LogDebug("Pair Setup Step 5/6");
                _logger.LogDebug("Exchange Response");

                try
                {
                    var iOsEncryptedData = parts.GetType(Constants.EncryptedData).AsSpan(); // A
                    var zeros            = new byte[] { 0, 0, 0, 0 };
                    var nonce            = new Nonce(zeros, Encoding.UTF8.GetBytes("PS-Msg05"));
                    var hdkf             = new HkdfSha512();
                    var hkdfEncKey       = hdkf.DeriveBytes(
                        SharedSecret.Import(SrpInteger.FromHex(_serverSession.Key).ToByteArray()),
                        Encoding.UTF8.GetBytes("Pair-Setup-Encrypt-Salt"),
                        Encoding.UTF8.GetBytes("Pair-Setup-Encrypt-Info"), 32);


                    var decrypt = AeadAlgorithm.ChaCha20Poly1305.Decrypt(
                        Key.Import(AeadAlgorithm.ChaCha20Poly1305, hkdfEncKey, KeyBlobFormat.RawSymmetricKey), nonce,
                        new byte[0], iOsEncryptedData, out var output);
                    var responseTlv = new Tlv();
                    responseTlv.AddType(Constants.State, 6);
                    if (!decrypt)
                    {
                        responseTlv.AddType(Constants.Error, ErrorCodes.Authentication);
                        return(new PairSetupReturn
                        {
                            State = 5,
                            TlvData = responseTlv,
                            Ok = false
                        });
                    }

                    var subData = TlvParser.Parse(output);

                    byte[] username = subData.GetType(Constants.Identifier);
                    byte[] ltpk     = subData.GetType(Constants.PublicKey);
                    byte[] proof    = subData.GetType(Constants.Signature);


                    var okm = hdkf.DeriveBytes(
                        SharedSecret.Import(SrpInteger.FromHex(_serverSession.Key).ToByteArray()),
                        Encoding.UTF8.GetBytes("Pair-Setup-Controller-Sign-Salt"),
                        Encoding.UTF8.GetBytes("Pair-Setup-Controller-Sign-Info"), 32);

                    var completeData = okm.Concat(username).Concat(ltpk).ToArray();


                    if (!SignatureAlgorithm.Ed25519.Verify(
                            PublicKey.Import(SignatureAlgorithm.Ed25519, ltpk, KeyBlobFormat.RawPublicKey), completeData,
                            proof))
                    {
                        var errorTlv = new Tlv();
                        errorTlv.AddType(Constants.Error, ErrorCodes.Authentication);
                        return(new PairSetupReturn
                        {
                            State = 5,
                            TlvData = errorTlv,
                            Ok = false
                        });
                    }

                    var accessory = hdkf.DeriveBytes(
                        SharedSecret.Import(SrpInteger.FromHex(_serverSession.Key).ToByteArray()),
                        Encoding.UTF8.GetBytes("Pair-Setup-Accessory-Sign-Salt"),
                        Encoding.UTF8.GetBytes("Pair-Setup-Accessory-Sign-Info"), 32);


                    var seed = new byte[32];
                    RandomNumberGenerator.Create().GetBytes(seed);
                    Chaos.NaCl.Ed25519.KeyPairFromSeed(out var accessoryLtpk, out var accessoryLtsk, seed);

                    var serverUsername = Encoding.UTF8.GetBytes(HapControllerServer.HapControllerId);
                    var material       = accessory.Concat(serverUsername).Concat(accessoryLtpk).ToArray();

                    var signature = Chaos.NaCl.Ed25519.Sign(material, accessoryLtsk);


                    var encoder = new Tlv();
                    encoder.AddType(Constants.Identifier, serverUsername);
                    encoder.AddType(Constants.PublicKey, accessoryLtpk);
                    encoder.AddType(Constants.Signature, signature);

                    var plaintext = TlvParser.Serialise(encoder);

                    var nonce6 = new Nonce(zeros, Encoding.UTF8.GetBytes("PS-Msg06"));

                    var encryptedOutput = AeadAlgorithm.ChaCha20Poly1305.Encrypt(
                        Key.Import(AeadAlgorithm.ChaCha20Poly1305, hkdfEncKey, KeyBlobFormat.RawSymmetricKey), nonce6,
                        new byte[0], plaintext);

                    responseTlv.AddType(Constants.EncryptedData, encryptedOutput);

                    return(new PairSetupReturn
                    {
                        State = 5,
                        TlvData = responseTlv,
                        Ok = true,
                        Ltsk = ByteArrayToString(accessoryLtsk),
                        Ltpk = ByteArrayToString(ltpk)
                    });
                }
                catch (Exception e)
                {
                    _logger.LogError(e, "Could not exchange request");
                    throw;
                }
            }

            return(null);
        }
Exemplo n.º 19
0
        public void HardcodedVersionOfRfc5054TestVector()
        {
            // https://www.ietf.org/rfc/rfc5054.txt
            var N  = SrpInteger.FromHex(@"EEAF0AB9 ADB38DD6 9C33F80A FA8FC5E8 60726187 75FF3C0B 9EA2314C
				9C256576 D674DF74 96EA81D3 383B4813 D692C6E0 E0D5D8E2 50B98BE4
				8E495C1D 6089DAD1 5DC7D7B4 6154D6B6 CE8EF4AD 69B15D49 82559B29
				7BCF1885 C529F566 660E57EC 68EDBC3C 05726CC0 2FD4CBF4 976EAA9A
				FD5138FE 8376435B 9FC61D2F C0EB06E3"                );
            var g  = SrpInteger.FromHex("02");
            var p  = SrpParameters.Create <SHA1>(N, g);
            var H  = p.Hash;
            var k  = p.Multiplier;
            var kx = SrpInteger.FromHex(@"7556AA04 5AEF2CDD 07ABAF0F 665C3E81 8913186F");

            Assert.AreEqual(kx, k);

            // prepare known parameters
            var I      = "alice";
            var P      = "password123";
            var s      = SrpInteger.FromHex(@"BEB25379 D1A8581E B5A72767 3A2441EE").ToHex();
            var client = new SrpClient(p);
            var server = new SrpServer(p);

            // validate the private key
            var x  = SrpInteger.FromHex(client.DerivePrivateKey(s, I, P));
            var xx = SrpInteger.FromHex(@"94B7555A ABE9127C C58CCF49 93DB6CF8 4D16C124");

            Assert.AreEqual(xx, x);

            // validate the verifier
            var v  = SrpInteger.FromHex(client.DeriveVerifier(x));
            var vx = SrpInteger.FromHex(@"
				7E273DE8 696FFC4F 4E337D05 B4B375BE B0DDE156 9E8FA00A 9886D812
				9BADA1F1 822223CA 1A605B53 0E379BA4 729FDC59 F105B478 7E5186F5
				C671085A 1447B52A 48CF1970 B4FB6F84 00BBF4CE BFBB1681 52E08AB5
				EA53D15C 1AFF87B2 B9DA6E04 E058AD51 CC72BFC9 033B564E 26480D78
				E955A5E2 9E7AB245 DB2BE315 E2099AFB"                );

            Assert.AreEqual(vx, v);

            // client ephemeral
            var a  = SrpInteger.FromHex("60975527 035CF2AD 1989806F 0407210B C81EDC04 E2762A56 AFD529DD DA2D4393");
            var A  = client.ComputeA(a);
            var Ax = SrpInteger.FromHex(@"
				61D5E490 F6F1B795 47B0704C 436F523D D0E560F0 C64115BB 72557EC4
				4352E890 3211C046 92272D8B 2D1A5358 A2CF1B6E 0BFCF99F 921530EC
				8E393561 79EAE45E 42BA92AE ACED8251 71E1E8B9 AF6D9C03 E1327F44
				BE087EF0 6530E69F 66615261 EEF54073 CA11CF58 58F0EDFD FE15EFEA
				B349EF5D 76988A36 72FAC47B 0769447B"                );

            Assert.AreEqual(Ax, A);
            var clientEphemeral = new SrpEphemeral {
                Public = A, Secret = a
            };

            // server ephemeral
            var b  = SrpInteger.FromHex("E487CB59 D31AC550 471E81F0 0F6928E0 1DDA08E9 74A004F4 9E61F5D1 05284D20");
            var B  = server.ComputeB(v, b);
            var Bx = SrpInteger.FromHex(@"
				BD0C6151 2C692C0C B6D041FA 01BB152D 4916A1E7 7AF46AE1 05393011
				BAF38964 DC46A067 0DD125B9 5A981652 236F99D9 B681CBF8 7837EC99
				6C6DA044 53728610 D0C6DDB5 8B318885 D7D82C7F 8DEB75CE 7BD4FBAA
				37089E6F 9C6059F3 88838E7A 00030B33 1EB76840 910440B1 B27AAEAE
				EB4012B7 D7665238 A8E3FB00 4B117B58"                );

            Assert.AreEqual(Bx, B);
            var serverEphemeral = new SrpEphemeral {
                Public = B, Secret = a
            };

            // u
            var u  = client.ComputeU(A, B);
            var ux = SrpInteger.FromHex("CE38B959 3487DA98 554ED47D 70A7AE5F 462EF019");

            Assert.AreEqual(ux, u);

            // premaster secret — client version
            var S  = client.ComputeS(a, B, u, x);
            var Sx = SrpInteger.FromHex(@"
				B0DC82BA BCF30674 AE450C02 87745E79 90A3381F 63B387AA F271A10D
				233861E3 59B48220 F7C4693C 9AE12B0A 6F67809F 0876E2D0 13800D6C
				41BB59B6 D5979B5C 00A172B4 A2A5903A 0BDCAF8A 709585EB 2AFAFA8F
				3499B200 210DCC1F 10EB3394 3CD67FC8 8A2F39A4 BE5BEC4E C0A3212D
				C346D7E4 74B29EDE 8A469FFE CA686E5A"                );

            Assert.AreEqual(Sx, S);

            // premaster secret — server version
            S = server.ComputeS(A, b, u, v);
            Assert.AreEqual(Sx, S);

            // client session
            var clientSession = client.DeriveSession(a, B, s, I, x);

            Assert.AreEqual("017eefa1cefc5c2e626e21598987f31e0f1b11bb", clientSession.Key);
            Assert.AreEqual("3f3bc67169ea71302599cf1b0f5d408b7b65d347", clientSession.Proof);

            // server session
            var serverSession = server.DeriveSession(b, A, s, I, v, clientSession.Proof);

            Assert.AreEqual("017eefa1cefc5c2e626e21598987f31e0f1b11bb", serverSession.Key);
            Assert.AreEqual("9cab3c575a11de37d3ac1421a9f009236a48eb55", serverSession.Proof);

            // verify server session
            client.VerifySession(A, clientSession, serverSession.Proof);
        }
Exemplo n.º 20
0
        private void SrpAuthentication(string username, string password, SrpParameters parameters = null)
        {
            // use default parameters if not specified: sha256, 2048-bit prime number
            var client = new SrpClient(parameters);
            var server = new SrpServer(parameters);

            // sign up
            var salt       = client.GenerateSalt();
            var privateKey = client.DerivePrivateKey(salt, username, password);
            var verifier   = client.DeriveVerifier(privateKey);

            // authenticate
            var clientEphemeral = client.GenerateEphemeral();
            var serverEphemeral = server.GenerateEphemeral(verifier);
            var clientSession   = client.DeriveSession(clientEphemeral.Secret, serverEphemeral.Public, salt, username, privateKey);

            try
            {
                var serverSession = server.DeriveSession(serverEphemeral.Secret, clientEphemeral.Public, salt, username, verifier, clientSession.Proof);
                client.VerifySession(clientEphemeral.Public, clientSession, serverSession.Proof);

                // make sure both the client and the server have the same session key
                Assert.AreEqual(clientSession.Key, serverSession.Key);
            }
            catch
            {
                // generate the regression test code
                Console.WriteLine("// regression test:");
                Console.WriteLine($"var parameters = {parameters?.ToString() ?? "new SrpParameters()"};");
                Console.WriteLine($"var serverEphemeral = new SrpEphemeral");
                Console.WriteLine($"{{");
                Console.WriteLine($"	Secret = \"{serverEphemeral.Secret}\",");
                Console.WriteLine($"	Public = \"{serverEphemeral.Public}\",");
                Console.WriteLine($"}};");
                Console.WriteLine();
                Console.WriteLine($"var clientEphemeral = new SrpEphemeral");
                Console.WriteLine($"{{");
                Console.WriteLine($"	Secret = \"{clientEphemeral.Secret}\",");
                Console.WriteLine($"	Public = \"{clientEphemeral.Public}\",");
                Console.WriteLine($"}};");
                Console.WriteLine();
                Console.WriteLine($"var salt = \"{salt}\";");
                Console.WriteLine($"var username = \"{username}\";");
                Console.WriteLine($"var privateKey = \"{privateKey}\";");
                Console.WriteLine($"var verifier = \"{verifier}\";");
                Console.WriteLine($"var clientSessionProof = \"{clientSession.Proof}\";");
                Console.WriteLine($"var serverSessionKey = \"{clientSession.Key}\";");
                Console.WriteLine($"var serverSessionProof = \"????\";");
                Console.WriteLine();
                Console.WriteLine($"var clientSession = new SrpClient(parameters).DeriveSession(clientEphemeral.Secret, serverEphemeral.Public, salt, username, privateKey);");
                Console.WriteLine($"Assert.IsNotNull(clientSession);");
                Console.WriteLine($"Assert.AreEqual(serverSessionKey, clientSession.Key);");
                Console.WriteLine($"Assert.AreEqual(clientSessionProof, clientSession.Proof);");
                Console.WriteLine();
                Console.WriteLine($"var serverSession = new SrpServer(parameters).DeriveSession(serverEphemeral.Secret, clientEphemeral.Public, salt, username, verifier, clientSessionProof);");
                Console.WriteLine($"Assert.IsNotNull(serverSession);");
                Console.WriteLine($"Assert.AreEqual(serverSessionKey, serverSession.Key);");
                Console.WriteLine($"Assert.AreEqual(serverSessionProof, serverSession.Proof);");
                throw;
            }
        }
Exemplo n.º 21
0
 public SrpCredentials(string userName, string password, SrpParameters parameters = null)
 {
     UserName  = userName;
     Password  = password;
     SrpClient = new SrpClient(parameters);
 }