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;
}
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();
}
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);
}
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);
}
}
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();
}
Aggregations