Search in sources :

Example 16 with CryptoException

use of co.krypt.krypton.exception.CryptoException in project krypton-android by kryptco.

the class VerifyEmailFragment method onCreateView.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    final View rootView = inflater.inflate(R.layout.fragment_teams_onboarding_verify_email, container, false);
    Button cancelButton = rootView.findViewById(R.id.cancelButton);
    cancelButton.setOnClickListener(v -> {
        progress.resetAndDeleteTeam(v.getContext());
        getActivity().finish();
    });
    ProgressBar progressBar = rootView.findViewById(R.id.progressBar);
    progressBar.setAlpha(0);
    Button submitButton = rootView.findViewById(R.id.submitButton);
    Button changeButton = rootView.findViewById(R.id.changeButton);
    Button resendButton = rootView.findViewById(R.id.resendButton);
    AppCompatTextView checkYourEmailText = rootView.findViewById(R.id.checkYourEmailText);
    AppCompatTextView checkYourEmailSubtext = rootView.findViewById(R.id.checkYourEmailSubtext);
    AppCompatEditText emailEditText = rootView.findViewById(R.id.profileEmail);
    InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
    Runnable onSubmitUI = () -> {
        emailEditText.setEnabled(false);
        emailEditText.clearFocus();
        if (imm != null) {
            imm.hideSoftInputFromWindow(emailEditText.getWindowToken(), 0);
        }
        progressBar.animate().alpha(1).setDuration(1000).start();
        submitButton.setEnabled(false);
        submitButton.animate().alpha(0).setDuration(500).start();
        checkYourEmailSubtext.animate().alpha(0).setDuration(500).start();
        checkYourEmailText.animate().alpha(0).setDuration(500).start();
    };
    Runnable onEditUI = () -> {
        emailEditText.setEnabled(true);
        submitButton.animate().alpha(1).setDuration(500).start();
        changeButton.animate().alpha(0).setDuration(500).start();
        resendButton.animate().alpha(0).setDuration(500).start();
        submitButton.setEnabled(true);
        changeButton.setEnabled(false);
        resendButton.setEnabled(false);
        checkYourEmailSubtext.animate().alpha(0).setDuration(500).start();
        checkYourEmailText.animate().alpha(0).setDuration(500).start();
        progressBar.animate().alpha(0).setDuration(500).start();
    };
    Runnable onSuccessUI = () -> {
        progressBar.animate().alpha(0).setDuration(500).start();
        changeButton.animate().alpha(1).setDuration(1000).start();
        resendButton.animate().alpha(1).setDuration(1000).start();
        submitButton.animate().alpha(0).setDuration(500).start();
        changeButton.setEnabled(true);
        resendButton.setEnabled(true);
        checkYourEmailSubtext.animate().alpha(1).setDuration(500).start();
        checkYourEmailText.animate().alpha(1).setDuration(500).start();
    };
    Runnable focusEmail = () -> {
        onEditUI.run();
        emailEditText.requestFocus();
        if (imm != null) {
            imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
        }
    };
    Runnable onErrorUI = () -> {
        focusEmail.run();
        Toast.makeText(getContext(), "Error sending email verification.", Toast.LENGTH_SHORT).show();
    };
    submitButton.setAlpha(1);
    changeButton.setAlpha(0);
    resendButton.setAlpha(0);
    checkYourEmailSubtext.setAlpha(0);
    checkYourEmailText.setAlpha(0);
    changeButton.setEnabled(false);
    resendButton.setEnabled(false);
    AppCompatTextView teamName = rootView.findViewById(R.id.teamName);
    teamName.setText(progress.getTeamOnboardingData().decryptInviteOutput.teamName);
    String initialEmail = Silo.shared(getContext().getApplicationContext()).meStorage().load().email;
    emailEditText.setText(initialEmail);
    final Sigchain.IndirectInvitationRestriction restriction = progress.getTeamOnboardingData().decryptInviteOutput.indirectInvitationSecret.restriction;
    Runnable requestEmailChallenge = () -> {
        final String email = emailEditText.getEditableText().toString();
        if (!Email.verifyEmailPattern.matcher(email).matches()) {
            Toast.makeText(getContext(), "Please enter a valid email.", Toast.LENGTH_SHORT).show();
            return;
        }
        if (!restriction.isSatisfiedByEmail(email)) {
            if (restriction.domain != null) {
                Toast.makeText(getContext(), "Email must end with @" + restriction.domain, Toast.LENGTH_SHORT).show();
            } else if (restriction.emails != null) {
                Toast.makeText(getContext(), "Invite link not valid for this email address.", Toast.LENGTH_SHORT).show();
            }
            return;
        }
        onSubmitUI.run();
        new Thread(() -> {
            MeStorage meStorage = Silo.shared(getContext()).meStorage();
            try {
                meStorage.setEmail(email);
            } catch (CryptoException e) {
                co.krypt.krypton.uiutils.Error.shortToast(getContext(), "Failed to set email: " + e.getMessage());
                e.printStackTrace();
                return;
            }
            Profile me = meStorage.load();
            progress.updateTeamData((s, d) -> {
                if (s.equals(JoinStage.VERIFY_EMAIL)) {
                    d.profile = me;
                    Log.i(TAG, "requesting email challenge...");
                    try {
                        final Sigchain.NativeResult<JsonObject> result = TeamDataProvider.requestEmailChallenge(getContext(), email);
                        emailEditText.post(() -> {
                            if (result.success != null) {
                                Log.i(TAG, "request email challenge success");
                                onSuccessUI.run();
                            } else {
                                Log.i(TAG, "request email challenge failure");
                                onErrorUI.run();
                            }
                        });
                        if (result.success != null) {
                            return JoinStage.CHALLENGE_EMAIL_SENT;
                        } else {
                            return s;
                        }
                    } catch (Native.NotLinked notLinked) {
                        notLinked.printStackTrace();
                    }
                }
                return s;
            });
        }).start();
    };
    final Runnable setSelectionBeforeDomain = () -> {
        String currentEmail = emailEditText.getText().toString();
        if (restriction.domain != null) {
            String domainSuffix = "@" + restriction.domain;
            if (currentEmail.length() >= domainSuffix.length()) {
                if (emailEditText.getSelectionStart() == emailEditText.getSelectionEnd()) {
                    if (emailEditText.getSelectionStart() > currentEmail.length() - domainSuffix.length()) {
                        emailEditText.setSelection(currentEmail.length() - domainSuffix.length());
                    }
                }
            }
        }
    };
    emailEditText.setOnEditorActionListener((v, i, ev) -> {
        requestEmailChallenge.run();
        return false;
    });
    // focus before adding listener
    focusEmail.run();
    setSelectionBeforeDomain.run();
    emailEditText.setOnFocusChangeListener((view, b) -> {
        if (view.isEnabled()) {
            if (b) {
                setSelectionBeforeDomain.run();
            }
        }
    });
    emailEditText.setOnClickListener(v -> setSelectionBeforeDomain.run());
    final AtomicReference<String> lastEmail = new AtomicReference<>(new String(emailEditText.getText().toString()));
    if (!restriction.isSatisfiedByEmail(lastEmail.get())) {
        if (restriction.domain != null) {
            lastEmail.set("@" + restriction.domain);
        } else if (restriction.emails != null && restriction.emails.length == 1) {
            lastEmail.set(restriction.emails[0]);
        } else {
            lastEmail.set("");
        }
        emailEditText.setText(lastEmail.get());
    }
    final Runnable updateTextColor = () -> {
        if (Email.verifyEmailPattern.matcher(emailEditText.getText()).matches()) {
            emailEditText.setTextColor(getContext().getColor(R.color.appGreen));
        } else {
            emailEditText.setTextColor(getContext().getColor(R.color.appGray));
        }
    };
    updateTextColor.run();
    final TextWatcher domainCheck = new TextWatcher() {

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            lastEmail.set(s.toString());
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            updateTextColor.run();
        }

        @Override
        public void afterTextChanged(Editable s) {
            if (restriction.domain != null) {
                if (!s.toString().endsWith("@" + restriction.domain)) {
                    emailEditText.removeTextChangedListener(this);
                    s.clear();
                    s.append(lastEmail.get());
                    setSelectionBeforeDomain.run();
                    emailEditText.addTextChangedListener(this);
                    Toast.makeText(getContext(), "Email must end with @" + restriction.domain, Toast.LENGTH_SHORT).show();
                }
            }
        }
    };
    emailEditText.addTextChangedListener(domainCheck);
    resendButton.setOnClickListener(v -> {
        requestEmailChallenge.run();
    });
    changeButton.setOnClickListener(v -> {
        focusEmail.run();
    });
    submitButton.setOnClickListener(v -> requestEmailChallenge.run());
    return rootView;
}
Also used : Sigchain(co.krypt.krypton.team.Sigchain) AppCompatTextView(android.support.v7.widget.AppCompatTextView) JsonObject(com.google.gson.JsonObject) InputMethodManager(android.view.inputmethod.InputMethodManager) AtomicReference(java.util.concurrent.atomic.AtomicReference) View(android.view.View) AppCompatTextView(android.support.v7.widget.AppCompatTextView) Profile(co.krypt.krypton.protocol.Profile) Native(co.krypt.krypton.team.Native) AppCompatEditText(android.support.v7.widget.AppCompatEditText) Button(android.widget.Button) MeStorage(co.krypt.krypton.me.MeStorage) TextWatcher(android.text.TextWatcher) Editable(android.text.Editable) CryptoException(co.krypt.krypton.exception.CryptoException) ProgressBar(android.widget.ProgressBar)

Example 17 with CryptoException

use of co.krypt.krypton.exception.CryptoException in project krypton-android by kryptco.

the class GenerateFragment method next.

private void next() {
    KeyType keyType = null;
    if (keyTypeButton.getText().equals(getString(R.string.ed25519_key_type))) {
        keyType = KeyType.Ed25519;
    } else if (keyTypeButton.getText().equals(getString(R.string.rsa_key_type))) {
        keyType = KeyType.RSA;
    } else {
        keyType = KeyType.RSA;
    }
    final KeyType finalKeyType = keyType;
    final FragmentActivity context = getActivity();
    final OnboardingProgress progress = new OnboardingProgress(getContext());
    progress.setStage(OnboardingStage.GENERATING);
    new Analytics(context).postEvent("onboard", "generate tapped", null, null, false);
    final long startMillis = System.currentTimeMillis();
    final GeneratingFragment generatingFragment = new GeneratingFragment();
    getActivity().getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left).replace(R.id.activity_onboarding, generatingFragment).commit();
    final Fragment self = this;
    new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                final long start = System.currentTimeMillis();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                SSHKeyPairI pair = KeyManager.loadOrGenerateKeyPair(context, finalKeyType, KeyManager.ME_TAG);
                new MeStorage(context).set(new Profile("", pair.publicKeySSHWireFormat(), null, null));
                final long genTime = System.currentTimeMillis() - start;
                new Analytics(context).postEvent("keypair", "generate", null, (int) (genTime / 1000), false);
                if (genTime < 5000) {
                    try {
                        Thread.sleep(5000 - genTime);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                generatingFragment.onGenerate();
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                progress.setStage(OnboardingStage.ENTER_EMAIL);
                EnterEmailFragment enterEmailFragment = new EnterEmailFragment();
                final FragmentActivity activity = context;
                if (activity != null && !activity.isDestroyed() && !activity.isFinishing()) {
                    activity.getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left).hide(generatingFragment).add(R.id.activity_onboarding, enterEmailFragment).show(enterEmailFragment).commitAllowingStateLoss();
                }
            } catch (InvalidKeyException | IOException | CryptoException | UnsupportedOperationException | IllegalArgumentException e) {
                e.printStackTrace();
                progress.reset();
                final FragmentActivity activity = context;
                if (activity != null && !activity.isDestroyed() && !activity.isFinishing()) {
                    GenerateFragment generateFragment = new GenerateFragment();
                    if (finalKeyType == KeyType.RSA) {
                        Bundle args = new Bundle();
                        args.putString(DEFAULT_KEY_TYPE_KEY, activity.getString(R.string.ed25519_key_type));
                        generateFragment.setArguments(args);
                        activity.runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                Toast.makeText(activity, "Error generating rsa key, try again to generate an ed25519 key.", Toast.LENGTH_LONG).show();
                            }
                        });
                    }
                    activity.getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left).replace(R.id.activity_onboarding, generateFragment).commitAllowingStateLoss();
                }
            }
        }
    }).start();
}
Also used : KeyType(co.krypt.krypton.crypto.KeyType) Bundle(android.os.Bundle) SSHKeyPairI(co.krypt.krypton.crypto.SSHKeyPairI) IOException(java.io.IOException) InvalidKeyException(java.security.InvalidKeyException) Fragment(android.support.v4.app.Fragment) Analytics(co.krypt.krypton.analytics.Analytics) Profile(co.krypt.krypton.protocol.Profile) FragmentActivity(android.support.v4.app.FragmentActivity) MeStorage(co.krypt.krypton.me.MeStorage) CryptoException(co.krypt.krypton.exception.CryptoException)

Example 18 with CryptoException

use of co.krypt.krypton.exception.CryptoException in project krypton-android by kryptco.

the class RSASSHKeyPair method getSignerAndPrepareData.

public Pair<Signature, byte[]> getSignerAndPrepareData(String digest, byte[] data) throws CryptoException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
    KeyFactory factory = KeyFactory.getInstance(keyPair.getPrivate().getAlgorithm(), "AndroidKeyStore");
    KeyInfo keyInfo;
    keyInfo = factory.getKeySpec(keyPair.getPrivate(), KeyInfo.class);
    Signature signer;
    if (Arrays.asList(keyInfo.getDigests()).contains(digest)) {
        switch(digest) {
            case KeyProperties.DIGEST_SHA1:
                signer = Signature.getInstance("SHA1withRSA");
                break;
            case KeyProperties.DIGEST_SHA256:
                signer = Signature.getInstance("SHA256withRSA");
                break;
            case KeyProperties.DIGEST_SHA512:
                signer = Signature.getInstance("SHA512withRSA");
                break;
            default:
                throw new CryptoException("Unsupported digest: " + digest);
        }
    } else {
        // fall back to NONEwithRSA for backwards compatibility
        signer = Signature.getInstance("NONEwithRSA");
        switch(digest) {
            case KeyProperties.DIGEST_SHA1:
                data = SHA1.digestPrependingOID(data);
                break;
            case KeyProperties.DIGEST_SHA256:
                data = SHA256.digestPrependingOID(data);
                break;
            case KeyProperties.DIGEST_SHA512:
                data = SHA512.digestPrependingOID(data);
                break;
            default:
                throw new CryptoException("Unsupported digest: " + digest);
        }
    }
    return new Pair<>(signer, data);
}
Also used : KeyInfo(android.security.keystore.KeyInfo) Signature(java.security.Signature) RSASignature(co.krypt.krypton.pgp.packet.RSASignature) CryptoException(co.krypt.krypton.exception.CryptoException) KeyFactory(java.security.KeyFactory) KeyPair(java.security.KeyPair) Pair(android.support.v4.util.Pair)

Example 19 with CryptoException

use of co.krypt.krypton.exception.CryptoException in project krypton-android by kryptco.

the class RSASSHKeyPair method signDigestAppendingPubkey.

public byte[] signDigestAppendingPubkey(byte[] data, String algo) throws CryptoException {
    try {
        ByteArrayOutputStream dataWithPubkey = new ByteArrayOutputStream();
        dataWithPubkey.write(data);
        dataWithPubkey.write(SSHWire.encode(publicKeySSHWireFormat()));
        byte[] signaturePayload = dataWithPubkey.toByteArray();
        String digest = getDigestForAlgo(algo);
        return signDigest(digest, signaturePayload);
    } catch (IOException | NoSuchAlgorithmException | InvalidKeyException | NoSuchProviderException | SignatureException | InvalidKeySpecException e) {
        e.printStackTrace();
        throw new CryptoException(e);
    }
}
Also used : ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) SignatureException(java.security.SignatureException) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) InvalidKeyException(java.security.InvalidKeyException) NoSuchProviderException(java.security.NoSuchProviderException) CryptoException(co.krypt.krypton.exception.CryptoException)

Example 20 with CryptoException

use of co.krypt.krypton.exception.CryptoException in project krypton-android by kryptco.

the class SHA512 method digestPrependingOID.

public static byte[] digestPrependingOID(byte[] data) throws CryptoException {
    MessageDigest sha512 = null;
    try {
        sha512 = MessageDigest.getInstance("SHA-512");
    } catch (NoSuchAlgorithmException e) {
        throw new CryptoException(e.getMessage());
    }
    ByteArrayOutputStream oidWithDigest = new ByteArrayOutputStream();
    try {
        oidWithDigest.write(PKCS1_PADDING);
        oidWithDigest.write(sha512.digest(data));
    } catch (IOException e) {
        e.printStackTrace();
    }
    return oidWithDigest.toByteArray();
}
Also used : NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) MessageDigest(java.security.MessageDigest) CryptoException(co.krypt.krypton.exception.CryptoException)

Aggregations

CryptoException (co.krypt.krypton.exception.CryptoException)23 IOException (java.io.IOException)13 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)8 MeStorage (co.krypt.krypton.me.MeStorage)6 ByteArrayOutputStream (java.io.ByteArrayOutputStream)6 Sigchain (co.krypt.krypton.team.Sigchain)5 View (android.view.View)4 NoSuchProviderException (java.security.NoSuchProviderException)4 AppCompatTextView (android.support.v7.widget.AppCompatTextView)3 Button (android.widget.Button)3 Analytics (co.krypt.krypton.analytics.Analytics)3 SSHKeyPairI (co.krypt.krypton.crypto.SSHKeyPairI)3 KnownHost (co.krypt.krypton.knownhosts.KnownHost)3 Profile (co.krypt.krypton.protocol.Profile)3 InvalidKeyException (java.security.InvalidKeyException)3 KeyStore (java.security.KeyStore)3 KeyStoreException (java.security.KeyStoreException)3 CertificateException (java.security.cert.CertificateException)3 ArrayList (java.util.ArrayList)3 FragmentManager (android.support.v4.app.FragmentManager)2