From 1c3996496b06a2da3ae25c358336302dfbce7ddb Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Wed, 4 Jan 2012 01:51:59 +0100 Subject: [PATCH] Implement all KeyStore methods except for password generation. * Add all relevant message constants. * Implement the messaging to send/retrieve key info. * Implement _Flatten/_Unflatten for sending flat BKey objects. * Remove application list from BKey, the key can't only differ by allowed applications as the identifiers would still collide, so the comparison isn't needed to uniquely identify the key. The applications can be enumerated via the BKeyStore instead. --- headers/os/app/Key.h | 7 +- headers/os/app/KeyStore.h | 4 + headers/private/app/RegistrarDefs.h | 19 +++ src/kits/app/Key.cpp | 80 +++++++----- src/kits/app/KeyStore.cpp | 188 +++++++++++++++++++++++++--- 5 files changed, 247 insertions(+), 51 deletions(-) diff --git a/headers/os/app/Key.h b/headers/os/app/Key.h index d4c74af78d..147104223b 100644 --- a/headers/os/app/Key.h +++ b/headers/os/app/Key.h @@ -73,14 +73,19 @@ public: bool operator==(const BKey& other) const; bool operator!=(const BKey& other) const; +protected: + virtual status_t _Flatten(BMessage& message) const; + virtual status_t _Unflatten(const BMessage& message); + private: + friend class BKeyStore; + BKeyPurpose fPurpose; BString fIdentifier; BString fSecondaryIdentifier; BString fOwner; bigtime_t fCreationTime; mutable BMallocIO fData; - BObjectList fApplications; bool fRegistered; }; diff --git a/headers/os/app/KeyStore.h b/headers/os/app/KeyStore.h index 6dc2096e64..3d23fcdf5d 100644 --- a/headers/os/app/KeyStore.h +++ b/headers/os/app/KeyStore.h @@ -93,6 +93,10 @@ public: status_t GeneratePassword(BPasswordKey& password, size_t length, uint32 flags); float PasswordStrength(const char* password); + +private: + status_t _SendKeyMessage(BMessage& message, + BMessage* reply) const; }; diff --git a/headers/private/app/RegistrarDefs.h b/headers/private/app/RegistrarDefs.h index c5144e2f91..548cd0f72b 100644 --- a/headers/private/app/RegistrarDefs.h +++ b/headers/private/app/RegistrarDefs.h @@ -122,6 +122,25 @@ enum { B_REG_GET_USER_GROUPS = 'rgug', B_REG_UPDATE_USER = 'ruus', B_REG_UPDATE_GROUP = 'rugr', + + // KeyStore requests + B_REG_GET_KEY = 'rgtK', + B_REG_GET_NEXT_KEY = 'rgnK', + B_REG_ADD_KEY = 'radK', + B_REG_REMOVE_KEY = 'rrmK', + B_REG_ADD_KEYRING = 'raKR', + B_REG_REMOVE_KEYRING = 'rrKR', + B_REG_GET_NEXT_KEYRING = 'rnKR', + B_REG_SET_MASTER_KEY = 'rsMK', + B_REG_REMOVE_MASTER_KEY = 'rrMK', + B_REG_ADD_KEYRING_TO_MASTER = 'rarM', + B_REG_REMOVE_KEYRING_FROM_MASTER = 'rrrM', + B_REG_GET_NEXT_MASTER_KEYRING = 'rnrM', + B_REG_IS_KEYRING_ACCESSIBLE = 'riaR', + B_REG_REVOKE_ACCESS = 'rvaR', + B_REG_REVOKE_MASTER_ACCESS = 'rvaM', + B_REG_GET_NEXT_APPLICATION = 'rnKA', + B_REG_REMOVE_APPLICATION = 'rrKA', }; // B_REG_MIME_SET_PARAM "which" constants diff --git a/src/kits/app/Key.cpp b/src/kits/app/Key.cpp index bfe187d963..a112e74c12 100644 --- a/src/kits/app/Key.cpp +++ b/src/kits/app/Key.cpp @@ -7,6 +7,8 @@ #include +#if 0 +// TODO: move this to the KeyStore or the registrar backend if needed static bool CompareLists(BObjectList a, BObjectList b) { @@ -20,6 +22,7 @@ CompareLists(BObjectList a, BObjectList b) return true; } +#endif // #pragma mark - Generic BKey @@ -159,35 +162,6 @@ BKey::IsRegistered() const } -#if 0 -// To be moved to BKeyStore -status_t -BKey::GetNextApplication(uint32& cookie, BString& signature) const -{ - BString* item = fApplications.ItemAt(cookie++); - if (item == NULL) - return B_ENTRY_NOT_FOUND; - - signature = *item; - return B_OK; -} - - -status_t -BKey::RemoveApplication(const char* signature) -{ - for (int32 i = 0; i < fApplications.CountItems(); i++) { - if (*fApplications.ItemAt(i) == signature) { - fApplications.RemoveItemAt(i); - return B_OK; - } - } - - return B_ENTRY_NOT_FOUND; -} -#endif - - BKey& BKey::operator=(const BKey& other) { @@ -199,7 +173,6 @@ BKey::operator=(const BKey& other) fOwner = other.fOwner; fCreationTime = other.CreationTime(); fRegistered = other.IsRegistered(); - fApplications = other.fApplications; return *this; } @@ -214,8 +187,7 @@ BKey::operator==(const BKey& other) const && fOwner == other.fOwner && fIdentifier == other.fIdentifier && fSecondaryIdentifier == other.fSecondaryIdentifier - && memcmp(Data(), other.Data(), DataLength()) == 0 - && CompareLists(fApplications, other.fApplications); + && memcmp(Data(), other.Data(), DataLength()) == 0; } @@ -226,6 +198,50 @@ BKey::operator!=(const BKey& other) const } +status_t +BKey::_Flatten(BMessage& message) const +{ + if (message.MakeEmpty() != B_OK + || message.AddUInt32("type", Type()) != B_OK + || message.AddUInt32("purpose", fPurpose) != B_OK + || message.AddString("identifier", fIdentifier) != B_OK + || message.AddString("secondaryIdentifier", fSecondaryIdentifier) + != B_OK + || message.AddString("owner", fOwner) != B_OK + || message.AddInt64("creationTime", fCreationTime) != B_OK + || message.AddData("data", B_RAW_TYPE, fData.Buffer(), + fData.BufferLength()) != B_OK) { + return B_ERROR; + } + + return B_OK; +} + + +status_t +BKey::_Unflatten(const BMessage& message) +{ + BKeyType type; + if (message.FindUInt32("type", (uint32*)&type) != B_OK || type != Type()) + return B_BAD_VALUE; + + const void* data = NULL; + ssize_t dataLength = 0; + if (message.FindUInt32("purpose", (uint32*)&fPurpose) != B_OK + || message.FindString("identifier", &fIdentifier) != B_OK + || message.FindString("secondaryIdentifier", &fSecondaryIdentifier) + != B_OK + || message.FindString("owner", &fOwner) != B_OK + || message.FindInt64("creationTime", &fCreationTime) != B_OK + || message.FindData("data", B_RAW_TYPE, &data, &dataLength) != B_OK + || dataLength < 0) { + return B_ERROR; + } + + return SetData((const uint8*)data, (size_t)dataLength); +} + + // #pragma mark - BPasswordKey diff --git a/src/kits/app/KeyStore.cpp b/src/kits/app/KeyStore.cpp index a3fbc593bc..621ccaf437 100644 --- a/src/kits/app/KeyStore.cpp +++ b/src/kits/app/KeyStore.cpp @@ -6,6 +6,12 @@ #include +#include +#include + + +using namespace BPrivate; + BKeyStore::BKeyStore() { @@ -69,7 +75,24 @@ BKeyStore::GetKey(const char* keyring, BKeyType type, BKeyPurpose purpose, const char* identifier, const char* secondaryIdentifier, bool secondaryIdentifierOptional, BKey& key) { - return B_ERROR; + BMessage message(B_REG_GET_KEY); + message.AddString("keyring", keyring); + message.AddUInt32("type", type); + message.AddUInt32("purpose", purpose); + message.AddString("identifier", identifier); + message.AddString("secondaryIdentifier", secondaryIdentifier); + message.AddBool("secondaryIdentifierOptional", secondaryIdentifierOptional); + + BMessage reply; + status_t result = _SendKeyMessage(message, &reply); + if (result != B_OK) + return result; + + BMessage keyMessage; + if (reply.FindMessage("key", &keyMessage) != B_OK) + return B_ERROR; + + return key._Unflatten(keyMessage); } @@ -83,7 +106,15 @@ BKeyStore::AddKey(const BKey& key) status_t BKeyStore::AddKey(const char* keyring, const BKey& key) { - return B_ERROR; + BMessage keyMessage; + if (key._Flatten(keyMessage) != B_OK) + return B_BAD_VALUE; + + BMessage message(B_REG_ADD_KEY); + message.AddString("keyring", keyring); + message.AddMessage("key", &keyMessage); + + return _SendKeyMessage(message, NULL); } @@ -97,7 +128,15 @@ BKeyStore::RemoveKey(const BKey& key) status_t BKeyStore::RemoveKey(const char* keyring, const BKey& key) { - return B_ERROR; + BMessage keyMessage; + if (key._Flatten(keyMessage) != B_OK) + return B_BAD_VALUE; + + BMessage message(B_REG_REMOVE_KEY); + message.AddString("keyring", keyring); + message.AddMessage("key", &keyMessage); + + return _SendKeyMessage(message, NULL); } @@ -119,7 +158,7 @@ BKeyStore::GetNextKey(BKeyType type, BKeyPurpose purpose, uint32& cookie, status_t BKeyStore::GetNextKey(const char* keyring, uint32& cookie, BKey& key) { - return B_ERROR; + return GetNextKey(keyring, B_KEY_TYPE_ANY, B_KEY_PURPOSE_ANY, cookie, key); } @@ -127,7 +166,22 @@ status_t BKeyStore::GetNextKey(const char* keyring, BKeyType type, BKeyPurpose purpose, uint32& cookie, BKey& key) { - return B_ERROR; + BMessage message(B_REG_GET_NEXT_KEY); + message.AddString("keyring", keyring); + message.AddUInt32("type", type); + message.AddUInt32("purpose", purpose); + message.AddUInt32("cookie", cookie); + + BMessage reply; + status_t result = _SendKeyMessage(message, &reply); + if (result != B_OK) + return result; + + BMessage keyMessage; + if (reply.FindMessage("key", &keyMessage) != B_OK) + return B_ERROR; + + return key._Unflatten(keyMessage); } @@ -137,21 +191,42 @@ BKeyStore::GetNextKey(const char* keyring, BKeyType type, BKeyPurpose purpose, status_t BKeyStore::AddKeyring(const char* keyring, const BKey& key) { - return B_ERROR; + BMessage keyMessage; + if (key._Flatten(keyMessage) != B_OK) + return B_BAD_VALUE; + + BMessage message(B_REG_ADD_KEYRING); + message.AddString("keyring", keyring); + message.AddMessage("key", &keyMessage); + + return _SendKeyMessage(message, NULL); } status_t BKeyStore::RemoveKeyring(const char* keyring) { - return B_ERROR; + BMessage message(B_REG_REMOVE_KEYRING); + message.AddString("keyring", keyring); + return _SendKeyMessage(message, NULL); } status_t BKeyStore::GetNextKeyring(uint32& cookie, BString& keyring) { - return B_ERROR; + BMessage message(B_REG_GET_NEXT_KEYRING); + message.AddUInt32("cookie", cookie); + + BMessage reply; + status_t result = _SendKeyMessage(message, &reply); + if (result != B_OK) + return result; + + if (reply.FindString("keyring", &keyring) != B_OK) + return B_ERROR; + + return B_OK; } @@ -161,35 +236,58 @@ BKeyStore::GetNextKeyring(uint32& cookie, BString& keyring) status_t BKeyStore::SetMasterKey(const BKey& key) { - return B_ERROR; + BMessage keyMessage; + if (key._Flatten(keyMessage) != B_OK) + return B_BAD_VALUE; + + BMessage message(B_REG_SET_MASTER_KEY); + message.AddMessage("key", &keyMessage); + + return _SendKeyMessage(message, NULL); } status_t BKeyStore::RemoveMasterKey() { - return B_ERROR; + BMessage message(B_REG_REMOVE_MASTER_KEY); + return _SendKeyMessage(message, NULL); } status_t BKeyStore::AddKeyringToMaster(const char* keyring) { - return B_ERROR; + BMessage message(B_REG_ADD_KEYRING_TO_MASTER); + message.AddString("keyring", keyring); + return _SendKeyMessage(message, NULL); } status_t BKeyStore::RemoveKeyringFromMaster(const char* keyring) { - return B_ERROR; + BMessage message(B_REG_REMOVE_KEYRING_FROM_MASTER); + message.AddString("keyring", keyring); + return _SendKeyMessage(message, NULL); } status_t BKeyStore::GetNextMasterKeyring(uint32& cookie, BString& keyring) { - return B_ERROR; + BMessage message(B_REG_GET_NEXT_MASTER_KEYRING); + message.AddUInt32("cookie", cookie); + + BMessage reply; + status_t result = _SendKeyMessage(message, &reply); + if (result != B_OK) + return result; + + if (reply.FindString("keyring", &keyring) != B_OK) + return B_ERROR; + + return B_OK; } @@ -199,21 +297,26 @@ BKeyStore::GetNextMasterKeyring(uint32& cookie, BString& keyring) bool BKeyStore::IsKeyringAccessible(const char* keyring) { - return false; + BMessage message(B_REG_IS_KEYRING_ACCESSIBLE); + message.AddString("keyring", keyring); + return _SendKeyMessage(message, NULL) == B_OK; } status_t BKeyStore::RevokeAccess(const char* keyring) { - return B_ERROR; + BMessage message(B_REG_REVOKE_ACCESS); + message.AddString("keyring", keyring); + return _SendKeyMessage(message, NULL); } status_t BKeyStore::RevokeMasterAccess() { - return B_ERROR; + BMessage message(B_REG_REVOKE_MASTER_ACCESS); + return _SendKeyMessage(message, NULL); } @@ -225,14 +328,38 @@ status_t BKeyStore::GetNextApplication(const BKey& key, uint32& cookie, BString& signature) const { - return B_ERROR; + BMessage keyMessage; + if (key._Flatten(keyMessage) != B_OK) + return B_BAD_VALUE; + + BMessage message(B_REG_GET_NEXT_APPLICATION); + message.AddMessage("key", &keyMessage); + message.AddUInt32("cookie", cookie); + + BMessage reply; + status_t result = _SendKeyMessage(message, &reply); + if (result != B_OK) + return result; + + if (reply.FindString("signature", &signature) != B_OK) + return B_ERROR; + + return B_OK; } status_t BKeyStore::RemoveApplication(const BKey& key, const char* signature) { - return B_ERROR; + BMessage keyMessage; + if (key._Flatten(keyMessage) != B_OK) + return B_BAD_VALUE; + + BMessage message(B_REG_REMOVE_APPLICATION); + message.AddMessage("key", &keyMessage); + message.AddString("signature", signature); + + return _SendKeyMessage(message, NULL); } @@ -251,3 +378,28 @@ BKeyStore::PasswordStrength(const char* password) { return 0; } + + +// #pragma mark - Private functions + + +status_t +BKeyStore::_SendKeyMessage(BMessage& message, BMessage* reply) const +{ + BMessage localReply; + if (reply == NULL) + reply = &localReply; + + if (BRoster::Private().SendTo(&message, reply, false) != B_OK) + return B_ERROR; + + if (reply->what != B_REG_SUCCESS) { + status_t result = B_ERROR; + if (reply->FindInt32("result", &result) != B_OK) + return B_ERROR; + + return result; + } + + return B_OK; +}