9deff4ee91047f6913a93d92f872f1ccb87d3642
[PrivacyBrowser.git] / app / src / main / java / com / stoutner / privacybrowser / helpers / CheckPinnedMismatchHelper.java
1 /*
2  * Copyright © 2018-2019,2021 Soren Stoutner <soren@stoutner.com>.
3  *
4  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
5  *
6  * Privacy Browser is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Privacy Browser is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 package com.stoutner.privacybrowser.helpers;
21
22 import android.app.Activity;
23 import android.net.http.SslCertificate;
24
25 import androidx.fragment.app.DialogFragment;
26 import androidx.fragment.app.FragmentManager;
27
28 import com.stoutner.privacybrowser.R;
29 import com.stoutner.privacybrowser.activities.MainWebViewActivity;
30 import com.stoutner.privacybrowser.definitions.PendingDialog;
31 import com.stoutner.privacybrowser.dialogs.PinnedMismatchDialog;
32 import com.stoutner.privacybrowser.views.NestedScrollWebView;
33
34 import java.util.ArrayList;
35 import java.util.Date;
36
37 public class CheckPinnedMismatchHelper {
38     public static void checkPinnedMismatch(Activity activity, FragmentManager fragmentManager, NestedScrollWebView nestedScrollWebView) {
39         // Initialize the current SSL certificate variables.
40         String currentWebsiteIssuedToCName = "";
41         String currentWebsiteIssuedToOName = "";
42         String currentWebsiteIssuedToUName = "";
43         String currentWebsiteIssuedByCName = "";
44         String currentWebsiteIssuedByOName = "";
45         String currentWebsiteIssuedByUName = "";
46         Date currentWebsiteSslStartDate = null;
47         Date currentWebsiteSslEndDate = null;
48
49         // Initialize the pinned SSL certificate variables.
50         String pinnedSslIssuedToCName = "";
51         String pinnedSslIssuedToOName = "";
52         String pinnedSslIssuedToUName = "";
53         String pinnedSslIssuedByCName = "";
54         String pinnedSslIssuedByOName = "";
55         String pinnedSslIssuedByUName = "";
56         Date pinnedSslStartDate = null;
57         Date pinnedSslEndDate = null;
58
59         // Get the current website SSL certificate.
60         SslCertificate currentWebsiteSslCertificate = nestedScrollWebView.getCertificate();
61
62         // Extract the individual pieces of information from the current website SSL certificate if it is not null.
63         if (currentWebsiteSslCertificate != null) {
64             currentWebsiteIssuedToCName = currentWebsiteSslCertificate.getIssuedTo().getCName();
65             currentWebsiteIssuedToOName = currentWebsiteSslCertificate.getIssuedTo().getOName();
66             currentWebsiteIssuedToUName = currentWebsiteSslCertificate.getIssuedTo().getUName();
67             currentWebsiteIssuedByCName = currentWebsiteSslCertificate.getIssuedBy().getCName();
68             currentWebsiteIssuedByOName = currentWebsiteSslCertificate.getIssuedBy().getOName();
69             currentWebsiteIssuedByUName = currentWebsiteSslCertificate.getIssuedBy().getUName();
70             currentWebsiteSslStartDate = currentWebsiteSslCertificate.getValidNotBeforeDate();
71             currentWebsiteSslEndDate = currentWebsiteSslCertificate.getValidNotAfterDate();
72         }
73
74         // Get the pinned SSL certificate information if it exists.
75         if (nestedScrollWebView.hasPinnedSslCertificate()) {
76             // Get the pinned SSL certificate.
77             ArrayList<Object> pinnedSslCertificateArrayList = nestedScrollWebView.getPinnedSslCertificate();
78
79             // Extract the arrays from the array list.
80             String[] pinnedSslCertificateStringArray = (String[]) pinnedSslCertificateArrayList.get(0);
81             Date[] pinnedSslCertificateDateArray = (Date[]) pinnedSslCertificateArrayList.get(1);
82
83             // Populate the pinned SSL certificate string variables.
84             pinnedSslIssuedToCName = pinnedSslCertificateStringArray[0];
85             pinnedSslIssuedToOName = pinnedSslCertificateStringArray[1];
86             pinnedSslIssuedToUName = pinnedSslCertificateStringArray[2];
87             pinnedSslIssuedByCName = pinnedSslCertificateStringArray[3];
88             pinnedSslIssuedByOName = pinnedSslCertificateStringArray[4];
89             pinnedSslIssuedByUName = pinnedSslCertificateStringArray[5];
90
91             // Populate the pinned SSL certificate date variables.
92             pinnedSslStartDate = pinnedSslCertificateDateArray[0];
93             pinnedSslEndDate = pinnedSslCertificateDateArray[1];
94         }
95
96         // Initialize string variables to store the SSL certificate dates.  Strings are needed to compare the values below, which doesn't work with dates if the first one is null.
97         String currentWebsiteSslStartDateString = "";
98         String currentWebsiteSslEndDateString = "";
99         String pinnedSslStartDateString = "";
100         String pinnedSslEndDateString = "";
101
102         // Convert the dates to strings if they are not null.
103         if (currentWebsiteSslStartDate != null) {
104             currentWebsiteSslStartDateString = currentWebsiteSslStartDate.toString();
105         }
106
107         if (currentWebsiteSslEndDate != null) {
108             currentWebsiteSslEndDateString = currentWebsiteSslEndDate.toString();
109         }
110
111         if (pinnedSslStartDate != null) {
112             pinnedSslStartDateString = pinnedSslStartDate.toString();
113         }
114
115         if (pinnedSslEndDate != null) {
116             pinnedSslEndDateString = pinnedSslEndDate.toString();
117         }
118
119         // Check to see if the pinned information matches the current information.
120         if ((nestedScrollWebView.hasPinnedIpAddresses() && !nestedScrollWebView.getCurrentIpAddresses().equals(nestedScrollWebView.getPinnedIpAddresses())) ||
121                 (nestedScrollWebView.hasPinnedSslCertificate() && (!currentWebsiteIssuedToCName.equals(pinnedSslIssuedToCName) ||
122                 !currentWebsiteIssuedToOName.equals(pinnedSslIssuedToOName) || !currentWebsiteIssuedToUName.equals(pinnedSslIssuedToUName) ||
123                 !currentWebsiteIssuedByCName.equals(pinnedSslIssuedByCName) || !currentWebsiteIssuedByOName.equals(pinnedSslIssuedByOName) ||
124                 !currentWebsiteIssuedByUName.equals(pinnedSslIssuedByUName) || !currentWebsiteSslStartDateString.equals(pinnedSslStartDateString) ||
125                 !currentWebsiteSslEndDateString.equals(pinnedSslEndDateString)))) {
126
127             // Get a handle for the pinned mismatch alert dialog.
128             DialogFragment pinnedMismatchDialogFragment = PinnedMismatchDialog.displayDialog(nestedScrollWebView.getWebViewFragmentId());
129
130             // Try to show the dialog.  Sometimes the window is not active.
131             try {
132                 // Show the pinned mismatch alert dialog.
133                 pinnedMismatchDialogFragment.show(fragmentManager, activity.getString(R.string.pinned_mismatch));
134             } catch (Exception exception) {
135                 // Add the dialog to the pending dialog array list.  It will be displayed in `onStart()`.
136                 MainWebViewActivity.pendingDialogsArrayList.add(new PendingDialog(pinnedMismatchDialogFragment, activity.getString(R.string.pinned_mismatch)));
137             }
138         }
139     }
140 }