1 // Copyright (c) 2012 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.
5 #include "net/cert/cert_verify_proc_android.h"
10 #include "base/logging.h"
11 #include "net/android/cert_verify_result_android.h"
12 #include "net/android/network_library.h"
13 #include "net/base/net_errors.h"
14 #include "net/cert/cert_status_flags.h"
15 #include "net/cert/cert_verify_result.h"
16 #include "net/cert/x509_certificate.h"
22 // Returns true if the certificate verification call was successful (regardless
23 // of its result), i.e. if |verify_result| was set. Otherwise returns false.
24 bool VerifyFromAndroidTrustManager(const std::vector
<std::string
>& cert_bytes
,
25 CertVerifyResult
* verify_result
) {
26 // TODO(joth): Fetch the authentication type from SSL rather than hardcode.
27 android::CertVerifyResultAndroid android_result
=
28 android::VerifyX509CertChain(cert_bytes
, "RSA");
29 switch (android_result
) {
30 case android::VERIFY_FAILED
:
32 case android::VERIFY_OK
:
34 case android::VERIFY_NO_TRUSTED_ROOT
:
35 verify_result
->cert_status
|= CERT_STATUS_AUTHORITY_INVALID
;
37 case android::VERIFY_EXPIRED
:
38 case android::VERIFY_NOT_YET_VALID
:
39 verify_result
->cert_status
|= CERT_STATUS_DATE_INVALID
;
41 case android::VERIFY_UNABLE_TO_PARSE
:
42 verify_result
->cert_status
|= CERT_STATUS_INVALID
;
44 case android::VERIFY_INCORRECT_KEY_USAGE
:
45 verify_result
->cert_status
|= CERT_STATUS_INVALID
;
49 verify_result
->cert_status
|= CERT_STATUS_INVALID
;
55 bool GetChainDEREncodedBytes(X509Certificate
* cert
,
56 std::vector
<std::string
>* chain_bytes
) {
57 X509Certificate::OSCertHandle cert_handle
= cert
->os_cert_handle();
58 X509Certificate::OSCertHandles cert_handles
=
59 cert
->GetIntermediateCertificates();
61 // Make sure the peer's own cert is the first in the chain, if it's not
63 if (cert_handles
.empty() || cert_handles
[0] != cert_handle
)
64 cert_handles
.insert(cert_handles
.begin(), cert_handle
);
66 chain_bytes
->reserve(cert_handles
.size());
67 for (X509Certificate::OSCertHandles::const_iterator it
=
68 cert_handles
.begin(); it
!= cert_handles
.end(); ++it
) {
69 std::string cert_bytes
;
70 if(!X509Certificate::GetDEREncoded(*it
, &cert_bytes
))
72 chain_bytes
->push_back(cert_bytes
);
79 CertVerifyProcAndroid::CertVerifyProcAndroid() {}
81 CertVerifyProcAndroid::~CertVerifyProcAndroid() {}
83 bool CertVerifyProcAndroid::SupportsAdditionalTrustAnchors() const {
87 int CertVerifyProcAndroid::VerifyInternal(
88 X509Certificate
* cert
,
89 const std::string
& hostname
,
92 const CertificateList
& additional_trust_anchors
,
93 CertVerifyResult
* verify_result
) {
94 if (!cert
->VerifyNameMatch(hostname
))
95 verify_result
->cert_status
|= CERT_STATUS_COMMON_NAME_INVALID
;
97 std::vector
<std::string
> cert_bytes
;
98 if (!GetChainDEREncodedBytes(cert
, &cert_bytes
))
99 return ERR_CERT_INVALID
;
100 if (!VerifyFromAndroidTrustManager(cert_bytes
, verify_result
)) {
104 if (IsCertStatusError(verify_result
->cert_status
))
105 return MapCertStatusToNetError(verify_result
->cert_status
);
107 // TODO(ppi): Implement missing functionality: yielding the constructed trust
108 // chain, public key hashes of its certificates and |is_issued_by_known_root|
109 // flag. All of the above require specific support from the platform, missing
110 // in the Java APIs. See also: http://crbug.com/116838
112 // Until the required support is available in the platform, we don't know if
113 // the trust root at the end of the chain was standard or user-added, so we
114 // mark all correctly verified certificates as issued by a known root.
115 verify_result
->is_issued_by_known_root
= true;