From 26fca259bcf5afce657fee07d07a0d58191d42b7 Mon Sep 17 00:00:00 2001 From: Christian Basler Date: Sun, 16 Apr 2017 22:38:11 +0200 Subject: [PATCH] Alternative key exchange by providing the public key in the URI --- .../apps/abit/AddressDetailFragment.java | 16 +++++ .../apps/abit/CreateAddressActivity.java | 58 +++++++++++++++++-- 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/ch/dissem/apps/abit/AddressDetailFragment.java b/app/src/main/java/ch/dissem/apps/abit/AddressDetailFragment.java index 40b2410..95ce443 100644 --- a/app/src/main/java/ch/dissem/apps/abit/AddressDetailFragment.java +++ b/app/src/main/java/ch/dissem/apps/abit/AddressDetailFragment.java @@ -26,6 +26,7 @@ import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.text.Editable; import android.text.TextWatcher; +import android.util.Base64; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -48,13 +49,18 @@ import com.mikepenz.google_material_typeface_library.GoogleMaterial; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + import ch.dissem.apps.abit.service.Singleton; import ch.dissem.apps.abit.util.Drawables; import ch.dissem.bitmessage.entity.BitmessageAddress; +import ch.dissem.bitmessage.exception.ApplicationException; import ch.dissem.bitmessage.wif.WifExporter; import static android.graphics.Color.BLACK; import static android.graphics.Color.WHITE; +import static android.util.Base64.URL_SAFE; /** @@ -269,6 +275,16 @@ public class AddressDetailFragment extends Fragment { if (address.getAlias() != null) { link.append("?label=").append(address.getAlias()); } + if (address.getPubkey() != null) { + link.append(address.getAlias() == null ? '?' : '&'); + ByteArrayOutputStream pubkey = new ByteArrayOutputStream(); + try { + address.getPubkey().writeUnencrypted(pubkey); + } catch (IOException e) { + throw new ApplicationException(e); + } + link.append("pubkey=").append(Base64.encodeToString(pubkey.toByteArray(), URL_SAFE)); + } BitMatrix result; try { result = new MultiFormatWriter().encode(link.toString(), diff --git a/app/src/main/java/ch/dissem/apps/abit/CreateAddressActivity.java b/app/src/main/java/ch/dissem/apps/abit/CreateAddressActivity.java index cf5d51f..27d344d 100644 --- a/app/src/main/java/ch/dissem/apps/abit/CreateAddressActivity.java +++ b/app/src/main/java/ch/dissem/apps/abit/CreateAddressActivity.java @@ -20,17 +20,32 @@ import android.app.Activity; import android.net.Uri; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; +import android.util.Base64; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Switch; import android.widget.TextView; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import ch.dissem.apps.abit.service.Singleton; import ch.dissem.bitmessage.BitmessageContext; import ch.dissem.bitmessage.entity.BitmessageAddress; +import ch.dissem.bitmessage.entity.payload.Pubkey; +import ch.dissem.bitmessage.entity.payload.V2Pubkey; +import ch.dissem.bitmessage.entity.payload.V3Pubkey; +import ch.dissem.bitmessage.entity.payload.V4Pubkey; + +import static android.util.Base64.URL_SAFE; public class CreateAddressActivity extends AppCompatActivity { + private static final Pattern KEY_VALUE_PATTERN = Pattern.compile("^([a-zA-Z]+)=(.*)$"); + private byte[] pubkeyBytes; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -48,12 +63,19 @@ public class CreateAddressActivity extends AppCompatActivity { String addressText = getAddress(uri); String[] parameters = getParameters(uri); for (String parameter : parameters) { - String name = parameter.substring(0, 6).toLowerCase(); - if (name.startsWith("label")) { - label.setText(parameter.substring(parameter.indexOf('=') + 1).trim()); - } else if (name.startsWith("action")) { - parameter = parameter.toLowerCase(); - subscribe.setChecked(parameter.contains("subscribe")); + Matcher matcher = KEY_VALUE_PATTERN.matcher(parameter); + String key = matcher.group(1).toLowerCase(); + String value = matcher.group(2); + switch (key) { + case "label": + label.setText(value.trim()); + break; + case "action": + subscribe.setChecked(value.trim().equalsIgnoreCase("subscribe")); + break; + case "pubkey": + pubkeyBytes = Base64.decode(value, URL_SAFE); + break; } } @@ -83,6 +105,30 @@ public class CreateAddressActivity extends AppCompatActivity { if (subscribe.isChecked()) { bmc.addSubscribtion(bmAddress); } + if (pubkeyBytes != null) { + try { + final Pubkey pubkey; + InputStream pubkeyStream = new ByteArrayInputStream(pubkeyBytes); + long stream = bmAddress.getStream(); + switch ((int) bmAddress.getVersion()) { + case 2: + pubkey = V2Pubkey.read(pubkeyStream, stream); + break; + case 3: + pubkey = V3Pubkey.read(pubkeyStream, stream); + break; + case 4: + pubkey = new V4Pubkey(V3Pubkey.read(pubkeyStream, stream)); + break; + default: + pubkey = null; + } + if (pubkey != null) { + bmAddress.setPubkey(pubkey); + } + } catch (Exception ignore) { + } + } setResult(Activity.RESULT_OK); finish();