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 |