/* crypto/asn1/n_pkey.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"
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#include <openssl/objects.h>
#include <openssl/asn1t.h>
#include <openssl/asn1_mac.h>
#include <openssl/evp.h>
#include <openssl/x509.h>


#ifndef OPENSSL_NO_RC4

typedef struct netscape_pkey_st
	{
	long version;
	X509_ALGOR *algor;
	ASN1_OCTET_STRING *private_key;
	} NETSCAPE_PKEY;

typedef struct netscape_encrypted_pkey_st
	{
	ASN1_OCTET_STRING *os;
	/* This is the same structure as DigestInfo so use it:
	 * although this isn't really anything to do with
	 * digests.
	 */
	X509_SIG *enckey;
	} NETSCAPE_ENCRYPTED_PKEY;


ASN1_BROKEN_SEQUENCE(NETSCAPE_ENCRYPTED_PKEY) = {
	ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, os, ASN1_OCTET_STRING),
	ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, enckey, X509_SIG)
} ASN1_BROKEN_SEQUENCE_END(NETSCAPE_ENCRYPTED_PKEY)

DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)
DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY,NETSCAPE_ENCRYPTED_PKEY)
IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)

ASN1_SEQUENCE(NETSCAPE_PKEY) = {
	ASN1_SIMPLE(NETSCAPE_PKEY, version, LONG),
	ASN1_SIMPLE(NETSCAPE_PKEY, algor, X509_ALGOR),
	ASN1_SIMPLE(NETSCAPE_PKEY, private_key, ASN1_OCTET_STRING)
} ASN1_SEQUENCE_END(NETSCAPE_PKEY)

DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)
DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_PKEY,NETSCAPE_PKEY)
IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)

static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
			  int (*cb)(char *buf, int len, const char *prompt,
				    int verify),
			  int sgckey);

int i2d_Netscape_RSA(const RSA *a, unsigned char **pp,
		     int (*cb)(char *buf, int len, const char *prompt,
			       int verify))
{
	return i2d_RSA_NET(a, pp, cb, 0);
}

int i2d_RSA_NET(const RSA *a, unsigned char **pp,
		int (*cb)(char *buf, int len, const char *prompt, int verify),
		int sgckey)
	{
	int i, j, ret = 0;
	int rsalen, pkeylen, olen;
	NETSCAPE_PKEY *pkey = NULL;
	NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
	unsigned char buf[256],*zz;
	unsigned char key[EVP_MAX_KEY_LENGTH];
	EVP_CIPHER_CTX ctx;
	EVP_CIPHER_CTX_init(&ctx);

	if (a == NULL) return(0);

	if ((pkey=NETSCAPE_PKEY_new()) == NULL) goto err;
	if ((enckey=NETSCAPE_ENCRYPTED_PKEY_new()) == NULL) goto err;
	pkey->version = 0;

	pkey->algor->algorithm=OBJ_nid2obj(NID_rsaEncryption);
	if ((pkey->algor->parameter=ASN1_TYPE_new()) == NULL) goto err;
	pkey->algor->parameter->type=V_ASN1_NULL;

	rsalen = i2d_RSAPrivateKey(a, NULL);

	/* Fake some octet strings just for the initial length
	 * calculation.
 	 */

	pkey->private_key->length=rsalen;

	pkeylen=i2d_NETSCAPE_PKEY(pkey,NULL);

	enckey->enckey->digest->length = pkeylen;

	enckey->os->length = 11;	/* "private-key" */

	enckey->enckey->algor->algorithm=OBJ_nid2obj(NID_rc4);
	if ((enckey->enckey->algor->parameter=ASN1_TYPE_new()) == NULL) goto err;
	enckey->enckey->algor->parameter->type=V_ASN1_NULL;

	if (pp == NULL)
		{
		olen = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, NULL);
		NETSCAPE_PKEY_free(pkey);
		NETSCAPE_ENCRYPTED_PKEY_free(enckey);
		return olen;
		}


	/* Since its RC4 encrypted length is actual length */
	if ((zz=(unsigned char *)OPENSSL_malloc(rsalen)) == NULL)
		{
		ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	pkey->private_key->data = zz;
	/* Write out private key encoding */
	i2d_RSAPrivateKey(a,&zz);

	if ((zz=OPENSSL_malloc(pkeylen)) == NULL)
		{
		ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	if (!ASN1_STRING_set(enckey->os, "private-key", -1)) 
		{
		ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	enckey->enckey->digest->data = zz;
	i2d_NETSCAPE_PKEY(pkey,&zz);

	/* Wipe the private key encoding */
	OPENSSL_cleanse(pkey->private_key->data, rsalen);
		
	if (cb == NULL)
		cb=EVP_read_pw_string;
	i=cb((char *)buf,256,"Enter Private Key password:",1);
	if (i != 0)
		{
		ASN1err(ASN1_F_I2D_RSA_NET,ASN1_R_BAD_PASSWORD_READ);
		goto err;
		}
	i = strlen((char *)buf);
	/* If the key is used for SGC the algorithm is modified a little. */
	if(sgckey) {
		if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
			goto err;
		memcpy(buf + 16, "SGCKEYSALT", 10);
		i = 26;
	}

	if (!EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL))
		goto err;
	OPENSSL_cleanse(buf,256);

	/* Encrypt private key in place */
	zz = enckey->enckey->digest->data;
	if (!EVP_EncryptInit_ex(&ctx,EVP_rc4(),NULL,key,NULL))
		goto err;
	if (!EVP_EncryptUpdate(&ctx,zz,&i,zz,pkeylen))
		goto err;
	if (!EVP_EncryptFinal_ex(&ctx,zz + i,&j))
		goto err;

	ret = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, pp);
err:
	EVP_CIPHER_CTX_cleanup(&ctx);
	NETSCAPE_ENCRYPTED_PKEY_free(enckey);
	NETSCAPE_PKEY_free(pkey);
	return(ret);
	}


RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
		      int (*cb)(char *buf, int len, const char *prompt,
				int verify))
{
	return d2i_RSA_NET(a, pp, length, cb, 0);
}

RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length,
		 int (*cb)(char *buf, int len, const char *prompt, int verify),
		 int sgckey)
	{
	RSA *ret=NULL;
	const unsigned char *p;
	NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;

	p = *pp;

	enckey = d2i_NETSCAPE_ENCRYPTED_PKEY(NULL, &p, length);
	if(!enckey) {
		ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_DECODING_ERROR);
		return NULL;
	}

	if ((enckey->os->length != 11) || (strncmp("private-key",
		(char *)enckey->os->data,11) != 0))
		{
		ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_PRIVATE_KEY_HEADER_MISSING);
		NETSCAPE_ENCRYPTED_PKEY_free(enckey);
		return NULL;
		}
	if (OBJ_obj2nid(enckey->enckey->algor->algorithm) != NID_rc4)
		{
		ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM);
		goto err;
	}
	if (cb == NULL)
		cb=EVP_read_pw_string;
	if ((ret=d2i_RSA_NET_2(a, enckey->enckey->digest,cb, sgckey)) == NULL) goto err;

	*pp = p;

	err:
	NETSCAPE_ENCRYPTED_PKEY_free(enckey);
	return ret;

	}

static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
			  int (*cb)(char *buf, int len, const char *prompt,
				    int verify), int sgckey)
	{
	NETSCAPE_PKEY *pkey=NULL;
	RSA *ret=NULL;
	int i,j;
	unsigned char buf[256];
	const unsigned char *zz;
	unsigned char key[EVP_MAX_KEY_LENGTH];
	EVP_CIPHER_CTX ctx;
	EVP_CIPHER_CTX_init(&ctx);

	i=cb((char *)buf,256,"Enter Private Key password:",0);
	if (i != 0)
		{
		ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_BAD_PASSWORD_READ);
		goto err;
		}

	i = strlen((char *)buf);
	if(sgckey){
		if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
			goto err;
		memcpy(buf + 16, "SGCKEYSALT", 10);
		i = 26;
	}
		
	if (!EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL))
		goto err;
	OPENSSL_cleanse(buf,256);

	if (!EVP_DecryptInit_ex(&ctx,EVP_rc4(),NULL, key,NULL))
		goto err;
	if (!EVP_DecryptUpdate(&ctx,os->data,&i,os->data,os->length))
		goto err;
	if (!EVP_DecryptFinal_ex(&ctx,&(os->data[i]),&j))
		goto err;
	os->length=i+j;

	zz=os->data;

	if ((pkey=d2i_NETSCAPE_PKEY(NULL,&zz,os->length)) == NULL)
		{
		ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY);
		goto err;
		}
		
	zz=pkey->private_key->data;
	if ((ret=d2i_RSAPrivateKey(a,&zz,pkey->private_key->length)) == NULL)
		{
		ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_UNABLE_TO_DECODE_RSA_KEY);
		goto err;
		}
err:
	EVP_CIPHER_CTX_cleanup(&ctx);
	NETSCAPE_PKEY_free(pkey);
	return(ret);
	}

#endif /* OPENSSL_NO_RC4 */

#else /* !OPENSSL_NO_RSA */

# if PEDANTIC
static void *dummy=&dummy;
# endif

#endif
