/* crypto/pem/pem_info.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 * 
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 * 
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 * 
 * 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 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 acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from 
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 * 
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS 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 AUTHOR OR 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.
 * 
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.]
 */

#include <stdio.h>
#include "cryptlib.h"
#include <openssl/buffer.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif

#ifndef OPENSSL_NO_FP_API
STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u)
	{
        BIO *b;
        STACK_OF(X509_INFO) *ret;

        if ((b=BIO_new(BIO_s_file())) == NULL)
		{
		PEMerr(PEM_F_PEM_X509_INFO_READ,ERR_R_BUF_LIB);
                return(0);
		}
        BIO_set_fp(b,fp,BIO_NOCLOSE);
        ret=PEM_X509_INFO_read_bio(b,sk,cb,u);
        BIO_free(b);
        return(ret);
	}
#endif

STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u)
	{
	X509_INFO *xi=NULL;
	char *name=NULL,*header=NULL;
	void *pp;
	unsigned char *data=NULL;
	const unsigned char *p;
	long len,error=0;
	int ok=0;
	STACK_OF(X509_INFO) *ret=NULL;
	unsigned int i,raw;
	d2i_of_void *d2i;

	if (sk == NULL)
		{
		if ((ret=sk_X509_INFO_new_null()) == NULL)
			{
			PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		}
	else
		ret=sk;

	if ((xi=X509_INFO_new()) == NULL) goto err;
	for (;;)
		{
		raw=0;
		i=PEM_read_bio(bp,&name,&header,&data,&len);
		if (i == 0)
			{
			error=ERR_GET_REASON(ERR_peek_last_error());
			if (error == PEM_R_NO_START_LINE)
				{
				ERR_clear_error();
				break;
				}
			goto err;
			}
start:
		if (	(strcmp(name,PEM_STRING_X509) == 0) ||
			(strcmp(name,PEM_STRING_X509_OLD) == 0))
			{
			d2i=(D2I_OF(void))d2i_X509;
			if (xi->x509 != NULL)
				{
				if (!sk_X509_INFO_push(ret,xi)) goto err;
				if ((xi=X509_INFO_new()) == NULL) goto err;
				goto start;
				}
			pp=&(xi->x509);
			}
		else if ((strcmp(name,PEM_STRING_X509_TRUSTED) == 0))
			{
			d2i=(D2I_OF(void))d2i_X509_AUX;
			if (xi->x509 != NULL)
				{
				if (!sk_X509_INFO_push(ret,xi)) goto err;
				if ((xi=X509_INFO_new()) == NULL) goto err;
				goto start;
				}
			pp=&(xi->x509);
			}
		else if (strcmp(name,PEM_STRING_X509_CRL) == 0)
			{
			d2i=(D2I_OF(void))d2i_X509_CRL;
			if (xi->crl != NULL)
				{
				if (!sk_X509_INFO_push(ret,xi)) goto err;
				if ((xi=X509_INFO_new()) == NULL) goto err;
				goto start;
				}
			pp=&(xi->crl);
			}
		else
#ifndef OPENSSL_NO_RSA
			if (strcmp(name,PEM_STRING_RSA) == 0)
			{
			d2i=(D2I_OF(void))d2i_RSAPrivateKey;
			if (xi->x_pkey != NULL) 
				{
				if (!sk_X509_INFO_push(ret,xi)) goto err;
				if ((xi=X509_INFO_new()) == NULL) goto err;
				goto start;
				}

			xi->enc_data=NULL;
			xi->enc_len=0;

			xi->x_pkey=X509_PKEY_new();
			if ((xi->x_pkey->dec_pkey=EVP_PKEY_new()) == NULL)
				goto err;
			xi->x_pkey->dec_pkey->type=EVP_PKEY_RSA;
			pp=&(xi->x_pkey->dec_pkey->pkey.rsa);
			if ((int)strlen(header) > 10) /* assume encrypted */
				raw=1;
			}
		else
#endif
#ifndef OPENSSL_NO_DSA
			if (strcmp(name,PEM_STRING_DSA) == 0)
			{
			d2i=(D2I_OF(void))d2i_DSAPrivateKey;
			if (xi->x_pkey != NULL) 
				{
				if (!sk_X509_INFO_push(ret,xi)) goto err;
				if ((xi=X509_INFO_new()) == NULL) goto err;
				goto start;
				}

			xi->enc_data=NULL;
			xi->enc_len=0;

			xi->x_pkey=X509_PKEY_new();
			if ((xi->x_pkey->dec_pkey=EVP_PKEY_new()) == NULL)
				goto err;
			xi->x_pkey->dec_pkey->type=EVP_PKEY_DSA;
			pp=&xi->x_pkey->dec_pkey->pkey.dsa;
			if ((int)strlen(header) > 10) /* assume encrypted */
				raw=1;
			}
		else
#endif
#ifndef OPENSSL_NO_EC
 			if (strcmp(name,PEM_STRING_ECPRIVATEKEY) == 0)
 			{
 				d2i=(D2I_OF(void))d2i_ECPrivateKey;
 				if (xi->x_pkey != NULL) 
 				{
 					if (!sk_X509_INFO_push(ret,xi)) goto err;
 					if ((xi=X509_INFO_new()) == NULL) goto err;
 						goto start;
 				}
 
 			xi->enc_data=NULL;
 			xi->enc_len=0;
 
 			xi->x_pkey=X509_PKEY_new();
 			if ((xi->x_pkey->dec_pkey=EVP_PKEY_new()) == NULL)
 				goto err;
 			xi->x_pkey->dec_pkey->type=EVP_PKEY_EC;
 			pp=&(xi->x_pkey->dec_pkey->pkey.ec);
 			if ((int)strlen(header) > 10) /* assume encrypted */
 				raw=1;
			}
		else
#endif
			{
			d2i=NULL;
			pp=NULL;
			}

		if (d2i != NULL)
			{
			if (!raw)
				{
				EVP_CIPHER_INFO cipher;

				if (!PEM_get_EVP_CIPHER_INFO(header,&cipher))
					goto err;
				if (!PEM_do_header(&cipher,data,&len,cb,u))
					goto err;
				p=data;
				if (d2i(pp,&p,len) == NULL)
					{
					PEMerr(PEM_F_PEM_X509_INFO_READ_BIO,ERR_R_ASN1_LIB);
					goto err;
					}
				}
			else
				{ /* encrypted RSA data */
				if (!PEM_get_EVP_CIPHER_INFO(header,
					&xi->enc_cipher)) goto err;
				xi->enc_data=(char *)data;
				xi->enc_len=(int)len;
				data=NULL;
				}
			}
		else	{
			/* unknown */
			}
		if (name != NULL) OPENSSL_free(name);
		if (header != NULL) OPENSSL_free(header);
		if (data != NULL) OPENSSL_free(data);
		name=NULL;
		header=NULL;
		data=NULL;
		}

	/* if the last one hasn't been pushed yet and there is anything
	 * in it then add it to the stack ... 
	 */
	if ((xi->x509 != NULL) || (xi->crl != NULL) ||
		(xi->x_pkey != NULL) || (xi->enc_data != NULL))
		{
		if (!sk_X509_INFO_push(ret,xi)) goto err;
		xi=NULL;
		}
	ok=1;
err:
	if (xi != NULL) X509_INFO_free(xi);
	if (!ok)
		{
		for (i=0; ((int)i)<sk_X509_INFO_num(ret); i++)
			{
			xi=sk_X509_INFO_value(ret,i);
			X509_INFO_free(xi);
			}
		if (ret != sk) sk_X509_INFO_free(ret);
		ret=NULL;
		}
		
	if (name != NULL) OPENSSL_free(name);
	if (header != NULL) OPENSSL_free(header);
	if (data != NULL) OPENSSL_free(data);
	return(ret);
	}


/* A TJH addition */
int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u)
	{
	EVP_CIPHER_CTX ctx;
	int i,ret=0;
	unsigned char *data=NULL;
	const char *objstr=NULL;
	char buf[PEM_BUFSIZE];
	unsigned char *iv=NULL;
	
	if (enc != NULL)
		{
		objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc));
		if (objstr == NULL)
			{
			PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER);
			goto err;
			}
		}

	/* now for the fun part ... if we have a private key then 
	 * we have to be able to handle a not-yet-decrypted key
	 * being written out correctly ... if it is decrypted or
	 * it is non-encrypted then we use the base code
	 */
	if (xi->x_pkey!=NULL)
		{
		if ( (xi->enc_data!=NULL) && (xi->enc_len>0) )
			{
			/* copy from weirdo names into more normal things */
			iv=xi->enc_cipher.iv;
			data=(unsigned char *)xi->enc_data;
			i=xi->enc_len;

			/* we take the encryption data from the
			 * internal stuff rather than what the
			 * user has passed us ... as we have to 
			 * match exactly for some strange reason
			 */
			objstr=OBJ_nid2sn(
				EVP_CIPHER_nid(xi->enc_cipher.cipher));
			if (objstr == NULL)
				{
				PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER);
				goto err;
				}

			/* create the right magic header stuff */
			OPENSSL_assert(strlen(objstr)+23+2*enc->iv_len+13 <= sizeof buf);
			buf[0]='\0';
			PEM_proc_type(buf,PEM_TYPE_ENCRYPTED);
			PEM_dek_info(buf,objstr,enc->iv_len,(char *)iv);

			/* use the normal code to write things out */
			i=PEM_write_bio(bp,PEM_STRING_RSA,buf,data,i);
			if (i <= 0) goto err;
			}
		else
			{
			/* Add DSA/DH */
#ifndef OPENSSL_NO_RSA
			/* normal optionally encrypted stuff */
			if (PEM_write_bio_RSAPrivateKey(bp,
				xi->x_pkey->dec_pkey->pkey.rsa,
				enc,kstr,klen,cb,u)<=0)
				goto err;
#endif
			}
		}

	/* if we have a certificate then write it out now */
	if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp,xi->x509) <= 0))
		goto err;

	/* we are ignoring anything else that is loaded into the X509_INFO
	 * structure for the moment ... as I don't need it so I'm not
	 * coding it here and Eric can do it when this makes it into the
	 * base library --tjh
	 */

	ret=1;

err:
	OPENSSL_cleanse((char *)&ctx,sizeof(ctx));
	OPENSSL_cleanse(buf,PEM_BUFSIZE);
	return(ret);
	}
