/*
 * 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 "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)
{
	PKCS7 *p7 = NULL;
	const unsigned char *p = pkcs7;
	STACK_OF(X509) *certs;
	int i, num, ret = -1;
	BIO *out = NULL;

	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;
	}

	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:
	PKCS7_free(p7);
	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;

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;

	num = SKM_sk_num(AttrOrOID, csrattrs->attrs);
	for (i = 0; i < num; i++) {
		AttrOrOID *ao = SKM_sk_value(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;
		}
	}
}


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;

	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_conf_nid(NULL, NULL, NID_basic_constraints,
				 "CA:FALSE");
	if (ex == NULL ||
	    !sk_X509_EXTENSION_push(exts, ex))
		goto fail;

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

	ex = X509V3_EXT_conf_nid(NULL, 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;

		X509_REQ_print(out, req);
		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;
		X509_REQ_print_fp(f, req);
		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;
	FILE *f;
	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);
	f = fopen("Cert/est-resp.raw", "w");
	if (f) {
		fwrite(resp, resp_len, 1, f);
		fclose(f);
	}

	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;
}
