Merge tag 'oc-android-1.9' into sdcard-save
[pub/Android/ownCloud.git] / src / com / owncloud / android / ui / adapter / X509CertificateViewAdapter.java
1 /**
2 * ownCloud Android client application
3 *
4 * @author masensio
5 * @author David A. Velasco
6 * Copyright (C) 2015 ownCloud Inc.
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2,
10 * as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21 package com.owncloud.android.ui.adapter;
22
23 import java.security.MessageDigest;
24 import java.security.NoSuchAlgorithmException;
25 import java.security.cert.CertificateEncodingException;
26 import java.security.cert.X509Certificate;
27 import java.text.DateFormat;
28 import java.util.Date;
29 import java.util.HashMap;
30 import java.util.Map;
31
32 import javax.security.auth.x500.X500Principal;
33
34 import com.owncloud.android.R;
35 import com.owncloud.android.ui.dialog.SslUntrustedCertDialog;
36
37 import android.util.Log;
38 import android.view.View;
39 import android.widget.TextView;
40
41 /**
42 *
43 */
44 public class X509CertificateViewAdapter implements SslUntrustedCertDialog.CertificateViewAdapter {
45
46 //private final static String TAG = X509CertificateViewAdapter.class.getSimpleName();
47
48 private X509Certificate mCertificate = null;
49
50 private static final String TAG = X509CertificateViewAdapter.class.getSimpleName();
51
52 public X509CertificateViewAdapter(X509Certificate certificate) {
53 mCertificate = certificate;
54 }
55
56 @Override
57 public void updateCertificateView(View dialogView) {
58 TextView nullCerView = (TextView) dialogView.findViewById(R.id.null_cert);
59
60 if (mCertificate != null) {
61 nullCerView.setVisibility(View.GONE);
62 showSubject(mCertificate.getSubjectX500Principal(), dialogView);
63 showIssuer(mCertificate.getIssuerX500Principal(), dialogView);
64 showValidity(mCertificate.getNotBefore(), mCertificate.getNotAfter(), dialogView);
65 showSignature(dialogView);
66
67 } else {
68 nullCerView.setVisibility(View.VISIBLE);
69 }
70 }
71
72 private byte[] getDigest(String algorithm, byte[] message) {
73 MessageDigest md = null;
74
75 try {
76 md = MessageDigest.getInstance(algorithm);
77 } catch (NoSuchAlgorithmException e) {
78 return null;
79 }
80 md.reset();
81 return md.digest(message);
82 }
83
84 private void showSignature(View dialogView) {
85 byte[] cert = null;
86
87 TextView certFingerprintView = ((TextView) dialogView.findViewById(R.id.value_certificate_fingerprint));
88 TextView algorithmView = ((TextView) dialogView.findViewById(R.id.value_signature_algorithm));
89
90 try {
91 cert = mCertificate.getEncoded();
92 if (cert == null) {
93
94 certFingerprintView.setText(R.string.certificate_load_problem);
95 algorithmView.setText(R.string.certificate_load_problem);
96
97 } else {
98
99 certFingerprintView.setText(
100 getDigestHexBytesWithColonsAndNewLines(dialogView, "SHA-256", cert)
101 + getDigestHexBytesWithColonsAndNewLines(dialogView, "SHA-1", cert)
102 + getDigestHexBytesWithColonsAndNewLines(dialogView, "MD5", cert));
103 algorithmView.setText(mCertificate.getSigAlgName());
104
105 }
106
107 } catch (CertificateEncodingException e) {
108 Log.e(TAG, "Problem while trying to decode the certificate.");
109 }
110
111
112 }
113
114 private final String getDigestHexBytesWithColonsAndNewLines(View dialogView, final String digestType, final byte [] cert) {
115 final byte[] rawDigest;
116 final String newLine = System.getProperty("line.separator");
117
118 rawDigest = getDigest(digestType, cert);
119
120 if ( rawDigest == null) {
121 return digestType + ":" + newLine + dialogView.getContext().getString(R.string.digest_algorithm_not_available) + newLine + newLine;
122 }
123
124 final StringBuilder hex = new StringBuilder(3 * rawDigest.length);
125
126 for (final byte b : rawDigest) {
127 final int hiVal = (b & 0xF0) >> 4;
128 final int loVal = b & 0x0F;
129 hex.append((char) ('0' + (hiVal + (hiVal / 10 * 7))));
130 hex.append((char) ('0' + (loVal + (loVal / 10 * 7))));
131 hex.append(":");
132 }
133 return digestType + ":" + newLine + hex.toString().replaceFirst("\\:$","") + newLine + newLine;
134 }
135
136 private void showValidity(Date notBefore, Date notAfter, View dialogView) {
137 TextView fromView = ((TextView)dialogView.findViewById(R.id.value_validity_from));
138 TextView toView = ((TextView)dialogView.findViewById(R.id.value_validity_to));
139 DateFormat dateFormat = DateFormat.getDateInstance();
140 fromView.setText(dateFormat.format(notBefore));
141 toView.setText(dateFormat.format(notAfter));
142 }
143
144 private void showSubject(X500Principal subject, View dialogView) {
145 Map<String, String> s = parsePrincipal(subject);
146 TextView cnView = ((TextView)dialogView.findViewById(R.id.value_subject_CN));
147 TextView oView = ((TextView)dialogView.findViewById(R.id.value_subject_O));
148 TextView ouView = ((TextView)dialogView.findViewById(R.id.value_subject_OU));
149 TextView cView = ((TextView)dialogView.findViewById(R.id.value_subject_C));
150 TextView stView = ((TextView)dialogView.findViewById(R.id.value_subject_ST));
151 TextView lView = ((TextView)dialogView.findViewById(R.id.value_subject_L));
152
153 if (s.get("CN") != null) {
154 cnView.setText(s.get("CN"));
155 cnView.setVisibility(View.VISIBLE);
156 } else {
157 cnView.setVisibility(View.GONE);
158 }
159 if (s.get("O") != null) {
160 oView.setText(s.get("O"));
161 oView.setVisibility(View.VISIBLE);
162 } else {
163 oView.setVisibility(View.GONE);
164 }
165 if (s.get("OU") != null) {
166 ouView.setText(s.get("OU"));
167 ouView.setVisibility(View.VISIBLE);
168 } else {
169 ouView.setVisibility(View.GONE);
170 }
171 if (s.get("C") != null) {
172 cView.setText(s.get("C"));
173 cView.setVisibility(View.VISIBLE);
174 } else {
175 cView.setVisibility(View.GONE);
176 }
177 if (s.get("ST") != null) {
178 stView.setText(s.get("ST"));
179 stView.setVisibility(View.VISIBLE);
180 } else {
181 stView.setVisibility(View.GONE);
182 }
183 if (s.get("L") != null) {
184 lView.setText(s.get("L"));
185 lView.setVisibility(View.VISIBLE);
186 } else {
187 lView.setVisibility(View.GONE);
188 }
189 }
190
191 private void showIssuer(X500Principal issuer, View dialogView) {
192 Map<String, String> s = parsePrincipal(issuer);
193 TextView cnView = ((TextView)dialogView.findViewById(R.id.value_issuer_CN));
194 TextView oView = ((TextView)dialogView.findViewById(R.id.value_issuer_O));
195 TextView ouView = ((TextView)dialogView.findViewById(R.id.value_issuer_OU));
196 TextView cView = ((TextView)dialogView.findViewById(R.id.value_issuer_C));
197 TextView stView = ((TextView)dialogView.findViewById(R.id.value_issuer_ST));
198 TextView lView = ((TextView)dialogView.findViewById(R.id.value_issuer_L));
199
200 if (s.get("CN") != null) {
201 cnView.setText(s.get("CN"));
202 cnView.setVisibility(View.VISIBLE);
203 } else {
204 cnView.setVisibility(View.GONE);
205 }
206 if (s.get("O") != null) {
207 oView.setText(s.get("O"));
208 oView.setVisibility(View.VISIBLE);
209 } else {
210 oView.setVisibility(View.GONE);
211 }
212 if (s.get("OU") != null) {
213 ouView.setText(s.get("OU"));
214 ouView.setVisibility(View.VISIBLE);
215 } else {
216 ouView.setVisibility(View.GONE);
217 }
218 if (s.get("C") != null) {
219 cView.setText(s.get("C"));
220 cView.setVisibility(View.VISIBLE);
221 } else {
222 cView.setVisibility(View.GONE);
223 }
224 if (s.get("ST") != null) {
225 stView.setText(s.get("ST"));
226 stView.setVisibility(View.VISIBLE);
227 } else {
228 stView.setVisibility(View.GONE);
229 }
230 if (s.get("L") != null) {
231 lView.setText(s.get("L"));
232 lView.setVisibility(View.VISIBLE);
233 } else {
234 lView.setVisibility(View.GONE);
235 }
236 }
237
238
239 private Map<String, String> parsePrincipal(X500Principal principal) {
240 Map<String, String> result = new HashMap<String, String>();
241 String toParse = principal.getName();
242 String[] pieces = toParse.split(",");
243 String[] tokens = {"CN", "O", "OU", "C", "ST", "L"};
244 for (int i=0; i < pieces.length ; i++) {
245 for (int j=0; j<tokens.length; j++) {
246 if (pieces[i].startsWith(tokens[j] + "=")) {
247 result.put(tokens[j], pieces[i].substring(tokens[j].length()+1));
248 }
249 }
250 }
251 return result;
252 }
253
254 }