diff --git a/app/src/main/java/eu/faircode/email/AdapterCertificate.java b/app/src/main/java/eu/faircode/email/AdapterCertificate.java index 74e6bb4c24..511c372e90 100644 --- a/app/src/main/java/eu/faircode/email/AdapterCertificate.java +++ b/app/src/main/java/eu/faircode/email/AdapterCertificate.java @@ -36,17 +36,25 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.widget.PopupMenu; import androidx.fragment.app.Fragment; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.OnLifecycleEvent; import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.ListUpdateCallback; import androidx.recyclerview.widget.RecyclerView; +import java.io.File; +import java.io.IOException; +import java.security.cert.CertificateException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; public class AdapterCertificate extends RecyclerView.Adapter { + private Fragment parentFragment; + private Context context; private LifecycleOwner owner; private LayoutInflater inflater; @@ -93,18 +101,62 @@ public class AdapterCertificate extends RecyclerView.Adapter() { + @Override + protected File onExecute(Context context, Bundle args) throws CertificateException, IOException { + long id = args.getLong("id"); + + DB db = DB.getInstance(context); + EntityCertificate certificate = db.certificate().getCertificate(id); + if (certificate == null) + return null; + + File dir = new File(context.getCacheDir(), "shared"); + if (!dir.exists()) + dir.mkdir(); + + String name = Helper.sanitizeFilename(certificate.email); + File file = new File(dir, name + ".pem"); + Helper.writeText(file, certificate.getPem()); + + return file; + } + + @Override + protected void onExecuted(Bundle args, File file) { + if (file == null) + return; + Helper.share(context, file, "application/*", file.getName()); + } + + @Override + protected void onException(Bundle args, Throwable ex) { + Log.unexpectedError(parentFragment.getParentFragmentManager(), ex); + } + }.execute(context, owner, args, "certificate:save"); + } + private void onActionDelete() { Bundle args = new Bundle(); args.putLong("id", certificate.id); @@ -122,7 +174,7 @@ public class AdapterCertificate extends RecyclerView.Adapter certificates) { diff --git a/app/src/main/java/eu/faircode/email/DaoCertificate.java b/app/src/main/java/eu/faircode/email/DaoCertificate.java index 9dd6d8026c..3a9ef7a528 100644 --- a/app/src/main/java/eu/faircode/email/DaoCertificate.java +++ b/app/src/main/java/eu/faircode/email/DaoCertificate.java @@ -35,6 +35,10 @@ public interface DaoCertificate { " ORDER BY intermediate, email, subject") LiveData> liveCertificates(); + @Query("SELECT * FROM certificate" + + " WHERE id = :id") + EntityCertificate getCertificate(long id); + @Query("SELECT * FROM certificate" + " WHERE fingerprint = :fingerprint" + " AND email = :email COLLATE NOCASE") diff --git a/app/src/main/java/eu/faircode/email/EntityCertificate.java b/app/src/main/java/eu/faircode/email/EntityCertificate.java index 1a50aa0309..5af4987c1b 100644 --- a/app/src/main/java/eu/faircode/email/EntityCertificate.java +++ b/app/src/main/java/eu/faircode/email/EntityCertificate.java @@ -37,10 +37,13 @@ import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder; +import org.bouncycastle.openssl.jcajce.JcaPEMWriter; import org.json.JSONException; import org.json.JSONObject; import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.StringWriter; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; @@ -111,6 +114,15 @@ public class EntityCertificate { .generateCertificate(new ByteArrayInputStream(encoded)); } + String getPem() throws CertificateException, IOException { + StringWriter writer = new StringWriter(); + JcaPEMWriter pemWriter = new JcaPEMWriter(writer); + pemWriter.writeObject(getCertificate()); + pemWriter.flush(); + pemWriter.close(); + return writer.toString(); + } + boolean isExpired() { return isExpired(null); }