From 1b3bb46aed33bd68bf5e4dba1625ad3211b31adc Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Tue, 7 Feb 2012 16:29:12 +0100 Subject: [PATCH] Restructure how keyrings are stored/restored. * Pass them through a flat buffer that can later be encrypted and decrypted in a central place. * Remove the data argument from the constructor as keyrings are now reading their data on their own. * Prepare for additional application info storage in the keyring. --- src/servers/keystore/KeyStoreServer.cpp | 28 +++--- src/servers/keystore/Keyring.cpp | 114 ++++++++++++++++++++++-- src/servers/keystore/Keyring.h | 9 +- 3 files changed, 130 insertions(+), 21 deletions(-) diff --git a/src/servers/keystore/KeyStoreServer.cpp b/src/servers/keystore/KeyStoreServer.cpp index 2324f18206..ac5fb69eff 100644 --- a/src/servers/keystore/KeyStoreServer.cpp +++ b/src/servers/keystore/KeyStoreServer.cpp @@ -82,7 +82,7 @@ KeyStoreServer::KeyStoreServer() _ReadKeyStoreDatabase(); if (fDefaultKeyring == NULL) - fDefaultKeyring = new(std::nothrow) Keyring("", BMessage()); + fDefaultKeyring = new(std::nothrow) Keyring(""); } @@ -388,19 +388,17 @@ KeyStoreServer::_ReadKeyStoreDatabase() int32 index = 0; char* keyringName = NULL; - while (keyrings.GetInfo(B_MESSAGE_TYPE, index++, &keyringName, - NULL) == B_OK) { - - BMessage keyringData; - if (keyrings.FindMessage(keyringName, &keyringData) != B_OK) { - printf("failed to retrieve keyring data for keyring \"%s\"\n", - keyringName); + while (keyrings.GetInfo(B_RAW_TYPE, index++, &keyringName, NULL) == B_OK) { + Keyring* keyring = new(std::nothrow) Keyring(keyringName); + if (keyring == NULL) { + printf("no memory for allocating keyring \"%s\"\n", keyringName); continue; } - Keyring* keyring = new(std::nothrow) Keyring(keyringName, keyringData); - if (keyring == NULL) { - printf("no memory for allocating keyring \"%s\"\n", keyringName); + status_t result = keyring->ReadFromMessage(keyrings); + if (result != B_OK) { + printf("failed to read keyring \"%s\" from data\n", keyringName); + delete keyring; continue; } @@ -422,14 +420,16 @@ KeyStoreServer::_WriteKeyStoreDatabase() BMessage keyrings; if (fDefaultKeyring != NULL) - keyrings.AddMessage("", &fDefaultKeyring->Data()); + fDefaultKeyring->WriteToMessage(keyrings); for (int32 i = 0; i < fKeyrings.CountItems(); i++) { Keyring* keyring = fKeyrings.ItemAt(i); if (keyring == NULL) continue; - keyrings.AddMessage(keyring->Name(), &keyring->Data()); + status_t result = keyring->WriteToMessage(keyrings); + if (result != B_OK) + return result; } return keyrings.Flatten(&fKeyStoreFile); @@ -494,7 +494,7 @@ KeyStoreServer::_AddKeyring(const BString& name, const BMessage& keyMessage) if (_FindKeyring(name) != NULL) return B_NAME_IN_USE; - Keyring* keyring = new(std::nothrow) Keyring(name, BMessage(), &keyMessage); + Keyring* keyring = new(std::nothrow) Keyring(name, &keyMessage); if (keyring == NULL) return B_NO_MEMORY; diff --git a/src/servers/keystore/Keyring.cpp b/src/servers/keystore/Keyring.cpp index fc77baf9ea..854b521f49 100644 --- a/src/servers/keystore/Keyring.cpp +++ b/src/servers/keystore/Keyring.cpp @@ -7,14 +7,13 @@ #include "Keyring.h" -Keyring::Keyring(const char* name, const BMessage& data, - const BMessage* keyMessage) +Keyring::Keyring(const char* name, const BMessage* keyMessage) : fName(name), - fData(data), - fKeyMessage(*keyMessage), - fAccessible(keyMessage != NULL) + fAccessible(false) { + if (keyMessage != NULL) + Access(*keyMessage); } @@ -23,10 +22,52 @@ Keyring::~Keyring() } +status_t +Keyring::ReadFromMessage(const BMessage& message) +{ + ssize_t size; + const void* data; + status_t result = message.FindData(fName, B_RAW_TYPE, &data, &size); + if (result != B_OK) + return result; + + if (size < 0) + return B_ERROR; + + fFlatBuffer.SetSize(0); + ssize_t written = fFlatBuffer.WriteAt(0, data, size); + if (written != size) { + fFlatBuffer.SetSize(0); + return written < 0 ? written : B_ERROR; + } + + return B_OK; +} + + +status_t +Keyring::WriteToMessage(BMessage& message) +{ + status_t result = _EncryptToFlatBuffer(); + if (result != B_OK) + return result; + + return message.AddData(fName, B_RAW_TYPE, fFlatBuffer.Buffer(), + fFlatBuffer.BufferLength()); +} + + status_t Keyring::Access(const BMessage& keyMessage) { fKeyMessage = keyMessage; + + status_t result = _DecryptFromFlatBuffer(); + if (result != B_OK) { + fKeyMessage.MakeEmpty(); + return result; + } + fAccessible = true; return B_OK; } @@ -35,7 +76,14 @@ Keyring::Access(const BMessage& keyMessage) void Keyring::RevokeAccess() { + if (!fAccessible) + return; + + _EncryptToFlatBuffer(); + fKeyMessage.MakeEmpty(); + fData.MakeEmpty(); + fApplications.MakeEmpty(); fAccessible = false; } @@ -222,3 +270,59 @@ Keyring::Compare(const BString* name, const Keyring* keyring) { return strcmp(name->String(), keyring->Name()); } + + +status_t +Keyring::_EncryptToFlatBuffer() +{ + if (!fAccessible) + return B_NOT_ALLOWED; + + BMessage container; + status_t result = container.AddMessage("data", &fData); + if (result != B_OK) + return result; + + result = container.AddMessage("applications", &fApplications); + if (result != B_OK) + return result; + + fFlatBuffer.SetSize(0); + fFlatBuffer.Seek(0, SEEK_SET); + + result = container.Flatten(&fFlatBuffer); + if (result != B_OK) + return result; + + // TODO: Actually encrypt the flat buffer... + + return B_OK; +} + + +status_t +Keyring::_DecryptFromFlatBuffer() +{ + if (fFlatBuffer.BufferLength() == 0) + return B_OK; + + // TODO: Actually decrypt the flat buffer... + + BMessage container; + fFlatBuffer.Seek(0, SEEK_SET); + status_t result = container.Unflatten(&fFlatBuffer); + if (result != B_OK) + return result; + + result = container.FindMessage("data", &fData); + if (result != B_OK) + return result; + + result = container.FindMessage("applications", &fApplications); + if (result != B_OK) { + fData.MakeEmpty(); + return result; + } + + return B_OK; +} diff --git a/src/servers/keystore/Keyring.h b/src/servers/keystore/Keyring.h index bdd426db1a..85c52ecd6c 100644 --- a/src/servers/keystore/Keyring.h +++ b/src/servers/keystore/Keyring.h @@ -13,12 +13,12 @@ class Keyring { public: Keyring(const char* name, - const BMessage& data, const BMessage* keyMessage = NULL); ~Keyring(); const char* Name() const { return fName; } - const BMessage& Data() const { return fData; } + status_t ReadFromMessage(const BMessage& message); + status_t WriteToMessage(BMessage& message); status_t Access(const BMessage& keyMessage); void RevokeAccess(); @@ -45,8 +45,13 @@ static int Compare(const BString* name, const Keyring* keyring); private: + status_t _EncryptToFlatBuffer(); + status_t _DecryptFromFlatBuffer(); + BString fName; + BMallocIO fFlatBuffer; BMessage fData; + BMessage fApplications; BMessage fKeyMessage; bool fAccessible; };