364 lines
13 KiB
C++
364 lines
13 KiB
C++
/**
|
|
* @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& credName) : LLCredential(credName) {}
|
|
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& credName,
|
|
const LLSD& identifier,
|
|
const LLSD& authenticator);
|
|
|
|
// load single credencial from default storage
|
|
virtual LLPointer<LLCredential> loadCredential(const std::string& credName);
|
|
|
|
// save credencial to default storage
|
|
virtual void saveCredential(LLPointer<LLCredential> cred, bool save_authenticator);
|
|
|
|
virtual void deleteCredential(LLPointer<LLCredential> cred);
|
|
|
|
virtual std::vector<std::string> listCredentials();
|
|
|
|
// 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
|
|
|
|
|
|
|