http_client.c 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238
  1. /*
  2. * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
  3. * Copyright Siemens AG 2018-2020
  4. *
  5. * Licensed under the Apache License 2.0 (the "License"). You may not use
  6. * this file except in compliance with the License. You can obtain a copy
  7. * in the file LICENSE in the source distribution or at
  8. * https://www.openssl.org/source/license.html
  9. */
  10. #include "e_os.h"
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include "crypto/ctype.h"
  14. #include <string.h>
  15. #include <openssl/asn1.h>
  16. #include <openssl/evp.h>
  17. #include <openssl/err.h>
  18. #include <openssl/httperr.h>
  19. #include <openssl/cmperr.h>
  20. #include <openssl/buffer.h>
  21. #include <openssl/http.h>
  22. #include "internal/sockets.h"
  23. #include "internal/cryptlib.h"
  24. #include "http_local.h"
  25. #define HTTP_PREFIX "HTTP/"
  26. #define HTTP_VERSION_PATT "1." /* allow 1.x */
  27. #define HTTP_VERSION_STR_LEN 3
  28. #define HTTP_LINE1_MINLEN ((int)strlen(HTTP_PREFIX HTTP_VERSION_PATT "x 200\n"))
  29. #define HTTP_VERSION_MAX_REDIRECTIONS 50
  30. #define HTTP_STATUS_CODE_OK 200
  31. #define HTTP_STATUS_CODE_MOVED_PERMANENTLY 301
  32. #define HTTP_STATUS_CODE_FOUND 302
  33. /* Stateful HTTP request code, supporting blocking and non-blocking I/O */
  34. /* Opaque HTTP request status structure */
  35. struct ossl_http_req_ctx_st {
  36. int state; /* Current I/O state */
  37. unsigned char *iobuf; /* Line buffer */
  38. int iobuflen; /* Line buffer length */
  39. BIO *wbio; /* BIO to send request to */
  40. BIO *rbio; /* BIO to read response from */
  41. BIO *mem; /* Memory BIO response is built into */
  42. int method_GET; /* HTTP method "GET" or "POST" */
  43. const char *expected_ct; /* expected Content-Type, or NULL */
  44. int expect_asn1; /* response must be ASN.1-encoded */
  45. unsigned long resp_len; /* length of response */
  46. unsigned long max_resp_len; /* Maximum length of response */
  47. time_t max_time; /* Maximum end time of the transfer, or 0 */
  48. char *redirection_url; /* Location given with HTTP status 301/302 */
  49. };
  50. #define HTTP_DEFAULT_MAX_LINE_LENGTH (4 * 1024)
  51. #define HTTP_DEFAULT_MAX_RESP_LEN (100 * 1024)
  52. /* HTTP states */
  53. #define OHS_NOREAD 0x1000 /* If set no reading should be performed */
  54. #define OHS_ERROR (0 | OHS_NOREAD) /* Error condition */
  55. #define OHS_FIRSTLINE 1 /* First line being read */
  56. #define OHS_REDIRECT 0xa /* Looking for redirection location */
  57. #define OHS_HEADERS 2 /* MIME headers being read */
  58. #define OHS_ASN1_HEADER 3 /* HTTP initial header (tag+length) being read */
  59. #define OHS_CONTENT 4 /* HTTP content octets being read */
  60. #define OHS_WRITE_INIT (5 | OHS_NOREAD) /* 1st call: ready to start I/O */
  61. #define OHS_WRITE (6 | OHS_NOREAD) /* Request being sent */
  62. #define OHS_FLUSH (7 | OHS_NOREAD) /* Request being flushed */
  63. #define OHS_DONE (8 | OHS_NOREAD) /* Completed */
  64. #define OHS_HTTP_HEADER (9 | OHS_NOREAD) /* Headers set, w/o final \r\n */
  65. OSSL_HTTP_REQ_CTX *OSSL_HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio,
  66. int method_GET, int maxline,
  67. unsigned long max_resp_len,
  68. int timeout,
  69. const char *expected_content_type,
  70. int expect_asn1)
  71. {
  72. OSSL_HTTP_REQ_CTX *rctx;
  73. if (wbio == NULL || rbio == NULL) {
  74. HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
  75. return NULL;
  76. }
  77. if ((rctx = OPENSSL_zalloc(sizeof(*rctx))) == NULL)
  78. return NULL;
  79. rctx->state = OHS_ERROR;
  80. rctx->iobuflen = maxline > 0 ? maxline : HTTP_DEFAULT_MAX_LINE_LENGTH;
  81. rctx->iobuf = OPENSSL_malloc(rctx->iobuflen);
  82. rctx->wbio = wbio;
  83. rctx->rbio = rbio;
  84. rctx->mem = BIO_new(BIO_s_mem());
  85. if (rctx->iobuf == NULL || rctx->mem == NULL) {
  86. OSSL_HTTP_REQ_CTX_free(rctx);
  87. return NULL;
  88. }
  89. rctx->method_GET = method_GET;
  90. rctx->expected_ct = expected_content_type;
  91. rctx->expect_asn1 = expect_asn1;
  92. rctx->resp_len = 0;
  93. OSSL_HTTP_REQ_CTX_set_max_response_length(rctx, max_resp_len);
  94. rctx->max_time = timeout > 0 ? time(NULL) + timeout : 0;
  95. return rctx;
  96. }
  97. void OSSL_HTTP_REQ_CTX_free(OSSL_HTTP_REQ_CTX *rctx)
  98. {
  99. if (rctx == NULL)
  100. return;
  101. BIO_free(rctx->mem); /* this may indirectly call ERR_clear_error() */
  102. OPENSSL_free(rctx->iobuf);
  103. OPENSSL_free(rctx);
  104. }
  105. BIO *OSSL_HTTP_REQ_CTX_get0_mem_bio(OSSL_HTTP_REQ_CTX *rctx)
  106. {
  107. if (rctx == NULL) {
  108. HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
  109. return NULL;
  110. }
  111. return rctx->mem;
  112. }
  113. void OSSL_HTTP_REQ_CTX_set_max_response_length(OSSL_HTTP_REQ_CTX *rctx,
  114. unsigned long len)
  115. {
  116. if (rctx == NULL) {
  117. HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
  118. return;
  119. }
  120. rctx->max_resp_len = len != 0 ? len : HTTP_DEFAULT_MAX_RESP_LEN;
  121. }
  122. /*
  123. * Create HTTP header using given op and path (or "/" in case path is NULL).
  124. * Server name (and port) must be given if and only if plain HTTP proxy is used.
  125. */
  126. int OSSL_HTTP_REQ_CTX_header(OSSL_HTTP_REQ_CTX *rctx, const char *server,
  127. const char *port, const char *path)
  128. {
  129. if (rctx == NULL) {
  130. HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
  131. return 0;
  132. }
  133. if (BIO_printf(rctx->mem, "%s ", rctx->method_GET ? "GET" : "POST") <= 0)
  134. return 0;
  135. if (server != NULL) { /* HTTP (but not HTTPS) proxy is used */
  136. /*
  137. * Section 5.1.2 of RFC 1945 states that the absoluteURI form is only
  138. * allowed when using a proxy
  139. */
  140. if (BIO_printf(rctx->mem, "http://%s", server) <= 0)
  141. return 0;
  142. if (port != NULL && BIO_printf(rctx->mem, ":%s", port) <= 0)
  143. return 0;
  144. }
  145. /* Make sure path includes a forward slash */
  146. if (path == NULL)
  147. path = "/";
  148. if (path[0] != '/' && BIO_printf(rctx->mem, "/") <= 0)
  149. return 0;
  150. if (BIO_printf(rctx->mem, "%s "HTTP_PREFIX"1.0\r\n", path) <= 0)
  151. return 0;
  152. rctx->state = OHS_HTTP_HEADER;
  153. return 1;
  154. }
  155. int OSSL_HTTP_REQ_CTX_add1_header(OSSL_HTTP_REQ_CTX *rctx,
  156. const char *name, const char *value)
  157. {
  158. if (rctx == NULL || name == NULL) {
  159. HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
  160. return 0;
  161. }
  162. if (BIO_puts(rctx->mem, name) <= 0)
  163. return 0;
  164. if (value != NULL) {
  165. if (BIO_write(rctx->mem, ": ", 2) != 2)
  166. return 0;
  167. if (BIO_puts(rctx->mem, value) <= 0)
  168. return 0;
  169. }
  170. if (BIO_write(rctx->mem, "\r\n", 2) != 2)
  171. return 0;
  172. rctx->state = OHS_HTTP_HEADER;
  173. return 1;
  174. }
  175. static int OSSL_HTTP_REQ_CTX_content(OSSL_HTTP_REQ_CTX *rctx,
  176. const char *content_type, BIO *req_mem)
  177. {
  178. const unsigned char *req;
  179. long req_len;
  180. if (rctx == NULL || req_mem == NULL) {
  181. HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
  182. return 0;
  183. }
  184. if (content_type != NULL
  185. && BIO_printf(rctx->mem, "Content-Type: %s\r\n", content_type) <= 0)
  186. return 0;
  187. if ((req_len = BIO_get_mem_data(req_mem, &req)) <= 0)
  188. return 0;
  189. rctx->state = OHS_WRITE_INIT;
  190. return BIO_printf(rctx->mem, "Content-Length: %ld\r\n\r\n", req_len) > 0
  191. && BIO_write(rctx->mem, req, req_len) == (int)req_len;
  192. }
  193. BIO *HTTP_asn1_item2bio(const ASN1_ITEM *it, ASN1_VALUE *val)
  194. {
  195. BIO *res;
  196. if (it == NULL || val == NULL) {
  197. HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
  198. return NULL;
  199. }
  200. if ((res = BIO_new(BIO_s_mem())) == NULL)
  201. return NULL;
  202. if (ASN1_item_i2d_bio(it, res, val) <= 0) {
  203. BIO_free(res);
  204. res = NULL;
  205. }
  206. return res;
  207. }
  208. int OSSL_HTTP_REQ_CTX_i2d(OSSL_HTTP_REQ_CTX *rctx, const char *content_type,
  209. const ASN1_ITEM *it, ASN1_VALUE *req)
  210. {
  211. BIO *mem;
  212. int res;
  213. if (rctx == NULL || it == NULL || req == NULL) {
  214. HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
  215. return 0;
  216. }
  217. res = (mem = HTTP_asn1_item2bio(it, req)) != NULL
  218. && OSSL_HTTP_REQ_CTX_content(rctx, content_type, mem);
  219. BIO_free(mem);
  220. return res;
  221. }
  222. static int OSSL_HTTP_REQ_CTX_add1_headers(OSSL_HTTP_REQ_CTX *rctx,
  223. const STACK_OF(CONF_VALUE) *headers,
  224. const char *host)
  225. {
  226. int i;
  227. int add_host = 1;
  228. CONF_VALUE *hdr;
  229. for (i = 0; i < sk_CONF_VALUE_num(headers); i++) {
  230. hdr = sk_CONF_VALUE_value(headers, i);
  231. if (add_host && strcasecmp("host", hdr->name) == 0)
  232. add_host = 0;
  233. if (!OSSL_HTTP_REQ_CTX_add1_header(rctx, hdr->name, hdr->value))
  234. return 0;
  235. }
  236. if (add_host && !OSSL_HTTP_REQ_CTX_add1_header(rctx, "Host", host))
  237. return 0;
  238. return 1;
  239. }
  240. /*-
  241. * Create OSSL_HTTP_REQ_CTX structure using the values provided.
  242. * If !use_http_proxy then the 'server' and 'port' parameters are ignored.
  243. * If req_mem == NULL then use GET and ignore content_type, else POST.
  244. */
  245. OSSL_HTTP_REQ_CTX *HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio, int use_http_proxy,
  246. const char *server, const char *port,
  247. const char *path,
  248. const STACK_OF(CONF_VALUE) *headers,
  249. const char *content_type, BIO *req_mem,
  250. int maxline, unsigned long max_resp_len,
  251. int timeout,
  252. const char *expected_content_type,
  253. int expect_asn1)
  254. {
  255. OSSL_HTTP_REQ_CTX *rctx;
  256. if (use_http_proxy && (server == NULL || port == NULL)) {
  257. HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
  258. return NULL;
  259. }
  260. /* remaining parameters are checked indirectly by the functions called */
  261. if ((rctx = OSSL_HTTP_REQ_CTX_new(wbio, rbio, req_mem == NULL, maxline,
  262. max_resp_len, timeout,
  263. expected_content_type, expect_asn1))
  264. == NULL)
  265. return NULL;
  266. if (OSSL_HTTP_REQ_CTX_header(rctx, use_http_proxy ? server : NULL,
  267. port, path)
  268. && OSSL_HTTP_REQ_CTX_add1_headers(rctx, headers, server)
  269. && (req_mem == NULL
  270. || OSSL_HTTP_REQ_CTX_content(rctx, content_type, req_mem)))
  271. return rctx;
  272. OSSL_HTTP_REQ_CTX_free(rctx);
  273. return NULL;
  274. }
  275. /*
  276. * Parse first HTTP response line. This should be like this: "HTTP/1.0 200 OK".
  277. * We need to obtain the numeric code and (optional) informational message.
  278. */
  279. static int parse_http_line1(char *line)
  280. {
  281. int retcode;
  282. char *code, *reason, *end;
  283. /* Skip to first whitespace (past protocol info) */
  284. for (code = line; *code != '\0' && !ossl_isspace(*code); code++)
  285. continue;
  286. if (*code == '\0') {
  287. HTTPerr(0, HTTP_R_SERVER_RESPONSE_PARSE_ERROR);
  288. return 0;
  289. }
  290. /* Skip past whitespace to start of response code */
  291. while (*code != '\0' && ossl_isspace(*code))
  292. code++;
  293. if (*code == '\0') {
  294. HTTPerr(0, HTTP_R_SERVER_RESPONSE_PARSE_ERROR);
  295. return 0;
  296. }
  297. /* Find end of response code: first whitespace after start of code */
  298. for (reason = code; *reason != '\0' && !ossl_isspace(*reason); reason++)
  299. continue;
  300. if (*reason == '\0') {
  301. HTTPerr(0, HTTP_R_SERVER_RESPONSE_PARSE_ERROR);
  302. return 0;
  303. }
  304. /* Set end of response code and start of message */
  305. *reason++ = '\0';
  306. /* Attempt to parse numeric code */
  307. retcode = strtoul(code, &end, 10);
  308. if (*end != '\0')
  309. return 0;
  310. /* Skip over any leading whitespace in message */
  311. while (*reason != '\0' && ossl_isspace(*reason))
  312. reason++;
  313. if (*reason != '\0') {
  314. /*
  315. * Finally zap any trailing whitespace in message (include CRLF)
  316. */
  317. /* chop any trailing whitespace from reason */
  318. /* We know reason has a non-whitespace character so this is OK */
  319. for (end = reason + strlen(reason) - 1; ossl_isspace(*end); end--)
  320. *end = '\0';
  321. }
  322. switch (retcode) {
  323. case HTTP_STATUS_CODE_OK:
  324. case HTTP_STATUS_CODE_MOVED_PERMANENTLY:
  325. case HTTP_STATUS_CODE_FOUND:
  326. return retcode;
  327. default:
  328. if (retcode < 400)
  329. HTTPerr(0, HTTP_R_STATUS_CODE_UNSUPPORTED);
  330. else
  331. HTTPerr(0, HTTP_R_SERVER_SENT_ERROR);
  332. if (*reason == '\0')
  333. ERR_add_error_data(2, "Code=", code);
  334. else
  335. ERR_add_error_data(4, "Code=", code, ",Reason=", reason);
  336. return 0;
  337. }
  338. }
  339. static int check_set_resp_len(OSSL_HTTP_REQ_CTX *rctx, unsigned long len)
  340. {
  341. const char *tag = NULL;
  342. unsigned long val = 0;
  343. if (len > rctx->max_resp_len) {
  344. HTTPerr(0, HTTP_R_MAX_RESP_LEN_EXCEEDED);
  345. tag = ",max=";
  346. val = rctx->max_resp_len;
  347. }
  348. if (rctx->resp_len != 0 && rctx->resp_len != len) {
  349. HTTPerr(0, HTTP_R_INCONSISTENT_CONTENT_LENGTH);
  350. tag = ",before=";
  351. val = rctx->resp_len;
  352. }
  353. if (tag != NULL) {
  354. char len_str[32];
  355. char str[32];
  356. BIO_snprintf(len_str, sizeof(len_str), "%lu", len);
  357. BIO_snprintf(str, sizeof(str), "%lu", val);
  358. ERR_add_error_data(4, "length=", len_str, tag, str);
  359. return 0;
  360. }
  361. rctx->resp_len = len;
  362. return 1;
  363. }
  364. /*
  365. * Try exchanging request and response via HTTP on (non-)blocking BIO in rctx.
  366. * Returns 1 on success, 0 on error or redirection, -1 on BIO_should_retry.
  367. */
  368. int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
  369. {
  370. int i;
  371. long n, n_to_send = 0;
  372. unsigned long resp_len;
  373. const unsigned char *p;
  374. char *key, *value, *line_end = NULL;
  375. if (rctx == NULL) {
  376. HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
  377. return 0;
  378. }
  379. rctx->redirection_url = NULL;
  380. next_io:
  381. if ((rctx->state & OHS_NOREAD) == 0) {
  382. n = BIO_read(rctx->rbio, rctx->iobuf, rctx->iobuflen);
  383. if (n <= 0) {
  384. if (BIO_should_retry(rctx->rbio))
  385. return -1;
  386. return 0;
  387. }
  388. /* Write data to memory BIO */
  389. if (BIO_write(rctx->mem, rctx->iobuf, n) != n)
  390. return 0;
  391. }
  392. switch (rctx->state) {
  393. case OHS_HTTP_HEADER:
  394. /* Last operation was adding headers: need a final \r\n */
  395. if (BIO_write(rctx->mem, "\r\n", 2) != 2) {
  396. rctx->state = OHS_ERROR;
  397. return 0;
  398. }
  399. rctx->state = OHS_WRITE_INIT;
  400. /* fall thru */
  401. case OHS_WRITE_INIT:
  402. n_to_send = BIO_get_mem_data(rctx->mem, NULL);
  403. rctx->state = OHS_WRITE;
  404. /* fall thru */
  405. case OHS_WRITE:
  406. n = BIO_get_mem_data(rctx->mem, &p);
  407. i = BIO_write(rctx->wbio, p + (n - n_to_send), n_to_send);
  408. if (i <= 0) {
  409. if (BIO_should_retry(rctx->wbio))
  410. return -1;
  411. rctx->state = OHS_ERROR;
  412. return 0;
  413. }
  414. n_to_send -= i;
  415. if (n_to_send > 0)
  416. goto next_io;
  417. rctx->state = OHS_FLUSH;
  418. (void)BIO_reset(rctx->mem);
  419. /* fall thru */
  420. case OHS_FLUSH:
  421. i = BIO_flush(rctx->wbio);
  422. if (i > 0) {
  423. rctx->state = OHS_FIRSTLINE;
  424. goto next_io;
  425. }
  426. if (BIO_should_retry(rctx->wbio))
  427. return -1;
  428. rctx->state = OHS_ERROR;
  429. return 0;
  430. case OHS_ERROR:
  431. return 0;
  432. case OHS_FIRSTLINE:
  433. case OHS_HEADERS:
  434. case OHS_REDIRECT:
  435. /* Attempt to read a line in */
  436. next_line:
  437. /*
  438. * Due to strange memory BIO behavior with BIO_gets we have to check
  439. * there's a complete line in there before calling BIO_gets or we'll
  440. * just get a partial read.
  441. */
  442. n = BIO_get_mem_data(rctx->mem, &p);
  443. if (n <= 0 || memchr(p, '\n', n) == 0) {
  444. if (n >= rctx->iobuflen) {
  445. rctx->state = OHS_ERROR;
  446. return 0;
  447. }
  448. goto next_io;
  449. }
  450. n = BIO_gets(rctx->mem, (char *)rctx->iobuf, rctx->iobuflen);
  451. if (n <= 0) {
  452. if (BIO_should_retry(rctx->mem))
  453. goto next_io;
  454. rctx->state = OHS_ERROR;
  455. return 0;
  456. }
  457. /* Don't allow excessive lines */
  458. if (n == rctx->iobuflen) {
  459. HTTPerr(0, HTTP_R_RESPONSE_LINE_TOO_LONG);
  460. rctx->state = OHS_ERROR;
  461. return 0;
  462. }
  463. /* First line */
  464. if (rctx->state == OHS_FIRSTLINE) {
  465. switch (parse_http_line1((char *)rctx->iobuf)) {
  466. case HTTP_STATUS_CODE_OK:
  467. rctx->state = OHS_HEADERS;
  468. goto next_line;
  469. case HTTP_STATUS_CODE_MOVED_PERMANENTLY:
  470. case HTTP_STATUS_CODE_FOUND: /* i.e., moved temporarily */
  471. if (rctx->method_GET) {
  472. rctx->state = OHS_REDIRECT;
  473. goto next_line;
  474. }
  475. HTTPerr(0, HTTP_R_REDIRECTION_NOT_ENABLED);
  476. /* redirection is not supported/recommended for POST */
  477. /* fall through */
  478. default:
  479. rctx->state = OHS_ERROR;
  480. return 0;
  481. }
  482. }
  483. key = (char *)rctx->iobuf;
  484. value = strchr(key, ':');
  485. if (value != NULL) {
  486. *(value++) = '\0';
  487. while (ossl_isspace(*value))
  488. value++;
  489. line_end = strchr(value, '\r');
  490. if (line_end == NULL)
  491. line_end = strchr(value, '\n');
  492. if (line_end != NULL)
  493. *line_end = '\0';
  494. }
  495. if (value != NULL && line_end != NULL) {
  496. if (rctx->state == OHS_REDIRECT && strcmp(key, "Location") == 0) {
  497. rctx->redirection_url = value;
  498. return 0;
  499. }
  500. if (rctx->expected_ct != NULL && strcmp(key, "Content-Type") == 0) {
  501. if (strcmp(rctx->expected_ct, value) != 0) {
  502. HTTPerr(0, HTTP_R_UNEXPECTED_CONTENT_TYPE);
  503. ERR_add_error_data(4, "expected=", rctx->expected_ct,
  504. ",actual=", value);
  505. return 0;
  506. }
  507. rctx->expected_ct = NULL; /* content-type has been found */
  508. }
  509. if (strcmp(key, "Content-Length") == 0) {
  510. resp_len = strtoul(value, &line_end, 10);
  511. if (line_end == value || *line_end != '\0') {
  512. HTTPerr(0, HTTP_R_ERROR_PARSING_CONTENT_LENGTH);
  513. ERR_add_error_data(2, "input=", value);
  514. return 0;
  515. }
  516. if (!check_set_resp_len(rctx, resp_len))
  517. return 0;
  518. }
  519. }
  520. /* Look for blank line: end of headers */
  521. for (p = rctx->iobuf; *p != '\0' ; p++) {
  522. if (*p != '\r' && *p != '\n')
  523. break;
  524. }
  525. if (*p != '\0') /* not end of headers */
  526. goto next_line;
  527. if (rctx->expected_ct != NULL) {
  528. HTTPerr(0, HTTP_R_MISSING_CONTENT_TYPE);
  529. ERR_add_error_data(2, "expected=", rctx->expected_ct);
  530. return 0;
  531. }
  532. if (rctx->state == OHS_REDIRECT) {
  533. /* http status code indicated redirect but there was no Location */
  534. HTTPerr(0, HTTP_R_MISSING_REDIRECT_LOCATION);
  535. return 0;
  536. }
  537. if (!rctx->expect_asn1) {
  538. rctx->state = OHS_CONTENT;
  539. goto content;
  540. }
  541. rctx->state = OHS_ASN1_HEADER;
  542. /* Fall thru */
  543. case OHS_ASN1_HEADER:
  544. /*
  545. * Now reading ASN1 header: can read at least 2 bytes which is enough
  546. * for ASN1 SEQUENCE header and either length field or at least the
  547. * length of the length field.
  548. */
  549. n = BIO_get_mem_data(rctx->mem, &p);
  550. if (n < 2)
  551. goto next_io;
  552. /* Check it is an ASN1 SEQUENCE */
  553. if (*p++ != (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) {
  554. HTTPerr(0, HTTP_R_MISSING_ASN1_ENCODING);
  555. return 0;
  556. }
  557. /* Check out length field */
  558. if ((*p & 0x80) != 0) {
  559. /*
  560. * If MSB set on initial length octet we can now always read 6
  561. * octets: make sure we have them.
  562. */
  563. if (n < 6)
  564. goto next_io;
  565. n = *p & 0x7F;
  566. /* Not NDEF or excessive length */
  567. if (n == 0 || (n > 4)) {
  568. HTTPerr(0, HTTP_R_ERROR_PARSING_ASN1_LENGTH);
  569. return 0;
  570. }
  571. p++;
  572. resp_len = 0;
  573. for (i = 0; i < n; i++) {
  574. resp_len <<= 8;
  575. resp_len |= *p++;
  576. }
  577. resp_len += n + 2;
  578. } else {
  579. resp_len = *p + 2;
  580. }
  581. if (!check_set_resp_len(rctx, resp_len))
  582. return 0;
  583. content:
  584. rctx->state = OHS_CONTENT;
  585. /* Fall thru */
  586. case OHS_CONTENT:
  587. default:
  588. n = BIO_get_mem_data(rctx->mem, NULL);
  589. if (n < (long)rctx->resp_len /* may be 0 if no Content-Type or ASN.1 */)
  590. goto next_io;
  591. rctx->state = OHS_DONE;
  592. return 1;
  593. }
  594. }
  595. #ifndef OPENSSL_NO_SOCK
  596. /* set up a new connection BIO, to HTTP server or to HTTP(S) proxy if given */
  597. static BIO *HTTP_new_bio(const char *server, const char *server_port,
  598. const char *proxy, const char *proxy_port)
  599. {
  600. const char *host = server;
  601. const char *port = server_port;
  602. BIO *cbio;
  603. if (server == NULL) {
  604. HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
  605. return NULL;
  606. }
  607. if (proxy != NULL) {
  608. host = proxy;
  609. port = proxy_port;
  610. }
  611. cbio = BIO_new_connect(host);
  612. if (cbio == NULL)
  613. goto end;
  614. if (port != NULL)
  615. (void)BIO_set_conn_port(cbio, port);
  616. end:
  617. return cbio;
  618. }
  619. static ASN1_VALUE *BIO_mem_d2i(BIO *mem, const ASN1_ITEM *it)
  620. {
  621. const unsigned char *p;
  622. long len = BIO_get_mem_data(mem, &p);
  623. ASN1_VALUE *resp = ASN1_item_d2i(NULL, &p, len, it);
  624. if (resp == NULL)
  625. HTTPerr(0, HTTP_R_SERVER_RESPONSE_PARSE_ERROR);
  626. return resp;
  627. }
  628. static BIO *OSSL_HTTP_REQ_CTX_transfer(OSSL_HTTP_REQ_CTX *rctx)
  629. {
  630. int sending = 1;
  631. int rv;
  632. if (rctx == NULL) {
  633. HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
  634. return NULL;
  635. }
  636. for (;;) {
  637. rv = OSSL_HTTP_REQ_CTX_nbio(rctx);
  638. if (rv != -1)
  639. break;
  640. /* BIO_should_retry was true */
  641. sending = 0;
  642. /* will not actually wait if rctx->max_time == 0 */
  643. if (BIO_wait(rctx->rbio, rctx->max_time) <= 0)
  644. return NULL;
  645. }
  646. if (rv == 0) {
  647. if (rctx->redirection_url == NULL) { /* an error occurred */
  648. if (sending && (rctx->state & OHS_NOREAD) != 0)
  649. HTTPerr(0, HTTP_R_ERROR_SENDING);
  650. else
  651. HTTPerr(0, HTTP_R_ERROR_RECEIVING);
  652. }
  653. return NULL;
  654. }
  655. if (!BIO_up_ref(rctx->mem))
  656. return NULL;
  657. return rctx->mem;
  658. }
  659. /* Exchange ASN.1-encoded request and response via HTTP on (non-)blocking BIO */
  660. ASN1_VALUE *OSSL_HTTP_REQ_CTX_sendreq_d2i(OSSL_HTTP_REQ_CTX *rctx,
  661. const ASN1_ITEM *it)
  662. {
  663. if (rctx == NULL || it == NULL) {
  664. HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
  665. return NULL;
  666. }
  667. return BIO_mem_d2i(OSSL_HTTP_REQ_CTX_transfer(rctx), it);
  668. }
  669. static int update_timeout(int timeout, time_t start_time)
  670. {
  671. long elapsed_time;
  672. if (timeout == 0)
  673. return 0;
  674. elapsed_time = (long)(time(NULL) - start_time); /* this might overflow */
  675. return timeout <= elapsed_time ? -1 : timeout - elapsed_time;
  676. }
  677. /*-
  678. * Exchange HTTP request and response with the given server.
  679. * If req_mem == NULL then use GET and ignore content_type, else POST.
  680. * The redirection_url output (freed by caller) parameter is used only for GET.
  681. *
  682. * Typically the bio and rbio parameters are NULL and a network BIO is created
  683. * internally for connecting to the given server and port, optionally via a
  684. * proxy and its port, and is then used for exchanging the request and response.
  685. * If bio is given and rbio is NULL then this BIO is used instead.
  686. * If both bio and rbio are given (which may be memory BIOs for instance)
  687. * then no explicit connection is attempted,
  688. * bio is used for writing the request, and rbio for reading the response.
  689. *
  690. * bio_update_fn is an optional BIO connect/disconnect callback function,
  691. * which has the prototype
  692. * BIO *(*OSSL_HTTP_bio_cb_t) (BIO *bio, void *arg, int conn, int detail);
  693. * The callback may modify the HTTP BIO provided in the bio argument,
  694. * whereby it may make use of any custom defined argument 'arg'.
  695. * During connection establishment, just after BIO_connect_retry(),
  696. * the callback function is invoked with the 'conn' argument being 1
  697. * 'detail' indicating whether a HTTPS (i.e., TLS) connection is requested.
  698. * On disconnect 'conn' is 0 and 'detail' indicates that no error occurred.
  699. * For instance, on connect the funct may prepend a TLS BIO to implement HTTPS;
  700. * after disconnect it may do some error diagnostics and/or specific cleanup.
  701. * The function should return NULL to indicate failure.
  702. * After disconnect the modified BIO will be deallocated using BIO_free_all().
  703. */
  704. BIO *OSSL_HTTP_transfer(const char *server, const char *port, const char *path,
  705. int use_ssl, const char *proxy, const char *proxy_port,
  706. BIO *bio, BIO *rbio,
  707. OSSL_HTTP_bio_cb_t bio_update_fn, void *arg,
  708. const STACK_OF(CONF_VALUE) *headers,
  709. const char *content_type, BIO *req_mem,
  710. int maxline, unsigned long max_resp_len, int timeout,
  711. const char *expected_ct, int expect_asn1,
  712. char **redirection_url)
  713. {
  714. time_t start_time = timeout > 0 ? time(NULL) : 0;
  715. BIO *cbio; /* = bio if present, used as connection BIO if rbio is NULL */
  716. OSSL_HTTP_REQ_CTX *rctx;
  717. BIO *resp = NULL;
  718. if (redirection_url != NULL)
  719. *redirection_url = NULL; /* do this beforehand to prevent dbl free */
  720. if (use_ssl && bio_update_fn == NULL) {
  721. HTTPerr(0, HTTP_R_TLS_NOT_ENABLED);
  722. return NULL;
  723. }
  724. if (rbio != NULL && (bio == NULL || bio_update_fn != NULL)) {
  725. HTTPerr(0, ERR_R_PASSED_INVALID_ARGUMENT);
  726. return NULL;
  727. }
  728. /* remaining parameters are checked indirectly by the functions called */
  729. if (bio != NULL)
  730. cbio = bio;
  731. else if ((cbio = HTTP_new_bio(server, port, proxy, proxy_port)) == NULL)
  732. return NULL;
  733. (void)ERR_set_mark(); /* prepare removing any spurious libssl errors */
  734. if (rbio == NULL && BIO_connect_retry(cbio, timeout) <= 0)
  735. goto end;
  736. /* now timeout is guaranteed to be >= 0 */
  737. /* callback can be used to wrap or prepend TLS session */
  738. if (bio_update_fn != NULL) {
  739. BIO *orig_bio = cbio;
  740. cbio = (*bio_update_fn)(cbio, arg, 1 /* connect */, use_ssl);
  741. if (cbio == NULL) {
  742. cbio = orig_bio;
  743. goto end;
  744. }
  745. }
  746. rctx = HTTP_REQ_CTX_new(cbio, rbio != NULL ? rbio : cbio,
  747. !use_ssl && proxy != NULL, server, port, path,
  748. headers, content_type, req_mem, maxline,
  749. max_resp_len, update_timeout(timeout, start_time),
  750. expected_ct, expect_asn1);
  751. if (rctx == NULL)
  752. goto end;
  753. resp = OSSL_HTTP_REQ_CTX_transfer(rctx);
  754. if (resp == NULL) {
  755. if (rctx->redirection_url != NULL) {
  756. if (redirection_url == NULL)
  757. HTTPerr(0, HTTP_R_REDIRECTION_NOT_ENABLED);
  758. else
  759. /* may be NULL if out of memory: */
  760. *redirection_url = OPENSSL_strdup(rctx->redirection_url);
  761. } else {
  762. char buf[200];
  763. unsigned long err = ERR_peek_error();
  764. int lib = ERR_GET_LIB(err);
  765. int reason = ERR_GET_REASON(err);
  766. if (lib == ERR_LIB_SSL || lib == ERR_LIB_HTTP
  767. || (lib == ERR_LIB_BIO && reason == BIO_R_CONNECT_TIMEOUT)
  768. || (lib == ERR_LIB_BIO && reason == BIO_R_CONNECT_ERROR)
  769. || (lib == ERR_LIB_CMP
  770. && reason == CMP_R_POTENTIALLY_INVALID_CERTIFICATE)) {
  771. BIO_snprintf(buf, 200, "server=%s:%s", server, port);
  772. ERR_add_error_data(1, buf);
  773. if (err == 0) {
  774. BIO_snprintf(buf, 200, "server has disconnected%s",
  775. use_ssl ? " violating the protocol" :
  776. ", likely because it requires the use of TLS");
  777. ERR_add_error_data(1, buf);
  778. }
  779. }
  780. }
  781. }
  782. OSSL_HTTP_REQ_CTX_free(rctx);
  783. /* callback can be used to clean up TLS session */
  784. if (bio_update_fn != NULL
  785. && (*bio_update_fn)(cbio, arg, 0, resp != NULL) == NULL) {
  786. BIO_free(resp);
  787. resp = NULL;
  788. }
  789. end:
  790. /*
  791. * Use BIO_free_all() because bio_update_fn may prepend or append to cbio.
  792. * This also frees any (e.g., SSL/TLS) BIOs linked with bio and,
  793. * like BIO_reset(bio), calls SSL_shutdown() to notify/alert the peer.
  794. */
  795. if (bio == NULL) /* cbio was not provided by caller */
  796. BIO_free_all(cbio);
  797. if (resp != NULL)
  798. /* remove any spurious error queue entries by ssl_add_cert_chain() */
  799. (void)ERR_pop_to_mark();
  800. else
  801. (void)ERR_clear_last_mark();
  802. return resp;
  803. }
  804. static int redirection_ok(int n_redir, const char *old_url, const char *new_url)
  805. {
  806. static const char https[] = "https:";
  807. int https_len = 6; /* strlen(https) */
  808. if (n_redir >= HTTP_VERSION_MAX_REDIRECTIONS) {
  809. HTTPerr(0, HTTP_R_TOO_MANY_REDIRECTIONS);
  810. return 0;
  811. }
  812. if (*new_url == '/') /* redirection to same server => same protocol */
  813. return 1;
  814. if (strncmp(old_url, https, https_len) == 0 &&
  815. strncmp(new_url, https, https_len) != 0) {
  816. HTTPerr(0, HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP);
  817. return 0;
  818. }
  819. return 1;
  820. }
  821. /* Get data via HTTP from server at given URL, potentially with redirection */
  822. BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *proxy_port,
  823. BIO *bio, BIO *rbio,
  824. OSSL_HTTP_bio_cb_t bio_update_fn, void *arg,
  825. const STACK_OF(CONF_VALUE) *headers,
  826. int maxline, unsigned long max_resp_len, int timeout,
  827. const char *expected_content_type, int expect_asn1)
  828. {
  829. time_t start_time = timeout > 0 ? time(NULL) : 0;
  830. char *current_url, *redirection_url;
  831. int n_redirs = 0;
  832. char *host;
  833. char *port;
  834. char *path;
  835. int use_ssl;
  836. BIO *resp = NULL;
  837. if (url == NULL) {
  838. HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
  839. return NULL;
  840. }
  841. if ((current_url = OPENSSL_strdup(url)) == NULL)
  842. return NULL;
  843. for (;;) {
  844. if (!OSSL_HTTP_parse_url(current_url, &host, &port, &path, &use_ssl))
  845. break;
  846. new_rpath:
  847. resp = OSSL_HTTP_transfer(host, port, path, use_ssl, proxy, proxy_port,
  848. bio, rbio,
  849. bio_update_fn, arg, headers, NULL, NULL,
  850. maxline, max_resp_len,
  851. update_timeout(timeout, start_time),
  852. expected_content_type, expect_asn1,
  853. &redirection_url);
  854. OPENSSL_free(path);
  855. if (resp == NULL && redirection_url != NULL) {
  856. if (redirection_ok(++n_redirs, current_url, redirection_url)) {
  857. (void)BIO_reset(bio);
  858. OPENSSL_free(current_url);
  859. current_url = redirection_url;
  860. if (*redirection_url == '/') { /* redirection to same server */
  861. path = OPENSSL_strdup(redirection_url);
  862. goto new_rpath;
  863. }
  864. OPENSSL_free(host);
  865. OPENSSL_free(port);
  866. continue;
  867. }
  868. OPENSSL_free(redirection_url);
  869. }
  870. OPENSSL_free(host);
  871. OPENSSL_free(port);
  872. break;
  873. }
  874. OPENSSL_free(current_url);
  875. return resp;
  876. }
  877. /* Get ASN.1-encoded data via HTTP from server at given URL */
  878. ASN1_VALUE *OSSL_HTTP_get_asn1(const char *url,
  879. const char *proxy, const char *proxy_port,
  880. BIO *bio, BIO *rbio,
  881. OSSL_HTTP_bio_cb_t bio_update_fn, void *arg,
  882. const STACK_OF(CONF_VALUE) *headers,
  883. int maxline, unsigned long max_resp_len,
  884. int timeout, const char *expected_content_type,
  885. const ASN1_ITEM *it)
  886. {
  887. BIO *mem;
  888. ASN1_VALUE *resp = NULL;
  889. if (url == NULL || it == NULL) {
  890. HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
  891. return NULL;
  892. }
  893. if ((mem = OSSL_HTTP_get(url, proxy, proxy_port, bio, rbio, bio_update_fn,
  894. arg, headers, maxline, max_resp_len, timeout,
  895. expected_content_type, 1 /* expect_asn1 */))
  896. != NULL)
  897. resp = BIO_mem_d2i(mem, it);
  898. BIO_free(mem);
  899. return resp;
  900. }
  901. /* Post ASN.1-encoded request via HTTP to server return ASN.1 response */
  902. ASN1_VALUE *OSSL_HTTP_post_asn1(const char *server, const char *port,
  903. const char *path, int use_ssl,
  904. const char *proxy, const char *proxy_port,
  905. BIO *bio, BIO *rbio,
  906. OSSL_HTTP_bio_cb_t bio_update_fn, void *arg,
  907. const STACK_OF(CONF_VALUE) *headers,
  908. const char *content_type,
  909. ASN1_VALUE *req, const ASN1_ITEM *req_it,
  910. int maxline, unsigned long max_resp_len,
  911. int timeout, const char *expected_ct,
  912. const ASN1_ITEM *rsp_it)
  913. {
  914. BIO *req_mem;
  915. BIO *res_mem;
  916. ASN1_VALUE *resp = NULL;
  917. if (req == NULL) {
  918. HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
  919. return NULL;
  920. }
  921. /* remaining parameters are checked indirectly */
  922. req_mem = HTTP_asn1_item2bio(req_it, req);
  923. res_mem = OSSL_HTTP_transfer(server, port, path, use_ssl, proxy, proxy_port,
  924. bio, rbio,
  925. bio_update_fn, arg, headers, content_type,
  926. req_mem /* may be NULL */, maxline,
  927. max_resp_len, timeout,
  928. expected_ct, 1 /* expect_asn1 */, NULL);
  929. BIO_free(req_mem);
  930. if (res_mem != NULL)
  931. resp = BIO_mem_d2i(res_mem, rsp_it);
  932. BIO_free(res_mem);
  933. return resp;
  934. }
  935. /* BASE64 encoder used for encoding basic proxy authentication credentials */
  936. static char *base64encode(const void *buf, size_t len)
  937. {
  938. int i;
  939. size_t outl;
  940. char *out;
  941. /* Calculate size of encoded data */
  942. outl = (len / 3);
  943. if (len % 3 > 0)
  944. outl++;
  945. outl <<= 2;
  946. out = OPENSSL_malloc(outl + 1);
  947. if (out == NULL)
  948. return 0;
  949. i = EVP_EncodeBlock((unsigned char *)out, buf, len);
  950. if (!ossl_assert(0 <= i && (size_t)i <= outl)) {
  951. OPENSSL_free(out);
  952. return NULL;
  953. }
  954. return out;
  955. }
  956. /*
  957. * Promote the given connection BIO using the CONNECT method for a TLS proxy.
  958. * This is typically called by an app, so bio_err and prog are used unless NULL
  959. * to print additional diagnostic information in a user-oriented way.
  960. */
  961. int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port,
  962. const char *proxyuser, const char *proxypass,
  963. int timeout, BIO *bio_err, const char *prog)
  964. {
  965. # undef BUF_SIZE
  966. # define BUF_SIZE (8 * 1024)
  967. char *mbuf = OPENSSL_malloc(BUF_SIZE);
  968. char *mbufp;
  969. int read_len = 0;
  970. int rv;
  971. int ret = 0;
  972. BIO *fbio = BIO_new(BIO_f_buffer());
  973. time_t max_time = timeout > 0 ? time(NULL) + timeout : 0;
  974. if (bio == NULL || server == NULL || port == NULL
  975. || (bio_err != NULL && prog == NULL)) {
  976. HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER);
  977. goto end;
  978. }
  979. if (mbuf == NULL || fbio == NULL) {
  980. BIO_printf(bio_err /* may be NULL */, "%s: out of memory", prog);
  981. goto end;
  982. }
  983. BIO_push(fbio, bio);
  984. BIO_printf(fbio, "CONNECT %s:%s "HTTP_PREFIX"1.0\r\n", server, port);
  985. /*
  986. * Workaround for broken proxies which would otherwise close
  987. * the connection when entering tunnel mode (e.g., Squid 2.6)
  988. */
  989. BIO_printf(fbio, "Proxy-Connection: Keep-Alive\r\n");
  990. /* Support for basic (base64) proxy authentication */
  991. if (proxyuser != NULL) {
  992. size_t len = strlen(proxyuser) + 1;
  993. char *proxyauth, *proxyauthenc = NULL;
  994. if (proxypass != NULL)
  995. len += strlen(proxypass);
  996. proxyauth = OPENSSL_malloc(len + 1);
  997. if (proxyauth == NULL)
  998. goto end;
  999. if (BIO_snprintf(proxyauth, len + 1, "%s:%s", proxyuser,
  1000. proxypass != NULL ? proxypass : "") != (int)len)
  1001. goto proxy_end;
  1002. proxyauthenc = base64encode(proxyauth, len);
  1003. if (proxyauthenc != NULL) {
  1004. BIO_printf(fbio, "Proxy-Authorization: Basic %s\r\n", proxyauthenc);
  1005. OPENSSL_clear_free(proxyauthenc, strlen(proxyauthenc));
  1006. }
  1007. proxy_end:
  1008. OPENSSL_clear_free(proxyauth, len);
  1009. if (proxyauthenc == NULL)
  1010. goto end;
  1011. }
  1012. /* Terminate the HTTP CONNECT request */
  1013. BIO_printf(fbio, "\r\n");
  1014. for (;;) {
  1015. if (BIO_flush(fbio) != 0)
  1016. break;
  1017. /* potentially needs to be retried if BIO is non-blocking */
  1018. if (!BIO_should_retry(fbio))
  1019. break;
  1020. }
  1021. for (;;) {
  1022. /* will not actually wait if timeout == 0 */
  1023. rv = BIO_wait(fbio, max_time);
  1024. if (rv <= 0) {
  1025. BIO_printf(bio_err, "%s: HTTP CONNECT %s\n", prog,
  1026. rv == 0 ? "timed out" : "failed waiting for data");
  1027. goto end;
  1028. }
  1029. /*-
  1030. * The first line is the HTTP response.
  1031. * According to RFC 7230, it is formatted exactly like this:
  1032. * HTTP/d.d ddd Reason text\r\n
  1033. */
  1034. read_len = BIO_gets(fbio, mbuf, BUF_SIZE);
  1035. /* the BIO may not block, so we must wait for the 1st line to come in */
  1036. if (read_len < HTTP_LINE1_MINLEN)
  1037. continue;
  1038. /* RFC 7231 4.3.6: any 2xx status code is valid */
  1039. if (strncmp(mbuf, HTTP_PREFIX, strlen(HTTP_PREFIX)) != 0) {
  1040. HTTPerr(0, HTTP_R_SERVER_RESPONSE_PARSE_ERROR);
  1041. BIO_printf(bio_err, "%s: HTTP CONNECT failed, non-HTTP response\n",
  1042. prog);
  1043. /* Wrong protocol, not even HTTP, so stop reading headers */
  1044. goto end;
  1045. }
  1046. mbufp = mbuf + strlen(HTTP_PREFIX);
  1047. if (strncmp(mbufp, HTTP_VERSION_PATT, strlen(HTTP_VERSION_PATT)) != 0) {
  1048. HTTPerr(0, HTTP_R_SERVER_SENT_WRONG_HTTP_VERSION);
  1049. BIO_printf(bio_err,
  1050. "%s: HTTP CONNECT failed, bad HTTP version %.*s\n",
  1051. prog, HTTP_VERSION_STR_LEN, mbufp);
  1052. goto end;
  1053. }
  1054. mbufp += HTTP_VERSION_STR_LEN;
  1055. if (strncmp(mbufp, " 2", strlen(" 2")) != 0) {
  1056. mbufp += 1;
  1057. /* chop any trailing whitespace */
  1058. while (read_len > 0 && ossl_isspace(mbuf[read_len - 1]))
  1059. read_len--;
  1060. mbuf[read_len] = '\0';
  1061. HTTPerr(0, HTTP_R_CONNECT_FAILURE);
  1062. ERR_add_error_data(2, "Reason=", mbufp);
  1063. BIO_printf(bio_err, "%s: HTTP CONNECT failed, Reason=%s\n",
  1064. prog, mbufp);
  1065. goto end;
  1066. }
  1067. ret = 1;
  1068. break;
  1069. }
  1070. /* Read past all following headers */
  1071. do {
  1072. /*
  1073. * TODO: This does not necessarily catch the case when the full
  1074. * HTTP response came in in more than a single TCP message.
  1075. */
  1076. read_len = BIO_gets(fbio, mbuf, BUF_SIZE);
  1077. } while (read_len > 2);
  1078. end:
  1079. if (fbio != NULL) {
  1080. (void)BIO_flush(fbio);
  1081. BIO_pop(fbio);
  1082. BIO_free(fbio);
  1083. }
  1084. OPENSSL_free(mbuf);
  1085. return ret;
  1086. # undef BUF_SIZE
  1087. }
  1088. #endif /* !defined(OPENSSL_NO_SOCK) */