share fingerprint with qr code

This commit is contained in:
Dominik Schürmann 2014-01-19 01:15:25 +01:00
parent 88aa439ea7
commit a966d1afa1
6 changed files with 79 additions and 33 deletions

View File

@ -9,7 +9,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="8dp" android:padding="8dp"
android:text="@string/share_qr_code_dialog_start"
android:textAppearance="@android:style/TextAppearance.Medium" /> android:textAppearance="@android:style/TextAppearance.Medium" />
<ImageView <ImageView

View File

@ -11,6 +11,10 @@
android:id="@+id/menu_key_view_share_default" android:id="@+id/menu_key_view_share_default"
android:showAsAction="never" android:showAsAction="never"
android:title="@string/menu_share"/> android:title="@string/menu_share"/>
<item
android:id="@+id/menu_key_view_share_qr_code_fingerprint"
android:showAsAction="never"
android:title="@string/menu_share_qr_code_fingerprint"/>
<item <item
android:id="@+id/menu_key_view_share_qr_code" android:id="@+id/menu_key_view_share_qr_code"
android:showAsAction="never" android:showAsAction="never"

View File

@ -43,7 +43,7 @@
<string name="section_signing_key">Your Key used for Signing</string> <string name="section_signing_key">Your Key used for Signing</string>
<string name="section_upload_key">Upload Key</string> <string name="section_upload_key">Upload Key</string>
<string name="section_key_server">Key Server</string> <string name="section_key_server">Key Server</string>
<!-- button --> <!-- button -->
<string name="btn_sign_to_clipboard">Sign (Clipboard)</string> <string name="btn_sign_to_clipboard">Sign (Clipboard)</string>
<string name="btn_encrypt_to_clipboard">Encrypt to Clipboard</string> <string name="btn_encrypt_to_clipboard">Encrypt to Clipboard</string>
@ -85,7 +85,8 @@
<string name="menu_update_key">Update from key server</string> <string name="menu_update_key">Update from key server</string>
<string name="menu_export_key_to_server">Upload to key server</string> <string name="menu_export_key_to_server">Upload to key server</string>
<string name="menu_share">Share with…</string> <string name="menu_share">Share with…</string>
<string name="menu_share_qr_code">Share with QR Code</string> <string name="menu_share_qr_code">Share with QR Code (whole key)</string>
<string name="menu_share_qr_code_fingerprint">Share with QR Code (fingerprint)</string>
<string name="menu_share_nfc">Share with NFC</string> <string name="menu_share_nfc">Share with NFC</string>
<string name="menu_copy_to_clipboard">Copy to clipboard</string> <string name="menu_copy_to_clipboard">Copy to clipboard</string>
<string name="menu_sign_key">Sign key</string> <string name="menu_sign_key">Sign key</string>
@ -353,7 +354,9 @@
<string name="api_error_wrong_signature">Signature check failed! Have you installed this app from a different source? If you are sure that this is not an attack, revoke this app\'s registration in OpenPGP Keychain and then register the app again.</string> <string name="api_error_wrong_signature">Signature check failed! Have you installed this app from a different source? If you are sure that this is not an attack, revoke this app\'s registration in OpenPGP Keychain and then register the app again.</string>
<!-- Share --> <!-- Share -->
<string name="share_qr_code_dialog_title">Share with QR Code</string>
<string name="share_qr_code_dialog_start">Go through all QR Codes using \'Next\', and scan them one by one.</string> <string name="share_qr_code_dialog_start">Go through all QR Codes using \'Next\', and scan them one by one.</string>
<string name="share_qr_code_dialog_fingerprint_text">Fingerprint:</string>
<string name="share_qr_code_dialog_progress">QR Code with ID %1$d of %2$d</string> <string name="share_qr_code_dialog_progress">QR Code with ID %1$d of %2$d</string>
<string name="share_nfc_dialog">Share with NFC</string> <string name="share_nfc_dialog">Share with NFC</string>

View File

@ -454,6 +454,12 @@ public class PgpKeyHelper {
return algorithmStr + ", " + keySize + " bit"; return algorithmStr + ", " + keySize + " bit";
} }
/**
* Converts fingerprint to hex with whitespaces after 4 characters
*
* @param fp
* @return
*/
public static String convertFingerprintToHex(byte[] fp) { public static String convertFingerprintToHex(byte[] fp) {
String fingerPrint = ""; String fingerPrint = "";
for (int i = 0; i < fp.length; ++i) { for (int i = 0; i < fp.length; ++i) {

View File

@ -169,8 +169,11 @@ public class ViewKeyActivity extends SherlockFragmentActivity implements CreateN
case R.id.menu_key_view_share_default: case R.id.menu_key_view_share_default:
shareKey(mDataUri); shareKey(mDataUri);
return true; return true;
case R.id.menu_key_view_share_qr_code_fingerprint:
shareKeyQrCode(mDataUri, true);
return true;
case R.id.menu_key_view_share_qr_code: case R.id.menu_key_view_share_qr_code:
shareKeyQrCode(mDataUri); shareKeyQrCode(mDataUri, false);
return true; return true;
case R.id.menu_key_view_share_nfc: case R.id.menu_key_view_share_nfc:
shareNfc(); shareNfc();
@ -318,10 +321,12 @@ public class ViewKeyActivity extends SherlockFragmentActivity implements CreateN
// the first key here is our master key // the first key here is our master key
if (data.moveToFirst()) { if (data.moveToFirst()) {
// get key id from MASTER_KEY_ID // get key id from MASTER_KEY_ID
String keyId = "0x" long keyId = data.getLong(KEYS_INDEX_KEY_ID);
+ PgpKeyHelper.convertKeyIdToHex(data.getLong(KEYS_INDEX_KEY_ID));
mKeyId.setText(keyId);
String keyIdStr = "0x" + PgpKeyHelper.convertKeyIdToHex(keyId);
mKeyId.setText(keyIdStr);
// get creation date from CREATION
if (data.isNull(KEYS_INDEX_CREATION)) { if (data.isNull(KEYS_INDEX_CREATION)) {
mCreation.setText(R.string.none); mCreation.setText(R.string.none);
} else { } else {
@ -331,6 +336,7 @@ public class ViewKeyActivity extends SherlockFragmentActivity implements CreateN
creationDate)); creationDate));
} }
// get creation date from EXPIRY
if (data.isNull(KEYS_INDEX_EXPIRY)) { if (data.isNull(KEYS_INDEX_EXPIRY)) {
mExpiry.setText(R.string.none); mExpiry.setText(R.string.none);
} else { } else {
@ -344,14 +350,9 @@ public class ViewKeyActivity extends SherlockFragmentActivity implements CreateN
data.getInt(KEYS_INDEX_ALGORITHM), data.getInt(KEYS_INDEX_KEY_SIZE)); data.getInt(KEYS_INDEX_ALGORITHM), data.getInt(KEYS_INDEX_KEY_SIZE));
mAlgorithm.setText(algorithmStr); mAlgorithm.setText(algorithmStr);
// TODO: Don't get key object here!!! // TODO: Can this be done better? fingerprint in db?
// put fingerprint in database? String fingerprint = PgpKeyHelper.getFingerPrint(this, keyId);
PGPPublicKeyRing ring = (PGPPublicKeyRing) ProviderHelper.getPGPKeyRing(this,
mDataUri);
PGPPublicKey publicKey = ring.getPublicKey();
String fingerprint = PgpKeyHelper.convertFingerprintToHex(publicKey
.getFingerprint());
fingerprint = fingerprint.replace(" ", "\n"); fingerprint = fingerprint.replace(" ", "\n");
mFingerprint.setText(fingerprint); mFingerprint.setText(fingerprint);
@ -448,14 +449,9 @@ public class ViewKeyActivity extends SherlockFragmentActivity implements CreateN
getResources().getText(R.string.action_share_key_with))); getResources().getText(R.string.action_share_key_with)));
} }
private void shareKeyQrCode(Uri dataUri) { private void shareKeyQrCode(Uri dataUri, boolean fingerprintOnly) {
// get public keyring as ascii armored string ShareQrCodeDialogFragment dialog = ShareQrCodeDialogFragment.newInstance(dataUri,
long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri); fingerprintOnly);
ArrayList<String> keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(this, dataUri,
new long[] { masterKeyId });
ShareQrCodeDialogFragment dialog = ShareQrCodeDialogFragment.newInstance(keyringArmored
.get(0));
dialog.show(getSupportFragmentManager(), "shareQrCodeDialog"); dialog.show(getSupportFragmentManager(), "shareQrCodeDialog");
} }

View File

@ -19,12 +19,17 @@ package org.sufficientlysecure.keychain.ui.dialog;
import java.util.ArrayList; import java.util.ArrayList;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.QrCodeUtils; import org.sufficientlysecure.keychain.util.QrCodeUtils;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -35,7 +40,8 @@ import android.widget.TextView;
import com.actionbarsherlock.app.SherlockDialogFragment; import com.actionbarsherlock.app.SherlockDialogFragment;
public class ShareQrCodeDialogFragment extends SherlockDialogFragment { public class ShareQrCodeDialogFragment extends SherlockDialogFragment {
private static final String ARG_CONTENT = "content"; private static final String ARG_URI = "uri";
private static final String ARG_FINGERPRINT_ONLY = "fingerprint_only";
private ImageView mImage; private ImageView mImage;
private TextView mText; private TextView mText;
@ -52,10 +58,11 @@ public class ShareQrCodeDialogFragment extends SherlockDialogFragment {
* Content to be shared via QR Codes * Content to be shared via QR Codes
* @return * @return
*/ */
public static ShareQrCodeDialogFragment newInstance(String content) { public static ShareQrCodeDialogFragment newInstance(Uri dataUri, boolean fingerprintOnly) {
ShareQrCodeDialogFragment frag = new ShareQrCodeDialogFragment(); ShareQrCodeDialogFragment frag = new ShareQrCodeDialogFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putString(ARG_CONTENT, content); args.putParcelable(ARG_URI, dataUri);
args.putBoolean(ARG_FINGERPRINT_ONLY, fingerprintOnly);
frag.setArguments(args); frag.setArguments(args);
@ -69,12 +76,12 @@ public class ShareQrCodeDialogFragment extends SherlockDialogFragment {
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
final Activity activity = getActivity(); final Activity activity = getActivity();
String content = getArguments().getString(ARG_CONTENT); Uri dataUri = getArguments().getParcelable(ARG_URI);
mContentList = splitString(content, 1000); boolean fingerprintOnly = getArguments().getBoolean(ARG_FINGERPRINT_ONLY);
AlertDialog.Builder alert = new AlertDialog.Builder(activity); AlertDialog.Builder alert = new AlertDialog.Builder(activity);
alert.setTitle(R.string.menu_share_qr_code); alert.setTitle(R.string.share_qr_code_dialog_title);
LayoutInflater inflater = activity.getLayoutInflater(); LayoutInflater inflater = activity.getLayoutInflater();
View view = inflater.inflate(R.layout.share_qr_code_dialog, null); View view = inflater.inflate(R.layout.share_qr_code_dialog, null);
@ -83,15 +90,46 @@ public class ShareQrCodeDialogFragment extends SherlockDialogFragment {
mImage = (ImageView) view.findViewById(R.id.share_qr_code_dialog_image); mImage = (ImageView) view.findViewById(R.id.share_qr_code_dialog_image);
mText = (TextView) view.findViewById(R.id.share_qr_code_dialog_text); mText = (TextView) view.findViewById(R.id.share_qr_code_dialog_text);
// TODO
long masterKeyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri);
String content = null;
if (fingerprintOnly) {
content = "openpgp4fpr:";
String fingerprint = PgpKeyHelper.convertKeyToHex(masterKeyId);
mText.setText(getString(R.string.share_qr_code_dialog_fingerprint_text) + " "
+ fingerprint);
content = content + fingerprint;
Log.d(Constants.TAG, "content: " + content);
alert.setPositiveButton(R.string.btn_okay, null);
} else {
mText.setText(R.string.share_qr_code_dialog_start);
// get public keyring as ascii armored string
ArrayList<String> keyringArmored = ProviderHelper.getKeyRingsAsArmoredString(
getActivity(), dataUri, new long[] { masterKeyId });
// TODO: binary?
content = keyringArmored.get(0);
// OnClickListener are set in onResume to prevent automatic dismissing of Dialogs
// http://stackoverflow.com/questions/2620444/how-to-prevent-a-dialog-from-closing-when-a-button-is-clicked
alert.setPositiveButton(R.string.btn_next, null);
alert.setNegativeButton(android.R.string.cancel, null);
}
mContentList = splitString(content, 1000);
// start with first // start with first
mCounter = 0; mCounter = 0;
updateQrCode(); updateQrCode();
// OnClickListener are set in onResume to prevent automatic dismissing of Dialogs
// http://stackoverflow.com/questions/2620444/how-to-prevent-a-dialog-from-closing-when-a-button-is-clicked
alert.setPositiveButton(R.string.btn_next, null);
alert.setNegativeButton(android.R.string.cancel, null);
return alert.create(); return alert.create();
} }