diff --git a/src/net/i2p/android/i2ptunnel/activity/TunnelWizardModel.java b/src/net/i2p/android/i2ptunnel/activity/TunnelWizardModel.java
index 0f2651a722905032f12eeaa52ae25a51252d9169..27abeaf4ac5d11146287845408126e5e20b45023 100644
--- a/src/net/i2p/android/i2ptunnel/activity/TunnelWizardModel.java
+++ b/src/net/i2p/android/i2ptunnel/activity/TunnelWizardModel.java
@@ -6,6 +6,7 @@ import net.i2p.android.router.R;
 import net.i2p.android.wizard.model.AbstractWizardModel;
 import net.i2p.android.wizard.model.BranchPage;
 import net.i2p.android.wizard.model.Conditional;
+import net.i2p.android.wizard.model.I2PDestinationPage;
 import net.i2p.android.wizard.model.PageList;
 import net.i2p.android.wizard.model.SingleFixedBooleanPage;
 import net.i2p.android.wizard.model.SingleFixedChoicePage;
@@ -57,7 +58,7 @@ public class TunnelWizardModel extends AbstractWizardModel {
             new SingleTextFieldPage(this, res.getString(R.string.i2ptunnel_wizard_k_desc))
                 .setDescription(res.getString(R.string.i2ptunnel_wizard_desc_desc)),
 
-            new SingleTextFieldPage(this, res.getString(R.string.i2ptunnel_wizard_k_dest))
+            new I2PDestinationPage(this, res.getString(R.string.i2ptunnel_wizard_k_dest))
                 .setDescription(res.getString(R.string.i2ptunnel_wizard_desc_dest))
                 .setRequired(true)
                 .setEqualAnyCondition(cClientType,
diff --git a/src/net/i2p/android/wizard/model/I2PDestinationPage.java b/src/net/i2p/android/wizard/model/I2PDestinationPage.java
new file mode 100644
index 0000000000000000000000000000000000000000..4ca8e0b5bc7ec900e778a02266d21be751733c60
--- /dev/null
+++ b/src/net/i2p/android/wizard/model/I2PDestinationPage.java
@@ -0,0 +1,54 @@
+package net.i2p.android.wizard.model;
+
+import java.util.Locale;
+
+import net.i2p.data.DataFormatException;
+import net.i2p.data.Destination;
+
+/**
+ * A page asking for an I2P Destination.
+ * This could be a B64, B32 or Addressbook domain.
+ */
+public class I2PDestinationPage extends SingleTextFieldPage {
+    private static final int BASE32_HASH_LENGTH = 52;   // 1 + Hash.HASH_LENGTH * 8 / 5
+    private String mFeedback;
+
+    public I2PDestinationPage(ModelCallbacks callbacks, String title) {
+        super(callbacks, title);
+    }
+
+    @Override
+    public boolean isValid() {
+        String data = mData.getString(SIMPLE_DATA_KEY);
+        if (data.toLowerCase(Locale.US).endsWith(".b32.i2p")) { /* B32 */
+            if (data.length() != BASE32_HASH_LENGTH + 8) {
+                mFeedback = "Invalid B32";
+                return false;
+            }
+        } else if (data.endsWith(".i2p")) { /* Domain */
+            // Valid
+        } else if (data.length() >= 516) { /* B64 */
+            try {
+                new Destination().fromBase64(data);
+            } catch (DataFormatException dfe) {
+                mFeedback = "Invalid B64";
+                return false;
+            }
+        } else {
+            mFeedback = "Not a valid I2P Destination";
+            return false;
+        }
+        mFeedback = "";
+        return true;
+    }
+
+    @Override
+    public boolean showFeedback() {
+        return true;
+    }
+
+    @Override
+    public String getFeedback() {
+        return mFeedback;
+    }
+}