org.riksa.a3.fragment.ImportKeyPairFragment.java Source code

Java tutorial

Introduction

Here is the source code for org.riksa.a3.fragment.ImportKeyPairFragment.java

Source

/*
 * This file is part of A3 - Android Authentication Agent
 * Copyright (c) 2012. riku salkia <riksa@iki.fi>
 * TODO: License ;)
 */

package org.riksa.a3.fragment;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import org.riksa.a3.R;
import org.riksa.a3.exception.ViewNotFoundException;
import org.riksa.a3.util.A3Utils;
import org.riksa.a3.util.LoggerFactory;
import org.riksa.a3.util.PrivateKeyFactory;
import org.slf4j.Logger;

import java.io.*;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;

/**
 * User: riksa
 * Date: 19.10.2012
 * Time: 20:15
 */
public class ImportKeyPairFragment extends Fragment {
    private static final Logger log = LoggerFactory.getLogger(ImportKeyPairFragment.class);
    private static final int BROWSE_PRIVATE = 1;
    private static final int BROWSE_PUBLIC = 2;
    public static final String ORG_OPENINTENTS_ACTION_PICK_FILE = "org.openintents.action.PICK_FILE";
    private static final int MAX_KEY_SIZE = 1024 * 2 * 17; // some reasonable upper limits for bytes in key so that we don't even try to validate ridiculously large keys. 17kB (hex encoded) ought to be enough for everyone

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_import_keypair, container, false);
    }

    @Override
    public void onResume() {
        super.onResume();
        try {
            A3Utils.findView(getActivity(), Button.class, R.id.pk_btn_browse_private)
                    .setOnClickListener(new View.OnClickListener() {
                        public void onClick(View view) {
                            onBrowsePrivateClicked(view);
                        }
                    });
            A3Utils.findView(getActivity(), Button.class, R.id.pk_btn_browse_public)
                    .setOnClickListener(new View.OnClickListener() {
                        public void onClick(View view) {
                            onBrowsePublicClicked(view);
                        }
                    });

            EditText privateKeyEditText = A3Utils.findView(getActivity(), EditText.class, R.id.pk_private_key_path);
            privateKeyEditText.addTextChangedListener(new TextWatcher() {
                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                    //To change body of implemented methods use File | Settings | File Templates.
                }

                public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                    validateKeys();
                }

                public void afterTextChanged(Editable editable) {
                    //To change body of implemented methods use File | Settings | File Templates.
                }
            });

            EditText publicKeyEditText = A3Utils.findView(getActivity(), EditText.class, R.id.pk_public_key_path);
            publicKeyEditText.addTextChangedListener(new TextWatcher() {
                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                    //To change body of implemented methods use File | Settings | File Templates.
                }

                public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                    validateKeys();
                }

                public void afterTextChanged(Editable editable) {
                    //To change body of implemented methods use File | Settings | File Templates.
                }
            });

        } catch (ViewNotFoundException e) {
            log.error(e.getMessage(), e);
        }
    }

    void validateKeys() {
        try {
            Button importButton = A3Utils.findView(getActivity(), Button.class, R.id.pk_btn_import);
            importButton.setEnabled(false);
            EditText privateEdit = A3Utils.findView(getActivity(), EditText.class, R.id.pk_private_key_path);
            EditText publicEdit = A3Utils.findView(getActivity(), EditText.class, R.id.pk_public_key_path);
            if (validatePrivateKey(privateEdit.getText().toString())
                    && validatePublicKey(publicEdit.getText().toString())) {
                importButton.setEnabled(true);
            }
        } catch (ViewNotFoundException e) {
            log.error(e.getMessage(), e);
        }
    }

    private boolean validatePrivateKey(String keyString) throws ViewNotFoundException {
        ImageView imageView = A3Utils.findView(getActivity(), ImageView.class, R.id.pk_icon_private_key_valid);
        TextView textView = A3Utils.findView(getActivity(), TextView.class, R.id.pk_text_private_key_valid);
        textView.setText(R.string.pk_text_private_key_invalid);
        imageView.setImageResource(R.drawable.btn_check_buttonless_off);
        if (keyString == null || keyString.length() == 0) {
            return false;
        }

        log.debug("privateKey={}", keyString);

        PrivateKey privateKey = PrivateKeyFactory.createPrivateKey(keyString.getBytes());
        if (privateKey == null) {
            return false;
        }

        String algorithm = privateKey.getAlgorithm();
        int bits = PrivateKeyFactory.getBits(privateKey);
        textView.setText(getString(R.string.pk_text_private_key_valid, algorithm, bits));
        imageView.setImageResource(R.drawable.btn_check_buttonless_on);
        return true;

    }

    private boolean validatePublicKey(String publicKey) throws ViewNotFoundException {
        ImageView imageView = A3Utils.findView(getActivity(), ImageView.class, R.id.pk_icon_public_key_valid);
        TextView textView = A3Utils.findView(getActivity(), TextView.class, R.id.pk_text_public_key_valid);
        textView.setText(R.string.pk_text_public_key_invalid);
        imageView.setImageResource(R.drawable.btn_check_buttonless_off);
        if (publicKey == null || publicKey.length() == 0) {
            return false;
        }

        log.debug("publicKey={}", publicKey);

        String type = "RSA";
        int bits = 1024;
        textView.setText(getString(R.string.pk_text_public_key_valid, type, bits));
        imageView.setImageResource(R.drawable.btn_check_buttonless_on);
        return true;
    }

    private void onBrowsePrivateClicked(View view) {
        Intent intent = new Intent(ORG_OPENINTENTS_ACTION_PICK_FILE);
        startActivityForResult(intent, BROWSE_PRIVATE);
    }

    private void onBrowsePublicClicked(View view) {
        Intent intent = new Intent(ORG_OPENINTENTS_ACTION_PICK_FILE);
        startActivityForResult(intent, BROWSE_PUBLIC);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        try {
            Uri uri = data.getData();
            if (uri != null) {
                String key = readKey(uri);

                if (key != null && key.length() < MAX_KEY_SIZE) {
                    switch (requestCode) {
                    case BROWSE_PRIVATE:
                        EditText privateEdit = A3Utils.findView(getActivity(), EditText.class,
                                R.id.pk_private_key_path);
                        privateEdit.setText(key);
                        break;
                    case BROWSE_PUBLIC:
                        EditText publicEdit = A3Utils.findView(getActivity(), EditText.class,
                                R.id.pk_public_key_path);
                        publicEdit.setText(key);
                        break;
                    }
                }

            }
        } catch (ViewNotFoundException e) {
            log.error(e.getMessage(), e);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }

    private String readKey(Uri uri) throws IOException {
        InputStream inputStream = getActivity().getContentResolver().openInputStream(uri);
        int bytesAvailable = inputStream.available();
        if (bytesAvailable > MAX_KEY_SIZE) {
            log.debug("Does not look like a valid key, stream size at least {} bytes", bytesAvailable);
            return null;
        }
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

        StringBuffer sb = new StringBuffer();
        String line;
        while (null != (line = reader.readLine())) {
            sb.append(line);
            if (sb.length() > MAX_KEY_SIZE) {
                log.debug("Does not look like a valid key, stream size at least {}", bytesAvailable);
                return null;
            }
        }
        return sb.toString();
    }
}