aesm_http_msg.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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. std::string url_path = url;
  95. uint32_t proxy_type;
  96. char proxy_url[MAX_PATH];
  97. EndpointSelectionInfo::instance().get_proxy(proxy_type, proxy_url);
  98. *curl = curl_easy_init();
  99. if(!*curl){
  100. AESM_DBG_ERROR("fail to init curl handle");
  101. return AE_FAILURE;
  102. }
  103. if((cc=curl_easy_setopt(*curl, CURLOPT_URL, url_path.c_str()))!=CURLE_OK){
  104. AESM_DBG_ERROR("fail error code %d in set url %s",(int)cc, url_path.c_str());
  105. curl_easy_cleanup(*curl);
  106. return AE_FAILURE;
  107. }
  108. (void)curl_easy_setopt(*curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
  109. //setting proxy now
  110. if(proxy_type == AESM_PROXY_TYPE_DIRECT_ACCESS){
  111. AESM_DBG_TRACE("use no proxy");
  112. (void)curl_easy_setopt(*curl, CURLOPT_NOPROXY , "*");
  113. }else if(proxy_type == AESM_PROXY_TYPE_MANUAL_PROXY){
  114. AESM_DBG_TRACE("use manual proxy %s",proxy_url);
  115. (void)curl_easy_setopt(*curl, CURLOPT_PROXY, proxy_url);
  116. }
  117. return AE_SUCCESS;
  118. }
  119. 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)
  120. {
  121. AESM_DBG_TRACE("send data method=%d",method);
  122. struct curl_slist *headers=NULL;
  123. struct curl_slist *tmp=NULL;
  124. ae_error_t ae_ret = AE_SUCCESS;
  125. CURLcode cc=CURLE_OK;
  126. int num_bytes = 0;
  127. if(is_ocsp){
  128. tmp = curl_slist_append(headers, "Accept: application/ocsp-response");
  129. if(tmp==NULL){
  130. AESM_DBG_ERROR("fail in add accept ocsp-response header");
  131. ae_ret = AE_FAILURE;
  132. goto fini;
  133. }
  134. headers = tmp;
  135. tmp = curl_slist_append(headers, "Content-Type: application/ocsp-request");
  136. if(tmp == NULL){
  137. AESM_DBG_ERROR("fail in add content type ocsp-request");
  138. ae_ret = AE_FAILURE;
  139. goto fini;
  140. }
  141. headers=tmp;
  142. AESM_DBG_TRACE("ocsp request");
  143. }
  144. char buf[50];
  145. num_bytes = snprintf(buf,sizeof(buf), "Content-Length: %u", (unsigned int)msg_size);
  146. if(num_bytes<0 || num_bytes>=sizeof(buf)){
  147. AESM_DBG_ERROR("fail to prepare string Content-Length");
  148. ae_ret = AE_FAILURE;
  149. goto fini;
  150. }
  151. tmp = curl_slist_append(headers, buf);
  152. if(tmp == NULL){
  153. AESM_DBG_ERROR("fail to add content-length header");
  154. ae_ret = AE_FAILURE;
  155. goto fini;
  156. }
  157. headers=tmp;
  158. if((cc=curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers))!=CURLE_OK){
  159. AESM_DBG_ERROR("fail to set http header:%d",(int)cc);
  160. ae_ret = AE_FAILURE;
  161. goto fini;
  162. }
  163. if(method == POST){
  164. if((cc=curl_easy_setopt(curl, CURLOPT_POSTFIELDS, req_msg))!=CURLE_OK){
  165. AESM_DBG_ERROR("fail to set POST fields:%d",(int)cc);
  166. ae_ret = AE_FAILURE;
  167. goto fini;
  168. }
  169. if((cc=curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, msg_size))!=CURLE_OK){
  170. AESM_DBG_ERROR("fail to set POST fields size:%d",(int)cc);
  171. ae_ret = AE_FAILURE;
  172. goto fini;
  173. }
  174. }
  175. if((cc=curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback))!=CURLE_OK){
  176. AESM_DBG_ERROR("Fail to set callback function:%d",(int)cc);
  177. ae_ret = AE_FAILURE;
  178. goto fini;
  179. }
  180. network_malloc_info_t malloc_info;
  181. malloc_info.base=NULL;
  182. malloc_info.size = 0;
  183. if((cc=curl_easy_setopt(curl, CURLOPT_WRITEDATA, reinterpret_cast<void *>(&malloc_info)))!=CURLE_OK){
  184. AESM_DBG_ERROR("fail to set write back function parameter:%d",(int)cc);
  185. ae_ret = AE_FAILURE;
  186. goto fini;
  187. }
  188. if((cc=curl_easy_perform(curl))!=CURLE_OK){
  189. if(malloc_info.base){
  190. free(malloc_info.base);
  191. }
  192. AESM_DBG_ERROR("fail in connect:%d",(int)cc);
  193. ae_ret = OAL_NETWORK_UNAVAILABLE_ERROR;
  194. goto fini;
  195. }
  196. *resp_msg = malloc_info.base;
  197. resp_size = malloc_info.size;
  198. AESM_DBG_TRACE("get response size=%d",resp_size);
  199. ae_ret = AE_SUCCESS;
  200. fini:
  201. if(headers!=NULL){
  202. curl_slist_free_all(headers);
  203. }
  204. return ae_ret;
  205. }
  206. static void http_network_fini(CURL *curl)
  207. {
  208. if(curl!=NULL)
  209. curl_easy_cleanup(curl);
  210. }
  211. ae_error_t aesm_network_send_receive(const char *server_url, const uint8_t *req, uint32_t req_size,
  212. uint8_t **p_resp, uint32_t *p_resp_size, http_methods_t method, bool is_ocsp)
  213. {
  214. AESM_PROFILE_FUN;
  215. ae_error_t ret= AE_SUCCESS;
  216. CURL *curl = NULL;
  217. ret = http_network_init(&curl, server_url, is_ocsp);
  218. if(ret != AE_SUCCESS){
  219. goto ret_point;
  220. }
  221. ret = http_network_send_data(curl, reinterpret_cast<const char *>(req), req_size,
  222. reinterpret_cast<char **>(p_resp), *p_resp_size, method, is_ocsp);
  223. ret_point:
  224. http_network_fini(curl);
  225. return ret;
  226. }
  227. void aesm_free_network_response_buffer(uint8_t *resp)
  228. {
  229. if(resp!=NULL)free(resp);
  230. }