aesm_http_msg.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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. s->base = reinterpret_cast<char *>(malloc(size*nmemb));
  56. s->size = static_cast<uint32_t>(size*nmemb);
  57. if(s->base==NULL){
  58. AESM_DBG_ERROR("malloc error in write callback fun");
  59. return 0;
  60. }
  61. }else{
  62. uint32_t newsize = s->size+static_cast<uint32_t>(size*nmemb);
  63. char *p=reinterpret_cast<char *>(malloc(newsize));
  64. if(p == NULL){
  65. free(s->base);
  66. s->base = NULL;
  67. AESM_DBG_ERROR("malloc error in write callback fun");
  68. return 0;
  69. }
  70. memcpy(p, s->base, s->size);
  71. free(s->base);
  72. start = s->size;
  73. s->base = p;
  74. s->size = newsize;
  75. }
  76. memcpy(s->base +start, ptr, size*nmemb);
  77. return nmemb;
  78. }
  79. static ae_error_t http_network_init(CURL **curl, const char *url, bool is_ocsp)
  80. {
  81. CURLcode cc = CURLE_OK;
  82. UNUSED(is_ocsp);
  83. AESM_DBG_TRACE("http init for url %s",url);
  84. if(!is_curl_initialized_succ()){
  85. AESM_DBG_ERROR("libcurl not initialized");
  86. return AE_FAILURE;//fatal error that libcurl could not be initialized
  87. }
  88. std::string url_path = url;
  89. uint32_t proxy_type;
  90. char proxy_url[MAX_PATH];
  91. EndpointSelectionInfo::instance().get_proxy(proxy_type, proxy_url);
  92. *curl = curl_easy_init();
  93. if(!*curl){
  94. AESM_DBG_ERROR("fail to init curl handle");
  95. return AE_FAILURE;
  96. }
  97. if((cc=curl_easy_setopt(*curl, CURLOPT_URL, url_path.c_str()))!=CURLE_OK){
  98. AESM_DBG_ERROR("fail error code %d in set url %s",(int)cc, url_path.c_str());
  99. return AE_FAILURE;
  100. }
  101. (void)curl_easy_setopt(*curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
  102. //setting proxy now
  103. if(proxy_type == AESM_PROXY_TYPE_DIRECT_ACCESS){
  104. AESM_DBG_TRACE("use no proxy");
  105. (void)curl_easy_setopt(*curl, CURLOPT_NOPROXY , "*");
  106. }else if(proxy_type == AESM_PROXY_TYPE_MANUAL_PROXY){
  107. AESM_DBG_TRACE("use manual proxy %s",proxy_url);
  108. (void)curl_easy_setopt(*curl, CURLOPT_PROXY, proxy_url);
  109. }
  110. return AE_SUCCESS;
  111. }
  112. 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)
  113. {
  114. AESM_DBG_TRACE("send data method=%d",method);
  115. struct curl_slist *headers=NULL;
  116. CURLcode cc=CURLE_OK;
  117. if(is_ocsp){
  118. headers = curl_slist_append(headers, "Accept: application/ocsp-response");
  119. if(headers==NULL){
  120. AESM_DBG_ERROR("fail in add accept ocsp-response header");
  121. return AE_FAILURE;
  122. }
  123. headers = curl_slist_append(headers, "Content-Type: application/ocsp-request");
  124. if(headers == NULL){
  125. AESM_DBG_ERROR("fail in add content type ocsp-request");
  126. return AE_FAILURE;
  127. }
  128. AESM_DBG_TRACE("ocsp request");
  129. }
  130. char buf[50];
  131. sprintf(buf, "Content-Length: %u", (unsigned int)msg_size);
  132. headers = curl_slist_append(headers, buf);
  133. if(headers == NULL){
  134. AESM_DBG_ERROR("fail to add content-length header");
  135. return AE_FAILURE;
  136. }
  137. if((cc=curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers))!=CURLE_OK){
  138. AESM_DBG_ERROR("fail to set http header:%d",(int)cc);
  139. return AE_FAILURE;
  140. }
  141. if(method == POST){
  142. if((cc=curl_easy_setopt(curl, CURLOPT_POSTFIELDS, req_msg))!=CURLE_OK){
  143. AESM_DBG_ERROR("fail to set POST fields:%d",(int)cc);
  144. return AE_FAILURE;
  145. }
  146. if((cc=curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, msg_size))!=CURLE_OK){
  147. AESM_DBG_ERROR("fail to set POST fields size:%d",(int)cc);
  148. return AE_FAILURE;
  149. }
  150. }
  151. if((cc=curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback))!=CURLE_OK){
  152. AESM_DBG_ERROR("Fail to set callback function:%d",(int)cc);
  153. return AE_FAILURE;
  154. }
  155. network_malloc_info_t malloc_info;
  156. malloc_info.base=NULL;
  157. malloc_info.size = 0;
  158. if((cc=curl_easy_setopt(curl, CURLOPT_WRITEDATA, reinterpret_cast<void *>(&malloc_info)))!=CURLE_OK){
  159. AESM_DBG_ERROR("fail to set write back function parameter:%d",(int)cc);
  160. return AE_FAILURE;
  161. }
  162. if((cc=curl_easy_perform(curl))!=CURLE_OK){
  163. if(malloc_info.base){
  164. free(malloc_info.base);
  165. }
  166. AESM_DBG_ERROR("fail in connect:%d",(int)cc);
  167. return OAL_NETWORK_UNAVAILABLE_ERROR;
  168. }
  169. *resp_msg = malloc_info.base;
  170. resp_size = malloc_info.size;
  171. AESM_DBG_TRACE("get response size=%d",resp_size);
  172. return AE_SUCCESS;
  173. }
  174. static void http_network_fini(CURL *curl)
  175. {
  176. if(curl!=NULL)
  177. curl_easy_cleanup(curl);
  178. }
  179. ae_error_t aesm_network_send_receive(const char *server_url, const uint8_t *req, uint32_t req_size,
  180. uint8_t **p_resp, uint32_t *p_resp_size, http_methods_t method, bool is_ocsp)
  181. {
  182. AESM_PROFILE_FUN;
  183. ae_error_t ret= AE_SUCCESS;
  184. CURL *curl = NULL;
  185. ret = http_network_init(&curl, server_url, is_ocsp);
  186. if(ret != AE_SUCCESS){
  187. goto ret_point;
  188. }
  189. ret = http_network_send_data(curl, reinterpret_cast<const char *>(req), req_size,
  190. reinterpret_cast<char **>(p_resp), *p_resp_size, method, is_ocsp);
  191. ret_point:
  192. http_network_fini(curl);
  193. return ret;
  194. }
  195. void aesm_free_network_response_buffer(uint8_t *resp)
  196. {
  197. if(resp!=NULL)free(resp);
  198. }