/*
 * HTTP wrapper for libcurl
 * Copyright (c) 2012-2014, Qualcomm Atheros, Inc.
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"
#include <curl/curl.h>
#ifdef EAP_TLS_OPENSSL
#include <openssl/ssl.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/x509v3.h>

#ifdef SSL_set_tlsext_status_type
#ifndef OPENSSL_NO_TLSEXT
#define HAVE_OCSP
#include <openssl/err.h>
#include <openssl/ocsp.h>
#endif /* OPENSSL_NO_TLSEXT */
#endif /* SSL_set_tlsext_status_type */
#endif /* EAP_TLS_OPENSSL */

#include "common.h"
#include "xml-utils.h"
#include "http-utils.h"


struct http_ctx {
	void *ctx;
	struct xml_node_ctx *xml;
	CURL *curl;
	struct curl_slist *curl_hdr;
	char *svc_address;
	char *svc_ca_fname;
	char *svc_username;
	char *svc_password;
	char *svc_client_cert;
	char *svc_client_key;
	char *curl_buf;
	size_t curl_buf_len;

	int (*cert_cb)(void *ctx, struct http_cert *cert);
	void *cert_cb_ctx;

	enum {
		NO_OCSP, OPTIONAL_OCSP, MANDATORY_OCSP
	} ocsp;
	X509 *peer_cert;
	X509 *peer_issuer;
	X509 *peer_issuer_issuer;

	const char *last_err;
};


static void clear_curl(struct http_ctx *ctx)
{
	if (ctx->curl) {
		curl_easy_cleanup(ctx->curl);
		ctx->curl = NULL;
	}
	if (ctx->curl_hdr) {
		curl_slist_free_all(ctx->curl_hdr);
		ctx->curl_hdr = NULL;
	}
}


static void clone_str(char **dst, const char *src)
{
	os_free(*dst);
	if (src)
		*dst = os_strdup(src);
	else
		*dst = NULL;
}


static void debug_dump(struct http_ctx *ctx, const char *title,
		       const char *buf, size_t len)
{
	char *txt;
	size_t i;

	for (i = 0; i < len; i++) {
		if (buf[i] < 32 && buf[i] != '\t' && buf[i] != '\n' &&
		    buf[i] != '\r') {
			wpa_hexdump_ascii(MSG_MSGDUMP, title, buf, len);
			return;
		}
	}

	txt = os_malloc(len + 1);
	if (txt == NULL)
		return;
	os_memcpy(txt, buf, len);
	txt[len] = '\0';
	while (len > 0) {
		len--;
		if (txt[len] == '\n' || txt[len] == '\r')
			txt[len] = '\0';
		else
			break;
	}
	wpa_printf(MSG_MSGDUMP, "%s[%s]", title, txt);
	os_free(txt);
}


static int curl_cb_debug(CURL *curl, curl_infotype info, char *buf, size_t len,
			 void *userdata)
{
	struct http_ctx *ctx = userdata;
	switch (info) {
	case CURLINFO_TEXT:
		debug_dump(ctx, "CURLINFO_TEXT", buf, len);
		break;
	case CURLINFO_HEADER_IN:
		debug_dump(ctx, "CURLINFO_HEADER_IN", buf, len);
		break;
	case CURLINFO_HEADER_OUT:
		debug_dump(ctx, "CURLINFO_HEADER_OUT", buf, len);
		break;
	case CURLINFO_DATA_IN:
		debug_dump(ctx, "CURLINFO_DATA_IN", buf, len);
		break;
	case CURLINFO_DATA_OUT:
		debug_dump(ctx, "CURLINFO_DATA_OUT", buf, len);
		break;
	case CURLINFO_SSL_DATA_IN:
		wpa_printf(MSG_DEBUG, "debug - CURLINFO_SSL_DATA_IN - %d",
			   (int) len);
		break;
	case CURLINFO_SSL_DATA_OUT:
		wpa_printf(MSG_DEBUG, "debug - CURLINFO_SSL_DATA_OUT - %d",
			   (int) len);
		break;
	case CURLINFO_END:
		wpa_printf(MSG_DEBUG, "debug - CURLINFO_END - %d",
			   (int) len);
		break;
	}
	return 0;
}


static size_t curl_cb_write(void *ptr, size_t size, size_t nmemb,
			    void *userdata)
{
	struct http_ctx *ctx = userdata;
	char *n;
	n = os_realloc(ctx->curl_buf, ctx->curl_buf_len + size * nmemb + 1);
	if (n == NULL)
		return 0;
	ctx->curl_buf = n;
	os_memcpy(n + ctx->curl_buf_len, ptr, size * nmemb);
	n[ctx->curl_buf_len + size * nmemb] = '\0';
	ctx->curl_buf_len += size * nmemb;
	return size * nmemb;
}


#ifdef EAP_TLS_OPENSSL

static void debug_dump_cert(const char *title, X509 *cert)
{
	BIO *out;
	char *txt;
	size_t rlen;

	out = BIO_new(BIO_s_mem());
	if (!out)
		return;

	X509_print_ex(out, cert, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
	rlen = BIO_ctrl_pending(out);
	txt = os_malloc(rlen + 1);
	if (txt) {
		int res = BIO_read(out, txt, rlen);
		if (res > 0) {
			txt[res] = '\0';
			wpa_printf(MSG_MSGDUMP, "%s:\n%s", title, txt);
		}
		os_free(txt);
	}
	BIO_free(out);
}


static void add_alt_name_othername(struct http_ctx *ctx, struct http_cert *cert,
				   OTHERNAME *o)
{
	char txt[100];
	int res;
	struct http_othername *on;
	ASN1_TYPE *val;

	on = os_realloc_array(cert->othername, cert->num_othername + 1,
			      sizeof(struct http_othername));
	if (on == NULL)
		return;
	cert->othername = on;
	on = &on[cert->num_othername];
	os_memset(on, 0, sizeof(*on));

	res = OBJ_obj2txt(txt, sizeof(txt), o->type_id, 1);
	if (res < 0 || res >= (int) sizeof(txt))
		return;

	on->oid = os_strdup(txt);
	if (on->oid == NULL)
		return;

	val = o->value;
	on->data = val->value.octet_string->data;
	on->len = val->value.octet_string->length;

	cert->num_othername++;
}


static void add_alt_name_dns(struct http_ctx *ctx, struct http_cert *cert,
			     ASN1_STRING *name)
{
	char *buf;
	char **n;

	buf = NULL;
	if (ASN1_STRING_to_UTF8((unsigned char **) &buf, name) < 0)
		return;

	n = os_realloc_array(cert->dnsname, cert->num_dnsname + 1,
			     sizeof(char *));
	if (n == NULL)
		return;

	cert->dnsname = n;
	n[cert->num_dnsname] = buf;
	cert->num_dnsname++;
}


static void add_alt_name(struct http_ctx *ctx, struct http_cert *cert,
			 const GENERAL_NAME *name)
{
	switch (name->type) {
	case GEN_OTHERNAME:
		add_alt_name_othername(ctx, cert, name->d.otherName);
		break;
	case GEN_DNS:
		add_alt_name_dns(ctx, cert, name->d.dNSName);
		break;
	}
}


static void add_alt_names(struct http_ctx *ctx, struct http_cert *cert,
			  GENERAL_NAMES *names)
{
	int num, i;

	num = sk_GENERAL_NAME_num(names);
	for (i = 0; i < num; i++) {
		const GENERAL_NAME *name;
		name = sk_GENERAL_NAME_value(names, i);
		add_alt_name(ctx, cert, name);
	}
}


/* RFC 3709 */

typedef struct {
	X509_ALGOR *hashAlg;
	ASN1_OCTET_STRING *hashValue;
} HashAlgAndValue;

typedef struct {
	STACK_OF(HashAlgAndValue) *refStructHash;
	STACK_OF(ASN1_IA5STRING) *refStructURI;
} LogotypeReference;

typedef struct {
	ASN1_IA5STRING *mediaType;
	STACK_OF(HashAlgAndValue) *logotypeHash;
	STACK_OF(ASN1_IA5STRING) *logotypeURI;
} LogotypeDetails;

typedef struct {
	int type;
	union {
		ASN1_INTEGER *numBits;
		ASN1_INTEGER *tableSize;
	} d;
} LogotypeImageResolution;

typedef struct {
	ASN1_INTEGER *type; /* LogotypeImageType ::= INTEGER */
	ASN1_INTEGER *fileSize;
	ASN1_INTEGER *xSize;
	ASN1_INTEGER *ySize;
	LogotypeImageResolution *resolution;
	ASN1_IA5STRING *language;
} LogotypeImageInfo;

typedef struct {
	LogotypeDetails *imageDetails;
	LogotypeImageInfo *imageInfo;
} LogotypeImage;

typedef struct {
	ASN1_INTEGER *fileSize;
	ASN1_INTEGER *playTime;
	ASN1_INTEGER *channels;
	ASN1_INTEGER *sampleRate;
	ASN1_IA5STRING *language;
} LogotypeAudioInfo;

typedef struct {
	LogotypeDetails *audioDetails;
	LogotypeAudioInfo *audioInfo;
} LogotypeAudio;

typedef struct {
	STACK_OF(LogotypeImage) *image;
	STACK_OF(LogotypeAudio) *audio;
} LogotypeData;

typedef struct {
	int type;
	union {
		LogotypeData *direct;
		LogotypeReference *indirect;
	} d;
} LogotypeInfo;

typedef struct {
	ASN1_OBJECT *logotypeType;
	LogotypeInfo *info;
} OtherLogotypeInfo;

typedef struct {
	STACK_OF(LogotypeInfo) *communityLogos;
	LogotypeInfo *issuerLogo;
	LogotypeInfo *subjectLogo;
	STACK_OF(OtherLogotypeInfo) *otherLogos;
} LogotypeExtn;

ASN1_SEQUENCE(HashAlgAndValue) = {
	ASN1_SIMPLE(HashAlgAndValue, hashAlg, X509_ALGOR),
	ASN1_SIMPLE(HashAlgAndValue, hashValue, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(HashAlgAndValue);

ASN1_SEQUENCE(LogotypeReference) = {
	ASN1_SEQUENCE_OF(LogotypeReference, refStructHash, HashAlgAndValue),
	ASN1_SEQUENCE_OF(LogotypeReference, refStructURI, ASN1_IA5STRING)
} ASN1_SEQUENCE_END(LogotypeReference);

ASN1_SEQUENCE(LogotypeDetails) = {
	ASN1_SIMPLE(LogotypeDetails, mediaType, ASN1_IA5STRING),
	ASN1_SEQUENCE_OF(LogotypeDetails, logotypeHash, HashAlgAndValue),
	ASN1_SEQUENCE_OF(LogotypeDetails, logotypeURI, ASN1_IA5STRING)
} ASN1_SEQUENCE_END(LogotypeDetails);

ASN1_CHOICE(LogotypeImageResolution) = {
	ASN1_IMP(LogotypeImageResolution, d.numBits, ASN1_INTEGER, 1),
	ASN1_IMP(LogotypeImageResolution, d.tableSize, ASN1_INTEGER, 2)
} ASN1_CHOICE_END(LogotypeImageResolution);

ASN1_SEQUENCE(LogotypeImageInfo) = {
	ASN1_IMP_OPT(LogotypeImageInfo, type, ASN1_INTEGER, 0),
	ASN1_SIMPLE(LogotypeImageInfo, fileSize, ASN1_INTEGER),
	ASN1_SIMPLE(LogotypeImageInfo, xSize, ASN1_INTEGER),
	ASN1_SIMPLE(LogotypeImageInfo, ySize, ASN1_INTEGER),
	ASN1_OPT(LogotypeImageInfo, resolution, LogotypeImageResolution),
	ASN1_IMP_OPT(LogotypeImageInfo, language, ASN1_IA5STRING, 4),
} ASN1_SEQUENCE_END(LogotypeImageInfo);

ASN1_SEQUENCE(LogotypeImage) = {
	ASN1_SIMPLE(LogotypeImage, imageDetails, LogotypeDetails),
	ASN1_OPT(LogotypeImage, imageInfo, LogotypeImageInfo)
} ASN1_SEQUENCE_END(LogotypeImage);

ASN1_SEQUENCE(LogotypeAudioInfo) = {
	ASN1_SIMPLE(LogotypeAudioInfo, fileSize, ASN1_INTEGER),
	ASN1_SIMPLE(LogotypeAudioInfo, playTime, ASN1_INTEGER),
	ASN1_SIMPLE(LogotypeAudioInfo, channels, ASN1_INTEGER),
	ASN1_IMP_OPT(LogotypeAudioInfo, sampleRate, ASN1_INTEGER, 3),
	ASN1_IMP_OPT(LogotypeAudioInfo, language, ASN1_IA5STRING, 4)
} ASN1_SEQUENCE_END(LogotypeAudioInfo);

ASN1_SEQUENCE(LogotypeAudio) = {
	ASN1_SIMPLE(LogotypeAudio, audioDetails, LogotypeDetails),
	ASN1_OPT(LogotypeAudio, audioInfo, LogotypeAudioInfo)
} ASN1_SEQUENCE_END(LogotypeAudio);

ASN1_SEQUENCE(LogotypeData) = {
	ASN1_SEQUENCE_OF_OPT(LogotypeData, image, LogotypeImage),
	ASN1_IMP_SEQUENCE_OF_OPT(LogotypeData, audio, LogotypeAudio, 1)
} ASN1_SEQUENCE_END(LogotypeData);

ASN1_CHOICE(LogotypeInfo) = {
	ASN1_IMP(LogotypeInfo, d.direct, LogotypeData, 0),
	ASN1_IMP(LogotypeInfo, d.indirect, LogotypeReference, 1)
} ASN1_CHOICE_END(LogotypeInfo);

ASN1_SEQUENCE(OtherLogotypeInfo) = {
	ASN1_SIMPLE(OtherLogotypeInfo, logotypeType, ASN1_OBJECT),
	ASN1_SIMPLE(OtherLogotypeInfo, info, LogotypeInfo)
} ASN1_SEQUENCE_END(OtherLogotypeInfo);

ASN1_SEQUENCE(LogotypeExtn) = {
	ASN1_EXP_SEQUENCE_OF_OPT(LogotypeExtn, communityLogos, LogotypeInfo, 0),
	ASN1_EXP_OPT(LogotypeExtn, issuerLogo, LogotypeInfo, 1),
	ASN1_EXP_OPT(LogotypeExtn, issuerLogo, LogotypeInfo, 2),
	ASN1_EXP_SEQUENCE_OF_OPT(LogotypeExtn, otherLogos, OtherLogotypeInfo, 3)
} ASN1_SEQUENCE_END(LogotypeExtn);

IMPLEMENT_ASN1_FUNCTIONS(LogotypeExtn);

#define sk_LogotypeInfo_num(st) SKM_sk_num(LogotypeInfo, (st))
#define sk_LogotypeInfo_value(st, i) SKM_sk_value(LogotypeInfo, (st), (i))
#define sk_LogotypeImage_num(st) SKM_sk_num(LogotypeImage, (st))
#define sk_LogotypeImage_value(st, i) SKM_sk_value(LogotypeImage, (st), (i))
#define sk_LogotypeAudio_num(st) SKM_sk_num(LogotypeAudio, (st))
#define sk_LogotypeAudio_value(st, i) SKM_sk_value(LogotypeAudio, (st), (i))
#define sk_HashAlgAndValue_num(st) SKM_sk_num(HashAlgAndValue, (st))
#define sk_HashAlgAndValue_value(st, i) SKM_sk_value(HashAlgAndValue, (st), (i))
#define sk_ASN1_IA5STRING_num(st) SKM_sk_num(ASN1_IA5STRING, (st))
#define sk_ASN1_IA5STRING_value(st, i) SKM_sk_value(ASN1_IA5STRING, (st), (i))


static void add_logo(struct http_ctx *ctx, struct http_cert *hcert,
		     HashAlgAndValue *hash, ASN1_IA5STRING *uri)
{
	char txt[100];
	int res, len;
	struct http_logo *n;

	if (hash == NULL || uri == NULL)
		return;

	res = OBJ_obj2txt(txt, sizeof(txt), hash->hashAlg->algorithm, 1);
	if (res < 0 || res >= (int) sizeof(txt))
		return;

	n = os_realloc_array(hcert->logo, hcert->num_logo + 1,
			     sizeof(struct http_logo));
	if (n == NULL)
		return;
	hcert->logo = n;
	n = &hcert->logo[hcert->num_logo];
	os_memset(n, 0, sizeof(*n));

	n->alg_oid = os_strdup(txt);
	if (n->alg_oid == NULL)
		return;

	n->hash_len = ASN1_STRING_length(hash->hashValue);
	n->hash = os_malloc(n->hash_len);
	if (n->hash == NULL) {
		os_free(n->alg_oid);
		return;
	}
	os_memcpy(n->hash, ASN1_STRING_data(hash->hashValue), n->hash_len);

	len = ASN1_STRING_length(uri);
	n->uri = os_malloc(len + 1);
	if (n->uri == NULL) {
		os_free(n->alg_oid);
		os_free(n->hash);
		return;
	}
	os_memcpy(n->uri, ASN1_STRING_data(uri), len);
	n->uri[len] = '\0';

	hcert->num_logo++;
}


static void add_logo_direct(struct http_ctx *ctx, struct http_cert *hcert,
			    LogotypeData *data)
{
	int i, num;

	if (data->image == NULL)
		return;

	num = sk_LogotypeImage_num(data->image);
	for (i = 0; i < num; i++) {
		LogotypeImage *image;
		LogotypeDetails *details;
		int j, hash_num, uri_num;
		HashAlgAndValue *found_hash = NULL;

		image = sk_LogotypeImage_value(data->image, i);
		if (image == NULL)
			continue;

		details = image->imageDetails;
		if (details == NULL)
			continue;

		hash_num = sk_HashAlgAndValue_num(details->logotypeHash);
		for (j = 0; j < hash_num; j++) {
			HashAlgAndValue *hash;
			char txt[100];
			int res;
			hash = sk_HashAlgAndValue_value(details->logotypeHash,
							j);
			if (hash == NULL)
				continue;
			res = OBJ_obj2txt(txt, sizeof(txt),
					  hash->hashAlg->algorithm, 1);
			if (res < 0 || res >= (int) sizeof(txt))
				continue;
			if (os_strcmp(txt, "2.16.840.1.101.3.4.2.1") == 0) {
				found_hash = hash;
				break;
			}
		}

		if (!found_hash) {
			wpa_printf(MSG_DEBUG, "OpenSSL: No SHA256 hash found for the logo");
			continue;
		}

		uri_num = sk_ASN1_IA5STRING_num(details->logotypeURI);
		for (j = 0; j < uri_num; j++) {
			ASN1_IA5STRING *uri;
			uri = sk_ASN1_IA5STRING_value(details->logotypeURI, j);
			add_logo(ctx, hcert, found_hash, uri);
		}
	}
}


static void add_logo_indirect(struct http_ctx *ctx, struct http_cert *hcert,
			      LogotypeReference *ref)
{
	int j, hash_num, uri_num;

	hash_num = sk_HashAlgAndValue_num(ref->refStructHash);
	uri_num = sk_ASN1_IA5STRING_num(ref->refStructURI);
	if (hash_num != uri_num) {
		wpa_printf(MSG_INFO, "Unexpected LogotypeReference array size difference %d != %d",
			   hash_num, uri_num);
		return;
	}

	for (j = 0; j < hash_num; j++) {
		HashAlgAndValue *hash;
		ASN1_IA5STRING *uri;
		hash = sk_HashAlgAndValue_value(ref->refStructHash, j);
		uri = sk_ASN1_IA5STRING_value(ref->refStructURI, j);
		add_logo(ctx, hcert, hash, uri);
	}
}


static void i2r_HashAlgAndValue(HashAlgAndValue *hash, BIO *out, int indent)
{
	int i;
	const unsigned char *data;

	BIO_printf(out, "%*shashAlg: ", indent, "");
	i2a_ASN1_OBJECT(out, hash->hashAlg->algorithm);
	BIO_printf(out, "\n");

	BIO_printf(out, "%*shashValue: ", indent, "");
	data = hash->hashValue->data;
	for (i = 0; i < hash->hashValue->length; i++)
		BIO_printf(out, "%s%02x", i > 0 ? ":" : "", data[i]);
	BIO_printf(out, "\n");
}

static void i2r_LogotypeDetails(LogotypeDetails *details, BIO *out, int indent)
{
	int i, num;

	BIO_printf(out, "%*sLogotypeDetails\n", indent, "");
	if (details->mediaType) {
		BIO_printf(out, "%*smediaType: ", indent, "");
		ASN1_STRING_print(out, details->mediaType);
		BIO_printf(out, "\n");
	}

	num = details->logotypeHash ?
		sk_HashAlgAndValue_num(details->logotypeHash) : 0;
	for (i = 0; i < num; i++) {
		HashAlgAndValue *hash;
		hash = sk_HashAlgAndValue_value(details->logotypeHash, i);
		i2r_HashAlgAndValue(hash, out, indent);
	}

	num = details->logotypeURI ?
		sk_ASN1_IA5STRING_num(details->logotypeURI) : 0;
	for (i = 0; i < num; i++) {
		ASN1_IA5STRING *uri;
		uri = sk_ASN1_IA5STRING_value(details->logotypeURI, i);
		BIO_printf(out, "%*slogotypeURI: ", indent, "");
		ASN1_STRING_print(out, uri);
		BIO_printf(out, "\n");
	}
}

static void i2r_LogotypeImageInfo(LogotypeImageInfo *info, BIO *out, int indent)
{
	long val;

	BIO_printf(out, "%*sLogotypeImageInfo\n", indent, "");
	if (info->type) {
		val = ASN1_INTEGER_get(info->type);
		BIO_printf(out, "%*stype: %ld\n", indent, "", val);
	} else {
		BIO_printf(out, "%*stype: default (1)\n", indent, "");
	}
	val = ASN1_INTEGER_get(info->xSize);
	BIO_printf(out, "%*sxSize: %ld\n", indent, "", val);
	val = ASN1_INTEGER_get(info->ySize);
	BIO_printf(out, "%*sySize: %ld\n", indent, "", val);
	if (info->resolution) {
		BIO_printf(out, "%*sresolution\n", indent, "");
		/* TODO */
	}
	if (info->language) {
		BIO_printf(out, "%*slanguage: ", indent, "");
		ASN1_STRING_print(out, info->language);
		BIO_printf(out, "\n");
	}
}

static void i2r_LogotypeImage(LogotypeImage *image, BIO *out, int indent)
{
	BIO_printf(out, "%*sLogotypeImage\n", indent, "");
	if (image->imageDetails) {
		i2r_LogotypeDetails(image->imageDetails, out, indent + 4);
	}
	if (image->imageInfo) {
		i2r_LogotypeImageInfo(image->imageInfo, out, indent + 4);
	}
}

static void i2r_LogotypeData(LogotypeData *data, const char *title, BIO *out,
			     int indent)
{
	int i, num;

	BIO_printf(out, "%*s%s - LogotypeData\n", indent, "", title);

	num = data->image ? sk_LogotypeImage_num(data->image) : 0;
	for (i = 0; i < num; i++) {
		LogotypeImage *image = sk_LogotypeImage_value(data->image, i);
		i2r_LogotypeImage(image, out, indent + 4);
	}

	num = data->audio ? sk_LogotypeAudio_num(data->audio) : 0;
	for (i = 0; i < num; i++) {
		BIO_printf(out, "%*saudio: TODO\n", indent, "");
	}
}

static void i2r_LogotypeReference(LogotypeReference *ref, const char *title,
				  BIO *out, int indent)
{
	int i, hash_num, uri_num;

	BIO_printf(out, "%*s%s - LogotypeReference\n", indent, "", title);

	hash_num = ref->refStructHash ?
		sk_HashAlgAndValue_num(ref->refStructHash) : 0;
	uri_num = ref->refStructURI ?
		sk_ASN1_IA5STRING_num(ref->refStructURI) : 0;
	if (hash_num != uri_num) {
		BIO_printf(out, "%*sUnexpected LogotypeReference array size difference %d != %d\n",
			   indent, "", hash_num, uri_num);
		return;
	}

	for (i = 0; i < hash_num; i++) {
		HashAlgAndValue *hash;
		ASN1_IA5STRING *uri;

		hash = sk_HashAlgAndValue_value(ref->refStructHash, i);
		i2r_HashAlgAndValue(hash, out, indent);

		uri = sk_ASN1_IA5STRING_value(ref->refStructURI, i);
		BIO_printf(out, "%*srefStructURI: ", indent, "");
		ASN1_STRING_print(out, uri);
		BIO_printf(out, "\n");
	}
}

static void i2r_LogotypeInfo(LogotypeInfo *info, const char *title, BIO *out,
			     int indent)
{
	switch (info->type) {
	case 0:
		i2r_LogotypeData(info->d.direct, title, out, indent);
		break;
	case 1:
		i2r_LogotypeReference(info->d.indirect, title, out, indent);
		break;
	}
}

static void debug_print_logotypeext(LogotypeExtn *logo)
{
	BIO *out;
	int i, num;
	int indent = 0;

	out = BIO_new_fp(stdout, BIO_NOCLOSE);
	if (out == NULL)
		return;

	if (logo->communityLogos) {
		num = sk_LogotypeInfo_num(logo->communityLogos);
		for (i = 0; i < num; i++) {
			LogotypeInfo *info;
			info = sk_LogotypeInfo_value(logo->communityLogos, i);
			i2r_LogotypeInfo(info, "communityLogo", out, indent);
		}
	}

	if (logo->issuerLogo) {
		i2r_LogotypeInfo(logo->issuerLogo, "issuerLogo", out, indent );
	}

	if (logo->subjectLogo) {
		i2r_LogotypeInfo(logo->subjectLogo, "subjectLogo", out, indent);
	}

	if (logo->otherLogos) {
		BIO_printf(out, "%*sotherLogos - TODO\n", indent, "");
	}

	BIO_free(out);
}


static void add_logotype_ext(struct http_ctx *ctx, struct http_cert *hcert,
			     X509 *cert)
{
	ASN1_OBJECT *obj;
	int pos;
	X509_EXTENSION *ext;
	ASN1_OCTET_STRING *os;
	LogotypeExtn *logo;
	const unsigned char *data;
	int i, num;

	obj = OBJ_txt2obj("1.3.6.1.5.5.7.1.12", 0);
	if (obj == NULL)
		return;

	pos = X509_get_ext_by_OBJ(cert, obj, -1);
	if (pos < 0) {
		wpa_printf(MSG_INFO, "No logotype extension included");
		return;
	}

	wpa_printf(MSG_INFO, "Parsing logotype extension");
	ext = X509_get_ext(cert, pos);
	if (!ext) {
		wpa_printf(MSG_INFO, "Could not get logotype extension");
		return;
	}

	os = X509_EXTENSION_get_data(ext);
	if (os == NULL) {
		wpa_printf(MSG_INFO, "Could not get logotype extension data");
		return;
	}

	wpa_hexdump(MSG_DEBUG, "logotypeExtn",
		    ASN1_STRING_data(os), ASN1_STRING_length(os));

	data = ASN1_STRING_data(os);
	logo = d2i_LogotypeExtn(NULL, &data, ASN1_STRING_length(os));
	if (logo == NULL) {
		wpa_printf(MSG_INFO, "Failed to parse logotypeExtn");
		return;
	}

	if (wpa_debug_level < MSG_INFO)
		debug_print_logotypeext(logo);

	if (!logo->communityLogos) {
		wpa_printf(MSG_INFO, "No communityLogos included");
		LogotypeExtn_free(logo);
		return;
	}

	num = sk_LogotypeInfo_num(logo->communityLogos);
	for (i = 0; i < num; i++) {
		LogotypeInfo *info;
		info = sk_LogotypeInfo_value(logo->communityLogos, i);
		switch (info->type) {
		case 0:
			add_logo_direct(ctx, hcert, info->d.direct);
			break;
		case 1:
			add_logo_indirect(ctx, hcert, info->d.indirect);
			break;
		}
	}

	LogotypeExtn_free(logo);
}


static void parse_cert(struct http_ctx *ctx, struct http_cert *hcert,
		       X509 *cert, GENERAL_NAMES **names)
{
	os_memset(hcert, 0, sizeof(*hcert));

	*names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
	if (*names)
		add_alt_names(ctx, hcert, *names);

	add_logotype_ext(ctx, hcert, cert);
}


static void parse_cert_free(struct http_cert *hcert, GENERAL_NAMES *names)
{
	unsigned int i;

	for (i = 0; i < hcert->num_dnsname; i++)
		OPENSSL_free(hcert->dnsname[i]);
	os_free(hcert->dnsname);

	for (i = 0; i < hcert->num_othername; i++)
		os_free(hcert->othername[i].oid);
	os_free(hcert->othername);

	for (i = 0; i < hcert->num_logo; i++) {
		os_free(hcert->logo[i].alg_oid);
		os_free(hcert->logo[i].hash);
		os_free(hcert->logo[i].uri);
	}
	os_free(hcert->logo);

	sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
}


static int validate_server_cert(struct http_ctx *ctx, X509 *cert)
{
	GENERAL_NAMES *names;
	struct http_cert hcert;
	int ret;

	if (ctx->cert_cb == NULL) {
		wpa_printf(MSG_DEBUG, "%s: no cert_cb configured", __func__);
		return 0;
	}

	if (0) {
		BIO *out;
		out = BIO_new_fp(stdout, BIO_NOCLOSE);
		X509_print_ex(out, cert, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
		BIO_free(out);
	}

	parse_cert(ctx, &hcert, cert, &names);
	ret = ctx->cert_cb(ctx->cert_cb_ctx, &hcert);
	parse_cert_free(&hcert, names);

	return ret;
}


void http_parse_x509_certificate(struct http_ctx *ctx, const char *fname)
{
	BIO *in, *out;
	X509 *cert;
	GENERAL_NAMES *names;
	struct http_cert hcert;
	unsigned int i;

	in = BIO_new_file(fname, "r");
	if (in == NULL) {
		wpa_printf(MSG_ERROR, "Could not read '%s'", fname);
		return;
	}

	cert = d2i_X509_bio(in, NULL);
	BIO_free(in);

	if (cert == NULL) {
		wpa_printf(MSG_ERROR, "Could not parse certificate");
		return;
	}

	out = BIO_new_fp(stdout, BIO_NOCLOSE);
	if (out) {
		X509_print_ex(out, cert, XN_FLAG_COMPAT,
			      X509_FLAG_COMPAT);
		BIO_free(out);
	}

	wpa_printf(MSG_INFO, "Additional parsing information:");
	parse_cert(ctx, &hcert, cert, &names);
	for (i = 0; i < hcert.num_othername; i++) {
		if (os_strcmp(hcert.othername[i].oid,
			      "1.3.6.1.4.1.40808.1.1.1") == 0) {
			char *name = os_zalloc(hcert.othername[i].len + 1);
			if (name) {
				os_memcpy(name, hcert.othername[i].data,
					  hcert.othername[i].len);
				wpa_printf(MSG_INFO,
					   "id-wfa-hotspot-friendlyName: %s",
					   name);
				os_free(name);
			}
			wpa_hexdump_ascii(MSG_INFO,
					  "id-wfa-hotspot-friendlyName",
					  hcert.othername[i].data,
					  hcert.othername[i].len);
		} else {
			wpa_printf(MSG_INFO, "subjAltName[othername]: oid=%s",
				   hcert.othername[i].oid);
			wpa_hexdump_ascii(MSG_INFO, "unknown othername",
					  hcert.othername[i].data,
					  hcert.othername[i].len);
		}
	}
	parse_cert_free(&hcert, names);

	X509_free(cert);
}


static int curl_cb_ssl_verify(int preverify_ok, X509_STORE_CTX *x509_ctx)
{
	struct http_ctx *ctx;
	X509 *cert;
	int err, depth;
	char buf[256];
	X509_NAME *name;
	const char *err_str;
	SSL *ssl;
	SSL_CTX *ssl_ctx;

	ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
					 SSL_get_ex_data_X509_STORE_CTX_idx());
	ssl_ctx = ssl->ctx;
	ctx = SSL_CTX_get_app_data(ssl_ctx);

	wpa_printf(MSG_DEBUG, "curl_cb_ssl_verify, preverify_ok: %d",
		   preverify_ok);

	err = X509_STORE_CTX_get_error(x509_ctx);
	err_str = X509_verify_cert_error_string(err);
	depth = X509_STORE_CTX_get_error_depth(x509_ctx);
	cert = X509_STORE_CTX_get_current_cert(x509_ctx);
	if (!cert) {
		wpa_printf(MSG_INFO, "No server certificate available");
		ctx->last_err = "No server certificate available";
		return 0;
	}

	if (depth == 0)
		ctx->peer_cert = cert;
	else if (depth == 1)
		ctx->peer_issuer = cert;
	else if (depth == 2)
		ctx->peer_issuer_issuer = cert;

	name = X509_get_subject_name(cert);
	X509_NAME_oneline(name, buf, sizeof(buf));
	wpa_printf(MSG_INFO, "Server certificate chain - depth=%d err=%d (%s) subject=%s",
		   depth, err, err_str, buf);
	debug_dump_cert("Server certificate chain - certificate", cert);

	if (depth == 0 && preverify_ok && validate_server_cert(ctx, cert) < 0)
		return 0;

	if (!preverify_ok)
		ctx->last_err = "TLS validation failed";

	return preverify_ok;
}


#ifdef HAVE_OCSP

static void ocsp_debug_print_resp(OCSP_RESPONSE *rsp)
{
	BIO *out;
	size_t rlen;
	char *txt;
	int res;

	out = BIO_new(BIO_s_mem());
	if (!out)
		return;

	OCSP_RESPONSE_print(out, rsp, 0);
	rlen = BIO_ctrl_pending(out);
	txt = os_malloc(rlen + 1);
	if (!txt) {
		BIO_free(out);
		return;
	}

	res = BIO_read(out, txt, rlen);
	if (res > 0) {
		txt[res] = '\0';
		wpa_printf(MSG_MSGDUMP, "OpenSSL: OCSP Response\n%s", txt);
	}
	os_free(txt);
	BIO_free(out);
}


static void tls_show_errors(const char *func, const char *txt)
{
	unsigned long err;

	wpa_printf(MSG_DEBUG, "OpenSSL: %s - %s %s",
		   func, txt, ERR_error_string(ERR_get_error(), NULL));

	while ((err = ERR_get_error())) {
		wpa_printf(MSG_DEBUG, "OpenSSL: pending error: %s",
			   ERR_error_string(err, NULL));
	}
}


static int ocsp_resp_cb(SSL *s, void *arg)
{
	struct http_ctx *ctx = arg;
	const unsigned char *p;
	int len, status, reason;
	OCSP_RESPONSE *rsp;
	OCSP_BASICRESP *basic;
	OCSP_CERTID *id;
	ASN1_GENERALIZEDTIME *produced_at, *this_update, *next_update;
	X509_STORE *store;
	STACK_OF(X509) *certs = NULL;

	len = SSL_get_tlsext_status_ocsp_resp(s, &p);
	if (!p) {
		wpa_printf(MSG_DEBUG, "OpenSSL: No OCSP response received");
		if (ctx->ocsp == MANDATORY_OCSP)
			ctx->last_err = "No OCSP response received";
		return (ctx->ocsp == MANDATORY_OCSP) ? 0 : 1;
	}

	wpa_hexdump(MSG_DEBUG, "OpenSSL: OCSP response", p, len);

	rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
	if (!rsp) {
		wpa_printf(MSG_INFO, "OpenSSL: Failed to parse OCSP response");
		ctx->last_err = "Failed to parse OCSP response";
		return 0;
	}

	ocsp_debug_print_resp(rsp);

	status = OCSP_response_status(rsp);
	if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
		wpa_printf(MSG_INFO, "OpenSSL: OCSP responder error %d (%s)",
			   status, OCSP_response_status_str(status));
		ctx->last_err = "OCSP responder error";
		return 0;
	}

	basic = OCSP_response_get1_basic(rsp);
	if (!basic) {
		wpa_printf(MSG_INFO, "OpenSSL: Could not find BasicOCSPResponse");
		ctx->last_err = "Could not find BasicOCSPResponse";
		return 0;
	}

	store = SSL_CTX_get_cert_store(s->ctx);
	if (ctx->peer_issuer) {
		wpa_printf(MSG_DEBUG, "OpenSSL: Add issuer");
		debug_dump_cert("OpenSSL: Issuer certificate",
				ctx->peer_issuer);

		if (X509_STORE_add_cert(store, ctx->peer_issuer) != 1) {
			tls_show_errors(__func__,
					"OpenSSL: Could not add issuer to certificate store");
		}
		certs = sk_X509_new_null();
		if (certs) {
			X509 *cert;
			cert = X509_dup(ctx->peer_issuer);
			if (cert && !sk_X509_push(certs, cert)) {
				tls_show_errors(
					__func__,
					"OpenSSL: Could not add issuer to OCSP responder trust store");
				X509_free(cert);
				sk_X509_free(certs);
				certs = NULL;
			}
			if (certs && ctx->peer_issuer_issuer) {
				cert = X509_dup(ctx->peer_issuer_issuer);
				if (cert && !sk_X509_push(certs, cert)) {
					tls_show_errors(
						__func__,
						"OpenSSL: Could not add issuer's issuer to OCSP responder trust store");
					X509_free(cert);
				}
			}
		}
	}

	status = OCSP_basic_verify(basic, certs, store, OCSP_TRUSTOTHER);
	sk_X509_pop_free(certs, X509_free);
	if (status <= 0) {
		tls_show_errors(__func__,
				"OpenSSL: OCSP response failed verification");
		OCSP_BASICRESP_free(basic);
		OCSP_RESPONSE_free(rsp);
		ctx->last_err = "OCSP response failed verification";
		return 0;
	}

	wpa_printf(MSG_DEBUG, "OpenSSL: OCSP response verification succeeded");

	if (!ctx->peer_cert) {
		wpa_printf(MSG_DEBUG, "OpenSSL: Peer certificate not available for OCSP status check");
		OCSP_BASICRESP_free(basic);
		OCSP_RESPONSE_free(rsp);
		ctx->last_err = "Peer certificate not available for OCSP status check";
		return 0;
	}

	if (!ctx->peer_issuer) {
		wpa_printf(MSG_DEBUG, "OpenSSL: Peer issuer certificate not available for OCSP status check");
		OCSP_BASICRESP_free(basic);
		OCSP_RESPONSE_free(rsp);
		ctx->last_err = "Peer issuer certificate not available for OCSP status check";
		return 0;
	}

	id = OCSP_cert_to_id(NULL, ctx->peer_cert, ctx->peer_issuer);
	if (!id) {
		wpa_printf(MSG_DEBUG, "OpenSSL: Could not create OCSP certificate identifier");
		OCSP_BASICRESP_free(basic);
		OCSP_RESPONSE_free(rsp);
		ctx->last_err = "Could not create OCSP certificate identifier";
		return 0;
	}

	if (!OCSP_resp_find_status(basic, id, &status, &reason, &produced_at,
				   &this_update, &next_update)) {
		wpa_printf(MSG_INFO, "OpenSSL: Could not find current server certificate from OCSP response%s",
			   (ctx->ocsp == MANDATORY_OCSP) ? "" :
			   " (OCSP not required)");
		OCSP_BASICRESP_free(basic);
		OCSP_RESPONSE_free(rsp);
		if (ctx->ocsp == MANDATORY_OCSP)

			ctx->last_err = "Could not find current server certificate from OCSP response";
		return (ctx->ocsp == MANDATORY_OCSP) ? 0 : 1;
	}

	if (!OCSP_check_validity(this_update, next_update, 5 * 60, -1)) {
		tls_show_errors(__func__, "OpenSSL: OCSP status times invalid");
		OCSP_BASICRESP_free(basic);
		OCSP_RESPONSE_free(rsp);
		ctx->last_err = "OCSP status times invalid";
		return 0;
	}

	OCSP_BASICRESP_free(basic);
	OCSP_RESPONSE_free(rsp);

	wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status for server certificate: %s",
		   OCSP_cert_status_str(status));

	if (status == V_OCSP_CERTSTATUS_GOOD)
		return 1;
	if (status == V_OCSP_CERTSTATUS_REVOKED) {
		ctx->last_err = "Server certificate has been revoked";
		return 0;
	}
	if (ctx->ocsp == MANDATORY_OCSP) {
		wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP required");
		ctx->last_err = "OCSP status unknown";
		return 0;
	}
	wpa_printf(MSG_DEBUG, "OpenSSL: OCSP status unknown, but OCSP was not required, so allow connection to continue");
	return 1;
}


static SSL_METHOD patch_ssl_method;
static const SSL_METHOD *real_ssl_method;

static int curl_patch_ssl_new(SSL *s)
{
	SSL_CTX *ssl = s->ctx;
	int ret;

	ssl->method = real_ssl_method;
	s->method = real_ssl_method;

	ret = s->method->ssl_new(s);
	SSL_set_tlsext_status_type(s, TLSEXT_STATUSTYPE_ocsp);

	return ret;
}

#endif /* HAVE_OCSP */


static CURLcode curl_cb_ssl(CURL *curl, void *sslctx, void *parm)
{
	struct http_ctx *ctx = parm;
	SSL_CTX *ssl = sslctx;

	wpa_printf(MSG_DEBUG, "curl_cb_ssl");
	SSL_CTX_set_app_data(ssl, ctx);
	SSL_CTX_set_verify(ssl, SSL_VERIFY_PEER, curl_cb_ssl_verify);

#ifdef HAVE_OCSP
	if (ctx->ocsp != NO_OCSP) {
		SSL_CTX_set_tlsext_status_cb(ssl, ocsp_resp_cb);
		SSL_CTX_set_tlsext_status_arg(ssl, ctx);

		/*
		 * Use a temporary SSL_METHOD to get a callback on SSL_new()
		 * from libcurl since there is no proper callback registration
		 * available for this.
		 */
		os_memset(&patch_ssl_method, 0, sizeof(patch_ssl_method));
		patch_ssl_method.ssl_new = curl_patch_ssl_new;
		real_ssl_method = ssl->method;
		ssl->method = &patch_ssl_method;
	}
#endif /* HAVE_OCSP */

	return CURLE_OK;
}

#endif /* EAP_TLS_OPENSSL */


static CURL * 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)
{
	CURL *curl;
#ifdef EAP_TLS_OPENSSL
	const char *extra = " tls=openssl";
#else /* EAP_TLS_OPENSSL */
	const char *extra = "";
#endif /* EAP_TLS_OPENSSL */

	wpa_printf(MSG_DEBUG, "Start HTTP client: address=%s ca_fname=%s "
		   "username=%s%s", address, ca_fname, username, extra);

	curl = curl_easy_init();
	if (curl == NULL)
		return NULL;

	curl_easy_setopt(curl, CURLOPT_URL, address);
	curl_easy_setopt(curl, CURLOPT_POST, 1L);
	if (ca_fname) {
		curl_easy_setopt(curl, CURLOPT_CAINFO, ca_fname);
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
#ifdef EAP_TLS_OPENSSL
		curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, curl_cb_ssl);
		curl_easy_setopt(curl, CURLOPT_SSL_CTX_DATA, ctx);
#endif /* EAP_TLS_OPENSSL */
	} else {
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
	}
	if (client_cert && client_key) {
		curl_easy_setopt(curl, CURLOPT_SSLCERT, client_cert);
		curl_easy_setopt(curl, CURLOPT_SSLKEY, client_key);
	}
	/* TODO: use curl_easy_getinfo() with CURLINFO_CERTINFO to fetch
	 * information about the server certificate */
	curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L);
	curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, curl_cb_debug);
	curl_easy_setopt(curl, CURLOPT_DEBUGDATA, ctx);
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_cb_write);
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, ctx);
	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
	if (username) {
		curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE);
		curl_easy_setopt(curl, CURLOPT_USERNAME, username);
		curl_easy_setopt(curl, CURLOPT_PASSWORD, password);
	}

	return curl;
}


static int post_init_client(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)
{
	char *pos;
	int count;

	clone_str(&ctx->svc_address, address);
	clone_str(&ctx->svc_ca_fname, ca_fname);
	clone_str(&ctx->svc_username, username);
	clone_str(&ctx->svc_password, password);
	clone_str(&ctx->svc_client_cert, client_cert);
	clone_str(&ctx->svc_client_key, client_key);

	/*
	 * Workaround for Apache "Hostname 'FOO' provided via SNI and hostname
	 * 'foo' provided via HTTP are different.
	 */
	for (count = 0, pos = ctx->svc_address; count < 3 && pos && *pos;
	     pos++) {
		if (*pos == '/')
			count++;
		*pos = tolower(*pos);
	}

	ctx->curl = setup_curl_post(ctx, ctx->svc_address, ca_fname, username,
				    password, client_cert, client_key);
	if (ctx->curl == NULL)
		return -1;

	return 0;
}


int soap_init_client(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)
{
	if (post_init_client(ctx, address, ca_fname, username, password,
			     client_cert, client_key) < 0)
		return -1;

	ctx->curl_hdr = curl_slist_append(ctx->curl_hdr,
					  "Content-Type: application/soap+xml");
	ctx->curl_hdr = curl_slist_append(ctx->curl_hdr, "SOAPAction: ");
	ctx->curl_hdr = curl_slist_append(ctx->curl_hdr, "Expect:");
	curl_easy_setopt(ctx->curl, CURLOPT_HTTPHEADER, ctx->curl_hdr);

	return 0;
}


int soap_reinit_client(struct http_ctx *ctx)
{
	char *address = NULL;
	char *ca_fname = NULL;
	char *username = NULL;
	char *password = NULL;
	char *client_cert = NULL;
	char *client_key = NULL;
	int ret;

	clear_curl(ctx);

	clone_str(&address, ctx->svc_address);
	clone_str(&ca_fname, ctx->svc_ca_fname);
	clone_str(&username, ctx->svc_username);
	clone_str(&password, ctx->svc_password);
	clone_str(&client_cert, ctx->svc_client_cert);
	clone_str(&client_key, ctx->svc_client_key);

	ret = soap_init_client(ctx, address, ca_fname, username, password,
			       client_cert, client_key);
	os_free(address);
	os_free(ca_fname);
	str_clear_free(username);
	str_clear_free(password);
	os_free(client_cert);
	os_free(client_key);
	return ret;
}


static void free_curl_buf(struct http_ctx *ctx)
{
	os_free(ctx->curl_buf);
	ctx->curl_buf = NULL;
	ctx->curl_buf_len = 0;
}


xml_node_t * soap_send_receive(struct http_ctx *ctx, xml_node_t *node)
{
	char *str;
	xml_node_t *envelope, *ret, *resp, *n;
	CURLcode res;
	long http = 0;

	ctx->last_err = NULL;

	wpa_printf(MSG_DEBUG, "SOAP: Sending message");
	envelope = soap_build_envelope(ctx->xml, node);
	str = xml_node_to_str(ctx->xml, envelope);
	xml_node_free(ctx->xml, envelope);
	wpa_printf(MSG_MSGDUMP, "SOAP[%s]", str);

	curl_easy_setopt(ctx->curl, CURLOPT_POSTFIELDS, str);
	free_curl_buf(ctx);

	res = curl_easy_perform(ctx->curl);
	if (res != CURLE_OK) {
		if (!ctx->last_err)
			ctx->last_err = curl_easy_strerror(res);
		wpa_printf(MSG_ERROR, "curl_easy_perform() failed: %s",
			   ctx->last_err);
		os_free(str);
		free_curl_buf(ctx);
		return NULL;
	}
	os_free(str);

	curl_easy_getinfo(ctx->curl, CURLINFO_RESPONSE_CODE, &http);
	wpa_printf(MSG_DEBUG, "SOAP: Server response code %ld", http);
	if (http != 200) {
		ctx->last_err = "HTTP download failed";
		wpa_printf(MSG_INFO, "HTTP download failed - code %ld", http);
		free_curl_buf(ctx);
		return NULL;
	}

	if (ctx->curl_buf == NULL)
		return NULL;

	wpa_printf(MSG_MSGDUMP, "Server response:\n%s", ctx->curl_buf);
	resp = xml_node_from_buf(ctx->xml, ctx->curl_buf);
	free_curl_buf(ctx);
	if (resp == NULL) {
		wpa_printf(MSG_INFO, "Could not parse SOAP response");
		ctx->last_err = "Could not parse SOAP response";
		return NULL;
	}

	ret = soap_get_body(ctx->xml, resp);
	if (ret == NULL) {
		wpa_printf(MSG_INFO, "Could not get SOAP body");
		ctx->last_err = "Could not get SOAP body";
		return NULL;
	}

	wpa_printf(MSG_DEBUG, "SOAP body localname: '%s'",
		   xml_node_get_localname(ctx->xml, ret));
	n = xml_node_copy(ctx->xml, ret);
	xml_node_free(ctx->xml, resp);

	return n;
}


struct http_ctx * http_init_ctx(void *upper_ctx, struct xml_node_ctx *xml_ctx)
{
	struct http_ctx *ctx;

	ctx = os_zalloc(sizeof(*ctx));
	if (ctx == NULL)
		return NULL;
	ctx->ctx = upper_ctx;
	ctx->xml = xml_ctx;
	ctx->ocsp = OPTIONAL_OCSP;

	curl_global_init(CURL_GLOBAL_ALL);

	return ctx;
}


void http_ocsp_set(struct http_ctx *ctx, int val)
{
	if (val == 0)
		ctx->ocsp = NO_OCSP;
	else if (val == 1)
		ctx->ocsp = OPTIONAL_OCSP;
	if (val == 2)
		ctx->ocsp = MANDATORY_OCSP;
}


void http_deinit_ctx(struct http_ctx *ctx)
{
	clear_curl(ctx);
	os_free(ctx->curl_buf);
	curl_global_cleanup();

	os_free(ctx->svc_address);
	os_free(ctx->svc_ca_fname);
	str_clear_free(ctx->svc_username);
	str_clear_free(ctx->svc_password);
	os_free(ctx->svc_client_cert);
	os_free(ctx->svc_client_key);

	os_free(ctx);
}


int http_download_file(struct http_ctx *ctx, const char *url,
		       const char *fname, const char *ca_fname)
{
	CURL *curl;
	FILE *f;
	CURLcode res;
	long http = 0;

	ctx->last_err = NULL;

	wpa_printf(MSG_DEBUG, "curl: Download file from %s to %s (ca=%s)",
		   url, fname, ca_fname);
	curl = curl_easy_init();
	if (curl == NULL)
		return -1;

	f = fopen(fname, "wb");
	if (f == NULL) {
		curl_easy_cleanup(curl);
		return -1;
	}

	curl_easy_setopt(curl, CURLOPT_URL, url);
	if (ca_fname) {
		curl_easy_setopt(curl, CURLOPT_CAINFO, ca_fname);
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
		curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L);
	} else {
		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
	}
	curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, curl_cb_debug);
	curl_easy_setopt(curl, CURLOPT_DEBUGDATA, ctx);
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, f);
	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);

	res = curl_easy_perform(curl);
	if (res != CURLE_OK) {
		if (!ctx->last_err)
			ctx->last_err = curl_easy_strerror(res);
		wpa_printf(MSG_ERROR, "curl_easy_perform() failed: %s",
			   ctx->last_err);
		curl_easy_cleanup(curl);
		fclose(f);
		return -1;
	}

	curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http);
	wpa_printf(MSG_DEBUG, "curl: Server response code %ld", http);
	if (http != 200) {
		ctx->last_err = "HTTP download failed";
		wpa_printf(MSG_INFO, "HTTP download failed - code %ld", http);
		curl_easy_cleanup(curl);
		fclose(f);
		return -1;
	}

	curl_easy_cleanup(curl);
	fclose(f);

	return 0;
}


char * 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)
{
	long http = 0;
	CURLcode res;
	char *ret;
	CURL *curl;
	struct curl_slist *curl_hdr = NULL;

	ctx->last_err = NULL;
	wpa_printf(MSG_DEBUG, "curl: HTTP POST to %s", url);
	curl = setup_curl_post(ctx, url, ca_fname, username, password,
			       client_cert, client_key);
	if (curl == NULL)
		return NULL;

	if (content_type) {
		char ct[200];
		snprintf(ct, sizeof(ct), "Content-Type: %s", content_type);
		curl_hdr = curl_slist_append(curl_hdr, ct);
	}
	if (ext_hdr)
		curl_hdr = curl_slist_append(curl_hdr, ext_hdr);
	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_hdr);

	curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
	free_curl_buf(ctx);

	res = curl_easy_perform(curl);
	if (res != CURLE_OK) {
		if (!ctx->last_err)
			ctx->last_err = curl_easy_strerror(res);
		wpa_printf(MSG_ERROR, "curl_easy_perform() failed: %s",
			   ctx->last_err);
		free_curl_buf(ctx);
		return NULL;
	}

	curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http);
	wpa_printf(MSG_DEBUG, "curl: Server response code %ld", http);
	if (http != 200) {
		ctx->last_err = "HTTP POST failed";
		wpa_printf(MSG_INFO, "HTTP POST failed - code %ld", http);
		free_curl_buf(ctx);
		return NULL;
	}

	if (ctx->curl_buf == NULL)
		return NULL;

	ret = ctx->curl_buf;
	if (resp_len)
		*resp_len = ctx->curl_buf_len;
	ctx->curl_buf = NULL;
	ctx->curl_buf_len = 0;

	wpa_printf(MSG_MSGDUMP, "Server response:\n%s", ret);

	return ret;
}


void http_set_cert_cb(struct http_ctx *ctx,
		      int (*cb)(void *ctx, struct http_cert *cert),
		      void *cb_ctx)
{
	ctx->cert_cb = cb;
	ctx->cert_cb_ctx = cb_ctx;
}


const char * http_get_err(struct http_ctx *ctx)
{
	return ctx->last_err;
}
