xref: /haiku/src/kits/app/KeyStore.cpp (revision c1ad322d8f274def4c26eded38fc9e0615d92cd6)
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