Skip to content

Commit da4e65a

Browse files
committed
Fix possible null mitm certificate after export
Fixes #887
1 parent 91a0a29 commit da4e65a

1 file changed

Lines changed: 35 additions & 5 deletions

File tree

‎app/src/main/java/com/emanuelef/remote_capture/fragments/mitmwizard/InstallCertificate.java‎

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
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

2020
package com.emanuelef.remote_capture.fragments.mitmwizard;
@@ -45,12 +45,14 @@
4545
import com.pcapdroid.mitm.MitmAPI;
4646

4747
import java.io.IOException;
48-
import java.io.PrintWriter;
48+
import java.io.OutputStream;
4949
import java.nio.charset.StandardCharsets;
5050
import java.security.cert.X509Certificate;
5151

5252
public 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

Comments
 (0)