mirror of https://github.com/M66B/FairEmail.git
Generate cloud key pair
This commit is contained in:
parent
a96d001b3c
commit
47d0d7c6ad
|
@ -53,6 +53,7 @@ import android.view.inputmethod.EditorInfo;
|
|||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
@ -81,10 +82,14 @@ import java.io.InputStream;
|
|||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
@ -108,6 +113,9 @@ public class FragmentOptionsBackup extends FragmentBase {
|
|||
private Button btnExport;
|
||||
private Button btnImport;
|
||||
private CardView cardCloud;
|
||||
private EditText etUser;
|
||||
private TextInputLayout tilPassword;
|
||||
private Button btnLogin;
|
||||
|
||||
private static final int REQUEST_EXPORT_SELECT = 1;
|
||||
private static final int REQUEST_IMPORT_SELECT = 2;
|
||||
|
@ -127,6 +135,9 @@ public class FragmentOptionsBackup extends FragmentBase {
|
|||
btnExport = view.findViewById(R.id.btnExport);
|
||||
btnImport = view.findViewById(R.id.btnImport);
|
||||
cardCloud = view.findViewById(R.id.cardCloud);
|
||||
etUser = view.findViewById(R.id.etUser);
|
||||
tilPassword = view.findViewById(R.id.tilPassword);
|
||||
btnLogin = view.findViewById(R.id.btnLogin);
|
||||
|
||||
// Wire controls
|
||||
|
||||
|
@ -153,9 +164,17 @@ public class FragmentOptionsBackup extends FragmentBase {
|
|||
}
|
||||
});
|
||||
|
||||
btnLogin.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onLogin();
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize
|
||||
FragmentDialogTheme.setBackground(getContext(), view, false);
|
||||
cardCloud.setVisibility(BuildConfig.DEBUG ? View.VISIBLE : View.GONE);
|
||||
cardCloud.setVisibility(BuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
|
||||
? View.VISIBLE : View.GONE);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
@ -1342,6 +1361,59 @@ public class FragmentOptionsBackup extends FragmentBase {
|
|||
return intent;
|
||||
}
|
||||
|
||||
private void onLogin() {
|
||||
Bundle args = new Bundle();
|
||||
args.putString("user", etUser.getText().toString());
|
||||
args.putString("password", tilPassword.getEditText().getText().toString());
|
||||
|
||||
new SimpleTask<Void>() {
|
||||
@Override
|
||||
protected void onPreExecute(Bundle args) {
|
||||
btnLogin.setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Bundle args) {
|
||||
btnLogin.setEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void onExecute(Context context, Bundle args) throws Throwable {
|
||||
String user = args.getString("user");
|
||||
String password = args.getString("password");
|
||||
|
||||
Pair<byte[], byte[]> key = getKeyPair(user, password);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onExecuted(Bundle args, Void data) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onException(Bundle args, Throwable ex) {
|
||||
Log.unexpectedError(getParentFragmentManager(), ex);
|
||||
}
|
||||
}.execute(FragmentOptionsBackup.this, args, "cloud:login");
|
||||
}
|
||||
|
||||
private static Pair<byte[], byte[]> getKeyPair(String user, String password)
|
||||
throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
byte[] salt = MessageDigest.getInstance("SHA256").digest(user.getBytes());
|
||||
|
||||
// https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
|
||||
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
|
||||
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 310000, 2 * 256);
|
||||
SecretKey secret = keyFactory.generateSecret(keySpec);
|
||||
|
||||
byte[] encoded = secret.getEncoded();
|
||||
int half = encoded.length / 2;
|
||||
return new Pair<>(
|
||||
Arrays.copyOfRange(encoded, 0, half),
|
||||
Arrays.copyOfRange(encoded, half, half + half));
|
||||
}
|
||||
|
||||
public static class FragmentDialogExport extends FragmentDialogBase {
|
||||
private TextInputLayout tilPassword1;
|
||||
private TextInputLayout tilPassword2;
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:autoMirrored="true">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M11,7L9.6,8.4l2.6,2.6H2v2h10.2l-2.6,2.6L11,17l5,-5L11,7zM20,19h-8v2h8c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2h-8v2h8V19z"/>
|
||||
</vector>
|
|
@ -0,0 +1,11 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:autoMirrored="true">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M5,5h7V3H5C3.9,3 3,3.9 3,5v14c0,1.1 0.9,2 2,2h7v-2H5V5zM21,12l-4,-4v3H9v2h8v3L21,12z"/>
|
||||
</vector>
|
|
@ -167,6 +167,68 @@
|
|||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvUser"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:labelFor="@+id/etUser"
|
||||
android:text="@string/title_user"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvCloud" />
|
||||
|
||||
<eu.faircode.email.EditTextPlain
|
||||
android:id="@+id/etUser"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:autofillHints="username"
|
||||
android:inputType="text"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvUser" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvPassword"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="@string/title_password"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/etUser" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/tilPassword"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:endIconMode="password_toggle"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvPassword">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:autofillHints="password"
|
||||
android:inputType="textPassword"
|
||||
android:maxLength="20000"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnLogin"
|
||||
style="?android:attr/buttonStyleSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:drawableEnd="@drawable/twotone_login_24"
|
||||
android:drawablePadding="6dp"
|
||||
android:text="@string/title_advanced_login"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tilPassword" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
|
@ -972,6 +972,8 @@
|
|||
<string name="title_advanced_cleanup_hint">This will delete all temporary files</string>
|
||||
<string name="title_advanced_keywords_hint" translatable="false">Space separated</string>
|
||||
|
||||
<string name="title_advanced_login" translatable="false">Login</string>
|
||||
|
||||
<string name="title_advanced_never_favorite">Never favorite</string>
|
||||
<string name="title_advanced_edit_name">Edit name</string>
|
||||
|
||||
|
|
Loading…
Reference in New Issue