Refactor to lay the groundwork for metadata encryption

Bug: 26778031
Test: Angler, Marlin build and boot
Change-Id: Ic136dfe6195a650f7db76d3489f36da6a1929dc5
diff --git a/KeyStorage.cpp b/KeyStorage.cpp
index 34dd6c0..ddecbb8 100644
--- a/KeyStorage.cpp
+++ b/KeyStorage.cpp
@@ -400,6 +400,10 @@
     return true;
 }
 
+bool pathExists(const std::string& path) {
+    return access(path.c_str(), F_OK) == 0;
+}
+
 bool storeKey(const std::string& dir, const KeyAuthentication& auth, const std::string& key) {
     if (TEMP_FAILURE_RETRY(mkdir(dir.c_str(), 0700)) == -1) {
         PLOG(ERROR) << "key mkdir " << dir;
@@ -437,6 +441,25 @@
     return true;
 }
 
+bool storeKeyAtomically(const std::string& key_path, const std::string& tmp_path,
+                        const KeyAuthentication& auth, const std::string& key) {
+    if (pathExists(key_path)) {
+        LOG(ERROR) << "Already exists, cannot create key at: " << key_path;
+        return false;
+    }
+    if (pathExists(tmp_path)) {
+        LOG(DEBUG) << "Already exists, destroying: " << tmp_path;
+        destroyKey(tmp_path);  // May be partially created so ignore errors
+    }
+    if (!storeKey(tmp_path, auth, key)) return false;
+    if (rename(tmp_path.c_str(), key_path.c_str()) != 0) {
+        PLOG(ERROR) << "Unable to move new key to location: " << key_path;
+        return false;
+    }
+    LOG(DEBUG) << "Created key: " << key_path;
+    return true;
+}
+
 bool retrieveKey(const std::string& dir, const KeyAuthentication& auth, std::string* key) {
     std::string version;
     if (!readFileToString(dir + "/" + kFn_version, &version)) return false;