OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/cert/cert_verify_proc_android.h" | 5 #include "net/cert/cert_verify_proc_android.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/sha1.h" | |
12 #include "base/strings/string_piece.h" | |
13 #include "crypto/sha2.h" | |
11 #include "net/android/cert_verify_result_android.h" | 14 #include "net/android/cert_verify_result_android.h" |
12 #include "net/android/network_library.h" | 15 #include "net/android/network_library.h" |
13 #include "net/base/net_errors.h" | 16 #include "net/base/net_errors.h" |
17 #include "net/cert/asn1_util.h" | |
14 #include "net/cert/cert_status_flags.h" | 18 #include "net/cert/cert_status_flags.h" |
15 #include "net/cert/cert_verify_result.h" | 19 #include "net/cert/cert_verify_result.h" |
16 #include "net/cert/x509_certificate.h" | 20 #include "net/cert/x509_certificate.h" |
17 | 21 |
18 namespace net { | 22 namespace net { |
19 | 23 |
20 namespace { | 24 namespace { |
21 | 25 |
22 // Returns true if the certificate verification call was successful (regardless | 26 // Returns true if the certificate verification call was successful (regardless |
23 // of its result), i.e. if |verify_result| was set. Otherwise returns false. | 27 // of its result), i.e. if |verify_result| was set. Otherwise returns false. |
24 bool VerifyFromAndroidTrustManager(const std::vector<std::string>& cert_bytes, | 28 bool VerifyFromAndroidTrustManager(const std::vector<std::string>& cert_bytes, |
29 const std::string& hostname, | |
25 CertVerifyResult* verify_result) { | 30 CertVerifyResult* verify_result) { |
31 android::CertVerifyStatusAndroid status; | |
32 std::vector<std::string> verified_chain; | |
33 | |
26 // TODO(joth): Fetch the authentication type from SSL rather than hardcode. | 34 // TODO(joth): Fetch the authentication type from SSL rather than hardcode. |
27 android::CertVerifyResultAndroid android_result = | 35 android::VerifyX509CertChain(cert_bytes, "RSA", hostname, |
28 android::VerifyX509CertChain(cert_bytes, "RSA"); | 36 &status, &verify_result->is_issued_by_known_root, |
29 switch (android_result) { | 37 &verified_chain); |
38 switch (status) { | |
30 case android::VERIFY_FAILED: | 39 case android::VERIFY_FAILED: |
31 return false; | 40 return false; |
32 case android::VERIFY_OK: | 41 case android::VERIFY_OK: |
33 break; | 42 break; |
34 case android::VERIFY_NO_TRUSTED_ROOT: | 43 case android::VERIFY_NO_TRUSTED_ROOT: |
35 verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID; | 44 verify_result->cert_status |= CERT_STATUS_AUTHORITY_INVALID; |
36 break; | 45 break; |
37 case android::VERIFY_EXPIRED: | 46 case android::VERIFY_EXPIRED: |
38 case android::VERIFY_NOT_YET_VALID: | 47 case android::VERIFY_NOT_YET_VALID: |
39 verify_result->cert_status |= CERT_STATUS_DATE_INVALID; | 48 verify_result->cert_status |= CERT_STATUS_DATE_INVALID; |
40 break; | 49 break; |
41 case android::VERIFY_UNABLE_TO_PARSE: | 50 case android::VERIFY_UNABLE_TO_PARSE: |
42 verify_result->cert_status |= CERT_STATUS_INVALID; | 51 verify_result->cert_status |= CERT_STATUS_INVALID; |
43 break; | 52 break; |
44 case android::VERIFY_INCORRECT_KEY_USAGE: | 53 case android::VERIFY_INCORRECT_KEY_USAGE: |
45 verify_result->cert_status |= CERT_STATUS_INVALID; | 54 verify_result->cert_status |= CERT_STATUS_INVALID; |
46 break; | 55 break; |
47 default: | 56 default: |
48 NOTREACHED(); | 57 NOTREACHED(); |
49 verify_result->cert_status |= CERT_STATUS_INVALID; | 58 verify_result->cert_status |= CERT_STATUS_INVALID; |
50 break; | 59 break; |
51 } | 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 | |
52 return true; | 90 return true; |
53 } | 91 } |
54 | 92 |
55 bool GetChainDEREncodedBytes(X509Certificate* cert, | 93 bool GetChainDEREncodedBytes(X509Certificate* cert, |
56 std::vector<std::string>* chain_bytes) { | 94 std::vector<std::string>* chain_bytes) { |
57 X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle(); | 95 X509Certificate::OSCertHandle cert_handle = cert->os_cert_handle(); |
58 X509Certificate::OSCertHandles cert_handles = | 96 X509Certificate::OSCertHandles cert_handles = |
59 cert->GetIntermediateCertificates(); | 97 cert->GetIntermediateCertificates(); |
60 | 98 |
61 // Make sure the peer's own cert is the first in the chain, if it's not | 99 // Make sure the peer's own cert is the first in the chain, if it's not |
(...skipping 30 matching lines...) Expand all Loading... | |
92 const CertificateList& additional_trust_anchors, | 130 const CertificateList& additional_trust_anchors, |
93 CertVerifyResult* verify_result) { | 131 CertVerifyResult* verify_result) { |
94 if (!cert->VerifyNameMatch(hostname, | 132 if (!cert->VerifyNameMatch(hostname, |
95 &verify_result->common_name_fallback_used)) { | 133 &verify_result->common_name_fallback_used)) { |
96 verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID; | 134 verify_result->cert_status |= CERT_STATUS_COMMON_NAME_INVALID; |
97 } | 135 } |
98 | 136 |
99 std::vector<std::string> cert_bytes; | 137 std::vector<std::string> cert_bytes; |
100 if (!GetChainDEREncodedBytes(cert, &cert_bytes)) | 138 if (!GetChainDEREncodedBytes(cert, &cert_bytes)) |
101 return ERR_CERT_INVALID; | 139 return ERR_CERT_INVALID; |
102 if (!VerifyFromAndroidTrustManager(cert_bytes, verify_result)) { | 140 if (!VerifyFromAndroidTrustManager(cert_bytes, hostname, verify_result)) { |
103 NOTREACHED(); | 141 NOTREACHED(); |
104 return ERR_FAILED; | 142 return ERR_FAILED; |
105 } | 143 } |
106 if (IsCertStatusError(verify_result->cert_status)) | 144 if (IsCertStatusError(verify_result->cert_status)) |
107 return MapCertStatusToNetError(verify_result->cert_status); | 145 return MapCertStatusToNetError(verify_result->cert_status); |
108 | 146 |
109 // TODO(ppi): Implement missing functionality: yielding the constructed trust | 147 // TODO(ppi): Implement missing functionality: yielding the constructed trust |
joth
2014/01/18 00:23:13
nit: I think this TODO is mostly obsolete now?
| |
110 // chain, public key hashes of its certificates and |is_issued_by_known_root| | 148 // chain, public key hashes of its certificates and |is_issued_by_known_root| |
111 // flag. All of the above require specific support from the platform, missing | 149 // flag. All of the above require specific support from the platform, missing |
112 // in the Java APIs. See also: http://crbug.com/116838 | 150 // in the Java APIs. See also: http://crbug.com/116838 |
113 | 151 |
114 // Until the required support is available in the platform, we don't know if | |
115 // the trust root at the end of the chain was standard or user-added, so we | |
116 // mark all correctly verified certificates as issued by a known root. | |
117 verify_result->is_issued_by_known_root = true; | |
118 | |
119 return OK; | 152 return OK; |
120 } | 153 } |
121 | 154 |
122 } // namespace net | 155 } // namespace net |
OLD | NEW |