/* bio_ndef.c */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
 * project.
 */
/* ====================================================================
 * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    licensing@OpenSSL.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 */

#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/bio.h>
#include <openssl/err.h>

#ifndef OPENSSL_SYSNAME_NETWARE
#include <memory.h>
#endif
#include <stdio.h>

/* Experimental NDEF ASN1 BIO support routines */

/* The usage is quite simple, initialize an ASN1 structure,
 * get a BIO from it then any data written through the BIO
 * will end up translated to approptiate format on the fly.
 * The data is streamed out and does *not* need to be
 * all held in memory at once.
 *
 * When the BIO is flushed the output is finalized and any
 * signatures etc written out.
 *
 * The BIO is a 'proper' BIO and can handle non blocking I/O
 * correctly.
 *
 * The usage is simple. The implementation is *not*...
 */

/* BIO support data stored in the ASN1 BIO ex_arg */

typedef struct ndef_aux_st
	{
	/* ASN1 structure this BIO refers to */
	ASN1_VALUE *val;
	const ASN1_ITEM *it;
	/* Top of the BIO chain */
	BIO *ndef_bio;
	/* Output BIO */
	BIO *out;
	/* Boundary where content is inserted */
	unsigned char **boundary;
	/* DER buffer start */
	unsigned char *derbuf;
	} NDEF_SUPPORT;

static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);

BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
	{
	NDEF_SUPPORT *ndef_aux = NULL;
	BIO *asn_bio = NULL;
	const ASN1_AUX *aux = it->funcs;
	ASN1_STREAM_ARG sarg;

	if (!aux || !aux->asn1_cb)
		{
		ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
		return NULL;
		}
	ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
	asn_bio = BIO_new(BIO_f_asn1());

	/* ASN1 bio needs to be next to output BIO */

	out = BIO_push(asn_bio, out);

	if (!ndef_aux || !asn_bio || !out)
		goto err;

	BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
	BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);

	/* Now let callback prepend any digest, cipher etc BIOs
	 * ASN1 structure needs.
	 */

	sarg.out = out;
	sarg.ndef_bio = NULL;
	sarg.boundary = NULL;

	if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
		goto err;

	ndef_aux->val = val;
	ndef_aux->it = it;
	ndef_aux->ndef_bio = sarg.ndef_bio;
	ndef_aux->boundary = sarg.boundary;
	ndef_aux->out = out;

	BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);

	return sarg.ndef_bio;

	err:
	if (asn_bio)
		BIO_free(asn_bio);
	if (ndef_aux)
		OPENSSL_free(ndef_aux);
	return NULL;
	}

static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
	{
	NDEF_SUPPORT *ndef_aux;
	unsigned char *p;
	int derlen;

	if (!parg)
		return 0;

	ndef_aux = *(NDEF_SUPPORT **)parg;

	derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
	p = OPENSSL_malloc(derlen);
	ndef_aux->derbuf = p;
	*pbuf = p;
	derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);

	if (!*ndef_aux->boundary)
		return 0;

	*plen = *ndef_aux->boundary - *pbuf;

	return 1;
	}

static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
	{
	NDEF_SUPPORT *ndef_aux;

	if (!parg)
		return 0;

	ndef_aux = *(NDEF_SUPPORT **)parg;

	if (ndef_aux->derbuf)
		OPENSSL_free(ndef_aux->derbuf);

	ndef_aux->derbuf = NULL;
	*pbuf = NULL;
	*plen = 0;
	return 1;
	}

static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
	{
	NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
	if (!ndef_prefix_free(b, pbuf, plen, parg))
		return 0;
	OPENSSL_free(*pndef_aux);
	*pndef_aux = NULL;
	return 1;
	}

static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
	{
	NDEF_SUPPORT *ndef_aux;
	unsigned char *p;
	int derlen;
	const ASN1_AUX *aux;
	ASN1_STREAM_ARG sarg;

	if (!parg)
		return 0;

	ndef_aux = *(NDEF_SUPPORT **)parg;

	aux = ndef_aux->it->funcs;

	/* Finalize structures */
	sarg.ndef_bio = ndef_aux->ndef_bio;
	sarg.out = ndef_aux->out;
	sarg.boundary = ndef_aux->boundary;
	if (aux->asn1_cb(ASN1_OP_STREAM_POST,
				&ndef_aux->val, ndef_aux->it, &sarg) <= 0)
		return 0;

	derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
	p = OPENSSL_malloc(derlen);
	ndef_aux->derbuf = p;
	*pbuf = p;
	derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);

	if (!*ndef_aux->boundary)
		return 0;
	*pbuf = *ndef_aux->boundary;
	*plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);

	return 1;
	}
