PageRenderTime 47ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llsechandler_basic.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1662 lines | 1216 code | 191 blank | 255 comment | 231 complexity | 0c2d74058ecbeee207fbeeac54b092cd MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llsechandler_basic.cpp
  3. * @brief Security API for services such as certificate handling
  4. * secure local storage, etc.
  5. *
  6. * $LicenseInfo:firstyear=2003&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. #include "llviewerprecompiledheaders.h"
  28. #include "llsecapi.h"
  29. #include "llsechandler_basic.h"
  30. #include "llsdserialize.h"
  31. #include "llviewernetwork.h"
  32. #include "llxorcipher.h"
  33. #include "llfile.h"
  34. #include "lldir.h"
  35. #include "llviewercontrol.h"
  36. #include <vector>
  37. #include <ios>
  38. #include <openssl/ossl_typ.h>
  39. #include <openssl/x509.h>
  40. #include <openssl/x509v3.h>
  41. #include <openssl/pem.h>
  42. #include <openssl/asn1.h>
  43. #include <openssl/rand.h>
  44. #include <openssl/err.h>
  45. #include <iostream>
  46. #include <iomanip>
  47. #include <time.h>
  48. #include "llmachineid.h"
  49. // 128 bits of salt data...
  50. #define STORE_SALT_SIZE 16
  51. #define BUFFER_READ_SIZE 256
  52. std::string cert_string_from_asn1_string(ASN1_STRING* value);
  53. std::string cert_string_from_octet_string(ASN1_OCTET_STRING* value);
  54. LLSD _basic_constraints_ext(X509* cert);
  55. LLSD _key_usage_ext(X509* cert);
  56. LLSD _ext_key_usage_ext(X509* cert);
  57. LLSD _subject_key_identifier_ext(X509 *cert);
  58. LLSD _authority_key_identifier_ext(X509* cert);
  59. LLBasicCertificate::LLBasicCertificate(const std::string& pem_cert)
  60. {
  61. // BIO_new_mem_buf returns a read only bio, but takes a void* which isn't const
  62. // so we need to cast it.
  63. BIO * pem_bio = BIO_new_mem_buf((void*)pem_cert.c_str(), pem_cert.length());
  64. if(pem_bio == NULL)
  65. {
  66. LL_WARNS("SECAPI") << "Could not allocate an openssl memory BIO." << LL_ENDL;
  67. throw LLInvalidCertificate(this);
  68. }
  69. mCert = NULL;
  70. PEM_read_bio_X509(pem_bio, &mCert, 0, NULL);
  71. BIO_free(pem_bio);
  72. if (!mCert)
  73. {
  74. throw LLInvalidCertificate(this);
  75. }
  76. }
  77. LLBasicCertificate::LLBasicCertificate(X509* pCert)
  78. {
  79. if (!pCert || !pCert->cert_info)
  80. {
  81. throw LLInvalidCertificate(this);
  82. }
  83. mCert = X509_dup(pCert);
  84. }
  85. LLBasicCertificate::~LLBasicCertificate()
  86. {
  87. if(mCert)
  88. {
  89. X509_free(mCert);
  90. }
  91. }
  92. //
  93. // retrieve the pem using the openssl functionality
  94. std::string LLBasicCertificate::getPem() const
  95. {
  96. char * pem_bio_chars = NULL;
  97. // a BIO is the equivalent of a 'std::stream', and
  98. // can be a file, mem stream, whatever. Grab a memory based
  99. // BIO for the result
  100. BIO *pem_bio = BIO_new(BIO_s_mem());
  101. if (!pem_bio)
  102. {
  103. LL_WARNS("SECAPI") << "Could not allocate an openssl memory BIO." << LL_ENDL;
  104. return std::string();
  105. }
  106. PEM_write_bio_X509(pem_bio, mCert);
  107. int length = BIO_get_mem_data(pem_bio, &pem_bio_chars);
  108. std::string result = std::string(pem_bio_chars, length);
  109. BIO_free(pem_bio);
  110. return result;
  111. }
  112. // get the DER encoding for the cert
  113. // DER is a binary encoding format for certs...
  114. std::vector<U8> LLBasicCertificate::getBinary() const
  115. {
  116. U8 * der_bio_data = NULL;
  117. // get a memory bio
  118. BIO *der_bio = BIO_new(BIO_s_mem());
  119. if (!der_bio)
  120. {
  121. LL_WARNS("SECAPI") << "Could not allocate an openssl memory BIO." << LL_ENDL;
  122. return std::vector<U8>();
  123. }
  124. i2d_X509_bio(der_bio, mCert);
  125. int length = BIO_get_mem_data(der_bio, &der_bio_data);
  126. std::vector<U8> result(length);
  127. // vectors are guranteed to be a contiguous chunk of memory.
  128. memcpy(&result[0], der_bio_data, length);
  129. BIO_free(der_bio);
  130. return result;
  131. }
  132. void LLBasicCertificate::getLLSD(LLSD &llsd)
  133. {
  134. if (mLLSDInfo.isUndefined())
  135. {
  136. _initLLSD();
  137. }
  138. llsd = mLLSDInfo;
  139. }
  140. // Initialize the LLSD info for the certificate
  141. LLSD& LLBasicCertificate::_initLLSD()
  142. {
  143. // call the various helpers to build the LLSD
  144. mLLSDInfo[CERT_SUBJECT_NAME] = cert_name_from_X509_NAME(X509_get_subject_name(mCert));
  145. mLLSDInfo[CERT_ISSUER_NAME] = cert_name_from_X509_NAME(X509_get_issuer_name(mCert));
  146. mLLSDInfo[CERT_SUBJECT_NAME_STRING] = cert_string_name_from_X509_NAME(X509_get_subject_name(mCert));
  147. mLLSDInfo[CERT_ISSUER_NAME_STRING] = cert_string_name_from_X509_NAME(X509_get_issuer_name(mCert));
  148. ASN1_INTEGER *sn = X509_get_serialNumber(mCert);
  149. if (sn != NULL)
  150. {
  151. mLLSDInfo[CERT_SERIAL_NUMBER] = cert_string_from_asn1_integer(sn);
  152. }
  153. mLLSDInfo[CERT_VALID_TO] = cert_date_from_asn1_time(X509_get_notAfter(mCert));
  154. mLLSDInfo[CERT_VALID_FROM] = cert_date_from_asn1_time(X509_get_notBefore(mCert));
  155. mLLSDInfo[CERT_SHA1_DIGEST] = cert_get_digest("sha1", mCert);
  156. mLLSDInfo[CERT_MD5_DIGEST] = cert_get_digest("md5", mCert);
  157. // add the known extensions
  158. mLLSDInfo[CERT_BASIC_CONSTRAINTS] = _basic_constraints_ext(mCert);
  159. mLLSDInfo[CERT_KEY_USAGE] = _key_usage_ext(mCert);
  160. mLLSDInfo[CERT_EXTENDED_KEY_USAGE] = _ext_key_usage_ext(mCert);
  161. mLLSDInfo[CERT_SUBJECT_KEY_IDENTFIER] = _subject_key_identifier_ext(mCert);
  162. mLLSDInfo[CERT_AUTHORITY_KEY_IDENTIFIER] = _authority_key_identifier_ext(mCert);
  163. return mLLSDInfo;
  164. }
  165. // Retrieve the basic constraints info
  166. LLSD _basic_constraints_ext(X509* cert)
  167. {
  168. LLSD result;
  169. BASIC_CONSTRAINTS *bs = (BASIC_CONSTRAINTS *)X509_get_ext_d2i(cert, NID_basic_constraints, NULL, NULL);
  170. if(bs)
  171. {
  172. result = LLSD::emptyMap();
  173. // Determines whether the cert can be used as a CA
  174. result[CERT_BASIC_CONSTRAINTS_CA] = (bool)bs->ca;
  175. if(bs->pathlen)
  176. {
  177. // the pathlen determines how deep a certificate chain can be from
  178. // this CA
  179. if((bs->pathlen->type == V_ASN1_NEG_INTEGER)
  180. || !bs->ca)
  181. {
  182. result[CERT_BASIC_CONSTRAINTS_PATHLEN] = 0;
  183. }
  184. else
  185. {
  186. result[CERT_BASIC_CONSTRAINTS_PATHLEN] = (int)ASN1_INTEGER_get(bs->pathlen);
  187. }
  188. }
  189. }
  190. return result;
  191. }
  192. // retrieve the key usage, which specifies how the cert can be used.
  193. //
  194. LLSD _key_usage_ext(X509* cert)
  195. {
  196. LLSD result;
  197. ASN1_STRING *usage_str = (ASN1_STRING *)X509_get_ext_d2i(cert, NID_key_usage, NULL, NULL);
  198. if(usage_str)
  199. {
  200. result = LLSD::emptyArray();
  201. long usage = 0;
  202. if(usage_str->length > 0)
  203. {
  204. usage = usage_str->data[0];
  205. if(usage_str->length > 1)
  206. {
  207. usage |= usage_str->data[1] << 8;
  208. }
  209. }
  210. ASN1_STRING_free(usage_str);
  211. if(usage)
  212. {
  213. if(usage & KU_DIGITAL_SIGNATURE) result.append(LLSD((std::string)CERT_KU_DIGITAL_SIGNATURE));
  214. if(usage & KU_NON_REPUDIATION) result.append(LLSD((std::string)CERT_KU_NON_REPUDIATION));
  215. if(usage & KU_KEY_ENCIPHERMENT) result.append(LLSD((std::string)CERT_KU_KEY_ENCIPHERMENT));
  216. if(usage & KU_DATA_ENCIPHERMENT) result.append(LLSD((std::string)CERT_KU_DATA_ENCIPHERMENT));
  217. if(usage & KU_KEY_AGREEMENT) result.append(LLSD((std::string)CERT_KU_KEY_AGREEMENT));
  218. if(usage & KU_KEY_CERT_SIGN) result.append(LLSD((std::string)CERT_KU_CERT_SIGN));
  219. if(usage & KU_CRL_SIGN) result.append(LLSD((std::string)CERT_KU_CRL_SIGN));
  220. if(usage & KU_ENCIPHER_ONLY) result.append(LLSD((std::string)CERT_KU_ENCIPHER_ONLY));
  221. if(usage & KU_DECIPHER_ONLY) result.append(LLSD((std::string)CERT_KU_DECIPHER_ONLY));
  222. }
  223. }
  224. return result;
  225. }
  226. // retrieve the extended key usage for the cert
  227. LLSD _ext_key_usage_ext(X509* cert)
  228. {
  229. LLSD result;
  230. EXTENDED_KEY_USAGE *eku = (EXTENDED_KEY_USAGE *)X509_get_ext_d2i(cert, NID_ext_key_usage, NULL, NULL);
  231. if(eku)
  232. {
  233. result = LLSD::emptyArray();
  234. while(sk_ASN1_OBJECT_num(eku))
  235. {
  236. ASN1_OBJECT *usage = sk_ASN1_OBJECT_pop(eku);
  237. if(usage)
  238. {
  239. int nid = OBJ_obj2nid(usage);
  240. if (nid)
  241. {
  242. std::string sn = OBJ_nid2sn(nid);
  243. result.append(sn);
  244. }
  245. ASN1_OBJECT_free(usage);
  246. }
  247. }
  248. }
  249. return result;
  250. }
  251. // retrieve the subject key identifier of the cert
  252. LLSD _subject_key_identifier_ext(X509 *cert)
  253. {
  254. LLSD result;
  255. ASN1_OCTET_STRING *skeyid = (ASN1_OCTET_STRING *)X509_get_ext_d2i(cert, NID_subject_key_identifier, NULL, NULL);
  256. if(skeyid)
  257. {
  258. result = cert_string_from_octet_string(skeyid);
  259. }
  260. return result;
  261. }
  262. // retrieve the authority key identifier of the cert
  263. LLSD _authority_key_identifier_ext(X509* cert)
  264. {
  265. LLSD result;
  266. AUTHORITY_KEYID *akeyid = (AUTHORITY_KEYID *)X509_get_ext_d2i(cert, NID_authority_key_identifier, NULL, NULL);
  267. if(akeyid)
  268. {
  269. result = LLSD::emptyMap();
  270. if(akeyid->keyid)
  271. {
  272. result[CERT_AUTHORITY_KEY_IDENTIFIER_ID] = cert_string_from_octet_string(akeyid->keyid);
  273. }
  274. if(akeyid->serial)
  275. {
  276. result[CERT_AUTHORITY_KEY_IDENTIFIER_SERIAL] = cert_string_from_asn1_integer(akeyid->serial);
  277. }
  278. }
  279. // we ignore the issuer name in the authority key identifier, we check the issue name via
  280. // the the issuer name entry in the cert.
  281. return result;
  282. }
  283. // retrieve an openssl x509 object,
  284. // which must be freed by X509_free
  285. X509* LLBasicCertificate::getOpenSSLX509() const
  286. {
  287. return X509_dup(mCert);
  288. }
  289. // generate a single string containing the subject or issuer
  290. // name of the cert.
  291. std::string cert_string_name_from_X509_NAME(X509_NAME* name)
  292. {
  293. char * name_bio_chars = NULL;
  294. // get a memory bio
  295. BIO *name_bio = BIO_new(BIO_s_mem());
  296. // stream the name into the bio. The name will be in the 'short name' format
  297. X509_NAME_print_ex(name_bio, name, 0, XN_FLAG_RFC2253);
  298. int length = BIO_get_mem_data(name_bio, &name_bio_chars);
  299. std::string result = std::string(name_bio_chars, length);
  300. BIO_free(name_bio);
  301. return result;
  302. }
  303. // generate an LLSD from a certificate name (issuer or subject name).
  304. // the name will be strings indexed by the 'long form'
  305. LLSD cert_name_from_X509_NAME(X509_NAME* name)
  306. {
  307. LLSD result = LLSD::emptyMap();
  308. int name_entries = X509_NAME_entry_count(name);
  309. for (int entry_index=0; entry_index < name_entries; entry_index++)
  310. {
  311. char buffer[32];
  312. X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, entry_index);
  313. std::string name_value = std::string((const char*)M_ASN1_STRING_data(X509_NAME_ENTRY_get_data(entry)),
  314. M_ASN1_STRING_length(X509_NAME_ENTRY_get_data(entry)));
  315. ASN1_OBJECT* name_obj = X509_NAME_ENTRY_get_object(entry);
  316. OBJ_obj2txt(buffer, sizeof(buffer), name_obj, 0);
  317. std::string obj_buffer_str = std::string(buffer);
  318. result[obj_buffer_str] = name_value;
  319. }
  320. return result;
  321. }
  322. // Generate a string from an ASN1 integer. ASN1 Integers are
  323. // bignums, so they can be 'infinitely' long, therefore we
  324. // cannot simply use a conversion to U64 or something.
  325. // We retrieve as a readable string for UI
  326. std::string cert_string_from_asn1_integer(ASN1_INTEGER* value)
  327. {
  328. std::string result;
  329. BIGNUM *bn = ASN1_INTEGER_to_BN(value, NULL);
  330. if(bn)
  331. {
  332. char * ascii_bn = BN_bn2hex(bn);
  333. if(ascii_bn)
  334. {
  335. result = ascii_bn;
  336. OPENSSL_free(ascii_bn);
  337. }
  338. BN_free(bn);
  339. }
  340. return result;
  341. }
  342. // Generate a string from an OCTET string.
  343. // we retrieve as a
  344. std::string cert_string_from_octet_string(ASN1_OCTET_STRING* value)
  345. {
  346. std::stringstream result;
  347. result << std::hex << std::setprecision(2);
  348. for (int i=0; i < value->length; i++)
  349. {
  350. if (i != 0)
  351. {
  352. result << ":";
  353. }
  354. result << std::setfill('0') << std::setw(2) << (int)value->data[i];
  355. }
  356. return result.str();
  357. }
  358. // Generate a string from an ASN1 integer. ASN1 Integers are
  359. // bignums, so they can be 'infinitely' long, therefore we
  360. // cannot simply use a conversion to U64 or something.
  361. // We retrieve as a readable string for UI
  362. std::string cert_string_from_asn1_string(ASN1_STRING* value)
  363. {
  364. char * string_bio_chars = NULL;
  365. std::string result;
  366. // get a memory bio
  367. BIO *string_bio = BIO_new(BIO_s_mem());
  368. if(!string_bio)
  369. {
  370. // stream the name into the bio. The name will be in the 'short name' format
  371. ASN1_STRING_print_ex(string_bio, value, ASN1_STRFLGS_RFC2253);
  372. int length = BIO_get_mem_data(string_bio, &string_bio_chars);
  373. result = std::string(string_bio_chars, length);
  374. BIO_free(string_bio);
  375. }
  376. else
  377. {
  378. LL_WARNS("SECAPI") << "Could not allocate an openssl memory BIO." << LL_ENDL;
  379. }
  380. return result;
  381. }
  382. // retrieve a date structure from an ASN1 time, for
  383. // validity checking.
  384. LLDate cert_date_from_asn1_time(ASN1_TIME* asn1_time)
  385. {
  386. struct tm timestruct = {0};
  387. int i = asn1_time->length;
  388. if (i < 10)
  389. {
  390. return LLDate();
  391. }
  392. // convert the date from the ASN1 time (which is a string in ZULU time), to
  393. // a timeval.
  394. timestruct.tm_year = (asn1_time->data[0]-'0') * 10 + (asn1_time->data[1]-'0');
  395. /* Deal with Year 2000 */
  396. if (timestruct.tm_year < 70)
  397. timestruct.tm_year += 100;
  398. timestruct.tm_mon = (asn1_time->data[2]-'0') * 10 + (asn1_time->data[3]-'0') - 1;
  399. timestruct.tm_mday = (asn1_time->data[4]-'0') * 10 + (asn1_time->data[5]-'0');
  400. timestruct.tm_hour = (asn1_time->data[6]-'0') * 10 + (asn1_time->data[7]-'0');
  401. timestruct.tm_min = (asn1_time->data[8]-'0') * 10 + (asn1_time->data[9]-'0');
  402. timestruct.tm_sec = (asn1_time->data[10]-'0') * 10 + (asn1_time->data[11]-'0');
  403. #if LL_WINDOWS
  404. return LLDate((F64)_mkgmtime(&timestruct));
  405. #else // LL_WINDOWS
  406. return LLDate((F64)timegm(&timestruct));
  407. #endif // LL_WINDOWS
  408. }
  409. // Generate a string containing a digest. The digest time is 'ssh1' or
  410. // 'md5', and the resulting string is of the form "aa:12:5c:' and so on
  411. std::string cert_get_digest(const std::string& digest_type, X509 *cert)
  412. {
  413. unsigned char digest_data[BUFFER_READ_SIZE];
  414. unsigned int len = sizeof(digest_data);
  415. std::stringstream result;
  416. const EVP_MD* digest = NULL;
  417. // we could use EVP_get_digestbyname, but that requires initializer code which
  418. // would require us to complicate things by plumbing it into the system.
  419. if (digest_type == "md5")
  420. {
  421. digest = EVP_md5();
  422. }
  423. else if (digest_type == "sha1")
  424. {
  425. digest = EVP_sha1();
  426. }
  427. else
  428. {
  429. return std::string();
  430. }
  431. X509_digest(cert, digest, digest_data, &len);
  432. result << std::hex << std::setprecision(2);
  433. for (unsigned int i=0; i < len; i++)
  434. {
  435. if (i != 0)
  436. {
  437. result << ":";
  438. }
  439. result << std::setfill('0') << std::setw(2) << (int)digest_data[i];
  440. }
  441. return result.str();
  442. }
  443. // class LLBasicCertificateVector
  444. // This class represents a list of certificates, implemented by a vector of certificate pointers.
  445. // it contains implementations of the virtual functions for iterators, search, add, remove, etc.
  446. //
  447. // Find a certificate in the list.
  448. // It will find a cert that has minimally the params listed, with the values being the same
  449. LLBasicCertificateVector::iterator LLBasicCertificateVector::find(const LLSD& params)
  450. {
  451. BOOL found = FALSE;
  452. // loop through the entire vector comparing the values in the certs
  453. // against those passed in via the params.
  454. // params should be a map. Only the items specified in the map will be
  455. // checked, but they must match exactly, even if they're maps or arrays.
  456. for(iterator cert = begin();
  457. cert != end();
  458. cert++)
  459. {
  460. found= TRUE;
  461. LLSD cert_info;
  462. (*cert)->getLLSD(cert_info);
  463. for (LLSD::map_const_iterator param = params.beginMap();
  464. param != params.endMap();
  465. param++)
  466. {
  467. if (!cert_info.has((std::string)param->first) ||
  468. (!valueCompareLLSD(cert_info[(std::string)param->first], param->second)))
  469. {
  470. found = FALSE;
  471. break;
  472. }
  473. }
  474. if (found)
  475. {
  476. return (cert);
  477. }
  478. }
  479. return end();
  480. }
  481. // Insert a certificate into the store. If the certificate already
  482. // exists in the store, nothing is done.
  483. void LLBasicCertificateVector::insert(iterator _iter,
  484. LLPointer<LLCertificate> cert)
  485. {
  486. LLSD cert_info;
  487. cert->getLLSD(cert_info);
  488. if (cert_info.isMap() && cert_info.has(CERT_SHA1_DIGEST))
  489. {
  490. LLSD existing_cert_info = LLSD::emptyMap();
  491. existing_cert_info[CERT_MD5_DIGEST] = cert_info[CERT_MD5_DIGEST];
  492. if(find(existing_cert_info) == end())
  493. {
  494. BasicIteratorImpl *basic_iter = dynamic_cast<BasicIteratorImpl*>(_iter.mImpl.get());
  495. llassert(basic_iter);
  496. if (basic_iter)
  497. {
  498. mCerts.insert(basic_iter->mIter, cert);
  499. }
  500. }
  501. }
  502. }
  503. // remove a certificate from the store
  504. LLPointer<LLCertificate> LLBasicCertificateVector::erase(iterator _iter)
  505. {
  506. if (_iter != end())
  507. {
  508. BasicIteratorImpl *basic_iter = dynamic_cast<BasicIteratorImpl*>(_iter.mImpl.get());
  509. LLPointer<LLCertificate> result = (*_iter);
  510. mCerts.erase(basic_iter->mIter);
  511. return result;
  512. }
  513. return NULL;
  514. }
  515. //
  516. // LLBasicCertificateStore
  517. // This class represents a store of CA certificates. The basic implementation
  518. // uses a pem file such as the legacy CA.pem stored in the existing
  519. // SL implementation.
  520. LLBasicCertificateStore::LLBasicCertificateStore(const std::string& filename)
  521. {
  522. mFilename = filename;
  523. load_from_file(filename);
  524. }
  525. void LLBasicCertificateStore::load_from_file(const std::string& filename)
  526. {
  527. // scan the PEM file extracting each certificate
  528. if (!LLFile::isfile(filename))
  529. {
  530. return;
  531. }
  532. BIO* file_bio = BIO_new(BIO_s_file());
  533. if(file_bio)
  534. {
  535. if (BIO_read_filename(file_bio, filename.c_str()) > 0)
  536. {
  537. X509 *cert_x509 = NULL;
  538. while((PEM_read_bio_X509(file_bio, &cert_x509, 0, NULL)) &&
  539. (cert_x509 != NULL))
  540. {
  541. try
  542. {
  543. add(new LLBasicCertificate(cert_x509));
  544. }
  545. catch (...)
  546. {
  547. LL_WARNS("SECAPI") << "Failure creating certificate from the certificate store file." << LL_ENDL;
  548. }
  549. X509_free(cert_x509);
  550. cert_x509 = NULL;
  551. }
  552. BIO_free(file_bio);
  553. }
  554. }
  555. else
  556. {
  557. LL_WARNS("SECAPI") << "Could not allocate a file BIO" << LL_ENDL;
  558. }
  559. }
  560. LLBasicCertificateStore::~LLBasicCertificateStore()
  561. {
  562. }
  563. // persist the store
  564. void LLBasicCertificateStore::save()
  565. {
  566. llofstream file_store(mFilename, llofstream::binary);
  567. if(!file_store.fail())
  568. {
  569. for(iterator cert = begin();
  570. cert != end();
  571. cert++)
  572. {
  573. std::string pem = (*cert)->getPem();
  574. if(!pem.empty())
  575. {
  576. file_store << (*cert)->getPem() << std::endl;
  577. }
  578. }
  579. file_store.close();
  580. }
  581. else
  582. {
  583. LL_WARNS("SECAPI") << "Could not open certificate store " << mFilename << "for save" << LL_ENDL;
  584. }
  585. }
  586. // return the store id
  587. std::string LLBasicCertificateStore::storeId() const
  588. {
  589. // this is the basic handler which uses the CA.pem store,
  590. // so we ignore this.
  591. return std::string("");
  592. }
  593. //
  594. // LLBasicCertificateChain
  595. // This class represents a chain of certs, each cert being signed by the next cert
  596. // in the chain. Certs must be properly signed by the parent
  597. LLBasicCertificateChain::LLBasicCertificateChain(const X509_STORE_CTX* store)
  598. {
  599. // we're passed in a context, which contains a cert, and a blob of untrusted
  600. // certificates which compose the chain.
  601. if((store == NULL) || (store->cert == NULL))
  602. {
  603. LL_WARNS("SECAPI") << "An invalid store context was passed in when trying to create a certificate chain" << LL_ENDL;
  604. return;
  605. }
  606. // grab the child cert
  607. LLPointer<LLCertificate> current = new LLBasicCertificate(store->cert);
  608. add(current);
  609. if(store->untrusted != NULL)
  610. {
  611. // if there are other certs in the chain, we build up a vector
  612. // of untrusted certs so we can search for the parents of each
  613. // consecutive cert.
  614. LLBasicCertificateVector untrusted_certs;
  615. for(int i = 0; i < sk_X509_num(store->untrusted); i++)
  616. {
  617. LLPointer<LLCertificate> cert = new LLBasicCertificate(sk_X509_value(store->untrusted, i));
  618. untrusted_certs.add(cert);
  619. }
  620. while(untrusted_certs.size() > 0)
  621. {
  622. LLSD find_data = LLSD::emptyMap();
  623. LLSD cert_data;
  624. current->getLLSD(cert_data);
  625. // we simply build the chain via subject/issuer name as the
  626. // client should not have passed in multiple CA's with the same
  627. // subject name. If they did, it'll come out in the wash during
  628. // validation.
  629. find_data[CERT_SUBJECT_NAME_STRING] = cert_data[CERT_ISSUER_NAME_STRING];
  630. LLBasicCertificateVector::iterator issuer = untrusted_certs.find(find_data);
  631. if (issuer != untrusted_certs.end())
  632. {
  633. current = untrusted_certs.erase(issuer);
  634. add(current);
  635. }
  636. else
  637. {
  638. break;
  639. }
  640. }
  641. }
  642. }
  643. // subdomain wildcard specifiers can be divided into 3 parts
  644. // the part before the first *, the part after the first * but before
  645. // the second *, and the part after the second *.
  646. // It then iterates over the second for each place in the string
  647. // that it matches. ie if the subdomain was testfoofoobar, and
  648. // the wildcard was test*foo*bar, it would match test, then
  649. // recursively match foofoobar and foobar
  650. bool _cert_subdomain_wildcard_match(const std::string& subdomain,
  651. const std::string& wildcard)
  652. {
  653. // split wildcard into the portion before the *, and the portion after
  654. int wildcard_pos = wildcard.find_first_of('*');
  655. // check the case where there is no wildcard.
  656. if(wildcard_pos == wildcard.npos)
  657. {
  658. return (subdomain == wildcard);
  659. }
  660. // we need to match the first part of the subdomain string up to the wildcard
  661. // position
  662. if(subdomain.substr(0, wildcard_pos) != wildcard.substr(0, wildcard_pos))
  663. {
  664. // the first portions of the strings didn't match
  665. return FALSE;
  666. }
  667. // as the portion of the wildcard string before the * matched, we need to check the
  668. // portion afterwards. Grab that portion.
  669. std::string new_wildcard_string = wildcard.substr( wildcard_pos+1, wildcard.npos);
  670. if(new_wildcard_string.empty())
  671. {
  672. // we had nothing after the *, so it's an automatic match
  673. return TRUE;
  674. }
  675. // grab the portion of the remaining wildcard string before the next '*'. We need to find this
  676. // within the remaining subdomain string. and then recursively check.
  677. std::string new_wildcard_match_string = new_wildcard_string.substr(0, new_wildcard_string.find_first_of('*'));
  678. // grab the portion of the subdomain after the part that matched the initial wildcard portion
  679. std::string new_subdomain = subdomain.substr(wildcard_pos, subdomain.npos);
  680. // iterate through the current subdomain, finding instances of the match string.
  681. int sub_pos = new_subdomain.find_first_of(new_wildcard_match_string);
  682. while(sub_pos != std::string::npos)
  683. {
  684. new_subdomain = new_subdomain.substr(sub_pos, std::string::npos);
  685. if(_cert_subdomain_wildcard_match(new_subdomain, new_wildcard_string))
  686. {
  687. return TRUE;
  688. }
  689. sub_pos = new_subdomain.find_first_of(new_wildcard_match_string, 1);
  690. }
  691. // didn't find any instances of the match string that worked in the subdomain, so fail.
  692. return FALSE;
  693. }
  694. // RFC2459 does not address wildcards as part of it's name matching
  695. // specification, and there is no RFC specifying wildcard matching,
  696. // RFC2818 does a few statements about wildcard matching, but is very
  697. // general. Generally, wildcard matching is per implementation, although
  698. // it's pretty similar.
  699. // in our case, we use the '*' wildcard character only, within each
  700. // subdomain. The hostname and the CN specification should have the
  701. // same number of subdomains.
  702. // We then iterate that algorithm over each subdomain.
  703. bool _cert_hostname_wildcard_match(const std::string& hostname, const std::string& common_name)
  704. {
  705. std::string new_hostname = hostname;
  706. std::string new_cn = common_name;
  707. // find the last '.' in the hostname and the match name.
  708. int subdomain_pos = new_hostname.find_last_of('.');
  709. int subcn_pos = new_cn.find_last_of('.');
  710. // if the last char is a '.', strip it
  711. if(subdomain_pos == (new_hostname.length()-1))
  712. {
  713. new_hostname = new_hostname.substr(0, subdomain_pos);
  714. subdomain_pos = new_hostname.find_last_of('.');
  715. }
  716. if(subcn_pos == (new_cn.length()-1))
  717. {
  718. new_cn = new_cn.substr(0, subcn_pos);
  719. subcn_pos = new_cn.find_last_of('.');
  720. }
  721. // Check to see if there are any further '.' in the string.
  722. while((subcn_pos != std::string::npos) && (subdomain_pos != std::string::npos))
  723. {
  724. // snip out last subdomain in both the match string and the hostname
  725. // The last bit for 'my.current.host.com' would be 'com'
  726. std::string cn_part = new_cn.substr(subcn_pos+1, std::string::npos);
  727. std::string hostname_part = new_hostname.substr(subdomain_pos+1, std::string::npos);
  728. if(!_cert_subdomain_wildcard_match(new_hostname.substr(subdomain_pos+1, std::string::npos),
  729. cn_part))
  730. {
  731. return FALSE;
  732. }
  733. new_hostname = new_hostname.substr(0, subdomain_pos);
  734. new_cn = new_cn.substr(0, subcn_pos);
  735. subdomain_pos = new_hostname.find_last_of('.');
  736. subcn_pos = new_cn.find_last_of('.');
  737. }
  738. // check to see if the most significant portion of the common name is '*'. If so, we can
  739. // simply return success as child domains are also matched.
  740. if(new_cn == "*")
  741. {
  742. // if it's just a '*' we support all child domains as well, so '*.
  743. return TRUE;
  744. }
  745. return _cert_subdomain_wildcard_match(new_hostname, new_cn);
  746. }
  747. // validate that the LLSD array in llsd_set contains the llsd_value
  748. bool _LLSDArrayIncludesValue(const LLSD& llsd_set, LLSD llsd_value)
  749. {
  750. for(LLSD::array_const_iterator set_value = llsd_set.beginArray();
  751. set_value != llsd_set.endArray();
  752. set_value++)
  753. {
  754. if(valueCompareLLSD((*set_value), llsd_value))
  755. {
  756. return TRUE;
  757. }
  758. }
  759. return FALSE;
  760. }
  761. void _validateCert(int validation_policy,
  762. LLPointer<LLCertificate> cert,
  763. const LLSD& validation_params,
  764. int depth)
  765. {
  766. LLSD current_cert_info;
  767. cert->getLLSD(current_cert_info);
  768. // check basic properties exist in the cert
  769. if(!current_cert_info.has(CERT_SUBJECT_NAME) || !current_cert_info.has(CERT_SUBJECT_NAME_STRING))
  770. {
  771. throw LLCertException(cert, "Cert doesn't have a Subject Name");
  772. }
  773. if(!current_cert_info.has(CERT_ISSUER_NAME_STRING))
  774. {
  775. throw LLCertException(cert, "Cert doesn't have an Issuer Name");
  776. }
  777. // check basic properties exist in the cert
  778. if(!current_cert_info.has(CERT_VALID_FROM) || !current_cert_info.has(CERT_VALID_TO))
  779. {
  780. throw LLCertException(cert, "Cert doesn't have an expiration period");
  781. }
  782. if (!current_cert_info.has(CERT_SHA1_DIGEST))
  783. {
  784. throw LLCertException(cert, "No SHA1 digest");
  785. }
  786. if (validation_policy & VALIDATION_POLICY_TIME)
  787. {
  788. LLDate validation_date(time(NULL));
  789. if(validation_params.has(CERT_VALIDATION_DATE))
  790. {
  791. validation_date = validation_params[CERT_VALIDATION_DATE];
  792. }
  793. if((validation_date < current_cert_info[CERT_VALID_FROM].asDate()) ||
  794. (validation_date > current_cert_info[CERT_VALID_TO].asDate()))
  795. {
  796. throw LLCertValidationExpirationException(cert, validation_date);
  797. }
  798. }
  799. if (validation_policy & VALIDATION_POLICY_SSL_KU)
  800. {
  801. if (current_cert_info.has(CERT_KEY_USAGE) && current_cert_info[CERT_KEY_USAGE].isArray() &&
  802. (!(_LLSDArrayIncludesValue(current_cert_info[CERT_KEY_USAGE],
  803. LLSD((std::string)CERT_KU_DIGITAL_SIGNATURE))) ||
  804. !(_LLSDArrayIncludesValue(current_cert_info[CERT_KEY_USAGE],
  805. LLSD((std::string)CERT_KU_KEY_ENCIPHERMENT)))))
  806. {
  807. throw LLCertKeyUsageValidationException(cert);
  808. }
  809. // only validate EKU if the cert has it
  810. if(current_cert_info.has(CERT_EXTENDED_KEY_USAGE) && current_cert_info[CERT_EXTENDED_KEY_USAGE].isArray() &&
  811. (!_LLSDArrayIncludesValue(current_cert_info[CERT_EXTENDED_KEY_USAGE],
  812. LLSD((std::string)CERT_EKU_SERVER_AUTH))))
  813. {
  814. throw LLCertKeyUsageValidationException(cert);
  815. }
  816. }
  817. if (validation_policy & VALIDATION_POLICY_CA_KU)
  818. {
  819. if (current_cert_info.has(CERT_KEY_USAGE) && current_cert_info[CERT_KEY_USAGE].isArray() &&
  820. (!_LLSDArrayIncludesValue(current_cert_info[CERT_KEY_USAGE],
  821. (std::string)CERT_KU_CERT_SIGN)))
  822. {
  823. throw LLCertKeyUsageValidationException(cert);
  824. }
  825. }
  826. // validate basic constraints
  827. if ((validation_policy & VALIDATION_POLICY_CA_BASIC_CONSTRAINTS) &&
  828. current_cert_info.has(CERT_BASIC_CONSTRAINTS) &&
  829. current_cert_info[CERT_BASIC_CONSTRAINTS].isMap())
  830. {
  831. if(!current_cert_info[CERT_BASIC_CONSTRAINTS].has(CERT_BASIC_CONSTRAINTS_CA) ||
  832. !current_cert_info[CERT_BASIC_CONSTRAINTS][CERT_BASIC_CONSTRAINTS_CA])
  833. {
  834. throw LLCertBasicConstraintsValidationException(cert);
  835. }
  836. if (current_cert_info[CERT_BASIC_CONSTRAINTS].has(CERT_BASIC_CONSTRAINTS_PATHLEN) &&
  837. ((current_cert_info[CERT_BASIC_CONSTRAINTS][CERT_BASIC_CONSTRAINTS_PATHLEN].asInteger() != 0) &&
  838. (depth > current_cert_info[CERT_BASIC_CONSTRAINTS][CERT_BASIC_CONSTRAINTS_PATHLEN].asInteger())))
  839. {
  840. throw LLCertBasicConstraintsValidationException(cert);
  841. }
  842. }
  843. }
  844. bool _verify_signature(LLPointer<LLCertificate> parent,
  845. LLPointer<LLCertificate> child)
  846. {
  847. bool verify_result = FALSE;
  848. LLSD cert1, cert2;
  849. parent->getLLSD(cert1);
  850. child->getLLSD(cert2);
  851. X509 *signing_cert = parent->getOpenSSLX509();
  852. X509 *child_cert = child->getOpenSSLX509();
  853. if((signing_cert != NULL) && (child_cert != NULL))
  854. {
  855. EVP_PKEY *pkey = X509_get_pubkey(signing_cert);
  856. if(pkey)
  857. {
  858. int verify_code = X509_verify(child_cert, pkey);
  859. verify_result = ( verify_code > 0);
  860. EVP_PKEY_free(pkey);
  861. }
  862. else
  863. {
  864. LL_WARNS("SECAPI") << "Could not validate the cert chain signature, as the public key of the signing cert could not be retrieved" << LL_ENDL;
  865. }
  866. }
  867. else
  868. {
  869. LL_WARNS("SECAPI") << "Signature verification failed as there are no certs in the chain" << LL_ENDL;
  870. }
  871. if(child_cert)
  872. {
  873. X509_free(child_cert);
  874. }
  875. if(signing_cert)
  876. {
  877. X509_free(signing_cert);
  878. }
  879. return verify_result;
  880. }
  881. // validate the certificate chain against a store.
  882. // There are many aspects of cert validatioin policy involved in
  883. // trust validation. The policies in this validation algorithm include
  884. // * Hostname matching for SSL certs
  885. // * Expiration time matching
  886. // * Signature validation
  887. // * Chain trust (is the cert chain trusted against the store)
  888. // * Basic constraints
  889. // * key usage and extended key usage
  890. // TODO: We should add 'authority key identifier' for chaining.
  891. // This algorithm doesn't simply validate the chain by itself
  892. // and verify the last cert is in the certificate store, or points
  893. // to a cert in the store. It validates whether any cert in the chain
  894. // is trusted in the store, even if it's not the last one.
  895. void LLBasicCertificateStore::validate(int validation_policy,
  896. LLPointer<LLCertificateChain> cert_chain,
  897. const LLSD& validation_params)
  898. {
  899. // If --no-verify-ssl-cert was passed on the command line, stop right now.
  900. if (gSavedSettings.getBOOL("NoVerifySSLCert")) return;
  901. if(cert_chain->size() < 1)
  902. {
  903. throw LLCertException(NULL, "No certs in chain");
  904. }
  905. iterator current_cert = cert_chain->begin();
  906. LLSD current_cert_info;
  907. LLSD validation_date;
  908. if (validation_params.has(CERT_VALIDATION_DATE))
  909. {
  910. validation_date = validation_params[CERT_VALIDATION_DATE];
  911. }
  912. if (validation_policy & VALIDATION_POLICY_HOSTNAME)
  913. {
  914. (*current_cert)->getLLSD(current_cert_info);
  915. if(!validation_params.has(CERT_HOSTNAME))
  916. {
  917. throw LLCertException((*current_cert), "No hostname passed in for validation");
  918. }
  919. if(!current_cert_info.has(CERT_SUBJECT_NAME) || !current_cert_info[CERT_SUBJECT_NAME].has(CERT_NAME_CN))
  920. {
  921. throw LLInvalidCertificate((*current_cert));
  922. }
  923. LL_DEBUGS("SECAPI") << "Validating the hostname " << validation_params[CERT_HOSTNAME].asString() <<
  924. "against the cert CN " << current_cert_info[CERT_SUBJECT_NAME][CERT_NAME_CN].asString() << LL_ENDL;
  925. if(!_cert_hostname_wildcard_match(validation_params[CERT_HOSTNAME].asString(),
  926. current_cert_info[CERT_SUBJECT_NAME][CERT_NAME_CN].asString()))
  927. {
  928. throw LLCertValidationHostnameException(validation_params[CERT_HOSTNAME].asString(),
  929. (*current_cert));
  930. }
  931. }
  932. // check the cache of already validated certs
  933. X509* cert_x509 = (*current_cert)->getOpenSSLX509();
  934. if(!cert_x509)
  935. {
  936. throw LLInvalidCertificate((*current_cert));
  937. }
  938. std::string sha1_hash((const char *)cert_x509->sha1_hash, SHA_DIGEST_LENGTH);
  939. t_cert_cache::iterator cache_entry = mTrustedCertCache.find(sha1_hash);
  940. if(cache_entry != mTrustedCertCache.end())
  941. {
  942. LL_DEBUGS("SECAPI") << "Found cert in cache" << LL_ENDL;
  943. // this cert is in the cache, so validate the time.
  944. if (validation_policy & VALIDATION_POLICY_TIME)
  945. {
  946. LLDate validation_date(time(NULL));
  947. if(validation_params.has(CERT_VALIDATION_DATE))
  948. {
  949. validation_date = validation_params[CERT_VALIDATION_DATE];
  950. }
  951. if((validation_date < cache_entry->second.first) ||
  952. (validation_date > cache_entry->second.second))
  953. {
  954. throw LLCertValidationExpirationException((*current_cert), validation_date);
  955. }
  956. }
  957. // successfully found in cache
  958. return;
  959. }
  960. if(current_cert_info.isUndefined())
  961. {
  962. (*current_cert)->getLLSD(current_cert_info);
  963. }
  964. LLDate from_time = current_cert_info[CERT_VALID_FROM].asDate();
  965. LLDate to_time = current_cert_info[CERT_VALID_TO].asDate();
  966. int depth = 0;
  967. LLPointer<LLCertificate> previous_cert;
  968. // loop through the cert chain, validating the current cert against the next one.
  969. while(current_cert != cert_chain->end())
  970. {
  971. int local_validation_policy = validation_policy;
  972. if(current_cert == cert_chain->begin())
  973. {
  974. // for the child cert, we don't validate CA stuff
  975. local_validation_policy &= ~(VALIDATION_POLICY_CA_KU |
  976. VALIDATION_POLICY_CA_BASIC_CONSTRAINTS);
  977. }
  978. else
  979. {
  980. // for non-child certs, we don't validate SSL Key usage
  981. local_validation_policy &= ~VALIDATION_POLICY_SSL_KU;
  982. if(!_verify_signature((*current_cert),
  983. previous_cert))
  984. {
  985. throw LLCertValidationInvalidSignatureException(previous_cert);
  986. }
  987. }
  988. _validateCert(local_validation_policy,
  989. (*current_cert),
  990. validation_params,
  991. depth);
  992. // look for a CA in the CA store that may belong to this chain.
  993. LLSD cert_search_params = LLSD::emptyMap();
  994. // is the cert itself in the store?
  995. cert_search_params[CERT_SHA1_DIGEST] = current_cert_info[CERT_SHA1_DIGEST];
  996. LLCertificateStore::iterator found_store_cert = find(cert_search_params);
  997. if(found_store_cert != end())
  998. {
  999. mTrustedCertCache[sha1_hash] = std::pair<LLDate, LLDate>(from_time, to_time);
  1000. return;
  1001. }
  1002. // is the parent in the cert store?
  1003. cert_search_params = LLSD::emptyMap();
  1004. cert_search_params[CERT_SUBJECT_NAME_STRING] = current_cert_info[CERT_ISSUER_NAME_STRING];
  1005. if (current_cert_info.has(CERT_AUTHORITY_KEY_IDENTIFIER))
  1006. {
  1007. LLSD cert_aki = current_cert_info[CERT_AUTHORITY_KEY_IDENTIFIER];
  1008. if(cert_aki.has(CERT_AUTHORITY_KEY_IDENTIFIER_ID))
  1009. {
  1010. cert_search_params[CERT_SUBJECT_KEY_IDENTFIER] = cert_aki[CERT_AUTHORITY_KEY_IDENTIFIER_ID];
  1011. }
  1012. if(cert_aki.has(CERT_AUTHORITY_KEY_IDENTIFIER_SERIAL))
  1013. {
  1014. cert_search_params[CERT_SERIAL_NUMBER] = cert_aki[CERT_AUTHORITY_KEY_IDENTIFIER_SERIAL];
  1015. }
  1016. }
  1017. found_store_cert = find(cert_search_params);
  1018. if(found_store_cert != end())
  1019. {
  1020. // validate the store cert against the depth
  1021. _validateCert(validation_policy & VALIDATION_POLICY_CA_BASIC_CONSTRAINTS,
  1022. (*found_store_cert),
  1023. LLSD(),
  1024. depth);
  1025. // verify the signature of the CA
  1026. if(!_verify_signature((*found_store_cert),
  1027. (*current_cert)))
  1028. {
  1029. throw LLCertValidationInvalidSignatureException(*current_cert);
  1030. }
  1031. // successfully validated.
  1032. mTrustedCertCache[sha1_hash] = std::pair<LLDate, LLDate>(from_time, to_time);
  1033. return;
  1034. }
  1035. previous_cert = (*current_cert);
  1036. current_cert++;
  1037. depth++;
  1038. if(current_cert != cert_chain->end())
  1039. {
  1040. (*current_cert)->getLLSD(current_cert_info);
  1041. }
  1042. }
  1043. if (validation_policy & VALIDATION_POLICY_TRUSTED)
  1044. {
  1045. // we reached the end without finding a trusted cert.
  1046. throw LLCertValidationTrustException((*cert_chain)[cert_chain->size()-1]);
  1047. }
  1048. mTrustedCertCache[sha1_hash] = std::pair<LLDate, LLDate>(from_time, to_time);
  1049. }
  1050. // LLSecAPIBasicHandler Class
  1051. // Interface handler class for the various security storage handlers.
  1052. // We read the file on construction, and write it on destruction. This
  1053. // means multiple processes cannot modify the datastore.
  1054. LLSecAPIBasicHandler::LLSecAPIBasicHandler(const std::string& protected_data_file,
  1055. const std::string& legacy_password_path)
  1056. {
  1057. mProtectedDataFilename = protected_data_file;
  1058. mProtectedDataMap = LLSD::emptyMap();
  1059. mLegacyPasswordPath = legacy_password_path;
  1060. }
  1061. LLSecAPIBasicHandler::LLSecAPIBasicHandler()
  1062. {
  1063. }
  1064. void LLSecAPIBasicHandler::init()
  1065. {
  1066. mProtectedDataMap = LLSD::emptyMap();
  1067. if (mProtectedDataFilename.length() == 0)
  1068. {
  1069. mProtectedDataFilename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
  1070. "bin_conf.dat");
  1071. mLegacyPasswordPath = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "password.dat");
  1072. mProtectedDataFilename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
  1073. "bin_conf.dat");
  1074. std::string store_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
  1075. "CA.pem");
  1076. LL_DEBUGS("SECAPI") << "Loading certificate store from " << store_file << LL_ENDL;
  1077. mStore = new LLBasicCertificateStore(store_file);
  1078. // grab the application CA.pem file that contains the well-known certs shipped
  1079. // with the product
  1080. std::string ca_file_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem");
  1081. llinfos << "app path " << ca_file_path << llendl;
  1082. LLPointer<LLBasicCertificateStore> app_ca_store = new LLBasicCertificateStore(ca_file_path);
  1083. // push the applicate CA files into the store, therefore adding any new CA certs that
  1084. // updated
  1085. for(LLCertificateVector::iterator i = app_ca_store->begin();
  1086. i != app_ca_store->end();
  1087. i++)
  1088. {
  1089. mStore->add(*i);
  1090. }
  1091. }
  1092. _readProtectedData(); // initialize mProtectedDataMap
  1093. // may throw LLProtectedDataException if saved datamap is not decryptable
  1094. }
  1095. LLSecAPIBasicHandler::~LLSecAPIBasicHandler()
  1096. {
  1097. _writeProtectedData();
  1098. }
  1099. void LLSecAPIBasicHandler::_readProtectedData()
  1100. {
  1101. // attempt to load the file into our map
  1102. LLPointer<LLSDParser> parser = new LLSDXMLParser();
  1103. llifstream protected_data_stream(mProtectedDataFilename.c_str(),
  1104. llifstream::binary);
  1105. if (!protected_data_stream.fail()) {
  1106. int offset;
  1107. U8 salt[STORE_SALT_SIZE];
  1108. U8 buffer[BUFFER_READ_SIZE];
  1109. U8 decrypted_buffer[BUFFER_READ_SIZE];
  1110. int decrypted_length;
  1111. unsigned char unique_id[MAC_ADDRESS_BYTES];
  1112. LLMachineID::getUniqueID(unique_id, sizeof(unique_id));
  1113. LLXORCipher cipher(unique_id, sizeof(unique_id));
  1114. // read in the salt and key
  1115. protected_data_stream.read((char *)salt, STORE_SALT_SIZE);
  1116. offset = 0;
  1117. if (protected_data_stream.gcount() < STORE_SALT_SIZE)
  1118. {
  1119. throw LLProtectedDataException("Config file too short.");
  1120. }
  1121. cipher.decrypt(salt, STORE_SALT_SIZE);
  1122. // totally lame. As we're not using the OS level protected data, we need to
  1123. // at least obfuscate the data. We do this by using a salt stored at the head of the file
  1124. // to encrypt the data, therefore obfuscating it from someone using simple existing tools.
  1125. // We do include the MAC address as part of the obfuscation, which would require an
  1126. // attacker to get the MAC address as well as the protected store, which improves things
  1127. // somewhat. It would be better to use the password, but as this store
  1128. // will be used to store the SL password when the user decides to have SL remember it,
  1129. // so we can't use that. OS-dependent store implementations will use the OS password/storage
  1130. // mechanisms and are considered to be more secure.
  1131. // We've a strong intent to move to OS dependent protected data stores.
  1132. // read in the rest of the file.
  1133. EVP_CIPHER_CTX ctx;
  1134. EVP_CIPHER_CTX_init(&ctx);
  1135. EVP_DecryptInit(&ctx, EVP_rc4(), salt, NULL);
  1136. // allocate memory:
  1137. std::string decrypted_data;
  1138. while(protected_data_stream.good()) {
  1139. // read data as a block:
  1140. protected_data_stream.read((char *)buffer, BUFFER_READ_SIZE);
  1141. EVP_DecryptUpdate(&ctx, decrypted_buffer, &decrypted_length,
  1142. buffer, protected_data_stream.gcount());
  1143. decrypted_data.append((const char *)decrypted_buffer, protected_data_stream.gcount());
  1144. }
  1145. // RC4 is a stream cipher, so we don't bother to EVP_DecryptFinal, as there is
  1146. // no block padding.
  1147. EVP_CIPHER_CTX_cleanup(&ctx);
  1148. std::istringstream parse_stream(decrypted_data);
  1149. if (parser->parse(parse_stream, mProtectedDataMap,
  1150. LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE)
  1151. {
  1152. throw LLProtectedDataException("Config file cannot be decrypted.");
  1153. }
  1154. }
  1155. }
  1156. void LLSecAPIBasicHandler::_writeProtectedData()
  1157. {
  1158. std::ostringstream formatted_data_ostream;
  1159. U8 salt[STORE_SALT_SIZE];
  1160. U8 buffer[BUFFER_READ_SIZE];
  1161. U8 encrypted_buffer[BUFFER_READ_SIZE];
  1162. if(mProtectedDataMap.isUndefined())
  1163. {
  1164. LLFile::remove(mProtectedDataFilename);
  1165. return;
  1166. }
  1167. // create a string with the formatted data.
  1168. LLSDSerialize::toXML(mProtectedDataMap, formatted_data_ostream);
  1169. std::istringstream formatted_data_istream(formatted_data_ostream.str());
  1170. // generate the seed
  1171. RAND_bytes(salt, STORE_SALT_SIZE);
  1172. // write to a temp file so we don't clobber the initial file if there is
  1173. // an error.
  1174. std::string tmp_filename = mProtectedDataFilename + ".tmp";
  1175. llofstream protected_data_stream(tmp_filename.c_str(),
  1176. llofstream::binary);
  1177. try
  1178. {
  1179. EVP_CIPHER_CTX ctx;
  1180. EVP_CIPHER_CTX_init(&ctx);
  1181. EVP_EncryptInit(&ctx, EVP_rc4(), salt, NULL);
  1182. unsigned char unique_id[MAC_ADDRESS_BYTES];
  1183. LLMachineID::getUniqueID(unique_id, sizeof(unique_id));
  1184. LLXORCipher cipher(unique_id, sizeof(unique_id));
  1185. cipher.encrypt(salt, STORE_SALT_SIZE);
  1186. protected_data_stream.write((const char *)salt, STORE_SALT_SIZE);
  1187. while (formatted_data_istream.good())
  1188. {
  1189. formatted_data_istream.read((char *)buffer, BUFFER_READ_SIZE);
  1190. if(formatted_data_istream.gcount() == 0)
  1191. {
  1192. break;
  1193. }
  1194. int encrypted_length;
  1195. EVP_EncryptUpdate(&ctx, encrypted_buffer, &encrypted_length,
  1196. buffer, formatted_data_istream.gcount());
  1197. protected_data_stream.write((const char *)encrypted_buffer, encrypted_length);
  1198. }
  1199. // no EVP_EncrypteFinal, as this is a stream cipher
  1200. EVP_CIPHER_CTX_cleanup(&ctx);
  1201. protected_data_stream.close();
  1202. }
  1203. catch (...)
  1204. {
  1205. // it's good practice to clean up any secure information on error
  1206. // (even though this file isn't really secure. Perhaps in the future
  1207. // it may be, however.
  1208. LLFile::remove(tmp_filename);
  1209. throw LLProtectedDataException("Error writing Protected Data Store");
  1210. }
  1211. // move the temporary file to the specified file location.
  1212. if((((LLFile::isfile(mProtectedDataFilename) != 0) &&
  1213. (LLFile::remove(mProtectedDataFilename) != 0))) ||
  1214. (LLFile::rename(tmp_filename, mProtectedDataFilename)))
  1215. {
  1216. LLFile::remove(tmp_filename);
  1217. throw LLProtectedDataException("Could not overwrite protected data store");
  1218. }
  1219. }
  1220. // instantiate a certificate from a pem string
  1221. LLPointer<LLCertificate> LLSecAPIBasicHandler::getCertificate(const std::string& pem_cert)
  1222. {
  1223. LLPointer<LLCertificate> result = new LLBasicCertificate(pem_cert);
  1224. return result;
  1225. }
  1226. // instiate a certificate from an openssl X509 structure
  1227. LLPointer<LLCertificate> LLSecAPIBasicHandler::getCertificate(X509* openssl_cert)
  1228. {
  1229. LLPointer<LLCertificate> result = new LLBasicCertificate(openssl_cert);
  1230. return result;
  1231. }
  1232. // instantiate a chain from an X509_STORE_CTX
  1233. LLPointer<LLCertificateChain> LLSecAPIBasicHandler::getCertificateChain(const X509_STORE_CTX* chain)
  1234. {
  1235. LLPointer<LLCertificateChain> result = new LLBasicCertificateChain(chain);
  1236. return result;
  1237. }
  1238. // instantiate a cert store given it's id. if a persisted version
  1239. // exists, it'll be loaded. If not, one will be created (but not
  1240. // persisted)
  1241. LLPointer<LLCertificateStore> LLSecAPIBasicHandler::getCertificateStore(const std::string& store_id)
  1242. {
  1243. return mStore;
  1244. }
  1245. // retrieve protected data
  1246. LLSD LLSecAPIBasicHandler::getProtectedData(const std::string& data_type,
  1247. const std::string& data_id)
  1248. {
  1249. if (mProtectedDataMap.has(data_type) &&
  1250. mProtectedDataMap[data_type].isMap() &&
  1251. mProtectedDataMap[data_type].has(data_id))
  1252. {
  1253. return mProtectedDataMap[data_type][data_id];
  1254. }
  1255. return LLSD();
  1256. }
  1257. void LLSecAPIBasicHandler::deleteProtectedData(const std::string& data_type,
  1258. const std::string& data_id)
  1259. {
  1260. if (mProtectedDataMap.has(data_type) &&
  1261. mProtectedDataMap[data_type].isMap() &&
  1262. mProtectedDataMap[data_type].has(data_id))
  1263. {
  1264. mProtectedDataMap[data_type].erase(data_id);
  1265. }
  1266. }
  1267. //
  1268. // persist data in a protected store
  1269. //
  1270. void LLSecAPIBasicHandler::setProtectedData(const std::string& data_type,
  1271. const std::string& data_id,
  1272. const LLSD& data)
  1273. {
  1274. if (!mProtectedDataMap.has(data_type) || !mProtectedDataMap[data_type].isMap()) {
  1275. mProtectedDataMap[data_type] = LLSD::emptyMap();
  1276. }
  1277. mProtectedDataMap[data_type][data_id] = data;
  1278. }
  1279. //
  1280. // Create a credential object from an identifier and authenticator. credentials are
  1281. // per grid.
  1282. LLPointer<LLCredential> LLSecAPIBasicHandler::createCredential(const std::string& grid,
  1283. const LLSD& identifier,
  1284. const LLSD& authenticator)
  1285. {
  1286. LLPointer<LLSecAPIBasicCredential> result = new LLSecAPIBasicCredential(grid);
  1287. result->setCredentialData(identifier, authenticator);
  1288. return result;
  1289. }
  1290. // Load a credential from the credential store, given the grid
  1291. LLPointer<LLCredential> LLSecAPIBasicHandler::loadCredential(const std::string& grid)
  1292. {
  1293. LLSD credential = getProtectedData("credential", grid);
  1294. LLPointer<LLSecAPIBasicCredential> result = new LLSecAPIBasicCredential(grid);
  1295. if(credential.isMap() &&
  1296. credential.has("identifier"))
  1297. {
  1298. LLSD identifier = credential["identifier"];
  1299. LLSD authenticator;
  1300. if (credential.has("authenticator"))
  1301. {
  1302. authenticator = credential["authenticator"];
  1303. }
  1304. result->setCredentialData(identifier, authenticator);
  1305. }
  1306. else
  1307. {
  1308. // credential was not in protected storage, so pull the credential
  1309. // from the legacy store.
  1310. std::string first_name = gSavedSettings.getString("FirstName");
  1311. std::string last_name = gSavedSettings.getString("LastName");
  1312. if ((first_name != "") &&
  1313. (last_name != ""))
  1314. {
  1315. LLSD identifier = LLSD::emptyMap();
  1316. LLSD authenticator;
  1317. identifier["type"] = "agent";
  1318. identifier["first_name"] = first_name;
  1319. identifier["last_name"] = last_name;
  1320. std::string legacy_password = _legacyLoadPassword();
  1321. if (legacy_password.length() > 0)
  1322. {
  1323. authenticator = LLSD::emptyMap();
  1324. authenticator["type"] = "hash";
  1325. authenticator["algorithm"] = "md5";
  1326. authenticator["secret"] = legacy_password;
  1327. }
  1328. result->setCredentialData(identifier, authenticator);
  1329. }
  1330. }
  1331. return result;
  1332. }
  1333. // Save the credential to the credential store. Save the authenticator also if requested.
  1334. // That feature is used to implement the 'remember password' functionality.
  1335. void LLSecAPIBasicHandler::saveCredential(LLPointer<LLCredential> cred, bool save_authenticator)
  1336. {
  1337. LLSD credential = LLSD::emptyMap();
  1338. credential["identifier"] = cred->getIdentifier();
  1339. if (save_authenticator)
  1340. {
  1341. credential["authenticator"] = cred->getAuthenticator();
  1342. }
  1343. LL_DEBUGS("SECAPI") << "Saving Credential " << cred->getGrid() << ":" << cred->userID() << " " << save_authenticator << LL_ENDL;
  1344. setProtectedData("credential", cred->getGrid(), credential);
  1345. //*TODO: If we're saving Agni credentials, should we write the
  1346. // credentials to the legacy password.dat/etc?
  1347. _writeProtectedData();
  1348. }
  1349. // Remove a credential from the credential store.
  1350. void LLSecAPIBasicHandler::deleteCredential(LLPointer<LLCredential> cred)
  1351. {
  1352. LLSD undefVal;
  1353. deleteProtectedData("credential", cred->getGrid());
  1354. cred->setCredentialData(undefVal, undefVal);
  1355. _writeProtectedData();
  1356. }
  1357. // load the legacy hash for agni, and decrypt it given the
  1358. // mac address
  1359. std::string LLSecAPIBasicHandler::_legacyLoadPassword()
  1360. {
  1361. const S32 HASHED_LENGTH = 32;
  1362. std::vector<U8> buffer(HASHED_LENGTH);
  1363. llifstream password_file(mLegacyPasswordPath, llifstream::binary);
  1364. if(password_file.fail())
  1365. {
  1366. return std::string("");
  1367. }
  1368. password_file.read((char*)&buffer[0], buffer.size());
  1369. if(password_file.gcount() != buffer.size())
  1370. {
  1371. return std::string("");
  1372. }
  1373. // Decipher with MAC address
  1374. unsigned char unique_id[MAC_ADDRESS_BYTES];
  1375. LLMachineID::getUniqueID(unique_id, sizeof(unique_id));
  1376. LLXORCipher cipher(unique_id, sizeof(unique_id));
  1377. cipher.decrypt(&buffer[0], buffer.size());
  1378. return std::string((const char*)&buffer[0], buffer.size());
  1379. }
  1380. // return an identifier for the user
  1381. std::string LLSecAPIBasicCredential::userID() const
  1382. {
  1383. if (!mIdentifier.isMap())
  1384. {
  1385. return mGrid + "(null)";
  1386. }
  1387. else if ((std::string)mIdentifier["type"] == "agent")
  1388. {
  1389. return (std::string)mIdentifier["first_name"] + "_" + (std::string)mIdentifier["last_name"];
  1390. }
  1391. else if ((std::string)mIdentifier["type"] == "account")
  1392. {
  1393. return (std::string)mIdentifier["account_name"];
  1394. }
  1395. return "unknown";
  1396. }
  1397. // return a printable user identifier
  1398. std::string LLSecAPIBasicCredential::asString() const
  1399. {
  1400. if (!mIdentifier.isMap())
  1401. {
  1402. return mGrid + ":(null)";
  1403. }
  1404. else if ((std::string)mIdentifier["type"] == "agent")
  1405. {
  1406. return mGrid + ":" + (std::string)mIdentifier["first_name"] + " " + (std::string)mIdentifier["last_name"];
  1407. }
  1408. else if ((std::string)mIdentifier["type"] == "account")
  1409. {
  1410. return mGrid + ":" + (std::string)mIdentifier["account_name"];
  1411. }
  1412. return mGrid + ":(unknown type)";
  1413. }
  1414. bool valueCompareLLSD(const LLSD& lhs, const LLSD& rhs)
  1415. {
  1416. if (lhs.type() != rhs.type())
  1417. {
  1418. return FALSE;
  1419. }
  1420. if (lhs.isMap())
  1421. {
  1422. // iterate through the map, verifying the right hand side has all of the
  1423. // values that the left hand side has.
  1424. for (LLSD::map_const_iterator litt = lhs.beginMap();
  1425. litt != lhs.endMap();
  1426. litt++)
  1427. {
  1428. if (!rhs.has(litt->first))
  1429. {
  1430. return FALSE;
  1431. }
  1432. }
  1433. // Now validate that the left hand side has everything the
  1434. // right hand side has, and that the values are equal.
  1435. for (LLSD::map_const_iterator ritt = rhs.beginMap();
  1436. ritt != rhs.endMap();
  1437. ritt++)
  1438. {
  1439. if (!lhs.has(ritt->first))
  1440. {
  1441. return FALSE;
  1442. }
  1443. if (!valueCompareLLSD(lhs[ritt->first], ritt->second))
  1444. {
  1445. return FALSE;
  1446. }
  1447. }
  1448. return TRUE;
  1449. }
  1450. else if (lhs.isArray())
  1451. {
  1452. LLSD::array_const_iterator ritt = rhs.beginArray();
  1453. // iterate through the array, comparing
  1454. for (LLSD::array_const_iterator litt = lhs.beginArray();
  1455. litt != lhs.endArray();
  1456. litt++)
  1457. {
  1458. if (!valueCompareLLSD(*ritt, *litt))
  1459. {
  1460. return FALSE;
  1461. }
  1462. ritt++;
  1463. }
  1464. return (ritt == rhs.endArray());
  1465. }
  1466. else
  1467. {
  1468. // simple type, compare as string
  1469. return (lhs.asString() == rhs.asString());
  1470. }
  1471. }