1414 * You should have received a copy of the GNU General Public License
1515 * along with PCAPdroid. If not, see <http://www.gnu.org/licenses/>.
1616 *
17- * Copyright 2022 - Emanuele Faranda
17+ * Copyright 2022-26 - Emanuele Faranda
1818 */
1919
2020package com .emanuelef .remote_capture .fragments .mitmwizard ;
4545import com .pcapdroid .mitm .MitmAPI ;
4646
4747import java .io .IOException ;
48- import java .io .PrintWriter ;
48+ import java .io .OutputStream ;
4949import java .nio .charset .StandardCharsets ;
5050import java .security .cert .X509Certificate ;
5151
5252public class InstallCertificate extends StepFragment implements MitmListener {
5353 private static final String TAG = "InstallCertificate" ;
54+ private static final String CA_PEM_KEY = "ca_pem" ;
55+ private static final String FALLBACK_EXPORT_KEY = "fallback_export" ;
5456 private MitmAddon mAddon ;
5557 private String mCaPem ;
5658 private X509Certificate mCaCert ;
@@ -64,6 +66,14 @@ public class InstallCertificate extends StepFragment implements MitmListener {
6466 @ Override
6567 public void onViewCreated (@ NonNull View view , @ Nullable Bundle savedInstanceState ) {
6668 super .onViewCreated (view , savedInstanceState );
69+
70+ if (savedInstanceState != null ) {
71+ mFallbackExport = savedInstanceState .getBoolean (FALLBACK_EXPORT_KEY );
72+ mCaPem = savedInstanceState .getString (CA_PEM_KEY );
73+ if (mCaPem != null )
74+ mCaCert = Utils .x509FromPem (mCaPem );
75+ }
76+
6777 mStepLabel .setText (R .string .checking_the_certificate );
6878 mStepButton .setText (canInstallCertViaIntent () ? R .string .install_action : R .string .export_action );
6979 mStepButton .setEnabled (false );
@@ -80,6 +90,15 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
8090 mAddon = new MitmAddon (requireContext (), this );
8191 }
8292
93+ @ Override
94+ public void onSaveInstanceState (@ NonNull Bundle outState ) {
95+ super .onSaveInstanceState (outState );
96+
97+ // Store the certificate into the saved state to prevent a null PEM on activity re-creation
98+ outState .putString (CA_PEM_KEY , mCaPem );
99+ outState .putBoolean (FALLBACK_EXPORT_KEY , mFallbackExport );
100+ }
101+
83102 @ Override
84103 public void onDestroyView () {
85104 mAddon .disconnect ();
@@ -169,17 +188,28 @@ private void certExportResult(final ActivityResult result) {
169188 if ((result .getResultCode () == Activity .RESULT_OK ) && (result .getData () != null )) {
170189 Context ctx = requireContext ();
171190 Uri cert_uri = result .getData ().getData ();
191+
192+ if (mCaPem == null ) {
193+ Log .e (TAG , "Certificate not available, cannot export" );
194+ Utils .showToastLong (ctx , R .string .export_failed );
195+ return ;
196+ }
197+
172198 boolean written = false ;
173199
174- try (PrintWriter writer = new PrintWriter (ctx .getContentResolver ().openOutputStream (cert_uri , "rwt" ))) {
175- writer .print (mCaPem );
176- written = true ;
200+ try (OutputStream out = ctx .getContentResolver ().openOutputStream (cert_uri , "rwt" )) {
201+ if (out != null ) {
202+ out .write (mCaPem .getBytes (StandardCharsets .UTF_8 ));
203+ written = true ;
204+ }
177205 } catch (IOException e ) {
178206 e .printStackTrace ();
179207 }
180208
181209 if (written )
182210 Utils .showToastLong (ctx , R .string .cert_exported_now_installed );
211+ else
212+ Utils .showToastLong (ctx , R .string .export_failed );
183213 }
184214 }
185215
0 commit comments