Exemple #1
0
 /// <summary>
 /// What to do when the selection changes in the QR Code site list:
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 private void cmboExportSiteQR_SelectedIndexChanged(object sender, EventArgs e)
 {
     // Asbestos underpants:
     try
     {
         // Get the current selection of the combo box and make sure it
         // isn't empty:
         String site = (string)cmboExportSiteQR.Text;
         if (!String.IsNullOrEmpty(site))
         {
             // Ask the main form to give us the site parameters for this site.
             // Since the main form has all the code to do this, we'll ask it
             // to do the dirty work.
             SiteParameters siteParams = caller.GetSiteParamsForQRCode(site);
             // Now we'll generate the text we'll embed into the QR Code.  We want
             // this to be as compact as we can get it, so our "headings" will be
             // single letters.  We'll start off with an identifying header so the
             // QR Code reader will know the format of our string.  We delimite the
             // string with pipes, which aren't allowed in any of our fields.  We
             // want this to match as closely to the values of the XML export file
             // for consistency.  That means the hash engine and the character
             // limit fields will need some tweaking.
             StringBuilder sb = new StringBuilder();
             sb.Append("CRYPTNOSv1|" +
                       "S:" + siteParams.Site + "|" +
                       "H:" + HashEngine.HashEnumStringToDisplayHash(siteParams.Hash) + "|" +
                       "I:" + siteParams.Iterations.ToString() + "|" +
                       "C:" + siteParams.CharTypes.ToString() + "|L:");
             if (siteParams.CharLimit < 0)
             {
                 sb.Append("0");
             }
             else
             {
                 sb.Append(siteParams.CharLimit.ToString());
             }
             // Now that we've built our string, use the QRCodeWriter from ZXing to
             // build the QR Code image and assign the bitmap to the picture box:
             byteMatrix = qrCodeWriter.encode(sb.ToString(),
                                              BarcodeFormat.QR_CODE, 200, 200);
             pictureBox1.Image = byteMatrix.ToBitmap();
         }
         // If the selection in the combo box wasn't useful, empty the picture box:
         else
         {
             pictureBox1.Image = null;
         }
     }
     // Similarly, if anything blew up, empty the picture box:
     catch { pictureBox1.Image = null; }
 }
Exemple #2
0
 /// <summary>
 /// Given an open registry key and a site key value, read the site parameters from
 /// the registry and return a SiteParameters object.
 /// </summary>
 /// <param name="registryKey">An open registry key</param>
 /// <param name="siteKey">A site key string</param>
 /// <returns>A SiteParameters object, or null on failure</returns>
 public static SiteParameters ReadFromRegistry(RegistryKey registryKey, string siteKey)
 {
     // Asbestos underpants:
     try
     {
         // This only works if the registry key is open and the site key is
         // something meaningful:
         if (registryKey != null && !String.IsNullOrEmpty(siteKey))
         {
             // Look for the site key value in the registry key and convert it from
             // Base64 to a byte array:
             byte[] encryptedParams = (byte[])registryKey.GetValue(siteKey);
             // Set up our decryption engine.  Create the Rijndael object, its
             // encryption key, and its initialization vector.
             RijndaelManaged rijndael = new RijndaelManaged();
             if (rijndael.ValidKeySize(256))
             {
                 rijndael.KeySize = 256;
             }
             rijndael.Padding = PaddingMode.PKCS7;
             byte[] cryptKey = GenerateEncryptionKey(siteKey);
             byte[] iv       = GenerateIV(rijndael.BlockSize / 8, siteKey);
             // Decrypt the raw bytes read from the registry:
             ICryptoTransform decryptor      = rijndael.CreateDecryptor(cryptKey, iv);
             MemoryStream     ms             = new MemoryStream(encryptedParams);
             CryptoStream     cs             = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
             byte[]           decryptedBytes = new byte[encryptedParams.Length];
             cs.Read(decryptedBytes, 0, decryptedBytes.Length);
             cs.Close();
             ms.Close();
             // Reset the memory stream to read the raw bytes and use a binary
             // formatter to deserialize the object:
             ms = new MemoryStream(decryptedBytes);
             BinaryFormatter bf = new BinaryFormatter();
             SiteParameters  sp = (SiteParameters)bf.Deserialize(ms);
             return(sp);
         }
         // If the registry key wasn't open or the site key wasn't meaningful, there's
         // nothing to do:
         else
         {
             return(null);
         }
     }
     // If anything blows up, don't return anything we can use:
     catch { return(null); }
 }
 /// <summary>
 /// Given a site name, save its parameter information to the registry
 /// </summary>
 /// <param name="site">The site to save</param>
 private void SaveSiteParams(string site)
 {
     // Asbestos underpants:
     try
     {
         // Only bother continuing if the registry is open and the site isn't empty:
         if (CryptnosRegistryKeyOpen() && !String.IsNullOrEmpty(site))
         {
             // Try to parse the iteration count text box value.  If it's not a positive
             // integer greater than zero, complain.  What I'm worried about here is
             // that I think this gets called when the application closes, so there's
             // a chance we could lose our site params if this fails.
             int iterations = 1;
             bool parsedIterations = Int32.TryParse(txtIterations.Text, out iterations);
             if (!parsedIterations || iterations < 1)
             {
                 MessageBox.Show("The iteration count must be a positive integer " +
                     "greater than zero.", "Error", MessageBoxButtons.OK,
                     MessageBoxIcon.Error);
                 txtIterations.Focus();
             }
             else
             {
                 // Using the GUI inputs, generate a SiteParameters object.  Note that for
                 // the character limit we'll pass in a -1 if the drop-down is actually
                 // set to the first item ("None"), while the rest go in pretty much as
                 // is.
                 SiteParameters siteParams = new SiteParameters(cbSites.Text,
                     cbCharTypes.SelectedIndex,
                     cbCharLimit.SelectedIndex == 0 ? -1 : cbCharLimit.SelectedIndex,
                     HashEngine.DisplayHashToHashEnumString((string)cbHashes.SelectedItem),
                     iterations);
                 // Attempt to save the site parameters to the registry.  If that works,
                 // proceed:
                 if (siteParams.SaveToRegistry(siteParamsKey))
                 {
                     // Set the last site value to this site:
                     CryptnosSettings.SetValue("LastSite",
                         SiteParameters.GenerateKeyFromSite(cbSites.Text),
                         RegistryValueKind.String);
                     // If the site doesn't exist in the drop-down list, add it now.  That way
                     // it can be quickly selected again.  To do that, we'll have to repopulate
                     // the entire list to make sure the it gets sorted alphabetically.  Then
                     // we'll set the selected value back to the new item's site token.
                     if (cbSites.Items.IndexOf(cbSites.Text) == -1)
                     {
                         PopulateSitesDropdown();
                         cbSites.SelectedValue = cbSites.Text;
                     }
                     // Since there are sites in the list now, enable the Forget and Export
                     // buttons:
                     btnForgetAll.Enabled = true;
                     btnExport.Enabled = true;
                     btnForget.Enabled = true;
                 }
             }
         }
     }
     // Silently ignore errors:
     catch { }
 }
 /// <summary>
 /// Read a <see cref="List"/> of <see cref="SiteParameters"/> from the new XML-based
 /// cross-platform export file format
 /// </summary>
 /// <param name="filename">A string containing the full path to the import file</param>
 /// <param name="password">A string containing the password used to decrypt the
 /// file</param>
 /// <returns>A <see cref="List"/> of <see cref="SiteParameters"/></returns>
 /// <exception cref="ImportHandlerException">Thrown if a parsing error occurs during
 /// the import process</exception>
 /// <exception cref="Exception">Thrown if anything else blows up along the way</exception>
 private static List <SiteParameters> ImportFromXMLv1File(string filename,
                                                          string password)
 {
     try
     {
         // Declare somewhere to hold the site count as read from the file:
         int siteCount = 0;
         // Try to open a file stream for the file:
         FileStream fs = new FileStream(filename, FileMode.Open);
         // The process below will blow up if we try to read a file that is so large
         // it exceeds the 32-bit integer max value.  This should never happen with an
         // actual Cryptnos export file, but if the user accidentally tries to import
         // a DVD ISO or something, we don't want to blow up their machine.  Bomb out
         // if we find out that the file is too large.
         if (fs.Length > (long)Int32.MaxValue)
         {
             fs.Close();
             throw new ImportHandlerException("Import file too large to load into memory");
         }
         // Read the entire contents of the file into memory:
         byte[] contents = new byte[(int)fs.Length];
         fs.Read(contents, 0, contents.Length);
         fs.Close();
         // Create our cipher in decryption mode:
         BufferedBlockCipher cipher = CreateCipher(password, false);
         // Create our plaintext container:
         byte[] plaintext = new byte[cipher.GetOutputSize(contents.Length)];
         // Decrypt the data and create a memory stream so we can read from it:
         plaintext = cipher.DoFinal(contents);
         MemoryStream ms = new MemoryStream(plaintext);
         contents = null;
         // Define our XML reader settings:
         XmlReaderSettings xmlReaderSettings = new XmlReaderSettings();
         // Note that we'll point to our local copy of the XSD, which should be in the
         // application directory:
         xmlReaderSettings.Schemas.Add("http://www.cryptnos.com/",
                                       Application.StartupPath + Char.ToString(System.IO.Path.DirectorySeparatorChar) +
                                       "cryptnos_export1.xsd");
         // Validate against the schema.  Invalid files will throw exceptions:
         xmlReaderSettings.ValidationType          = ValidationType.Schema;
         xmlReaderSettings.ValidationEventHandler +=
             new ValidationEventHandler(xmlReaderSettings_ValidationEventHandler);
         // Ignore unnecessary information:
         xmlReaderSettings.IgnoreComments   = true;
         xmlReaderSettings.IgnoreWhitespace = true;
         // Close any other file/input streams when we close this one:
         xmlReaderSettings.CloseInput = true;
         // Create the XML reader.  Note that we're reading from the memory stream
         // created from the decrypted file, then passing that through a gzip
         // decompressor before actually getting to the data.
         XmlReader xr = XmlReader.Create(new GZipStream(ms,
                                                        CompressionMode.Decompress), xmlReaderSettings);
         // This forces us to go to the first element, which should be <cryptnos>.  If
         // not, complain:
         xr.MoveToContent();
         if (xr.Name != "cryptnos")
         {
             throw new ImportHandlerException("Invalid Cryptnos export file; expected <cryptnos> tag but got <" + xr.Name + ">");
         }
         // At this point, things are looking good.  We'll hopefully have sites we can
         // import now.  Go ahead and create our List of SiteParameters so we can start
         // building it:
         List <SiteParameters> siteList = new List <SiteParameters>();
         // Read the next element.  This should be a <version> tag.  If it is, make sure
         // it's a version we recognize.  Otherwise, complain.
         xr.Read();
         if (xr.NodeType != XmlNodeType.Element)
         {
             throw new ImportHandlerException("Invalid Cryptnos export file; expected an element, but got " + xr.NodeType.ToString());
         }
         if (xr.Name.CompareTo("version") == 0)
         {
             xr.Read();
             // Make sure this is a text value, then make sure it's the version
             // number we expect.  This version of Cryptnos only accepts version
             // 1 of the Cryptnos export file format.
             if (xr.NodeType == XmlNodeType.Text && xr.Value != "1")
             {
                 throw new ImportHandlerException("This Cryptnos export file appears to have been generated by a later version of Cryptnos and is incompatible with this version. (File format version was " + xr.Value + ".)");
             }
         }
         else
         {
             throw new ImportHandlerException("Invalid Cryptnos export file; expected a <version> element, but got <" + xr.Name + ">");
         }
         // Read on to the next tag:
         xr.Read();
         while (xr.NodeType == XmlNodeType.EndElement)
         {
             xr.Read();
         }
         if (xr.NodeType != XmlNodeType.Element)
         {
             throw new ImportHandlerException("Invalid Cryptnos export file; expected an element, but got " + xr.NodeType.ToString());
         }
         // At this point, the next few tags should be the <generator> and/or <comment>
         // tags, neither of which we care about.  Therefore, just read ahead until we
         // hit the <sites> tag, which is where we really want to go to next.
         while (xr.Name.CompareTo("siteCount") != 0)
         {
             do
             {
                 xr.Read();
             } while (xr.NodeType != XmlNodeType.Element);
         }
         // The next tag should be the <siteCount> tag.  This contains the number of
         // site blocks in the file.  This technically isn't necessary, but it was added
         // to improve reporting on Android, where performance is much more of an issue.
         // The main thing we'll worry about here is that (a) it's an integer greater
         // than zero and (b) the number of sites we eventually read must equal the
         // count listed here.
         if (xr.NodeType == XmlNodeType.Element && xr.Name.CompareTo("siteCount") == 0)
         {
             xr.Read();
             if (xr.NodeType == XmlNodeType.Text)
             {
                 siteCount = Int32.Parse(xr.Value);
             }
             if (siteCount <= 0)
             {
                 throw new ImportHandlerException("Invalid Cryptnos export file; <siteCount> is " + siteCount.ToString());
             }
         }
         // Read on to the next tag:
         xr.Read();
         while (xr.NodeType == XmlNodeType.EndElement)
         {
             xr.Read();
         }
         // Now we need to check to make sure we actually got a <sites> tag:
         if (xr.NodeType == XmlNodeType.Element && xr.Name.CompareTo("sites") == 0)
         {
             // Read the next tag.  This should be a <site> tag and the beginning of a
             // site defintion.
             xr.Read();
             while (xr.NodeType == XmlNodeType.Element && xr.Name.CompareTo("site") == 0)
             {
                 // Create a new SiteParameters object to store the data we're about
                 // to read.
                 SiteParameters site = new SiteParameters();
                 // Try to read the <siteToken> tag:
                 xr.Read();
                 if (xr.NodeType != XmlNodeType.Element)
                 {
                     throw new ImportHandlerException("Invalid Cryptnos export file; expected an element, but got " + xr.NodeType.ToString());
                 }
                 if (xr.Name.CompareTo("siteToken") == 0)
                 {
                     xr.Read();
                     if (xr.NodeType == XmlNodeType.Text)
                     {
                         site.Site = xr.Value;
                     }
                     else
                     {
                         throw new ImportHandlerException("Invalid site token (" + xr.Value + ")");
                     }
                 }
                 else
                 {
                     throw new ImportHandlerException("Invalid Cryptnos export file; expected a <siteToken> element, but got <" + xr.Name + ">");
                 }
                 do
                 {
                     xr.Read();
                 } while (xr.NodeType != XmlNodeType.Element);
                 // Try to read the <hash> tag:
                 if (xr.NodeType != XmlNodeType.Element)
                 {
                     throw new ImportHandlerException("Invalid Cryptnos export file; expected an element, but got " + xr.NodeType.ToString());
                 }
                 if (xr.Name.CompareTo("hash") == 0)
                 {
                     xr.Read();
                     if (xr.NodeType == XmlNodeType.Text)
                     {
                         site.Hash = HashEngine.DisplayHashToHashEnumString(xr.Value);
                     }
                     else
                     {
                         throw new ImportHandlerException("Invalid hash token (" + xr.Value + ")");
                     }
                 }
                 else
                 {
                     throw new ImportHandlerException("Invalid Cryptnos export file; expected a <hash> element, but got <" + xr.Name + ">");
                 }
                 do
                 {
                     xr.Read();
                 } while (xr.NodeType != XmlNodeType.Element);
                 // Try to read the <iterations> tag:
                 if (xr.NodeType != XmlNodeType.Element)
                 {
                     throw new ImportHandlerException("Invalid Cryptnos export file; expected an element, but got " + xr.NodeType.ToString());
                 }
                 if (xr.Name.CompareTo("iterations") == 0)
                 {
                     xr.Read();
                     if (xr.NodeType == XmlNodeType.Text)
                     {
                         site.Iterations = Int32.Parse(xr.Value);
                     }
                     else
                     {
                         throw new ImportHandlerException("Invalid iterations token (" + xr.Value + ")");
                     }
                 }
                 else
                 {
                     throw new ImportHandlerException("Invalid Cryptnos export file; expected an <iterations> element, but got <" + xr.Name + ">");
                 }
                 do
                 {
                     xr.Read();
                 } while (xr.NodeType != XmlNodeType.Element);
                 // Try to read the <charTypes> tag:
                 if (xr.NodeType != XmlNodeType.Element)
                 {
                     throw new ImportHandlerException("Invalid Cryptnos export file; expected an element, but got " + xr.NodeType.ToString());
                 }
                 if (xr.Name.CompareTo("charTypes") == 0)
                 {
                     xr.Read();
                     if (xr.NodeType == XmlNodeType.Text)
                     {
                         site.CharTypes = Int32.Parse(xr.Value);
                     }
                     else
                     {
                         throw new ImportHandlerException("Invalid charTypes token (" + xr.Value + ")");
                     }
                 }
                 else
                 {
                     throw new ImportHandlerException("Invalid Cryptnos export file; expected a <charTypes> element, but got <" + xr.Name + ">");
                 }
                 do
                 {
                     xr.Read();
                 } while (xr.NodeType != XmlNodeType.Element);
                 // Try to read the <charLimit> tag:
                 if (xr.NodeType != XmlNodeType.Element)
                 {
                     throw new ImportHandlerException("Invalid Cryptnos export file; expected an element, but got " + xr.NodeType.ToString());
                 }
                 if (xr.Name.CompareTo("charLimit") == 0)
                 {
                     xr.Read();
                     if (xr.NodeType == XmlNodeType.Text)
                     {
                         // The character limit, unfortunately, is a bit inconsistent.
                         // Obviously, we can't limit it to zero, as that will mean we
                         // have an empty password.  But the XML schema defines this as
                         // only positive integers, so our built-in -1 value can't work.
                         // So if we read a zero, convert it to -1 here.  We'll do the
                         // reverse when we write the file.
                         site.CharLimit = Int32.Parse(xr.Value);
                         if (site.CharLimit == 0)
                         {
                             site.CharLimit = -1;
                         }
                     }
                     else
                     {
                         throw new ImportHandlerException("Invalid charLimit token (" + xr.Value + ")");
                     }
                 }
                 else
                 {
                     throw new ImportHandlerException("Invalid Cryptnos export file; expected a <charLimit> element, but got <" + xr.Name + ">");
                 }
                 // The next item should be the closing element for <charLimit>, so
                 // read it in and then read the next one.  That should either be the
                 // start element for the next <site> or the closing element for
                 // <sites>.
                 xr.Read();
                 if (xr.NodeType == XmlNodeType.EndElement)
                 {
                     xr.Read();
                 }
                 else
                 {
                     throw new ImportHandlerException("Invalid Cryptnos export file; expected ending <charLimit> tag, got " + xr.NodeType.ToString());
                 }
                 if (xr.NodeType == XmlNodeType.EndElement)
                 {
                     xr.Read();
                 }
                 else
                 {
                     throw new ImportHandlerException("Invalid Cryptnos export file; expected ending <site> tag, got " + xr.NodeType.ToString());
                 }
                 // We should now have a hopefully valid SiteParameters object.  Add it
                 // to the site list:
                 siteList.Add(site);
             }
             // We get here, we've exhausted the <sites> block and all that should be
             // left will be closing tags.  If we were going to be extremely thorough,
             // we should probably check these closing tags and make sure they're legit.
             // For now, we'll just assume there's nothing left to read.  Close the
             // streams, free up memory, and return the list of read sites.
             xr.Close();
             ms.Close();
             ms.Dispose();
             plaintext = null;
             if (siteList.Count != siteCount)
             {
                 throw new ImportHandlerException("Invalid Cryptnos export file; File reported " + siteCount.ToString() + " sites in the file, but actually read " + siteList.Count.ToString());
             }
             return(siteList);
         }
         else
         {
             throw new ImportHandlerException("Invalid Cryptnos export file; could not find <sites> tag");
         }
     }
     catch (Exception ex) { throw ex; }
 }