Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / net / cert / cert_verify_proc_android.cc
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.
4
5 #include "net/cert/cert_verify_proc_android.h"
6
7 #include <string>
8 #include <vector>
9
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"
21
22 namespace net {
23
24 namespace {
25
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;
33
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;
60   }
61
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]);
67     }
68     scoped_refptr<X509Certificate> verified_cert =
69         X509Certificate::CreateFromDERCertChain(verified_chain_pieces);
70     if (verified_cert)
71       verify_result->verified_cert = verified_cert;
72   }
73
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;
79
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);
84
85     HashValue sha256(HASH_VALUE_SHA256);
86     crypto::SHA256HashString(spki_bytes, sha256.data(), crypto::kSHA256Length);
87     verify_result->public_key_hashes.push_back(sha256);
88   }
89
90   return true;
91 }
92
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();
98
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);
103
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);
111   }
112   return true;
113 }
114
115 }  // namespace
116
117 CertVerifyProcAndroid::CertVerifyProcAndroid() {}
118
119 CertVerifyProcAndroid::~CertVerifyProcAndroid() {}
120
121 bool CertVerifyProcAndroid::SupportsAdditionalTrustAnchors() const {
122   return false;
123 }
124
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;
135   }
136
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;
143   }
144   if (IsCertStatusError(verify_result->cert_status))
145     return MapCertStatusToNetError(verify_result->cert_status);
146
147   return OK;
148 }
149
150 }  // namespace net