Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2014 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 "net/http/disk_based_cert_cache.h" | |
| 6 | |
| 7 #include <string> | |
|
wtc
2014/06/12 03:13:16
Nit: since the .h file includes <string>, the .cc
| |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "base/callback.h" | |
| 11 #include "base/callback_helpers.h" | |
| 12 #include "base/memory/ref_counted.h" | |
| 13 #include "base/memory/weak_ptr.h" | |
| 14 #include "base/strings/string_number_conversions.h" | |
| 15 #include "net/base/io_buffer.h" | |
| 16 #include "net/base/net_errors.h" | |
| 17 #include "net/cert/x509_certificate.h" | |
| 18 #include "net/disk_cache/disk_cache.h" | |
|
wtc
2014/06/12 03:13:16
The headers that are included by the .h file don't
| |
| 19 | |
| 20 namespace net { | |
| 21 | |
| 22 DiskBasedCertCache::DiskBasedCertCache(disk_cache::Backend* backend) | |
| 23 : backend_(backend), | |
| 24 active_entry_(NULL), | |
| 25 state_(NONE), | |
| 26 create_failed_(false), | |
| 27 active_entry_size_(0), | |
| 28 weak_factory_(this) { | |
| 29 DCHECK(backend_); | |
| 30 io_callback_ = | |
| 31 base::Bind(&DiskBasedCertCache::OnIOComplete, weak_factory_.GetWeakPtr()); | |
| 32 } | |
| 33 | |
| 34 DiskBasedCertCache::~DiskBasedCertCache() { | |
| 35 weak_factory_.InvalidateWeakPtrs(); | |
| 36 } | |
| 37 | |
| 38 void DiskBasedCertCache::Get( | |
| 39 std::string& key, | |
| 40 base::Callback<void(X509Certificate::OSCertHandle cert_handle)> cb) { | |
| 41 user_read_callback_ = cb; | |
| 42 | |
| 43 state_ = START_READ; | |
| 44 | |
| 45 int rv = backend_->OpenEntry(key, &active_entry_, io_callback_); | |
| 46 | |
| 47 DoLoop(rv); | |
| 48 } | |
| 49 | |
| 50 int DiskBasedCertCache::DoStartRead(int rv) { | |
| 51 // todo(brandonsalmon) implement error handling | |
|
wtc
2014/06/12 03:13:16
Our convention is all caps TODO.
| |
| 52 if (rv <= 0) | |
| 53 NOTIMPLEMENTED(); | |
| 54 | |
| 55 active_entry_size_ = active_entry_->GetDataSize(0 /* index */); | |
| 56 buffer = new IOBuffer(active_entry_size_); | |
| 57 | |
| 58 state_ = FINISH_READ; | |
| 59 | |
| 60 return active_entry_->ReadData( | |
| 61 0 /* index */, 0 /* offset */, buffer, active_entry_size_, io_callback_); | |
| 62 } | |
| 63 | |
| 64 int DiskBasedCertCache::DoFinishRead(int rv) { | |
| 65 // todo(brandonsalmon) implement error handling | |
| 66 if (rv <= 0) | |
| 67 NOTIMPLEMENTED(); | |
| 68 | |
| 69 if (user_read_callback_.is_null()) { | |
| 70 ResetState(); | |
| 71 return OK; // todo(brandonsalmon): is this ERR_ABORTED? | |
| 72 } | |
| 73 | |
| 74 active_cert_handle_ = X509Certificate::CreateOSCertHandleFromBytes( | |
| 75 buffer->data(), active_entry_size_); | |
| 76 | |
| 77 CHECK(active_cert_handle_); | |
| 78 | |
| 79 base::ResetAndReturn(&user_read_callback_).Run(active_cert_handle_); | |
| 80 | |
| 81 ResetState(); | |
| 82 return OK; | |
| 83 } | |
| 84 | |
| 85 void DiskBasedCertCache::Set(const X509Certificate::OSCertHandle cert_handle, | |
| 86 base::Callback<void(const std::string&)> cb) { | |
| 87 DCHECK(!cb.is_null()); | |
| 88 | |
| 89 active_cert_handle_ = cert_handle; | |
| 90 | |
| 91 state_ = CREATE_OR_OPEN; | |
| 92 user_write_callback_ = cb; | |
| 93 DoLoop(OK); | |
| 94 } | |
| 95 | |
| 96 std::string DiskBasedCertCache::Key() { | |
| 97 CHECK(active_cert_handle_); | |
| 98 | |
| 99 SHA1HashValue fingerprint = | |
| 100 X509Certificate::CalculateFingerprint(active_cert_handle_); | |
| 101 | |
| 102 // should update to store the key so the data doesn't have to be encoded | |
| 103 // multiple times. | |
| 104 | |
| 105 return "cert:" + base::HexEncode(fingerprint.data, 20); | |
|
wtc
2014/06/12 03:13:16
Avoid the use of 20. Try arraysize(fingerprint.dat
| |
| 106 } | |
| 107 | |
| 108 void DiskBasedCertCache::DoLoop(int rv) { | |
| 109 do { | |
| 110 switch (state_) { | |
| 111 case CREATE_OR_OPEN: | |
| 112 rv = DoCreateOrOpen(rv); | |
| 113 break; | |
| 114 case START_WRITE: | |
| 115 rv = DoStartWrite(rv); | |
| 116 break; | |
| 117 case FINISH_CREATE_OR_OPEN: | |
| 118 rv = DoFinishCreateOrOpen(rv); | |
| 119 break; | |
| 120 case FINISH_WRITE: | |
| 121 rv = DoFinishWrite(rv); | |
| 122 break; | |
| 123 case START_READ: | |
| 124 rv = DoStartRead(rv); | |
| 125 break; | |
| 126 case FINISH_READ: | |
| 127 rv = DoFinishRead(rv); | |
| 128 break; | |
| 129 case NONE: | |
| 130 break; | |
| 131 } | |
| 132 } while (rv != ERR_IO_PENDING && state_ != NONE); | |
| 133 } | |
| 134 | |
| 135 void DiskBasedCertCache::OnIOComplete(int rv) { | |
| 136 // todo(brandonsalmon) Check for fatal errors? | |
| 137 DoLoop(rv); | |
| 138 } | |
| 139 | |
| 140 int DiskBasedCertCache::DoStartWrite(int rv) { | |
| 141 // todo(brandonsalmon) implement error handling | |
| 142 if (rv <= 0) | |
| 143 NOTIMPLEMENTED(); | |
| 144 | |
| 145 std::string write_data; | |
| 146 // todo(brandonsalmon) deal with faulty encoding. | |
| 147 bool encoded = | |
| 148 X509Certificate::GetDEREncoded(active_cert_handle_, &write_data); | |
| 149 | |
| 150 if (!encoded) | |
| 151 NOTIMPLEMENTED(); | |
| 152 | |
| 153 buffer = new IOBuffer(write_data.size()); | |
| 154 memcpy(buffer->data(), write_data.data(), write_data.size()); | |
| 155 | |
| 156 state_ = FINISH_WRITE; | |
| 157 | |
| 158 return active_entry_->WriteData(0 /* index */, | |
| 159 0 /* offset */, | |
| 160 buffer, | |
| 161 write_data.size(), | |
| 162 io_callback_, | |
| 163 true /* truncate */); | |
| 164 } | |
| 165 | |
| 166 int DiskBasedCertCache::DoCreateOrOpen(int rv) { | |
| 167 DCHECK(active_entry_ == NULL); | |
| 168 | |
| 169 state_ = FINISH_CREATE_OR_OPEN; | |
| 170 | |
| 171 if (create_failed_) { | |
| 172 return backend_->OpenEntry(Key(), &active_entry_, io_callback_); | |
| 173 } | |
| 174 | |
| 175 return backend_->CreateEntry(Key(), &active_entry_, io_callback_); | |
| 176 } | |
| 177 | |
| 178 int DiskBasedCertCache::DoFinishCreateOrOpen(int rv) { | |
| 179 // ERR_FAILED implies create entry failed, and we should try opening instead. | |
| 180 //!create_failed is checked to make sure we only try to open once. | |
| 181 if (rv == ERR_FAILED && !create_failed_) { | |
| 182 create_failed_ = true; | |
| 183 state_ = CREATE_OR_OPEN; | |
| 184 return OK; | |
| 185 } else if (rv <= 0) { | |
| 186 NOTIMPLEMENTED(); | |
| 187 } | |
| 188 | |
| 189 state_ = START_WRITE; | |
| 190 return OK; | |
| 191 } | |
| 192 | |
| 193 int DiskBasedCertCache::DoFinishWrite(int rv) { | |
| 194 // todo(brandonsalmon) implement error handling | |
| 195 if (rv <= 0) | |
| 196 NOTIMPLEMENTED(); | |
| 197 | |
| 198 if (user_write_callback_.is_null()) { | |
| 199 ResetState(); | |
| 200 return OK; // todo(brandonsalmon): is this ERR_ABORTED? | |
| 201 } | |
| 202 | |
| 203 base::ResetAndReturn(&user_write_callback_).Run(Key()); | |
| 204 ResetState(); | |
| 205 return OK; | |
| 206 } | |
| 207 | |
| 208 void DiskBasedCertCache::ResetState() { | |
| 209 state_ = NONE; | |
| 210 active_entry_->Close(); | |
| 211 active_entry_ = NULL; | |
| 212 active_cert_handle_ = NULL; | |
| 213 user_write_callback_.Reset(); | |
| 214 user_read_callback_.Reset(); | |
| 215 } | |
| 216 | |
| 217 } // namespace net | |
| OLD | NEW |