1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
|
/**
* @file llsechandler_basic.h
* @brief Security API for services such as certificate handling
* secure local storage, etc.
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LLSECHANDLER_BASIC
#define LLSECHANDLER_BASIC
#ifdef LL_WINDOWS
#pragma warning (push)
#pragma warning(disable:4250)
#endif // LL_WINDOWS
#include "llsecapi.h"
#include <vector>
#include <openssl/x509.h>
// helpers
extern LLSD cert_name_from_X509_NAME(X509_NAME* name);
extern std::string cert_string_name_from_X509_NAME(X509_NAME* name);
extern std::string cert_string_from_asn1_integer(ASN1_INTEGER* value);
extern LLDate cert_date_from_asn1_time(ASN1_TIME* asn1_time);
extern std::string cert_get_digest(const std::string& digest_type, X509 *cert);
// class LLCertificate
//
class LLBasicCertificate : public LLCertificate
{
public:
LOG_CLASS(LLBasicCertificate);
// The optional validation_params allow us to make the unit test time-invariant
LLBasicCertificate(const std::string& pem_cert, const LLSD* validation_params = NULL);
LLBasicCertificate(X509* openSSLX509, const LLSD* validation_params = NULL);
virtual ~LLBasicCertificate();
virtual std::string getPem() const;
virtual std::vector<U8> getBinary() const;
virtual void getLLSD(LLSD &llsd);
virtual X509* getOpenSSLX509() const;
// set llsd elements for testing
void setLLSD(const std::string name, const LLSD& value) { mLLSDInfo[name] = value; }
protected:
// certificates are stored as X509 objects, as validation and
// other functionality is via openssl
X509* mCert;
LLSD& _initLLSD();
LLSD mLLSDInfo;
};
// class LLBasicCertificateVector
// Class representing a list of certificates
// This implementation uses a stl vector of certificates.
class LLBasicCertificateVector : virtual public LLCertificateVector
{
public:
LLBasicCertificateVector() {}
virtual ~LLBasicCertificateVector() {}
// Implementation of the basic iterator implementation.
// The implementation uses a vector iterator derived from
// the vector in the LLBasicCertificateVector class
class BasicIteratorImpl : public iterator_impl
{
public:
BasicIteratorImpl(std::vector<LLPointer<LLCertificate> >::iterator _iter) { mIter = _iter;}
virtual ~BasicIteratorImpl() {};
// seek forward or back. Used by the operator++/operator-- implementations
virtual void seek(bool incr)
{
if(incr)
{
mIter++;
}
else
{
mIter--;
}
}
// create a copy of the iterator implementation class, used by the iterator copy constructor
virtual LLPointer<iterator_impl> clone() const
{
return new BasicIteratorImpl(mIter);
}
virtual bool equals(const LLPointer<iterator_impl>& _iter) const
{
const BasicIteratorImpl *rhs_iter = dynamic_cast<const BasicIteratorImpl *>(_iter.get());
llassert(rhs_iter);
if (!rhs_iter) return 0;
return (mIter == rhs_iter->mIter);
}
virtual LLPointer<LLCertificate> get()
{
return *mIter;
}
protected:
friend class LLBasicCertificateVector;
std::vector<LLPointer<LLCertificate> >::iterator mIter;
};
// numeric index of the vector
virtual LLPointer<LLCertificate> operator[](int _index) { return mCerts[_index];}
// Iteration
virtual iterator begin() { return iterator(new BasicIteratorImpl(mCerts.begin())); }
virtual iterator end() { return iterator(new BasicIteratorImpl(mCerts.end())); }
// find a cert given params
virtual iterator find(const LLSD& params);
// return the number of certs in the store
virtual int size() const { return static_cast<int>(mCerts.size()); }
// insert the cert to the store. if a copy of the cert already exists in the store, it is removed first
virtual void add(LLPointer<LLCertificate> cert) { insert(end(), cert); }
// insert the cert to the store. if a copy of the cert already exists in the store, it is removed first
virtual void insert(iterator _iter, LLPointer<LLCertificate> cert);
// remove a certificate from the store
virtual LLPointer<LLCertificate> erase(iterator _iter);
protected:
std::vector<LLPointer<LLCertificate> >mCerts;
};
// class LLCertificateStore
// represents a store of certificates, typically a store of root CA
// certificates. The store can be persisted, and can be used to validate
// a cert chain
//
class LLBasicCertificateStore : virtual public LLBasicCertificateVector, public LLCertificateStore
{
public:
LLBasicCertificateStore(const std::string& filename);
void load_from_file(const std::string& filename);
virtual ~LLBasicCertificateStore();
// persist the store
virtual void save();
// return the store id
virtual std::string storeId() const;
// validate a certificate chain against a certificate store, using the
// given validation policy.
virtual void validate(int validation_policy,
LLPointer<LLCertificateChain> ca_chain,
const LLSD& validation_params);
// Clears cache of certs validated agains store
virtual void clearSertCache() { mTrustedCertCache.clear(); }
protected:
std::vector<LLPointer<LLCertificate> > mCerts;
// cache of cert sha1 hashes to from/to date pairs, to improve
// performance of cert trust. Note, these are not the CA certs,
// but the certs that have been validated against this store.
typedef std::map<std::string, std::pair<LLDate, LLDate> > t_cert_cache;
t_cert_cache mTrustedCertCache;
std::string mFilename;
};
// class LLCertificateChain
// Class representing a chain of certificates in order, with the
// first element being the child cert.
class LLBasicCertificateChain : virtual public LLBasicCertificateVector, public LLCertificateChain
{
public:
LLBasicCertificateChain(X509_STORE_CTX * store);
virtual ~LLBasicCertificateChain() {}
};
// LLSecAPIBasicCredential class
class LLSecAPIBasicCredential : public LLCredential
{
public:
LLSecAPIBasicCredential(const std::string& grid) : LLCredential(grid) {}
virtual ~LLSecAPIBasicCredential() {}
// return a value representing the user id, used for server and voice
// (could be guid, name in format "name_resident", whatever)
virtual std::string userID() const;
// printible string identifying the credential.
virtual std::string asString() const;
};
// LLSecAPIBasicHandler Class
// Interface handler class for the various security storage handlers.
class LLSecAPIBasicHandler : public LLSecAPIHandler
{
public:
LLSecAPIBasicHandler(const std::string& protected_data_filename,
const std::string& legacy_password_path);
LLSecAPIBasicHandler();
void init();
virtual ~LLSecAPIBasicHandler();
// instantiate a certificate from a pem string
virtual LLPointer<LLCertificate> getCertificate(const std::string& pem_cert);
// instiate a certificate from an openssl X509 structure
virtual LLPointer<LLCertificate> getCertificate(X509* openssl_cert);
// instantiate a chain from an X509_STORE_CTX
virtual LLPointer<LLCertificateChain> getCertificateChain(X509_STORE_CTX* chain);
// instantiate a cert store given it's id. if a persisted version
// exists, it'll be loaded. If not, one will be created (but not
// persisted)
virtual LLPointer<LLCertificateStore> getCertificateStore(const std::string& store_id);
// protectedData functions technically should be pretected or private,
// they are not because of llsechandler_basic_test imlementation
// persist data in a protected store
virtual void setProtectedData(const std::string& data_type,
const std::string& data_id,
const LLSD& data);
// retrieve protected data
virtual LLSD getProtectedData(const std::string& data_type,
const std::string& data_id);
// delete a protected data item from the store
virtual void deleteProtectedData(const std::string& data_type,
const std::string& data_id);
// persist data in a protected store's map
virtual void addToProtectedMap(const std::string& data_type,
const std::string& data_id,
const std::string& map_elem,
const LLSD& data);
// remove data from protected store's map
virtual void removeFromProtectedMap(const std::string& data_type,
const std::string& data_id,
const std::string& map_elem);
// ensure protected store's map is written to storage
virtual void syncProtectedMap();
// credential management routines
virtual LLPointer<LLCredential> createCredential(const std::string& grid,
const LLSD& identifier,
const LLSD& authenticator);
// load single credencial from default storage
virtual LLPointer<LLCredential> loadCredential(const std::string& grid);
// save credencial to default storage
virtual void saveCredential(LLPointer<LLCredential> cred, bool save_authenticator);
virtual void deleteCredential(LLPointer<LLCredential> cred);
// has map of credentials declared as specific storage
virtual bool hasCredentialMap(const std::string& storage,
const std::string& grid);
// returns true if map is empty or does not exist
virtual bool emptyCredentialMap(const std::string& storage,
const std::string& grid);
// load map of credentials from specific storage
virtual void loadCredentialMap(const std::string& storage,
const std::string& grid,
credential_map_t& credential_map);
// load single username from map of credentials from specific storage
virtual LLPointer<LLCredential> loadFromCredentialMap(const std::string& storage,
const std::string& grid,
const std::string& userid);
// add item to map of credentials from specific storage
virtual void addToCredentialMap(const std::string& storage,
LLPointer<LLCredential> cred,
bool save_authenticator);
// remove item from map of credentials from specific storage
virtual void removeFromCredentialMap(const std::string& storage,
LLPointer<LLCredential> cred);
// remove item from map of credentials from specific storage
virtual void removeFromCredentialMap(const std::string& storage,
const std::string& grid,
const std::string& userid);
virtual void removeCredentialMap(const std::string& storage,
const std::string& grid);
protected:
void _readProtectedData(unsigned char *unique_id, U32 id_len);
void _readProtectedData();
void _writeProtectedData();
std::string _legacyLoadPassword();
std::string mProtectedDataFilename;
LLSD mProtectedDataMap;
LLPointer<LLBasicCertificateStore> mStore;
std::string mLegacyPasswordPath;
};
bool valueCompareLLSD(const LLSD& lhs, const LLSD& rhs);
#ifdef LL_WINDOWS
#pragma warning (pop)
#endif // LL_WINDOWS
#endif // LLSECHANDLER_BASIC
|