15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/single_request_cert_verifier.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/x509_certificate.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SingleRequestCertVerifier::SingleRequestCertVerifier(
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CertVerifier* cert_verifier)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : cert_verifier_(cert_verifier),
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cur_request_(NULL) {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(cert_verifier_ != NULL);
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SingleRequestCertVerifier::~SingleRequestCertVerifier() {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cur_request_) {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cert_verifier_->CancelRequest(cur_request_);
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur_request_ = NULL;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SingleRequestCertVerifier::Verify(X509Certificate* cert,
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const std::string& hostname,
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      int flags,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      CRLSet* crl_set,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      CertVerifyResult* verify_result,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const CompletionCallback& callback,
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const BoundNetLog& net_log) {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should not be already in use.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!cur_request_ && cur_request_callback_.is_null());
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CertVerifier::RequestHandle request = NULL;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We need to be notified of completion before |callback| is called, so that
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we can clear out |cur_request_*|.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = cert_verifier_->Verify(
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cert, hostname, flags, crl_set, verify_result,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&SingleRequestCertVerifier::OnVerifyCompletion,
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)),
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &request, net_log);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Cleared in OnVerifyCompletion().
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur_request_ = request;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur_request_callback_ = callback;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rv;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SingleRequestCertVerifier::OnVerifyCompletion(int result) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(cur_request_ && !cur_request_callback_.is_null());
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CompletionCallback callback = cur_request_callback_;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear the outstanding request information.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cur_request_ = NULL;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cur_request_callback_.Reset();
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Call the user's original callback.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback.Run(result);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
71