190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file. 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/ocsp/nss_ocsp.h" 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <string> 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/file_util.h" 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/files/file_path.h" 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/logging.h" 1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/memory/ref_counted.h" 1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/base/net_errors.h" 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/base/test_completion_callback.h" 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/base/test_data_directory.h" 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/cert/cert_status_flags.h" 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/cert/cert_verifier.h" 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/cert/cert_verify_proc.h" 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/cert/cert_verify_proc_nss.h" 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/cert/cert_verify_result.h" 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/cert/multi_threaded_cert_verifier.h" 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/cert/test_root_certs.h" 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/cert/x509_certificate.h" 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/test/cert_test_util.h" 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/url_request/url_request_filter.h" 2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "net/url_request/url_request_interceptor.h" 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/url_request/url_request_test_job.h" 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/url_request/url_request_test_util.h" 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace net { 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace { 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Matches the caIssuers hostname from the generated certificate. 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kAiaHost[] = "aia-test.invalid"; 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Returning a single DER-encoded cert, so the mime-type must be 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// application/pkix-cert per RFC 5280. 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char kAiaHeaders[] = "HTTP/1.1 200 OK\0" 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "Content-type: application/pkix-cert\0" 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "\0"; 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class AiaResponseHandler : public net::URLRequestInterceptor { 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AiaResponseHandler(const std::string& headers, const std::string& cert_data) 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : headers_(headers), cert_data_(cert_data), request_count_(0) {} 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual ~AiaResponseHandler() {} 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // net::URLRequestInterceptor implementation: 5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual net::URLRequestJob* MaybeInterceptRequest( 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::URLRequest* request, 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::NetworkDelegate* network_delegate) const OVERRIDE { 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ++const_cast<AiaResponseHandler*>(this)->request_count_; 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return new net::URLRequestTestJob( 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) request, network_delegate, headers_, cert_data_, true); 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int request_count() const { return request_count_; } 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private: 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string headers_; 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string cert_data_; 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int request_count_; 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AiaResponseHandler); 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class NssHttpTest : public ::testing::Test { 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NssHttpTest() 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : context_(false), 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) handler_(NULL), 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) verify_proc_(new CertVerifyProcNSS), 77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) verifier_(new MultiThreadedCertVerifier(verify_proc_.get())) {} 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual ~NssHttpTest() {} 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void SetUp() { 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string file_contents; 8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_TRUE(base::ReadFileToString( 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetTestCertsDirectory().AppendASCII("aia-intermediate.der"), 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &file_contents)); 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_FALSE(file_contents.empty()); 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Ownership of |handler| is transferred to the URLRequestFilter, but 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // hold onto the original pointer in order to access |request_count()|. 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<AiaResponseHandler> handler( 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new AiaResponseHandler(kAiaHeaders, file_contents)); 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) handler_ = handler.get(); 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) URLRequestFilter::GetInstance()->AddHostnameInterceptor( 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "http", 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) kAiaHost, 9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) handler.PassAs<URLRequestInterceptor>()); 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetURLRequestContextForNSSHttpIO(&context_); 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EnsureNSSHttpIOInit(); 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void TearDown() { 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ShutdownNSSHttpIO(); 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (handler_) 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) URLRequestFilter::GetInstance()->RemoveHostnameHandler("http", kAiaHost); 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CertVerifier* verifier() const { 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return verifier_.get(); 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int request_count() const { 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return handler_->request_count(); 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) protected: 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const CertificateList empty_cert_list_; 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private: 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TestURLRequestContext context_; 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AiaResponseHandler* handler_; 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_refptr<CertVerifyProc> verify_proc_; 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<CertVerifier> verifier_; 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Tests that when using NSS to verify certificates, and IO is enabled, 12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// that a request to fetch missing intermediate certificates is 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// made successfully. 13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(NssHttpTest, TestAia) { 13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_refptr<X509Certificate> test_cert( 13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ImportCertFromFile(GetTestCertsDirectory(), "aia-cert.pem")); 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(test_cert.get()); 13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_refptr<X509Certificate> test_root( 13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ImportCertFromFile(GetTestCertsDirectory(), "aia-root.pem")); 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_TRUE(test_root.get()); 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ScopedTestRoot scoped_root(test_root.get()); 14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CertVerifyResult verify_result; 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TestCompletionCallback test_callback; 14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CertVerifier::RequestHandle request_handle; 14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int flags = CertVerifier::VERIFY_CERT_IO_ENABLED; 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int error = verifier()->Verify(test_cert.get(), 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "aia-host.invalid", 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) flags, 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NULL, 150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &verify_result, 151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) test_callback.callback(), 152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &request_handle, 153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) BoundNetLog()); 15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ASSERT_EQ(ERR_IO_PENDING, error); 15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) error = test_callback.WaitForResult(); 15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(OK, error); 15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Ensure that NSS made an AIA request for the missing intermediate. 16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_LT(0, request_count()); 16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace net 165