コード例 #1
0
 /// <summary>
 /// Creates a new <c>SQRLOptions</c> object and initializes it
 /// with the values stored in <paramref name="options"/>.
 /// </summary>
 /// <param name="options">The sqrl transaction options to be set.</param>
 public SQRLOptions(SQRLOpts options)
 {
     this.NOIPTEST = (options & SQRLOpts.NOIPTEST) != 0;
     this.SUK      = (options & SQRLOpts.SUK) != 0;
     this.SQRLONLY = (options & SQRLOpts.SQRLONLY) != 0;
     this.HARDLOCK = (options & SQRLOpts.HARDLOCK) != 0;
     this.CPS      = (options & SQRLOpts.CPS) != 0;
 }
コード例 #2
0
        static async Task Main(string[] args)
        {
            SQRL sqrl = SQRL.GetInstance(true);


            Console.WriteLine("Importing Identity");
            var progress = new Progress <KeyValuePair <int, string> >(percent =>
            {
                Console.WriteLine($"{percent.Value}: {percent.Key}%");
            });

            SQRLIdentity newId = SQRLIdentity.FromFile(Path.Combine(@"C:\Users\jose\Downloads\SQRL-Test-Identity-Resources\", @"Spec-Vectors-Identity.sqrl"));
            //SQRLIdentity newId = SQRLIdentity.FromFile(Path.Combine(Directory.GetCurrentDirectory(), @"980591756918003626376697.sqrl"));

            SQRLOpts optsFlags = (sqrl.cps != null && sqrl.cps.Running ? SQRLOpts.SUK | SQRLOpts.CPS : SQRLOpts.SUK);


            SQRLOptions opts = new SQRLOptions(optsFlags);
            bool        run  = true;


            var block1Keys = await SQRL.DecryptBlock1(newId, "Zingo-Bingo-Slingo-Dingo", progress);

            if (block1Keys.DecryptionSucceeded)
            {
                try
                {
                    do
                    {
                        Console.WriteLine("Enter SQRL URL:");
                        string url        = Console.ReadLine();
                        Uri    requestURI = new Uri(url);
                        string AltID      = "";


                        var siteKvp = SQRL.CreateSiteKey(requestURI, AltID, block1Keys.Imk);
                        Dictionary <byte[], PriorSiteKeysResult> priorSiteKeys = null;
                        if (newId.Block3 != null && newId.Block3.Edition > 0)
                        {
                            byte[]        decryptedBlock3 = SQRL.DecryptBlock3(block1Keys.Imk, newId, out bool allGood);
                            List <byte[]> oldIUKs         = new List <byte[]>();
                            if (allGood)
                            {
                                int skip = 0;
                                int ct   = 0;
                                while (skip < decryptedBlock3.Length)
                                {
                                    oldIUKs.Add(decryptedBlock3.Skip(skip).Take(32).ToArray());
                                    skip += 32;
                                    ;
                                    if (++ct >= 3)
                                    {
                                        break;
                                    }
                                }

                                SQRL.ZeroFillByteArray(ref decryptedBlock3);
                                priorSiteKeys = SQRL.CreatePriorSiteKeys(oldIUKs, requestURI, AltID);
                                oldIUKs.Clear();
                            }
                        }

                        //SQRL.ZeroFillByteArray(ref decryptedData.Item2);
                        //decryptedData.Item2.ZeroFill();
                        var serverRespose = SQRL.GenerateQueryCommand(requestURI, siteKvp, opts, null, 0, priorSiteKeys);

                        if (!serverRespose.CommandFailed)
                        {
                            if (!serverRespose.CurrentIDMatch && !serverRespose.PreviousIDMatch)
                            {
                                StringBuilder additionalData = null;
                                if (!string.IsNullOrEmpty(serverRespose.SIN))
                                {
                                    additionalData = new StringBuilder();
                                    byte[] ids = SQRL.CreateIndexedSecret(requestURI, AltID, block1Keys.Imk,
                                                                          Encoding.UTF8.GetBytes(serverRespose.SIN));
                                    additionalData.AppendLineWindows($"ins={Sodium.Utilities.BinaryToBase64(ids, Utilities.Base64Variant.UrlSafeNoPadding)}");
                                }
                                Console.WriteLine("The site doesn't recognize this ID, would you like to proceed and create one? (Y/N)");
                                if (Console.ReadLine().StartsWith("Y", StringComparison.OrdinalIgnoreCase))
                                {
                                    serverRespose = SQRL.GenerateNewIdentCommand(serverRespose.NewNutURL, siteKvp,
                                                                                 serverRespose.FullServerRequest, block1Keys.Ilk, opts, additionalData);
                                }
                            }
                            else if (serverRespose.PreviousIDMatch)
                            {
                                byte[] ursKey = null;
                                ursKey = SQRL.GetURSKey(serverRespose.PriorMatchedKey.Key, Sodium.Utilities.Base64ToBinary(
                                                            serverRespose.SUK, string.Empty, Sodium.Utilities.Base64Variant.UrlSafeNoPadding));

                                StringBuilder additionalData = null;
                                if (!string.IsNullOrEmpty(serverRespose.SIN))
                                {
                                    additionalData = new StringBuilder();
                                    byte[] ids = SQRL.CreateIndexedSecret(requestURI, AltID, block1Keys.Imk, Encoding.UTF8.GetBytes(serverRespose.SIN));
                                    additionalData.AppendLineWindows($"ins={Sodium.Utilities.BinaryToBase64(ids, Utilities.Base64Variant.UrlSafeNoPadding)}");
                                    byte[] pids = SQRL.CreateIndexedSecret(serverRespose.PriorMatchedKey.Value.SiteSeed, Encoding.UTF8.GetBytes(serverRespose.SIN));
                                    additionalData.AppendLineWindows($"pins={Sodium.Utilities.BinaryToBase64(pids, Utilities.Base64Variant.UrlSafeNoPadding)}");
                                }
                                serverRespose = SQRL.GenerateIdentCommandWithReplace(
                                    serverRespose.NewNutURL, siteKvp, serverRespose.FullServerRequest, block1Keys.Ilk,
                                    ursKey, serverRespose.PriorMatchedKey.Value.KeyPair, opts, additionalData);
                            }
                            else if (serverRespose.CurrentIDMatch)
                            {
                                int askResponse = 0;
                                if (serverRespose.HasAsk)
                                {
                                    Console.WriteLine(serverRespose.AskMessage);
                                    Console.WriteLine($"Enter 1 for {serverRespose.GetAskButtons[0]} or 2 for {serverRespose.GetAskButtons[1]}");
                                    int resp;
                                    do
                                    {
                                        string response = Console.ReadLine();
                                        int.TryParse(response, out resp);

                                        if (resp == 0)
                                        {
                                            Console.WriteLine("Invalid Entry, please enter 1 or 2 as shown above");
                                        }
                                    } while (resp == 0);
                                    askResponse = resp;
                                }

                                StringBuilder addClientData = null;
                                if (askResponse > 0)
                                {
                                    addClientData = new StringBuilder();
                                    addClientData.AppendLineWindows($"btn={askResponse}");
                                }

                                if (serverRespose.SQRLDisabled)
                                {
                                    Console.WriteLine("SQRL Is Disabled, to Continue you must enable it. Do you want to? (Y/N)");
                                    if (Console.ReadLine().StartsWith("Y", StringComparison.OrdinalIgnoreCase))
                                    {
                                        Console.WriteLine("Enter your Rescue Code (No Sapces or Dashes)");
                                        string rescueCode = Console.ReadLine().Trim();
                                        progress = new Progress <KeyValuePair <int, string> >(percent =>
                                        {
                                            Console.WriteLine($"Decrypting with Rescue Code: {percent.Key}%");
                                        });
                                        var iukData = await SQRL.DecryptBlock2(newId, rescueCode, progress);

                                        if (iukData.DecryptionSucceeded)
                                        {
                                            byte[] ursKey = null;
                                            ursKey = SQRL.GetURSKey(iukData.Iuk, Sodium.Utilities.Base64ToBinary(serverRespose.SUK, string.Empty, Sodium.Utilities.Base64Variant.UrlSafeNoPadding));

                                            iukData.Iuk.ZeroFill();
                                            serverRespose = SQRL.GenerateEnableCommand(serverRespose.NewNutURL, siteKvp, serverRespose.FullServerRequest, ursKey, addClientData, opts);
                                        }
                                        else
                                        {
                                            throw new Exception("Failed to Decrypt Block 2, Invalid Rescue Code");
                                        }
                                    }
                                }

                                Console.WriteLine("Which Command Would you like to Issue?:");
                                Console.WriteLine("*********************************************");
                                Console.WriteLine("0- Ident (Default/Enter) ");
                                Console.WriteLine("1- Disable ");
                                Console.WriteLine("2- Remove ");
                                Console.WriteLine("3- Cancel ");
                                Console.WriteLine("4- Re-Key ");
                                Console.WriteLine("10- Quit ");
                                Console.WriteLine("*********************************************");
                                var value = Console.ReadLine();
                                int.TryParse(value, out int selection);

                                switch (selection)
                                {
                                case 0:
                                {
                                    serverRespose = SQRL.GenerateSQRLCommand(SQRLCommands.ident, serverRespose.NewNutURL, siteKvp, serverRespose.FullServerRequest, addClientData, opts);
                                    if (sqrl.cps != null && sqrl.cps.PendingResponse)
                                    {
                                        sqrl.cps.cpsBC.Add(new Uri(serverRespose.SuccessUrl));
                                    }
                                }
                                break;

                                case 1:
                                {
                                    Console.WriteLine("This will disable all use of this SQRL Identity on the server, are you sure you want to proceed?: (Y/N)");
                                    if (Console.ReadLine().StartsWith("Y", StringComparison.OrdinalIgnoreCase))
                                    {
                                        serverRespose = SQRL.GenerateSQRLCommand(SQRLCommands.disable, serverRespose.NewNutURL, siteKvp, serverRespose.FullServerRequest, addClientData, opts);
                                        if (sqrl.cps != null && sqrl.cps.PendingResponse)
                                        {
                                            sqrl.cps.cpsBC.Add(sqrl.cps.Can);
                                        }
                                    }
                                }
                                break;

                                case 2:
                                {
                                    Console.WriteLine("Enter your Rescue Code (No Sapces or Dashes)");
                                    string rescueCode = Console.ReadLine().Trim();
                                    progress = new Progress <KeyValuePair <int, string> >(percent =>
                                        {
                                            Console.WriteLine($"Decrypting with Rescue Code: {percent.Key}%");
                                        });
                                    var iukData = await SQRL.DecryptBlock2(newId, rescueCode);

                                    if (iukData.DecryptionSucceeded)
                                    {
                                        byte[] ursKey = SQRL.GetURSKey(iukData.Iuk, Sodium.Utilities.Base64ToBinary(serverRespose.SUK, string.Empty, Sodium.Utilities.Base64Variant.UrlSafeNoPadding));
                                        iukData.Iuk.ZeroFill();
                                        serverRespose = SQRL.GenerateSQRLCommand(SQRLCommands.remove, serverRespose.NewNutURL, siteKvp, serverRespose.FullServerRequest, addClientData, opts, null, ursKey);
                                        if (sqrl.cps != null && sqrl.cps.PendingResponse)
                                        {
                                            sqrl.cps.cpsBC.Add(sqrl.cps.Can);
                                        }
                                    }
                                    else
                                    {
                                        throw new Exception("Failed to Decrypt Block 2, Invalid Rescue Code");
                                    }
                                }
                                break;

                                case 3:
                                {
                                    if (sqrl.cps != null && sqrl.cps.PendingResponse)
                                    {
                                        sqrl.cps.cpsBC.Add(sqrl.cps.Can);
                                    }
                                }
                                break;

                                default:
                                {
                                    Console.WriteLine("bye");
                                    run = false;
                                }
                                break;
                                }
                            }
                        }
                    } while (run);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error: {ex.ToString()}");
                }
            }
            else
            {
                Console.WriteLine("Failed to Decrypt Block 1, bad password!");
            }
        }