OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/quic/crypto/proof_verifier_chromium.h" | 5 #include "net/quic/crypto/proof_verifier_chromium.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
(...skipping 15 matching lines...) Expand all Loading... |
26 using base::StringPiece; | 26 using base::StringPiece; |
27 using base::StringPrintf; | 27 using base::StringPrintf; |
28 using std::string; | 28 using std::string; |
29 using std::vector; | 29 using std::vector; |
30 | 30 |
31 namespace net { | 31 namespace net { |
32 | 32 |
33 ProofVerifierChromium::ProofVerifierChromium(CertVerifier* cert_verifier, | 33 ProofVerifierChromium::ProofVerifierChromium(CertVerifier* cert_verifier, |
34 const BoundNetLog& net_log) | 34 const BoundNetLog& net_log) |
35 : cert_verifier_(cert_verifier), | 35 : cert_verifier_(cert_verifier), |
36 cert_verify_result_(NULL), | |
37 error_details_(NULL), | |
38 next_state_(STATE_NONE), | 36 next_state_(STATE_NONE), |
39 net_log_(net_log) { | 37 net_log_(net_log) { |
40 } | 38 } |
41 | 39 |
42 ProofVerifierChromium::~ProofVerifierChromium() { | 40 ProofVerifierChromium::~ProofVerifierChromium() { |
43 verifier_.reset(); | 41 verifier_.reset(); |
44 } | 42 } |
45 | 43 |
46 int ProofVerifierChromium::VerifyProof(const string& hostname, | 44 ProofVerifierChromium::Status ProofVerifierChromium::VerifyProof( |
47 const string& server_config, | 45 const string& hostname, |
48 const vector<string>& certs, | 46 const string& server_config, |
49 const string& signature, | 47 const vector<string>& certs, |
50 std::string* error_details, | 48 const string& signature, |
51 CertVerifyResult* cert_verify_result, | 49 std::string* error_details, |
52 const CompletionCallback& callback) { | 50 scoped_ptr<ProofVerifyDetails>* details, |
| 51 ProofVerifierCallback* callback) { |
53 DCHECK(error_details); | 52 DCHECK(error_details); |
54 DCHECK(cert_verify_result); | 53 DCHECK(details); |
| 54 DCHECK(callback); |
| 55 |
| 56 callback_.reset(callback); |
55 error_details->clear(); | 57 error_details->clear(); |
56 cert_verify_result->Reset(); | |
57 | 58 |
58 DCHECK_EQ(STATE_NONE, next_state_); | 59 DCHECK_EQ(STATE_NONE, next_state_); |
59 if (STATE_NONE != next_state_) { | 60 if (STATE_NONE != next_state_) { |
60 *error_details = "Certificate is already set and VerifyProof has begun"; | 61 *error_details = "Certificate is already set and VerifyProof has begun"; |
61 DLOG(WARNING) << *error_details; | 62 DLOG(WARNING) << *error_details; |
62 return ERR_FAILED; | 63 return FAILURE; |
63 } | 64 } |
64 | 65 |
| 66 verify_details_.reset(new ProofVerifyDetailsChromium); |
| 67 |
65 if (certs.empty()) { | 68 if (certs.empty()) { |
66 *error_details = "Failed to create certificate chain. Certs are empty."; | 69 *error_details = "Failed to create certificate chain. Certs are empty."; |
67 DLOG(WARNING) << *error_details; | 70 DLOG(WARNING) << *error_details; |
68 return ERR_FAILED; | 71 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID; |
| 72 details->reset(verify_details_.release()); |
| 73 return FAILURE; |
69 } | 74 } |
70 | 75 |
71 // Convert certs to X509Certificate. | 76 // Convert certs to X509Certificate. |
72 vector<StringPiece> cert_pieces(certs.size()); | 77 vector<StringPiece> cert_pieces(certs.size()); |
73 for (unsigned i = 0; i < certs.size(); i++) { | 78 for (unsigned i = 0; i < certs.size(); i++) { |
74 cert_pieces[i] = base::StringPiece(certs[i]); | 79 cert_pieces[i] = base::StringPiece(certs[i]); |
75 } | 80 } |
76 cert_ = X509Certificate::CreateFromDERCertChain(cert_pieces); | 81 cert_ = X509Certificate::CreateFromDERCertChain(cert_pieces); |
77 if (!cert_.get()) { | 82 if (!cert_.get()) { |
78 *error_details = "Failed to create certificate chain"; | 83 *error_details = "Failed to create certificate chain"; |
79 DLOG(WARNING) << *error_details; | 84 DLOG(WARNING) << *error_details; |
80 cert_verify_result->cert_status = CERT_STATUS_INVALID; | 85 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID; |
81 return ERR_FAILED; | 86 details->reset(verify_details_.release()); |
| 87 return FAILURE; |
82 } | 88 } |
83 | 89 |
84 // We call VerifySignature first to avoid copying of server_config and | 90 // We call VerifySignature first to avoid copying of server_config and |
85 // signature. | 91 // signature. |
86 if (!VerifySignature(server_config, signature, certs[0])) { | 92 if (!VerifySignature(server_config, signature, certs[0])) { |
87 *error_details = "Failed to verify signature of server config"; | 93 *error_details = "Failed to verify signature of server config"; |
88 DLOG(WARNING) << *error_details; | 94 DLOG(WARNING) << *error_details; |
89 return ERR_FAILED; | 95 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID; |
| 96 details->reset(verify_details_.release()); |
| 97 return FAILURE; |
90 } | 98 } |
91 | 99 |
92 hostname_ = hostname; | 100 hostname_ = hostname; |
93 callback_ = callback; | |
94 error_details_ = error_details; | |
95 cert_verify_result_ = cert_verify_result; | |
96 | 101 |
97 next_state_ = STATE_VERIFY_CERT; | 102 next_state_ = STATE_VERIFY_CERT; |
98 return DoLoop(OK); | 103 switch (DoLoop(OK)) { |
| 104 case OK: |
| 105 return SUCCESS; |
| 106 case ERR_IO_PENDING: |
| 107 return PENDING; |
| 108 default: |
| 109 *error_details = error_details_; |
| 110 return FAILURE; |
| 111 } |
99 } | 112 } |
100 | 113 |
101 int ProofVerifierChromium::DoLoop(int last_result) { | 114 int ProofVerifierChromium::DoLoop(int last_result) { |
102 int rv = last_result; | 115 int rv = last_result; |
103 do { | 116 do { |
104 State state = next_state_; | 117 State state = next_state_; |
105 next_state_ = STATE_NONE; | 118 next_state_ = STATE_NONE; |
106 switch (state) { | 119 switch (state) { |
107 case STATE_VERIFY_CERT: | 120 case STATE_VERIFY_CERT: |
108 DCHECK(rv == OK); | 121 DCHECK(rv == OK); |
109 rv = DoVerifyCert(rv); | 122 rv = DoVerifyCert(rv); |
110 break; | 123 break; |
111 case STATE_VERIFY_CERT_COMPLETE: | 124 case STATE_VERIFY_CERT_COMPLETE: |
112 rv = DoVerifyCertComplete(rv); | 125 rv = DoVerifyCertComplete(rv); |
113 break; | 126 break; |
114 case STATE_NONE: | 127 case STATE_NONE: |
115 default: | 128 default: |
116 rv = ERR_UNEXPECTED; | 129 rv = ERR_UNEXPECTED; |
117 LOG(DFATAL) << "unexpected state " << state; | 130 LOG(DFATAL) << "unexpected state " << state; |
118 break; | 131 break; |
119 } | 132 } |
120 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); | 133 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); |
121 return rv; | 134 return rv; |
122 } | 135 } |
123 | 136 |
124 void ProofVerifierChromium::OnIOComplete(int result) { | 137 void ProofVerifierChromium::OnIOComplete(int result) { |
125 int rv = DoLoop(result); | 138 int rv = DoLoop(result); |
126 if (rv != ERR_IO_PENDING) { | 139 if (rv != ERR_IO_PENDING) { |
127 base::ResetAndReturn(&callback_).Run(rv); | 140 scoped_ptr<ProofVerifyDetails> scoped_details(verify_details_.release()); |
| 141 callback_->Run(rv == OK, error_details_, &scoped_details); |
| 142 callback_.reset(); |
128 } | 143 } |
129 } | 144 } |
130 | 145 |
131 int ProofVerifierChromium::DoVerifyCert(int result) { | 146 int ProofVerifierChromium::DoVerifyCert(int result) { |
132 next_state_ = STATE_VERIFY_CERT_COMPLETE; | 147 next_state_ = STATE_VERIFY_CERT_COMPLETE; |
133 | 148 |
134 int flags = 0; | 149 int flags = 0; |
135 verifier_.reset(new SingleRequestCertVerifier(cert_verifier_)); | 150 verifier_.reset(new SingleRequestCertVerifier(cert_verifier_)); |
136 return verifier_->Verify( | 151 return verifier_->Verify( |
137 cert_.get(), | 152 cert_.get(), |
138 hostname_, | 153 hostname_, |
139 flags, | 154 flags, |
140 SSLConfigService::GetCRLSet().get(), | 155 SSLConfigService::GetCRLSet().get(), |
141 cert_verify_result_, | 156 &verify_details_->cert_verify_result, |
142 base::Bind(&ProofVerifierChromium::OnIOComplete, | 157 base::Bind(&ProofVerifierChromium::OnIOComplete, |
143 base::Unretained(this)), | 158 base::Unretained(this)), |
144 net_log_); | 159 net_log_); |
145 } | 160 } |
146 | 161 |
147 int ProofVerifierChromium::DoVerifyCertComplete(int result) { | 162 int ProofVerifierChromium::DoVerifyCertComplete(int result) { |
148 verifier_.reset(); | 163 verifier_.reset(); |
149 | 164 |
150 if (result <= ERR_FAILED) { | 165 if (result <= ERR_FAILED) { |
151 *error_details_ = StringPrintf("Failed to verify certificate chain: %s", | 166 error_details_ = StringPrintf("Failed to verify certificate chain: %s", |
152 ErrorToString(result)); | 167 ErrorToString(result)); |
153 DLOG(WARNING) << *error_details_; | 168 DLOG(WARNING) << error_details_; |
154 result = ERR_FAILED; | 169 result = ERR_FAILED; |
155 } | 170 } |
156 | 171 |
157 // Exit DoLoop and return the result to the caller to VerifyProof. | 172 // Exit DoLoop and return the result to the caller to VerifyProof. |
158 DCHECK_EQ(STATE_NONE, next_state_); | 173 DCHECK_EQ(STATE_NONE, next_state_); |
159 return result; | 174 return result; |
160 } | 175 } |
161 | 176 |
162 bool ProofVerifierChromium::VerifySignature(const string& signed_data, | 177 bool ProofVerifierChromium::VerifySignature(const string& signed_data, |
163 const string& signature, | 178 const string& signature, |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 if (!verifier.VerifyFinal()) { | 246 if (!verifier.VerifyFinal()) { |
232 DLOG(WARNING) << "VerifyFinal failed"; | 247 DLOG(WARNING) << "VerifyFinal failed"; |
233 return false; | 248 return false; |
234 } | 249 } |
235 | 250 |
236 DLOG(INFO) << "VerifyFinal success"; | 251 DLOG(INFO) << "VerifyFinal success"; |
237 return true; | 252 return true; |
238 } | 253 } |
239 | 254 |
240 } // namespace net | 255 } // namespace net |
OLD | NEW |