/indra/newview/llsecapi.h

https://bitbucket.org/lindenlab/viewer-beta/ · C Header · 493 lines · 290 code · 112 blank · 91 comment · 5 complexity · eca85bff6e4d697597b979ab68e2165a MD5 · raw file

  1. /**
  2. * @file llsecapi.h
  3. * @brief Security API for services such as certificate handling
  4. * secure local storage, etc.
  5. *
  6. * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  7. * Second Life Viewer Source Code
  8. * Copyright (C) 2010, Linden Research, Inc.
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation;
  13. * version 2.1 of the License only.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public
  21. * License along with this library; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. *
  24. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  25. * $/LicenseInfo$
  26. */
  27. #ifndef LLSECAPI_H
  28. #define LLSECAPI_H
  29. #include <vector>
  30. #include <openssl/x509.h>
  31. #include <ostream>
  32. #ifdef LL_WINDOWS
  33. #pragma warning(disable:4250)
  34. #endif // LL_WINDOWS
  35. // All error handling is via exceptions.
  36. #define CERT_SUBJECT_NAME "subject_name"
  37. #define CERT_ISSUER_NAME "issuer_name"
  38. #define CERT_NAME_CN "commonName"
  39. #define CERT_SUBJECT_NAME_STRING "subject_name_string"
  40. #define CERT_ISSUER_NAME_STRING "issuer_name_string"
  41. #define CERT_SERIAL_NUMBER "serial_number"
  42. #define CERT_VALID_FROM "valid_from"
  43. #define CERT_VALID_TO "valid_to"
  44. #define CERT_SHA1_DIGEST "sha1_digest"
  45. #define CERT_MD5_DIGEST "md5_digest"
  46. #define CERT_HOSTNAME "hostname"
  47. #define CERT_BASIC_CONSTRAINTS "basicConstraints"
  48. #define CERT_BASIC_CONSTRAINTS_CA "CA"
  49. #define CERT_BASIC_CONSTRAINTS_PATHLEN "pathLen"
  50. #define CERT_KEY_USAGE "keyUsage"
  51. #define CERT_KU_DIGITAL_SIGNATURE "digitalSignature"
  52. #define CERT_KU_NON_REPUDIATION "nonRepudiation"
  53. #define CERT_KU_KEY_ENCIPHERMENT "keyEncipherment"
  54. #define CERT_KU_DATA_ENCIPHERMENT "dataEncipherment"
  55. #define CERT_KU_KEY_AGREEMENT "keyAgreement"
  56. #define CERT_KU_CERT_SIGN "certSigning"
  57. #define CERT_KU_CRL_SIGN "crlSigning"
  58. #define CERT_KU_ENCIPHER_ONLY "encipherOnly"
  59. #define CERT_KU_DECIPHER_ONLY "decipherOnly"
  60. #define BASIC_SECHANDLER "BASIC_SECHANDLER"
  61. #define CERT_VALIDATION_DATE "validation_date"
  62. #define CERT_EXTENDED_KEY_USAGE "extendedKeyUsage"
  63. #define CERT_EKU_SERVER_AUTH SN_server_auth
  64. #define CERT_SUBJECT_KEY_IDENTFIER "subjectKeyIdentifier"
  65. #define CERT_AUTHORITY_KEY_IDENTIFIER "authorityKeyIdentifier"
  66. #define CERT_AUTHORITY_KEY_IDENTIFIER_ID "authorityKeyIdentifierId"
  67. #define CERT_AUTHORITY_KEY_IDENTIFIER_NAME "authorityKeyIdentifierName"
  68. #define CERT_AUTHORITY_KEY_IDENTIFIER_SERIAL "authorityKeyIdentifierSerial"
  69. // validate the current time lies within
  70. // the validation period of the cert
  71. #define VALIDATION_POLICY_TIME 1
  72. // validate that the CA, or some cert in the chain
  73. // lies within the certificate store
  74. #define VALIDATION_POLICY_TRUSTED 2
  75. // validate that the subject name of
  76. // the cert contains the passed in hostname
  77. // or validates against the hostname
  78. #define VALIDATION_POLICY_HOSTNAME 4
  79. // validate that the cert contains the SSL EKU
  80. #define VALIDATION_POLICY_SSL_KU 8
  81. // validate that the cert contains the SSL EKU
  82. #define VALIDATION_POLICY_CA_KU 16
  83. #define VALIDATION_POLICY_CA_BASIC_CONSTRAINTS 32
  84. // validate that the cert is correct for SSL
  85. #define VALIDATION_POLICY_SSL (VALIDATION_POLICY_TIME | \
  86. VALIDATION_POLICY_HOSTNAME | \
  87. VALIDATION_POLICY_TRUSTED | \
  88. VALIDATION_POLICY_SSL_KU | \
  89. VALIDATION_POLICY_CA_BASIC_CONSTRAINTS | \
  90. VALIDATION_POLICY_CA_KU)
  91. class LLProtectedDataException
  92. {
  93. public:
  94. LLProtectedDataException(const char *msg)
  95. {
  96. LL_WARNS("SECAPI") << "Protected Data Error: " << (std::string)msg << LL_ENDL;
  97. mMsg = (std::string)msg;
  98. }
  99. std::string getMessage() { return mMsg; }
  100. protected:
  101. std::string mMsg;
  102. };
  103. // class LLCertificate
  104. // parent class providing an interface for certifiate.
  105. // LLCertificates are considered unmodifiable
  106. // Certificates are pulled out of stores, or created via
  107. // factory calls
  108. class LLCertificate : public LLThreadSafeRefCount
  109. {
  110. LOG_CLASS(LLCertificate);
  111. public:
  112. LLCertificate() {}
  113. virtual ~LLCertificate() {}
  114. // return a PEM encoded certificate. The encoding
  115. // includes the -----BEGIN CERTIFICATE----- and end certificate elements
  116. virtual std::string getPem() const=0;
  117. // return a DER encoded certificate
  118. virtual std::vector<U8> getBinary() const=0;
  119. // return an LLSD object containing information about the certificate
  120. // such as its name, signature, expiry time, serial number
  121. virtual void getLLSD(LLSD& llsd)=0;
  122. // return an openSSL X509 struct for the certificate
  123. virtual X509* getOpenSSLX509() const=0;
  124. };
  125. // class LLCertificateVector
  126. // base class for a list of certificates.
  127. class LLCertificateVector : public LLThreadSafeRefCount
  128. {
  129. public:
  130. LLCertificateVector() {};
  131. virtual ~LLCertificateVector() {};
  132. // base iterator implementation class, providing
  133. // the functionality needed for the iterator class.
  134. class iterator_impl : public LLThreadSafeRefCount
  135. {
  136. public:
  137. iterator_impl() {};
  138. virtual ~iterator_impl() {};
  139. virtual void seek(bool incr)=0;
  140. virtual LLPointer<iterator_impl> clone() const=0;
  141. virtual bool equals(const LLPointer<iterator_impl>& _iter) const=0;
  142. virtual LLPointer<LLCertificate> get()=0;
  143. };
  144. // iterator class
  145. class iterator
  146. {
  147. public:
  148. iterator(LLPointer<iterator_impl> impl) : mImpl(impl) {}
  149. iterator() : mImpl(NULL) {}
  150. iterator(const iterator& _iter) {mImpl = _iter.mImpl->clone(); }
  151. ~iterator() {}
  152. iterator& operator++() { if(mImpl.notNull()) mImpl->seek(true); return *this;}
  153. iterator& operator--() { if(mImpl.notNull()) mImpl->seek(false); return *this;}
  154. iterator operator++(int) { iterator result = *this; if(mImpl.notNull()) mImpl->seek(true); return result;}
  155. iterator operator--(int) { iterator result = *this; if(mImpl.notNull()) mImpl->seek(false); return result;}
  156. LLPointer<LLCertificate> operator*() { return mImpl->get(); }
  157. LLPointer<iterator_impl> mImpl;
  158. protected:
  159. friend bool operator==(const LLCertificateVector::iterator& _lhs, const LLCertificateVector::iterator& _rhs);
  160. bool equals(const iterator& _iter) const { return mImpl->equals(_iter.mImpl); }
  161. };
  162. // numeric indexer
  163. virtual LLPointer<LLCertificate> operator[](int)=0;
  164. // Iteration
  165. virtual iterator begin()=0;
  166. virtual iterator end()=0;
  167. // find a cert given params
  168. virtual iterator find(const LLSD& params) =0;
  169. // return the number of certs in the store
  170. virtual int size() const = 0;
  171. // append the cert to the store. if a copy of the cert already exists in the store, it is removed first
  172. virtual void add(LLPointer<LLCertificate> cert)=0;
  173. // insert the cert to the store. if a copy of the cert already exists in the store, it is removed first
  174. virtual void insert(iterator location, LLPointer<LLCertificate> cert)=0;
  175. // remove a certificate from the store
  176. virtual LLPointer<LLCertificate> erase(iterator cert)=0;
  177. };
  178. // class LLCertificateChain
  179. // Class representing a chain of certificates in order, with the
  180. // first element being the child cert.
  181. class LLCertificateChain : virtual public LLCertificateVector
  182. {
  183. public:
  184. LLCertificateChain() {}
  185. virtual ~LLCertificateChain() {}
  186. };
  187. // class LLCertificateStore
  188. // represents a store of certificates, typically a store of root CA
  189. // certificates. The store can be persisted, and can be used to validate
  190. // a cert chain
  191. //
  192. class LLCertificateStore : virtual public LLCertificateVector
  193. {
  194. public:
  195. LLCertificateStore() {}
  196. virtual ~LLCertificateStore() {}
  197. // persist the store
  198. virtual void save()=0;
  199. // return the store id
  200. virtual std::string storeId() const=0;
  201. // validate a certificate chain given the params.
  202. // Will throw exceptions on error
  203. virtual void validate(int validation_policy,
  204. LLPointer<LLCertificateChain> cert_chain,
  205. const LLSD& validation_params) =0;
  206. };
  207. inline
  208. bool operator==(const LLCertificateVector::iterator& _lhs, const LLCertificateVector::iterator& _rhs)
  209. {
  210. return _lhs.equals(_rhs);
  211. }
  212. inline
  213. bool operator!=(const LLCertificateVector::iterator& _lhs, const LLCertificateVector::iterator& _rhs)
  214. {
  215. return !(_lhs == _rhs);
  216. }
  217. #define CRED_IDENTIFIER_TYPE_ACCOUNT "account"
  218. #define CRED_IDENTIFIER_TYPE_AGENT "agent"
  219. #define CRED_AUTHENTICATOR_TYPE_CLEAR "clear"
  220. #define CRED_AUTHENTICATOR_TYPE_HASH "hash"
  221. //
  222. // LLCredential - interface for credentials providing the following functionality:
  223. // * Persistence of credential information based on grid (for saving username/password)
  224. // * Serialization to an OGP identifier/authenticator pair
  225. //
  226. class LLCredential : public LLThreadSafeRefCount
  227. {
  228. public:
  229. LLCredential() {}
  230. LLCredential(const std::string& grid)
  231. {
  232. mGrid = grid;
  233. mIdentifier = LLSD::emptyMap();
  234. mAuthenticator = LLSD::emptyMap();
  235. }
  236. virtual ~LLCredential() {}
  237. virtual void setCredentialData(const LLSD& identifier, const LLSD& authenticator)
  238. {
  239. mIdentifier = identifier;
  240. mAuthenticator = authenticator;
  241. }
  242. virtual LLSD getIdentifier() { return mIdentifier; }
  243. virtual void identifierType(std::string& idType);
  244. virtual LLSD getAuthenticator() { return mAuthenticator; }
  245. virtual void authenticatorType(std::string& authType);
  246. virtual LLSD getLoginParams();
  247. virtual std::string getGrid() { return mGrid; }
  248. virtual void clearAuthenticator() { mAuthenticator = LLSD(); }
  249. virtual std::string userID() const { return std::string("unknown");}
  250. virtual std::string asString() const { return std::string("unknown");}
  251. operator std::string() const { return asString(); }
  252. protected:
  253. LLSD mIdentifier;
  254. LLSD mAuthenticator;
  255. std::string mGrid;
  256. };
  257. std::ostream& operator <<(std::ostream& s, const LLCredential& cred);
  258. // All error handling is via exceptions.
  259. class LLCertException
  260. {
  261. public:
  262. LLCertException(LLPointer<LLCertificate> cert, const char* msg)
  263. {
  264. mCert = cert;
  265. LL_WARNS("SECAPI") << "Certificate Error: " << (std::string)msg << LL_ENDL;
  266. mMsg = (std::string)msg;
  267. }
  268. LLPointer<LLCertificate> getCert() { return mCert; }
  269. std::string getMessage() { return mMsg; }
  270. protected:
  271. LLPointer<LLCertificate> mCert;
  272. std::string mMsg;
  273. };
  274. class LLInvalidCertificate : public LLCertException
  275. {
  276. public:
  277. LLInvalidCertificate(LLPointer<LLCertificate> cert) : LLCertException(cert, "CertInvalid")
  278. {
  279. }
  280. protected:
  281. };
  282. class LLCertValidationTrustException : public LLCertException
  283. {
  284. public:
  285. LLCertValidationTrustException(LLPointer<LLCertificate> cert) : LLCertException(cert, "CertUntrusted")
  286. {
  287. }
  288. protected:
  289. };
  290. class LLCertValidationHostnameException : public LLCertException
  291. {
  292. public:
  293. LLCertValidationHostnameException(std::string hostname,
  294. LLPointer<LLCertificate> cert) : LLCertException(cert, "CertInvalidHostname")
  295. {
  296. mHostname = hostname;
  297. }
  298. std::string getHostname() { return mHostname; }
  299. protected:
  300. std::string mHostname;
  301. };
  302. class LLCertValidationExpirationException : public LLCertException
  303. {
  304. public:
  305. LLCertValidationExpirationException(LLPointer<LLCertificate> cert,
  306. LLDate current_time) : LLCertException(cert, "CertExpired")
  307. {
  308. mTime = current_time;
  309. }
  310. LLDate GetTime() { return mTime; }
  311. protected:
  312. LLDate mTime;
  313. };
  314. class LLCertKeyUsageValidationException : public LLCertException
  315. {
  316. public:
  317. LLCertKeyUsageValidationException(LLPointer<LLCertificate> cert) : LLCertException(cert, "CertKeyUsage")
  318. {
  319. }
  320. protected:
  321. };
  322. class LLCertBasicConstraintsValidationException : public LLCertException
  323. {
  324. public:
  325. LLCertBasicConstraintsValidationException(LLPointer<LLCertificate> cert) : LLCertException(cert, "CertBasicConstraints")
  326. {
  327. }
  328. protected:
  329. };
  330. class LLCertValidationInvalidSignatureException : public LLCertException
  331. {
  332. public:
  333. LLCertValidationInvalidSignatureException(LLPointer<LLCertificate> cert) : LLCertException(cert, "CertInvalidSignature")
  334. {
  335. }
  336. protected:
  337. };
  338. // LLSecAPIHandler Class
  339. // Interface handler class for the various security storage handlers.
  340. class LLSecAPIHandler : public LLThreadSafeRefCount
  341. {
  342. public:
  343. LLSecAPIHandler() {}
  344. virtual ~LLSecAPIHandler() {}
  345. // initialize the SecAPIHandler
  346. virtual void init() {};
  347. // instantiate a certificate from a pem string
  348. virtual LLPointer<LLCertificate> getCertificate(const std::string& pem_cert)=0;
  349. // instiate a certificate from an openssl X509 structure
  350. virtual LLPointer<LLCertificate> getCertificate(X509* openssl_cert)=0;
  351. // instantiate a chain from an X509_STORE_CTX
  352. virtual LLPointer<LLCertificateChain> getCertificateChain(const X509_STORE_CTX* chain)=0;
  353. // instantiate a cert store given it's id. if a persisted version
  354. // exists, it'll be loaded. If not, one will be created (but not
  355. // persisted)
  356. virtual LLPointer<LLCertificateStore> getCertificateStore(const std::string& store_id)=0;
  357. // persist data in a protected store
  358. virtual void setProtectedData(const std::string& data_type,
  359. const std::string& data_id,
  360. const LLSD& data)=0;
  361. // retrieve protected data
  362. virtual LLSD getProtectedData(const std::string& data_type,
  363. const std::string& data_id)=0;
  364. // delete a protected data item from the store
  365. virtual void deleteProtectedData(const std::string& data_type,
  366. const std::string& data_id)=0;
  367. virtual LLPointer<LLCredential> createCredential(const std::string& grid,
  368. const LLSD& identifier,
  369. const LLSD& authenticator)=0;
  370. virtual LLPointer<LLCredential> loadCredential(const std::string& grid)=0;
  371. virtual void saveCredential(LLPointer<LLCredential> cred, bool save_authenticator)=0;
  372. virtual void deleteCredential(LLPointer<LLCredential> cred)=0;
  373. };
  374. void initializeSecHandler();
  375. // retrieve a security api depending on the api type
  376. LLPointer<LLSecAPIHandler> getSecHandler(const std::string& handler_type);
  377. void registerSecHandler(const std::string& handler_type,
  378. LLPointer<LLSecAPIHandler>& handler);
  379. extern LLPointer<LLSecAPIHandler> gSecAPIHandler;
  380. int secapiSSLCertVerifyCallback(X509_STORE_CTX *ctx, void *param);
  381. #endif // LL_SECAPI_H