1 /* 2 * Copyright 2011, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <KeyStore.h> 8 9 #include <KeyStoreDefs.h> 10 11 #include <Messenger.h> 12 #include <Roster.h> 13 14 15 using namespace BPrivate; 16 17 18 BKeyStore::BKeyStore() 19 { 20 } 21 22 23 BKeyStore::~BKeyStore() 24 { 25 } 26 27 28 // #pragma mark - Key handling 29 30 31 status_t 32 BKeyStore::GetKey(BKeyType type, const char* identifier, BKey& key) 33 { 34 return GetKey(NULL, type, identifier, NULL, true, key); 35 } 36 37 38 status_t 39 BKeyStore::GetKey(BKeyType type, const char* identifier, 40 const char* secondaryIdentifier, BKey& key) 41 { 42 return GetKey(NULL, type, identifier, secondaryIdentifier, true, key); 43 } 44 45 46 status_t 47 BKeyStore::GetKey(BKeyType type, const char* identifier, 48 const char* secondaryIdentifier, bool secondaryIdentifierOptional, 49 BKey& key) 50 { 51 return GetKey(NULL, type, identifier, secondaryIdentifier, 52 secondaryIdentifierOptional, key); 53 } 54 55 56 status_t 57 BKeyStore::GetKey(const char* keyring, BKeyType type, const char* identifier, 58 BKey& key) 59 { 60 return GetKey(keyring, type, identifier, NULL, true, key); 61 } 62 63 64 status_t 65 BKeyStore::GetKey(const char* keyring, BKeyType type, const char* identifier, 66 const char* secondaryIdentifier, BKey& key) 67 { 68 return GetKey(keyring, type, identifier, secondaryIdentifier, true, key); 69 } 70 71 72 status_t 73 BKeyStore::GetKey(const char* keyring, BKeyType type, const char* identifier, 74 const char* secondaryIdentifier, bool secondaryIdentifierOptional, 75 BKey& key) 76 { 77 BMessage message(KEY_STORE_GET_KEY); 78 message.AddString("keyring", keyring); 79 message.AddUInt32("type", type); 80 message.AddString("identifier", identifier); 81 message.AddString("secondaryIdentifier", secondaryIdentifier); 82 message.AddBool("secondaryIdentifierOptional", secondaryIdentifierOptional); 83 84 BMessage reply; 85 status_t result = _SendKeyMessage(message, &reply); 86 if (result != B_OK) 87 return result; 88 89 BMessage keyMessage; 90 if (reply.FindMessage("key", &keyMessage) != B_OK) 91 return B_ERROR; 92 93 return key.Unflatten(keyMessage); 94 } 95 96 97 status_t 98 BKeyStore::AddKey(const BKey& key) 99 { 100 return AddKey(NULL, key); 101 } 102 103 104 status_t 105 BKeyStore::AddKey(const char* keyring, const BKey& key) 106 { 107 BMessage keyMessage; 108 if (key.Flatten(keyMessage) != B_OK) 109 return B_BAD_VALUE; 110 111 BMessage message(KEY_STORE_ADD_KEY); 112 message.AddString("keyring", keyring); 113 message.AddMessage("key", &keyMessage); 114 115 return _SendKeyMessage(message, NULL); 116 } 117 118 119 status_t 120 BKeyStore::RemoveKey(const BKey& key) 121 { 122 return RemoveKey(NULL, key); 123 } 124 125 126 status_t 127 BKeyStore::RemoveKey(const char* keyring, const BKey& key) 128 { 129 BMessage keyMessage; 130 if (key.Flatten(keyMessage) != B_OK) 131 return B_BAD_VALUE; 132 133 BMessage message(KEY_STORE_REMOVE_KEY); 134 message.AddString("keyring", keyring); 135 message.AddMessage("key", &keyMessage); 136 137 return _SendKeyMessage(message, NULL); 138 } 139 140 141 status_t 142 BKeyStore::GetNextKey(uint32& cookie, BKey& key) 143 { 144 return GetNextKey(NULL, cookie, key); 145 } 146 147 148 status_t 149 BKeyStore::GetNextKey(BKeyType type, BKeyPurpose purpose, uint32& cookie, 150 BKey& key) 151 { 152 return GetNextKey(NULL, type, purpose, cookie, key); 153 } 154 155 156 status_t 157 BKeyStore::GetNextKey(const char* keyring, uint32& cookie, BKey& key) 158 { 159 return GetNextKey(keyring, B_KEY_TYPE_ANY, B_KEY_PURPOSE_ANY, cookie, key); 160 } 161 162 163 status_t 164 BKeyStore::GetNextKey(const char* keyring, BKeyType type, BKeyPurpose purpose, 165 uint32& cookie, BKey& key) 166 { 167 BMessage message(KEY_STORE_GET_NEXT_KEY); 168 message.AddString("keyring", keyring); 169 message.AddUInt32("type", type); 170 message.AddUInt32("purpose", purpose); 171 message.AddUInt32("cookie", cookie); 172 173 BMessage reply; 174 status_t result = _SendKeyMessage(message, &reply); 175 if (result != B_OK) 176 return result; 177 178 BMessage keyMessage; 179 if (reply.FindMessage("key", &keyMessage) != B_OK) 180 return B_ERROR; 181 182 reply.FindUInt32("cookie", &cookie); 183 return key.Unflatten(keyMessage); 184 } 185 186 187 // #pragma mark - Keyrings 188 189 190 status_t 191 BKeyStore::AddKeyring(const char* keyring) 192 { 193 BMessage message(KEY_STORE_ADD_KEYRING); 194 message.AddString("keyring", keyring); 195 return _SendKeyMessage(message, NULL); 196 } 197 198 199 status_t 200 BKeyStore::RemoveKeyring(const char* keyring) 201 { 202 BMessage message(KEY_STORE_REMOVE_KEYRING); 203 message.AddString("keyring", keyring); 204 return _SendKeyMessage(message, NULL); 205 } 206 207 208 status_t 209 BKeyStore::GetNextKeyring(uint32& cookie, BString& keyring) 210 { 211 BMessage message(KEY_STORE_GET_NEXT_KEYRING); 212 message.AddUInt32("cookie", cookie); 213 214 BMessage reply; 215 status_t result = _SendKeyMessage(message, &reply); 216 if (result != B_OK) 217 return result; 218 219 if (reply.FindString("keyring", &keyring) != B_OK) 220 return B_ERROR; 221 222 reply.FindUInt32("cookie", &cookie); 223 return B_OK; 224 } 225 226 227 status_t 228 BKeyStore::SetUnlockKey(const char* keyring, const BKey& key) 229 { 230 BMessage keyMessage; 231 if (key.Flatten(keyMessage) != B_OK) 232 return B_BAD_VALUE; 233 234 BMessage message(KEY_STORE_SET_UNLOCK_KEY); 235 message.AddString("keyring", keyring); 236 message.AddMessage("key", &keyMessage); 237 238 return _SendKeyMessage(message, NULL); 239 } 240 241 242 status_t 243 BKeyStore::RemoveUnlockKey(const char* keyring) 244 { 245 BMessage message(KEY_STORE_REMOVE_UNLOCK_KEY); 246 message.AddString("keyring", keyring); 247 return _SendKeyMessage(message, NULL); 248 } 249 250 251 // #pragma mark - Master key 252 253 254 status_t 255 BKeyStore::SetMasterUnlockKey(const BKey& key) 256 { 257 return SetUnlockKey(NULL, key); 258 } 259 260 261 status_t 262 BKeyStore::RemoveMasterUnlockKey() 263 { 264 return RemoveUnlockKey(NULL); 265 } 266 267 268 status_t 269 BKeyStore::AddKeyringToMaster(const char* keyring) 270 { 271 BMessage message(KEY_STORE_ADD_KEYRING_TO_MASTER); 272 message.AddString("keyring", keyring); 273 return _SendKeyMessage(message, NULL); 274 } 275 276 277 status_t 278 BKeyStore::RemoveKeyringFromMaster(const char* keyring) 279 { 280 BMessage message(KEY_STORE_REMOVE_KEYRING_FROM_MASTER); 281 message.AddString("keyring", keyring); 282 return _SendKeyMessage(message, NULL); 283 } 284 285 286 status_t 287 BKeyStore::GetNextMasterKeyring(uint32& cookie, BString& keyring) 288 { 289 BMessage message(KEY_STORE_GET_NEXT_MASTER_KEYRING); 290 message.AddUInt32("cookie", cookie); 291 292 BMessage reply; 293 status_t result = _SendKeyMessage(message, &reply); 294 if (result != B_OK) 295 return result; 296 297 if (reply.FindString("keyring", &keyring) != B_OK) 298 return B_ERROR; 299 300 reply.FindUInt32("cookie", &cookie); 301 return B_OK; 302 } 303 304 305 // #pragma mark - Locking 306 307 308 bool 309 BKeyStore::IsKeyringUnlocked(const char* keyring) 310 { 311 BMessage message(KEY_STORE_IS_KEYRING_UNLOCKED); 312 message.AddString("keyring", keyring); 313 314 BMessage reply; 315 if (_SendKeyMessage(message, &reply) != B_OK) 316 return false; 317 318 bool unlocked; 319 if (reply.FindBool("unlocked", &unlocked) != B_OK) 320 return false; 321 322 return unlocked; 323 } 324 325 326 status_t 327 BKeyStore::LockKeyring(const char* keyring) 328 { 329 BMessage message(KEY_STORE_LOCK_KEYRING); 330 message.AddString("keyring", keyring); 331 return _SendKeyMessage(message, NULL); 332 } 333 334 335 status_t 336 BKeyStore::LockMasterKeyring() 337 { 338 return LockKeyring(NULL); 339 } 340 341 342 343 // #pragma mark - Applications 344 345 346 status_t 347 BKeyStore::GetNextApplication(uint32& cookie, BString& signature) const 348 { 349 return GetNextApplication(NULL, cookie, signature); 350 } 351 352 353 status_t 354 BKeyStore::GetNextApplication(const char* keyring, uint32& cookie, 355 BString& signature) const 356 { 357 BMessage message(KEY_STORE_GET_NEXT_APPLICATION); 358 message.AddString("keyring", keyring); 359 message.AddUInt32("cookie", cookie); 360 361 BMessage reply; 362 status_t result = _SendKeyMessage(message, &reply); 363 if (result != B_OK) 364 return result; 365 366 if (reply.FindString("signature", &signature) != B_OK) 367 return B_ERROR; 368 369 reply.FindUInt32("cookie", &cookie); 370 return B_OK; 371 } 372 373 374 status_t 375 BKeyStore::RemoveApplication(const char* signature) 376 { 377 return RemoveApplication(NULL, signature); 378 } 379 380 381 status_t 382 BKeyStore::RemoveApplication(const char* keyring, const char* signature) 383 { 384 BMessage message(KEY_STORE_REMOVE_APPLICATION); 385 message.AddString("keyring", keyring); 386 message.AddString("signature", signature); 387 388 return _SendKeyMessage(message, NULL); 389 } 390 391 392 // #pragma mark - Service functions 393 394 395 status_t 396 BKeyStore::GeneratePassword(BPasswordKey& password, size_t length, uint32 flags) 397 { 398 return B_ERROR; 399 } 400 401 402 float 403 BKeyStore::PasswordStrength(const char* password) 404 { 405 return 0; 406 } 407 408 409 // #pragma mark - Private functions 410 411 412 status_t 413 BKeyStore::_SendKeyMessage(BMessage& message, BMessage* reply) const 414 { 415 BMessage localReply; 416 if (reply == NULL) 417 reply = &localReply; 418 419 BMessenger messenger(kKeyStoreServerSignature); 420 if (!messenger.IsValid()) { 421 // Try to start the keystore server. 422 status_t result = be_roster->Launch(kKeyStoreServerSignature); 423 if (result != B_OK && result != B_ALREADY_RUNNING) 424 return B_ERROR; 425 426 // Then re-target the messenger and check again. 427 messenger.SetTo(kKeyStoreServerSignature); 428 if (!messenger.IsValid()) 429 return B_ERROR; 430 } 431 432 if (messenger.SendMessage(&message, reply) != B_OK) 433 return B_ERROR; 434 435 if (reply->what != KEY_STORE_SUCCESS) { 436 status_t result = B_ERROR; 437 if (reply->FindInt32("result", &result) != B_OK) 438 return B_ERROR; 439 440 return result; 441 } 442 443 return B_OK; 444 } 445