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
BKeyStore()18 BKeyStore::BKeyStore()
19 {
20 }
21
22
~BKeyStore()23 BKeyStore::~BKeyStore()
24 {
25 }
26
27
28 // #pragma mark - Key handling
29
30
31 status_t
GetKey(BKeyType type,const char * identifier,BKey & key)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
GetKey(BKeyType type,const char * identifier,const char * secondaryIdentifier,BKey & key)39 BKeyStore::GetKey(BKeyType type, const char* identifier,
40 const char* secondaryIdentifier, BKey& key)
41 {
42 return GetKey(NULL, type, identifier, secondaryIdentifier, false, key);
43 }
44
45
46 status_t
GetKey(BKeyType type,const char * identifier,const char * secondaryIdentifier,bool secondaryIdentifierOptional,BKey & key)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
GetKey(const char * keyring,BKeyType type,const char * identifier,BKey & key)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
GetKey(const char * keyring,BKeyType type,const char * identifier,const char * secondaryIdentifier,BKey & key)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, false, key);
69 }
70
71
72 status_t
GetKey(const char * keyring,BKeyType type,const char * identifier,const char * secondaryIdentifier,bool secondaryIdentifierOptional,BKey & key)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
AddKey(const BKey & key)98 BKeyStore::AddKey(const BKey& key)
99 {
100 return AddKey(NULL, key);
101 }
102
103
104 status_t
AddKey(const char * keyring,const BKey & key)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
RemoveKey(const BKey & key)120 BKeyStore::RemoveKey(const BKey& key)
121 {
122 return RemoveKey(NULL, key);
123 }
124
125
126 status_t
RemoveKey(const char * keyring,const BKey & key)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
GetNextKey(uint32 & cookie,BKey & key)142 BKeyStore::GetNextKey(uint32& cookie, BKey& key)
143 {
144 return GetNextKey(NULL, cookie, key);
145 }
146
147
148 status_t
GetNextKey(BKeyType type,BKeyPurpose purpose,uint32 & cookie,BKey & key)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
GetNextKey(const char * keyring,uint32 & cookie,BKey & key)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
GetNextKey(const char * keyring,BKeyType type,BKeyPurpose purpose,uint32 & cookie,BKey & key)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
AddKeyring(const char * keyring)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
RemoveKeyring(const char * keyring)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
GetNextKeyring(uint32 & cookie,BString & keyring)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
SetUnlockKey(const char * keyring,const BKey & key)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
RemoveUnlockKey(const char * keyring)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
SetMasterUnlockKey(const BKey & key)255 BKeyStore::SetMasterUnlockKey(const BKey& key)
256 {
257 return SetUnlockKey(NULL, key);
258 }
259
260
261 status_t
RemoveMasterUnlockKey()262 BKeyStore::RemoveMasterUnlockKey()
263 {
264 return RemoveUnlockKey(NULL);
265 }
266
267
268 status_t
AddKeyringToMaster(const char * keyring)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
RemoveKeyringFromMaster(const char * keyring)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
GetNextMasterKeyring(uint32 & cookie,BString & keyring)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
IsKeyringUnlocked(const char * keyring)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
LockKeyring(const char * keyring)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
LockMasterKeyring()336 BKeyStore::LockMasterKeyring()
337 {
338 return LockKeyring(NULL);
339 }
340
341
342
343 // #pragma mark - Applications
344
345
346 status_t
GetNextApplication(uint32 & cookie,BString & signature) const347 BKeyStore::GetNextApplication(uint32& cookie, BString& signature) const
348 {
349 return GetNextApplication(NULL, cookie, signature);
350 }
351
352
353 status_t
GetNextApplication(const char * keyring,uint32 & cookie,BString & signature) const354 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
RemoveApplication(const char * signature)375 BKeyStore::RemoveApplication(const char* signature)
376 {
377 return RemoveApplication(NULL, signature);
378 }
379
380
381 status_t
RemoveApplication(const char * keyring,const char * signature)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
GeneratePassword(BPasswordKey & password,size_t length,uint32 flags)396 BKeyStore::GeneratePassword(BPasswordKey& password, size_t length, uint32 flags)
397 {
398 return B_ERROR;
399 }
400
401
402 float
PasswordStrength(const char * password)403 BKeyStore::PasswordStrength(const char* password)
404 {
405 return 0;
406 }
407
408
409 // #pragma mark - Private functions
410
411
412 status_t
_SendKeyMessage(BMessage & message,BMessage * reply) const413 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