Commit 23073f97 authored by davidben@chromium.org's avatar davidben@chromium.org

Export verified_cert and public_key_hashes on Android.

On API level 17 and up, X509TrustManager can export the verified chain. Use it
to populate some of the fields in CertVerifyResult. Also correctly populate
is_issued_by_known_root and enable intranet host checking.

Add a test to make sure non-standard roots get flagged as such. If the APIs
are not available, is_issued_by_known_root is always false.

BUG=116838,147945
TEST=CertVerifyProcTest.PublicKeyHashes
     CertVerifyProcTest.VerifyReturnChainBasic
     CertVerifyProcTest.VerifyReturnChainFiltersUnrelatedCerts
     CertVerifyProcTest.VerifyReturnChainProperlyOrdered
     CertVerifyProcTest.IntranetHostsRejected
     CertVerifyProcTest.IsIssuedByKnownRootIgnoresTestRoots
     CertVerifyProcTest.ExtraneousMD5RootCert
     CertVerifyProcTest.NameConstraintsFailure

Review URL: https://codereview.chromium.org/108653013

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@245649 0039d316-1c4b-4281-b951-d872f2087c98
parent 56aca707
......@@ -59,7 +59,7 @@ $(call intermediates-dir-for,GYP,shared)/templates/org/chromium/content/browser/
$(call intermediates-dir-for,GYP,shared)/templates/org/chromium/content/common/ResultCodes.java \
$(call intermediates-dir-for,GYP,shared)/templates/org/chromium/media/ImageFormat.java \
$(call intermediates-dir-for,GYP,shared)/templates/org/chromium/net/CertificateMimeType.java \
$(call intermediates-dir-for,GYP,shared)/templates/org/chromium/net/CertVerifyResultAndroid.java \
$(call intermediates-dir-for,GYP,shared)/templates/org/chromium/net/CertVerifyStatusAndroid.java \
$(call intermediates-dir-for,GYP,shared)/templates/org/chromium/net/NetError.java \
$(call intermediates-dir-for,GYP,shared)/templates/org/chromium/net/PrivateKeyType.java \
$(call intermediates-dir-for,GYP,shared)/templates/org/chromium/ui/WindowOpenDisposition.java \
......
......@@ -23,7 +23,7 @@
'../content/content.gyp:speech_recognition_error_java',
'../media/media.gyp:media_android_imageformat_list',
'../net/net.gyp:certificate_mime_types_java',
'../net/net.gyp:cert_verify_result_android_java',
'../net/net.gyp:cert_verify_status_android_java',
'../net/net.gyp:net_errors_java',
'../net/net.gyp:private_key_types_java',
'../ui/android/ui_android.gyp:window_open_disposition_java',
......
......@@ -18,7 +18,6 @@ M C CSM: Shouldn't use synchronized method, please narrow down the synchronizati
M C CST: Shouldn't use synchronized(this), please narrow down the synchronization scope. At HttpAuthDatabase.java
M C CST: Shouldn't use synchronized(this), please narrow down the synchronization scope. At SimpleSynchronizedThis.java
M C RCN: Nullcheck of GestureDetector.mVelocityTracker at line 639 of value previously dereferenced in org.chromium.content.browser.third_party.GestureDetector.onTouchEvent(MotionEvent) At GestureDetector.java
M C USELESS_STRING: Invocation of toString on certChain in org.chromium.net.X509Util.verifyServerCertificates(byte[][], String) At X509Util.java
M D DMI: Hard coded reference to an absolute pathname in org.chromium.android_webview.test.ArchiveTest.testAutoBadPath() At ArchiveTest.java
M D DMI: Hard coded reference to an absolute pathname in org.chromium.android_webview.test.ArchiveTest.testExplicitBadPath() At ArchiveTest.java
M D SF: Switch statement found in org.chromium.chrome.browser.ChromeBrowserProvider.insert(Uri, ContentValues) where one case falls through to the next case At ChromeBrowserProvider.java
......
# List of suppressions.
CertVerifyProcTest.PublicKeyHashes
CertVerifyProcTest.VerifyReturnChainBasic
CertVerifyProcTest.VerifyReturnChainFiltersUnrelatedCerts
CertVerifyProcTest.VerifyReturnChainProperlyOrdered
# Bug: 171812
MultiThreadedCertVerifierTest.CancelRequest
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/android/cert_verify_result_android.h"
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "jni/AndroidCertVerifyResult_jni.h"
using base::android::AttachCurrentThread;
using base::android::JavaArrayOfByteArrayToStringVector;
namespace net {
namespace android {
void ExtractCertVerifyResult(jobject result,
CertVerifyStatusAndroid* status,
bool* is_issued_by_known_root,
std::vector<std::string>* verified_chain) {
JNIEnv* env = AttachCurrentThread();
*status = static_cast<CertVerifyStatusAndroid>(
Java_AndroidCertVerifyResult_getStatus(env, result));
*is_issued_by_known_root =
Java_AndroidCertVerifyResult_isIssuedByKnownRoot(env, result);
ScopedJavaLocalRef<jobjectArray> chain_byte_array =
Java_AndroidCertVerifyResult_getCertificateChainEncoded(env, result);
JavaArrayOfByteArrayToStringVector(
env, chain_byte_array.obj(), verified_chain);
}
bool RegisterCertVerifyResult(JNIEnv* env) {
return RegisterNativesImpl(env);
}
} // namespace android
} // namespace net
......@@ -5,18 +5,32 @@
#ifndef NET_ANDROID_CERT_VERIFY_RESULT_ANDROID_H_
#define NET_ANDROID_CERT_VERIFY_RESULT_ANDROID_H_
#include <jni.h>
#include <string>
#include <vector>
#include "base/basictypes.h"
namespace net {
namespace android {
enum CertVerifyResultAndroid {
#define CERT_VERIFY_RESULT_ANDROID(label, value) VERIFY_ ## label = value,
#include "net/android/cert_verify_result_android_list.h"
#undef CERT_VERIFY_RESULT_ANDROID
enum CertVerifyStatusAndroid {
#define CERT_VERIFY_STATUS_ANDROID(label, value) VERIFY_ ## label = value,
#include "net/android/cert_verify_status_android_list.h"
#undef CERT_VERIFY_STATUS_ANDROID
};
// Extract parameters out of an AndroidCertVerifyResult object.
void ExtractCertVerifyResult(jobject result,
CertVerifyStatusAndroid* status,
bool* is_issued_by_known_root,
std::vector<std::string>* verified_chain);
// Register JNI methods.
bool RegisterCertVerifyResult(JNIEnv* env);
} // namespace android
} // namespace net
......
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
......@@ -9,23 +9,23 @@
// from Java side to the C++ side.
// Certificate is trusted.
CERT_VERIFY_RESULT_ANDROID(OK, 0)
CERT_VERIFY_STATUS_ANDROID(OK, 0)
// Certificate verification could not be conducted.
CERT_VERIFY_RESULT_ANDROID(FAILED, -1)
CERT_VERIFY_STATUS_ANDROID(FAILED, -1)
// Certificate is not trusted due to non-trusted root of the certificate chain.
CERT_VERIFY_RESULT_ANDROID(NO_TRUSTED_ROOT, -2)
CERT_VERIFY_STATUS_ANDROID(NO_TRUSTED_ROOT, -2)
// Certificate is not trusted because it has expired.
CERT_VERIFY_RESULT_ANDROID(EXPIRED, -3)
CERT_VERIFY_STATUS_ANDROID(EXPIRED, -3)
// Certificate is not trusted because it is not valid yet.
CERT_VERIFY_RESULT_ANDROID(NOT_YET_VALID, -4)
CERT_VERIFY_STATUS_ANDROID(NOT_YET_VALID, -4)
// Certificate is not trusted because it could not be parsed.
CERT_VERIFY_RESULT_ANDROID(UNABLE_TO_PARSE, -5)
CERT_VERIFY_STATUS_ANDROID(UNABLE_TO_PARSE, -5)
// Certificate is not trusted because it has an extendedKeyUsage field, but
// its value is not correct for a web server.
CERT_VERIFY_RESULT_ANDROID(INCORRECT_KEY_USAGE, -6)
CERT_VERIFY_STATUS_ANDROID(INCORRECT_KEY_USAGE, -6)
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.net;
public class CertVerifyResultAndroid {
#define CERT_VERIFY_RESULT_ANDROID(name, value) public static final int VERIFY_##name = value;
#include "net/android/cert_verify_result_android_list.h"
public class CertVerifyStatusAndroid {
#define CERT_VERIFY_STATUS_ANDROID(name, value) public static final int VERIFY_##name = value;
#include "net/android/cert_verify_status_android_list.h"
}
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.net;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* The result of a certification verification.
*/
@JNINamespace("net::android")
public class AndroidCertVerifyResult {
/**
* The verification status. One of the values in CertVerifyStatusAndroid.
*/
private final int mStatus;
/**
* True if the root CA in the chain is in the system store.
*/
private final boolean mIsIssuedByKnownRoot;
/**
* The properly ordered certificate chain used for verification.
*/
private final List<X509Certificate> mCertificateChain;
public AndroidCertVerifyResult(int status,
boolean isIssuedByKnownRoot,
List<X509Certificate> certificateChain) {
mStatus = status;
mIsIssuedByKnownRoot = isIssuedByKnownRoot;
mCertificateChain = new ArrayList<X509Certificate>(certificateChain);
}
public AndroidCertVerifyResult(int status) {
mStatus = status;
mIsIssuedByKnownRoot = false;
mCertificateChain = Collections.<X509Certificate>emptyList();
}
@CalledByNative
public int getStatus() {
return mStatus;
}
@CalledByNative
public boolean isIssuedByKnownRoot() {
return mIsIssuedByKnownRoot;
}
@CalledByNative
public byte[][] getCertificateChainEncoded() {
byte[][] verifiedChainArray = new byte[mCertificateChain.size()][];
try {
for (int i = 0; i < mCertificateChain.size(); i++) {
verifiedChainArray[i] = mCertificateChain.get(i).getEncoded();
}
} catch (CertificateEncodingException e) {
return new byte[0][];
}
return verifiedChainArray;
}
}
......@@ -198,20 +198,24 @@ class AndroidNetworkLibrary {
}
/**
* Validate the server's certificate chain is trusted.
* Validate the server's certificate chain is trusted. Note that the caller
* must still verify the name matches that of the leaf certificate.
*
* @param certChain The ASN.1 DER encoded bytes for certificates.
* @param authType The key exchange algorithm name (e.g. RSA)
* @param authType The key exchange algorithm name (e.g. RSA).
* @param host The hostname of the server.
* @return Android certificate verification result code.
*/
@CalledByNative
public static int verifyServerCertificates(byte[][] certChain, String authType) {
public static AndroidCertVerifyResult verifyServerCertificates(byte[][] certChain,
String authType,
String host) {
try {
return X509Util.verifyServerCertificates(certChain, authType);
return X509Util.verifyServerCertificates(certChain, authType, host);
} catch (KeyStoreException e) {
return CertVerifyResultAndroid.VERIFY_FAILED;
return new AndroidCertVerifyResult(CertVerifyStatusAndroid.VERIFY_FAILED);
} catch (NoSuchAlgorithmException e) {
return CertVerifyResultAndroid.VERIFY_FAILED;
return new AndroidCertVerifyResult(CertVerifyStatusAndroid.VERIFY_FAILED);
}
}
......
......@@ -18,6 +18,7 @@ namespace net {
namespace android {
static base::android::RegistrationMethod kNetRegisteredMethods[] = {
{ "AndroidCertVerifyResult", net::android::RegisterCertVerifyResult },
{ "AndroidKeyStore", net::android::RegisterKeyStore },
{ "AndroidNetworkLibrary", net::android::RegisterNetworkLibrary },
{ "GURLUtils", net::RegisterGURLUtils },
......
......@@ -23,9 +23,12 @@ using base::android::ToJavaByteArray;
namespace net {
namespace android {
CertVerifyResultAndroid VerifyX509CertChain(
const std::vector<std::string>& cert_chain,
const std::string& auth_type) {
void VerifyX509CertChain(const std::vector<std::string>& cert_chain,
const std::string& auth_type,
const std::string& host,
CertVerifyStatusAndroid* status,
bool* is_issued_by_known_root,
std::vector<std::string>* verified_chain) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jobjectArray> chain_byte_array =
......@@ -36,10 +39,20 @@ CertVerifyResultAndroid VerifyX509CertChain(
ConvertUTF8ToJavaString(env, auth_type);
DCHECK(!auth_string.is_null());
jint result = Java_AndroidNetworkLibrary_verifyServerCertificates(
env, chain_byte_array.obj(), auth_string.obj());
ScopedJavaLocalRef<jstring> host_string =
ConvertUTF8ToJavaString(env, host);
DCHECK(!host_string.is_null());
return static_cast<CertVerifyResultAndroid>(result);
ScopedJavaLocalRef<jobject> result =
Java_AndroidNetworkLibrary_verifyServerCertificates(
env, chain_byte_array.obj(), auth_string.obj(), host_string.obj());
if (ClearException(env)) {
*status = android::VERIFY_FAILED;
return;
}
ExtractCertVerifyResult(result.obj(),
status, is_issued_by_known_root, verified_chain);
}
void AddTestRootCertificate(const uint8* cert, size_t len) {
......
......@@ -21,9 +21,12 @@ namespace android {
// |cert_chain| is DER encoded chain of certificates, with the server's own
// certificate listed first.
// |auth_type| is as per the Java X509Certificate.checkServerTrusted method.
CertVerifyResultAndroid VerifyX509CertChain(
const std::vector<std::string>& cert_chain,
const std::string& auth_type);
void VerifyX509CertChain(const std::vector<std::string>& cert_chain,
const std::string& auth_type,
const std::string& host,
CertVerifyStatusAndroid* status,
bool* is_issued_by_known_root,
std::vector<std::string>* verified_chain);
// Adds a certificate as a root trust certificate to the trust manager.
// |cert| is DER encoded certificate, |len| is its length in bytes.
......
......@@ -261,21 +261,16 @@ int CertVerifyProc::Verify(X509Certificate* cert,
rv = MapCertStatusToNetError(verify_result->cert_status);
}
#if !defined(OS_ANDROID)
// Flag certificates from publicly-trusted CAs that are issued to intranet
// hosts. While the CA/Browser Forum Baseline Requirements (v1.1) permit
// these to be issued until 1 November 2015, they represent a real risk for
// the deployment of gTLDs and are being phased out ahead of the hard
// deadline.
//
// TODO(ppi): is_issued_by_known_root is incorrect on Android. Once this is
// fixed, re-enable this check for Android. crbug.com/116838
if (verify_result->is_issued_by_known_root && IsHostnameNonUnique(hostname)) {
verify_result->cert_status |= CERT_STATUS_NON_UNIQUE_NAME;
// CERT_STATUS_NON_UNIQUE_NAME will eventually become a hard error. For
// now treat it as a warning and do not map it to an error return value.
}
#endif
return rv;
}
......
......@@ -8,9 +8,13 @@
#include <vector>
#include "base/logging.h"
#include "base/sha1.h"
#include "base/strings/string_piece.h"
#include "crypto/sha2.h"
#include "net/android/cert_verify_result_android.h"
#include "net/android/network_library.h"
#include "net/base/net_errors.h"
#include "net/cert/asn1_util.h"
#include "net/cert/cert_status_flags.h"
#include "net/cert/cert_verify_result.h"
#include "net/cert/x509_certificate.h"
......@@ -22,11 +26,16 @@ namespace {
// Returns true if the certificate verification call was successful (regardless
// of its result), i.e. if |verify_result| was set. Otherwise returns false.
bool VerifyFromAndroidTrustManager(const std::vector<std::string>& cert_bytes,
const std::string& hostname,
CertVerifyResult* verify_result) {
android::CertVerifyStatusAndroid status;
std::vector<std::string> verified_chain;
// TODO(joth): Fetch the authentication type from SSL rather than hardcode.
android::CertVerifyResultAndroid android_result =
android::VerifyX509CertChain(cert_bytes, "RSA");
switch (android_result) {
android::VerifyX509CertChain(cert_bytes, "RSA", hostname,
&status, &verify_result->is_issued_by_known_root,
&verified_chain);
switch (status) {
case android::VERIFY_FAILED:
return false;
case android::VERIFY_OK:
......@@ -49,6 +58,35 @@ bool VerifyFromAndroidTrustManager(const std::vector<std::string>& cert_bytes,
verify_result->cert_status |= CERT_STATUS_INVALID;
break;
}
// Save the verified chain.
if (!verified_chain.empty()) {
std::vector<base::StringPiece> verified_chain_pieces(verified_chain.size());
for (size_t i = 0; i < verified_chain.size(); i++) {
verified_chain_pieces[i] = base::StringPiece(verified_chain[i]);
}
scoped_refptr<X509Certificate> verified_cert =
X509Certificate::CreateFromDERCertChain(verified_chain_pieces);
if (verified_cert)
verify_result->verified_cert = verified_cert;
}
// Extract the public key hashes.
for (size_t i = 0; i < verified_chain.size(); i++) {
base::StringPiece spki_bytes;
if (!asn1::ExtractSPKIFromDERCert(verified_chain[i], &spki_bytes))
continue;
HashValue sha1(HASH_VALUE_SHA1);
base::SHA1HashBytes(reinterpret_cast<const uint8*>(spki_bytes.data()),
spki_bytes.size(), sha1.data());
verify_result->public_key_hashes.push_back(sha1);
HashValue sha256(HASH_VALUE_SHA256);
crypto::SHA256HashString(spki_bytes, sha256.data(), crypto::kSHA256Length);
verify_result->public_key_hashes.push_back(sha256);
}
return true;
}
......@@ -99,7 +137,7 @@ int CertVerifyProcAndroid::VerifyInternal(
std::vector<std::string> cert_bytes;
if (!GetChainDEREncodedBytes(cert, &cert_bytes))
return ERR_CERT_INVALID;
if (!VerifyFromAndroidTrustManager(cert_bytes, verify_result)) {
if (!VerifyFromAndroidTrustManager(cert_bytes, hostname, verify_result)) {
NOTREACHED();
return ERR_FAILED;
}
......@@ -111,11 +149,6 @@ int CertVerifyProcAndroid::VerifyInternal(
// flag. All of the above require specific support from the platform, missing
// in the Java APIs. See also: http://crbug.com/116838
// Until the required support is available in the platform, we don't know if
// the trust root at the end of the chain was standard or user-added, so we
// mark all correctly verified certificates as issued by a known root.
verify_result->is_issued_by_known_root = true;
return OK;
}
......
......@@ -29,6 +29,8 @@
#include "base/win/windows_version.h"
#elif defined(OS_MACOSX) && !defined(OS_IOS)
#include "base/mac/mac_util.h"
#elif defined(OS_ANDROID)
#include "base/android/build_info.h"
#endif
using base::HexEncode;
......@@ -83,6 +85,26 @@ int WellKnownCaCertVerifyProc::VerifyInternal(
return OK;
}
bool SupportsReturningVerifiedChain() {
#if defined(OS_ANDROID)
// Before API level 17, Android does not expose the APIs necessary to get at
// the verified certificate chain.
if (base::android::BuildInfo::GetInstance()->sdk_int() < 17)
return false;
#endif
return true;
}
bool SupportsDetectingKnownRoots() {
#if defined(OS_ANDROID)
// Before API level 17, Android does not expose the APIs necessary to get at
// the verified certificate chain and detect known roots.
if (base::android::BuildInfo::GetInstance()->sdk_int() < 17)
return false;
#endif
return true;
}
} // namespace
class CertVerifyProcTest : public testing::Test {
......@@ -398,14 +420,15 @@ TEST_F(CertVerifyProcTest, RejectWeakKeys) {
// provided by servers. See CertVerifyProcTest.CybertrustGTERoot for further
// details.
#define MAYBE_ExtraneousMD5RootCert DISABLED_ExtraneousMD5RootCert
#elif defined(USE_OPENSSL) || defined(OS_ANDROID)
// Disabled for OpenSSL / Android - Android and OpenSSL do not attempt to find
// a minimal certificate chain, thus prefer the MD5 root over the SHA-1 root.
#define MAYBE_ExtraneousMD5RootCert DISABLED_ExtraneousMD5RootCert
#else
#define MAYBE_ExtraneousMD5RootCert ExtraneousMD5RootCert
#endif
TEST_F(CertVerifyProcTest, MAYBE_ExtraneousMD5RootCert) {
if (!SupportsReturningVerifiedChain()) {
LOG(INFO) << "Skipping this test in this platform.";
return;
}
base::FilePath certs_dir = GetTestCertsDirectory();
scoped_refptr<X509Certificate> server_cert =
......@@ -554,13 +577,12 @@ TEST_F(CertVerifyProcTest, NameConstraintsOk) {
EXPECT_EQ(0U, verify_result.cert_status);
}
#if defined(OS_ANDROID)
// Disabled because Android isn't filling in SPKI hashes: crbug.com/116838.
#define MAYBE_NameConstraintsFailure DISABLED_NameConstraintsFailure
#else
#define MAYBE_NameConstraintsFailure NameConstraintsFailure
#endif
TEST_F(CertVerifyProcTest, MAYBE_NameConstraintsFailure) {
TEST_F(CertVerifyProcTest, NameConstraintsFailure) {
if (!SupportsReturningVerifiedChain()) {
LOG(INFO) << "Skipping this test in this platform.";
return;
}
CertificateList ca_cert_list =
CreateCertificateListFromFile(GetTestCertsDirectory(),
"root_ca_cert.pem",
......@@ -591,8 +613,12 @@ TEST_F(CertVerifyProcTest, MAYBE_NameConstraintsFailure) {
verify_result.cert_status & CERT_STATUS_NAME_CONSTRAINT_VIOLATION);
}
// The certse.pem certificate has been revoked. crbug.com/259723.
TEST_F(CertVerifyProcTest, TestKnownRoot) {
if (!SupportsDetectingKnownRoots()) {
LOG(INFO) << "Skipping this test in this platform.";
return;
}
base::FilePath certs_dir = GetTestCertsDirectory();
CertificateList certs = CreateCertificateListFromFile(
certs_dir, "satveda.pem", X509Certificate::FORMAT_AUTO);
......@@ -622,6 +648,11 @@ TEST_F(CertVerifyProcTest, TestKnownRoot) {
// The certse.pem certificate has been revoked. crbug.com/259723.
TEST_F(CertVerifyProcTest, PublicKeyHashes) {
if (!SupportsReturningVerifiedChain()) {
LOG(INFO) << "Skipping this test in this platform.";
return;
}
base::FilePath certs_dir = GetTestCertsDirectory();
CertificateList certs = CreateCertificateListFromFile(
certs_dir, "satveda.pem", X509Certificate::FORMAT_AUTO);
......@@ -717,6 +748,11 @@ TEST_F(CertVerifyProcTest, InvalidKeyUsage) {
// used to ensure that the actual, verified chain is being returned by
// Verify().
TEST_F(CertVerifyProcTest, VerifyReturnChainBasic) {
if (!SupportsReturningVerifiedChain()) {
LOG(INFO) << "Skipping this test in this platform.";
return;
}
base::FilePath certs_dir = GetTestCertsDirectory();
CertificateList certs = CreateCertificateListFromFile(
certs_dir, "x509_verify_results.chain.pem",
......@@ -759,19 +795,16 @@ TEST_F(CertVerifyProcTest, VerifyReturnChainBasic) {
certs[2]->os_cert_handle()));
}
#if defined(OS_ANDROID)
// TODO(ppi): Disabled because is_issued_by_known_root is incorrect on Android.
// Once this is fixed, re-enable this check for android. crbug.com/116838
#define MAYBE_IntranetHostsRejected DISABLED_IntranetHostsRejected
#else
#define MAYBE_IntranetHostsRejected IntranetHostsRejected
#endif
// Test that certificates issued for 'intranet' names (that is, containing no
// known public registry controlled domain information) issued by well-known
// CAs are flagged appropriately, while certificates that are issued by
// internal CAs are not flagged.
TEST_F(CertVerifyProcTest, MAYBE_IntranetHostsRejected) {
TEST_F(CertVerifyProcTest, IntranetHostsRejected) {
if (!SupportsDetectingKnownRoots()) {
LOG(INFO) << "Skipping this test in this platform.";
return;
}
CertificateList cert_list = CreateCertificateListFromFile(
GetTestCertsDirectory(), "ok_cert.pem",
X509Certificate::FORMAT_AUTO);
......@@ -802,6 +835,11 @@ TEST_F(CertVerifyProcTest, MAYBE_IntranetHostsRejected) {
// of intermediate certificates are combined, it's possible that order may
// not be maintained.
TEST_F(CertVerifyProcTest, VerifyReturnChainProperlyOrdered) {
if (!SupportsReturningVerifiedChain()) {
LOG(INFO) << "Skipping this test in this platform.";
return;
}
base::FilePath certs_dir = GetTestCertsDirectory();
CertificateList certs = CreateCertificateListFromFile(
certs_dir, "x509_verify_results.chain.pem",
......@@ -848,6 +886,11 @@ TEST_F(CertVerifyProcTest, VerifyReturnChainProperlyOrdered) {
// Test that Verify() filters out certificates which are not related to
// or part of the certificate chain being verified.
TEST_F(CertVerifyProcTest, VerifyReturnChainFiltersUnrelatedCerts) {
if (!SupportsReturningVerifiedChain()) {
LOG(INFO) << "Skipping this test in this platform.";
return;
}
base::FilePath certs_dir = GetTestCertsDirectory();
CertificateList certs = CreateCertificateListFromFile(
certs_dir, "x509_verify_results.chain.pem",
......@@ -946,6 +989,32 @@ TEST_F(CertVerifyProcTest, AdditionalTrustAnchors) {
EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor);
}
// Tests that certificates issued by user-supplied roots are not flagged as
// issued by a known root. This should pass whether or not the platform supports
// detecting known roots.
TEST_F(CertVerifyProcTest, IsIssuedByKnownRootIgnoresTestRoots) {
// Load root_ca_cert.pem into the test root store.
TestRootCerts* root_certs = TestRootCerts::GetInstance();
root_certs->AddFromFile(
GetTestCertsDirectory().AppendASCII("root_ca_cert.pem"));
CertificateList cert_list = CreateCertificateListFromFile(
GetTestCertsDirectory(), "ok_cert.pem",
X509Certificate::FORMAT_AUTO);
ASSERT_EQ(1U, cert_list.size());
scoped_refptr<X509Certificate> cert(cert_list[0]);
// Verification should pass.
int flags = 0;
CertVerifyResult verify_result;
int error = Verify(
cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_, &verify_result);
EXPECT_EQ(OK, error);
EXPECT_EQ(0U, verify_result.cert_status);
// But should not be marked as a known root.
EXPECT_FALSE(verify_result.is_issued_by_known_root);
}
#if defined(OS_MACOSX) && !defined(OS_IOS)
// Tests that, on OS X, issues with a cross-certified Baltimore CyberTrust
// Root can be successfully worked around once Apple completes removing the
......
......@@ -60,8 +60,9 @@
'net_resources',
],
'sources': [
'android/cert_verify_result_android.cc',
'android/cert_verify_result_android.h',
'android/cert_verify_result_android_list.h',
'android/cert_verify_status_android_list.h',
'android/gurl_utils.cc',
'android/gurl_utils.h',
'android/keystore.cc',
......@@ -2958,6 +2959,7 @@
'target_name': 'net_jni_headers',
'type': 'none',
'sources': [
'android/java/src/org/chromium/net/AndroidCertVerifyResult.java',
'android/java/src/org/chromium/net/AndroidKeyStore.java',
'android/java/src/org/chromium/net/AndroidNetworkLibrary.java',
'android/java/src/org/chromium/net/GURLUtils.java',
......@@ -2991,7 +2993,7 @@
},
'dependencies': [
'../base/base.gyp:base',
'cert_verify_result_android_java',
'cert_verify_status_android_java',
'certificate_mime_types_java',
'net_errors_java',
'private_key_types_java',
......@@ -3044,14 +3046,14 @@
'includes': [ '../build/android/java_cpp_template.gypi' ],
},
{
'target_name': 'cert_verify_result_android_java',
'target_name': 'cert_verify_status_android_java',
'type': 'none',
'sources': [
'android/java/CertVerifyResultAndroid.template',
'android/java/CertVerifyStatusAndroid.template',
],
'variables': {
'package_name': 'org/chromium/net',
'template_deps': ['android/cert_verify_result_android_list.h'],
'template_deps': ['android/cert_verify_status_android_list.h'],
},
'includes': [ '../build/android/java_cpp_template.gypi' ],
},
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment