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
;
46 verify_result
->cert_status
|= CERT_STATUS_INVALID
;
52 bool GetChainDEREncodedBytes(X509Certificate
* cert
,
53 std::vector
<std::string
>* chain_bytes
) {
54 X509Certificate::OSCertHandle cert_handle
= cert
->os_cert_handle();
55 X509Certificate::OSCertHandles cert_handles
=
56 cert
->GetIntermediateCertificates();
58 // Make sure the peer's own cert is the first in the chain, if it's not
60 if (cert_handles
.empty() || cert_handles
[0] != cert_handle
)
61 cert_handles
.insert(cert_handles
.begin(), cert_handle
);
63 chain_bytes
->reserve(cert_handles
.size());
64 for (X509Certificate::OSCertHandles::const_iterator it
=
65 cert_handles
.begin(); it
!= cert_handles
.end(); ++it
) {
66 std::string cert_bytes
;
67 if(!X509Certificate::GetDEREncoded(*it
, &cert_bytes
))
69 chain_bytes
->push_back(cert_bytes
);
76 CertVerifyProcAndroid::CertVerifyProcAndroid() {}
78 CertVerifyProcAndroid::~CertVerifyProcAndroid() {}
80 bool CertVerifyProcAndroid::SupportsAdditionalTrustAnchors() const {
84 int CertVerifyProcAndroid::VerifyInternal(
85 X509Certificate
* cert
,
86 const std::string
& hostname
,
89 const CertificateList
& additional_trust_anchors
,
90 CertVerifyResult
* verify_result
) {
91 if (!cert
->VerifyNameMatch(hostname
))
92 verify_result
->cert_status
|= CERT_STATUS_COMMON_NAME_INVALID
;
94 std::vector
<std::string
> cert_bytes
;
95 if (!GetChainDEREncodedBytes(cert
, &cert_bytes
))
96 return ERR_CERT_INVALID
;
97 if (!VerifyFromAndroidTrustManager(cert_bytes
, verify_result
)) {
101 if (IsCertStatusError(verify_result
->cert_status
))
102 return MapCertStatusToNetError(verify_result
->cert_status
);
104 // TODO(ppi): Implement missing functionality: yielding the constructed trust
105 // chain, public key hashes of its certificates and |is_issued_by_known_root|
106 // flag. All of the above require specific support from the platform, missing
107 // in the Java APIs. See also: http://crbug.com/116838
109 // Until the required support is available in the platform, we don't know if
110 // the trust root at the end of the chain was standard or user-added, so we
111 // mark all correctly verified certificates as issued by a known root.
112 verify_result
->is_issued_by_known_root
= true;