Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be87cc94 authored by Brian Carlstrom's avatar Brian Carlstrom Committed by Android (Google) Code Review
Browse files

Merge "Adding additional details to ssl_certificate view"

parents 5161eb7b 4a062810
Loading
Loading
Loading
Loading
+136 −39
Original line number Diff line number Diff line
@@ -23,13 +23,20 @@ import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

import java.io.ByteArrayInputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;

import com.android.org.bouncycastle.asn1.DERObjectIdentifier;
import com.android.org.bouncycastle.asn1.x509.X509Name;

/**
@@ -45,22 +52,31 @@ public class SslCertificate {
    /**
     * Name of the entity this certificate is issued to
     */
    private DName mIssuedTo;
    private final DName mIssuedTo;

    /**
     * Name of the entity this certificate is issued by
     */
    private DName mIssuedBy;
    private final DName mIssuedBy;

    /**
     * Not-before date from the validity period
     */
    private Date mValidNotBefore;
    private final Date mValidNotBefore;

    /**
     * Not-after date from the validity period
     */
    private Date mValidNotAfter;
    private final Date mValidNotAfter;

    /**
     * The original source certificate, if available.
     *
     * TODO If deprecated constructors are removed, this should always
     * be available, and saveState and restoreState can be simplified
     * to be unconditional.
     */
    private final X509Certificate mX509Certificate;

    /**
     * Bundle key names
@@ -69,6 +85,7 @@ public class SslCertificate {
    private static final String ISSUED_BY = "issued-by";
    private static final String VALID_NOT_BEFORE = "valid-not-before";
    private static final String VALID_NOT_AFTER = "valid-not-after";
    private static final String X509_CERTIFICATE = "x509-certificate";

    /**
     * Saves the certificate state to a bundle
@@ -76,18 +93,21 @@ public class SslCertificate {
     * @return A bundle with the certificate stored in it or null if fails
     */
    public static Bundle saveState(SslCertificate certificate) {
        Bundle bundle = null;

        if (certificate != null) {
            bundle = new Bundle();

        if (certificate == null) {
            return null;
        }
        Bundle bundle = new Bundle();
        bundle.putString(ISSUED_TO, certificate.getIssuedTo().getDName());
        bundle.putString(ISSUED_BY, certificate.getIssuedBy().getDName());

        bundle.putString(VALID_NOT_BEFORE, certificate.getValidNotBefore());
        bundle.putString(VALID_NOT_AFTER, certificate.getValidNotAfter());
        X509Certificate x509Certificate = certificate.mX509Certificate;
        if (x509Certificate != null) {
            try {
                bundle.putByteArray(X509_CERTIFICATE, x509Certificate.getEncoded());
            } catch (CertificateEncodingException ignored) {
            }
        }

        return bundle;
    }

@@ -97,16 +117,28 @@ public class SslCertificate {
     * @return The SSL certificate stored in the bundle or null if fails
     */
    public static SslCertificate restoreState(Bundle bundle) {
        if (bundle != null) {
            return new SslCertificate(
                bundle.getString(ISSUED_TO),
                bundle.getString(ISSUED_BY),
                bundle.getString(VALID_NOT_BEFORE),
                bundle.getString(VALID_NOT_AFTER));
        }

        if (bundle == null) {
            return null;
        }
        X509Certificate x509Certificate;
        byte[] bytes = bundle.getByteArray(X509_CERTIFICATE);
        if (bytes == null) {
            x509Certificate = null;
        } else {
            try {
                CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
                Certificate cert = certFactory.generateCertificate(new ByteArrayInputStream(bytes));
                x509Certificate = (X509Certificate) cert;
            } catch (CertificateException e) {
                x509Certificate = null;
            }
        }
        return new SslCertificate(bundle.getString(ISSUED_TO),
                                  bundle.getString(ISSUED_BY),
                                  parseDate(bundle.getString(VALID_NOT_BEFORE)),
                                  parseDate(bundle.getString(VALID_NOT_AFTER)),
                                  x509Certificate);
    }

    /**
     * Creates a new SSL certificate object
@@ -121,7 +153,7 @@ public class SslCertificate {
    @Deprecated
    public SslCertificate(
            String issuedTo, String issuedBy, String validNotBefore, String validNotAfter) {
        this(issuedTo, issuedBy, parseDate(validNotBefore), parseDate(validNotAfter));
        this(issuedTo, issuedBy, parseDate(validNotBefore), parseDate(validNotAfter), null);
    }

    /**
@@ -135,10 +167,7 @@ public class SslCertificate {
    @Deprecated
    public SslCertificate(
            String issuedTo, String issuedBy, Date validNotBefore, Date validNotAfter) {
        mIssuedTo = new DName(issuedTo);
        mIssuedBy = new DName(issuedBy);
        mValidNotBefore = cloneDate(validNotBefore);
        mValidNotAfter  = cloneDate(validNotAfter);
        this(issuedTo, issuedBy, validNotBefore, validNotAfter, null);
    }

    /**
@@ -149,7 +178,19 @@ public class SslCertificate {
        this(certificate.getSubjectDN().getName(),
             certificate.getIssuerDN().getName(),
             certificate.getNotBefore(),
             certificate.getNotAfter());
             certificate.getNotAfter(),
             certificate);
    }

    private SslCertificate(
            String issuedTo, String issuedBy,
            Date validNotBefore, Date validNotAfter,
            X509Certificate x509Certificate) {
        mIssuedTo = new DName(issuedTo);
        mIssuedBy = new DName(issuedBy);
        mValidNotBefore = cloneDate(validNotBefore);
        mValidNotAfter  = cloneDate(validNotAfter);
        mX509Certificate = x509Certificate;
    }

    /**
@@ -204,6 +245,54 @@ public class SslCertificate {
        return mIssuedBy;
    }

    /**
     * Convenience for UI presentation, not intended as public API.
     */
    private static String getSerialNumber(X509Certificate x509Certificate) {
        if (x509Certificate == null) {
            return "";
        }
        BigInteger serialNumber = x509Certificate.getSerialNumber();
        if (serialNumber == null) {
            return "";
        }
        return fingerprint(serialNumber.toByteArray());
    }

    /**
     * Convenience for UI presentation, not intended as public API.
     */
    private static String getDigest(X509Certificate x509Certificate, String algorithm) {
        if (x509Certificate == null) {
            return "";
        }
        try {
            byte[] bytes = x509Certificate.getEncoded();
            MessageDigest md = MessageDigest.getInstance(algorithm);
            byte[] digest = md.digest(bytes);
            return fingerprint(digest);
        } catch (CertificateEncodingException ignored) {
            return "";
        } catch (NoSuchAlgorithmException ignored) {
            return "";
        }
    }

    private static final String fingerprint(byte[] bytes) {
        if (bytes == null) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            byte b = bytes[i];
            IntegralToString.appendByteAsHex(sb, b, true);
            if (i+1 != bytes.length) {
                sb.append(':');
            }
        }
        return sb.toString();
    }

    /**
     * @return A string representation of this certificate for debugging
     */
@@ -338,7 +427,6 @@ public class SslCertificate {
     * Inflates the SSL certificate view (helper method).
     * @return The resultant certificate view with issued-to, issued-by,
     * issued-on, expires-on, and possibly other fields set.
     * If the input certificate is null, returns null.
     *
     * @hide Used by Browser and Settings
     */
@@ -358,6 +446,9 @@ public class SslCertificate {
            ((TextView) certificateView.findViewById(com.android.internal.R.id.to_org_unit))
                    .setText(issuedTo.getUName());
        }
        // serial number:
        ((TextView) certificateView.findViewById(com.android.internal.R.id.serial_number))
                .setText(getSerialNumber(mX509Certificate));

        // issued by:
        SslCertificate.DName issuedBy = getIssuedBy();
@@ -380,6 +471,12 @@ public class SslCertificate {
        ((TextView) certificateView.findViewById(com.android.internal.R.id.expires_on))
                .setText(expiresOn);

        // fingerprints:
        ((TextView) certificateView.findViewById(com.android.internal.R.id.sha256_fingerprint))
                .setText(getDigest(mX509Certificate, "SHA256"));
        ((TextView) certificateView.findViewById(com.android.internal.R.id.sha1_fingerprint))
                .setText(getDigest(mX509Certificate, "SHA1"));

        return certificateView;
    }

+79 −28
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
        android:id="@+id/body"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="left"
        android:orientation="vertical" >

        <!-- Placeholder for the success message or one or more warnings -->
@@ -43,8 +44,7 @@
            android:layout_weight="1"
            android:gravity="fill_horizontal"
            android:layout_marginLeft="20dip"
            android:layout_marginRight="20dip"
            android:layout_marginBottom="12dip" />
            android:layout_marginRight="20dip"/>

        <TableLayout
            android:layout_width="match_parent"
@@ -58,7 +58,8 @@
                android:text="@string/issued_to"
                android:textStyle="bold"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:layout_width="match_parent"
                android:layout_marginTop="12dip"
                android:layout_marginLeft="20dip"
                android:layout_marginRight="20dip"
                android:layout_marginBottom="7dip" />
@@ -68,12 +69,10 @@
                <TextView
                    android:id="@+id/to_common_header"
                    android:text="@string/common_name"
                    android:gravity="left"
                    android:layout_marginLeft="20dip" />

                <TextView
                    android:id="@+id/to_common"
                    android:gravity="left"
                    android:layout_marginLeft="10dip"
                    android:layout_marginRight="20dip"
                    android:layout_marginBottom="7dip" />
@@ -84,12 +83,10 @@
                <TextView
                    android:id="@+id/to_org_header"
                    android:text="@string/org_name"
                    android:gravity="left"
                    android:layout_marginLeft="20dip" />

                <TextView
                    android:id="@+id/to_org"
                    android:gravity="left"
                    android:layout_marginLeft="10dip"
                    android:layout_marginRight="20dip"
                    android:layout_marginBottom="7dip" />
@@ -100,15 +97,27 @@
                <TextView
                    android:id="@+id/to_org_unit_header"
                    android:text="@string/org_unit"
                    android:gravity="left"
                    android:layout_marginLeft="20dip" />

                <TextView
                    android:id="@+id/to_org_unit"
                    android:gravity="left"
                    android:layout_marginLeft="10dip"
                    android:layout_marginRight="20dip"
                    android:layout_marginBottom="12dip" />
                    android:layout_marginBottom="7dip" />
            </TableRow>

            <!-- Serial number: -->
            <TableRow>
                <TextView
                    android:id="@+id/serial_number_header"
                    android:text="@string/serial_number"
                    android:layout_marginLeft="20dip" />

                <TextView
                    android:id="@+id/serial_number"
                    android:layout_marginLeft="10dip"
                    android:layout_marginRight="20dip"
                    android:layout_marginBottom="7dip" />
            </TableRow>

            <!-- Issued by: -->
@@ -117,7 +126,8 @@
                android:text="@string/issued_by"
                android:textStyle="bold"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:layout_width="match_parent"
                android:layout_marginTop="12dip"
                android:layout_marginLeft="20dip"
                android:layout_marginRight="20dip"
                android:layout_marginBottom="7dip" />
@@ -127,12 +137,10 @@
                <TextView
                    android:id="@+id/by_common_header"
                    android:text="@string/common_name"
                    android:gravity="left"
                    android:layout_marginLeft="20dip" />

                <TextView
                    android:id="@+id/by_common"
                    android:gravity="left"
                    android:layout_marginLeft="10dip"
                    android:layout_marginRight="20dip"
                    android:layout_marginBottom="7dip" />
@@ -143,12 +151,10 @@
                <TextView
                    android:id="@+id/by_org_header"
                    android:text="@string/org_name"
                    android:gravity="left"
                    android:layout_marginLeft="20dip" />

                <TextView
                    android:id="@+id/by_org"
                    android:gravity="left"
                    android:layout_marginLeft="10dip"
                    android:layout_marginRight="20dip"
                    android:layout_marginBottom="7dip" />
@@ -159,24 +165,23 @@
                <TextView
                    android:id="@+id/by_org_unit_header"
                    android:text="@string/org_unit"
                    android:gravity="left"
                    android:layout_marginLeft="20dip" />

                <TextView
                    android:id="@+id/by_org_unit"
                    android:gravity="left"
                    android:layout_marginLeft="10dip"
                    android:layout_marginRight="20dip"
                    android:layout_marginBottom="12dip" />
                    android:layout_marginBottom="7dip" />
            </TableRow>

            <!-- Validity Dates: -->
            <TextView
                android:id="@+id/validity_header"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:layout_width="match_parent"
                android:text="@string/validity_period"
                android:textStyle="bold"
                android:layout_marginTop="12dip"
                android:layout_marginLeft="20dip"
                android:layout_marginRight="20dip"
                android:layout_marginBottom="7dip" />
@@ -185,17 +190,15 @@
            <TableRow>
                <TextView
                    android:id="@+id/issued_on_header"
                    android:layout_width="wrap_content"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/issued_on"
                    android:gravity="left"
                    android:layout_marginLeft="20dip" />

                <TextView
                    android:id="@+id/issued_on"
                    android:layout_height="wrap_content"
                    android:layout_width="wrap_content"
                    android:gravity="left"
                    android:layout_width="match_parent"
                    android:layout_marginLeft="10dip"
                    android:layout_marginRight="20dip"
                    android:layout_marginBottom="7dip" />
@@ -206,20 +209,68 @@
            <TableRow>
                <TextView
                    android:id="@+id/expires_on_header"
                    android:layout_width="wrap_content"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/expires_on"
                    android:gravity="left"
                    android:layout_marginLeft="20dip" />

                <TextView
                    android:id="@+id/expires_on"
                    android:layout_height="wrap_content"
                    android:layout_width="wrap_content"
                    android:gravity="left"
                    android:layout_width="match_parent"
                    android:layout_marginLeft="10dip"
                    android:layout_marginRight="20dip"
                    android:layout_marginBottom="12dip" />
                    android:layout_marginBottom="7dip" />
            </TableRow>

            <!-- Fingerprints: -->
            <TextView
                android:id="@+id/fingerprints"
                android:layout_height="wrap_content"
                android:layout_width="match_parent"
                android:text="@string/fingerprints"
                android:textStyle="bold"
                android:layout_marginTop="12dip"
                android:layout_marginLeft="20dip"
                android:layout_marginRight="20dip"
                android:layout_marginBottom="7dip" />

            <!-- SHA-256 fingerprint: -->
            <TableRow>
                <TextView
                    android:id="@+id/sha256_fingerprint_header"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/sha256_fingerprint"
                    android:layout_marginLeft="20dip" />

                <TextView
                    android:id="@+id/sha256_fingerprint"
                    android:layout_height="wrap_content"
                    android:layout_width="match_parent"
                    android:layout_marginLeft="10dip"
                    android:layout_marginRight="20dip"
                    android:layout_marginBottom="7dip" />

            </TableRow>

            <!-- SHA-1 fingerprint: -->
            <TableRow>
                <TextView
                    android:id="@+id/sha1_fingerprint_header"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/sha1_fingerprint"
                    android:layout_marginLeft="20dip" />

                <TextView
                    android:id="@+id/sha1_fingerprint"
                    android:layout_height="wrap_content"
                    android:layout_width="match_parent"
                    android:layout_marginLeft="10dip"
                    android:layout_marginRight="20dip"
                    android:layout_marginBottom="7dip" />

            </TableRow>

        </TableLayout>
+236 −193

File changed.

Preview size limit exceeded, changes collapsed.

+8 −0
Original line number Diff line number Diff line
@@ -2989,6 +2989,14 @@
    <string name="issued_on">Issued on:</string>
    <!-- Label for an information field on an SSL Certificate Dialog -->
    <string name="expires_on">Expires on:</string>
    <!-- Label for an information field on an SSL Certificate Dialog -->
    <string name="serial_number">Serial number:</string>
    <!-- Label for an information field on an SSL Certificate Dialog -->
    <string name="fingerprints">Fingerprints:</string>
    <!-- Label for an information field on an SSL Certificate Dialog -->
    <string name="sha256_fingerprint">SHA-256 fingerprint:</string>
    <!-- Label for an information field on an SSL Certificate Dialog -->
    <string name="sha1_fingerprint">SHA-1 fingerprint:</string>

    <!-- Title for a button to expand the list of activities in ActivityChooserView [CHAR LIMIT=25] -->
    <string name="activity_chooser_view_see_all">See all...</string>