Example #1
0
		/// <summary>
		/// Import a v2 authenticator from an existing file name
		/// </summary>
		/// <param name="authenticatorFile">name of v2 xml file</param>
		private void importAuthenticatorFromV2(string authenticatorFile)
		{
			bool retry = false;
			string password = null;
			bool needPassword = false;
			bool invalidPassword = false;
			do
			{
				try
				{
					WinAuthConfig config = WinAuthHelper.LoadConfig(this, authenticatorFile, password);
					if (config.Count == 0)
					{
						return;
					}

					// get the actual authenticator and ensure it is synced
					WinAuthAuthenticator importedAuthenticator = config[0];
					importedAuthenticator.Sync();

					// make sure there isn't a name clash
					int rename = 0;
					string importedName = importedAuthenticator.Name;
					while (this.Config.Where(a => a.Name == importedName).Count() != 0)
					{
						importedName = importedAuthenticator.Name + " (" + (++rename) + ")";
					}
					importedAuthenticator.Name = importedName;

					// save off any new authenticators as a backup
					WinAuthHelper.SaveToRegistry(this.Config, importedAuthenticator);

					// first time we prompt for protection and set out main settings from imported config
					if (this.Config.Count == 0)
					{
						this.Config.StartWithWindows = config.StartWithWindows;
						this.Config.UseTrayIcon = config.UseTrayIcon;
						this.Config.AlwaysOnTop = config.AlwaysOnTop;

						ChangePasswordForm form = new ChangePasswordForm();
						form.PasswordType = Authenticator.PasswordTypes.Explicit;
						if (form.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
						{
							this.Config.Yubi = form.Yubikey;
							this.Config.PasswordType = form.PasswordType;
							if ((this.Config.PasswordType & Authenticator.PasswordTypes.Explicit) != 0 && string.IsNullOrEmpty(form.Password) == false)
							{
								this.Config.Password = form.Password;
							}
						}
					}

					// add to main list
					this.Config.Add(importedAuthenticator);
					SaveConfig(true);
					loadAuthenticatorList(importedAuthenticator);

					// reset UI
					setAutoSize();
					introLabel.Visible = (this.Config.Count == 0);

					// reset hotkeys
					HookHotkeys();

					needPassword = false;
					retry = false;
				}
				catch (EncrpytedSecretDataException)
				{
					needPassword = true;
					invalidPassword = false;
				}
				catch (BadYubiKeyException)
				{
					needPassword = true;
					invalidPassword = false;
				}
				catch (BadPasswordException)
				{
					needPassword = true;
					invalidPassword = true;
				}
				catch (Exception ex)
				{
					if (ErrorDialog(this, strings.UnknownError + ": " + ex.Message, ex, MessageBoxButtons.RetryCancel) == System.Windows.Forms.DialogResult.Cancel)
					{
						return;
					}
					needPassword = false;
					invalidPassword = false;
					retry = true;
				}

				if (needPassword == true)
				{
					GetPasswordForm form = new GetPasswordForm();
					form.InvalidPassword = invalidPassword;
					var result = form.ShowDialog(this);
					if (result == DialogResult.Cancel)
					{
						return;
					}
					password = form.Password;
					retry = true;
				}
			} while (retry == true);
		}
Example #2
0
		/// <summary>
		/// Click the Export menu
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void exportOptionsMenuItem_Click(object sender, EventArgs e)
		{
			// confirm current password
			if ((this.Config.PasswordType & Authenticator.PasswordTypes.Explicit) != 0)
			{
				bool invalidPassword = false;
				while (true)
				{
					GetPasswordForm checkform = new GetPasswordForm();
					checkform.InvalidPassword = invalidPassword;
					var result = checkform.ShowDialog(this);
					if (result == DialogResult.Cancel)
					{
						return;
					}
					if (this.Config.IsPassword(checkform.Password) == true)
					{
						break;
					}
					invalidPassword = true;
				}
			}

			ExportForm exportform = new ExportForm();
			if (exportform.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
			{
				WinAuthHelper.ExportAuthenticators(this, this.Config, exportform.ExportFile, exportform.Password, exportform.PGPKey);
			}
		}
Example #3
0
		/// <summary>
		/// Process the context menu item
		/// </summary>
		/// <param name="menuitem"></param>
		private void ProcessMenu(ToolStripItem menuitem)
		{
			var item = this.CurrentItem;
			var auth = item.Authenticator;

			// check and perform each menu
			if (menuitem.Name == "setPasswordMenuItem")
			{
				// check if the authentcated is still protected
				DialogResult wasprotected = UnprotectAuthenticator(item);
				if (wasprotected == DialogResult.Cancel)
				{
					return;
				}
				try
				{
					// show the new password form
					SetPasswordForm form = new SetPasswordForm();
					if (form.ShowDialog(this.Parent as Form) != DialogResult.OK)
					{
						return;
					}

					// set the encrpytion
					string password = form.Password;
					if (string.IsNullOrEmpty(password) == false)
					{
						auth.AuthenticatorData.SetEncryption(Authenticator.PasswordTypes.Explicit, password);
						// can't have autorefresh on
						auth.AutoRefresh = false;

						item.UnprotectCount = 0;
						item.DisplayUntil = DateTime.MinValue;
						item.LastUpdate = DateTime.MinValue;
						item.LastCode = null;
					}
					else
					{
						auth.AuthenticatorData.SetEncryption(Authenticator.PasswordTypes.None);
					}
					// make sure authenticator is saved
					auth.MarkChanged();
					RefreshCurrentItem();
				}
				finally
				{
					if (wasprotected == DialogResult.OK)
					{
						ProtectAuthenticator(item);
					}
				}
			}
			else if (menuitem.Name == "showCodeMenuItem")
			{
				// check if the authentcated is still protected
				if (UnprotectAuthenticator(item) == DialogResult.Cancel)
				{
					return;
				}

				// reduce unprotect count if already displayed
				if (item.DisplayUntil != DateTime.MinValue)
				{
					ProtectAuthenticator(item);
				}

				item.LastCode = auth.CurrentCode;
				item.LastUpdate = DateTime.Now;
				item.DisplayUntil = DateTime.Now.AddSeconds(10);
				RefreshCurrentItem();
			}
			else if (menuitem.Name == "copyCodeMenuItem")
			{
				// check if the authentcated is still protected
				DialogResult wasprotected = UnprotectAuthenticator(item);
				if (wasprotected == DialogResult.Cancel)
				{
					return;
				}
				try
				{
					auth.CopyCodeToClipboard(this.Parent as Form, item.LastCode, true);
				}
				finally
				{
					if (wasprotected == DialogResult.OK)
					{
						ProtectAuthenticator(item);
					}
				}
			}
			else if (menuitem.Name == "autoRefreshMenuItem")
			{
				auth.AutoRefresh = !auth.AutoRefresh;
				item.LastUpdate = DateTime.Now;
				item.DisplayUntil = DateTime.MinValue;
				RefreshCurrentItem();
			}
			else if (menuitem.Name == "shortcutKeyMenuItem")
			{
				DialogResult wasprotected = UnprotectAuthenticator(item);
				if (wasprotected == DialogResult.Cancel)
				{
					return;
				}
				try
				{
					SetShortcutKeyForm form = new SetShortcutKeyForm();
					form.Hotkey = auth.HotKey;
					if (form.ShowDialog(this.Parent as Form) != DialogResult.OK)
					{
						return;
					}
					auth.HotKey = form.Hotkey;
				}
				finally
				{
					if (wasprotected == DialogResult.OK)
					{
						ProtectAuthenticator(item);
					}
				}
			}
			else if (menuitem.Name == "copyOnCodeMenuItem")
			{
				auth.CopyOnCode = !auth.CopyOnCode;
			}
			else if (menuitem.Name == "showRestoreCodeMenuItem")
			{
				// check if the authentcated is still protected
				DialogResult wasprotected = UnprotectAuthenticator(item);
				if (wasprotected == DialogResult.Cancel)
				{
					return;
				}
				try
				{
					if (wasprotected != DialogResult.OK)
					{
						// confirm current main password
						var mainform = this.Parent as WinAuthForm;
						if ((mainform.Config.PasswordType & Authenticator.PasswordTypes.Explicit) != 0)
						{
							bool invalidPassword = false;
							while (true)
							{
								GetPasswordForm checkform = new GetPasswordForm();
								checkform.InvalidPassword = invalidPassword;
								var result = checkform.ShowDialog(this);
								if (result == DialogResult.Cancel)
								{
									return;
								}
								if (mainform.Config.IsPassword(checkform.Password) == true)
								{
									break;
								}
								invalidPassword = true;
							}
						}
					}

					// show the serial and restore code for Battle.net authenticator				
					ShowRestoreCodeForm form = new ShowRestoreCodeForm();
					form.CurrentAuthenticator = auth;
					form.ShowDialog(this.Parent as Form);
				}
				finally
				{
					if (wasprotected == DialogResult.OK)
					{
						ProtectAuthenticator(item);
					}
				}
			}
			else if (menuitem.Name == "showGoogleSecretMenuItem")
			{
				// check if the authentcated is still protected
				DialogResult wasprotected = UnprotectAuthenticator(item);
				if (wasprotected == DialogResult.Cancel)
				{
					return;
				}
				try
				{
					if (wasprotected != DialogResult.OK)
					{
						// confirm current main password
						var mainform = this.Parent as WinAuthForm;
						if ((mainform.Config.PasswordType & Authenticator.PasswordTypes.Explicit) != 0)
						{
							bool invalidPassword = false;
							while (true)
							{
								GetPasswordForm checkform = new GetPasswordForm();
								checkform.InvalidPassword = invalidPassword;
								var result = checkform.ShowDialog(this);
								if (result == DialogResult.Cancel)
								{
									return;
								}
								if (mainform.Config.IsPassword(checkform.Password) == true)
								{
									break;
								}
								invalidPassword = true;
							}
						}
					}

					// show the secret key for Google authenticator				
					ShowSecretKeyForm form = new ShowSecretKeyForm();
					form.CurrentAuthenticator = auth;
					form.ShowDialog(this.Parent as Form);
				}
				finally
				{
					if (wasprotected == DialogResult.OK)
					{
						ProtectAuthenticator(item);
					}
				}
			}
			else if (menuitem.Name == "showTrionSecretMenuItem")
			{
				// check if the authenticator is still protected
				DialogResult wasprotected = UnprotectAuthenticator(item);
				if (wasprotected == DialogResult.Cancel)
				{
					return;
				}
				try
				{
					// show the secret key for Trion authenticator				
					ShowTrionSecretForm form = new ShowTrionSecretForm();
					form.CurrentAuthenticator = auth;
					form.ShowDialog(this.Parent as Form);
				}
				finally
				{
					if (wasprotected == DialogResult.OK)
					{
						ProtectAuthenticator(item);
					}
				}
			}
			else if (menuitem.Name == "showSteamSecretMenuItem")
			{
				// check if the authenticator is still protected
				DialogResult wasprotected = UnprotectAuthenticator(item);
				if (wasprotected == DialogResult.Cancel)
				{
					return;
				}

				try
				{
					if (wasprotected != DialogResult.OK)
					{
						// confirm current main password
						var mainform = this.Parent as WinAuthForm;
						if ((mainform.Config.PasswordType & Authenticator.PasswordTypes.Explicit) != 0)
						{
							bool invalidPassword = false;
							while (true)
							{
								GetPasswordForm checkform = new GetPasswordForm();
								checkform.InvalidPassword = invalidPassword;
								var result = checkform.ShowDialog(this);
								if (result == DialogResult.Cancel)
								{
									return;
								}
								if (mainform.Config.IsPassword(checkform.Password) == true)
								{
									break;
								}
								invalidPassword = true;
							}
						}
					}

					// show the secret key for Google authenticator				
					ShowSteamSecretForm form = new ShowSteamSecretForm();
					form.CurrentAuthenticator = auth;
					form.ShowDialog(this.Parent as Form);
				}
				finally
				{
					if (wasprotected == DialogResult.OK)
					{
						ProtectAuthenticator(item);
					}
				}
			}
			else if (menuitem.Name == "showSteamTradesMenuItem")
			{
				// check if the authenticator is still protected
				DialogResult wasprotected = UnprotectAuthenticator(item);
				if (wasprotected == DialogResult.Cancel)
				{
					return;
				}

				try
				{
					// show the Steam trades dialog
					ShowSteamTradesForm form = new ShowSteamTradesForm();
					form.Authenticator = auth;
					form.ShowDialog(this.Parent as Form);
				}
				finally
				{
					if (wasprotected == DialogResult.OK)
					{
						ProtectAuthenticator(item);
					}
				}
			}
			else if (menuitem.Name == "deleteMenuItem")
			{
				if (WinAuthForm.ConfirmDialog(this.Parent as Form, strings.DeleteAuthenticatorWarning, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
				{
					int index = item.Index;
					this.Items.Remove(item);
					ItemRemoved(this, new AuthenticatorListItemRemovedEventArgs(item));
					if (index >= this.Items.Count)
					{
						index = this.Items.Count - 1;
					}
					this.CurrentItem = (this.Items.Count != 0 ? this.Items[index] as AuthenticatorListitem : null);
					// reset the correct indexes of our items
					for (int i = 0; i < this.Items.Count; i++)
					{
						(this.Items[i] as AuthenticatorListitem).Index = i;
					}
				}
			}
			else if (menuitem.Name == "renameMenuItem")
			{
				int y = (this.ItemHeight * item.Index) - (this.TopIndex * this.ItemHeight) + 8;
				RenameTextbox.Location = new Point(64, y);
				RenameTextbox.Text = auth.Name;
				RenameTextbox.Tag = item;
				RenameTextbox.Visible = true;
				RenameTextbox.Focus();
			}
			else if (menuitem.Name == "syncMenuItem")
			{
				// check if the authentcated is still protected
				DialogResult wasprotected = UnprotectAuthenticator(item);
				if (wasprotected == DialogResult.Cancel)
				{
					return;
				}
				Cursor cursor = Cursor.Current;
				try {
					Cursor.Current = Cursors.WaitCursor;
					auth.Sync();
					RefreshItem(item);
				}
				finally
				{
					Cursor.Current = cursor;
					if (wasprotected == DialogResult.OK)
					{
						ProtectAuthenticator(item);
					}
				}
			}
			else if (menuitem.Name.StartsWith("iconMenuItem_") == true)
			{
				if (menuitem.Tag is string && string.Compare((string)menuitem.Tag, "OTHER") == 0)
				{
					do
					{
						// other..choose an image file
						OpenFileDialog ofd = new OpenFileDialog();
						ofd.AddExtension = true;
						ofd.CheckFileExists = true;
						ofd.DefaultExt = "png";
						ofd.InitialDirectory = Directory.GetCurrentDirectory();
						ofd.FileName = string.Empty;
						ofd.Filter = "PNG Image Files (*.png)|*.png|GIF Image Files (*.gif)|*.gif|All Files (*.*)|*.*";
						ofd.RestoreDirectory = true;
						ofd.ShowReadOnly = false;
						ofd.Title = strings.LoadIconImage + " (png or gif @ 48x48)";
						DialogResult result = ofd.ShowDialog(this);
						if (result != System.Windows.Forms.DialogResult.OK)
						{
							return;
						}
						try
						{
							// get the image and create an icon if not already the right size
							using (Bitmap iconimage = (Bitmap)Image.FromFile(ofd.FileName))
							{
								if (iconimage.Width != ICON_WIDTH || iconimage.Height != ICON_HEIGHT)
								{
                  using (Bitmap scaled = new Bitmap(ICON_WIDTH, ICON_HEIGHT))
                  {
                    using (Graphics g = Graphics.FromImage(scaled))
                    {
                      g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                      g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                      g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                      g.DrawImage(iconimage, new Rectangle(0, 0, ICON_WIDTH, ICON_HEIGHT));
                    }
                    auth.Icon = scaled;
                  }
								}
								else
								{
									auth.Icon = iconimage;
								}
								RefreshCurrentItem();
							}
						}
						catch (Exception ex)
						{
							if (MessageBox.Show(this.Parent as Form,
								string.Format(strings.ErrorLoadingIconFile, ex.Message),
								WinAuthMain.APPLICATION_NAME,
								MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
							{
								continue;
							}
						}
						break;
					} while (true);
				}
				else 
				{
					auth.Skin = (((string)menuitem.Tag).Length != 0 ? (string)menuitem.Tag : null);
					RefreshCurrentItem();
				}
			}
		}
Example #4
0
		/// <summary>
		/// Click the Change Password item of the Options menu
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void changePasswordOptionsMenuItem_Click(object sender, EventArgs e)
		{
			// confirm current password
			if ((this.Config.PasswordType & Authenticator.PasswordTypes.Explicit) != 0)
			{
				bool invalidPassword = false;
				while (true)
				{
					GetPasswordForm checkform = new GetPasswordForm();
					checkform.InvalidPassword = invalidPassword;
					var result = checkform.ShowDialog(this);
					if (result == DialogResult.Cancel)
					{
						return;
					}
					if (this.Config.IsPassword(checkform.Password) == true)
					{
						break;
					}
					invalidPassword = true;
				}
			}

			ChangePasswordForm form = new ChangePasswordForm();
			form.PasswordType = this.Config.PasswordType;
			if (form.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
			{
				bool retry;
				var retrypasswordtype = this.Config.PasswordType;
				do
				{
					retry = false;

					this.Config.PasswordType = form.PasswordType;
					if ((this.Config.PasswordType & (Authenticator.PasswordTypes.YubiKeySlot1 | Authenticator.PasswordTypes.YubiKeySlot2)) != 0 && form.Yubikey != null)
					{
						this.Config.Yubi = form.Yubikey;
					}
					if ((this.Config.PasswordType & Authenticator.PasswordTypes.Explicit) != 0 && string.IsNullOrEmpty(form.Password) == false)
					{
						this.Config.Password = form.Password;
					}

					try
					{
						SaveConfig(true);
					}
					catch (InvalidEncryptionException)
					{
						var result = WinAuthForm.ConfirmDialog(this, "Decryption test failed. Retry?", MessageBoxButtons.YesNo);
						if (result == DialogResult.Yes)
						{
							retry = true;
							continue;
						}
						this.Config.PasswordType = retrypasswordtype;
					}
					catch (ChallengeResponseException)
					{
						var result = WinAuthForm.ConfirmDialog(this, "YubiKey Challenge/Response failed. Retry?", MessageBoxButtons.YesNo);
						if (result == DialogResult.Yes)
						{
							retry = true;
							continue;
						}
						this.Config.PasswordType = retrypasswordtype;
					}
				} while (retry);
			}
		}
Example #5
0
		/// <summary>
		/// Import a file containing authenticators in the KeyUriFormat. The file might be plain text, encrypted zip or encrypted pgp.
		/// </summary>
		/// <param name="parent">parent Form</param>
		/// <param name="file">file name to import</param>
		/// <returns>list of imported authenticators</returns>
		public static List<WinAuthAuthenticator> ImportAuthenticators(Form parent, string file)
		{
			List<WinAuthAuthenticator> authenticators = new List<WinAuthAuthenticator>();

			string password = null;
			string pgpKey = null;

			StringBuilder lines = new StringBuilder();
			bool retry;
			do
			{
				retry = false;
				lines.Length = 0;

				// open the zip file
				if (string.Compare(Path.GetExtension(file), ".zip", true) == 0)
				{
					using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read))
					{
						ZipFile zip = null;
						try
						{
							zip = new ZipFile(fs);
							if (string.IsNullOrEmpty(password) == false)
							{
								zip.Password = password;
							}

							byte[] buffer = new byte[4096];
							foreach (ZipEntry entry in zip)
							{
								if (entry.IsFile == false || string.Compare(Path.GetExtension(entry.Name), ".txt", true) != 0)
								{
									continue;
								}

								// read file out
								Stream zs = zip.GetInputStream(entry);
								using (var ms = new MemoryStream())
								{
									StreamUtils.Copy(zs, ms, buffer);

									// get as string and append
									ms.Seek(0, SeekOrigin.Begin);
									using (var sr = new StreamReader(ms))
									{
										lines.Append(sr.ReadToEnd()).Append(Environment.NewLine);
									}
								}
							}
						}
						catch (ZipException ex)
						{
							if (ex.Message.IndexOf("password") != -1)
							{
								// already have a password
								if (string.IsNullOrEmpty(password) == false)
								{
									WinAuthForm.ErrorDialog(parent, strings.InvalidPassword, ex.InnerException, MessageBoxButtons.OK);
								}

								// need password
								GetPasswordForm form = new GetPasswordForm();
								if (form.ShowDialog(parent) == DialogResult.Cancel)
								{
									return null;
								}
								password = form.Password;
								retry = true;
								continue;
							}

							throw;
						}
						finally
						{
							if (zip != null)
							{
								zip.IsStreamOwner = true;
								zip.Close();
							}
						}
					}
				}
				else if (string.Compare(Path.GetExtension(file), ".pgp", true) == 0)
				{
					string encoded = File.ReadAllText(file);
					if (string.IsNullOrEmpty(pgpKey) == true)
					{
						// need password
						GetPGPKeyForm form = new GetPGPKeyForm();
						if (form.ShowDialog(parent) == DialogResult.Cancel)
						{
							return null;
						}
						pgpKey = form.PGPKey;
						password = form.Password;
						retry = true;
						continue;
					}
					try
					{
						string line = PGPDecrypt(encoded, pgpKey, password);
						lines.Append(line);
					}
					catch (Exception ex)
					{
						WinAuthForm.ErrorDialog(parent, strings.InvalidPassword, ex.InnerException, MessageBoxButtons.OK);

						pgpKey = null;
						password = null;
						retry = true;
						continue;
					}
				}
				else // read a plain text file
				{
					lines.Append(File.ReadAllText(file));
				}
			} while (retry);

			int linenumber = 0;
			try
			{
				using (var sr = new StringReader(lines.ToString()))
				{
					string line;
					while ((line = sr.ReadLine()) != null)
					{
						linenumber++;

						// ignore blank lines or comments
						line = line.Trim();
						if (line.Length == 0 || line.IndexOf("#") == 0)
						{
							continue;
						}

						// parse and validate URI
						var uri = new Uri(line);

						// we only support "otpauth"
						if (uri.Scheme != "otpauth")
						{
							throw new ApplicationException("Import only supports otpauth://");
						}
						// we only support totp (not hotp)
						if (uri.Host != "totp" && uri.Host != "hotp")
						{
							throw new ApplicationException("Import only supports otpauth://totp/ or otpauth://hotp/");
						}

						// get the label and optional issuer
						string issuer = string.Empty;
						string label = (string.IsNullOrEmpty(uri.LocalPath) == false ? uri.LocalPath.Substring(1) : string.Empty); // skip past initial /
						int p = label.IndexOf(":");
						if (p != -1)
						{
							issuer = label.Substring(0, p);
							label = label.Substring(p + 1);
						}
						// + aren't decoded
						label = label.Replace("+", " ");

						var query = HttpUtility.ParseQueryString(uri.Query);
						string secret = query["secret"];
						if (string.IsNullOrEmpty(secret) == true)
						{
							throw new ApplicationException("Authenticator does not contain secret");
						}

						string counter = query["counter"];
						if (uri.Host == "hotp" && string.IsNullOrEmpty(counter) == true)
						{
							throw new ApplicationException("HOTP authenticator should have a counter");
						}

						WinAuthAuthenticator importedAuthenticator = new WinAuthAuthenticator();
						importedAuthenticator.AutoRefresh = false;
						//
						Authenticator auth;
						if (string.Compare(issuer, "BattleNet", true) == 0)
						{
							string serial = query["serial"];
							if (string.IsNullOrEmpty(serial) == true)
							{
								throw new ApplicationException("Battle.net Authenticator does not have a serial");
							}
							serial = serial.ToUpper();
							if (Regex.IsMatch(serial, @"^[A-Z]{2}-?[\d]{4}-?[\d]{4}-?[\d]{4}$") == false)
							{
								throw new ApplicationException("Invalid serial for Battle.net Authenticator");
							}
							auth = new BattleNetAuthenticator();
							//char[] decoded = Base32.getInstance().Decode(secret).Select(c => Convert.ToChar(c)).ToArray(); // this is hex string values
							//string hex = new string(decoded);
							//((BattleNetAuthenticator)auth).SecretKey = Authenticator.StringToByteArray(hex);

							((BattleNetAuthenticator)auth).SecretKey = Base32.getInstance().Decode(secret);

							((BattleNetAuthenticator)auth).Serial = serial;

							issuer = string.Empty;
						}
						else if (string.Compare(issuer, "Steam", true) == 0)
						{
							auth = new SteamAuthenticator();
							((SteamAuthenticator)auth).SecretKey = Base32.getInstance().Decode(secret);
							((SteamAuthenticator)auth).Serial = string.Empty;
							((SteamAuthenticator)auth).DeviceId = string.Empty;
							((SteamAuthenticator)auth).RevocationCode = string.Empty;
							issuer = string.Empty;
						}
						else if (uri.Host == "hotp")
						{
							auth = new HOTPAuthenticator();
							((HOTPAuthenticator)auth).SecretKey = Base32.getInstance().Decode(secret);
							((HOTPAuthenticator)auth).Counter = int.Parse(counter);
							
							if (string.IsNullOrEmpty(issuer) == false)
							{
								auth.Issuer = issuer;
							}
						}
						else // if (string.Compare(issuer, "Google", true) == 0)
						{
							auth = new GoogleAuthenticator();
							((GoogleAuthenticator)auth).Enroll(secret);

							if (string.Compare(issuer, "Google", true) == 0)
							{
								issuer = string.Empty;
							}
							else if (string.IsNullOrEmpty(issuer) == false)
							{
								auth.Issuer = issuer;
							}
						}
						//
						int digits = 0;
						int.TryParse(query["digits"], out digits);
						if (digits != 0)
						{
							auth.CodeDigits = digits;
						}
						//
						if (label.Length != 0)
						{
							importedAuthenticator.Name = (issuer.Length != 0 ? issuer + " (" + label + ")" : label);
						}
						else if (issuer.Length != 0)
						{
							importedAuthenticator.Name = issuer;
						}
						else
						{
							importedAuthenticator.Name = "Imported";
						}
						//
						importedAuthenticator.AuthenticatorData = auth;

						// set the icon
						string icon = query["icon"];
						if (string.IsNullOrEmpty(icon) == false)
						{
							if (icon.StartsWith("base64:") == true)
							{
								string b64 = Convert.ToBase64String(Base32.getInstance().Decode(icon.Substring(7)));
								importedAuthenticator.Skin = "base64:" + b64;
							}
							else
							{
								importedAuthenticator.Skin = icon + "Icon.png";
							}
						}

						// sync
						importedAuthenticator.Sync();

						authenticators.Add(importedAuthenticator);
					}
				}

				return authenticators;
			}
			catch (UriFormatException ex)
			{
				throw new ImportException(string.Format(strings.ImportInvalidUri, linenumber), ex);
			}
			catch (Exception ex)
			{
				throw new ImportException(string.Format(strings.ImportError, linenumber, ex.Message), ex);
			}
		}