/*
 *
 * authfile.c
 *
 * Author: Tatu Ylonen <ylo@cs.hut.fi>
 *
 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 *                    All rights reserved
 *
 * Created: Mon Mar 27 03:52:05 1995 ylo
 *
 * This file contains functions for reading and writing identity files, and
 * for reading the passphrase from the user.
 *
 */

#include "includes.h"
RCSID("$Id: authfile.c,v 1.12 2000/04/29 13:57:10 damien Exp $");

#include <openssl/bn.h>
#include <openssl/dsa.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/evp.h>

#include "xmalloc.h"
#include "buffer.h"
#include "bufaux.h"
#include "cipher.h"
#include "ssh.h"
#include "key.h"

/* Version identification string for identity files. */
#define AUTHFILE_ID_STRING "SSH PRIVATE KEY FILE FORMAT 1.1\n"

/*
 * Saves the authentication (private) key in a file, encrypting it with
 * passphrase.  The identification of the file (lowest 64 bits of n) will
 * precede the key to provide identification of the key without needing a
 * passphrase.
 */

int
save_private_key_rsa(const char *filename, const char *passphrase,
    RSA *key, const char *comment)
{
	Buffer buffer, encrypted;
	char buf[100], *cp;
	int fd, i;
	CipherContext cipher;
	int cipher_type;
	u_int32_t rand;

	/*
	 * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting
	 * to another cipher; otherwise use SSH_AUTHFILE_CIPHER.
	 */
	if (strcmp(passphrase, "") == 0)
		cipher_type = SSH_CIPHER_NONE;
	else
		cipher_type = SSH_AUTHFILE_CIPHER;

	/* This buffer is used to built the secret part of the private key. */
	buffer_init(&buffer);

	/* Put checkbytes for checking passphrase validity. */
	rand = arc4random();
	buf[0] = rand & 0xff;
	buf[1] = (rand >> 8) & 0xff;
	buf[2] = buf[0];
	buf[3] = buf[1];
	buffer_append(&buffer, buf, 4);

	/*
	 * Store the private key (n and e will not be stored because they
	 * will be stored in plain text, and storing them also in encrypted
	 * format would just give known plaintext).
	 */
	buffer_put_bignum(&buffer, key->d);
	buffer_put_bignum(&buffer, key->iqmp);
	buffer_put_bignum(&buffer, key->q);	/* reverse from SSL p */
	buffer_put_bignum(&buffer, key->p);	/* reverse from SSL q */

	/* Pad the part to be encrypted until its size is a multiple of 8. */
	while (buffer_len(&buffer) % 8 != 0)
		buffer_put_char(&buffer, 0);

	/* This buffer will be used to contain the data in the file. */
	buffer_init(&encrypted);

	/* First store keyfile id string. */
	cp = AUTHFILE_ID_STRING;
	for (i = 0; cp[i]; i++)
		buffer_put_char(&encrypted, cp[i]);
	buffer_put_char(&encrypted, 0);

	/* Store cipher type. */
	buffer_put_char(&encrypted, cipher_type);
	buffer_put_int(&encrypted, 0);	/* For future extension */

	/* Store public key.  This will be in plain text. */
	buffer_put_int(&encrypted, BN_num_bits(key->n));
	buffer_put_bignum(&encrypted, key->n);
	buffer_put_bignum(&encrypted, key->e);
	buffer_put_string(&encrypted, comment, strlen(comment));

	/* Allocate space for the private part of the key in the buffer. */
	buffer_append_space(&encrypted, &cp, buffer_len(&buffer));

	cipher_set_key_string(&cipher, cipher_type, passphrase);
	cipher_encrypt(&cipher, (unsigned char *) cp,
		       (unsigned char *) buffer_ptr(&buffer),
		       buffer_len(&buffer));
	memset(&cipher, 0, sizeof(cipher));

	/* Destroy temporary data. */
	memset(buf, 0, sizeof(buf));
	buffer_free(&buffer);

	fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
	if (fd < 0)
		return 0;
	if (write(fd, buffer_ptr(&encrypted), buffer_len(&encrypted)) !=
	    buffer_len(&encrypted)) {
		debug("Write to key file %.200s failed: %.100s", filename,
		      strerror(errno));
		buffer_free(&encrypted);
		close(fd);
		remove(filename);
		return 0;
	}
	close(fd);
	buffer_free(&encrypted);
	return 1;
}

/* save DSA key in OpenSSL PEM format */

int
save_private_key_dsa(const char *filename, const char *passphrase,
    DSA *dsa, const char *comment)
{
	FILE *fp;
	int fd;
	int success = 1;
	int len = strlen(passphrase);

	if (len > 0 && len <= 4) {
		error("passphrase too short: %d bytes", len);
		errno = 0;
		return 0;
	}
	fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
	if (fd < 0) {
		debug("open %s failed", filename);
		return 0;
	}
	fp = fdopen(fd, "w");
	if (fp == NULL ) {
		debug("fdopen %s failed", filename);
		close(fd);
		return 0;
	}
	if (len > 0) {
		if (!PEM_write_DSAPrivateKey(fp, dsa, EVP_des_ede3_cbc(),
		    (char *)passphrase, strlen(passphrase), NULL, NULL))
			success = 0;
	} else {
		if (!PEM_write_DSAPrivateKey(fp, dsa, NULL,
		    NULL, 0, NULL, NULL))
			success = 0;
	}
	fclose(fp);
	return success;
}

int
save_private_key(const char *filename, const char *passphrase, Key *key,
    const char *comment)
{
	switch (key->type) {
	case KEY_RSA:
		return save_private_key_rsa(filename, passphrase, key->rsa, comment);
		break;
	case KEY_DSA:
		return save_private_key_dsa(filename, passphrase, key->dsa, comment);
		break;
	default:
		break;
	}
	return 0;
}

/*
 * Loads the public part of the key file.  Returns 0 if an error was
 * encountered (the file does not exist or is not readable), and non-zero
 * otherwise.
 */

int
load_public_key_rsa(const char *filename, RSA * pub, char **comment_return)
{
	int fd, i;
	off_t len;
	Buffer buffer;
	char *cp;

	fd = open(filename, O_RDONLY);
	if (fd < 0)
		return 0;
	len = lseek(fd, (off_t) 0, SEEK_END);
	lseek(fd, (off_t) 0, SEEK_SET);

	buffer_init(&buffer);
	buffer_append_space(&buffer, &cp, len);

	if (read(fd, cp, (size_t) len) != (size_t) len) {
		debug("Read from key file %.200s failed: %.100s", filename,
		    strerror(errno));
		buffer_free(&buffer);
		close(fd);
		return 0;
	}
	close(fd);

	/* Check that it is at least big enought to contain the ID string. */
	if (len < strlen(AUTHFILE_ID_STRING) + 1) {
		debug("Bad key file %.200s.", filename);
		buffer_free(&buffer);
		return 0;
	}
	/*
	 * Make sure it begins with the id string.  Consume the id string
	 * from the buffer.
	 */
	for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++)
		if (buffer_get_char(&buffer) != (u_char) AUTHFILE_ID_STRING[i]) {
			debug("Bad key file %.200s.", filename);
			buffer_free(&buffer);
			return 0;
		}
	/* Skip cipher type and reserved data. */
	(void) buffer_get_char(&buffer);	/* cipher type */
	(void) buffer_get_int(&buffer);		/* reserved */

	/* Read the public key from the buffer. */
	buffer_get_int(&buffer);
	/* XXX alloc */
	if (pub->n == NULL)
		pub->n = BN_new();
	buffer_get_bignum(&buffer, pub->n);
	/* XXX alloc */
	if (pub->e == NULL)
		pub->e = BN_new();
	buffer_get_bignum(&buffer, pub->e);
	if (comment_return)
		*comment_return = buffer_get_string(&buffer, NULL);
	/* The encrypted private part is not parsed by this function. */

	buffer_free(&buffer);

	return 1;
}

int
load_public_key(const char *filename, Key * key, char **comment_return)
{
	switch (key->type) {
	case KEY_RSA:
		return load_public_key_rsa(filename, key->rsa, comment_return);
		break;
	case KEY_DSA:
	default:
		break;
	}
	return 0;
}

/*
 * Loads the private key from the file.  Returns 0 if an error is encountered
 * (file does not exist or is not readable, or passphrase is bad). This
 * initializes the private key.
 * Assumes we are called under uid of the owner of the file.
 */

int
load_private_key_rsa(int fd, const char *filename,
    const char *passphrase, RSA * prv, char **comment_return)
{
	int i, check1, check2, cipher_type;
	off_t len;
	Buffer buffer, decrypted;
	char *cp;
	CipherContext cipher;
	BN_CTX *ctx;
	BIGNUM *aux;

	len = lseek(fd, (off_t) 0, SEEK_END);
	lseek(fd, (off_t) 0, SEEK_SET);

	buffer_init(&buffer);
	buffer_append_space(&buffer, &cp, len);

	if (read(fd, cp, (size_t) len) != (size_t) len) {
		debug("Read from key file %.200s failed: %.100s", filename,
		      strerror(errno));
		buffer_free(&buffer);
		close(fd);
		return 0;
	}
	close(fd);

	/* Check that it is at least big enought to contain the ID string. */
	if (len < strlen(AUTHFILE_ID_STRING) + 1) {
		debug("Bad key file %.200s.", filename);
		buffer_free(&buffer);
		return 0;
	}
	/*
	 * Make sure it begins with the id string.  Consume the id string
	 * from the buffer.
	 */
	for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++)
		if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) {
			debug("Bad key file %.200s.", filename);
			buffer_free(&buffer);
			return 0;
		}
	/* Read cipher type. */
	cipher_type = buffer_get_char(&buffer);
	(void) buffer_get_int(&buffer);	/* Reserved data. */

	/* Read the public key from the buffer. */
	buffer_get_int(&buffer);
	prv->n = BN_new();
	buffer_get_bignum(&buffer, prv->n);
	prv->e = BN_new();
	buffer_get_bignum(&buffer, prv->e);
	if (comment_return)
		*comment_return = buffer_get_string(&buffer, NULL);
	else
		xfree(buffer_get_string(&buffer, NULL));

	/* Check that it is a supported cipher. */
	if (((cipher_mask1() | SSH_CIPHER_NONE | SSH_AUTHFILE_CIPHER) &
	     (1 << cipher_type)) == 0) {
		debug("Unsupported cipher %.100s used in key file %.200s.",
		      cipher_name(cipher_type), filename);
		buffer_free(&buffer);
		goto fail;
	}
	/* Initialize space for decrypted data. */
	buffer_init(&decrypted);
	buffer_append_space(&decrypted, &cp, buffer_len(&buffer));

	/* Rest of the buffer is encrypted.  Decrypt it using the passphrase. */
	cipher_set_key_string(&cipher, cipher_type, passphrase);
	cipher_decrypt(&cipher, (unsigned char *) cp,
		       (unsigned char *) buffer_ptr(&buffer),
		       buffer_len(&buffer));

	buffer_free(&buffer);

	check1 = buffer_get_char(&decrypted);
	check2 = buffer_get_char(&decrypted);
	if (check1 != buffer_get_char(&decrypted) ||
	    check2 != buffer_get_char(&decrypted)) {
		if (strcmp(passphrase, "") != 0)
			debug("Bad passphrase supplied for key file %.200s.", filename);
		/* Bad passphrase. */
		buffer_free(&decrypted);
fail:
		BN_clear_free(prv->n);
		prv->n = NULL;
		BN_clear_free(prv->e);
		prv->e = NULL;
		if (comment_return)
			xfree(*comment_return);
		return 0;
	}
	/* Read the rest of the private key. */
	prv->d = BN_new();
	buffer_get_bignum(&decrypted, prv->d);
	prv->iqmp = BN_new();
	buffer_get_bignum(&decrypted, prv->iqmp);	/* u */
	/* in SSL and SSH p and q are exchanged */
	prv->q = BN_new();
	buffer_get_bignum(&decrypted, prv->q);		/* p */
	prv->p = BN_new();
	buffer_get_bignum(&decrypted, prv->p);		/* q */

	ctx = BN_CTX_new();
	aux = BN_new();

	BN_sub(aux, prv->q, BN_value_one());
	prv->dmq1 = BN_new();
	BN_mod(prv->dmq1, prv->d, aux, ctx);

	BN_sub(aux, prv->p, BN_value_one());
	prv->dmp1 = BN_new();
	BN_mod(prv->dmp1, prv->d, aux, ctx);

	BN_clear_free(aux);
	BN_CTX_free(ctx);

	buffer_free(&decrypted);

	return 1;
}

int
load_private_key_dsa(int fd, const char *passphrase, Key *k, char **comment_return)
{
	DSA *dsa;
	BIO *in;
	FILE *fp;

	in = BIO_new(BIO_s_file());
	if (in == NULL) {
		error("BIO_new failed");
		return 0;
	}
	fp = fdopen(fd, "r");
	if (fp == NULL) {
		error("fdopen failed");
		return 0;
	}
	BIO_set_fp(in, fp, BIO_NOCLOSE);
	dsa = PEM_read_bio_DSAPrivateKey(in, NULL, NULL, (char *)passphrase);
	if (dsa == NULL) {
		debug("PEM_read_bio_DSAPrivateKey failed");
	} else {
		/* replace k->dsa with loaded key */
		DSA_free(k->dsa);
		k->dsa = dsa;
	}
	BIO_free(in);
	fclose(fp);
	if (comment_return)
		*comment_return = xstrdup("dsa w/o comment");
	debug("read DSA private key done");
#ifdef DEBUG_DSS
	DSA_print_fp(stderr, dsa, 8);
#endif
	return dsa != NULL ? 1 : 0;
}

int
load_private_key(const char *filename, const char *passphrase, Key *key,
    char **comment_return)
{
	int fd;
	int ret = 0;
	struct stat st;

	fd = open(filename, O_RDONLY);
	if (fd < 0)
		return 0;

	/* check owner and modes */
	if (fstat(fd, &st) < 0 ||
	    (st.st_uid != 0 && st.st_uid != getuid()) ||
	    (st.st_mode & 077) != 0) {
		close(fd);
		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
		error("@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @");
		error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
		error("Bad ownership or mode(0%3.3o) for '%s'.",
		      st.st_mode & 0777, filename);
		error("It is recommended that your private key files are NOT accessible by others.");
		return 0;
	}
	switch (key->type) {
	case KEY_RSA:
		if (key->rsa->e != NULL) {
			BN_clear_free(key->rsa->e);
			key->rsa->e = NULL;
		}
		if (key->rsa->n != NULL) {
			BN_clear_free(key->rsa->n);
			key->rsa->n = NULL;
		}
		ret = load_private_key_rsa(fd, filename, passphrase,
		     key->rsa, comment_return);
		break;
	case KEY_DSA:
		ret = load_private_key_dsa(fd, passphrase, key, comment_return);
	default:
		break;
	}
	close(fd);
	return ret;
}
