EMMA Coverage Report (generated Fri Aug 23 16:39:17 PDT 2013)
[all classes][org.chromium.chrome.browser]

COVERAGE SUMMARY FOR SOURCE FILE [CertificateViewer.java]

nameclass, %method, %block, %line, %
CertificateViewer.java0%   (0/1)0%   (0/14)0%   (0/459)0%   (0/97)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class CertificateViewer0%   (0/1)0%   (0/14)0%   (0/459)0%   (0/97)
CertificateViewer (Context): void 0%   (0/1)0%   (0/25)0%   (0/6)
addCertificate (byte []): void 0%   (0/1)0%   (0/39)0%   (0/8)
addCertificateDetails (Certificate, byte [], byte []): void 0%   (0/1)0%   (0/131)0%   (0/23)
addItem (LinearLayout, String, String): void 0%   (0/1)0%   (0/14)0%   (0/4)
addLabel (LinearLayout, String): TextView 0%   (0/1)0%   (0/29)0%   (0/6)
addSectionTitle (LinearLayout, String): void 0%   (0/1)0%   (0/9)0%   (0/3)
addValue (LinearLayout, String): void 0%   (0/1)0%   (0/24)0%   (0/5)
formatBytes (byte [], char): String 0%   (0/1)0%   (0/39)0%   (0/6)
getDigest (byte [], String): byte [] 0%   (0/1)0%   (0/12)0%   (0/5)
onItemSelected (AdapterView, View, int, long): void 0%   (0/1)0%   (0/22)0%   (0/3)
onNothingSelected (AdapterView): void 0%   (0/1)0%   (0/1)0%   (0/1)
showCertificateChain (Context, byte [][]): void 0%   (0/1)0%   (0/9)0%   (0/3)
showCertificateChain (byte [][]): void 0%   (0/1)0%   (0/76)0%   (0/17)
showDialogForView (View): void 0%   (0/1)0%   (0/29)0%   (0/7)

1// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4 
5package org.chromium.chrome.browser;
6 
7import android.app.Dialog;
8import android.content.Context;
9import android.graphics.Typeface;
10import android.net.http.SslCertificate;
11import android.text.format.DateFormat;
12import android.util.Log;
13import android.view.View;
14import android.widget.AdapterView;
15import android.widget.AdapterView.OnItemSelectedListener;
16import android.widget.ArrayAdapter;
17import android.widget.LinearLayout;
18import android.widget.ScrollView;
19import android.widget.Spinner;
20import android.widget.TextView;
21 
22import org.chromium.chrome.R;
23 
24import java.io.ByteArrayInputStream;
25import java.security.MessageDigest;
26import java.security.cert.Certificate;
27import java.security.cert.CertificateException;
28import java.security.cert.CertificateFactory;
29import java.security.cert.X509Certificate;
30import java.util.ArrayList;
31 
32/**
33 * UI component for displaying certificate information.
34 */
35class CertificateViewer implements OnItemSelectedListener {
36    private static final String X_509 = "X.509";
37    private final Context mContext;
38    private final ArrayList<LinearLayout> mViews;
39    private final ArrayList<String> mTitles;
40    private final int mPadding;
41    private CertificateFactory mCertificateFactory;
42 
43    /**
44     * Show a dialog with the provided certificate information.
45     *
46     * @param context The context this view should display in.
47     * @param derData DER-encoded data representing a X509 certificate chain.
48     */
49    public static void showCertificateChain(Context context, byte[][] derData) {
50        CertificateViewer viewer = new CertificateViewer(context);
51        viewer.showCertificateChain(derData);
52    }
53 
54    private CertificateViewer(Context context) {
55        mContext = context;
56        mViews = new ArrayList<LinearLayout>();
57        mTitles = new ArrayList<String>();
58        mPadding = (int) context.getResources().getDimension(
59                R.dimen.certificate_viewer_padding) / 2;
60    }
61 
62    // Show information about an array of DER-encoded data representing a X509 certificate chain.
63    // A spinner will be displayed allowing the user to select which certificate to display.
64    private void showCertificateChain(byte[][] derData) {
65        for (int i = 0; i < derData.length; i++) {
66            addCertificate(derData[i]);
67        }
68        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(mContext,
69                android.R.layout.simple_spinner_item,
70                mTitles);
71        arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
72 
73        Spinner spinner = new Spinner(mContext);
74        spinner.setAdapter(arrayAdapter);
75        spinner.setOnItemSelectedListener(this);
76 
77        LinearLayout container = new LinearLayout(mContext);
78        container.setOrientation(LinearLayout.VERTICAL);
79        container.addView(spinner);
80 
81        for (int i = 0; i < mViews.size(); ++i) {
82            LinearLayout certificateView = mViews.get(i);
83            if (i != 0) {
84                certificateView.setVisibility(LinearLayout.GONE);
85            }
86            container.addView(certificateView);
87        }
88 
89        showDialogForView(container);
90    }
91 
92    // Displays a dialog with scrolling for the given view.
93    private void showDialogForView(View view) {
94        Dialog dialog = new Dialog(mContext);
95        dialog.setTitle(R.string.certtitle);
96        ScrollView scrollView = new ScrollView(mContext);
97        scrollView.addView(view);
98        dialog.addContentView(scrollView,
99                new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
100                        LinearLayout.LayoutParams.MATCH_PARENT));
101        dialog.show();
102    }
103 
104    private void addCertificate(byte[] derData) {
105        try {
106            if (mCertificateFactory == null) {
107                mCertificateFactory = CertificateFactory.getInstance(X_509);
108            }
109            Certificate cert = mCertificateFactory.generateCertificate(
110                    new ByteArrayInputStream(derData));
111            addCertificateDetails(cert, getDigest(derData, "SHA-256"), getDigest(derData, "SHA-1"));
112        } catch (CertificateException e) {
113            Log.e("CertViewer", "Error parsing certificate" + e.toString());
114        }
115    }
116 
117    private void addCertificateDetails(Certificate cert, byte[] sha256Digest, byte[] sha1Digest) {
118        LinearLayout certificateView = new LinearLayout(mContext);
119        mViews.add(certificateView);
120        certificateView.setOrientation(LinearLayout.VERTICAL);
121 
122        X509Certificate x509 = (X509Certificate) cert;
123        SslCertificate sslCert = new SslCertificate(x509);
124 
125        mTitles.add(sslCert.getIssuedTo().getCName());
126 
127        addSectionTitle(certificateView, nativeGetCertIssuedToText());
128        addItem(certificateView, nativeGetCertInfoCommonNameText(),
129                sslCert.getIssuedTo().getCName());
130        addItem(certificateView, nativeGetCertInfoOrganizationText(),
131                sslCert.getIssuedTo().getOName());
132        addItem(certificateView, nativeGetCertInfoOrganizationUnitText(),
133                sslCert.getIssuedTo().getUName());
134        addItem(certificateView, nativeGetCertInfoSerialNumberText(),
135                formatBytes(x509.getSerialNumber().toByteArray(), ':'));
136 
137        addSectionTitle(certificateView, nativeGetCertIssuedByText());
138        addItem(certificateView, nativeGetCertInfoCommonNameText(),
139                sslCert.getIssuedBy().getCName());
140        addItem(certificateView, nativeGetCertInfoOrganizationText(),
141                sslCert.getIssuedBy().getOName());
142        addItem(certificateView, nativeGetCertInfoOrganizationUnitText(),
143                sslCert.getIssuedBy().getUName());
144 
145        addSectionTitle(certificateView, nativeGetCertValidityText());
146        java.text.DateFormat dateFormat = DateFormat.getDateFormat(mContext);
147        addItem(certificateView, nativeGetCertIssuedOnText(),
148                dateFormat.format(sslCert.getValidNotBeforeDate()));
149        addItem(certificateView, nativeGetCertExpiresOnText(),
150                dateFormat.format(sslCert.getValidNotAfterDate()));
151 
152        addSectionTitle(certificateView, nativeGetCertFingerprintsText());
153        addItem(certificateView, nativeGetCertSHA256FingerprintText(),
154                formatBytes(sha256Digest, ' '));
155        addItem(certificateView, nativeGetCertSHA1FingerprintText(),
156                formatBytes(sha1Digest, ' '));
157    }
158 
159    private void addSectionTitle(LinearLayout certificateView, String label) {
160        TextView title = addLabel(certificateView, label);
161        title.setAllCaps(true);
162    }
163 
164    private void addItem(LinearLayout certificateView, String label, String value) {
165        if (value.isEmpty()) return;
166 
167        addLabel(certificateView, label);
168        addValue(certificateView, value);
169    }
170 
171    private TextView addLabel(LinearLayout certificateView, String label) {
172        TextView t = new TextView(mContext);
173        t.setPadding(mPadding, mPadding / 2, mPadding, 0);
174        t.setText(label);
175        t.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
176        certificateView.addView(t);
177        return t;
178    }
179 
180    private void addValue(LinearLayout certificateView, String value) {
181        TextView t = new TextView(mContext);
182        t.setText(value);
183        t.setPadding(mPadding, 0, mPadding, mPadding / 2);
184        certificateView.addView(t);
185    }
186 
187    private static String formatBytes(byte[] bytes, char separator) {
188        StringBuilder sb = new StringBuilder();
189        for (int i = 0; i < bytes.length; i++) {
190            sb.append(String.format("%02X", bytes[i]));
191            if (i != bytes.length - 1) {
192                sb.append(separator);
193            }
194        }
195        return sb.toString();
196    }
197 
198    private static byte[] getDigest(byte[] bytes, String algorithm) {
199      try {
200        MessageDigest md = MessageDigest.getInstance(algorithm);
201        md.update(bytes);
202        return md.digest();
203      } catch (java.security.NoSuchAlgorithmException e) {
204        return null;
205      }
206    }
207 
208    @Override
209    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
210        for (int i = 0; i < mViews.size(); ++i) {
211            mViews.get(i).setVisibility(
212                    i == position ? LinearLayout.VISIBLE : LinearLayout.GONE);
213        }
214    }
215 
216    @Override
217    public void onNothingSelected(AdapterView<?> parent) {
218    }
219 
220    private static native String nativeGetCertIssuedToText();
221    private static native String nativeGetCertInfoCommonNameText();
222    private static native String nativeGetCertInfoOrganizationText();
223    private static native String nativeGetCertInfoSerialNumberText();
224    private static native String nativeGetCertInfoOrganizationUnitText();
225    private static native String nativeGetCertIssuedByText();
226    private static native String nativeGetCertValidityText();
227    private static native String nativeGetCertIssuedOnText();
228    private static native String nativeGetCertExpiresOnText();
229    private static native String nativeGetCertFingerprintsText();
230    private static native String nativeGetCertSHA256FingerprintText();
231    private static native String nativeGetCertSHA1FingerprintText();
232}

[all classes][org.chromium.chrome.browser]
EMMA 2.0.5312 (C) Vladimir Roubtsov