| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "chrome/browser/chromeos/platform_keys/platform_keys.h" | 5 #include "chrome/browser/chromeos/platform_keys/platform_keys.h" |
| 6 | 6 |
| 7 #include <cryptohi.h> | 7 #include <cryptohi.h> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 using content::BrowserThread; | 31 using content::BrowserThread; |
| 32 | 32 |
| 33 namespace { | 33 namespace { |
| 34 const char kErrorInternal[] = "Internal Error."; | 34 const char kErrorInternal[] = "Internal Error."; |
| 35 const char kErrorKeyNotFound[] = "Key not found."; | 35 const char kErrorKeyNotFound[] = "Key not found."; |
| 36 const char kErrorCertificateNotFound[] = "Certificate could not be found."; | 36 const char kErrorCertificateNotFound[] = "Certificate could not be found."; |
| 37 const char kErrorAlgorithmNotSupported[] = "Algorithm not supported."; | 37 const char kErrorAlgorithmNotSupported[] = "Algorithm not supported."; |
| 38 | 38 |
| 39 // The current maximal RSA modulus length that ChromeOS's TPM supports for key | 39 // The current maximal RSA modulus length that ChromeOS's TPM supports for key |
| 40 // generation. | 40 // generation. |
| 41 const unsigned int kMaxRSAModulusLength = 2048; | 41 const unsigned int kMaxRSAModulusLengthBits = 2048; |
| 42 } | 42 } |
| 43 | 43 |
| 44 namespace chromeos { | 44 namespace chromeos { |
| 45 | 45 |
| 46 namespace platform_keys { | 46 namespace platform_keys { |
| 47 | 47 |
| 48 namespace { | 48 namespace { |
| 49 | 49 |
| 50 // Base class to store state that is common to all NSS database operations and | 50 // Base class to store state that is common to all NSS database operations and |
| 51 // to provide convenience methods to call back. | 51 // to provide convenience methods to call back. |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 BrowserThread::PostTask(BrowserThread::IO, | 119 BrowserThread::PostTask(BrowserThread::IO, |
| 120 FROM_HERE, | 120 FROM_HERE, |
| 121 base::Bind(&GetCertDatabaseOnIOThread, | 121 base::Bind(&GetCertDatabaseOnIOThread, |
| 122 browser_context->GetResourceContext(), | 122 browser_context->GetResourceContext(), |
| 123 callback, | 123 callback, |
| 124 state)); | 124 state)); |
| 125 } | 125 } |
| 126 | 126 |
| 127 class GenerateRSAKeyState : public NSSOperationState { | 127 class GenerateRSAKeyState : public NSSOperationState { |
| 128 public: | 128 public: |
| 129 GenerateRSAKeyState(unsigned int modulus_length, | 129 GenerateRSAKeyState(unsigned int modulus_length_bits, |
| 130 const GenerateKeyCallback& callback); | 130 const subtle::GenerateKeyCallback& callback); |
| 131 virtual ~GenerateRSAKeyState() {} | 131 virtual ~GenerateRSAKeyState() {} |
| 132 | 132 |
| 133 virtual void OnError(const tracked_objects::Location& from, | 133 virtual void OnError(const tracked_objects::Location& from, |
| 134 const std::string& error_message) OVERRIDE { | 134 const std::string& error_message) OVERRIDE { |
| 135 CallBack(from, std::string() /* no public key */, error_message); | 135 CallBack(from, std::string() /* no public key */, error_message); |
| 136 } | 136 } |
| 137 | 137 |
| 138 void CallBack(const tracked_objects::Location& from, | 138 void CallBack(const tracked_objects::Location& from, |
| 139 const std::string& public_key_spki_der, | 139 const std::string& public_key_spki_der, |
| 140 const std::string& error_message) { | 140 const std::string& error_message) { |
| 141 origin_task_runner_->PostTask( | 141 origin_task_runner_->PostTask( |
| 142 from, base::Bind(callback_, public_key_spki_der, error_message)); | 142 from, base::Bind(callback_, public_key_spki_der, error_message)); |
| 143 } | 143 } |
| 144 | 144 |
| 145 const unsigned int modulus_length_; | 145 const unsigned int modulus_length_bits_; |
| 146 | 146 |
| 147 private: | 147 private: |
| 148 // Must be called on origin thread, use CallBack() therefore. | 148 // Must be called on origin thread, use CallBack() therefore. |
| 149 GenerateKeyCallback callback_; | 149 subtle::GenerateKeyCallback callback_; |
| 150 }; | 150 }; |
| 151 | 151 |
| 152 class SignState : public NSSOperationState { | 152 class SignState : public NSSOperationState { |
| 153 public: | 153 public: |
| 154 SignState(const std::string& public_key, | 154 SignState(const std::string& public_key, |
| 155 const std::string& data, | 155 const std::string& data, |
| 156 const SignCallback& callback); | 156 const subtle::SignCallback& callback); |
| 157 virtual ~SignState() {} | 157 virtual ~SignState() {} |
| 158 | 158 |
| 159 virtual void OnError(const tracked_objects::Location& from, | 159 virtual void OnError(const tracked_objects::Location& from, |
| 160 const std::string& error_message) OVERRIDE { | 160 const std::string& error_message) OVERRIDE { |
| 161 CallBack(from, std::string() /* no signature */, error_message); | 161 CallBack(from, std::string() /* no signature */, error_message); |
| 162 } | 162 } |
| 163 | 163 |
| 164 void CallBack(const tracked_objects::Location& from, | 164 void CallBack(const tracked_objects::Location& from, |
| 165 const std::string& signature, | 165 const std::string& signature, |
| 166 const std::string& error_message) { | 166 const std::string& error_message) { |
| 167 origin_task_runner_->PostTask( | 167 origin_task_runner_->PostTask( |
| 168 from, base::Bind(callback_, signature, error_message)); | 168 from, base::Bind(callback_, signature, error_message)); |
| 169 } | 169 } |
| 170 | 170 |
| 171 const std::string public_key_; | 171 const std::string public_key_; |
| 172 const std::string data_; | 172 const std::string data_; |
| 173 | 173 |
| 174 private: | 174 private: |
| 175 // Must be called on origin thread, use CallBack() therefore. | 175 // Must be called on origin thread, use CallBack() therefore. |
| 176 SignCallback callback_; | 176 subtle::SignCallback callback_; |
| 177 }; | 177 }; |
| 178 | 178 |
| 179 class GetCertificatesState : public NSSOperationState { | 179 class GetCertificatesState : public NSSOperationState { |
| 180 public: | 180 public: |
| 181 explicit GetCertificatesState(const GetCertificatesCallback& callback); | 181 explicit GetCertificatesState(const GetCertificatesCallback& callback); |
| 182 virtual ~GetCertificatesState() {} | 182 virtual ~GetCertificatesState() {} |
| 183 | 183 |
| 184 virtual void OnError(const tracked_objects::Location& from, | 184 virtual void OnError(const tracked_objects::Location& from, |
| 185 const std::string& error_message) OVERRIDE { | 185 const std::string& error_message) OVERRIDE { |
| 186 CallBack(from, | 186 CallBack(from, |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 | 245 |
| 246 private: | 246 private: |
| 247 // Must be called on origin thread, use CallBack() therefore. | 247 // Must be called on origin thread, use CallBack() therefore. |
| 248 RemoveCertificateCallback callback_; | 248 RemoveCertificateCallback callback_; |
| 249 }; | 249 }; |
| 250 | 250 |
| 251 NSSOperationState::NSSOperationState() | 251 NSSOperationState::NSSOperationState() |
| 252 : origin_task_runner_(base::ThreadTaskRunnerHandle::Get()) { | 252 : origin_task_runner_(base::ThreadTaskRunnerHandle::Get()) { |
| 253 } | 253 } |
| 254 | 254 |
| 255 GenerateRSAKeyState::GenerateRSAKeyState(unsigned int modulus_length, | 255 GenerateRSAKeyState::GenerateRSAKeyState( |
| 256 const GenerateKeyCallback& callback) | 256 unsigned int modulus_length_bits, |
| 257 : modulus_length_(modulus_length), | 257 const subtle::GenerateKeyCallback& callback) |
| 258 callback_(callback) { | 258 : modulus_length_bits_(modulus_length_bits), callback_(callback) { |
| 259 } | 259 } |
| 260 | 260 |
| 261 SignState::SignState(const std::string& public_key, | 261 SignState::SignState(const std::string& public_key, |
| 262 const std::string& data, | 262 const std::string& data, |
| 263 const SignCallback& callback) | 263 const subtle::SignCallback& callback) |
| 264 : public_key_(public_key), data_(data), callback_(callback) { | 264 : public_key_(public_key), data_(data), callback_(callback) { |
| 265 } | 265 } |
| 266 | 266 |
| 267 GetCertificatesState::GetCertificatesState( | 267 GetCertificatesState::GetCertificatesState( |
| 268 const GetCertificatesCallback& callback) | 268 const GetCertificatesCallback& callback) |
| 269 : callback_(callback) { | 269 : callback_(callback) { |
| 270 } | 270 } |
| 271 | 271 |
| 272 ImportCertificateState::ImportCertificateState( | 272 ImportCertificateState::ImportCertificateState( |
| 273 scoped_refptr<net::X509Certificate> certificate, | 273 scoped_refptr<net::X509Certificate> certificate, |
| 274 const ImportCertificateCallback& callback) | 274 const ImportCertificateCallback& callback) |
| 275 : certificate_(certificate), callback_(callback) { | 275 : certificate_(certificate), callback_(callback) { |
| 276 } | 276 } |
| 277 | 277 |
| 278 RemoveCertificateState::RemoveCertificateState( | 278 RemoveCertificateState::RemoveCertificateState( |
| 279 scoped_refptr<net::X509Certificate> certificate, | 279 scoped_refptr<net::X509Certificate> certificate, |
| 280 const RemoveCertificateCallback& callback) | 280 const RemoveCertificateCallback& callback) |
| 281 : certificate_(certificate), callback_(callback) { | 281 : certificate_(certificate), callback_(callback) { |
| 282 } | 282 } |
| 283 | 283 |
| 284 // Does the actual key generation on a worker thread. Used by | 284 // Does the actual key generation on a worker thread. Used by |
| 285 // GenerateRSAKeyWithDB(). | 285 // GenerateRSAKeyWithDB(). |
| 286 void GenerateRSAKeyOnWorkerThread(scoped_ptr<GenerateRSAKeyState> state) { | 286 void GenerateRSAKeyOnWorkerThread(scoped_ptr<GenerateRSAKeyState> state) { |
| 287 scoped_ptr<crypto::RSAPrivateKey> rsa_key( | 287 scoped_ptr<crypto::RSAPrivateKey> rsa_key( |
| 288 crypto::RSAPrivateKey::CreateSensitive(state->slot_.get(), | 288 crypto::RSAPrivateKey::CreateSensitive(state->slot_.get(), |
| 289 state->modulus_length_)); | 289 state->modulus_length_bits_)); |
| 290 if (!rsa_key) { | 290 if (!rsa_key) { |
| 291 LOG(ERROR) << "Couldn't create key."; | 291 LOG(ERROR) << "Couldn't create key."; |
| 292 state->OnError(FROM_HERE, kErrorInternal); | 292 state->OnError(FROM_HERE, kErrorInternal); |
| 293 return; | 293 return; |
| 294 } | 294 } |
| 295 | 295 |
| 296 std::vector<uint8> public_key_spki_der; | 296 std::vector<uint8> public_key_spki_der; |
| 297 if (!rsa_key->ExportPublicKey(&public_key_spki_der)) { | 297 if (!rsa_key->ExportPublicKey(&public_key_spki_der)) { |
| 298 // TODO(pneubeck): Remove rsa_key from storage. | 298 // TODO(pneubeck): Remove rsa_key from storage. |
| 299 LOG(ERROR) << "Couldn't export public key."; | 299 LOG(ERROR) << "Couldn't export public key."; |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 scoped_refptr<net::X509Certificate> certificate = state->certificate_; | 463 scoped_refptr<net::X509Certificate> certificate = state->certificate_; |
| 464 bool certificate_found = certificate->os_cert_handle()->isperm; | 464 bool certificate_found = certificate->os_cert_handle()->isperm; |
| 465 cert_db->DeleteCertAndKeyAsync( | 465 cert_db->DeleteCertAndKeyAsync( |
| 466 certificate, | 466 certificate, |
| 467 base::Bind( | 467 base::Bind( |
| 468 &DidRemoveCertificate, base::Passed(&state), certificate_found)); | 468 &DidRemoveCertificate, base::Passed(&state), certificate_found)); |
| 469 } | 469 } |
| 470 | 470 |
| 471 } // namespace | 471 } // namespace |
| 472 | 472 |
| 473 namespace subtle { |
| 474 |
| 473 void GenerateRSAKey(const std::string& token_id, | 475 void GenerateRSAKey(const std::string& token_id, |
| 474 unsigned int modulus_length, | 476 unsigned int modulus_length_bits, |
| 475 const GenerateKeyCallback& callback, | 477 const GenerateKeyCallback& callback, |
| 476 BrowserContext* browser_context) { | 478 BrowserContext* browser_context) { |
| 477 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 479 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 478 scoped_ptr<GenerateRSAKeyState> state( | 480 scoped_ptr<GenerateRSAKeyState> state( |
| 479 new GenerateRSAKeyState(modulus_length, callback)); | 481 new GenerateRSAKeyState(modulus_length_bits, callback)); |
| 480 | 482 |
| 481 if (modulus_length > kMaxRSAModulusLength) { | 483 if (modulus_length_bits > kMaxRSAModulusLengthBits) { |
| 482 state->OnError(FROM_HERE, kErrorAlgorithmNotSupported); | 484 state->OnError(FROM_HERE, kErrorAlgorithmNotSupported); |
| 483 return; | 485 return; |
| 484 } | 486 } |
| 485 | 487 |
| 486 // Get the pointer to |state| before base::Passed releases |state|. | 488 // Get the pointer to |state| before base::Passed releases |state|. |
| 487 NSSOperationState* state_ptr = state.get(); | 489 NSSOperationState* state_ptr = state.get(); |
| 488 GetCertDatabase(token_id, | 490 GetCertDatabase(token_id, |
| 489 base::Bind(&GenerateRSAKeyWithDB, base::Passed(&state)), | 491 base::Bind(&GenerateRSAKeyWithDB, base::Passed(&state)), |
| 490 browser_context, | 492 browser_context, |
| 491 state_ptr); | 493 state_ptr); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 503 | 505 |
| 504 // The NSSCertDatabase object is not required. But in case it's not available | 506 // The NSSCertDatabase object is not required. But in case it's not available |
| 505 // we would get more informative error messages and we can double check that | 507 // we would get more informative error messages and we can double check that |
| 506 // we use a key of the correct token. | 508 // we use a key of the correct token. |
| 507 GetCertDatabase(token_id, | 509 GetCertDatabase(token_id, |
| 508 base::Bind(&RSASignWithDB, base::Passed(&state)), | 510 base::Bind(&RSASignWithDB, base::Passed(&state)), |
| 509 browser_context, | 511 browser_context, |
| 510 state_ptr); | 512 state_ptr); |
| 511 } | 513 } |
| 512 | 514 |
| 515 } // namespace subtle |
| 516 |
| 513 void GetCertificates(const std::string& token_id, | 517 void GetCertificates(const std::string& token_id, |
| 514 const GetCertificatesCallback& callback, | 518 const GetCertificatesCallback& callback, |
| 515 BrowserContext* browser_context) { | 519 BrowserContext* browser_context) { |
| 516 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 520 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 517 scoped_ptr<GetCertificatesState> state(new GetCertificatesState(callback)); | 521 scoped_ptr<GetCertificatesState> state(new GetCertificatesState(callback)); |
| 518 // Get the pointer to |state| before base::Passed releases |state|. | 522 // Get the pointer to |state| before base::Passed releases |state|. |
| 519 NSSOperationState* state_ptr = state.get(); | 523 NSSOperationState* state_ptr = state.get(); |
| 520 GetCertDatabase(token_id, | 524 GetCertDatabase(token_id, |
| 521 base::Bind(&GetCertificatesWithDB, base::Passed(&state)), | 525 base::Bind(&GetCertificatesWithDB, base::Passed(&state)), |
| 522 browser_context, | 526 browser_context, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 // we would get more informative error messages. | 560 // we would get more informative error messages. |
| 557 GetCertDatabase(token_id, | 561 GetCertDatabase(token_id, |
| 558 base::Bind(&RemoveCertificateWithDB, base::Passed(&state)), | 562 base::Bind(&RemoveCertificateWithDB, base::Passed(&state)), |
| 559 browser_context, | 563 browser_context, |
| 560 state_ptr); | 564 state_ptr); |
| 561 } | 565 } |
| 562 | 566 |
| 563 } // namespace platform_keys | 567 } // namespace platform_keys |
| 564 | 568 |
| 565 } // namespace chromeos | 569 } // namespace chromeos |
| OLD | NEW |