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 <Key.h>
8
9#include <stdio.h>
10
11
12#if 0
13// TODO: move this to the KeyStore or the registrar backend if needed
14static bool
15CompareLists(BObjectList<BString> a, BObjectList<BString> b)
16{
17	if (a.CountItems() != b.CountItems())
18		return false;
19
20	for (int32 i = 0; i < a.CountItems(); i++) {
21		if (*a.ItemAt(i) != *b.ItemAt(i))
22			return false;
23	}
24
25	return true;
26}
27#endif
28
29
30// #pragma mark - Generic BKey
31
32
33BKey::BKey()
34{
35	Unset();
36}
37
38
39BKey::BKey(BKeyPurpose purpose, const char* identifier,
40	const char* secondaryIdentifier, const uint8* data, size_t length)
41{
42	SetTo(purpose, identifier, secondaryIdentifier, data, length);
43}
44
45
46BKey::BKey(BKey& other)
47{
48	*this = other;
49}
50
51
52BKey::~BKey()
53{
54}
55
56
57void
58BKey::Unset()
59{
60	SetTo(B_KEY_PURPOSE_GENERIC, "", "", NULL, 0);
61}
62
63
64status_t
65BKey::SetTo(BKeyPurpose purpose, const char* identifier,
66	const char* secondaryIdentifier, const uint8* data, size_t length)
67{
68	fCreationTime = 0;
69	SetPurpose(purpose);
70	SetIdentifier(identifier);
71	SetSecondaryIdentifier(secondaryIdentifier);
72	return SetData(data, length);
73}
74
75
76void
77BKey::SetPurpose(BKeyPurpose purpose)
78{
79	fPurpose = purpose;
80}
81
82
83BKeyPurpose
84BKey::Purpose() const
85{
86	return fPurpose;
87}
88
89
90void
91BKey::SetIdentifier(const char* identifier)
92{
93	fIdentifier = identifier;
94}
95
96
97const char*
98BKey::Identifier() const
99{
100	return fIdentifier.String();
101}
102
103
104void
105BKey::SetSecondaryIdentifier(const char* identifier)
106{
107	fSecondaryIdentifier = identifier;
108}
109
110
111const char*
112BKey::SecondaryIdentifier() const
113{
114	return fSecondaryIdentifier.String();
115}
116
117
118status_t
119BKey::SetData(const uint8* data, size_t length)
120{
121	fData.SetSize(0);
122	ssize_t bytesWritten = fData.WriteAt(0, data, length);
123	if (bytesWritten < 0)
124		return (status_t)bytesWritten;
125
126	return (size_t)bytesWritten == length ? B_OK : B_NO_MEMORY;
127}
128
129
130size_t
131BKey::DataLength() const
132{
133	return fData.BufferLength();
134}
135
136
137const uint8*
138BKey::Data() const
139{
140	return (const uint8*)fData.Buffer();
141}
142
143
144status_t
145BKey::GetData(uint8* buffer, size_t bufferSize) const
146{
147	ssize_t bytesRead = fData.ReadAt(0, buffer, bufferSize);
148	if (bytesRead < 0)
149		return (status_t)bytesRead;
150
151	return B_OK;
152}
153
154
155
156const char*
157BKey::Owner() const
158{
159	return fOwner.String();
160}
161
162
163bigtime_t
164BKey::CreationTime() const
165{
166	return fCreationTime;
167}
168
169
170status_t
171BKey::Flatten(BMessage& message) const
172{
173	if (message.MakeEmpty() != B_OK
174		|| message.AddUInt32("type", Type()) != B_OK
175		|| message.AddUInt32("purpose", fPurpose) != B_OK
176		|| message.AddString("identifier", fIdentifier) != B_OK
177		|| message.AddString("secondaryIdentifier", fSecondaryIdentifier)
178			!= B_OK
179		|| message.AddString("owner", fOwner) != B_OK
180		|| message.AddInt64("creationTime", fCreationTime) != B_OK
181		|| message.AddData("data", B_RAW_TYPE, fData.Buffer(),
182			fData.BufferLength()) != B_OK) {
183		return B_ERROR;
184	}
185
186	return B_OK;
187}
188
189
190status_t
191BKey::Unflatten(const BMessage& message)
192{
193	BKeyType type;
194	if (message.FindUInt32("type", (uint32*)&type) != B_OK || type != Type())
195		return B_BAD_VALUE;
196
197	const void* data = NULL;
198	ssize_t dataLength = 0;
199	if (message.FindUInt32("purpose", (uint32*)&fPurpose) != B_OK
200		|| message.FindString("identifier", &fIdentifier) != B_OK
201		|| message.FindString("secondaryIdentifier", &fSecondaryIdentifier)
202			!= B_OK
203		|| message.FindString("owner", &fOwner) != B_OK
204		|| message.FindInt64("creationTime", &fCreationTime) != B_OK
205		|| message.FindData("data", B_RAW_TYPE, &data, &dataLength) != B_OK
206		|| dataLength < 0) {
207		return B_ERROR;
208	}
209
210	return SetData((const uint8*)data, (size_t)dataLength);
211}
212
213
214BKey&
215BKey::operator=(const BKey& other)
216{
217	SetPurpose(other.Purpose());
218	SetData((const uint8*)other.Data(), other.DataLength());
219
220	fIdentifier = other.fIdentifier;
221	fSecondaryIdentifier = other.fSecondaryIdentifier;
222	fOwner = other.fOwner;
223	fCreationTime = other.fCreationTime;
224
225	return *this;
226}
227
228
229bool
230BKey::operator==(const BKey& other) const
231{
232	return Type() == other.Type()
233		&& DataLength() == other.DataLength()
234		&& Purpose() == other.Purpose()
235		&& fOwner == other.fOwner
236		&& fIdentifier == other.fIdentifier
237		&& fSecondaryIdentifier == other.fSecondaryIdentifier
238		&& memcmp(Data(), other.Data(), DataLength()) == 0;
239}
240
241
242bool
243BKey::operator!=(const BKey& other) const
244{
245	return !(*this == other);
246}
247
248
249void
250BKey::PrintToStream()
251{
252	if (Type() == B_KEY_TYPE_GENERIC)
253		printf("generic key:\n");
254
255	const char* purposeString = "unknown";
256	switch (fPurpose) {
257		case B_KEY_PURPOSE_ANY:
258			purposeString = "any";
259			break;
260		case B_KEY_PURPOSE_GENERIC:
261			purposeString = "generic";
262			break;
263		case B_KEY_PURPOSE_KEYRING:
264			purposeString = "keyring";
265			break;
266		case B_KEY_PURPOSE_WEB:
267			purposeString = "web";
268			break;
269		case B_KEY_PURPOSE_NETWORK:
270			purposeString = "network";
271			break;
272		case B_KEY_PURPOSE_VOLUME:
273			purposeString = "volume";
274			break;
275	}
276
277	printf("\tpurpose: %s\n", purposeString);
278	printf("\tidentifier: \"%s\"\n", fIdentifier.String());
279	printf("\tsecondary identifier: \"%s\"\n", fSecondaryIdentifier.String());
280	printf("\towner: \"%s\"\n", fOwner.String());
281	printf("\tcreation time: %" B_PRIu64 "\n", fCreationTime);
282	printf("\traw data length: %" B_PRIuSIZE "\n", fData.BufferLength());
283}
284
285
286// #pragma mark - BPasswordKey
287
288
289BPasswordKey::BPasswordKey()
290{
291}
292
293
294BPasswordKey::BPasswordKey(const char* password, BKeyPurpose purpose,
295	const char* identifier, const char* secondaryIdentifier)
296	:
297	BKey(purpose, identifier, secondaryIdentifier, (const uint8*)password,
298		strlen(password) + 1)
299{
300}
301
302
303BPasswordKey::BPasswordKey(BPasswordKey& other)
304{
305}
306
307
308BPasswordKey::~BPasswordKey()
309{
310}
311
312
313status_t
314BPasswordKey::SetTo(const char* password, BKeyPurpose purpose,
315	const char* identifier, const char* secondaryIdentifier)
316{
317	return BKey::SetTo(purpose, identifier, secondaryIdentifier,
318		(const uint8*)password, strlen(password) + 1);
319}
320
321
322status_t
323BPasswordKey::SetPassword(const char* password)
324{
325	return SetData((const uint8*)password, strlen(password) + 1);
326}
327
328
329const char*
330BPasswordKey::Password() const
331{
332	return (const char*)Data();
333}
334
335
336void
337BPasswordKey::PrintToStream()
338{
339	printf("password key:\n");
340	BKey::PrintToStream();
341	printf("\tpassword: \"%s\"\n", Password());
342}
343