Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(461)

Side by Side Diff: components/cronet/ios/test/cronet_test_base.mm

Issue 2928653002: [Cronet-iOS] Public-Key-Pinning Tests (Closed)
Patch Set: Build fix on bot Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 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 "cronet_test_base.h"
6
7 #include "components/grpc_support/test/quic_test_server.h"
8 #include "crypto/sha2.h"
9 #include "net/base/net_errors.h"
10 #include "net/cert/asn1_util.h"
11 #include "net/cert/mock_cert_verifier.h"
12 #include "net/test/cert_test_util.h"
13 #include "net/test/test_data_directory.h"
14
15 #pragma mark
16
17 @implementation TestDelegate
18
19 @synthesize semaphore = _semaphore;
20 @synthesize error = _error;
21 @synthesize totalBytesReceived = _totalBytesReceived;
22
23 NSMutableArray<NSData*>* _responseData;
24
25 - (id)init {
26 if (self = [super init]) {
27 _semaphore = dispatch_semaphore_create(0);
28 }
29 return self;
30 }
31
32 - (void)reset {
33 _responseData = nil;
34 _error = nil;
35 _totalBytesReceived = 0;
36 }
37
38 - (NSString*)responseBody {
39 if (_responseData == nil) {
40 return nil;
41 }
42 NSMutableString* body = [NSMutableString string];
43 for (NSData* data in _responseData) {
44 [body appendString:[[NSString alloc] initWithData:data
45 encoding:NSUTF8StringEncoding]];
46 }
47 VLOG(3) << "responseBody size:" << [body length]
48 << " chunks:" << [_responseData count];
49 return body;
50 }
51
52 - (void)URLSession:(NSURLSession*)session
53 didBecomeInvalidWithError:(NSError*)error {
54 }
55
56 - (void)URLSession:(NSURLSession*)session
57 task:(NSURLSessionTask*)task
58 didCompleteWithError:(NSError*)error {
59 [self setError:error];
60 dispatch_semaphore_signal(_semaphore);
61 }
62
63 - (void)URLSession:(NSURLSession*)session
64 task:(NSURLSessionTask*)task
65 didReceiveChallenge:(NSURLAuthenticationChallenge*)challenge
66 completionHandler:
67 (void (^)(NSURLSessionAuthChallengeDisposition disp,
68 NSURLCredential* credential))completionHandler {
69 completionHandler(NSURLSessionAuthChallengeUseCredential, nil);
70 }
71
72 - (void)URLSession:(NSURLSession*)session
73 dataTask:(NSURLSessionDataTask*)dataTask
74 didReceiveResponse:(NSURLResponse*)response
75 completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))
76 completionHandler {
77 completionHandler(NSURLSessionResponseAllow);
78 }
79
80 - (void)URLSession:(NSURLSession*)session
81 dataTask:(NSURLSessionDataTask*)dataTask
82 didReceiveData:(NSData*)data {
83 _totalBytesReceived += [data length];
84 if (_responseData == nil) {
85 _responseData = [[NSMutableArray alloc] init];
86 }
87 [_responseData addObject:data];
88 }
89
90 - (void)URLSession:(NSURLSession*)session
91 dataTask:(NSURLSessionDataTask*)dataTask
92 willCacheResponse:(NSCachedURLResponse*)proposedResponse
93 completionHandler:
94 (void (^)(NSCachedURLResponse* cachedResponse))completionHandler {
95 completionHandler(proposedResponse);
96 }
97
98 @end
99
100 namespace cronet {
101
102 void CronetTestBase::SetUp() {
103 ::testing::Test::SetUp();
104 grpc_support::StartQuicTestServer();
105 delegate_ = [[TestDelegate alloc] init];
106 }
107
108 void CronetTestBase::TearDown() {
109 grpc_support::ShutdownQuicTestServer();
110 ::testing::Test::TearDown();
111 }
112
113 // Launches the supplied |task| and blocks until it completes, with a timeout
114 // of 1 second.
115 void CronetTestBase::StartDataTaskAndWaitForCompletion(
116 NSURLSessionDataTask* task) {
117 [delegate_ reset];
118 [task resume];
119
120 int64_t deadline_ns = 20 * NSEC_PER_SEC;
121 ASSERT_EQ(0, dispatch_semaphore_wait(
122 [delegate_ semaphore],
123 dispatch_time(DISPATCH_TIME_NOW, deadline_ns)));
124 }
125
126 ::testing::AssertionResult CronetTestBase::IsResponseSuccessful() {
127 if ([delegate_ error])
128 return ::testing::AssertionFailure() << "error in response: " <<
129 [[[delegate_ error] description]
130 cStringUsingEncoding:NSUTF8StringEncoding];
131 else
132 return ::testing::AssertionSuccess() << "no errors in response";
133 }
134
135 std::unique_ptr<net::MockCertVerifier> CronetTestBase::CreateMockCertVerifier(
136 const std::vector<std::string>& certs,
137 bool known_root) {
138 std::unique_ptr<net::MockCertVerifier> mock_cert_verifier(
139 new net::MockCertVerifier());
140 for (const auto& cert : certs) {
141 net::CertVerifyResult verify_result;
142 verify_result.verified_cert =
143 net::ImportCertFromFile(net::GetTestCertsDirectory(), cert);
144
145 // By default, HPKP verification is enabled for known trust roots only.
146 verify_result.is_issued_by_known_root = known_root;
147
148 // Calculate the public key hash and add it to the verify_result.
149 net::HashValue hashValue;
150 CHECK(CalculatePublicKeySha256(*verify_result.verified_cert.get(),
151 &hashValue));
152 verify_result.public_key_hashes.push_back(hashValue);
153
154 mock_cert_verifier->AddResultForCert(verify_result.verified_cert.get(),
155 verify_result, net::OK);
156 }
157 return mock_cert_verifier;
158 }
159
160 bool CronetTestBase::CalculatePublicKeySha256(const net::X509Certificate& cert,
161 net::HashValue* out_hash_value) {
162 // Convert the cert to DER encoded bytes.
163 std::string der_cert_bytes;
164 net::X509Certificate::OSCertHandle cert_handle = cert.os_cert_handle();
165 if (!net::X509Certificate::GetDEREncoded(cert_handle, &der_cert_bytes)) {
166 LOG(INFO) << "Unable to convert the given cert to DER encoding";
167 return false;
168 }
169 // Extract the public key from the cert.
170 base::StringPiece spki_bytes;
171 if (!net::asn1::ExtractSPKIFromDERCert(der_cert_bytes, &spki_bytes)) {
172 LOG(INFO) << "Unable to retrieve the public key from the DER cert";
173 return false;
174 }
175 // Calculate SHA256 hash of public key bytes.
176 out_hash_value->tag = net::HASH_VALUE_SHA256;
177 crypto::SHA256HashString(spki_bytes, out_hash_value->data(),
178 crypto::kSHA256Length);
179 return true;
180 }
181
182 } // namespace cronet
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698