Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / net / cert / cert_verify_proc_android.cc
blobbd747267a2e0c293465020e2ff35497d806f8c74
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"
7 #include <string>
8 #include <vector>
10 #include "base/logging.h"
11 #include "base/sha1.h"
12 #include "base/strings/string_piece.h"
13 #include "crypto/sha2.h"
14 #include "net/android/cert_verify_result_android.h"
15 #include "net/android/network_library.h"
16 #include "net/base/net_errors.h"
17 #include "net/cert/asn1_util.h"
18 #include "net/cert/cert_status_flags.h"
19 #include "net/cert/cert_verify_result.h"
20 #include "net/cert/x509_certificate.h"
22 namespace net {
24 namespace {
26 // Returns true if the certificate verification call was successful (regardless
27 // of its result), i.e. if |verify_result| was set. Otherwise returns false.
28 bool VerifyFromAndroidTrustManager(const std::vector<std::string>& cert_bytes,
29 const std::string& hostname,
30 CertVerifyResult* verify_result) {
31 android::CertVerifyStatusAndroid status;
32 std::vector<std::string> verified_chain;
34 // TODO(joth): Fetch the authentication type from SSL rather than hardcode.
35 android::VerifyX509CertChain(cert_bytes, "RSA", hostname,
36 &status, &verify_result->is_issued_by_known_root,
37 &verified_chain);
38 switch (status) {
39 case android::VERIFY_FAILED:
40 return false;
41 case android::VERIFY_OK:
42 break;
43 case android::VERIFY_NO_TRUSTED_ROOT:
44 verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID;
45 break;
46 case android::VERIFY_EXPIRED:
47 case android::VERIFY_NOT_YET_VALID:
48 verify_result->cert_status |= CERT_STATUS_DATE_INVALID;
49 break;
50 case android::VERIFY_UNABLE_TO_PARSE:
51 verify_result->cert_status |= CERT_STATUS_INVALID;
52 break;
53 case android::VERIFY_INCORRECT_KEY_USAGE:
54 verify_result->cert_status |= CERT_STATUS_INVALID;
55 break;
56 default:
57 NOTREACHED();
58 verify_result->cert_status |= CERT_STATUS_INVALID;
59 break;
62 // Save the verified chain.
63 if (!verified_chain.empty()) {
64 std::vector<base::StringPiece> verified_chain_pieces(verified_chain.size());
65 for (size_t i = 0; i < verified_chain.size(); i++) {
66 verified_chain_pieces[i] = base::StringPiece(verified_chain[i]);
68 scoped_refptr<X509Certificate> verified_cert =
69 X509Certificate::CreateFromDERCertChain(verified_chain_pieces);
70 if (verified_cert)
71 verify_result->verified_cert = verified_cert;
74 // Extract the public key hashes.
75 for (size_t i = 0; i < verified_chain.size(); i++) {
76 base::StringPiece spki_bytes;
77 if (!asn1::ExtractSPKIFromDERCert(verified_chain[i], &spki_bytes))
78 continue;
80 HashValue sha1(HASH_VALUE_SHA1);
81 base::SHA1HashBytes(reinterpret_cast<const uint8*>(spki_bytes.data()),
82 spki_bytes.size(), sha1.data());
83 verify_result->public_key_hashes.push_back(sha1);
85 HashValue sha256(HASH_VALUE_SHA256);
86 crypto::SHA256HashString(spki_bytes, sha256.data(), crypto::kSHA256Length);
87 verify_result->public_key_hashes.push_back(sha256);
90 return true;
93 bool GetChainDEREncodedBytes(X509Certificate* cert,
94 std::vector<std::string>* chain_bytes) {
95 X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle();
96 X509Certificate::OSCertHandles cert_handles =
97 cert->GetIntermediateCertificates();
99 // Make sure the peer's own cert is the first in the chain, if it's not
100 // already there.
101 if (cert_handles.empty() || cert_handles[0] != cert_handle)
102 cert_handles.insert(cert_handles.begin(), cert_handle);
104 chain_bytes->reserve(cert_handles.size());
105 for (X509Certificate::OSCertHandles::const_iterator it =
106 cert_handles.begin(); it != cert_handles.end(); ++it) {
107 std::string cert_bytes;
108 if(!X509Certificate::GetDEREncoded(*it, &cert_bytes))
109 return false;
110 chain_bytes->push_back(cert_bytes);
112 return true;
115 } // namespace
117 CertVerifyProcAndroid::CertVerifyProcAndroid() {}
119 CertVerifyProcAndroid::~CertVerifyProcAndroid() {}
121 bool CertVerifyProcAndroid::SupportsAdditionalTrustAnchors() const {
122 return false;
125 int CertVerifyProcAndroid::VerifyInternal(
126 X509Certificate* cert,
127 const std::string& hostname,
128 int flags,
129 CRLSet* crl_set,
130 const CertificateList& additional_trust_anchors,
131 CertVerifyResult* verify_result) {
132 if (!cert->VerifyNameMatch(hostname,
133 &verify_result->common_name_fallback_used)) {
134 verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID;
137 std::vector<std::string> cert_bytes;
138 if (!GetChainDEREncodedBytes(cert, &cert_bytes))
139 return ERR_CERT_INVALID;
140 if (!VerifyFromAndroidTrustManager(cert_bytes, hostname, verify_result)) {
141 NOTREACHED();
142 return ERR_FAILED;
144 if (IsCertStatusError(verify_result->cert_status))
145 return MapCertStatusToNetError(verify_result->cert_status);
147 return OK;
150 } // namespace net