diff options
| author | Vincent Breitmoser <valodim@mugenguild.com> | 2015-01-14 18:32:50 +0100 | 
|---|---|---|
| committer | Vincent Breitmoser <valodim@mugenguild.com> | 2015-01-14 18:32:50 +0100 | 
| commit | c03bcc2799774cef4ac5f35ca6225059a13f45c8 (patch) | |
| tree | 31203131f1088a8e3577994453f8bedc4bf25d18 /OpenKeychain/src/main/java/org/sufficientlysecure | |
| parent | 55ea957644820cc56c71295f50bb04f1108236b0 (diff) | |
| download | open-keychain-c03bcc2799774cef4ac5f35ca6225059a13f45c8.tar.gz open-keychain-c03bcc2799774cef4ac5f35ca6225059a13f45c8.tar.bz2 open-keychain-c03bcc2799774cef4ac5f35ca6225059a13f45c8.zip  | |
work on dns resource, working (dummy) verification
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure')
6 files changed, 454 insertions, 66 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/AffirmationResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/AffirmationResource.java index ffe89931a..80398396e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/AffirmationResource.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/AffirmationResource.java @@ -64,7 +64,7 @@ public abstract class AffirmationResource {              return new LinkedVerifyResult(LinkedVerifyResult.RESULT_ERROR, log);          } -        Log.d(Constants.TAG, res); +        Log.d(Constants.TAG, "Resource data: '" + res + "'");          return verifyString(log, 1, res, nonce, fingerprint); @@ -72,19 +72,23 @@ public abstract class AffirmationResource {      protected abstract String fetchResource (OperationLog log, int indent); +    protected Matcher matchResource (OperationLog log, int indent, String res) { +        return magicPattern.matcher(res); +    } +      protected LinkedVerifyResult verifyString (OperationLog log, int indent,                                                 String res,                                                 String nonce, byte[] fingerprint) {          log.add(LogType.MSG_LV_MATCH, indent); -        Matcher match = magicPattern.matcher(res); +        Matcher match = matchResource(log, indent+1, res);          if (!match.find()) {              log.add(LogType.MSG_LV_MATCH_ERROR, 2);              return new LinkedVerifyResult(LinkedVerifyResult.RESULT_ERROR, log);          } -        String candidateFp = match.group(1); -        String nonceCandidate = match.group(2); +        String candidateFp = match.group(1).toLowerCase(); +        String nonceCandidate = match.group(2).toLowerCase();          String fp = KeyFormattingUtils.convertFingerprintToHex(fingerprint); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/LinkedIdentity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/LinkedIdentity.java index ee9933da3..00d898df9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/LinkedIdentity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/LinkedIdentity.java @@ -167,7 +167,7 @@ public class LinkedIdentity {          // return Hex.toHexString(data);          // debug for now -        return "0123456789ABCDEF01234567"; +        return "0123456789abcdef01234567";      }  } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/DnsResouce.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/DnsResouce.java deleted file mode 100644 index 20216972a..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/DnsResouce.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.sufficientlysecure.keychain.pgp.affirmation.resources; - -import android.content.Context; - -import org.sufficientlysecure.keychain.Constants; -import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; -import org.sufficientlysecure.keychain.pgp.affirmation.AffirmationResource; -import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; -import org.sufficientlysecure.keychain.util.Log; - -import java.net.URI; -import java.util.HashMap; -import java.util.Set; - -import de.measite.minidns.Client; -import de.measite.minidns.DNSMessage; -import de.measite.minidns.Question; -import de.measite.minidns.Record; -import de.measite.minidns.Record.TYPE; -import de.measite.minidns.record.TXT; - -public class DnsResouce extends AffirmationResource { - -    DnsResouce(Set<String> flags, HashMap<String,String> params, URI uri) { -        super(flags, params, uri); -    } - -    public static String generate (Context context, byte[] fingerprint, String nonce) { - -        return "pgpid+cookie:" -                + KeyFormattingUtils.convertFingerprintToHex(fingerprint) + ";" + nonce + ""; - -    } - -    @Override -    protected String fetchResource (OperationLog log, int indent) { - -        Client c = new Client(); -        DNSMessage msg = c.query(new Question("mugenguild.com", TYPE.TXT)); -        Record aw = msg.getAnswers()[0]; -        TXT txt = (TXT) aw.getPayload(); -        Log.d(Constants.TAG, txt.getText()); -        return txt.getText(); - -    } - -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/DnsResource.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/DnsResource.java new file mode 100644 index 000000000..272aa5dcd --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/pgp/affirmation/resources/DnsResource.java @@ -0,0 +1,70 @@ +package org.sufficientlysecure.keychain.pgp.affirmation.resources; + +import android.content.Context; + +import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog; +import org.sufficientlysecure.keychain.pgp.affirmation.AffirmationResource; +import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; + +import java.net.URI; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import de.measite.minidns.Client; +import de.measite.minidns.DNSMessage; +import de.measite.minidns.Question; +import de.measite.minidns.Record; +import de.measite.minidns.Record.TYPE; +import de.measite.minidns.record.TXT; + +public class DnsResource extends AffirmationResource { + +    static Pattern magicPattern = +            Pattern.compile("pgpid\\+cookie=([a-zA-Z0-9]+)(?:#|;)([a-zA-Z0-9]+)"); + +    DnsResource(Set<String> flags, HashMap<String, String> params, URI uri) { +        super(flags, params, uri); +    } + +    public static String generateText (Context context, byte[] fingerprint, String nonce) { + +        return "pgpid+cookie=" +                + KeyFormattingUtils.convertFingerprintToHex(fingerprint) + ";" + nonce + ""; + +    } + +    public static DnsResource createNew (String domain) { +        HashSet<String> flags = new HashSet<String>(); +        HashMap<String,String> params = new HashMap<String,String>(); +        URI uri = URI.create("dns:" + domain); +        return create(flags, params, uri); +    } + +    public static DnsResource create(Set<String> flags, HashMap<String,String> params, URI uri) { +        if ( ! ("dns".equals(uri.getScheme()) +                && (flags == null || flags.isEmpty()) +                && (params == null || params.isEmpty()))) { +            return null; +        } +        return new DnsResource(flags, params, uri); +    } + +    @Override +    protected String fetchResource (OperationLog log, int indent) { + +        Client c = new Client(); +        DNSMessage msg = c.query(new Question("mugenguild.com", TYPE.TXT)); +        Record aw = msg.getAnswers()[0]; +        TXT txt = (TXT) aw.getPayload(); +        return txt.getText().toLowerCase(); + +    } + +    @Override +    protected Matcher matchResource(OperationLog log, int indent, String res) { +        return magicPattern.matcher(res); +    } +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/affirmations/AffirmationCreateDnsStep1Fragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/affirmations/AffirmationCreateDnsStep1Fragment.java index 4b23f0f06..70258eb5a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/affirmations/AffirmationCreateDnsStep1Fragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/affirmations/AffirmationCreateDnsStep1Fragment.java @@ -30,13 +30,13 @@ import android.widget.EditText;  import org.sufficientlysecure.keychain.R;  import org.sufficientlysecure.keychain.pgp.affirmation.LinkedIdentity; -import org.sufficientlysecure.keychain.pgp.affirmation.resources.GenericHttpsResource; +import org.sufficientlysecure.keychain.pgp.affirmation.resources.DnsResource;  public class AffirmationCreateDnsStep1Fragment extends Fragment {      AffirmationWizard mAffirmationWizard; -    EditText mEditUri; +    EditText mEditDns;      /**       * Creates new instance of this fragment @@ -66,18 +66,19 @@ public class AffirmationCreateDnsStep1Fragment extends Fragment {              @Override              public void onClick(View v) { -                String uri = "https://" + mEditUri.getText(); +                String uri = mEditDns.getText().toString();                  if (!checkUri(uri)) { +                    mEditDns.setError("Please enter a valid domain name!");                      return;                  }                  String proofNonce = LinkedIdentity.generateNonce(); -                String proofText = GenericHttpsResource.generateText(getActivity(), +                String proofText = DnsResource.generateText(getActivity(),                          mAffirmationWizard.mFingerprint, proofNonce); -                AffirmationCreateHttpsStep2Fragment frag = -                        AffirmationCreateHttpsStep2Fragment.newInstance(uri, proofNonce, proofText); +                AffirmationCreateDnsStep2Fragment frag = +                        AffirmationCreateDnsStep2Fragment.newInstance(uri, proofNonce, proofText);                  mAffirmationWizard.loadFragment(null, frag, AffirmationWizard.FRAG_ACTION_TO_RIGHT); @@ -91,9 +92,9 @@ public class AffirmationCreateDnsStep1Fragment extends Fragment {              }          }); -        mEditUri = (EditText) view.findViewById(R.id.affirmation_create_https_uri); +        mEditDns = (EditText) view.findViewById(R.id.affirmation_create_dns_domain); -        mEditUri.addTextChangedListener(new TextWatcher() { +        mEditDns.addTextChangedListener(new TextWatcher() {              @Override              public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {              } @@ -104,29 +105,29 @@ public class AffirmationCreateDnsStep1Fragment extends Fragment {              @Override              public void afterTextChanged(Editable editable) { -                String uri = "https://" + editable; +                String uri = editable.toString();                  if (uri.length() > 0) {                      if (checkUri(uri)) { -                        mEditUri.setCompoundDrawablesWithIntrinsicBounds(0, 0, +                        mEditDns.setCompoundDrawablesWithIntrinsicBounds(0, 0,                                  R.drawable.uid_mail_ok, 0);                      } else { -                        mEditUri.setCompoundDrawablesWithIntrinsicBounds(0, 0, +                        mEditDns.setCompoundDrawablesWithIntrinsicBounds(0, 0,                                  R.drawable.uid_mail_bad, 0);                      }                  } else {                      // remove drawable if email is empty -                    mEditUri.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); +                    mEditDns.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);                  }              }          }); -        mEditUri.setText("mugenguild.com/pgpkey.txt"); +        mEditDns.setText("mugenguild.com");          return view;      }      private static boolean checkUri(String uri) { -        return Patterns.WEB_URL.matcher(uri).matches(); +        return Patterns.DOMAIN_NAME.matcher(uri).matches();      }  } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/affirmations/AffirmationCreateDnsStep2Fragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/affirmations/AffirmationCreateDnsStep2Fragment.java new file mode 100644 index 000000000..87568ddc2 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/affirmations/AffirmationCreateDnsStep2Fragment.java @@ -0,0 +1,360 @@ +/* + * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.ui.affirmations; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Intent; +import android.graphics.PorterDuff; +import android.net.Uri; +import android.os.AsyncTask; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.os.Message; +import android.os.Messenger; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; + +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.operations.results.LinkedVerifyResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult; +import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute; +import org.sufficientlysecure.keychain.pgp.affirmation.LinkedIdentity; +import org.sufficientlysecure.keychain.pgp.affirmation.resources.DnsResource; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import org.sufficientlysecure.keychain.ui.PassphraseDialogActivity; +import org.sufficientlysecure.keychain.ui.util.Notify; +import org.sufficientlysecure.keychain.ui.util.Notify.Style; +import org.sufficientlysecure.keychain.util.FileHelper; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.PrintWriter; + +public class AffirmationCreateDnsStep2Fragment extends Fragment { + +    private static final int REQUEST_CODE_OUTPUT = 0x00007007; +    private static final int REQUEST_CODE_PASSPHRASE = 0x00007008; + +    public static final String DOMAIN = "domain", NONCE = "nonce", TEXT = "text"; + +    AffirmationWizard mAffirmationWizard; + +    EditText mEditUri; +    ImageView mVerifyImage; +    View mVerifyProgress; +    TextView mVerifyStatus; + +    String mResourceDomain; +    String mResourceNonce, mResourceString; + +    // This is a resource, set AFTER it has been verified +    DnsResource mVerifiedResource = null; + +    /** +     * Creates new instance of this fragment +     */ +    public static AffirmationCreateDnsStep2Fragment newInstance +            (String uri, String proofNonce, String proofText) { + +        AffirmationCreateDnsStep2Fragment frag = new AffirmationCreateDnsStep2Fragment(); + +        Bundle args = new Bundle(); +        args.putString(DOMAIN, uri); +        args.putString(NONCE, proofNonce); +        args.putString(TEXT, proofText); +        frag.setArguments(args); + +        return frag; +    } + +    @Override +    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { +        final View view = inflater.inflate(R.layout.affirmation_create_dns_fragment_step2, container, false); + +        mResourceDomain = getArguments().getString(DOMAIN); +        mResourceNonce = getArguments().getString(NONCE); +        mResourceString = getArguments().getString(TEXT); + +        view.findViewById(R.id.next_button).setOnClickListener(new OnClickListener() { +            @Override +            public void onClick(View v) { +                startCertify(); +            } +        }); + +        view.findViewById(R.id.back_button).setOnClickListener(new OnClickListener() { +            @Override +            public void onClick(View v) { +                mAffirmationWizard.loadFragment(null, null, AffirmationWizard.FRAG_ACTION_TO_LEFT); +            } +        }); + +        mVerifyImage = (ImageView) view.findViewById(R.id.verify_image); +        mVerifyProgress = view.findViewById(R.id.verify_progress); +        mVerifyStatus = (TextView) view.findViewById(R.id.verify_status); + +        view.findViewById(R.id.button_send).setOnClickListener(new OnClickListener() { +            @Override +            public void onClick(View v) { +                proofSend(); +            } +        }); + +        view.findViewById(R.id.button_save).setOnClickListener(new OnClickListener() { +            @Override +            public void onClick(View v) { +                proofSave(); +            } +        }); + +        view.findViewById(R.id.button_verify).setOnClickListener(new OnClickListener() { +            @Override +            public void onClick(View v) { +                proofVerify(); +            } +        }); + +        mEditUri = (EditText) view.findViewById(R.id.affirmation_create_dns_text); +        mEditUri.setText(mResourceString); + +        setVerifyProgress(false, null); +        mVerifyStatus.setText(R.string.linked_verify_pending); + +        return view; +    } + +    @Override +    public void onActivityCreated(Bundle savedInstanceState) { +        super.onActivityCreated(savedInstanceState); + +        mAffirmationWizard = (AffirmationWizard) getActivity(); +    } + +    public void setVerifyProgress(boolean on, Boolean success) { +        mVerifyProgress.setVisibility(on ? View.VISIBLE : View.GONE); +        mVerifyImage.setVisibility(on ? View.GONE : View.VISIBLE); +        if (success == null) { +            mVerifyStatus.setText(R.string.linked_verifying); +            mVerifyImage.setImageResource(R.drawable.status_signature_unverified_cutout); +            mVerifyImage.setColorFilter(getResources().getColor(R.color.tertiary_text_light), +                    PorterDuff.Mode.SRC_IN); +        } else if (success) { +            mVerifyStatus.setText(R.string.linked_verify_success); +            mVerifyImage.setImageResource(R.drawable.status_signature_verified_cutout); +            mVerifyImage.setColorFilter(getResources().getColor(R.color.android_green_dark), +                    PorterDuff.Mode.SRC_IN); +        } else { +            mVerifyStatus.setText(R.string.linked_verify_error); +            mVerifyImage.setImageResource(R.drawable.status_signature_unknown_cutout); +            mVerifyImage.setColorFilter(getResources().getColor(R.color.android_red_dark), +                    PorterDuff.Mode.SRC_IN); +        } +    } + +    private void proofSend () { +        Intent sendIntent = new Intent(); +        sendIntent.setAction(Intent.ACTION_SEND); +        sendIntent.putExtra(Intent.EXTRA_TEXT, mResourceString); +        sendIntent.setType("text/plain"); +        startActivity(sendIntent); +    } + +    private void proofSave () { +        String state = Environment.getExternalStorageState(); +        if (!Environment.MEDIA_MOUNTED.equals(state)) { +            Notify.showNotify(getActivity(), "External storage not available!", Style.ERROR); +            return; +        } + +        String targetName = "pgpkey.txt"; + +        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { +            File targetFile = new File(Constants.Path.APP_DIR, targetName); +            FileHelper.saveFile(this, getString(R.string.title_decrypt_to_file), +                    getString(R.string.specify_file_to_decrypt_to), targetFile, REQUEST_CODE_OUTPUT); +        } else { +            FileHelper.saveDocument(this, "text/plain", targetName, REQUEST_CODE_OUTPUT); +        } +    } + +    private void saveFile(Uri uri) { +        try { +            PrintWriter out = +                    new PrintWriter(getActivity().getContentResolver().openOutputStream(uri)); +            out.print(mResourceString); +            if (out.checkError()) { +                Notify.showNotify(getActivity(), "Error writing file!", Style.ERROR); +            } +        } catch (FileNotFoundException e) { +            Notify.showNotify(getActivity(), "File could not be opened for writing!", Style.ERROR); +            e.printStackTrace(); +        } +    } + +    public void proofVerify() { +        setVerifyProgress(true, null); + +        final DnsResource resource = DnsResource.createNew(mResourceDomain); + +        new AsyncTask<Void,Void,LinkedVerifyResult>() { + +            @Override +            protected LinkedVerifyResult doInBackground(Void... params) { +                return resource.verify(mAffirmationWizard.mFingerprint, mResourceNonce); +            } + +            @Override +            protected void onPostExecute(LinkedVerifyResult result) { +                super.onPostExecute(result); +                if (result.success()) { +                    setVerifyProgress(false, true); +                    mVerifiedResource = resource; +                } else { +                    setVerifyProgress(false, false); +                    // on error, show error message +                    result.createNotify(getActivity()).show(); +                } +            } +        }.execute(); + +    } + +    public void startCertify() { + +        if (mVerifiedResource == null) { +            Notify.showNotify(getActivity(), R.string.linked_need_verify, Style.ERROR); +            return; +        } + +        Intent intent = new Intent(getActivity(), PassphraseDialogActivity.class); +        intent.putExtra(PassphraseDialogActivity.EXTRA_SUBKEY_ID, mAffirmationWizard.mMasterKeyId); +        startActivityForResult(intent, REQUEST_CODE_PASSPHRASE); + +    } + +    public void certifyLinkedIdentity (String passphrase) { +        KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler( +                getActivity(), +                getString(R.string.progress_saving), +                ProgressDialog.STYLE_HORIZONTAL, +                true) { +            public void handleMessage(Message message) { +                // handle messages by standard KeychainIntentServiceHandler first +                super.handleMessage(message); + +                if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { + +                    // get returned data bundle +                    Bundle returnData = message.getData(); +                    if (returnData == null) { +                        return; +                    } +                    final OperationResult result = +                            returnData.getParcelable(OperationResult.EXTRA_RESULT); +                    if (result == null) { +                        return; +                    } + +                    // if bad -> display here! +                    if (!result.success()) { +                        result.createNotify(getActivity()).show(); +                        return; +                    } + +                    result.createNotify(getActivity()).show(); + +                    // if good -> finish, return result to showkey and display there! +                    // Intent intent = new Intent(); +                    // intent.putExtra(OperationResult.EXTRA_RESULT, result); +                    // getActivity().setResult(EditKeyActivity.RESULT_OK, intent); + +                    // AffirmationCreateHttpsStep3Fragment frag = +                    // AffirmationCreateHttpsStep3Fragment.newInstance( +                    // mResourceDomain, mResourceNonce, mResourceString); + +                    // mAffirmationWizard.loadFragment(null, frag, AffirmationWizard.FRAG_ACTION_TO_RIGHT); + +                } +            } +        }; + +        SaveKeyringParcel skp = +                new SaveKeyringParcel(mAffirmationWizard.mMasterKeyId, mAffirmationWizard.mFingerprint); + +        WrappedUserAttribute ua = +                LinkedIdentity.fromResource(mVerifiedResource, mResourceNonce).toUserAttribute(); + +        skp.mAddUserAttribute.add(ua); + +        // Send all information needed to service to import key in other thread +        Intent intent = new Intent(getActivity(), KeychainIntentService.class); +        intent.setAction(KeychainIntentService.ACTION_EDIT_KEYRING); + +        // fill values for this action +        Bundle data = new Bundle(); +        data.putString(KeychainIntentService.EDIT_KEYRING_PASSPHRASE, passphrase); +        data.putParcelable(KeychainIntentService.EDIT_KEYRING_PARCEL, skp); +        intent.putExtra(KeychainIntentService.EXTRA_DATA, data); + +        // Create a new Messenger for the communication back +        Messenger messenger = new Messenger(saveHandler); +        intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); + +        // show progress dialog +        saveHandler.showProgressDialog(getActivity()); + +        // start service with intent +        getActivity().startService(intent); + +    } + + +    @Override +    public void onActivityResult(int requestCode, int resultCode, Intent data) { +        switch (requestCode) { +            // For saving a file +            case REQUEST_CODE_OUTPUT: +                if (data == null) { +                    return; +                } +                Uri uri = data.getData(); +                saveFile(uri); +                break; +            case REQUEST_CODE_PASSPHRASE: +                if (resultCode == Activity.RESULT_OK && data != null) { +                    String passphrase = +                            data.getStringExtra(PassphraseDialogActivity.MESSAGE_DATA_PASSPHRASE); +                    certifyLinkedIdentity(passphrase); +                } +                break; +        } +        super.onActivityResult(requestCode, resultCode, data); +    } + +}  | 
