You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SSecurityRSAAES.cxx 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. /* Copyright (C) 2022 Dinglan Peng
  2. *
  3. * This is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This software is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this software; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  16. * USA.
  17. */
  18. #ifdef HAVE_CONFIG_H
  19. #include <config.h>
  20. #endif
  21. #ifndef HAVE_NETTLE
  22. #error "This source should not be compiled without HAVE_NETTLE defined"
  23. #endif
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <assert.h>
  27. #include <vector>
  28. #include <nettle/bignum.h>
  29. #include <nettle/sha1.h>
  30. #include <nettle/sha2.h>
  31. #include <nettle/base64.h>
  32. #include <nettle/asn1.h>
  33. #include <rfb/SSecurityRSAAES.h>
  34. #include <rfb/SConnection.h>
  35. #include <rfb/LogWriter.h>
  36. #include <rfb/Exception.h>
  37. #include <rdr/AESInStream.h>
  38. #include <rdr/AESOutStream.h>
  39. #if !defined(WIN32) && !defined(__APPLE__)
  40. #include <rfb/UnixPasswordValidator.h>
  41. #endif
  42. #ifdef WIN32
  43. #include <rfb/WinPasswdValidator.h>
  44. #endif
  45. #include <rfb/SSecurityVncAuth.h>
  46. enum {
  47. SendPublicKey,
  48. ReadPublicKey,
  49. ReadRandom,
  50. ReadHash,
  51. ReadCredentials,
  52. };
  53. const int MinKeyLength = 1024;
  54. const int MaxKeyLength = 8192;
  55. const size_t MaxKeyFileSize = 32 * 1024;
  56. using namespace rfb;
  57. StringParameter SSecurityRSAAES::keyFile
  58. ("RSAKey", "Path to the RSA key for the RSA-AES security types in "
  59. "PEM format", "", ConfServer);
  60. BoolParameter SSecurityRSAAES::requireUsername
  61. ("RequireUsername", "Require username for the RSA-AES security types",
  62. false, ConfServer);
  63. SSecurityRSAAES::SSecurityRSAAES(SConnection* sc, uint32_t _secType,
  64. int _keySize, bool _isAllEncrypted)
  65. : SSecurity(sc), state(SendPublicKey),
  66. keySize(_keySize), isAllEncrypted(_isAllEncrypted), secType(_secType),
  67. serverKey(), clientKey(),
  68. serverKeyN(NULL), serverKeyE(NULL), clientKeyN(NULL), clientKeyE(NULL),
  69. accessRights(SConnection::AccessDefault),
  70. rais(NULL), raos(NULL), rawis(NULL), rawos(NULL)
  71. {
  72. assert(keySize == 128 || keySize == 256);
  73. }
  74. SSecurityRSAAES::~SSecurityRSAAES()
  75. {
  76. cleanup();
  77. }
  78. void SSecurityRSAAES::cleanup()
  79. {
  80. if (serverKeyN)
  81. delete[] serverKeyN;
  82. if (serverKeyE)
  83. delete[] serverKeyE;
  84. if (clientKeyN)
  85. delete[] clientKeyN;
  86. if (clientKeyE)
  87. delete[] clientKeyE;
  88. if (serverKey.size)
  89. rsa_private_key_clear(&serverKey);
  90. if (clientKey.size)
  91. rsa_public_key_clear(&clientKey);
  92. if (isAllEncrypted && rawis && rawos)
  93. sc->setStreams(rawis, rawos);
  94. if (rais)
  95. delete rais;
  96. if (raos)
  97. delete raos;
  98. }
  99. static inline ssize_t findSubstr(uint8_t* data, size_t size, const char *pattern)
  100. {
  101. size_t patternLength = strlen(pattern);
  102. for (size_t i = 0; i + patternLength < size; ++i) {
  103. for (size_t j = 0; j < patternLength; ++j)
  104. if (data[i + j] != pattern[j])
  105. goto next;
  106. return i;
  107. next:
  108. continue;
  109. }
  110. return -1;
  111. }
  112. static bool loadPEM(uint8_t* data, size_t size, const char *begin,
  113. const char *end, std::vector<uint8_t> *der)
  114. {
  115. ssize_t pos1 = findSubstr(data, size, begin);
  116. if (pos1 == -1)
  117. return false;
  118. pos1 += strlen(begin);
  119. ssize_t base64Size = findSubstr(data + pos1, size - pos1, end);
  120. if (base64Size == -1)
  121. return false;
  122. char *derBase64 = (char *)data + pos1;
  123. if (!base64Size)
  124. return false;
  125. der->resize(BASE64_DECODE_LENGTH(base64Size));
  126. struct base64_decode_ctx ctx;
  127. size_t derSize;
  128. base64_decode_init(&ctx);
  129. if (!base64_decode_update(&ctx, &derSize, der->data(),
  130. base64Size, derBase64))
  131. return false;
  132. if (!base64_decode_final(&ctx))
  133. return false;
  134. assert(derSize <= der->size());
  135. der->resize(derSize);
  136. return true;
  137. }
  138. void SSecurityRSAAES::loadPrivateKey()
  139. {
  140. FILE* file = fopen(keyFile, "rb");
  141. if (!file)
  142. throw ConnFailedException("failed to open key file");
  143. fseek(file, 0, SEEK_END);
  144. size_t size = ftell(file);
  145. if (size == 0 || size > MaxKeyFileSize) {
  146. fclose(file);
  147. throw ConnFailedException("size of key file is zero or too big");
  148. }
  149. fseek(file, 0, SEEK_SET);
  150. std::vector<uint8_t> data(size);
  151. if (fread(data.data(), 1, data.size(), file) != size) {
  152. fclose(file);
  153. throw ConnFailedException("failed to read key");
  154. }
  155. fclose(file);
  156. std::vector<uint8_t> der;
  157. if (loadPEM(data.data(), data.size(),
  158. "-----BEGIN RSA PRIVATE KEY-----\n",
  159. "-----END RSA PRIVATE KEY-----", &der)) {
  160. loadPKCS1Key(der.data(), der.size());
  161. return;
  162. }
  163. if (loadPEM(data.data(), data.size(),
  164. "-----BEGIN PRIVATE KEY-----\n",
  165. "-----END PRIVATE KEY-----", &der)) {
  166. loadPKCS8Key(der.data(), der.size());
  167. return;
  168. }
  169. throw ConnFailedException("failed to import key");
  170. }
  171. void SSecurityRSAAES::loadPKCS1Key(const uint8_t* data, size_t size)
  172. {
  173. struct rsa_public_key pub;
  174. rsa_private_key_init(&serverKey);
  175. rsa_public_key_init(&pub);
  176. if (!rsa_keypair_from_der(&pub, &serverKey, 0, size, data)) {
  177. rsa_private_key_clear(&serverKey);
  178. rsa_public_key_clear(&pub);
  179. throw ConnFailedException("failed to import key");
  180. }
  181. serverKeyLength = serverKey.size * 8;
  182. serverKeyN = new uint8_t[serverKey.size];
  183. serverKeyE = new uint8_t[serverKey.size];
  184. nettle_mpz_get_str_256(serverKey.size, serverKeyN, pub.n);
  185. nettle_mpz_get_str_256(serverKey.size, serverKeyE, pub.e);
  186. rsa_public_key_clear(&pub);
  187. }
  188. void SSecurityRSAAES::loadPKCS8Key(const uint8_t* data, size_t size)
  189. {
  190. struct asn1_der_iterator i, j;
  191. uint32_t version;
  192. const char* rsaIdentifier = "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01";
  193. const size_t rsaIdentifierLength = 9;
  194. enum asn1_iterator_result res = asn1_der_iterator_first(&i, size, data);
  195. if (res != ASN1_ITERATOR_CONSTRUCTED)
  196. goto failed;
  197. if (i.type != ASN1_SEQUENCE)
  198. goto failed;
  199. if (asn1_der_decode_constructed_last(&i) != ASN1_ITERATOR_PRIMITIVE)
  200. goto failed;
  201. if (!(i.type == ASN1_INTEGER &&
  202. asn1_der_get_uint32(&i, &version) &&
  203. version == 0))
  204. goto failed;
  205. if (!(asn1_der_iterator_next(&i) == ASN1_ITERATOR_CONSTRUCTED &&
  206. i.type == ASN1_SEQUENCE &&
  207. asn1_der_decode_constructed(&i, &j) == ASN1_ITERATOR_PRIMITIVE &&
  208. j.type == ASN1_IDENTIFIER &&
  209. j.length == rsaIdentifierLength &&
  210. memcmp(j.data, rsaIdentifier, rsaIdentifierLength) == 0))
  211. goto failed;
  212. if (!(asn1_der_iterator_next(&i) == ASN1_ITERATOR_PRIMITIVE &&
  213. i.type == ASN1_OCTETSTRING && i.length))
  214. goto failed;
  215. loadPKCS1Key(i.data, i.length);
  216. return;
  217. failed:
  218. throw ConnFailedException("failed to import key");
  219. }
  220. bool SSecurityRSAAES::processMsg()
  221. {
  222. switch (state) {
  223. case SendPublicKey:
  224. loadPrivateKey();
  225. writePublicKey();
  226. state = ReadPublicKey;
  227. /* fall through */
  228. case ReadPublicKey:
  229. if (!readPublicKey())
  230. return false;
  231. writeRandom();
  232. state = ReadRandom;
  233. /* fall through */
  234. case ReadRandom:
  235. if (!readRandom())
  236. return false;
  237. setCipher();
  238. writeHash();
  239. state = ReadHash;
  240. /* fall through */
  241. case ReadHash:
  242. if (!readHash())
  243. return false;
  244. clearSecrets();
  245. writeSubtype();
  246. state = ReadCredentials;
  247. /* fall through */
  248. case ReadCredentials:
  249. if (!readCredentials())
  250. return false;
  251. if (requireUsername)
  252. verifyUserPass();
  253. else
  254. verifyPass();
  255. return true;
  256. }
  257. assert(!"unreachable");
  258. return false;
  259. }
  260. void SSecurityRSAAES::writePublicKey()
  261. {
  262. rdr::OutStream* os = sc->getOutStream();
  263. os->writeU32(serverKeyLength);
  264. os->writeBytes(serverKeyN, serverKey.size);
  265. os->writeBytes(serverKeyE, serverKey.size);
  266. os->flush();
  267. }
  268. bool SSecurityRSAAES::readPublicKey()
  269. {
  270. rdr::InStream* is = sc->getInStream();
  271. if (!is->hasData(4))
  272. return false;
  273. is->setRestorePoint();
  274. clientKeyLength = is->readU32();
  275. if (clientKeyLength < MinKeyLength)
  276. throw ConnFailedException("client key is too short");
  277. if (clientKeyLength > MaxKeyLength)
  278. throw ConnFailedException("client key is too long");
  279. size_t size = (clientKeyLength + 7) / 8;
  280. if (!is->hasDataOrRestore(size * 2))
  281. return false;
  282. is->clearRestorePoint();
  283. clientKeyE = new uint8_t[size];
  284. clientKeyN = new uint8_t[size];
  285. is->readBytes(clientKeyN, size);
  286. is->readBytes(clientKeyE, size);
  287. rsa_public_key_init(&clientKey);
  288. nettle_mpz_set_str_256_u(clientKey.n, size, clientKeyN);
  289. nettle_mpz_set_str_256_u(clientKey.e, size, clientKeyE);
  290. if (!rsa_public_key_prepare(&clientKey))
  291. throw ConnFailedException("client key is invalid");
  292. return true;
  293. }
  294. static void random_func(void* ctx, size_t length, uint8_t* dst)
  295. {
  296. rdr::RandomStream* rs = (rdr::RandomStream*)ctx;
  297. if (!rs->hasData(length))
  298. throw ConnFailedException("failed to encrypt random");
  299. rs->readBytes(dst, length);
  300. }
  301. void SSecurityRSAAES::writeRandom()
  302. {
  303. rdr::OutStream* os = sc->getOutStream();
  304. if (!rs.hasData(keySize / 8))
  305. throw ConnFailedException("failed to generate random");
  306. rs.readBytes(serverRandom, keySize / 8);
  307. mpz_t x;
  308. mpz_init(x);
  309. int res;
  310. try {
  311. res = rsa_encrypt(&clientKey, &rs, random_func, keySize / 8,
  312. serverRandom, x);
  313. } catch (...) {
  314. mpz_clear(x);
  315. throw;
  316. }
  317. if (!res) {
  318. mpz_clear(x);
  319. throw ConnFailedException("failed to encrypt random");
  320. }
  321. uint8_t* buffer = new uint8_t[clientKey.size];
  322. nettle_mpz_get_str_256(clientKey.size, buffer, x);
  323. mpz_clear(x);
  324. os->writeU16(clientKey.size);
  325. os->writeBytes(buffer, clientKey.size);
  326. os->flush();
  327. delete[] buffer;
  328. }
  329. bool SSecurityRSAAES::readRandom()
  330. {
  331. rdr::InStream* is = sc->getInStream();
  332. if (!is->hasData(2))
  333. return false;
  334. is->setRestorePoint();
  335. size_t size = is->readU16();
  336. if (size != serverKey.size)
  337. throw ConnFailedException("server key length doesn't match");
  338. if (!is->hasDataOrRestore(size))
  339. return false;
  340. is->clearRestorePoint();
  341. uint8_t* buffer = new uint8_t[size];
  342. is->readBytes(buffer, size);
  343. size_t randomSize = keySize / 8;
  344. mpz_t x;
  345. nettle_mpz_init_set_str_256_u(x, size, buffer);
  346. delete[] buffer;
  347. if (!rsa_decrypt(&serverKey, &randomSize, clientRandom, x) ||
  348. randomSize != (size_t)keySize / 8) {
  349. mpz_clear(x);
  350. throw ConnFailedException("failed to decrypt client random");
  351. }
  352. mpz_clear(x);
  353. return true;
  354. }
  355. void SSecurityRSAAES::setCipher()
  356. {
  357. rawis = sc->getInStream();
  358. rawos = sc->getOutStream();
  359. uint8_t key[32];
  360. if (keySize == 128) {
  361. struct sha1_ctx ctx;
  362. sha1_init(&ctx);
  363. sha1_update(&ctx, 16, serverRandom);
  364. sha1_update(&ctx, 16, clientRandom);
  365. sha1_digest(&ctx, 16, key);
  366. rais = new rdr::AESInStream(rawis, key, 128);
  367. sha1_init(&ctx);
  368. sha1_update(&ctx, 16, clientRandom);
  369. sha1_update(&ctx, 16, serverRandom);
  370. sha1_digest(&ctx, 16, key);
  371. raos = new rdr::AESOutStream(rawos, key, 128);
  372. } else {
  373. struct sha256_ctx ctx;
  374. sha256_init(&ctx);
  375. sha256_update(&ctx, 32, serverRandom);
  376. sha256_update(&ctx, 32, clientRandom);
  377. sha256_digest(&ctx, 32, key);
  378. rais = new rdr::AESInStream(rawis, key, 256);
  379. sha256_init(&ctx);
  380. sha256_update(&ctx, 32, clientRandom);
  381. sha256_update(&ctx, 32, serverRandom);
  382. sha256_digest(&ctx, 32, key);
  383. raos = new rdr::AESOutStream(rawos, key, 256);
  384. }
  385. if (isAllEncrypted)
  386. sc->setStreams(rais, raos);
  387. }
  388. void SSecurityRSAAES::writeHash()
  389. {
  390. uint8_t hash[32];
  391. size_t len = serverKeyLength;
  392. uint8_t lenServerKey[4] = {
  393. (uint8_t)((len & 0xff000000) >> 24),
  394. (uint8_t)((len & 0xff0000) >> 16),
  395. (uint8_t)((len & 0xff00) >> 8),
  396. (uint8_t)(len & 0xff)
  397. };
  398. len = clientKeyLength;
  399. uint8_t lenClientKey[4] = {
  400. (uint8_t)((len & 0xff000000) >> 24),
  401. (uint8_t)((len & 0xff0000) >> 16),
  402. (uint8_t)((len & 0xff00) >> 8),
  403. (uint8_t)(len & 0xff)
  404. };
  405. int hashSize;
  406. if (keySize == 128) {
  407. hashSize = 20;
  408. struct sha1_ctx ctx;
  409. sha1_init(&ctx);
  410. sha1_update(&ctx, 4, lenServerKey);
  411. sha1_update(&ctx, serverKey.size, serverKeyN);
  412. sha1_update(&ctx, serverKey.size, serverKeyE);
  413. sha1_update(&ctx, 4, lenClientKey);
  414. sha1_update(&ctx, clientKey.size, clientKeyN);
  415. sha1_update(&ctx, clientKey.size, clientKeyE);
  416. sha1_digest(&ctx, hashSize, hash);
  417. } else {
  418. hashSize = 32;
  419. struct sha256_ctx ctx;
  420. sha256_init(&ctx);
  421. sha256_update(&ctx, 4, lenServerKey);
  422. sha256_update(&ctx, serverKey.size, serverKeyN);
  423. sha256_update(&ctx, serverKey.size, serverKeyE);
  424. sha256_update(&ctx, 4, lenClientKey);
  425. sha256_update(&ctx, clientKey.size, clientKeyN);
  426. sha256_update(&ctx, clientKey.size, clientKeyE);
  427. sha256_digest(&ctx, hashSize, hash);
  428. }
  429. raos->writeBytes(hash, hashSize);
  430. raos->flush();
  431. }
  432. bool SSecurityRSAAES::readHash()
  433. {
  434. uint8_t hash[32];
  435. uint8_t realHash[32];
  436. int hashSize = keySize == 128 ? 20 : 32;
  437. if (!rais->hasData(hashSize))
  438. return false;
  439. rais->readBytes(hash, hashSize);
  440. size_t len = serverKeyLength;
  441. uint8_t lenServerKey[4] = {
  442. (uint8_t)((len & 0xff000000) >> 24),
  443. (uint8_t)((len & 0xff0000) >> 16),
  444. (uint8_t)((len & 0xff00) >> 8),
  445. (uint8_t)(len & 0xff)
  446. };
  447. len = clientKeyLength;
  448. uint8_t lenClientKey[4] = {
  449. (uint8_t)((len & 0xff000000) >> 24),
  450. (uint8_t)((len & 0xff0000) >> 16),
  451. (uint8_t)((len & 0xff00) >> 8),
  452. (uint8_t)(len & 0xff)
  453. };
  454. if (keySize == 128) {
  455. struct sha1_ctx ctx;
  456. sha1_init(&ctx);
  457. sha1_update(&ctx, 4, lenClientKey);
  458. sha1_update(&ctx, clientKey.size, clientKeyN);
  459. sha1_update(&ctx, clientKey.size, clientKeyE);
  460. sha1_update(&ctx, 4, lenServerKey);
  461. sha1_update(&ctx, serverKey.size, serverKeyN);
  462. sha1_update(&ctx, serverKey.size, serverKeyE);
  463. sha1_digest(&ctx, hashSize, realHash);
  464. } else {
  465. struct sha256_ctx ctx;
  466. sha256_init(&ctx);
  467. sha256_update(&ctx, 4, lenClientKey);
  468. sha256_update(&ctx, clientKey.size, clientKeyN);
  469. sha256_update(&ctx, clientKey.size, clientKeyE);
  470. sha256_update(&ctx, 4, lenServerKey);
  471. sha256_update(&ctx, serverKey.size, serverKeyN);
  472. sha256_update(&ctx, serverKey.size, serverKeyE);
  473. sha256_digest(&ctx, hashSize, realHash);
  474. }
  475. if (memcmp(hash, realHash, hashSize) != 0)
  476. throw ConnFailedException("hash doesn't match");
  477. return true;
  478. }
  479. void SSecurityRSAAES::clearSecrets()
  480. {
  481. rsa_private_key_clear(&serverKey);
  482. rsa_public_key_clear(&clientKey);
  483. serverKey.size = 0;
  484. clientKey.size = 0;
  485. delete[] serverKeyN;
  486. delete[] serverKeyE;
  487. delete[] clientKeyN;
  488. delete[] clientKeyE;
  489. serverKeyN = NULL;
  490. serverKeyE = NULL;
  491. clientKeyN = NULL;
  492. clientKeyE = NULL;
  493. memset(serverRandom, 0, sizeof(serverRandom));
  494. memset(clientRandom, 0, sizeof(clientRandom));
  495. }
  496. void SSecurityRSAAES::writeSubtype()
  497. {
  498. if (requireUsername)
  499. raos->writeU8(secTypeRA2UserPass);
  500. else
  501. raos->writeU8(secTypeRA2Pass);
  502. raos->flush();
  503. }
  504. bool SSecurityRSAAES::readCredentials()
  505. {
  506. rais->setRestorePoint();
  507. if (!rais->hasData(1))
  508. return false;
  509. uint8_t lenUsername = rais->readU8();
  510. if (!rais->hasDataOrRestore(lenUsername + 1))
  511. return false;
  512. rais->readBytes(username, lenUsername);
  513. username[lenUsername] = 0;
  514. uint8_t lenPassword = rais->readU8();
  515. if (!rais->hasDataOrRestore(lenPassword))
  516. return false;
  517. rais->readBytes(password, lenPassword);
  518. password[lenPassword] = 0;
  519. rais->clearRestorePoint();
  520. return true;
  521. }
  522. void SSecurityRSAAES::verifyUserPass()
  523. {
  524. #ifndef __APPLE__
  525. #ifdef WIN32
  526. WinPasswdValidator* valid = new WinPasswdValidator();
  527. #elif !defined(__APPLE__)
  528. UnixPasswordValidator *valid = new UnixPasswordValidator();
  529. #endif
  530. if (!valid->validate(sc, username, password)) {
  531. delete valid;
  532. throw AuthFailureException("invalid password or username");
  533. }
  534. delete valid;
  535. #else
  536. throw AuthFailureException("No password validator configured");
  537. #endif
  538. }
  539. void SSecurityRSAAES::verifyPass()
  540. {
  541. VncAuthPasswdGetter* pg = &SSecurityVncAuth::vncAuthPasswd;
  542. std::string passwd, passwdReadOnly;
  543. pg->getVncAuthPasswd(&passwd, &passwdReadOnly);
  544. if (passwd.empty())
  545. throw AuthFailureException("No password configured for VNC Auth");
  546. if (password == passwd) {
  547. accessRights = SConnection::AccessDefault;
  548. return;
  549. }
  550. if (!passwdReadOnly.empty() && password == passwdReadOnly) {
  551. accessRights = SConnection::AccessView;
  552. return;
  553. }
  554. throw AuthFailureException();
  555. }
  556. const char* SSecurityRSAAES::getUserName() const
  557. {
  558. return username;
  559. }