public static synchronized void addCertificate(SslCertificate certificate) throws GeneralSecurityException, IOException { KeyStore localTrustStore = loadTrustStore(); X509Certificate x509Certificate = getX509CertFromSslCertHack(certificate); String alias = hashName(x509Certificate.getSubjectX500Principal()); localTrustStore.setCertificateEntry(alias, x509Certificate); saveTrustStore(localTrustStore); // reset fields so the keystore gets read again mTrustManager = null; mSslContext = null; // notify listeners synchronized (mListeners) { for (CertChangedListener l : mListeners) { l.certAdded(); } } }
/** * Obtain the X509Certificate from SslError * @param error SslError * @return X509Certificate from error */ public X509Certificate getX509CertificateFromError (SslError error) { Bundle bundle = SslCertificate.saveState(error.getCertificate()); 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 x509Certificate; }
private void showSubject(SslCertificate.DName subject, View dialogView) { TextView cnView = ((TextView)dialogView.findViewById(R.id.value_subject_CN)); cnView.setText(subject.getCName()); cnView.setVisibility(View.VISIBLE); TextView oView = ((TextView)dialogView.findViewById(R.id.value_subject_O)); oView.setText(subject.getOName()); oView.setVisibility(View.VISIBLE); TextView ouView = ((TextView)dialogView.findViewById(R.id.value_subject_OU)); ouView.setText(subject.getUName()); ouView.setVisibility(View.VISIBLE); // SslCertificates don't offer this information dialogView.findViewById(R.id.value_subject_C).setVisibility(View.GONE); dialogView.findViewById(R.id.value_subject_ST).setVisibility(View.GONE); dialogView.findViewById(R.id.value_subject_L).setVisibility(View.GONE); dialogView.findViewById(R.id.label_subject_C).setVisibility(View.GONE); dialogView.findViewById(R.id.label_subject_ST).setVisibility(View.GONE); dialogView.findViewById(R.id.label_subject_L).setVisibility(View.GONE); }
private void showIssuer(SslCertificate.DName issuer, View dialogView) { TextView cnView = ((TextView)dialogView.findViewById(R.id.value_issuer_CN)); cnView.setText(issuer.getCName()); cnView.setVisibility(View.VISIBLE); TextView oView = ((TextView)dialogView.findViewById(R.id.value_issuer_O)); oView.setText(issuer.getOName()); oView.setVisibility(View.VISIBLE); TextView ouView = ((TextView)dialogView.findViewById(R.id.value_issuer_OU)); ouView.setText(issuer.getUName()); ouView.setVisibility(View.VISIBLE); // SslCertificates don't offer this information dialogView.findViewById(R.id.value_issuer_C).setVisibility(View.GONE); dialogView.findViewById(R.id.value_issuer_ST).setVisibility(View.GONE); dialogView.findViewById(R.id.value_issuer_L).setVisibility(View.GONE); dialogView.findViewById(R.id.label_issuer_C).setVisibility(View.GONE); dialogView.findViewById(R.id.label_issuer_ST).setVisibility(View.GONE); dialogView.findViewById(R.id.label_issuer_L).setVisibility(View.GONE); }
@CalledByNative private boolean allowCertificateError(int certError, byte[] derBytes, final String url, final int id) { final SslCertificate cert = SslUtil.getCertificateFromDerBytes(derBytes); if (cert == null) { // if the certificate or the client is null, cancel the request return false; } final SslError sslError = SslUtil.sslErrorFromNetErrorCode(certError, cert, url); ValueCallback<Boolean> callback = new ValueCallback<Boolean>() { @Override public void onReceiveValue(Boolean value) { proceedSslError(value.booleanValue(), id); } }; mClient.onReceivedSslError(callback, sslError); return true; }
/** * Creates an SslError object from a chromium net error code. */ public static SslError sslErrorFromNetErrorCode(int error, SslCertificate cert, String url) { assert (error >= NetError.ERR_CERT_END && error <= NetError.ERR_CERT_COMMON_NAME_INVALID); switch(error) { case NetError.ERR_CERT_COMMON_NAME_INVALID: return new SslError(SslError.SSL_IDMISMATCH, cert, url); case NetError.ERR_CERT_DATE_INVALID: return new SslError(SslError.SSL_DATE_INVALID, cert, url); case NetError.ERR_CERT_AUTHORITY_INVALID: return new SslError(SslError.SSL_UNTRUSTED, cert, url); default: break; } // Map all other codes to SSL_INVALID. return new SslError(SslError.SSL_INVALID, cert, url); }
public static synchronized boolean isTrusted(SslCertificate cert) { if (mTrustManager == null) { KeyStore trustStore = loadTrustStore(); mTrustManager = new LocalTrustManager(trustStore); } try { mTrustManager.checkClientTrusted(new X509Certificate[]{getX509CertFromSslCertHack(cert)}, "generic"); } catch (CertificateException e) { return false; } return true; }
void saveState(SystemWebView view, Bundle bundle) { final SslCertificate certificate = view.getCertificate(); if (certificate != null) { bundle.putString(STATE_KEY_URL, view.getUrl()); bundle.putBundle(STATE_KEY_CERTIFICATE, SslCertificate.saveState(certificate)); } }
@Override public void onPageFinished(AmazonWebView view, final String url) { SslCertificate certificate = view.getCertificate(); if (!TextUtils.isEmpty(restoredUrl)) { if (restoredUrl.equals(url) && certificate == null) { // We just restored the previous state. Let's re-use the certificate we restored. // The reason for that is that WebView doesn't restore the certificate itself. // Without restoring the certificate manually we'd lose the certificate when // switching tabs or restoring a previous session for other reasons. certificate = restoredCertificate; } else { // The URL has changed since we restored the last state. Let's just clear all // restored data because we do not need it anymore. restoredUrl = null; restoredCertificate = null; } } if (callback != null) { callback.onPageFinished(certificate != null); // The URL which is supplied in onPageFinished() could be fake (see #301), but webview's // URL is always correct _except_ for error pages final String viewURL = view.getUrl(); if (!UrlUtils.isInternalErrorURL(viewURL) && viewURL != null) { callback.onURLChanged(viewURL); } } super.onPageFinished(view, url); // evaluateJavascript(view, // "(function() {" + // // CLEAR_VISITED_CSS + // // "})();"); }
void saveState(WebView view, Bundle bundle) { final SslCertificate certificate = view.getCertificate(); if (certificate != null) { bundle.putString(STATE_KEY_URL, view.getUrl()); bundle.putBundle(STATE_KEY_CERTIFICATE, SslCertificate.saveState(certificate)); } }
@Override public void onPageFinished(WebView view, final String url) { SslCertificate certificate = view.getCertificate(); if (!TextUtils.isEmpty(restoredUrl)) { if (restoredUrl.equals(url) && certificate == null) { // We just restored the previous state. Let's re-use the certificate we restored. // The reason for that is that WebView doesn't restore the certificate itself. // Without restoring the certificate manually we'd lose the certificate when // switching tabs or restoring a previous session for other reasons. certificate = restoredCertificate; } else { // The URL has changed since we restored the last state. Let's just clear all // restored data because we do not need it anymore. restoredUrl = null; restoredCertificate = null; } } if (callback != null) { callback.onPageFinished(certificate != null); // The URL which is supplied in onPageFinished() could be fake (see #301), but webview's // URL is always correct _except_ for error pages final String viewURL = view.getUrl(); if (!UrlUtils.isInternalErrorURL(viewURL) && viewURL != null) { callback.onURLChanged(viewURL); } } super.onPageFinished(view, url); view.evaluateJavascript( "(function() {" + CLEAR_VISITED_CSS + "})();", null); }
/** * Catch (self-signed) SSL errors and test if they correspond to Syncthing's certificate. */ @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { try { int sdk = android.os.Build.VERSION.SDK_INT; if (sdk < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { // The mX509Certificate field is not available for ICS- devices Log.w(TAG, "Skipping certificate check for devices <ICS"); handler.proceed(); return; } // Use reflection to access the private mX509Certificate field of SslCertificate SslCertificate sslCert = error.getCertificate(); Field f = sslCert.getClass().getDeclaredField("mX509Certificate"); f.setAccessible(true); X509Certificate cert = (X509Certificate)f.get(sslCert); if (cert == null) { Log.w(TAG, "X509Certificate reference invalid"); handler.cancel(); return; } cert.verify(mCaCert.getPublicKey()); handler.proceed(); } catch (NoSuchFieldException|IllegalAccessException|CertificateException| NoSuchAlgorithmException|InvalidKeyException|NoSuchProviderException| SignatureException e) { Log.w(TAG, e); handler.cancel(); } }
@Override public SslCertificate getCertificate() { mFactory.startYourEngines(true); if (checkNeedsPost()) { SslCertificate ret = runOnUiThreadBlocking(new Callable<SslCertificate>() { @Override public SslCertificate call() { return getCertificate(); } }); return ret; } return mAwContents.getCertificate(); }
private X509Certificate getCertificateFromError(SslError error) throws NoSuchFieldException, IllegalAccessException { SslCertificate sslCertificate = error.getCertificate(); Field mX509CertificateField = sslCertificate.getClass().getDeclaredField("mX509Certificate"); mX509CertificateField.setAccessible(true); return (X509Certificate) mX509CertificateField.get(sslCertificate); }
public WebViewAssert hasCertificate(SslCertificate certificate) { isNotNull(); SslCertificate actualCertificate = actual.getCertificate(); assertThat(actualCertificate) // .overridingErrorMessage("Expected certificate <%s> but was <%s>.", certificate, actualCertificate) // .isSameAs(certificate); return this; }
private void addCertificateDetails(Certificate cert, byte[] sha256Digest, byte[] sha1Digest) { LinearLayout certificateView = new LinearLayout(mContext); mViews.add(certificateView); certificateView.setOrientation(LinearLayout.VERTICAL); X509Certificate x509 = (X509Certificate) cert; SslCertificate sslCert = new SslCertificate(x509); mTitles.add(sslCert.getIssuedTo().getCName()); addSectionTitle(certificateView, nativeGetCertIssuedToText()); addItem(certificateView, nativeGetCertInfoCommonNameText(), sslCert.getIssuedTo().getCName()); addItem(certificateView, nativeGetCertInfoOrganizationText(), sslCert.getIssuedTo().getOName()); addItem(certificateView, nativeGetCertInfoOrganizationUnitText(), sslCert.getIssuedTo().getUName()); addItem(certificateView, nativeGetCertInfoSerialNumberText(), formatBytes(x509.getSerialNumber().toByteArray(), ':')); addSectionTitle(certificateView, nativeGetCertIssuedByText()); addItem(certificateView, nativeGetCertInfoCommonNameText(), sslCert.getIssuedBy().getCName()); addItem(certificateView, nativeGetCertInfoOrganizationText(), sslCert.getIssuedBy().getOName()); addItem(certificateView, nativeGetCertInfoOrganizationUnitText(), sslCert.getIssuedBy().getUName()); addSectionTitle(certificateView, nativeGetCertValidityText()); java.text.DateFormat dateFormat = DateFormat.getDateFormat(mContext); addItem(certificateView, nativeGetCertIssuedOnText(), dateFormat.format(sslCert.getValidNotBeforeDate())); addItem(certificateView, nativeGetCertExpiresOnText(), dateFormat.format(sslCert.getValidNotAfterDate())); addSectionTitle(certificateView, nativeGetCertFingerprintsText()); addItem(certificateView, nativeGetCertSHA256FingerprintText(), formatBytes(sha256Digest, ' ')); addItem(certificateView, nativeGetCertSHA1FingerprintText(), formatBytes(sha1Digest, ' ')); }
void restoreState(Bundle bundle) { if (bundle != null && bundle.containsKey(STATE_KEY_CERTIFICATE)) { restoredUrl = bundle.getString(STATE_KEY_URL); restoredCertificate = SslCertificate.restoreState(bundle.getBundle("client_last_certificate")); } }
public WebViewSubject hasCertificate(SslCertificate certificate) { assertThat(actual().getCertificate()) .named("certificate") .isSameAs(certificate); return this; }
/** * @return The SSL certificate associated with the error set */ public SslCertificate getCertificate() { return mCertificate; }
private void addCertificateDetails(Certificate cert, byte[] sha256Digest, byte[] sha1Digest) { LinearLayout certificateView = new LinearLayout(mContext); mViews.add(certificateView); certificateView.setOrientation(LinearLayout.VERTICAL); X509Certificate x509 = (X509Certificate) cert; SslCertificate sslCert = new SslCertificate(x509); mTitles.add(sslCert.getIssuedTo().getCName()); addSectionTitle(certificateView, nativeGetCertIssuedToText()); addItem(certificateView, nativeGetCertInfoCommonNameText(), sslCert.getIssuedTo().getCName()); addItem(certificateView, nativeGetCertInfoOrganizationText(), sslCert.getIssuedTo().getOName()); addItem(certificateView, nativeGetCertInfoOrganizationUnitText(), sslCert.getIssuedTo().getUName()); addItem(certificateView, nativeGetCertInfoSerialNumberText(), formatBytes(x509.getSerialNumber().toByteArray(), ':')); addSectionTitle(certificateView, nativeGetCertIssuedByText()); addItem(certificateView, nativeGetCertInfoCommonNameText(), sslCert.getIssuedBy().getCName()); addItem(certificateView, nativeGetCertInfoOrganizationText(), sslCert.getIssuedBy().getOName()); addItem(certificateView, nativeGetCertInfoOrganizationUnitText(), sslCert.getIssuedBy().getUName()); addSectionTitle(certificateView, nativeGetCertValidityText()); DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM); addItem(certificateView, nativeGetCertIssuedOnText(), dateFormat.format(sslCert.getValidNotBeforeDate())); addItem(certificateView, nativeGetCertExpiresOnText(), dateFormat.format(sslCert.getValidNotAfterDate())); addSectionTitle(certificateView, nativeGetCertFingerprintsText()); addItem(certificateView, nativeGetCertSHA256FingerprintText(), formatBytes(sha256Digest, ' ')); addItem(certificateView, nativeGetCertSHA1FingerprintText(), formatBytes(sha1Digest, ' ')); }
private View getCertErrorView(final Context context, final SslCertificate certificate){ LayoutInflater factory = LayoutInflater.from(context); View certificateView = factory.inflate( R.layout.ssl_certificate, null); // issued to: SslCertificate.DName issuedTo = certificate.getIssuedTo(); if (issuedTo != null) { ((TextView) certificateView.findViewById(R.id.to_common)) .setText(issuedTo.getCName()); ((TextView) certificateView.findViewById(R.id.to_org)) .setText(issuedTo.getOName()); ((TextView) certificateView.findViewById(R.id.to_org_unit)) .setText(issuedTo.getUName()); } // issued by: SslCertificate.DName issuedBy = certificate.getIssuedBy(); if (issuedBy != null) { ((TextView) certificateView.findViewById(R.id.by_common)) .setText(issuedBy.getCName()); ((TextView) certificateView.findViewById(R.id.by_org)) .setText(issuedBy.getOName()); ((TextView) certificateView.findViewById(R.id.by_org_unit)) .setText(issuedBy.getUName()); } // issued on: String issuedOn = formatCertificateDate(context, certificate.getValidNotBeforeDate()); ((TextView) certificateView.findViewById(R.id.issued_on)) .setText(issuedOn); // expires on: String expiresOn = formatCertificateDate(context, certificate.getValidNotAfterDate()); ((TextView) certificateView.findViewById(R.id.expires_on)) .setText(expiresOn); return certificateView; }
/** * Checks the site certificate against the DNS domain name of the site being * visited * * @param certificate * The certificate to check * @param thisDomain * The DNS domain name of the site being visited * @return True iff if there is a domain match as specified by RFC2818 */ private static boolean matchDns(X509Certificate certificate, String thisDomain) { boolean hasDns = false; try { Collection<List<?>> subjectAltNames = certificate.getSubjectAlternativeNames(); if (subjectAltNames != null) { for (List<?> altNameEntry : subjectAltNames) { if ((altNameEntry != null) && (2 <= altNameEntry.size())) { Integer altNameType = (Integer)(altNameEntry.get(0)); if (altNameType != null && altNameType.intValue() == ALT_DNS_NAME) { hasDns = true; String altName = (String)(altNameEntry.get(1)); if (altName != null && matchDns(thisDomain, altName)) { return true; } } } } } } catch (CertificateParsingException e) { // one way we can get here is if an alternative name starts with // '*' character, which is contrary to one interpretation of the // spec (a valid DNS name must start with a letter); there is no // good way around this, and in order to be compatible we proceed // to check the common name (ie, ignore alternative names) if (K9.DEBUG) { String errorMessage = e.getMessage(); if (errorMessage == null) { errorMessage = "failed to parse certificate"; } Log.v(K9.LOG_TAG, "DomainNameChecker.matchDns(): " + errorMessage); } } if (!hasDns) { SslCertificate sslCertificate = new SslCertificate(certificate); return matchDns(thisDomain, sslCertificate.getIssuedTo().getCName()); } return false; }
/** * Checks the site certificate against the DNS domain name of the site being * visited * * @param certificate * The certificate to check * @param thisDomain * The DNS domain name of the site being visited * @return True iff if there is a domain match as specified by RFC2818 */ private static boolean matchDns(X509Certificate certificate, String thisDomain) { boolean hasDns = false; try { Collection<?> subjectAltNames = certificate.getSubjectAlternativeNames(); if (subjectAltNames != null) { Iterator<?> i = subjectAltNames.iterator(); while (i.hasNext()) { List<?> altNameEntry = (List<?>)(i.next()); if ((altNameEntry != null) && (2 <= altNameEntry.size())) { Integer altNameType = (Integer)(altNameEntry.get(0)); if (altNameType != null && altNameType.intValue() == ALT_DNS_NAME) { hasDns = true; String altName = (String)(altNameEntry.get(1)); if (altName != null && matchDns(thisDomain, altName)) { return true; } } } } } } catch (CertificateParsingException e) { // one way we can get here is if an alternative name starts with // '*' character, which is contrary to one interpretation of the // spec (a valid DNS name must start with a letter); there is no // good way around this, and in order to be compatible we proceed // to check the common name (ie, ignore alternative names) if (K9.DEBUG) { String errorMessage = e.getMessage(); if (errorMessage == null) { errorMessage = "failed to parse certificate"; } Log.v(K9.LOG_TAG, "DomainNameChecker.matchDns(): " + errorMessage); } } if (!hasDns) { SslCertificate sslCertificate = new SslCertificate(certificate); return matchDns(thisDomain, sslCertificate.getIssuedTo().getCName()); } return false; }
/** * @see android.webkit.WebView#getCertificate() */ public SslCertificate getCertificate() { if (mNativeAwContents == 0) return null; return SslUtil.getCertificateFromDerBytes(nativeGetCertificate(mNativeAwContents)); }
@Override public void setCertificate(SslCertificate certificate) { // intentional no-op }
/** * Constructor * * @param */ public SslCertificateViewAdapter(SslCertificate certificate) { mCertificate = certificate; }
/** * Creates a new SSL error set object * @param error The SSL error * @param certificate The associated SSL certificate */ public SslError(int error, SslCertificate certificate) { addError(error); mCertificate = certificate; }
/** * Creates a new SSL error set object * @param error The SSL error * @param certificate The associated SSL certificate */ public SslError(int error, X509Certificate certificate) { addError(error); mCertificate = new SslCertificate(certificate); }
/** * Gets the SSL certificate for the main top-level page or null if there is * no certificate (the site is not secure). * * @return the SSL certificate for the main top-level page */ public SslCertificate getCertificate() { checkThread(); return mProvider.getCertificate(); }
public SslCertificate getCertificate();
public void setCertificate(SslCertificate certificate);