/*
 * Hotspot 2.0 OSU client - EST client
 * 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 <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/pkcs7.h>
#include <openssl/rsa.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/opensslv.h>
#ifdef OPENSSL_IS_BORINGSSL
#include <openssl/buf.h>
#endif /* OPENSSL_IS_BORINGSSL */

#include "common.h"
#include "utils/base64.h"
#include "utils/xml-utils.h"
#include "utils/http-utils.h"
#include "osu_client.h"


static int pkcs7_to_cert(struct hs20_osu_client *ctx, const u8 *pkcs7,
			 size_t len, char *pem_file, char *der_file)
{
#ifdef OPENSSL_IS_BORINGSSL
	CBS pkcs7_cbs;
#else /* OPENSSL_IS_BORINGSSL */
	PKCS7 *p7 = NULL;
	const unsigned char *p = pkcs7;
#endif /* OPENSSL_IS_BORINGSSL */
	STACK_OF(X509) *certs;
	int i, num, ret = -1;
	BIO *out = NULL;

#ifdef OPENSSL_IS_BORINGSSL
	certs = sk_X509_new_null();
	if (!certs)
		goto fail;
	CBS_init(&pkcs7_cbs, pkcs7, len);
	if (!PKCS7_get_certificates(certs, &pkcs7_cbs)) {
		wpa_printf(MSG_INFO, "Could not parse PKCS#7 object: %s",
			   ERR_error_string(ERR_get_error(), NULL));
		write_result(ctx, "Could not parse PKCS#7 object from EST");
		goto fail;
	}
#else /* OPENSSL_IS_BORINGSSL */
	p7 = d2i_PKCS7(NULL, &p, len);
	if (p7 == NULL) {
		wpa_printf(MSG_INFO, "Could not parse PKCS#7 object: %s",
			   ERR_error_string(ERR_get_error(), NULL));
		write_result(ctx, "Could not parse PKCS#7 object from EST");
		goto fail;
	}

	switch (OBJ_obj2nid(p7->type)) {
	case NID_pkcs7_signed:
		certs = p7->d.sign->cert;
		break;
	case NID_pkcs7_signedAndEnveloped:
		certs = p7->d.signed_and_enveloped->cert;
		break;
	default:
		certs = NULL;
		break;
	}
#endif /* OPENSSL_IS_BORINGSSL */

	if (!certs || ((num = sk_X509_num(certs)) == 0)) {
		wpa_printf(MSG_INFO, "No certificates found in PKCS#7 object");
		write_result(ctx, "No certificates found in PKCS#7 object");
		goto fail;
	}

	if (der_file) {
		FILE *f = fopen(der_file, "wb");
		if (f == NULL)
			goto fail;
		i2d_X509_fp(f, sk_X509_value(certs, 0));
		fclose(f);
	}

	if (pem_file) {
		out = BIO_new(BIO_s_file());
		if (out == NULL ||
		    BIO_write_filename(out, pem_file) <= 0)
			goto fail;

		for (i = 0; i < num; i++) {
			X509 *cert = sk_X509_value(certs, i);
			X509_print(out, cert);
			PEM_write_bio_X509(out, cert);
			BIO_puts(out, "\n");
		}
	}

	ret = 0;

fail:
#ifdef OPENSSL_IS_BORINGSSL
	if (certs)
		sk_X509_pop_free(certs, X509_free);
#else /* OPENSSL_IS_BORINGSSL */
	PKCS7_free(p7);
#endif /* OPENSSL_IS_BORINGSSL */
	if (out)
		BIO_free_all(out);

	return ret;
}


int est_load_cacerts(struct hs20_osu_client *ctx, const char *url)
{
	char *buf, *resp;
	size_t buflen;
	unsigned char *pkcs7;
	size_t pkcs7_len, resp_len;
	int res;

	buflen = os_strlen(url) + 100;
	buf = os_malloc(buflen);
	if (buf == NULL)
		return -1;

	os_snprintf(buf, buflen, "%s/cacerts", url);
	wpa_printf(MSG_INFO, "Download EST cacerts from %s", buf);
	write_summary(ctx, "Download EST cacerts from %s", buf);
	ctx->no_osu_cert_validation = 1;
	http_ocsp_set(ctx->http, 1);
	res = http_download_file(ctx->http, buf, "Cert/est-cacerts.txt",
				 ctx->ca_fname);
	http_ocsp_set(ctx->http,
		      (ctx->workarounds & WORKAROUND_OCSP_OPTIONAL) ? 1 : 2);
	ctx->no_osu_cert_validation = 0;
	if (res < 0) {
		wpa_printf(MSG_INFO, "Failed to download EST cacerts from %s",
			   buf);
		write_result(ctx, "Failed to download EST cacerts from %s",
			     buf);
		os_free(buf);
		return -1;
	}
	os_free(buf);

	resp = os_readfile("Cert/est-cacerts.txt", &resp_len);
	if (resp == NULL) {
		wpa_printf(MSG_INFO, "Could not read Cert/est-cacerts.txt");
		write_result(ctx, "Could not read EST cacerts");
		return -1;
	}

	pkcs7 = base64_decode((unsigned char *) resp, resp_len, &pkcs7_len);
	if (pkcs7 && pkcs7_len < resp_len / 2) {
		wpa_printf(MSG_INFO, "Too short base64 decode (%u bytes; downloaded %u bytes) - assume this was binary",
			   (unsigned int) pkcs7_len, (unsigned int) resp_len);
		os_free(pkcs7);
		pkcs7 = NULL;
	}
	if (pkcs7 == NULL) {
		wpa_printf(MSG_INFO, "EST workaround - Could not decode base64, assume this is DER encoded PKCS7");
		pkcs7 = os_malloc(resp_len);
		if (pkcs7) {
			os_memcpy(pkcs7, resp, resp_len);
			pkcs7_len = resp_len;
		}
	}
	os_free(resp);

	if (pkcs7 == NULL) {
		wpa_printf(MSG_INFO, "Could not fetch PKCS7 cacerts");
		write_result(ctx, "Could not fetch EST PKCS#7 cacerts");
		return -1;
	}

	res = pkcs7_to_cert(ctx, pkcs7, pkcs7_len, "Cert/est-cacerts.pem",
			    NULL);
	os_free(pkcs7);
	if (res < 0) {
		wpa_printf(MSG_INFO, "Could not parse CA certs from PKCS#7 cacerts response");
		write_result(ctx, "Could not parse CA certs from EST PKCS#7 cacerts response");
		return -1;
	}
	unlink("Cert/est-cacerts.txt");

	return 0;
}


/*
 * CsrAttrs ::= SEQUENCE SIZE (0..MAX) OF AttrOrOID
 *
 * AttrOrOID ::= CHOICE {
 *   oid OBJECT IDENTIFIER,
 *   attribute Attribute }
 *
 * Attribute ::= SEQUENCE {
 *   type OBJECT IDENTIFIER,
 *   values SET SIZE(1..MAX) OF OBJECT IDENTIFIER }
 */

typedef struct {
	ASN1_OBJECT *type;
	STACK_OF(ASN1_OBJECT) *values;
} Attribute;

typedef struct {
	int type;
	union {
		ASN1_OBJECT *oid;
		Attribute *attribute;
	} d;
} AttrOrOID;

#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(OPENSSL_IS_BORINGSSL)
DEFINE_STACK_OF(AttrOrOID)
#endif

typedef struct {
	int type;
	STACK_OF(AttrOrOID) *attrs;
} CsrAttrs;

ASN1_SEQUENCE(Attribute) = {
	ASN1_SIMPLE(Attribute, type, ASN1_OBJECT),
	ASN1_SET_OF(Attribute, values, ASN1_OBJECT)
} ASN1_SEQUENCE_END(Attribute);

ASN1_CHOICE(AttrOrOID) = {
	ASN1_SIMPLE(AttrOrOID, d.oid, ASN1_OBJECT),
	ASN1_SIMPLE(AttrOrOID, d.attribute, Attribute)
} ASN1_CHOICE_END(AttrOrOID);

ASN1_CHOICE(CsrAttrs) = {
	ASN1_SEQUENCE_OF(CsrAttrs, attrs, AttrOrOID)
} ASN1_CHOICE_END(CsrAttrs);

IMPLEMENT_ASN1_FUNCTIONS(CsrAttrs);


static void add_csrattrs_oid(struct hs20_osu_client *ctx, ASN1_OBJECT *oid,
			     STACK_OF(X509_EXTENSION) *exts)
{
	char txt[100];
	int res;

	if (!oid)
		return;

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

	if (os_strcmp(txt, "1.2.840.113549.1.9.7") == 0) {
		wpa_printf(MSG_INFO, "TODO: csrattr challengePassword");
	} else if (os_strcmp(txt, "1.2.840.113549.1.1.11") == 0) {
		wpa_printf(MSG_INFO, "csrattr sha256WithRSAEncryption");
	} else {
		wpa_printf(MSG_INFO, "Ignore unsupported csrattr oid %s", txt);
	}
}


static void add_csrattrs_ext_req(struct hs20_osu_client *ctx,
				 STACK_OF(ASN1_OBJECT) *values,
				 STACK_OF(X509_EXTENSION) *exts)
{
	char txt[100];
	int i, num, res;

	num = sk_ASN1_OBJECT_num(values);
	for (i = 0; i < num; i++) {
		ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(values, i);

		res = OBJ_obj2txt(txt, sizeof(txt), oid, 1);
		if (res < 0 || res >= (int) sizeof(txt))
			continue;

		if (os_strcmp(txt, "1.3.6.1.1.1.1.22") == 0) {
			wpa_printf(MSG_INFO, "TODO: extReq macAddress");
		} else if (os_strcmp(txt, "1.3.6.1.4.1.40808.1.1.3") == 0) {
			wpa_printf(MSG_INFO, "TODO: extReq imei");
		} else if (os_strcmp(txt, "1.3.6.1.4.1.40808.1.1.4") == 0) {
			wpa_printf(MSG_INFO, "TODO: extReq meid");
		} else if (os_strcmp(txt, "1.3.6.1.4.1.40808.1.1.5") == 0) {
			wpa_printf(MSG_INFO, "TODO: extReq DevId");
		} else {
			wpa_printf(MSG_INFO, "Ignore unsupported cstattr extensionsRequest %s",
				   txt);
		}
	}
}


static void add_csrattrs_attr(struct hs20_osu_client *ctx, Attribute *attr,
			      STACK_OF(X509_EXTENSION) *exts)
{
	char txt[100], txt2[100];
	int i, num, res;

	if (!attr || !attr->type || !attr->values)
		return;

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

	if (os_strcmp(txt, "1.2.840.113549.1.9.14") == 0) {
		add_csrattrs_ext_req(ctx, attr->values, exts);
		return;
	}

	num = sk_ASN1_OBJECT_num(attr->values);
	for (i = 0; i < num; i++) {
		ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(attr->values, i);

		res = OBJ_obj2txt(txt2, sizeof(txt2), oid, 1);
		if (res < 0 || res >= (int) sizeof(txt2))
			continue;

		wpa_printf(MSG_INFO, "Ignore unsupported cstattr::attr %s oid %s",
			   txt, txt2);
	}
}


static void add_csrattrs(struct hs20_osu_client *ctx, CsrAttrs *csrattrs,
			 STACK_OF(X509_EXTENSION) *exts)
{
	int i, num;

	if (!csrattrs || ! csrattrs->attrs)
		return;

#ifdef OPENSSL_IS_BORINGSSL
	num = sk_num(CHECKED_CAST(_STACK *, STACK_OF(AttrOrOID) *,
				  csrattrs->attrs));
	for (i = 0; i < num; i++) {
		AttrOrOID *ao = sk_value(
			CHECKED_CAST(_STACK *, const STACK_OF(AttrOrOID) *,
				     csrattrs->attrs), i);
		switch (ao->type) {
		case 0:
			add_csrattrs_oid(ctx, ao->d.oid, exts);
			break;
		case 1:
			add_csrattrs_attr(ctx, ao->d.attribute, exts);
			break;
		}
	}
#else /* OPENSSL_IS_BORINGSSL */
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(OPENSSL_IS_BORINGSSL)
	num = sk_AttrOrOID_num(csrattrs->attrs);
#else
	num = SKM_sk_num(AttrOrOID, csrattrs->attrs);
#endif
	for (i = 0; i < num; i++) {
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(OPENSSL_IS_BORINGSSL)
		AttrOrOID *ao = sk_AttrOrOID_value(csrattrs->attrs, i);
#else
		AttrOrOID *ao = SKM_sk_value(AttrOrOID, csrattrs->attrs, i);
#endif
		switch (ao->type) {
		case 0:
			add_csrattrs_oid(ctx, ao->d.oid, exts);
			break;
		case 1:
			add_csrattrs_attr(ctx, ao->d.attribute, exts);
			break;
		}
	}
#endif /* OPENSSL_IS_BORINGSSL */
}


static int generate_csr(struct hs20_osu_client *ctx, char *key_pem,
			char *csr_pem, char *est_req, char *old_cert,
			CsrAttrs *csrattrs)
{
	EVP_PKEY_CTX *pctx = NULL;
	EVP_PKEY *pkey = NULL;
	RSA *rsa;
	X509_REQ *req = NULL;
	int ret = -1;
	unsigned int val;
	X509_NAME *subj = NULL;
	char name[100];
	STACK_OF(X509_EXTENSION) *exts = NULL;
	X509_EXTENSION *ex;
	BIO *out;
	CONF *ctmp = NULL;

	wpa_printf(MSG_INFO, "Generate RSA private key");
	write_summary(ctx, "Generate RSA private key");
	pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
	if (!pctx)
		return -1;

	if (EVP_PKEY_keygen_init(pctx) <= 0)
		goto fail;

	if (EVP_PKEY_CTX_set_rsa_keygen_bits(pctx, 2048) <= 0)
		goto fail;

	if (EVP_PKEY_keygen(pctx, &pkey) <= 0)
		goto fail;
	EVP_PKEY_CTX_free(pctx);
	pctx = NULL;

	rsa = EVP_PKEY_get1_RSA(pkey);
	if (rsa == NULL)
		goto fail;

	if (key_pem) {
		FILE *f = fopen(key_pem, "wb");
		if (f == NULL)
			goto fail;
		if (!PEM_write_RSAPrivateKey(f, rsa, NULL, NULL, 0, NULL,
					     NULL)) {
			wpa_printf(MSG_INFO, "Could not write private key: %s",
				   ERR_error_string(ERR_get_error(), NULL));
			fclose(f);
			goto fail;
		}
		fclose(f);
	}

	wpa_printf(MSG_INFO, "Generate CSR");
	write_summary(ctx, "Generate CSR");
	req = X509_REQ_new();
	if (req == NULL)
		goto fail;

	if (old_cert) {
		FILE *f;
		X509 *cert;
		int res;

		f = fopen(old_cert, "r");
		if (f == NULL)
			goto fail;
		cert = PEM_read_X509(f, NULL, NULL, NULL);
		fclose(f);

		if (cert == NULL)
			goto fail;
		res = X509_REQ_set_subject_name(req,
						X509_get_subject_name(cert));
		X509_free(cert);
		if (!res)
			goto fail;
	} else {
		os_get_random((u8 *) &val, sizeof(val));
		os_snprintf(name, sizeof(name), "cert-user-%u", val);
		subj = X509_NAME_new();
		if (subj == NULL ||
		    !X509_NAME_add_entry_by_txt(subj, "CN", MBSTRING_ASC,
						(unsigned char *) name,
						-1, -1, 0) ||
		    !X509_REQ_set_subject_name(req, subj))
			goto fail;
		X509_NAME_free(subj);
		subj = NULL;
	}

	if (!X509_REQ_set_pubkey(req, pkey))
		goto fail;

	exts = sk_X509_EXTENSION_new_null();
	if (!exts)
		goto fail;

	ex = X509V3_EXT_nconf_nid(ctmp, NULL, NID_basic_constraints,
				  "CA:FALSE");
	if (ex == NULL ||
	    !sk_X509_EXTENSION_push(exts, ex))
		goto fail;

	ex = X509V3_EXT_nconf_nid(ctmp, NULL, NID_key_usage,
				  "nonRepudiation,digitalSignature,keyEncipherment");
	if (ex == NULL ||
	    !sk_X509_EXTENSION_push(exts, ex))
		goto fail;

	ex = X509V3_EXT_nconf_nid(ctmp, NULL, NID_ext_key_usage,
				  "1.3.6.1.4.1.40808.1.1.2");
	if (ex == NULL ||
	    !sk_X509_EXTENSION_push(exts, ex))
		goto fail;

	add_csrattrs(ctx, csrattrs, exts);

	if (!X509_REQ_add_extensions(req, exts))
		goto fail;
	sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
	exts = NULL;

	if (!X509_REQ_sign(req, pkey, EVP_sha256()))
		goto fail;

	out = BIO_new(BIO_s_mem());
	if (out) {
		char *txt;
		size_t rlen;

#if !defined(ANDROID) || !defined(OPENSSL_IS_BORINGSSL)
		X509_REQ_print(out, req);
#endif
		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, "OpenSSL: Certificate request:\n%s",
					   txt);
			}
			os_free(txt);
		}
		BIO_free(out);
	}

	if (csr_pem) {
		FILE *f = fopen(csr_pem, "w");
		if (f == NULL)
			goto fail;
#if !defined(ANDROID) || !defined(OPENSSL_IS_BORINGSSL)
		X509_REQ_print_fp(f, req);
#endif
		if (!PEM_write_X509_REQ(f, req)) {
			fclose(f);
			goto fail;
		}
		fclose(f);
	}

	if (est_req) {
		BIO *mem = BIO_new(BIO_s_mem());
		BUF_MEM *ptr;
		char *pos, *end, *buf_end;
		FILE *f;

		if (mem == NULL)
			goto fail;
		if (!PEM_write_bio_X509_REQ(mem, req)) {
			BIO_free(mem);
			goto fail;
		}

		BIO_get_mem_ptr(mem, &ptr);
		pos = ptr->data;
		buf_end = pos + ptr->length;

		/* Remove START/END lines */
		while (pos < buf_end && *pos != '\n')
			pos++;
		if (pos == buf_end) {
			BIO_free(mem);
			goto fail;
		}
		pos++;

		end = pos;
		while (end < buf_end && *end != '-')
			end++;

		f = fopen(est_req, "w");
		if (f == NULL) {
			BIO_free(mem);
			goto fail;
		}
		fwrite(pos, end - pos, 1, f);
		fclose(f);

		BIO_free(mem);
	}

	ret = 0;
fail:
	if (exts)
		sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
	if (subj)
		X509_NAME_free(subj);
	if (req)
		X509_REQ_free(req);
	if (pkey)
		EVP_PKEY_free(pkey);
	if (pctx)
		EVP_PKEY_CTX_free(pctx);
	return ret;
}


int est_build_csr(struct hs20_osu_client *ctx, const char *url)
{
	char *buf;
	size_t buflen;
	int res;
	char old_cert_buf[200];
	char *old_cert = NULL;
	CsrAttrs *csrattrs = NULL;

	buflen = os_strlen(url) + 100;
	buf = os_malloc(buflen);
	if (buf == NULL)
		return -1;

	os_snprintf(buf, buflen, "%s/csrattrs", url);
	wpa_printf(MSG_INFO, "Download csrattrs from %s", buf);
	write_summary(ctx, "Download EST csrattrs from %s", buf);
	ctx->no_osu_cert_validation = 1;
	http_ocsp_set(ctx->http, 1);
	res = http_download_file(ctx->http, buf, "Cert/est-csrattrs.txt",
				 ctx->ca_fname);
	http_ocsp_set(ctx->http,
		      (ctx->workarounds & WORKAROUND_OCSP_OPTIONAL) ? 1 : 2);
	ctx->no_osu_cert_validation = 0;
	os_free(buf);
	if (res < 0) {
		wpa_printf(MSG_INFO, "Failed to download EST csrattrs - assume no extra attributes are needed");
	} else {
		size_t resp_len;
		char *resp;
		unsigned char *attrs;
		const unsigned char *pos;
		size_t attrs_len;

		resp = os_readfile("Cert/est-csrattrs.txt", &resp_len);
		if (resp == NULL) {
			wpa_printf(MSG_INFO, "Could not read csrattrs");
			return -1;
		}

		attrs = base64_decode((unsigned char *) resp, resp_len,
				      &attrs_len);
		os_free(resp);

		if (attrs == NULL) {
			wpa_printf(MSG_INFO, "Could not base64 decode csrattrs");
			return -1;
		}
		unlink("Cert/est-csrattrs.txt");

		pos = attrs;
		csrattrs = d2i_CsrAttrs(NULL, &pos, attrs_len);
		os_free(attrs);
		if (csrattrs == NULL) {
			wpa_printf(MSG_INFO, "Failed to parse csrattrs ASN.1");
			/* Continue assuming no additional requirements */
		}
	}

	if (ctx->client_cert_present) {
		os_snprintf(old_cert_buf, sizeof(old_cert_buf),
			    "SP/%s/client-cert.pem", ctx->fqdn);
		old_cert = old_cert_buf;
	}

	res = generate_csr(ctx, "Cert/privkey-plain.pem", "Cert/est-req.pem",
			   "Cert/est-req.b64", old_cert, csrattrs);
	if (csrattrs)
		CsrAttrs_free(csrattrs);

	return res;
}


int est_simple_enroll(struct hs20_osu_client *ctx, const char *url,
		      const char *user, const char *pw)
{
	char *buf, *resp, *req, *req2;
	size_t buflen, resp_len, len, pkcs7_len;
	unsigned char *pkcs7;
	char client_cert_buf[200];
	char client_key_buf[200];
	const char *client_cert = NULL, *client_key = NULL;
	int res;

	req = os_readfile("Cert/est-req.b64", &len);
	if (req == NULL) {
		wpa_printf(MSG_INFO, "Could not read Cert/req.b64");
		return -1;
	}
	req2 = os_realloc(req, len + 1);
	if (req2 == NULL) {
		os_free(req);
		return -1;
	}
	req2[len] = '\0';
	req = req2;
	wpa_printf(MSG_DEBUG, "EST simpleenroll request: %s", req);

	buflen = os_strlen(url) + 100;
	buf = os_malloc(buflen);
	if (buf == NULL) {
		os_free(req);
		return -1;
	}

	if (ctx->client_cert_present) {
		os_snprintf(buf, buflen, "%s/simplereenroll", url);
		os_snprintf(client_cert_buf, sizeof(client_cert_buf),
			    "SP/%s/client-cert.pem", ctx->fqdn);
		client_cert = client_cert_buf;
		os_snprintf(client_key_buf, sizeof(client_key_buf),
			    "SP/%s/client-key.pem", ctx->fqdn);
		client_key = client_key_buf;
	} else
		os_snprintf(buf, buflen, "%s/simpleenroll", url);
	wpa_printf(MSG_INFO, "EST simpleenroll URL: %s", buf);
	write_summary(ctx, "EST simpleenroll URL: %s", buf);
	ctx->no_osu_cert_validation = 1;
	http_ocsp_set(ctx->http, 1);
	resp = http_post(ctx->http, buf, req, "application/pkcs10",
			 "Content-Transfer-Encoding: base64",
			 ctx->ca_fname, user, pw, client_cert, client_key,
			 &resp_len);
	http_ocsp_set(ctx->http,
		      (ctx->workarounds & WORKAROUND_OCSP_OPTIONAL) ? 1 : 2);
	ctx->no_osu_cert_validation = 0;
	os_free(buf);
	if (resp == NULL) {
		wpa_printf(MSG_INFO, "EST certificate enrollment failed");
		write_result(ctx, "EST certificate enrollment failed");
		return -1;
	}
	wpa_printf(MSG_DEBUG, "EST simpleenroll response: %s", resp);

	pkcs7 = base64_decode((unsigned char *) resp, resp_len, &pkcs7_len);
	if (pkcs7 == NULL) {
		wpa_printf(MSG_INFO, "EST workaround - Could not decode base64, assume this is DER encoded PKCS7");
		pkcs7 = os_malloc(resp_len);
		if (pkcs7) {
			os_memcpy(pkcs7, resp, resp_len);
			pkcs7_len = resp_len;
		}
	}
	os_free(resp);

	if (pkcs7 == NULL) {
		wpa_printf(MSG_INFO, "Failed to parse simpleenroll base64 response");
		write_result(ctx, "Failed to parse EST simpleenroll base64 response");
		return -1;
	}

	res = pkcs7_to_cert(ctx, pkcs7, pkcs7_len, "Cert/est_cert.pem",
			    "Cert/est_cert.der");
	os_free(pkcs7);

	if (res < 0) {
		wpa_printf(MSG_INFO, "EST: Failed to extract certificate from PKCS7 file");
		write_result(ctx, "EST: Failed to extract certificate from EST PKCS7 file");
		return -1;
	}

	wpa_printf(MSG_INFO, "EST simple%senroll completed successfully",
		   ctx->client_cert_present ? "re" : "");
	write_summary(ctx, "EST simple%senroll completed successfully",
		      ctx->client_cert_present ? "re" : "");

	return 0;
}
