/* 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 <openssl/pem.h>

#include <assert.h>
#include <stdio.h>
#include <string.h>

#include <openssl/buf.h>
#include <openssl/dsa.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>


#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)
		{
		OPENSSL_PUT_ERROR(PEM, 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,ptype;
	d2i_of_void *d2i = 0;

	if (sk == NULL)
		{
		if ((ret=sk_X509_INFO_new_null()) == NULL)
			{
			OPENSSL_PUT_ERROR(PEM, 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;
		ptype = 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
			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();
			ptype=EVP_PKEY_RSA;
			pp=&xi->x_pkey->dec_pkey;
			if ((int)strlen(header) > 10) /* assume encrypted */
				raw=1;
			}
		else
#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();
			ptype = EVP_PKEY_DSA;
			pp=&xi->x_pkey->dec_pkey;
			if ((int)strlen(header) > 10) /* assume encrypted */
				raw=1;
			}
		else
#endif
 			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();
			ptype = EVP_PKEY_EC;
 			pp=&xi->x_pkey->dec_pkey;
 			if ((int)strlen(header) > 10) /* assume encrypted */
 				raw=1;
			}
		else
			{
			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 (ptype)
					{
					if (!d2i_PrivateKey(ptype, pp, &p, len))
						{
						OPENSSL_PUT_ERROR(PEM, PEM_X509_INFO_read_bio, ERR_R_ASN1_LIB);
						goto err;
						}
					}
				else if (d2i(pp,&p,len) == NULL)
					{
					OPENSSL_PUT_ERROR(PEM, 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;
	unsigned iv_len = 0;
	
	if (enc != NULL)
		{
		iv_len = EVP_CIPHER_iv_length(enc);
		objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc));
		if (objstr == NULL)
			{
			OPENSSL_PUT_ERROR(PEM, 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) )
			{
			if (enc == NULL)
				{
				OPENSSL_PUT_ERROR(PEM, PEM_X509_INFO_write_bio, PEM_R_CIPHER_IS_NULL);
				goto err;
				}

			/* 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)
				{
				OPENSSL_PUT_ERROR(PEM, PEM_X509_INFO_write_bio, PEM_R_UNSUPPORTED_CIPHER);
				goto err;
				}

			/* create the right magic header stuff */
			assert(strlen(objstr)+23+2*iv_len+13 <= sizeof buf);
			buf[0]='\0';
			PEM_proc_type(buf,PEM_TYPE_ENCRYPTED);
			PEM_dek_info(buf,objstr,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 */
			/* 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;
			}
		}

	/* 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);
	}
