/*
 * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <string.h>
#include <stdlib.h>
#include <ipxe/init.h>
#include <ipxe/dhcp.h>
#include <ipxe/settings.h>
#include <ipxe/malloc.h>
#include <ipxe/crypto.h>
#include <ipxe/asn1.h>
#include <ipxe/x509.h>
#include <ipxe/certstore.h>

/** @file
 *
 * Certificate store
 *
 */

/** Raw certificate data for all permanent stored certificates */
#undef CERT
#define CERT( _index, _path )						\
	extern char stored_cert_ ## _index ## _data[];			\
	extern char stored_cert_ ## _index ## _len[];			\
	__asm__ ( ".section \".rodata\", \"a\", " PROGBITS "\n\t"	\
		  "\nstored_cert_" #_index "_data:\n\t"			\
		  ".incbin \"" _path "\"\n\t"				\
		  "\nstored_cert_" #_index "_end:\n\t"			\
		  ".equ stored_cert_" #_index "_len, "			\
			"( stored_cert_" #_index "_end - "		\
			"  stored_cert_" #_index "_data )\n\t"		\
		  ".previous\n\t" );
CERT_ALL

/** Raw certificate cursors for all permanent stored certificates */
#undef CERT
#define CERT( _index, _path ) {						\
	.data = stored_cert_ ## _index ## _data,			\
	.len = ( size_t ) stored_cert_ ## _index ## _len, 		\
},
static struct asn1_cursor certstore_raw[] = {
	CERT_ALL
};

/** X.509 certificate structures for all permanent stored certificates */
static struct x509_certificate certstore_certs[ sizeof ( certstore_raw ) /
						sizeof ( certstore_raw[0] ) ];

/**
 * Mark stored certificate as most recently used
 *
 * @v store		Certificate store
 * @v cert		X.509 certificate
 */
static void certstore_found ( struct x509_chain *store,
			      struct x509_certificate *cert ) {

	/* Mark as most recently used */
	list_del ( &cert->store.list );
	list_add ( &cert->store.list, &store->links );
	DBGC2 ( store, "CERTSTORE found certificate %s\n",
		x509_name ( cert ) );
}

/** Certificate store */
struct x509_chain certstore = {
	.refcnt = REF_INIT ( ref_no_free ),
	.links = LIST_HEAD_INIT ( certstore.links ),
	.found = certstore_found,
};

/**
 * Add certificate to store
 *
 * @v cert		X.509 certificate
 */
void certstore_add ( struct x509_certificate *cert ) {

	/* Add certificate to store */
	cert->store.cert = cert;
	x509_get ( cert );
	list_add ( &cert->store.list, &certstore.links );
	DBGC ( &certstore, "CERTSTORE added certificate %s\n",
	       x509_name ( cert ) );
}

/**
 * Remove certificate from store
 *
 * @v cert		X.509 certificate
 */
void certstore_del ( struct x509_certificate *cert ) {

	/* Ignore attempts to remove permanent certificates */
	if ( cert->flags & X509_FL_PERMANENT )
		return;

	/* Remove certificate from store */
	DBGC ( &certstore, "CERTSTORE removed certificate %s\n",
	       x509_name ( cert ) );
	list_del ( &cert->store.list );
	x509_put ( cert );
}

/**
 * Discard a stored certificate
 *
 * @ret discarded	Number of cached items discarded
 */
static unsigned int certstore_discard ( void ) {
	struct x509_certificate *cert;

	/* Discard the least recently used certificate for which the
	 * only reference is held by the store itself.
	 */
	list_for_each_entry_reverse ( cert, &certstore.links, store.list ) {

		/* Skip certificates for which another reference is held */
		if ( cert->refcnt.count > 0 )
			continue;

		/* Skip certificates that were added at build time or
		 * added explicitly at run time.
		 */
		if ( cert->flags & ( X509_FL_PERMANENT | X509_FL_EXPLICIT ) )
			continue;

		/* Discard certificate */
		certstore_del ( cert );
		return 1;
	}

	return 0;
}

/** Certificate store cache discarder */
struct cache_discarder certstore_discarder __cache_discarder ( CACHE_NORMAL ) ={
	.discard = certstore_discard,
};

/**
 * Construct permanent certificate store
 *
 */
static void certstore_init ( void ) {
	struct asn1_cursor *raw;
	struct x509_certificate *cert;
	int i;
	int rc;

	/* Skip if we have no permanent stored certificates */
	if ( ! sizeof ( certstore_raw ) )
		return;

	/* Add certificates */
	for ( i = 0 ; i < ( int ) ( sizeof ( certstore_raw ) /
				    sizeof ( certstore_raw[0] ) ) ; i++ ) {

		/* Skip if certificate already present in store */
		raw = &certstore_raw[i];
		if ( ( cert = x509_find ( &certstore, raw ) ) != NULL ) {
			DBGC ( &certstore, "CERTSTORE permanent certificate %d "
			       "is a duplicate of %s\n", i, x509_name ( cert ));
			continue;
		}

		/* Parse certificate */
		cert = &certstore_certs[i];
		ref_init ( &cert->refcnt, ref_no_free );
		if ( ( rc = x509_parse ( cert, raw ) ) != 0 ) {
			DBGC ( &certstore, "CERTSTORE could not parse "
			       "permanent certificate %d: %s\n",
			       i, strerror ( rc ) );
			continue;
		}

		/* Add certificate to store.  Certificate will never
		 * be discarded from the store, since we retain a
		 * permanent reference to it.
		 */
		certstore_add ( cert );
		cert->flags |= X509_FL_PERMANENT;
		DBGC ( &certstore, "CERTSTORE permanent certificate %d is %s\n",
		       i, x509_name ( cert ) );
	}
}

/** Certificate store initialisation function */
struct init_fn certstore_init_fn __init_fn ( INIT_LATE ) = {
	.initialise = certstore_init,
};

/** Additional certificate setting */
static struct setting cert_setting __setting ( SETTING_CRYPTO, cert ) = {
	.name = "cert",
	.description = "Certificate",
	.tag = DHCP_EB_CERT,
	.type = &setting_type_hex,
};

/**
 * Apply certificate store configuration settings
 *
 * @ret rc		Return status code
 */
static int certstore_apply_settings ( void ) {
	static struct x509_certificate *cert = NULL;
	struct x509_certificate *old_cert;
	void *cert_data;
	int len;
	int rc;

	/* Record any existing additional certificate */
	old_cert = cert;
	cert = NULL;

	/* Add additional certificate, if any */
	if ( ( len = fetch_raw_setting_copy ( NULL, &cert_setting,
					      &cert_data ) ) >= 0 ) {
		if ( ( rc = x509_certificate ( cert_data, len, &cert ) ) == 0 ){
			DBGC ( &certstore, "CERTSTORE added additional "
			       "certificate %s\n", x509_name ( cert ) );
		} else {
			DBGC ( &certstore, "CERTSTORE could not parse "
			       "additional certificate: %s\n",
			       strerror ( rc ) );
			/* Do not fail; leave as an unusable certificate */
		}
		free ( cert_data );
	}

	/* Free old additional certificiate.  Do this after reparsing
	 * the additional certificate; in the common case that the
	 * certificate has not changed, this will allow the stored
	 * certificate to be reused.
	 */
	x509_put ( old_cert );

	return 0;
}

/** Certificate store settings applicator */
struct settings_applicator certstore_applicator __settings_applicator = {
	.apply = certstore_apply_settings,
};
