aesm_http_msg.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /*
  2. * Copyright (C) 2011-2016 Intel Corporation. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in
  12. * the documentation and/or other materials provided with the
  13. * distribution.
  14. * * Neither the name of Intel Corporation nor the names of its
  15. * contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. *
  30. */
  31. #include <string>
  32. #include "aesm_encode.h"
  33. #include "oal.h"
  34. #include "se_wrapper.h"
  35. #include "prof_fun.h"
  36. #include "aesm_proxy_type.h"
  37. #include "endpoint_select_info.h"
  38. #include "util.h"
  39. #include <curl/curl.h>
  40. #ifndef INTERNET_DEFAULT_HTTP_PORT
  41. #define INTERNET_DEFAULT_HTTP_PORT 80
  42. #endif
  43. #define AESM_DEFAULT_CONN_TIME_OUT 1000
  44. #define AESM_DEFAULT_TIME_OUT 10000
  45. bool is_curl_initialized_succ(void);//network is available only when curl library is successfully initialized
  46. typedef struct _network_malloc_info_t{
  47. char *base;
  48. uint32_t size;
  49. }network_malloc_info_t;
  50. static size_t write_callback(void *ptr, size_t size, size_t nmemb, void *stream)
  51. {
  52. network_malloc_info_t* s=reinterpret_cast<network_malloc_info_t *>(stream);
  53. uint32_t start=0;
  54. if(s->base==NULL){
  55. if(UINT32_MAX/size<nmemb){
  56. return 0;//buffer overflow
  57. }
  58. s->base = reinterpret_cast<char *>(malloc(size*nmemb));
  59. s->size = static_cast<uint32_t>(size*nmemb);
  60. if(s->base==NULL){
  61. AESM_DBG_ERROR("malloc error in write callback fun");
  62. return 0;
  63. }
  64. }else{
  65. uint32_t newsize = s->size+static_cast<uint32_t>(size*nmemb);
  66. if((UINT32_MAX-s->size)/size<nmemb){
  67. return 0;//buffer overflow
  68. }
  69. char *p=reinterpret_cast<char *>(malloc(newsize));
  70. if(p == NULL){
  71. free(s->base);
  72. s->base = NULL;
  73. AESM_DBG_ERROR("malloc error in write callback fun");
  74. return 0;
  75. }
  76. memcpy(p, s->base, s->size);
  77. free(s->base);
  78. start = s->size;
  79. s->base = p;
  80. s->size = newsize;
  81. }
  82. memcpy(s->base +start, ptr, size*nmemb);
  83. return nmemb;
  84. }
  85. static ae_error_t http_network_init(CURL **curl, const char *url, bool is_ocsp)
  86. {
  87. CURLcode cc = CURLE_OK;
  88. UNUSED(is_ocsp);
  89. AESM_DBG_TRACE("http init for url %s",url);
  90. if(!is_curl_initialized_succ()){
  91. AESM_DBG_ERROR("libcurl not initialized");
  92. return AE_FAILURE;//fatal error that libcurl could not be initialized
  93. }
  94. if(NULL == url){
  95. AESM_DBG_ERROR("NULL url");
  96. return AE_FAILURE;
  97. }
  98. std::string url_path = url;
  99. uint32_t proxy_type;
  100. char proxy_url[MAX_PATH];
  101. EndpointSelectionInfo::instance().get_proxy(proxy_type, proxy_url);
  102. *curl = curl_easy_init();
  103. if(!*curl){
  104. AESM_DBG_ERROR("fail to init curl handle");
  105. return AE_FAILURE;
  106. }
  107. if((cc=curl_easy_setopt(*curl, CURLOPT_URL, url_path.c_str()))!=CURLE_OK){
  108. AESM_DBG_ERROR("fail error code %d in set url %s",(int)cc, url_path.c_str());
  109. curl_easy_cleanup(*curl);
  110. return AE_FAILURE;
  111. }
  112. (void)curl_easy_setopt(*curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
  113. //setting proxy now
  114. if(proxy_type == AESM_PROXY_TYPE_DIRECT_ACCESS){
  115. AESM_DBG_TRACE("use no proxy");
  116. (void)curl_easy_setopt(*curl, CURLOPT_NOPROXY , "*");
  117. }else if(proxy_type == AESM_PROXY_TYPE_MANUAL_PROXY){
  118. AESM_DBG_TRACE("use manual proxy %s",proxy_url);
  119. (void)curl_easy_setopt(*curl, CURLOPT_PROXY, proxy_url);
  120. }
  121. return AE_SUCCESS;
  122. }
  123. static ae_error_t http_network_send_data(CURL *curl, const char *req_msg, uint32_t msg_size, char **resp_msg, uint32_t& resp_size, http_methods_t method, bool is_ocsp)
  124. {
  125. AESM_DBG_TRACE("send data method=%d",method);
  126. struct curl_slist *headers=NULL;
  127. struct curl_slist *tmp=NULL;
  128. ae_error_t ae_ret = AE_SUCCESS;
  129. CURLcode cc=CURLE_OK;
  130. int num_bytes = 0;
  131. if(is_ocsp){
  132. tmp = curl_slist_append(headers, "Accept: application/ocsp-response");
  133. if(tmp==NULL){
  134. AESM_DBG_ERROR("fail in add accept ocsp-response header");
  135. ae_ret = AE_FAILURE;
  136. goto fini;
  137. }
  138. headers = tmp;
  139. tmp = curl_slist_append(headers, "Content-Type: application/ocsp-request");
  140. if(tmp == NULL){
  141. AESM_DBG_ERROR("fail in add content type ocsp-request");
  142. ae_ret = AE_FAILURE;
  143. goto fini;
  144. }
  145. headers=tmp;
  146. AESM_DBG_TRACE("ocsp request");
  147. }
  148. char buf[50];
  149. num_bytes = snprintf(buf,sizeof(buf), "Content-Length: %u", (unsigned int)msg_size);
  150. if(num_bytes<0 || num_bytes>=sizeof(buf)){
  151. AESM_DBG_ERROR("fail to prepare string Content-Length");
  152. ae_ret = AE_FAILURE;
  153. goto fini;
  154. }
  155. tmp = curl_slist_append(headers, buf);
  156. if(tmp == NULL){
  157. AESM_DBG_ERROR("fail to add content-length header");
  158. ae_ret = AE_FAILURE;
  159. goto fini;
  160. }
  161. headers=tmp;
  162. if((cc=curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers))!=CURLE_OK){
  163. AESM_DBG_ERROR("fail to set http header:%d",(int)cc);
  164. ae_ret = AE_FAILURE;
  165. goto fini;
  166. }
  167. if(method == POST){
  168. if((cc=curl_easy_setopt(curl, CURLOPT_POSTFIELDS, req_msg))!=CURLE_OK){
  169. AESM_DBG_ERROR("fail to set POST fields:%d",(int)cc);
  170. ae_ret = AE_FAILURE;
  171. goto fini;
  172. }
  173. if((cc=curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, msg_size))!=CURLE_OK){
  174. AESM_DBG_ERROR("fail to set POST fields size:%d",(int)cc);
  175. ae_ret = AE_FAILURE;
  176. goto fini;
  177. }
  178. }
  179. if((cc=curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback))!=CURLE_OK){
  180. AESM_DBG_ERROR("Fail to set callback function:%d",(int)cc);
  181. ae_ret = AE_FAILURE;
  182. goto fini;
  183. }
  184. network_malloc_info_t malloc_info;
  185. malloc_info.base=NULL;
  186. malloc_info.size = 0;
  187. if((cc=curl_easy_setopt(curl, CURLOPT_WRITEDATA, reinterpret_cast<void *>(&malloc_info)))!=CURLE_OK){
  188. AESM_DBG_ERROR("fail to set write back function parameter:%d",(int)cc);
  189. ae_ret = AE_FAILURE;
  190. goto fini;
  191. }
  192. if((cc=curl_easy_perform(curl))!=CURLE_OK){
  193. if(malloc_info.base){
  194. free(malloc_info.base);
  195. }
  196. AESM_DBG_ERROR("fail in connect:%d",(int)cc);
  197. ae_ret = OAL_NETWORK_UNAVAILABLE_ERROR;
  198. goto fini;
  199. }
  200. *resp_msg = malloc_info.base;
  201. resp_size = malloc_info.size;
  202. AESM_DBG_TRACE("get response size=%d",resp_size);
  203. ae_ret = AE_SUCCESS;
  204. fini:
  205. if(headers!=NULL){
  206. curl_slist_free_all(headers);
  207. }
  208. return ae_ret;
  209. }
  210. static void http_network_fini(CURL *curl)
  211. {
  212. if(curl!=NULL)
  213. curl_easy_cleanup(curl);
  214. }
  215. ae_error_t aesm_network_send_receive(const char *server_url, const uint8_t *req, uint32_t req_size,
  216. uint8_t **p_resp, uint32_t *p_resp_size, http_methods_t method, bool is_ocsp)
  217. {
  218. AESM_PROFILE_FUN;
  219. ae_error_t ret= AE_SUCCESS;
  220. CURL *curl = NULL;
  221. ret = http_network_init(&curl, server_url, is_ocsp);
  222. if(ret != AE_SUCCESS){
  223. goto ret_point;
  224. }
  225. ret = http_network_send_data(curl, reinterpret_cast<const char *>(req), req_size,
  226. reinterpret_cast<char **>(p_resp), *p_resp_size, method, is_ocsp);
  227. ret_point:
  228. http_network_fini(curl);
  229. return ret;
  230. }
  231. void aesm_free_network_response_buffer(uint8_t *resp)
  232. {
  233. if(resp!=NULL)free(resp);
  234. }