ChipMaster's trial hacks on C++CMS starting with v1.2.1. Not sure I'll follow on with the v2 since it looks to be breaking and mostly frivolous.
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.
 
 
 
 
 
 

216 lines
4.9 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 2008-2010 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
  4. //
  5. // This program is free software: you can redistribute it and/or modify
  6. // it under the terms of the GNU Lesser General Public License as published by
  7. // the Free Software Foundation, either version 3 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU Lesser General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU Lesser General Public License
  16. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. //
  18. ///////////////////////////////////////////////////////////////////////////////
  19. #define CPPCMS_SOURCE
  20. #include <assert.h>
  21. #include <stdio.h>
  22. #include <string>
  23. #include <vector>
  24. #include <algorithm>
  25. #include "cppcms_error.h"
  26. #include "aes_encryptor.h"
  27. #include "base64.h"
  28. #ifdef CPPCMS_WIN_NATIVE
  29. #define CPPCMS_GCRYPT_USE_BOOSTER_THREADS
  30. #endif
  31. #ifdef CPPCMS_GCRYPT_USE_BOOSTER_THREADS
  32. #include <booster/thread.h>
  33. static int nt_mutex_init(void **p)
  34. {
  35. try {
  36. *p=new booster::mutex();
  37. return 0;
  38. }
  39. catch(...)
  40. {
  41. return 1;
  42. }
  43. }
  44. static int nt_mutex_destroy(void **p)
  45. {
  46. booster::mutex **m=reinterpret_cast<booster::mutex **>(p);
  47. delete *m;
  48. *m=0;
  49. return 0;
  50. }
  51. static int nt_mutex_lock(void **p)
  52. {
  53. booster::mutex *m=reinterpret_cast<booster::mutex *>(*p);
  54. try {
  55. m->lock();
  56. return 0;
  57. }
  58. catch(...)
  59. {
  60. return 1;
  61. }
  62. }
  63. static int nt_mutex_unlock(void **p)
  64. {
  65. booster::mutex *m=reinterpret_cast<booster::mutex *>(*p);
  66. try {
  67. m->unlock();
  68. return 0;
  69. }
  70. catch(...)
  71. {
  72. return 1;
  73. }
  74. }
  75. static struct gcry_thread_cbs threads_nt = {
  76. GCRY_THREAD_OPTION_USER,
  77. 0,
  78. nt_mutex_init,
  79. nt_mutex_destroy,
  80. nt_mutex_lock,
  81. nt_mutex_unlock,
  82. 0,0,0,0,
  83. 0,0,0,0
  84. };
  85. static void set_gcrypt_cbs()
  86. {
  87. gcry_control (GCRYCTL_SET_THREAD_CBS, &threads_nt);
  88. }
  89. #else
  90. #include <pthread.h>
  91. #include <errno.h>
  92. GCRY_THREAD_OPTION_PTHREAD_IMPL;
  93. static void set_gcrypt_cbs()
  94. {
  95. gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
  96. }
  97. #endif
  98. using namespace std;
  99. namespace cppcms {
  100. namespace sessions {
  101. namespace impl {
  102. namespace {
  103. class load {
  104. public:
  105. load() {
  106. set_gcrypt_cbs();
  107. gcry_check_version(NULL);
  108. }
  109. } loader;
  110. } // anon namespace
  111. aes_cipher::aes_cipher(string k) :
  112. base_encryptor(k)
  113. {
  114. bool in=false,out=false;
  115. in=gcry_cipher_open(&hd_in,GCRY_CIPHER_AES,GCRY_CIPHER_MODE_CBC,0) == 0;
  116. out=gcry_cipher_open(&hd_out,GCRY_CIPHER_AES,GCRY_CIPHER_MODE_CBC,0) == 0;
  117. if(!in || !out){
  118. goto error_exit;
  119. }
  120. if( gcry_cipher_setkey(hd_in,&key.front(),16) != 0) {
  121. goto error_exit;
  122. }
  123. if( gcry_cipher_setkey(hd_out,&key.front(),16) != 0)
  124. goto error_exit;
  125. char iv[16];
  126. gcry_create_nonce(iv,sizeof(iv));
  127. gcry_cipher_setiv(hd_out,iv,sizeof(iv));
  128. return;
  129. error_exit:
  130. if(in) gcry_cipher_close(hd_in);
  131. if(out) gcry_cipher_close(hd_out);
  132. throw cppcms_error("AES cipher initialization failed");
  133. }
  134. aes_cipher::~aes_cipher()
  135. {
  136. gcry_cipher_close(hd_in);
  137. gcry_cipher_close(hd_out);
  138. }
  139. string aes_cipher::encrypt(string const &plain,time_t timeout)
  140. {
  141. size_t block_size=(plain.size() + 15) / 16 * 16;
  142. vector<unsigned char> data(sizeof(aes_hdr)+sizeof(info)+block_size,0);
  143. copy(plain.begin(),plain.end(),data.begin() + sizeof(aes_hdr)+sizeof(info));
  144. aes_hdr &aes_header=*(aes_hdr*)(&data.front());
  145. info &header=*(info *)(&data.front()+sizeof(aes_hdr));
  146. header.timeout=timeout;
  147. header.size=plain.size();
  148. memset(&aes_header,0,16);
  149. gcry_md_hash_buffer(GCRY_MD_MD5,&aes_header.md5,&header,block_size+sizeof(info));
  150. gcry_cipher_encrypt(hd_out,&data.front(),data.size(),NULL,0);
  151. return base64_enc(data);
  152. }
  153. bool aes_cipher::decrypt(string const &cipher,string &plain,time_t *timeout)
  154. {
  155. vector<unsigned char> data;
  156. base64_dec(cipher,data);
  157. size_t norm_size=b64url::decoded_size(cipher.size());
  158. if(norm_size<sizeof(info)+sizeof(aes_hdr) || norm_size % 16 !=0)
  159. return false;
  160. gcry_cipher_decrypt(hd_in,&data.front(),data.size(),NULL,0);
  161. gcry_cipher_reset(hd_in);
  162. vector<char> md5(16,0);
  163. gcry_md_hash_buffer(GCRY_MD_MD5,&md5.front(),&data.front()+sizeof(aes_hdr),data.size()-sizeof(aes_hdr));
  164. aes_hdr &aes_header = *(aes_hdr*)&data.front();
  165. if(!std::equal(md5.begin(),md5.end(),aes_header.md5)) {
  166. return false;
  167. }
  168. info &header=*(info *)(&data.front()+sizeof(aes_hdr));
  169. if(time(NULL)>header.timeout)
  170. return false;
  171. if(timeout) *timeout=header.timeout;
  172. vector<unsigned char>::iterator data_start=data.begin()+sizeof(aes_hdr)+sizeof(info),
  173. data_end=data_start+header.size;
  174. plain.assign(data_start,data_end);
  175. return true;
  176. }
  177. } // impl
  178. } // sessions
  179. } // cppcms