1  /*
2   * HTTP wrapper for libcurl
3   * Copyright (c) 2012-2014, Qualcomm Atheros, Inc.
4   *
5   * This software may be distributed under the terms of the BSD license.
6   * See README for more details.
7   */
8  
9  #include "includes.h"
10  #include <curl/curl.h>
11  #ifdef EAP_TLS_OPENSSL
12  #include <openssl/ssl.h>
13  #include <openssl/asn1.h>
14  #include <openssl/asn1t.h>
15  #include <openssl/x509v3.h>
16  
17  #ifdef SSL_set_tlsext_status_type
18  #ifndef OPENSSL_NO_TLSEXT
19  #define HAVE_OCSP
20  #include <openssl/err.h>
21  #include <openssl/ocsp.h>
22  #endif /* OPENSSL_NO_TLSEXT */
23  #endif /* SSL_set_tlsext_status_type */
24  #endif /* EAP_TLS_OPENSSL */
25  
26  #include "common.h"
27  #include "xml-utils.h"
28  #include "http-utils.h"
29  #ifdef EAP_TLS_OPENSSL
30  #include "crypto/tls_openssl.h"
31  #endif /* EAP_TLS_OPENSSL */
32  
33  
34  struct http_ctx {
35  	void *ctx;
36  	struct xml_node_ctx *xml;
37  	CURL *curl;
38  	struct curl_slist *curl_hdr;
39  	char *svc_address;
40  	char *curl_buf;
41  	size_t curl_buf_len;
42  
43  	enum {
44  		NO_OCSP, OPTIONAL_OCSP, MANDATORY_OCSP
45  	} ocsp;
46  	X509 *peer_cert;
47  	X509 *peer_issuer;
48  	X509 *peer_issuer_issuer;
49  
50  	const char *last_err;
51  	const char *url;
52  };
53  
54  
clear_curl(struct http_ctx * ctx)55  static void clear_curl(struct http_ctx *ctx)
56  {
57  	if (ctx->curl) {
58  		curl_easy_cleanup(ctx->curl);
59  		ctx->curl = NULL;
60  	}
61  	if (ctx->curl_hdr) {
62  		curl_slist_free_all(ctx->curl_hdr);
63  		ctx->curl_hdr = NULL;
64  	}
65  }
66  
67  
debug_dump(struct http_ctx * ctx,const char * title,const char * buf,size_t len)68  static void debug_dump(struct http_ctx *ctx, const char *title,
69  		       const char *buf, size_t len)
70  {
71  	char *txt;
72  	size_t i;
73  
74  	for (i = 0; i < len; i++) {
75  		if (buf[i] < 32 && buf[i] != '\t' && buf[i] != '\n' &&
76  		    buf[i] != '\r') {
77  			wpa_hexdump_ascii(MSG_MSGDUMP, title, buf, len);
78  			return;
79  		}
80  	}
81  
82  	txt = os_malloc(len + 1);
83  	if (txt == NULL)
84  		return;
85  	os_memcpy(txt, buf, len);
86  	txt[len] = '\0';
87  	while (len > 0) {
88  		len--;
89  		if (txt[len] == '\n' || txt[len] == '\r')
90  			txt[len] = '\0';
91  		else
92  			break;
93  	}
94  	wpa_printf(MSG_MSGDUMP, "%s[%s]", title, txt);
95  	os_free(txt);
96  }
97  
98  
curl_cb_debug(CURL * curl,curl_infotype info,char * buf,size_t len,void * userdata)99  static int curl_cb_debug(CURL *curl, curl_infotype info, char *buf, size_t len,
100  			 void *userdata)
101  {
102  	struct http_ctx *ctx = userdata;
103  	switch (info) {
104  	case CURLINFO_TEXT:
105  		debug_dump(ctx, "CURLINFO_TEXT", buf, len);
106  		break;
107  	case CURLINFO_HEADER_IN:
108  		debug_dump(ctx, "CURLINFO_HEADER_IN", buf, len);
109  		break;
110  	case CURLINFO_HEADER_OUT:
111  		debug_dump(ctx, "CURLINFO_HEADER_OUT", buf, len);
112  		break;
113  	case CURLINFO_DATA_IN:
114  		debug_dump(ctx, "CURLINFO_DATA_IN", buf, len);
115  		break;
116  	case CURLINFO_DATA_OUT:
117  		debug_dump(ctx, "CURLINFO_DATA_OUT", buf, len);
118  		break;
119  	case CURLINFO_SSL_DATA_IN:
120  		wpa_printf(MSG_DEBUG, "debug - CURLINFO_SSL_DATA_IN - %d",
121  			   (int) len);
122  		break;
123  	case CURLINFO_SSL_DATA_OUT:
124  		wpa_printf(MSG_DEBUG, "debug - CURLINFO_SSL_DATA_OUT - %d",
125  			   (int) len);
126  		break;
127  	case CURLINFO_END:
128  		wpa_printf(MSG_DEBUG, "debug - CURLINFO_END - %d",
129  			   (int) len);
130  		break;
131  	}
132  	return 0;
133  }
134  
135  
curl_cb_write(void * ptr,size_t size,size_t nmemb,void * userdata)136  static size_t curl_cb_write(void *ptr, size_t size, size_t nmemb,
137  			    void *userdata)
138  {
139  	struct http_ctx *ctx = userdata;
140  	char *n;
141  	n = os_realloc(ctx->curl_buf, ctx->curl_buf_len + size * nmemb + 1);
142  	if (n == NULL)
143  		return 0;
144  	ctx->curl_buf = n;
145  	os_memcpy(n + ctx->curl_buf_len, ptr, size * nmemb);
146  	n[ctx->curl_buf_len + size * nmemb] = '\0';
147  	ctx->curl_buf_len += size * nmemb;
148  	return size * nmemb;
149  }
150  
151  
152  #ifdef EAP_TLS_OPENSSL
153  
debug_dump_cert(const char * title,X509 * cert)154  static void debug_dump_cert(const char *title, X509 *cert)
155  {
156  	BIO *out;
157  	char *txt;
158  	size_t rlen;
159  
160  	out = BIO_new(BIO_s_mem());
161  	if (!out)
162  		return;
163  
164  	X509_print_ex(out, cert, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
165  	rlen = BIO_ctrl_pending(out);
166  	txt = os_malloc(rlen + 1);
167  	if (txt) {
168  		int res = BIO_read(out, txt, rlen);
169  		if (res > 0) {
170  			txt[res] = '\0';
171  			wpa_printf(MSG_MSGDUMP, "%s:\n%s", title, txt);
172  		}
173  		os_free(txt);
174  	}
175  	BIO_free(out);
176  }
177  
178  
curl_cb_ssl_verify(int preverify_ok,X509_STORE_CTX * x509_ctx)179  static int curl_cb_ssl_verify(int preverify_ok, X509_STORE_CTX *x509_ctx)
180  {
181  	struct http_ctx *ctx;
182  	X509 *cert;
183  	int err, depth;
184  	char buf[256];
185  	X509_NAME *name;
186  	const char *err_str;
187  	SSL *ssl;
188  	SSL_CTX *ssl_ctx;
189  
190  	ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
191  					 SSL_get_ex_data_X509_STORE_CTX_idx());
192  	ssl_ctx = SSL_get_SSL_CTX(ssl);
193  	ctx = SSL_CTX_get_app_data(ssl_ctx);
194  
195  	wpa_printf(MSG_DEBUG, "curl_cb_ssl_verify, preverify_ok: %d",
196  		   preverify_ok);
197  
198  	err = X509_STORE_CTX_get_error(x509_ctx);
199  	err_str = X509_verify_cert_error_string(err);
200  	depth = X509_STORE_CTX_get_error_depth(x509_ctx);
201  	cert = X509_STORE_CTX_get_current_cert(x509_ctx);
202  	if (!cert) {
203  		wpa_printf(MSG_INFO, "No server certificate available");
204  		ctx->last_err = "No server certificate available";
205  		return 0;
206  	}
207  
208  	if (depth == 0)
209  		ctx->peer_cert = cert;
210  	else if (depth == 1)
211  		ctx->peer_issuer = cert;
212  	else if (depth == 2)
213  		ctx->peer_issuer_issuer = cert;
214  
215  	name = X509_get_subject_name(cert);
216  	X509_NAME_oneline(name, buf, sizeof(buf));
217  	wpa_printf(MSG_INFO, "Server certificate chain - depth=%d err=%d (%s) subject=%s",
218  		   depth, err, err_str, buf);
219  	debug_dump_cert("Server certificate chain - certificate", cert);
220  
221  #ifdef OPENSSL_IS_BORINGSSL
222  	if (depth == 0 && ctx->ocsp != NO_OCSP && preverify_ok) {
223  		enum ocsp_result res;
224  
225  		res = check_ocsp_resp(ssl_ctx, ssl, cert, ctx->peer_issuer,
226  				      ctx->peer_issuer_issuer);
227  		if (res == OCSP_REVOKED) {
228  			preverify_ok = 0;
229  			wpa_printf(MSG_INFO, "OCSP: certificate revoked");
230  			if (err == X509_V_OK)
231  				X509_STORE_CTX_set_error(
232  					x509_ctx, X509_V_ERR_CERT_REVOKED);
233  		} else if (res != OCSP_GOOD && (ctx->ocsp == MANDATORY_OCSP)) {
234  			preverify_ok = 0;
235  			wpa_printf(MSG_INFO,
236  				   "OCSP: bad certificate status response");
237  		}
238  	}
239  #endif /* OPENSSL_IS_BORINGSSL */
240  
241  	if (!preverify_ok)
242  		ctx->last_err = "TLS validation failed";
243  
244  	return preverify_ok;
245  }
246  
247  
248  #ifdef HAVE_OCSP
249  
ocsp_debug_print_resp(OCSP_RESPONSE * rsp)250  static void ocsp_debug_print_resp(OCSP_RESPONSE *rsp)
251  {
252  	BIO *out;
253  	size_t rlen;
254  	char *txt;
255  	int res;
256  
257  	out = BIO_new(BIO_s_mem());
258  	if (!out)
259  		return;
260  
261  	OCSP_RESPONSE_print(out, rsp, 0);
262  	rlen = BIO_ctrl_pending(out);
263  	txt = os_malloc(rlen + 1);
264  	if (!txt) {
265  		BIO_free(out);
266  		return;
267  	}
268  
269  	res = BIO_read(out, txt, rlen);
270  	if (res > 0) {
271  		txt[res] = '\0';
272  		wpa_printf(MSG_MSGDUMP, "OpenSSL: OCSP Response\n%s", txt);
273  	}
274  	os_free(txt);
275  	BIO_free(out);
276  }
277  
278  
tls_show_errors(const char * func,const char * txt)279  static void tls_show_errors(const char *func, const char *txt)
280  {
281  	unsigned long err;
282  
283  	wpa_printf(MSG_DEBUG, "OpenSSL: %s - %s %s",
284  		   func, txt, ERR_error_string(ERR_get_error(), NULL));
285  
286  	while ((err = ERR_get_error())) {
287  		wpa_printf(MSG_DEBUG, "OpenSSL: pending error: %s",
288  			   ERR_error_string(err, NULL));
289  	}
290  }
291  
292  
ocsp_resp_cb(SSL * s,void * arg)293  static int ocsp_resp_cb(SSL *s, void *arg)
294  {
295  	struct http_ctx *ctx = arg;
296  	const unsigned char *p;
297  	int len, status, reason, res;
298  	OCSP_RESPONSE *rsp;
299  	OCSP_BASICRESP *basic;
300  	OCSP_CERTID *id;
301  	ASN1_GENERALIZEDTIME *produced_at, *this_update, *next_update;
302  	X509_STORE *store;
303  	STACK_OF(X509) *certs = NULL;
304  
305  	len = SSL_get_tlsext_status_ocsp_resp(s, &p);
306  	if (!p) {
307  		wpa_printf(MSG_DEBUG, "OpenSSL: No OCSP response received");
308  		if (ctx->ocsp == MANDATORY_OCSP)
309  			ctx->last_err = "No OCSP response received";
310  		return (ctx->ocsp == MANDATORY_OCSP) ? 0 : 1;
311  	}
312  
313  	wpa_hexdump(MSG_DEBUG, "OpenSSL: OCSP response", p, len);
314  
315  	rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
316  	if (!rsp) {
317  		wpa_printf(MSG_INFO, "OpenSSL: Failed to parse OCSP response");
318  		ctx->last_err = "Failed to parse OCSP response";
319  		return 0;
320  	}
321  
322  	ocsp_debug_print_resp(rsp);
323  
324  	status = OCSP_response_status(rsp);
325  	if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
326  		wpa_printf(MSG_INFO, "OpenSSL: OCSP responder error %d (%s)",
327  			   status, OCSP_response_status_str(status));
328  		ctx->last_err = "OCSP responder error";
329  		return 0;
330  	}
331  
332  	basic = OCSP_response_get1_basic(rsp);
333  	if (!basic) {
334  		wpa_printf(MSG_INFO, "OpenSSL: Could not find BasicOCSPResponse");
335  		ctx->last_err = "Could not find BasicOCSPResponse";
336  		return 0;
337  	}
338  
339  	store = SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s));
340  	if (ctx->peer_issuer) {
341  		wpa_printf(MSG_DEBUG, "OpenSSL: Add issuer");
342  		debug_dump_cert("OpenSSL: Issuer certificate",
343  				ctx->peer_issuer);
344  
345  		if (X509_STORE_add_cert(store, ctx->peer_issuer) != 1) {
346  			tls_show_errors(__func__,
347  					"OpenSSL: Could not add issuer to certificate store");
348  		}
349  		certs = sk_X509_new_null();
350  		if (certs) {
351  			X509 *cert;
352  			cert = X509_dup(ctx->peer_issuer);
353  			if (cert && !sk_X509_push(certs, cert)) {
354  				tls_show_errors(
355  					__func__,
356  					"OpenSSL: Could not add issuer to OCSP responder trust store");
357  				X509_free(cert);
358  				sk_X509_free(certs);
359  				certs = NULL;
360  			}
361  			if (certs && ctx->peer_issuer_issuer) {
362  				cert = X509_dup(ctx->peer_issuer_issuer);
363  				if (cert && !sk_X509_push(certs, cert)) {
364  					tls_show_errors(
365  						__func__,
366  						"OpenSSL: Could not add issuer's issuer to OCSP responder trust store");
367  					X509_free(cert);
368  				}
369  			}
370  		}
371  	}
372  
373  	status = OCSP_basic_verify(basic, certs, store, OCSP_TRUSTOTHER);
374  	sk_X509_pop_free(certs, X509_free);
375  	if (status <= 0) {
376  		tls_show_errors(__func__,
377  				"OpenSSL: OCSP response failed verification");
378  		OCSP_BASICRESP_free(basic);
379  		OCSP_RESPONSE_free(rsp);
380  		ctx->last_err = "OCSP response failed verification";
381  		return 0;
382  	}
383  
384  	wpa_printf(MSG_DEBUG, "OpenSSL: OCSP response verification succeeded");
385  
386  	if (!ctx->peer_cert) {
387  		wpa_printf(MSG_DEBUG, "OpenSSL: Peer certificate not available for OCSP status check");
388  		OCSP_BASICRESP_free(basic);
389  		OCSP_RESPONSE_free(rsp);
390  		ctx->last_err = "Peer certificate not available for OCSP status check";
391  		return 0;
392  	}
393  
394  	if (!ctx->peer_issuer) {
395  		wpa_printf(MSG_DEBUG, "OpenSSL: Peer issuer certificate not available for OCSP status check");
396  		OCSP_BASICRESP_free(basic);
397  		OCSP_RESPONSE_free(rsp);
398  		ctx->last_err = "Peer issuer certificate not available for OCSP status check";
399  		return 0;
400  	}
401  
402  	id = OCSP_cert_to_id(EVP_sha256(), ctx->peer_cert, ctx->peer_issuer);
403  	if (!id) {
404  		wpa_printf(MSG_DEBUG,
405  			   "OpenSSL: Could not create OCSP certificate identifier (SHA256)");
406  		OCSP_BASICRESP_free(basic);
407  		OCSP_RESPONSE_free(rsp);
408  		ctx->last_err = "Could not create OCSP certificate identifier";
409  		return 0;
410  	}
411  
412  	res = OCSP_resp_find_status(basic, id, &status, &reason, &produced_at,
413  				    &this_update, &next_update);
414  	if (!res) {
415  		id = OCSP_cert_to_id(NULL, ctx->peer_cert, ctx->peer_issuer);
416  		if (!id) {
417  			wpa_printf(MSG_DEBUG,
418  				   "OpenSSL: Could not create OCSP certificate identifier (SHA1)");
419  			OCSP_BASICRESP_free(basic);
420  			OCSP_RESPONSE_free(rsp);
421  			ctx->last_err =
422  				"Could not create OCSP certificate identifier";
423  			return 0;
424  		}
425  
426  		res = OCSP_resp_find_status(basic, id, &status, &reason,
427  					    &produced_at, &this_update,
428  					    &next_update);
429  	}
430  
431  	if (!res) {
432  		wpa_printf(MSG_INFO, "OpenSSL: Could not find current server certificate from OCSP response%s",
433  			   (ctx->ocsp == MANDATORY_OCSP) ? "" :
434  			   " (OCSP not required)");
435  		OCSP_CERTID_free(id);
436  		OCSP_BASICRESP_free(basic);
437  		OCSP_RESPONSE_free(rsp);
438  		if (ctx->ocsp == MANDATORY_OCSP)
439  
440  			ctx->last_err = "Could not find current server certificate from OCSP response";
441  		return (ctx->ocsp == MANDATORY_OCSP) ? 0 : 1;
442  	}
443  	OCSP_CERTID_free(id);
444  
445  	if (!OCSP_check_validity(this_update, next_update, 5 * 60, -1)) {
446  		tls_show_errors(__func__, "OpenSSL: OCSP status times invalid");
447  		OCSP_BASICRESP_free(basic);
448  		OCSP_RESPONSE_free(rsp);
449  		ctx->last_err = "OCSP status times invalid";
450  		return 0;
451  	}
452  
453  	OCSP_BASICRESP_free(basic);
454  	OCSP_RESPONSE_free(rsp);
455  
456  	wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status for server certificate: %s",
457  		   OCSP_cert_status_str(status));
458  
459  	if (status == V_OCSP_CERTSTATUS_GOOD)
460  		return 1;
461  	if (status == V_OCSP_CERTSTATUS_REVOKED) {
462  		ctx->last_err = "Server certificate has been revoked";
463  		return 0;
464  	}
465  	if (ctx->ocsp == MANDATORY_OCSP) {
466  		wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP required");
467  		ctx->last_err = "OCSP status unknown";
468  		return 0;
469  	}
470  	wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP was not required, so allow connection to continue");
471  	return 1;
472  }
473  
474  
475  #if OPENSSL_VERSION_NUMBER < 0x10100000L
476  static SSL_METHOD patch_ssl_method;
477  static const SSL_METHOD *real_ssl_method;
478  
curl_patch_ssl_new(SSL * s)479  static int curl_patch_ssl_new(SSL *s)
480  {
481  	SSL_CTX *ssl = SSL_get_SSL_CTX(s);
482  	int ret;
483  
484  	ssl->method = real_ssl_method;
485  	s->method = real_ssl_method;
486  
487  	ret = s->method->ssl_new(s);
488  	SSL_set_tlsext_status_type(s, TLSEXT_STATUSTYPE_ocsp);
489  
490  	return ret;
491  }
492  #endif /* OpenSSL < 1.1.0 */
493  
494  #endif /* HAVE_OCSP */
495  
496  
curl_cb_ssl(CURL * curl,void * sslctx,void * parm)497  static CURLcode curl_cb_ssl(CURL *curl, void *sslctx, void *parm)
498  {
499  	struct http_ctx *ctx = parm;
500  	SSL_CTX *ssl = sslctx;
501  
502  	wpa_printf(MSG_DEBUG, "curl_cb_ssl");
503  	SSL_CTX_set_app_data(ssl, ctx);
504  	SSL_CTX_set_verify(ssl, SSL_VERIFY_PEER, curl_cb_ssl_verify);
505  
506  #ifdef HAVE_OCSP
507  	if (ctx->ocsp != NO_OCSP) {
508  		SSL_CTX_set_tlsext_status_cb(ssl, ocsp_resp_cb);
509  		SSL_CTX_set_tlsext_status_arg(ssl, ctx);
510  
511  #if OPENSSL_VERSION_NUMBER < 0x10100000L
512  		/*
513  		 * Use a temporary SSL_METHOD to get a callback on SSL_new()
514  		 * from libcurl since there is no proper callback registration
515  		 * available for this.
516  		 */
517  		os_memset(&patch_ssl_method, 0, sizeof(patch_ssl_method));
518  		patch_ssl_method.ssl_new = curl_patch_ssl_new;
519  		real_ssl_method = ssl->method;
520  		ssl->method = &patch_ssl_method;
521  #endif /* OpenSSL < 1.1.0 */
522  	}
523  #endif /* HAVE_OCSP */
524  
525  	return CURLE_OK;
526  }
527  
528  #endif /* EAP_TLS_OPENSSL */
529  
530  
setup_curl_post(struct http_ctx * ctx,const char * address,const char * ca_fname,const char * username,const char * password,const char * client_cert,const char * client_key)531  static CURL * setup_curl_post(struct http_ctx *ctx, const char *address,
532  			      const char *ca_fname, const char *username,
533  			      const char *password, const char *client_cert,
534  			      const char *client_key)
535  {
536  	CURL *curl;
537  #ifdef EAP_TLS_OPENSSL
538  	const char *extra = " tls=openssl";
539  #else /* EAP_TLS_OPENSSL */
540  	const char *extra = "";
541  #endif /* EAP_TLS_OPENSSL */
542  
543  	wpa_printf(MSG_DEBUG, "Start HTTP client: address=%s ca_fname=%s "
544  		   "username=%s%s", address, ca_fname, username, extra);
545  
546  	curl = curl_easy_init();
547  	if (curl == NULL)
548  		return NULL;
549  
550  	curl_easy_setopt(curl, CURLOPT_URL, address);
551  	curl_easy_setopt(curl, CURLOPT_POST, 1L);
552  	if (ca_fname) {
553  		curl_easy_setopt(curl, CURLOPT_CAINFO, ca_fname);
554  		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
555  #ifdef EAP_TLS_OPENSSL
556  		curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, curl_cb_ssl);
557  		curl_easy_setopt(curl, CURLOPT_SSL_CTX_DATA, ctx);
558  #if defined(OPENSSL_IS_BORINGSSL) || (OPENSSL_VERSION_NUMBER >= 0x10100000L)
559  		/* For now, using the CURLOPT_SSL_VERIFYSTATUS option only
560  		 * with BoringSSL since the OpenSSL specific callback hack to
561  		 * enable OCSP is not available with BoringSSL. The OCSP
562  		 * implementation within libcurl is not sufficient for the
563  		 * Hotspot 2.0 OSU needs, so cannot use this with OpenSSL.
564  		 */
565  		if (ctx->ocsp != NO_OCSP)
566  			curl_easy_setopt(curl, CURLOPT_SSL_VERIFYSTATUS, 1L);
567  #endif /* OPENSSL_IS_BORINGSSL */
568  #endif /* EAP_TLS_OPENSSL */
569  	} else {
570  		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
571  	}
572  	if (client_cert && client_key) {
573  		curl_easy_setopt(curl, CURLOPT_SSLCERT, client_cert);
574  		curl_easy_setopt(curl, CURLOPT_SSLKEY, client_key);
575  	}
576  	/* TODO: use curl_easy_getinfo() with CURLINFO_CERTINFO to fetch
577  	 * information about the server certificate */
578  	curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L);
579  	curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, curl_cb_debug);
580  	curl_easy_setopt(curl, CURLOPT_DEBUGDATA, ctx);
581  	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_cb_write);
582  	curl_easy_setopt(curl, CURLOPT_WRITEDATA, ctx);
583  	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
584  	if (username) {
585  		curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);
586  		curl_easy_setopt(curl, CURLOPT_USERNAME, username);
587  		curl_easy_setopt(curl, CURLOPT_PASSWORD, password);
588  	}
589  
590  	return curl;
591  }
592  
593  
free_curl_buf(struct http_ctx * ctx)594  static void free_curl_buf(struct http_ctx *ctx)
595  {
596  	os_free(ctx->curl_buf);
597  	ctx->curl_buf = NULL;
598  	ctx->curl_buf_len = 0;
599  }
600  
601  
http_init_ctx(void * upper_ctx,struct xml_node_ctx * xml_ctx)602  struct http_ctx * http_init_ctx(void *upper_ctx, struct xml_node_ctx *xml_ctx)
603  {
604  	struct http_ctx *ctx;
605  
606  	ctx = os_zalloc(sizeof(*ctx));
607  	if (ctx == NULL)
608  		return NULL;
609  	ctx->ctx = upper_ctx;
610  	ctx->xml = xml_ctx;
611  	ctx->ocsp = OPTIONAL_OCSP;
612  
613  	curl_global_init(CURL_GLOBAL_ALL);
614  
615  	return ctx;
616  }
617  
618  
http_ocsp_set(struct http_ctx * ctx,int val)619  void http_ocsp_set(struct http_ctx *ctx, int val)
620  {
621  	if (val == 0)
622  		ctx->ocsp = NO_OCSP;
623  	else if (val == 1)
624  		ctx->ocsp = OPTIONAL_OCSP;
625  	if (val == 2)
626  		ctx->ocsp = MANDATORY_OCSP;
627  }
628  
629  
http_deinit_ctx(struct http_ctx * ctx)630  void http_deinit_ctx(struct http_ctx *ctx)
631  {
632  	clear_curl(ctx);
633  	os_free(ctx->curl_buf);
634  	curl_global_cleanup();
635  
636  	os_free(ctx->svc_address);
637  
638  	os_free(ctx);
639  }
640  
641  
http_download_file(struct http_ctx * ctx,const char * url,const char * fname,const char * ca_fname)642  int http_download_file(struct http_ctx *ctx, const char *url,
643  		       const char *fname, const char *ca_fname)
644  {
645  	CURL *curl;
646  	FILE *f = NULL;
647  	CURLcode res;
648  	long http = 0;
649  	int ret = -1;
650  
651  	ctx->last_err = NULL;
652  	ctx->url = url;
653  
654  	wpa_printf(MSG_DEBUG, "curl: Download file from %s to %s (ca=%s)",
655  		   url, fname, ca_fname);
656  	curl = curl_easy_init();
657  	if (curl == NULL)
658  		goto fail;
659  
660  	f = fopen(fname, "wb");
661  	if (!f)
662  		goto fail;
663  
664  	curl_easy_setopt(curl, CURLOPT_URL, url);
665  	if (ca_fname) {
666  		curl_easy_setopt(curl, CURLOPT_CAINFO, ca_fname);
667  		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
668  		curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L);
669  	} else {
670  		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
671  	}
672  	curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, curl_cb_debug);
673  	curl_easy_setopt(curl, CURLOPT_DEBUGDATA, ctx);
674  	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
675  	curl_easy_setopt(curl, CURLOPT_WRITEDATA, f);
676  	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
677  
678  	res = curl_easy_perform(curl);
679  	if (res != CURLE_OK) {
680  		if (!ctx->last_err)
681  			ctx->last_err = curl_easy_strerror(res);
682  		wpa_printf(MSG_ERROR, "curl_easy_perform() failed: %s",
683  			   ctx->last_err);
684  		goto fail;
685  	}
686  
687  	curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http);
688  	wpa_printf(MSG_DEBUG, "curl: Server response code %ld", http);
689  	if (http != 200) {
690  		ctx->last_err = "HTTP download failed";
691  		wpa_printf(MSG_INFO, "HTTP download failed - code %ld", http);
692  		goto fail;
693  	}
694  
695  	ret = 0;
696  
697  fail:
698  	ctx->url = NULL;
699  	if (curl)
700  		curl_easy_cleanup(curl);
701  	if (f)
702  		fclose(f);
703  
704  	return ret;
705  }
706  
707  
http_post(struct http_ctx * ctx,const char * url,const char * data,const char * content_type,const char * ext_hdr,const char * ca_fname,const char * username,const char * password,const char * client_cert,const char * client_key,size_t * resp_len)708  char * http_post(struct http_ctx *ctx, const char *url, const char *data,
709  		 const char *content_type, const char *ext_hdr,
710  		 const char *ca_fname,
711  		 const char *username, const char *password,
712  		 const char *client_cert, const char *client_key,
713  		 size_t *resp_len)
714  {
715  	long http = 0;
716  	CURLcode res;
717  	char *ret = NULL;
718  	CURL *curl;
719  	struct curl_slist *curl_hdr = NULL;
720  
721  	ctx->last_err = NULL;
722  	ctx->url = url;
723  	wpa_printf(MSG_DEBUG, "curl: HTTP POST to %s", url);
724  	curl = setup_curl_post(ctx, url, ca_fname, username, password,
725  			       client_cert, client_key);
726  	if (curl == NULL)
727  		goto fail;
728  
729  	if (content_type) {
730  		char ct[200];
731  		snprintf(ct, sizeof(ct), "Content-Type: %s", content_type);
732  		curl_hdr = curl_slist_append(curl_hdr, ct);
733  	}
734  	if (ext_hdr)
735  		curl_hdr = curl_slist_append(curl_hdr, ext_hdr);
736  	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_hdr);
737  
738  	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
739  	free_curl_buf(ctx);
740  
741  	res = curl_easy_perform(curl);
742  	if (res != CURLE_OK) {
743  		if (!ctx->last_err)
744  			ctx->last_err = curl_easy_strerror(res);
745  		wpa_printf(MSG_ERROR, "curl_easy_perform() failed: %s",
746  			   ctx->last_err);
747  		goto fail;
748  	}
749  
750  	curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http);
751  	wpa_printf(MSG_DEBUG, "curl: Server response code %ld", http);
752  	if (http != 200) {
753  		ctx->last_err = "HTTP POST failed";
754  		wpa_printf(MSG_INFO, "HTTP POST failed - code %ld", http);
755  		goto fail;
756  	}
757  
758  	if (ctx->curl_buf == NULL)
759  		goto fail;
760  
761  	ret = ctx->curl_buf;
762  	if (resp_len)
763  		*resp_len = ctx->curl_buf_len;
764  	ctx->curl_buf = NULL;
765  	ctx->curl_buf_len = 0;
766  
767  	wpa_printf(MSG_MSGDUMP, "Server response:\n%s", ret);
768  
769  fail:
770  	free_curl_buf(ctx);
771  	ctx->url = NULL;
772  	return ret;
773  }
774  
775  
http_get_err(struct http_ctx * ctx)776  const char * http_get_err(struct http_ctx *ctx)
777  {
778  	return ctx->last_err;
779  }
780