| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium OS 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 "login_manager/owner_key.h" | 5 #include "login_manager/owner_key.h" |
| 6 | 6 |
| 7 #include <base/crypto/rsa_private_key.h> | 7 #include <base/crypto/rsa_private_key.h> |
| 8 #include <base/file_path.h> | 8 #include <base/file_path.h> |
| 9 #include <base/file_util.h> | 9 #include <base/file_util.h> |
| 10 #include <base/logging.h> | 10 #include <base/logging.h> |
| 11 #include <base/scoped_ptr.h> | 11 #include <base/scoped_ptr.h> |
| 12 | 12 |
| 13 #include "login_manager/child_job.h" | 13 #include "login_manager/child_job.h" |
| 14 #include "login_manager/nss_util.h" | 14 #include "login_manager/nss_util.h" |
| 15 #include "login_manager/system_utils.h" | 15 #include "login_manager/system_utils.h" |
| 16 | 16 |
| 17 namespace login_manager { | 17 namespace login_manager { |
| 18 | 18 |
| 19 // Note: this structure is an ASN.1 which encodes the algorithm used | 19 // Note: this structure is an ASN.1 which encodes the algorithm used |
| 20 // with its parameters. This is defined in PKCS #1 v2.1 (RFC 3447). | 20 // with its parameters. This is defined in PKCS #1 v2.1 (RFC 3447). |
| 21 // It is encoding: { OID sha1WithRSAEncryption PARAMETERS NULL } | 21 // It is encoding: { OID sha1WithRSAEncryption PARAMETERS NULL } |
| 22 // static | 22 // static |
| 23 const uint8 OwnerKey::kAlgorithm[15] = { | 23 const uint8 OwnerKey::kAlgorithm[15] = { |
| 24 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, | 24 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, |
| 25 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00 | 25 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00 |
| 26 }; | 26 }; |
| 27 | 27 |
| 28 OwnerKey::OwnerKey(const FilePath& key_file) | 28 OwnerKey::OwnerKey(const FilePath& key_file) |
| 29 : key_file_(key_file), | 29 : key_file_(key_file), |
| 30 have_checked_disk_(false), | 30 have_checked_disk_(false), |
| 31 have_replaced_(false), |
| 31 utils_(new SystemUtils) { | 32 utils_(new SystemUtils) { |
| 32 } | 33 } |
| 33 | 34 |
| 34 OwnerKey::~OwnerKey() {} | 35 OwnerKey::~OwnerKey() {} |
| 35 | 36 |
| 37 bool OwnerKey::Equals(const std::string& key_der) const { |
| 38 return VEquals(std::vector<uint8>(key_der.c_str(), |
| 39 key_der.c_str() + key_der.length())); |
| 40 } |
| 41 |
| 42 bool OwnerKey::VEquals(const std::vector<uint8>& key_der) const { |
| 43 return ((key_.empty() == key_der.empty()) && |
| 44 memcmp(&key_der[0], &key_[0], key_.size()) == 0); |
| 45 } |
| 46 |
| 36 bool OwnerKey::HaveCheckedDisk() { return have_checked_disk_; } | 47 bool OwnerKey::HaveCheckedDisk() { return have_checked_disk_; } |
| 37 | 48 |
| 38 bool OwnerKey::IsPopulated() { return !key_.empty(); } | 49 bool OwnerKey::IsPopulated() { return !key_.empty(); } |
| 39 | 50 |
| 40 bool OwnerKey::PopulateFromDiskIfPossible() { | 51 bool OwnerKey::PopulateFromDiskIfPossible() { |
| 41 have_checked_disk_ = true; | 52 have_checked_disk_ = true; |
| 42 if (!file_util::PathExists(key_file_)) { | 53 if (!file_util::PathExists(key_file_)) { |
| 43 LOG(INFO) << "No owner key on disk."; | 54 LOG(INFO) << "No owner key on disk."; |
| 44 return true; | 55 return true; |
| 45 } | 56 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 std::vector<uint8> public_key_der; | 92 std::vector<uint8> public_key_der; |
| 82 if (pair && pair->ExportPublicKey(&public_key_der)) | 93 if (pair && pair->ExportPublicKey(&public_key_der)) |
| 83 return PopulateFromBuffer(public_key_der); | 94 return PopulateFromBuffer(public_key_der); |
| 84 LOG(ERROR) << "Failed to export public key from key pair"; | 95 LOG(ERROR) << "Failed to export public key from key pair"; |
| 85 return false; | 96 return false; |
| 86 } | 97 } |
| 87 | 98 |
| 88 bool OwnerKey::Persist() { | 99 bool OwnerKey::Persist() { |
| 89 // It is a programming error to call this before checking for the key on disk. | 100 // It is a programming error to call this before checking for the key on disk. |
| 90 CHECK(have_checked_disk_) << "Haven't checked disk for owner key yet!"; | 101 CHECK(have_checked_disk_) << "Haven't checked disk for owner key yet!"; |
| 91 if (file_util::PathExists(key_file_)) { | 102 if (!have_replaced_ && file_util::PathExists(key_file_)) { |
| 92 LOG(ERROR) << "Tried to overwrite owner key!"; | 103 LOG(ERROR) << "Tried to overwrite owner key!"; |
| 93 return false; | 104 return false; |
| 94 } | 105 } |
| 95 | 106 |
| 96 if (!utils_->AtomicFileWrite(key_file_, | 107 if (!utils_->AtomicFileWrite(key_file_, |
| 97 reinterpret_cast<char*>(&key_[0]), | 108 reinterpret_cast<char*>(&key_[0]), |
| 98 key_.size())) { | 109 key_.size())) { |
| 99 PLOG(ERROR) << "Could not write data to " << key_file_.value(); | 110 PLOG(ERROR) << "Could not write data to " << key_file_.value(); |
| 100 return false; | 111 return false; |
| 101 } | 112 } |
| 102 DLOG(INFO) << "wrote " << key_.size() << " bytes to " << key_file_.value(); | 113 DLOG(INFO) << "wrote " << key_.size() << " bytes to " << key_file_.value(); |
| 103 return true; | 114 return true; |
| 104 } | 115 } |
| 105 | 116 |
| 106 bool OwnerKey::Verify(const char* data, | 117 bool OwnerKey::Rotate(const std::vector<uint8>& public_key_der, |
| 118 const std::vector<uint8>& signature) { |
| 119 if (!IsPopulated()) { |
| 120 LOG(ERROR) << "Don't yet have an owner key!"; |
| 121 return false; |
| 122 } |
| 123 if (Verify(&public_key_der[0], |
| 124 public_key_der.size(), |
| 125 &signature[0], |
| 126 signature.size())) { |
| 127 key_ = public_key_der; |
| 128 have_replaced_ = true; |
| 129 return true; |
| 130 } |
| 131 LOG(ERROR) << "Invalid signature on new key!"; |
| 132 return false; |
| 133 } |
| 134 |
| 135 void OwnerKey::ClobberCompromisedKey(const std::vector<uint8>& public_key_der) { |
| 136 // It is a programming error to call this before checking for the key on disk. |
| 137 CHECK(have_checked_disk_) << "Haven't checked disk for owner key yet!"; |
| 138 // It is a programming error to call this without a key already loaded. |
| 139 CHECK(IsPopulated()) << "Don't yet have an owner key!"; |
| 140 |
| 141 key_ = public_key_der; |
| 142 have_replaced_ = true; |
| 143 } |
| 144 |
| 145 bool OwnerKey::Verify(const uint8* data, |
| 107 uint32 data_len, | 146 uint32 data_len, |
| 108 const char* signature, | 147 const uint8* signature, |
| 109 uint32 sig_len) { | 148 uint32 sig_len) { |
| 110 scoped_ptr<NssUtil> util(NssUtil::Create()); | 149 scoped_ptr<NssUtil> util(NssUtil::Create()); |
| 111 | |
| 112 if (!util->Verify(kAlgorithm, | 150 if (!util->Verify(kAlgorithm, |
| 113 sizeof(kAlgorithm), | 151 sizeof(kAlgorithm), |
| 114 reinterpret_cast<const uint8*>(signature), | 152 signature, |
| 115 sig_len, | 153 sig_len, |
| 116 reinterpret_cast<const uint8*>(data), | 154 data, |
| 117 data_len, | 155 data_len, |
| 118 &key_[0], | 156 &key_[0], |
| 119 key_.size())) { | 157 key_.size())) { |
| 120 LOG(ERROR) << "Signature verification of " << data << " failed"; | 158 LOG(ERROR) << "Signature verification of " << data << " failed"; |
| 121 return false; | 159 return false; |
| 122 } | 160 } |
| 123 return true; | 161 return true; |
| 124 } | 162 } |
| 125 | 163 |
| 126 bool OwnerKey::Sign(const char* data, | 164 bool OwnerKey::Sign(const uint8* data, |
| 127 uint32 data_len, | 165 uint32 data_len, |
| 128 std::vector<uint8>* OUT_signature) { | 166 std::vector<uint8>* OUT_signature) { |
| 129 scoped_ptr<NssUtil> util(NssUtil::Create()); | 167 scoped_ptr<NssUtil> util(NssUtil::Create()); |
| 130 scoped_ptr<base::RSAPrivateKey> private_key(util->GetPrivateKey(key_)); | 168 scoped_ptr<base::RSAPrivateKey> private_key(util->GetPrivateKey(key_)); |
| 131 if (!private_key.get()) | 169 if (!private_key.get()) |
| 132 return false; | 170 return false; |
| 133 if (!util->Sign(reinterpret_cast<const uint8*>(data), | 171 if (!util->Sign(data, data_len, OUT_signature, private_key.get())) { |
| 134 data_len, | |
| 135 OUT_signature, | |
| 136 private_key.get())) { | |
| 137 LOG(ERROR) << "Signing of " << data << " failed"; | 172 LOG(ERROR) << "Signing of " << data << " failed"; |
| 138 return false; | 173 return false; |
| 139 } | 174 } |
| 140 return true; | 175 return true; |
| 141 } | 176 } |
| 142 | 177 |
| 143 | 178 |
| 144 int OwnerKey::StartGeneration(ChildJobInterface* generator) { | 179 int OwnerKey::StartGeneration(ChildJobInterface* generator) { |
| 145 int pid = fork(); | 180 int pid = fork(); |
| 146 if (pid == 0) { | 181 if (pid == 0) { |
| 147 generator->Run(); | 182 generator->Run(); |
| 148 exit(1); // Run() is not supposed to return. | 183 exit(1); // Run() is not supposed to return. |
| 149 } | 184 } |
| 150 return pid; | 185 return pid; |
| 151 } | 186 } |
| 152 | 187 |
| 153 } // namespace login_manager | 188 } // namespace login_manager |
| OLD | NEW |